# Local family dashboard admin CRUD + PWA hardening

Use after the task/ledger/calendar/benefits phases of a local family dashboard when the next blueprint steps require admin maintenance screens, iPad PWA installability, and family-operations hardening.

## Admin auth + CRUD pattern

1. **Protect every admin route**
   - Keep child-facing/read endpoints public only when intentionally safe.
   - Require a short-lived admin session token for `/api/admin/*` routes via a header such as `X-Admin-Session`.
   - Store only a token hash server-side; return the raw token only once at login.
   - Use a simple PIN auth model for MVP when the blueprint says no full role/user system.
   - Store the PIN only as a salted password hash (e.g. PBKDF2). Never print or seed a cleartext PIN beyond placeholder/local dev docs.
   - SQLite often round-trips datetimes as offset-naive; compare session expiry using consistently naive UTC or consistently aware UTC to avoid `can't compare offset-naive and offset-aware datetimes`.

2. **CRUD MVP scope discipline**
   - For child dashboards, admin CRUD usually means: children, task templates, benefits, manual coin transactions, exams, simple schedule days/blocks, special days, and app settings.
   - Implement small, tablet-friendly forms first; do not build drag-and-drop or complex week matrices unless the blueprint explicitly asks.
   - Prefer soft-deactivation (`active=false`) for task templates/benefits so historical task instances and redemption ledgers remain explainable.
   - Manual negative coin bookings must require a comment; positive manual bookings may use a default comment but should still be auditable.
   - Make all mutations survive reload: write real DB rows, then verify by re-reading after an app/db re-init path when tests support it.

3. **Frontend admin UX**
   - Add a dedicated Admin view instead of hiding maintenance in child-facing views.
   - If not authenticated, show only PIN login and no admin data.
   - Store the admin session in local browser storage only for local MVP convenience; clear it on logout and when admin requests fail.
   - Invalidate dashboard/benefit/admin queries after every admin mutation so child-facing summaries reflect changes.
   - Keep touch targets at iPad size; admin forms are for adults, but still used on the same tablet.

## PWA + iPad optimization pattern

1. **PWA essentials**
   - Add `manifest.webmanifest` with `display: standalone`, `orientation: landscape-primary`, theme/background colors, and 192/512 icons.
   - Add Apple metadata in `index.html`: `apple-mobile-web-app-capable`, title, status bar style, `viewport-fit=cover`, `apple-touch-icon`.
   - Provide a real `apple-touch-icon.png`; SVG-only icons are not enough for iPad Home Screen reliability.
   - Register a service worker for app-shell caching and a friendly offline page. Do not overclaim offline sync unless API data is explicitly cached/merged.

2. **Offline and install UX**
   - Keep `/api/*` network-first/no-cache in the service worker unless a real sync strategy exists.
   - Show a friendly backend/network offline banner in the app; also provide `/offline.html` for navigation fallback.
   - Show an iPad install hint when not in standalone mode; hide it in `display-mode: standalone`.

3. **iPad acceptance checks**
   - Preserve `body { min-width: 1024px; overflow-x: hidden; }` or an equivalent no-horizontal-scroll strategy for iPad landscape.
   - Add safe-area padding using `env(safe-area-inset-*)` at the shell level.
   - For portrait, a friendly “rotate to landscape” banner is acceptable for a landscape-first dashboard.
   - Verify built assets exist and are served: `/manifest.webmanifest`, `/sw.js`, `/offline.html`, and touch icons.
   - Browser-smoke the running Docker/Vite app and check console errors, not just `npm run build`.

## Verification checklist

- Backend tests cover: admin login/logout/session required, protected admin routes return 401 without a token, CRUD mutation persists, negative manual coin booking requires a comment.
- Frontend build passes TypeScript.
- Manifest JSON parses and contains standalone + landscape settings.
- PWA files exist in built/served app.
- Docker Compose smoke includes backend health, frontend HTTP 200, manifest/service-worker/offline asset HTTP 200, and container status.
- README/docs include iPad Home Screen setup and Tailscale Serve notes if local Tailnet access is part of the blueprint.
