docs: refresh INDEX.md to match live code
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Surgical refresh of the drifted project index: corrected the repo path, documented the internal-admin "Supe Panel", payments now Stripe-only (EFT history preserved as deprecated), CI/CD -> qa-gate + Coolify(dev)/PM2(prod), added blog/changelog/posthog modules + Sentry entry points, route count 36 -> 42, and replaced the fictional docs list with the files that exist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
141
docs/INDEX.md
141
docs/INDEX.md
@@ -1,9 +1,9 @@
|
||||
# Sase.tr - Project Documentation Index
|
||||
|
||||
> **Automotive parts search platform** for the Turkish market with VIN decoding, subscription-based access, and multi-source parts catalog integration.
|
||||
> **URL:** https://sase.tr | **Repo:** `/home/s/ss`
|
||||
> **URL:** https://sase.tr · **Staging:** https://dev.sase.tr | **Repo:** `/home/s/sase.tr`
|
||||
|
||||
Generated: 2026-03-02
|
||||
Generated: 2026-03-02 · Last refreshed: 2026-05-24
|
||||
|
||||
---
|
||||
|
||||
@@ -74,15 +74,15 @@ Generated: 2026-03-02
|
||||
| **Database** | PostgreSQL 17, Drizzle ORM 0.41 |
|
||||
| **Cache** | Redis 7.4, ioredis |
|
||||
| **Auth** | Better Auth 1.2 (email/password + Google OAuth) |
|
||||
| **Payments** | Stripe (card), EFT (bank transfer with receipt upload) |
|
||||
| **Payments** | Stripe (card checkout + webhook) |
|
||||
| **Storage** | MinIO (S3-compatible) |
|
||||
| **Jobs** | BullMQ (Redis-backed queues) |
|
||||
| **Email** | Postal (transactional email) |
|
||||
| **Analytics** | PostHog (product analytics) |
|
||||
| **Observability** | OpenTelemetry (API), Grafana Faro (frontend) |
|
||||
| **Observability** | OpenTelemetry + Sentry (API), Grafana Faro (frontend) |
|
||||
| **Testing** | Vitest 3, Playwright 1.50 |
|
||||
| **Linting** | Biome (2-space, double quotes, semicolons, trailing commas) |
|
||||
| **CI/CD** | GitHub Actions → SSH deploy → PM2 |
|
||||
| **CI/CD** | GitHub Actions `qa-gate` (PR tests) · Coolify (dev.sase.tr) · GitHub Actions → PM2 (prod) |
|
||||
| **Package Mgmt** | pnpm 10.29, Turborepo 2 |
|
||||
|
||||
---
|
||||
@@ -95,15 +95,17 @@ sase.tr/
|
||||
│ ├── api/ # NestJS backend API
|
||||
│ │ ├── src/
|
||||
│ │ │ ├── main.ts # Bootstrap (global prefix /api, CORS, Helmet, rate limiting)
|
||||
│ │ │ ├── instrument.ts # Sentry init (imported first in main.ts)
|
||||
│ │ │ ├── app.module.ts # Root module (global guards, interceptors, filters)
|
||||
│ │ │ ├── worker.ts # Standalone worker process
|
||||
│ │ │ ├── instrument-worker.ts # Sentry init for the worker process
|
||||
│ │ │ ├── health.controller.ts # Health check endpoint
|
||||
│ │ │ ├── auth/ # Better Auth integration
|
||||
│ │ │ ├── users/ # User account management
|
||||
│ │ │ ├── brands/ # Brand CRUD
|
||||
│ │ │ ├── plans/ # Pricing plan CRUD
|
||||
│ │ │ ├── subscriptions/ # Subscription lifecycle
|
||||
│ │ │ ├── payments/ # Stripe + EFT payment processing
|
||||
│ │ │ ├── payments/ # Stripe payment processing (checkout + webhook)
|
||||
│ │ │ ├── referrals/ # Referral program
|
||||
│ │ │ ├── vehicles/ # VIN decoding + vehicle history
|
||||
│ │ │ ├── categories/ # Parts category tree
|
||||
@@ -111,7 +113,11 @@ sase.tr/
|
||||
│ │ │ ├── catalog/ # VIN-less catalog browser (PL24 model families)
|
||||
│ │ │ ├── translations/ # Automotive term translations
|
||||
│ │ │ ├── admin/ # Admin dashboard endpoints
|
||||
│ │ │ ├── analytics/ # Usage analytics tracking
|
||||
│ │ │ ├── internal-admin/ # Founder-only "Supe Panel" (impersonation, lifecycle, billing, refunds)
|
||||
│ │ │ ├── analytics/ # OEM copy-event tracking
|
||||
│ │ │ ├── posthog/ # PostHog server-side event capture
|
||||
│ │ │ ├── blog/ # Blog posts (public + automation webhook)
|
||||
│ │ │ ├── changelog/ # Changelog entries (public + automation webhook)
|
||||
│ │ │ ├── common/ # Shared guards, pipes, interceptors, filters, decorators
|
||||
│ │ │ ├── config/ # Runtime configuration
|
||||
│ │ │ ├── database/ # Drizzle ORM setup + schemas (core, emex, pl24, parts-catalogs, relations)
|
||||
@@ -175,6 +181,7 @@ sase.tr/
|
||||
| API Server | `apps/api/src/main.ts` | NestJS bootstrap (Helmet, CORS, rate limiting) |
|
||||
| Root Module | `apps/api/src/app.module.ts` | Global guards, interceptors, filters |
|
||||
| Worker | `apps/api/src/worker.ts` | BullMQ background job processor |
|
||||
| Sentry Init | `apps/api/src/instrument.ts` · `instrument-worker.ts` | Sentry instrumentation (imported before app bootstrap) |
|
||||
| Health | `apps/api/src/health.controller.ts` | Health check endpoint |
|
||||
| Frontend | `apps/web/src/main.tsx` | React 19 + TanStack Router + Query + Faro + PostHog |
|
||||
| Root Layout | `apps/web/src/routes/__root.tsx` | Theme, Toaster, PostHog tracking |
|
||||
@@ -192,15 +199,19 @@ sase.tr/
|
||||
| **BrandsModule** | module, service, controller, spec | Brand CRUD (cached, admin-managed) |
|
||||
| **PlansModule** | module, service, controller, spec | Pricing plan CRUD (cached, admin-managed) |
|
||||
| **SubscriptionsModule** | module, service, controller, spec | Create, activate, cancel, resume, extend subscriptions |
|
||||
| **PaymentsModule** | module, service, controller, spec | Stripe card payments, EFT with receipt upload, admin approval |
|
||||
| **PaymentsModule** | module, service, controller, spec | Stripe card payments (checkout session + webhook), payment history |
|
||||
| **ReferralsModule** | module, service, controller, spec | Referral code generation, application, tier-based rewards |
|
||||
| **VehiclesModule** | module, service, controller, spec | VIN decode (multi-source fallback), vehicle history, brand access check |
|
||||
| **CategoriesModule** | module, service, controller, spec | Hierarchical category tree, schema pictures |
|
||||
| **PartsModule** | module, service, controller, spec | Parts by category, OEM code search |
|
||||
| **CatalogModule** | module, service, controller, dto | VIN-less PL24 catalog browser: brands, models, category trees, parts |
|
||||
| **TranslationsModule** | module, service, controller, spec | Automotive term translation (Redis → DB → Dictionary fallback) |
|
||||
| **AdminModule** | module, service, controller, spec | Dashboard stats, user management, payment approval, analytics |
|
||||
| **AnalyticsModule** | module, service, controller | Usage analytics tracking |
|
||||
| **AdminModule** | module, service, controller, spec | Dashboard stats, user management, query logs, referral & daily stats, OEM copy logs |
|
||||
| **InternalAdminModule** | impersonation, lifecycle, billing, payments, vehicles (controller+service each) | Founder-only "Supe Panel": read-only impersonation, suspend/ban, trial/plan edits, refunds, vehicle cache ops. Gated by `InternalTokenGuard` (`INTERNAL_API_TOKEN`) |
|
||||
| **AnalyticsModule** | module, service, controller | OEM code copy-event tracking (`oemCodeCopies`) |
|
||||
| **PostHogModule** | module, service | Server-side PostHog event capture (optional) |
|
||||
| **BlogModule** | module, service, controller | Blog posts: public list/detail + automation webhook (Bearer token) |
|
||||
| **ChangelogModule** | module, service, controller, spec | Changelog entries: public list + admin CRUD + automation webhook |
|
||||
| **EmailModule** | module, service | Postal transactional emails (password reset, welcome, payment confirmation) |
|
||||
| **StorageModule** | module, service | S3/MinIO file upload/download |
|
||||
| **RedisModule** | module, service, provider | Key-value cache operations |
|
||||
@@ -213,6 +224,8 @@ sase.tr/
|
||||
| **Guard** | `RolesGuard` (global) | Checks `@Roles("admin")` metadata against `user.role` |
|
||||
| **Guard** | `BrandAccessGuard` (per-route) | Verifies user's subscription includes the target brand |
|
||||
| **Guard** | `ThrottlerGuard` (global) | Rate limiting (100/min default) |
|
||||
| **Guard** | `ImpersonationReadonlyGuard` (global) | Blocks mutations during a read-only impersonation session |
|
||||
| **Guard** | `InternalTokenGuard` (per-route) | Validates `INTERNAL_API_TOKEN` bearer for `/api/internal/admin/*` (Supe Panel) |
|
||||
| **Interceptor** | `TransformInterceptor` (global) | Wraps responses: `{success: true, data: ...}` |
|
||||
| **Interceptor** | `LoggingInterceptor` (global) | Logs method, URL, status, response time |
|
||||
| **Interceptor** | `TimeoutInterceptor` (global) | 30s request timeout |
|
||||
@@ -291,9 +304,13 @@ userBrands (junction)
|
||||
|
||||
payments
|
||||
├── id (uuid, PK), userId → users, subscriptionId → userSubscriptions
|
||||
├── amount, currency, method (stripe/eft), status (pending/completed/failed/refunded)
|
||||
├── stripePaymentIntentId, eftReceiptUrl, adminNote
|
||||
└── Indexes: userId, status
|
||||
├── amount, currency, method, status (pending/completed/failed/refunded)
|
||||
├── stripeSessionId, stripePaymentIntentId, adminNote
|
||||
├── iyzicoPaymentId, bankAccountId → bankAccounts, eftReceiptUrl (@deprecated — legacy iyzico/EFT, kept for historical rows only)
|
||||
└── Indexes: userId, status, stripeSessionId
|
||||
|
||||
bankAccounts
|
||||
└── (legacy) EFT bank-transfer accounts; retained for historical payments only
|
||||
|
||||
vehicles
|
||||
├── id (uuid, PK), vin (unique), brandId → brands
|
||||
@@ -340,6 +357,15 @@ passwordResetTokens
|
||||
emexCategoryTranslations
|
||||
└── id, originalName (unique), translatedName, isManual
|
||||
|
||||
oemCodeCopies
|
||||
└── OEM code copy events (userId, oemCode, optional partId/vehicleId/categoryId) — admin copy-log analytics
|
||||
|
||||
blogPosts
|
||||
└── SEO blog posts (slug, title, content, publish state)
|
||||
|
||||
changelogEntries
|
||||
└── Product changelog entries (shown in Settings → Changelog)
|
||||
|
||||
catalogVehicles
|
||||
├── id (uuid, PK), source (pl24), serviceName, brandName, brandId → brands
|
||||
├── model, year, engine, bodyType, transmission, market
|
||||
@@ -467,14 +493,11 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|
||||
#### Payments
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| `POST` | `/api/payments/stripe/checkout` | User | Start Stripe card payment |
|
||||
| `POST` | `/api/payments/stripe/checkout` | User | Create Stripe checkout session |
|
||||
| `POST` | `/api/payments/stripe/webhook` | Public | Stripe webhook callback |
|
||||
| `POST` | `/api/payments/eft` | User | Create EFT payment |
|
||||
| `POST` | `/api/payments/eft/:id/receipt` | User | Upload EFT receipt (PNG/JPG/PDF, 5MB max) |
|
||||
| `PATCH` | `/api/payments/eft/:id/approve` | Admin | Approve EFT payment |
|
||||
| `PATCH` | `/api/payments/eft/:id/reject` | Admin | Reject EFT payment |
|
||||
| `GET` | `/api/payments/me` | User | Payment history |
|
||||
| `GET` | `/api/payments/pending` | Admin | Pending EFT payments |
|
||||
|
||||
> EFT (bank-transfer) endpoints were removed in the Stripe migration (FN-343). The `payments` table keeps `eftReceiptUrl`/`bankAccountId`/`iyzicoPaymentId` only for historical rows.
|
||||
|
||||
#### Referrals
|
||||
| Method | Path | Auth | Description |
|
||||
@@ -486,8 +509,12 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|
||||
#### Vehicles
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| `GET` | `/api/vehicles/preview/:vin` | Public | Preview vehicle by VIN (pre-decode) |
|
||||
| `POST` | `/api/vehicles/decode` | User | Decode VIN (rate limited: 20/min) |
|
||||
| `GET` | `/api/vehicles/history` | User | Vehicle history (paginated) |
|
||||
| `POST` | `/api/vehicles/report-vin` | User | Report an unrecognized VIN to admin |
|
||||
| `GET` | `/api/vehicles/:vehicleId/prefetch-status` | User | Catalog prefetch job status |
|
||||
| `GET` | `/api/vehicles/:vehicleId/categories/:categoryId` | User | Parts for a vehicle + category |
|
||||
| `GET` | `/api/vehicles/:id` | User | Get vehicle details |
|
||||
| `DELETE` | `/api/vehicles/:id` | User | Delete vehicle |
|
||||
|
||||
@@ -515,6 +542,9 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|
||||
| `GET` | `/api/catalog/vehicles/:id/categories/:categoryId` | User | Sub-categories or parts+schema (`?body=&engine=&gearbox=`); lazy PL24 fetch |
|
||||
| `POST` | `/api/catalog/explore/:serviceName` | Admin | Explore PL24 service structure (discovery tool) |
|
||||
|
||||
**EMEX sub-catalog** (`/api/catalog/emex/*`): `brands`, `brands/:code/vehicles`, `brands/:code/wizard`, `brands/:code/wizard-vehicles`, `vehicles/:id/groups`, `vehicles/:id/groups/:groupId`, `search?oem=`, `match?catalogCode=&name=`
|
||||
**PCAT sub-catalog** (`/api/catalog/pcat/*`): `catalogs`, `catalogs/:id/models`, `catalogs/:id/groups`, `catalogs/:id/models/:modelId/cars`, `cars/:carId/groups`, `cars/:carId/groups/:groupId/schemas`, `schemas/:schemaImageId`
|
||||
|
||||
#### Translations
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
@@ -526,19 +556,39 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|
||||
#### Admin
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| `POST` | `/api/admin/users` | Admin | Create a user |
|
||||
| `GET` | `/api/admin/dashboard` | Admin | Dashboard stats (users, revenue, queries) |
|
||||
| `GET` | `/api/admin/users` | Admin | User list with search (paginated) |
|
||||
| `GET` | `/api/admin/users/:id` | Admin | User detail with subscriptions & payments |
|
||||
| `GET` | `/api/admin/payments/pending` | Admin | Pending EFT payments |
|
||||
| `GET` | `/api/admin/query-logs` | Admin | Query logs (paginated, filterable) |
|
||||
| `GET` | `/api/admin/referrals` | Admin | Referral stats (paginated) |
|
||||
| `GET` | `/api/admin/stats/daily` | Admin | Daily VIN decode stats (last 30 days) |
|
||||
| `GET` | `/api/admin/copy-logs` | Admin | OEM code copy logs |
|
||||
| `GET` | `/api/admin/copy-logs/top` | Admin | Top copied OEM codes (`?days=`) |
|
||||
|
||||
#### Analytics
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| `POST` | `/api/analytics/oem-copy` | User | Track OEM code copy event (oemCode, partId?, vehicleId?, categoryId?) |
|
||||
|
||||
#### Blog
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| `GET` | `/api/blog/posts` | Public | List published posts |
|
||||
| `GET` | `/api/blog/posts/:slug` | Public | Get post by slug |
|
||||
| `POST` | `/api/blog/posts/internal` | Token (Bearer) | Create/update post via automation |
|
||||
|
||||
#### Internal Admin — "Supe Panel" (founder-only, `InternalTokenGuard`)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| `POST` | `/api/internal/admin/users/:id/impersonate-readonly` | Mint a signed read-only impersonation consume-URL |
|
||||
| `GET` | `/api/admin/impersonate/consume?t=` | Consume token → set read-only session cookie |
|
||||
| `POST` | `/api/internal/admin/users/:id/{suspend,reactivate,ban}` | Account lifecycle |
|
||||
| `POST` | `/api/internal/admin/subscriptions/:id/{trial/extend,activate,change-plan,cancel,resume,brands}` | Billing / subscription overrides |
|
||||
| `POST` | `/api/internal/admin/payments/:id/refund` | Refund a payment |
|
||||
| `POST` | `/api/internal/admin/vehicles/:vin/cache-clear` | Clear cached catalog data for a VIN |
|
||||
| `DELETE` | `/api/internal/admin/vehicles/:vin` | Force-delete a vehicle |
|
||||
|
||||
#### Changelog
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
@@ -562,7 +612,9 @@ Flow:
|
||||
6. User injected into request via @CurrentUser() decorator
|
||||
```
|
||||
|
||||
**User model extensions:** `role` (default: "user"), `referralCode`, `referredBy`
|
||||
**User model extensions:** `role` (default: "user"), `referralCode`, `referredBy`, account `status` (active/suspended/banned — non-active users are rejected by `AuthGuard`).
|
||||
|
||||
**Internal/founder access:** the `/api/internal/admin/*` "Supe Panel" routes are gated by `InternalTokenGuard` (`INTERNAL_API_TOKEN` bearer), separate from user auth. Read-only impersonation issues an HMAC-signed consume token (`INTERNAL_IMPERSONATION_SECRET`); the resulting session is mutation-blocked by `ImpersonationReadonlyGuard`.
|
||||
|
||||
---
|
||||
|
||||
@@ -570,7 +622,7 @@ Flow:
|
||||
|
||||
### Routes & Pages
|
||||
|
||||
**Router:** TanStack Router (file-based, auto-generated route tree — 36 files)
|
||||
**Router:** TanStack Router (file-based, auto-generated route tree — 42 files)
|
||||
|
||||
#### Public
|
||||
| Path | Route File | Description |
|
||||
@@ -600,9 +652,8 @@ Flow:
|
||||
| `/dashboard` | `routes/dashboard/index.tsx` | Dashboard home |
|
||||
| `/dashboard/search` | `routes/dashboard/search.tsx` | VIN Search — main VIN decoder input |
|
||||
| `/dashboard/history` | `routes/dashboard/history.tsx` | Past VIN decode searches |
|
||||
| `/dashboard/subscription` | `routes/dashboard/subscription/index.tsx` | Plan selection & brand picker |
|
||||
| `/dashboard/subscription/pay` | `routes/dashboard/subscription/pay.tsx` | Card (Stripe) or EFT payment |
|
||||
| `/dashboard/billing` | `routes/dashboard/billing.tsx` | Payment history & receipts |
|
||||
| `/dashboard/subscription` | `routes/dashboard/subscription/index.tsx` | Plan selection & brand picker (Stripe checkout redirect) |
|
||||
| `/dashboard/billing` | `routes/dashboard/billing.tsx` | Payment history |
|
||||
| `/dashboard/settings` | `routes/dashboard/settings.tsx` | Profile, Security, Connections, Referral, Account, Changelog tabs |
|
||||
| `/dashboard/vehicles/$id` | `routes/dashboard/vehicles_/$id/index.tsx` | Vehicle details |
|
||||
| `/dashboard/vehicles/$id/categories/$categoryId` | `routes/dashboard/vehicles_/$id/categories_/$categoryId.tsx` | Interactive schema + parts table |
|
||||
@@ -615,12 +666,13 @@ Flow:
|
||||
| `/dashboard/catalog/$brandName/$modelId` | `routes/dashboard/catalog_/$brandName_/$modelId/index.tsx` | Vehicle details + category tree (grid/tree toggle) |
|
||||
| `/dashboard/catalog/$brandName/$modelId/categories/$categoryId` | `routes/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId.tsx` | Category sub-groups or schema+parts (lazy PL24 fetch) |
|
||||
|
||||
> Source-specific sub-browsers also exist: `/dashboard/catalog/emex/$catalogCode[/$vehicleId]` (EMEX group navigation) and `/dashboard/catalog/pcat/$catalogId` (PartsCatalogs). A `/dashboard/service-test` page surfaces catalog-source status.
|
||||
|
||||
#### Admin (Role-based)
|
||||
| Path | Route File | Description |
|
||||
|------|------------|-------------|
|
||||
| `/dashboard/admin` | `routes/dashboard/admin/index.tsx` | Stats overview with charts |
|
||||
| `/dashboard/admin/users` | `routes/dashboard/admin/users.tsx` | User management |
|
||||
| `/dashboard/admin/payments` | `routes/dashboard/admin/payments.tsx` | EFT approval workflow |
|
||||
| `/dashboard/admin/referrals` | `routes/dashboard/admin/referrals.tsx` | Referral program tracking |
|
||||
| `/dashboard/admin/analytics` | `routes/dashboard/admin/analytics.tsx` | Daily query statistics |
|
||||
| `/dashboard/admin/copy-logs` | `routes/dashboard/admin/copy-logs.tsx` | OEM code copy tracking |
|
||||
@@ -705,7 +757,7 @@ Flow:
|
||||
|
||||
| Directory | Exports |
|
||||
|-----------|---------|
|
||||
| `types/` | User, UserProfile, UserSubscriptionSummary, Vehicle, VinDecodeResult, CategoryNode, VehicleSource, Brand, Plan, Subscription, UserBrand, CreateSubscriptionInput, SubscriptionStatus, Payment, PaymentMethod, PaymentStatus, EftPaymentInput, Part, PartSource, PartSearchResult, Category, CategoryWithSchema, SchemaPic, Hotspot, ApiResponse, ApiError, PaginationMeta, PaginationInput, PaginatedResult, ChangelogEntry, CreateChangelogEntry, UpdateChangelogEntry, ChangelogChangeType |
|
||||
| `types/` | User, UserProfile, UserSubscriptionSummary, Vehicle, VinDecodeResult, CategoryNode, VehicleSource, Brand, Plan, Subscription, UserBrand, CreateSubscriptionInput, SubscriptionStatus, Payment, PaymentMethod, PaymentStatus, Part, PartSource, PartSearchResult, Category, CategoryWithSchema, SchemaPic, Hotspot, ApiResponse, ApiError, PaginationMeta, PaginationInput, PaginatedResult, ChangelogEntry, CreateChangelogEntry, UpdateChangelogEntry, ChangelogChangeType |
|
||||
| `schemas/` | loginSchema, registerSchema, forgotPasswordSchema, resetPasswordSchema, vinSchema, paginationSchema, changelogEntrySchema, createChangelogEntrySchema, updateChangelogEntrySchema, changelogChangeTypeEnum (Zod) |
|
||||
| `constants/` | ERROR_CODES (30+, prefixed AUTH/VIN/SUB/PAY), PLANS (Single/Double/Triple/Full), REFERRAL_REWARDS (Tier 1: 3→7d, Tier 2: 5→30d), VIN_REGEX, EMAIL_REGEX, OEM_CODE_REGEX, CURRENCY |
|
||||
| `utils/` | VIN validator (check digit, WMI extraction, model year decode), currency (formatTRY, kurus↔lira), formatters (VIN, date, datetime, Turkish slug, referral code) |
|
||||
@@ -762,6 +814,8 @@ Dependencies: Radix UI (accordion, dialog, dropdown-menu, label, popover, select
|
||||
| Redis 7.4 | `redis:7.4-alpine` | 127.0.0.1:6379 | `redis_data` |
|
||||
| MinIO | `minio/minio` | 9000 (API), 9001 (Console) | `minio_data` |
|
||||
|
||||
> **Staging / prod:** `docker-compose.coolify.yml` (repo root) defines the deployed services — `api`, `worker`, and `sase-redis` (Redis 7.4). PostgreSQL and MinIO are external/managed in those environments.
|
||||
|
||||
### SEO Infrastructure
|
||||
|
||||
- `apps/web/scripts/prerender.mjs` — Pre-renders public pages to static HTML (landing, blog posts, pricing, etc.) for crawler/bot visibility
|
||||
@@ -774,21 +828,15 @@ Dependencies: Radix UI (accordion, dialog, dropdown-menu, label, popover, select
|
||||
- `sase.tr.conf` — Frontend SPA + `/api` proxy + `/collect/` Faro telemetry CORS proxy + gzip (level 6) + 1-year asset cache + security headers
|
||||
- `api.sase.tr.conf` — NestJS proxy (60s timeout for VIN decode) + SSL + blocked paths (.git, .env, node_modules)
|
||||
|
||||
### CI/CD (GitHub Actions)
|
||||
### CI/CD
|
||||
|
||||
**`ci.yml`** — Runs on all branches & PRs to main (15min timeout):
|
||||
1. Biome lint
|
||||
2. TypeScript type check
|
||||
3. Vitest unit tests
|
||||
4. Full build
|
||||
**GitHub Actions — `.github/workflows/qa-gate.yml`** (PR gate, 15min timeout):
|
||||
- Triggers on PRs touching `apps/api/**` or `apps/web/**`; cancels superseded runs for the same PR.
|
||||
- Detects which app changed, then runs `pnpm --filter <app> test` only for the changed app(s) (Node 22 + pnpm).
|
||||
|
||||
**`deploy.yml`** — Runs on push to `main` (10min timeout):
|
||||
1. SSH into production
|
||||
2. `git pull origin main`
|
||||
3. `pnpm install`
|
||||
4. `pnpm build`
|
||||
5. `pnpm db:migrate` (migrations)
|
||||
6. PM2 reload all
|
||||
**Deploy — Coolify (staging) + GitHub Actions → PM2 (production):**
|
||||
- **`dev` branch → Coolify → https://dev.sase.tr** via Gitea/GitHub webhook. The container is built from the root `Dockerfile`; runtime services are defined in `docker-compose.coolify.yml` (`api`, `worker`, `sase-redis`). Migrations run on container start via `apps/api/start.sh`, before the server boots.
|
||||
- **`main` branch → production (https://sase.tr)** is promoted manually by the maintainer (merge `dev → main`), then shipped via GitHub Actions → SSH → PM2 (`pnpm build` + `pnpm db:migrate` + `pm2 reload`). See `AGENTS.md` for the dev-only deploy policy.
|
||||
|
||||
### PM2 Configuration
|
||||
|
||||
@@ -933,9 +981,16 @@ pm2 reload all
|
||||
|
||||
## Documentation
|
||||
|
||||
| File | Topic |
|
||||
| File / Dir | Topic |
|
||||
|------|-------|
|
||||
| `docs/INDEX.md` | This file — comprehensive project reference |
|
||||
| `README.md` | Quick stack overview & commands (Turkish) |
|
||||
| `CLAUDE.md` | Claude Code project guide |
|
||||
| `.claude/product-marketing-context.md` | Marketing context |
|
||||
| `docs/00-overview.md` — `docs/13-analytics-posthog.md` | Detailed topic docs |
|
||||
| `AGENTS.md` | Fusion agent deploy policy (dev-only; prod is human-merged) |
|
||||
| `knowledge.md` | Long-form knowledge base (Dify.ai export) |
|
||||
| `docs/pl24-catalog/*.md` | Per-brand PL24 catalog notes (BMW, Mercedes, Ford, …) + `_summary.md` |
|
||||
| `docs/product/*.md` | CRO funnel audits & product shortlists |
|
||||
| `docs/design-specs/*.md` | UX/design specs (e.g. VIN-decode error branches) |
|
||||
| `docs/clarification/*.md` | Open requirement clarifications |
|
||||
| `docs/00-testing.md` · `docs/TASK_REGISTRY_GUIDELINES.md` | Testing guide · task-registry conventions |
|
||||
| `docs/analytics-queries.sql` | Saved analytics SQL |
|
||||
|
||||
Reference in New Issue
Block a user