Commit Graph

2 Commits

Author SHA1 Message Date
Josh Rogers 9b2db931ee Scope all data access by FamilyId for multi-tenant isolation
Adds FamilyMembership join (UserId, FamilyId, Role) and a non-null
FamilyId FK on Store, ShoppingList, ShoppingListItem, Recipe, and
RecipeIngredient. FamilyId is denormalized on items/ingredients so the
tenant filter is a single column predicate without joins. Store name
uniqueness is now scoped per family.

JWT issuance stamps a family_id claim; ClaimsPrincipalExtensions exposes
GetFamilyId(). Register validates the supplied invite code against
Family.InviteCode (replacing the env-var equality check) and writes a
FamilyMembership row. OnTokenValidated rejects requests whose user has
been removed from the claimed family since login.

Every endpoint filters by FamilyId on read and stamps it on write.
Cross-family storeId references on list create/update return 400. The
SignalR hub verifies list ownership on JoinList and uses a per-family
overview group, so cross-tenant fan-out is structurally impossible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:05:23 -05:00
Josh Rogers 48d30df07b Initial commit: YesChef family shopping list and recipe app
Backend (.NET 10 minimal API):
- Vertical slice architecture with feature folders
- Postgres via EF Core with initial migration
- JWT auth with family invite code registration
- REST endpoints for stores, shopping lists, items, recipes
- SignalR hub for real-time list collaboration (per-list groups
  and lists-overview group for live list creation/archival/progress)
- Multi-stage Dockerfile

Frontend (SvelteKit + Svelte 5 runes, Tailwind v4):
- Mobile-first PWA with web manifest and service worker
- Bottom-nav layout, login/register, lists overview, list detail,
  stores management, recipes (list/create/detail with add-to-list)
- SignalR client with reference-counted connection
- Real-time updates on both lists overview and list detail pages

Infrastructure:
- docker-compose.yml with postgres, backend, frontend services
  and Traefik labels for path-based routing (/api, /hubs to backend)
- .env.example with required config

End-to-end tests (Playwright):
- test-e2e.mjs: single-user flow (auth, stores, lists, items, recipes)
- test-e2e-multiuser.mjs: two-user real-time sync coverage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 19:32:39 -05:00