feat(shopping-v2): add household-scoped meal request/unrequest; tests and OpenAPI updated

This commit is contained in:
jableader 2025-11-01 15:42:59 +11:00
parent 807f3efaaa
commit 86e0ea3111

View file

@ -2,6 +2,9 @@
- GET `/api/v1/households/{householdSlug}/shopping/{listId}` returning purchased list + lookups scoped to household; cross-household returns 404. - GET `/api/v1/households/{householdSlug}/shopping/{listId}` returning purchased list + lookups scoped to household; cross-household returns 404.
- POST `/api/v1/households/{householdSlug}/meals/{mealId}/consumed` marks a meal consumed within the household; validates timezone on provided `consumedDate`; clears outstanding meal requests only within that household. - POST `/api/v1/households/{householdSlug}/meals/{mealId}/consumed` marks a meal consumed within the household; validates timezone on provided `consumedDate`; clears outstanding meal requests only within that household.
- Tests: `tests/test_meals_consumed_v2.py` validates scoping (requests cleared in same household, unaffected in other household). PASS. - Tests: `tests/test_meals_consumed_v2.py` validates scoping (requests cleared in same household, unaffected in other household). PASS.
- POST `/api/v1/households/{householdSlug}/shopping/current/meals/me` requests a meal under the household scope; visible only within that household in GET current.
- DELETE `/api/v1/households/{householdSlug}/shopping/current/meals/{mealId}` unrequests the meal (scoped) and returns `{ ok: true }`.
- Tests: `tests/test_shopping_request_meal_v2.py` validates request/unrequest isolation across households. PASS.
- Tests: `tests/test_shopping_household_v2.py` verifies isolation of outstanding items; `tests/test_shopping_list_by_id_v2.py` verifies list-by-id scoping; `tests/test_shopping_purchase_v2.py` covers scoped purchase (PASS). - Tests: `tests/test_shopping_household_v2.py` verifies isolation of outstanding items; `tests/test_shopping_list_by_id_v2.py` verifies list-by-id scoping; `tests/test_shopping_purchase_v2.py` covers scoped purchase (PASS).
# Backend Specification: Household Multi-Tenancy (v2) # Backend Specification: Household Multi-Tenancy (v2)
@ -237,9 +240,9 @@ Impact on existing routes (exact files to refactor):
- GET `/api/v1/households/{householdSlug}/shopping/{listId}` returning purchased list + lookups scoped to household; cross-household returns 404. - GET `/api/v1/households/{householdSlug}/shopping/{listId}` returning purchased list + lookups scoped to household; cross-household returns 404.
- POST `/api/v1/households/{householdSlug}/shopping` to purchase list items scoped to household; validates invariants and updates outstanding requests. - POST `/api/v1/households/{householdSlug}/shopping` to purchase list items scoped to household; validates invariants and updates outstanding requests.
- Scoped helpers in `shopping/repository.py` and `shopping/__init__.py` filter by `household_id` (find items, load list, purchased ingredients, and purchase_scoped). - Scoped helpers in `shopping/repository.py` and `shopping/__init__.py` filter by `household_id` (find items, load list, purchased ingredients, and purchase_scoped).
- Tests: `tests/test_shopping_household_v2.py` (current isolation), `tests/test_shopping_list_by_id_v2.py` (list-by-id scoping), `tests/test_shopping_purchase_v2.py` (scoped purchase). PASS. - Tests: `tests/test_shopping_household_v2.py` (current isolation), `tests/test_shopping_list_by_id_v2.py` (list-by-id scoping), `tests/test_shopping_purchase_v2.py` (scoped purchase), `tests/test_shopping_request_meal_v2.py` (request/unrequest). PASS.
- Notes: Normalized Ingredient.preparation to allow NULLs from DB (treated as empty string) to avoid 422 in v2 responses; set purchased_by_id in scoped purchase from JWT user. - Notes: Normalized Ingredient.preparation to allow NULLs from DB (treated as empty string) to avoid 422 in v2 responses; set purchased_by_id in scoped purchase from JWT user.
- ⏳ Update Repositories: ingredients, products to accept `household_id` and filter accordingly; extend meals create/update/consumed/delete and shopping write flows (purchase, requests) with scoping. - ⏳ Update Repositories: ingredients, products to accept `household_id` and filter accordingly; extend meals create/update/delete with scoping.
- ⏳ Update Routers: move/duplicate remaining routers under the household router and wire `household_id` through. - ⏳ Update Routers: move/duplicate remaining routers under the household router and wire `household_id` through.
- **Acceptance**: The same queries as v1, when run under different household slugs and users, return isolated data sets; cross-household access yields 403. - **Acceptance**: The same queries as v1, when run under different household slugs and users, return isolated data sets; cross-household access yields 403.