feat(frontend): auto-generate TypeScript types from backend OpenAPI schema
Replace manually maintained types in src/lib/types.ts with auto-generated types from FastAPI's OpenAPI schema using @hey-api/openapi-ts. The bridge file re-exports generated types with renames, Require<> augmentations for fields that are optional in the schema but always present in responses, and manually added relationship fields excluded from OpenAPI. - Add openapi-ts.config.ts and generate:api npm script - Generate types into src/lib/api/generated/types.gen.ts - Rewrite src/lib/types.ts as bridge with re-exports and augmentations - Fix null vs undefined mismatches in consumer components - Remove unused manual type definitions from api.ts - Update AGENTS.md docs with type generation workflow
This commit is contained in:
parent
470d49b061
commit
e29d62f949
16 changed files with 13745 additions and 2298 deletions
|
|
@ -19,7 +19,8 @@ frontend/src/
|
|||
│ └── profile/ # User profile
|
||||
└── lib/
|
||||
├── api.ts # Typed fetch wrappers (server: PUBLIC_API_BASE, browser: /api)
|
||||
├── types.ts # TypeScript types mirroring backend models (manual sync)
|
||||
├── types.ts # Type bridge — re-exports from generated OpenAPI types with augmentations
|
||||
├── api/generated/ # Auto-generated types from backend OpenAPI schema — DO NOT EDIT
|
||||
├── utils.ts # cn() class merger, bits-ui types
|
||||
├── utils/ # forms.ts (preventIfNotConfirmed), skin-display.ts (label helpers)
|
||||
├── paraglide/ # Generated i18n runtime — DO NOT EDIT
|
||||
|
|
@ -123,6 +124,7 @@ pnpm check # Type check + Svelte validation
|
|||
pnpm lint # ESLint
|
||||
pnpm format # Prettier
|
||||
pnpm build # Production build → build/
|
||||
pnpm generate:api # Regenerate TypeScript types from backend OpenAPI schema
|
||||
```
|
||||
|
||||
## Anti-Patterns
|
||||
|
|
@ -130,3 +132,29 @@ pnpm build # Production build → build/
|
|||
- No frontend tests exist. Only linting + type checking.
|
||||
- ESLint `svelte/no-navigation-without-resolve` has `ignoreGoto: true` workaround (upstream bug sveltejs/eslint-plugin-svelte#1327).
|
||||
- `src/paraglide/` is a legacy output path — active i18n output is in `src/lib/paraglide/`.
|
||||
|
||||
## Type Generation
|
||||
|
||||
TypeScript types are auto-generated from the FastAPI backend's OpenAPI schema using `@hey-api/openapi-ts`.
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Generate `openapi.json` from backend: `cd backend && uv run python -c "import json; from main import app; print(json.dumps(app.openapi(), indent=2))" > ../frontend/openapi.json`
|
||||
2. Generate types: `cd frontend && pnpm generate:api`
|
||||
3. Output lands in `src/lib/api/generated/types.gen.ts` — **never edit this file directly**.
|
||||
|
||||
### Architecture
|
||||
|
||||
- **Generated types**: `src/lib/api/generated/types.gen.ts` — raw OpenAPI types, auto-generated.
|
||||
- **Bridge file**: `src/lib/types.ts` — re-exports from generated types with:
|
||||
- **Renames**: `ProductWithInventory` → `Product`, `ProductListItem` → `ProductSummary`, `UserProfilePublic` → `UserProfile`, `SkinConditionSnapshotPublic` → `SkinConditionSnapshot`.
|
||||
- **`Require<T, K>` augmentations**: Fields with `default_factory` in SQLModel are optional in OpenAPI but always present in API responses (e.g. `id`, `created_at`, `updated_at`, `targets`, `inventory`).
|
||||
- **Relationship fields**: SQLModel `Relationship()` fields are excluded from OpenAPI schema. Added manually: `MedicationEntry.usage_history`, `Routine.steps`, `RoutineStep.product`, `ProductInventory.product`, `Product.inventory` (with augmented `ProductInventory`).
|
||||
- **Manual types**: `PriceTierSource`, `ShoppingPriority` — inline literals in backend, not named in OpenAPI.
|
||||
- **Canonical import**: Always `import type { ... } from '$lib/types'` — never import from `$lib/api/generated` directly.
|
||||
|
||||
### When to regenerate
|
||||
|
||||
- After adding/modifying backend models or response schemas.
|
||||
- After adding/modifying API endpoints that change the OpenAPI spec.
|
||||
- After updating the bridge file, run `pnpm check` to verify type compatibility.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue