# FamilyDashboard daily knowledge quiz + school-friendly math prompts

Session learning from adding an `Allgemeinwissen des Tages` quiz below the daily math quiz.

## Trigger
Use this when the user asks for FamilyDashboard child learning widgets, a new daily quiz type, quiz coin rewards, quiz difficulty settings, or math prompt wording for Swiss primary-school children.

## Backend pattern for a new daily quiz
- Mirror the stable snapshot pattern used by DailyMath/DailyPhrase:
  - Pool table, e.g. `DailyKnowledgeQuestion` with `level`, `category`, `question`, 3 answer fields, `explanation`, `active`.
  - Assignment table with `UniqueConstraint(child_id, day)` and a full snapshot of the selected question/answers/explanation.
  - Attempt table with `UniqueConstraint(child_id, day, question_id)` so reloads preserve answered state.
- Assignment selection should be deterministic per `child_id + date + level`, but store the snapshot so later pool/level edits do not change an already assigned day.
- Add an idempotent SQLite migration for any new `ChildSettings` columns. For this feature: `knowledge_quiz_level`.
- Seed child-specific defaults without overwriting intentional existing settings:
  - Valerie: `knowledge_quiz_level = 2`
  - Emilia: `knowledge_quiz_level = 3`
- Seed the app setting `knowledge_quiz_coin_value = 1` so the reward is configurable even if MVP copy says `+1`.

## Coin reward pattern
- Correct answer creates an append-only `CoinTransaction`:
  - `transaction_type = earned`
  - comment: `Allgemeinwissen des Tages richtig beantwortet`
  - idempotency key: `daily-knowledge-quiz:{child_id}:{date}:{question_id}`
- Wrong answer creates no coin transaction.
- Duplicate/reload answer returns `idempotent: true` and never books a second coin.
- Response should include: `correct`, `correct_answer`, `coin_awarded`, `coin_value`, `idempotent`, `attempt`.

## API endpoints
- `GET /api/daily-knowledge?date=YYYY-MM-DD` — non-quiz/full data.
- `GET /api/daily-knowledge/quiz?date=YYYY-MM-DD` — hides correct answer until answered.
- `POST /api/daily-knowledge/quiz-answer` with `child_id`, `date`, `question_id`, `selected_answer`.

## Frontend pattern
- Add `DailyKnowledgeWidget.tsx`, copied structurally from `DailyMathWidget`/`DailyPhraseWidget`:
  - Header: `Allgemeinwissen des Tages`
  - Badge: `+{coin_value} 🪙`
  - one card per child, 3 answer buttons, explanation after answer.
- Render order on Home should remain clean:
  1. Date switcher
  2. Timeline
  3. Task boards
  4. Daily phrase / quiz of the day
  5. Daily math
  6. Daily knowledge
- On successful answer, invalidate these query prefixes:
  - `daily-knowledge-quiz`
  - `dashboard`
  - `coins`
  - `coin-ledger`
  - `admin`, `ledger` (or the current admin ledger query key)

## Admin pattern
- Extend `ChildSettingsUpdate`, admin child serialization, and frontend child settings types with the new level field.
- In `Lernen / Quiz`, keep one compact area with:
  - language quiz language + level,
  - math quiz level,
  - knowledge quiz level,
  - coin values for language, math, and knowledge.
- Level changes affect new assignments only; existing assignment snapshots stay stable.

## Child-safe content guidelines
- Prefer useful, age-appropriate Swiss primary-school knowledge: Switzerland/cantons/municipalities, nature, body basics, money/saving/alltag, time/calendar, media literacy, social situations, environment/energy, simple history, reading comprehension, logic.
- Avoid politics fights, fear topics, sexual topics, violence, religion/ideology, medical advice, adult finance/trading, and overly obscure trivia.
- For MVP, 20 Level 2 + 20 Level 3 questions is the minimum acceptable pool; better is 60–100 across Levels 1–4.

## Swiss primary math wording pitfall
- Do not show fractional prompts like `1/2 von 48 = ?` for the MVP daily math quiz.
- Use Swiss school-friendly operators:
  - division: `48 : 2 = ?`
  - multiplication: `7 × 8 = ?`
- If old unattempted/current assignments contain `1/{denom} von X = ?`, add a gentle migration/display transform to show `X : {denom} = ?` without deleting attempts or coin transactions.

## Timeline school-start marker polish
- For Home timeline, keep `school_start` anchored horizontally to the visual end of the `Loslaufen/Schulweg` range.
- If the school marker appears visually too high, adjust only `.timeline-marker.timeline-kind-school_start` CSS; do not move sleep/moon.
- Good corrective pattern from this session:
  - increase `top` for `school_start` only;
  - use a less aggressive translate, e.g. `transform: translate(-50%, -42%)` depending on the current CSS;
  - hide the label in `display-iconOnly` so cramped layouts show only 🏫.

## Verification checklist
- Backend focused tests:
  - math generator never emits `1/2 von` / `1/4 von`; division uses `:`.
  - daily knowledge assignment stable for same child/day.
  - correct answer books exactly one coin.
  - wrong answer books no coin.
  - duplicate answer is idempotent and books no second coin.
  - child level controls selected question level.
- Full verification:
  - `pytest` in backend container.
  - frontend `npm run build` in container.
  - Playwright smoke.
  - `docker compose build backend frontend` and `docker compose up -d backend frontend` (never `down -v`).
  - health: `curl -fsS http://localhost:8000/api/health` and `curl -I http://localhost:5173`.

## Safety reminders
- Never delete the productive DB.
- Never run `docker compose down -v`.
- Never mutate/delete old `CoinTransaction` rows or old quiz attempts.
- Leave unrelated untracked backup files alone unless the user explicitly asks to clean them.
