Foundation for the upcoming email-based invite and password-reset flows.
- IEmailSender abstraction with SmtpEmailSender (MailKit 4.16) and a
LoggingEmailSender fallback used automatically when SMTP is unconfigured
so local dev works without a real SMTP server.
- Fixed-window rate limits keyed by remote IP: 10 / 15 min on /login,
5 / hour on /register. Returns 429 with Retry-After. Bypassed in the
Testing environment so the existing integration suite is unaffected.
- New env vars (SMTP_*, APP_BASE_URL) plumbed through docker-compose
and documented in .env.example.
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>