feat(FN-188): add Changelog tab to dashboard settings
Some checks failed
Sync dev → Gitea / Mirror dev to Gitea (push) Has been cancelled

Squash-recovery of fusion/fn-188 onto dev — original branch was based on
main (dccd4fa) due to baseBranch=None drift in Fusion settings; rebase
onto dev surfaced unrelated main-only commits (EMEX/PL24/Corgi) as false
conflicts. This commit applies only FN-188's 23-file changelog patch.

- apps/api: ChangelogModule (controller, service, DTO, spec, schema)
- apps/web: ChangelogTab (timeline + accordion), useChangelog hook, i18n
- packages/shared: changelog Zod schemas + types
- packages/ui: Accordion component + Badge stage variant
- docs/INDEX.md: changelog feature documented

Lint, typecheck, all 169 api tests + 2 web tests pass.
This commit is contained in:
Fusion
2026-05-11 20:05:16 +00:00
parent a7042dffb0
commit 85ebd35048
23 changed files with 739 additions and 13 deletions

View File

@@ -504,6 +504,14 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|--------|------|------|-------------|
| `POST` | `/api/analytics/oem-copy` | User | Track OEM code copy event (oemCode, partId?, vehicleId?, categoryId?) |
#### Changelog
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `GET` | `/api/changelog` | Public | List changelog entries (Redis-cached, 30min) |
| `POST` | `/api/changelog` | Admin | Create changelog entry |
| `PATCH` | `/api/changelog/:id` | Admin | Update changelog entry |
| `DELETE` | `/api/changelog/:id` | Admin | Delete changelog entry |
### Authentication
**Provider:** Better Auth 1.2
@@ -559,7 +567,7 @@ Flow:
| `/dashboard/subscription` | `routes/dashboard/subscription/index.tsx` | Plan selection & brand picker |
| `/dashboard/subscription/pay` | `routes/dashboard/subscription/pay.tsx` | Card (Iyzico) or EFT payment |
| `/dashboard/billing` | `routes/dashboard/billing.tsx` | Payment history & receipts |
| `/dashboard/settings` | `routes/dashboard/settings.tsx` | Profile, Security, Connections, Referral, Account tabs |
| `/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 |
@@ -598,10 +606,11 @@ Flow:
| **DailyChart** | `components/admin/daily-chart.tsx` | Daily VIN decode stats chart |
| **PaymentContent** | `components/payment/payment-content.tsx` | Payment form and flow |
| **SettingsContent** | `components/settings/settings-content.tsx` | User settings panel content |
| **ChangelogTab** | `components/settings/changelog-tab.tsx` | Timeline + accordion changelog viewer |
| **PsaVariantSelector** | `components/catalog/psa-variant-selector.tsx` | PSA (Citroën/Peugeot) body/engine/gearbox picker for VIN-less catalog |
| **FordVariantSelector** | `components/catalog/ford-variant-selector.tsx` | Ford model-year/engine/gearbox picker for VIN-less catalog |
**UI primitives** from `@sase/ui`: Button, Card, Input, Label, Badge, Dialog, Tabs, Separator, Skeleton
**UI primitives** from `@sase/ui`: Button, Card, Input, Label, Badge (with stage variant), Dialog, Tabs, Separator, Skeleton, Accordion
### Hooks & Stores
@@ -612,6 +621,7 @@ Flow:
| `useCategoryParts(vehicleId, categoryId)` | TanStack Query for schema + parts + hotspots |
| `useSchemaInteraction()` | Pan/zoom/pinch event handlers for schema viewer |
| `usePageMeta(options)` | Sets `<title>`, meta description, canonical, OG/Twitter tags; restores defaults on unmount |
| `useChangelog()` | TanStack Query for changelog entries (staleTime: 30min) |
**Stores (Zustand):**
| Store | State |
@@ -659,8 +669,8 @@ Flow:
| Directory | Exports |
|-----------|---------|
| `types/` | User, UserProfile, UserSubscriptionSummary, Vehicle, VinDecodeResult, CategoryNode, VehicleSource, Brand, Plan, Subscription, UserBrand, CreateSubscriptionInput, SubscriptionStatus, Payment, PaymentMethod, PaymentStatus, IyzicoInitializeInput, EftPaymentInput, Part, PartSource, PartSearchResult, Category, CategoryWithSchema, SchemaPic, Hotspot, ApiResponse, ApiError, PaginationMeta, PaginationInput, PaginatedResult |
| `schemas/` | loginSchema, registerSchema, forgotPasswordSchema, resetPasswordSchema, vinSchema, paginationSchema (Zod) |
| `types/` | User, UserProfile, UserSubscriptionSummary, Vehicle, VinDecodeResult, CategoryNode, VehicleSource, Brand, Plan, Subscription, UserBrand, CreateSubscriptionInput, SubscriptionStatus, Payment, PaymentMethod, PaymentStatus, IyzicoInitializeInput, EftPaymentInput, Part, PartSource, PartSearchResult, Category, CategoryWithSchema, SchemaPic, Hotspot, ApiResponse, ApiError, PaginationMeta, PaginationInput, PaginatedResult, ChangelogEntry, CreateChangelogEntry, UpdateChangelogEntry, ChangelogStage |
| `schemas/` | loginSchema, registerSchema, forgotPasswordSchema, resetPasswordSchema, vinSchema, paginationSchema, changelogEntrySchema, createChangelogEntrySchema, updateChangelogEntrySchema, changelogStageEnum (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) |
@@ -673,9 +683,9 @@ Groups: DATABASE_URL, REDIS_*, BETTER_AUTH_*, GOOGLE_*, MINIO_*, CORS_ORIGIN, IY
### @sase/ui (`packages/ui/src/`)
Components: Button (CVA variants), Input, Card (6 compound parts), Badge (CVA), Label, Skeleton, Separator, Dialog (10 compound parts), Tabs (4 compound parts), `cn()` utility
Components: Button (CVA variants), Input, Card (6 compound parts), Badge (CVA, includes stage variant: alpha/beta/prod), Label, Skeleton, Separator, Dialog (10 compound parts), Tabs (4 compound parts), Accordion (4 compound parts), `cn()` utility
Dependencies: Radix UI (dialog, dropdown-menu, label, popover, select, separator, slot, tabs, tooltip), class-variance-authority, clsx, tailwind-merge, lucide-react
Dependencies: Radix UI (accordion, dialog, dropdown-menu, label, popover, select, separator, slot, tabs, tooltip), class-variance-authority, clsx, tailwind-merge, lucide-react
---
@@ -685,12 +695,12 @@ Dependencies: Radix UI (dialog, dropdown-menu, label, popover, select, separator
| Category | Files | Total Lines |
|----------|-------|-------------|
| **Service specs** | 11 (admin, brands, categories, parts, payments, plans, referrals, subscriptions, translations, users, vehicles) | 2,521 |
| **Service specs** | 12 (admin, brands, categories, changelog, parts, payments, plans, referrals, subscriptions, translations, users, vehicles) | 2,521 |
| **Guard specs** | 3 (auth, roles, brand-access) | 380 |
| **Pipe specs** | 1 (vin-validation) | 77 |
| **Integration specs** | 1 (corgi) | 121 |
| **Telemetry specs** | 1 | 97 |
| **Total API** | **17 test files** | **3,196 lines** |
| **Total API** | **18 test files** | **3,196 lines** |
**Test Config:**
- API: `apps/api/vitest.config.ts``src/**/*.spec.ts`, v8 coverage (text + lcov)