Spec reflection and update
This commit is contained in:
parent
d90ffddcd7
commit
adb2fc1bae
1 changed files with 11 additions and 12 deletions
|
|
@ -1,12 +1,9 @@
|
||||||
## 0. Current State (Nov 1, 2025)
|
## 0. Current State (Nov 1, 2025)
|
||||||
|
|
||||||
All core features are migrated to multi-tenancy with path-scoped endpoints and token-based auth. The codebase no longer uses the `X-Household-Slug` header. Tests and type checks are fully green.
|
|
||||||
## 0. Current State (Nov 1, 2025)
|
|
||||||
|
|
||||||
All core features are migrated to multi-tenancy with path-scoped endpoints and token-based auth. The codebase no longer uses the `X-Household-Slug` header. Tests and type checks are fully green.
|
All core features are migrated to multi-tenancy with path-scoped endpoints and token-based auth. The codebase no longer uses the `X-Household-Slug` header. Tests and type checks are fully green.
|
||||||
|
|
||||||
Status of tests and typing
|
Status of tests and typing
|
||||||
- All tests pass: 27 files, 46 tests (slug-only routes; memory history fallback in non-browser envs; unauthenticated and refresh-401 guard redirects covered).
|
- All tests pass: 28 files, 45 tests (slug-only routes; memory history fallback in non-browser envs; unauthenticated and refresh-401 guard redirects covered).
|
||||||
- `tsc` and `vue-tsc` pass with no errors.
|
- `tsc` and `vue-tsc` pass with no errors.
|
||||||
|
|
||||||
# Frontend Specification: Household Multi-Tenancy (v2)
|
# Frontend Specification: Household Multi-Tenancy (v2)
|
||||||
|
|
@ -126,7 +123,9 @@ What exists now
|
||||||
- `src/router/index.ts`: slug-only nesting under `/:householdSlug/...`; public routes include `/create-account`, `/welcome`, and `/invitations/accept`.
|
- `src/router/index.ts`: slug-only nesting under `/:householdSlug/...`; public routes include `/create-account`, `/welcome`, and `/invitations/accept`.
|
||||||
- Guard fetches households, redirects root `/` to the first household's `mealplan`, and uses memory history in tests (hash in browser).
|
- Guard fetches households, redirects root `/` to the first household's `mealplan`, and uses memory history in tests (hash in browser).
|
||||||
- SDK/API
|
- SDK/API
|
||||||
- `src/api/sdk.ts`: recipes, meals, and shopping are migrated to `/api/v1/households/{householdSlug}/...` typed endpoints. Person endpoints removed; parse uses a temporary raw fetch endpoint until typed coverage is available.
|
- `src/api/sdk.ts`: recipes, meals, and shopping are migrated to `/api/v1/households/{householdSlug}/...` typed endpoints. Person endpoints removed. Parse endpoints are now typed:
|
||||||
|
- `POST /api/v1/households/{householdSlug}/recipes/parse-from-url` returns `RecipeCreate-Output`; SDK constructs a minimal `RecipeOut` for decoding (id/createdById set to -1).
|
||||||
|
- `GET /api/v1/households/{householdSlug}/ingredients/parse?lines=...` returns `Ingredient[]`.
|
||||||
- `src/api/client.ts`: Authorization header provider only; household header injection removed.
|
- `src/api/client.ts`: Authorization header provider only; household header injection removed.
|
||||||
- Domain & UI
|
- Domain & UI
|
||||||
- Member arrays (`chefs`, `consumers`, `cleanup`) normalized to `MemberRef` `{ id, displayName }` with decoders handling legacy shapes gracefully.
|
- Member arrays (`chefs`, `consumers`, `cleanup`) normalized to `MemberRef` `{ id, displayName }` with decoders handling legacy shapes gracefully.
|
||||||
|
|
@ -136,7 +135,7 @@ What exists now
|
||||||
- MyShopping: page remains as in master with editable panel backed by legacy v1 stubs (`getMyShoppingList/saveMyShoppingList`) pending backend ad-hoc item endpoints.
|
- MyShopping: page remains as in master with editable panel backed by legacy v1 stubs (`getMyShoppingList/saveMyShoppingList`) pending backend ad-hoc item endpoints.
|
||||||
|
|
||||||
Status of tests and typing
|
Status of tests and typing
|
||||||
- All tests pass: 27 files, 46 tests.
|
- All tests pass: 28 files, 45 tests.
|
||||||
- `tsc` and `vue-tsc` pass with no errors.
|
- `tsc` and `vue-tsc` pass with no errors.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -171,12 +170,12 @@ Progress Log (Nov 1, 2025)
|
||||||
- Backend updated OpenAPI and codegen has been run:
|
- Backend updated OpenAPI and codegen has been run:
|
||||||
- Many endpoints are now path-scoped with `{householdSlug}` (recipes, meals, shopping, invitations (create), whoami).
|
- Many endpoints are now path-scoped with `{householdSlug}` (recipes, meals, shopping, invitations (create), whoami).
|
||||||
- Auth endpoints (login/register/refresh/logout) are fully typed; `refresh` returns only `{ accessToken, tokenType }`.
|
- Auth endpoints (login/register/refresh/logout) are fully typed; `refresh` returns only `{ accessToken, tokenType }`.
|
||||||
- Completed migration to typed path parameters; header injection removed; only small raw fetch helpers remain for endpoints not yet in OpenAPI (parse only).
|
- Completed migration to typed path parameters; header injection removed; only Google OAuth remains using raw fetch until typed endpoints are available.
|
||||||
|
|
||||||
Refinements (Nov 1, 2025, later):
|
Refinements (Nov 1, 2025, later):
|
||||||
- Lint hardening: removed remaining `as any` and unsafe assertions across SDK/decoders.
|
- Lint hardening: removed remaining `as` and unsafe assertions across SDK/decoders.
|
||||||
- decodeRecipe/decodeMeal simplified to use concrete OpenAPI shapes and defaults; legacy Person normalization removed.
|
- decodeRecipe/decodeMeal simplified to use concrete OpenAPI shapes and defaults; legacy Person normalization removed.
|
||||||
- Raw parse endpoints now use small runtime guards and normalize to strict RecipeOut before decoding.
|
- Parse flows are fully typed; SDK constructs a minimal RecipeOut for decoding where needed (no ad-hoc property guards).
|
||||||
- UI polish: MemberList and EditMealPage CSS class names unified (person-* → member-*). Login page shows a Google sign-in button wired to the placeholder handler.
|
- UI polish: MemberList and EditMealPage CSS class names unified (person-* → member-*). Login page shows a Google sign-in button wired to the placeholder handler.
|
||||||
|
|
||||||
Google OAuth (Nov 1, 2025, later):
|
Google OAuth (Nov 1, 2025, later):
|
||||||
|
|
@ -226,7 +225,7 @@ SDK
|
||||||
- `POST /api/v1/households/{householdSlug}/shopping/current/meals/me` — request a meal.
|
- `POST /api/v1/households/{householdSlug}/shopping/current/meals/me` — request a meal.
|
||||||
- `DELETE /api/v1/households/{householdSlug}/shopping/current/meals/{meal_id}` — unrequest a meal.
|
- `DELETE /api/v1/households/{householdSlug}/shopping/current/meals/{meal_id}` — unrequest a meal.
|
||||||
- `POST /api/v1/households/{householdSlug}/shopping/current/ingredients` — request an ingredient (by id) for shopping.
|
- `POST /api/v1/households/{householdSlug}/shopping/current/ingredients` — request an ingredient (by id) for shopping.
|
||||||
- Persons and parse endpoints are still raw until they are added to the OpenAPI.
|
- Google OAuth endpoints remain raw until they are added to the OpenAPI.
|
||||||
|
|
||||||
UI
|
UI
|
||||||
- Login Page: Refactored to show email/password form; Google sign-in planned. Link to Create Account added.
|
- Login Page: Refactored to show email/password form; Google sign-in planned. Link to Create Account added.
|
||||||
|
|
@ -245,12 +244,12 @@ Tests
|
||||||
|
|
||||||
## OpenAPI & Typing Considerations (Updated)
|
## OpenAPI & Typing Considerations (Updated)
|
||||||
|
|
||||||
- Avoid `any`/`unknown` in app code; keep all API calls typed via `openapi-fetch`.
|
- Avoid `any`/`unknown` in app code; keep all API calls typed via `openapi-fetch`. Do not use ad-hoc property guards (e.g., hasProp/Reflect) in the SDK; rely on generated types plus decoders at the boundary.
|
||||||
- Household scoping: use typed path params (`{ params: { path: { householdSlug } } }`); do not mutate path strings.
|
- Household scoping: use typed path params (`{ params: { path: { householdSlug } } }`); do not mutate path strings.
|
||||||
- Auth refresh: returns `{ accessToken, tokenType }`. After refresh, call user/household endpoints to populate app state. Use `whoami` to validate the active route’s slug when needed.
|
- Auth refresh: returns `{ accessToken, tokenType }`. After refresh, call user/household endpoints to populate app state. Use `whoami` to validate the active route’s slug when needed.
|
||||||
- Cleanup/migration tasks:
|
- Cleanup/migration tasks:
|
||||||
1) Remove X-Household-Slug header injection in `api/client.ts` and refactor services to accept `householdSlug` via typed params. (Completed)
|
1) Remove X-Household-Slug header injection in `api/client.ts` and refactor services to accept `householdSlug` via typed params. (Completed)
|
||||||
2) Replace temporary raw fetch calls with generated typed endpoints where available: invitations and members listing are now typed; migrate usages. Persons and parse remain raw for now.
|
2) Replace temporary raw fetch calls with generated typed endpoints where available: invitations and members listing are now typed; parse is now typed; Google OAuth remains raw for now.
|
||||||
3) Integrate the new `POST /shopping/current/ingredients` endpoint into the SDK (`requestIngredient(ingredientId: number)`) and expose via `useShopping`; refactor `MyShoppingPage.vue` accordingly and remove legacy stubs. (SDK + composable done; UI refactor next)
|
3) Integrate the new `POST /shopping/current/ingredients` endpoint into the SDK (`requestIngredient(ingredientId: number)`) and expose via `useShopping`; refactor `MyShoppingPage.vue` accordingly and remove legacy stubs. (SDK + composable done; UI refactor next)
|
||||||
4) Identity: `User` remains the primary identity. `Person` has been removed; meal-related UIs use `MemberRef` exclusively.
|
4) Identity: `User` remains the primary identity. `Person` has been removed; meal-related UIs use `MemberRef` exclusively.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue