# Local family dashboard admin auth + CRUD MVP pattern

Use for local family/PWA dashboards after the child-facing Home/Todo, calendar/exams, benefits, and ledger flows exist and the next phase is a PIN-protected admin area with pragmatic tablet-friendly CRUD.

## Scope discipline

- Build the admin MVP strictly as simple forms and lists; do not add drag-and-drop or a complex weekly matrix in the first pass.
- Keep the admin surface behind a short-lived session token. Do not expose admin list/mutation endpoints without the session header.
- The initial PIN may be seeded from environment/config, but only a PBKDF2 hash belongs in the database. Never return or log the PIN.
- Keep role/user systems out of the MVP unless the blueprint explicitly asks for them.

## Backend pattern

1. Add an `AdminSession` table with `token_hash`, `username`, `created_at`, `expires_at`, and `revoked_at`.
2. Implement auth endpoints:
   - `POST /api/admin/auth/login` verifies the PIN and returns an opaque token plus expiry.
   - `GET /api/admin/auth/me` verifies the token and returns a minimal authenticated status.
   - `POST /api/admin/auth/logout` revokes the token.
3. Protect admin routes with an `X-Admin-Session` header dependency.
4. With SQLite/SQLModel, be careful comparing datetimes loaded from SQLite: they may come back timezone-naive even if created from timezone-aware values. Normalize consistently before comparing `expires_at` with `now`.
5. CRUD MVP endpoints should cover the blueprint surface, usually:
   - children: list/update;
   - task templates: list/create/update/deactivate;
   - benefits: list/create/update/deactivate;
   - manual coin booking;
   - exams CRUD or reuse existing protected exam routes;
   - special days CRUD;
   - settings list/update;
   - simple schedule day/block upserts, not a full matrix.
6. Prefer soft-deactivation (`active=false`) for seeded task templates and benefits so historical task instances/redemptions remain explainable.
7. Manual coin deductions (`amount < 0`) must require a non-empty comment. Keep the ledger immutable via `CoinTransaction`, not a mutable balance.

## Frontend pattern

- Add an Admin nav item that opens a PIN gate when no token is present.
- Store the opaque admin token in browser local storage only if the app is local/private and the blueprint accepts that MVP trade-off; remove it on logout.
- Send `X-Admin-Session` for every admin fetch/mutation.
- Make forms tablet-friendly: large touch targets, card layout, required field validation, and explicit disabled states.
- For this user's FamilyDashboard/iPad workflows, keep the admin area as an operations cockpit, not a duplicate of the child dashboard: hide the morning/status timeline in Admin; do not surface child-name or coin-name editing unless explicitly requested; prioritize exam creation, coin history, and task-template management.
- Optimize exam creation around parent language: `Auswahl Kind`, `Prüfung-Name`, `Detailinfos`, `Prüfungs-Datum`; then create the calendar entry and learning ToDos up to the exam date. If the user says “daily”, prefer one study task per school day until the exam over a fixed small `study_sessions` default.
- Task template management should be one simple list with activate/deactivate/delete controls and an add form that can target Emilia, Valerie, or both. Keep historical instances explainable with soft-deactivation.
- Add per-child coin ledger/history in Admin so the parent can see balance changes from bonus tasks, penalties for missed required tasks, reversals, redemptions, and manual adjustments.
- After admin mutations, invalidate dashboard, calendar, benefits, and admin queries so changes survive reload and show up immediately.
- Keep forms intentionally narrow: a few useful MVP actions beat a spreadsheet pretending to be an app.

## Testing strategy

- Tests should prove admin routes return 401 without login.
- Test correct PIN login, `/me`, logout, and post-logout rejection.
- Assert the PIN hash is not the raw PIN and starts with the expected hash scheme.
- Test CRUD persistence after re-running idempotent seed/init code.
- Test manual coin deduction without comment returns validation error, while plus/minus bookings update the ledger.
- Add API smoke covering: login → child edit → template create → benefit create → manual coin booking → setting update.

## Docker/smoke acceptance

A complete delivery should include:

- backend unit/API tests;
- frontend production build;
- API smoke of admin auth and at least one CRUD route;
- Docker Compose build/start;
- backend health, frontend HTTP 200, and an admin protected endpoint returning 401 without a session.
