Files
breakpilot-lehrer/docs-src/services/schulkalender/architecture.md
T
Benjamin Admin 77c720e2df
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 50s
CI / test-go-edu-search (push) Successful in 45s
CI / test-python-klausur (push) Failing after 3m50s
CI / test-python-agent-core (push) Successful in 36s
CI / test-nodejs-website (push) Successful in 49s
Document Stundenplan + Schulkalender end-of-session state
- CLAUDE.md gets a new section summarising the two feature strands,
  pitfalls (Timefold name, JSX quotes, LOC budget), the auth/messaging
  outsourcing, and pointers to the three memory files for next session.
- docs-src/services/schulkalender/ — 5 MkDocs pages mirroring the
  stundenplan structure: index, architecture, holidays, parent-flow,
  notifications. Each with DB tables, endpoints, and the dispatch
  payload contract for the colleague's Matrix/Email services.
- mkdocs.yml gains the Schulkalender nav entry under Services.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 18:41:31 +02:00

2.7 KiB

Architektur

Datenmodell

Phase 9a — Kalender-Stammdaten

Tabelle Inhalt Owner
cal_public_event Ferien + Feiertage (region, type, name, start, end) global (alle Bundeslaender)
cal_school_config Bundesland-Auswahl + Schuljahr-Daten 1 row per user_id

Phase 9b — Schul-Events

Tabelle Inhalt Owner
cal_school_event Titel + Typ + Datum/Zeit + affected_class_ids + Notification-Flags created_by_user_id

Event-Typen (CHECK constraint): fortbildung, schulfeier, klassenfahrt, projekttag, eltern_info, andere.

Phase 9c — Parent-Accounts

Tabelle Inhalt
parent_account Email + preferred_language, UNIQUE pro (Lehrer, Email)
parent_child Vorname/Nachname + FK auf tt_class
parent_magic_link Einmal-Token (SHA-256 in DB), expires_at 7 Tage
parent_session Browser-Session-Token (SHA-256 in DB), expires_at 30 Tage

Phase 9d — Notifications

Tabelle Inhalt
notification_log Idempotenz: UNIQUE(event_id, lead_days, audience, channel)

Auth-Modell

Zwei voneinander unabhaengige Auth-Wege:

  1. Lehrer: JWT in Authorization-Header (oder Dev-Bypass mit Default-User wenn ENVIRONMENT != "production"). Routen unter /api/v1/school/....
  2. Eltern: Session-Cookie bp_parent_session (HttpOnly, SameSite=Lax), gesetzt vom /api/v1/parent/auth/redeem Endpoint. ParentSessionMiddleware resolved Cookie → parent_account.

Eltern sehen nie Daten anderer Eltern. Privacy-Check via ChildBelongsToParent in jedem GET, Plus Filterung der Lessons gegen tt_solution des einladenden Lehrers.

Bundesland-Wizard

Erster Aufruf von /schulkalender → kein cal_school_configBundeslandWizard UI → POST /calendar/config mit {bundesland: "DE-NI"} → MonthView lädt für die naechsten ~6 Wochen.

Schuljahres-Rollover

POST /calendar/school-year-rollover (optional {new_year_start, new_year_end}):

  1. DELETE FROM tt_class WHERE grade_level >= 13 (Abschlusskohorte)
  2. UPDATE tt_class SET grade_level = grade_level + 1
  3. UPDATE cal_school_config SET school_year_start/end = ...

Alles in einer Transaction. Stundenplan-Lehrer-Faecher-Raum-Bestand bleibt unangetastet.

Auth + Messaging outsourced

Production-Auth, Matrix-Bridge und Email-Gateway werden vom Kollegen gepflegt — siehe globale Memory stundenplan_auth_and_messaging.md. Wir definieren nur:

  • Dispatch-Payload-Struct (siehe notifications.md)
  • Env-Vars MATRIX_SERVICE_URL, EMAIL_SERVICE_URL (leer = Stub-Mode)
  • Endpoint-Vertrag (POST mit JSON-Body, HTTP 2xx = sent)