Document Stundenplan + Schulkalender end-of-session state
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

- 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>
This commit is contained in:
Benjamin Admin
2026-05-22 18:41:31 +02:00
parent 89011d64f7
commit 77c720e2df
7 changed files with 371 additions and 0 deletions
@@ -0,0 +1,71 @@
# Ferien + Feiertage
## Quelle
[openholidaysapi.org](https://openholidaysapi.org) — EU-Initiative, MIT-Lizenz
fuer den API-Code, ODbL fuer die Daten. Liefert sowohl `PublicHolidays` als
auch `SchoolHolidays` je Bundesland mit ISO-Codes `DE-BW`, `DE-BY`, ...
## Build-Time-Snapshot
Statt zur Laufzeit zu pollen wird ein JSON-Snapshot committed:
```bash
bash scripts/calendar-snapshot.sh 2026 2030
```
Schreibt nach `school-service/internal/seed/calendar_holidays.json`. Das
Dockerfile kopiert die Datei ins Image; bei jedem Container-Start importiert
`CalendarService.SeedFromSnapshot()` die Eintraege idempotent (UNIQUE auf
region, event_type, name_de, start_date).
**Stand 2026-05-22:** 854 Events fuer alle 16 Bundeslaender × 3 Schuljahre.
## Aktualisierungs-Workflow
1. Jaehrlich (z.B. im Mai vor neuem Schuljahr):
```bash
bash scripts/calendar-snapshot.sh 2027 2031
```
2. Diff im Git pruefen — sollte nur neue Eintraege haben, nicht alte ueberschreiben.
3. Commit + push + Container-Rebuild.
4. Beim ersten Boot werden neue Eintraege in `cal_public_event` eingefuegt; bestehende bleiben.
## API
```
GET /api/v1/school/calendar/holidays?region=DE-NI&from=2026-08-01&to=2027-07-31
```
Liefert Array sortiert nach `start_date`. Beispiel-Antwort:
```json
[
{"id":"…","region":"DE-NI","event_type":"school_holiday","name_de":"Sommerferien","start_date":"2026-07-02","end_date":"2026-08-12"},
{"id":"…","region":"DE-NI","event_type":"public_holiday","name_de":"Tag der Deutschen Einheit","start_date":"2026-10-03","end_date":"2026-10-03"},
...
]
```
## Format-Mapping (Snapshot-Script)
OpenHolidaysAPI gibt:
```json
{"id":"...","startDate":"2026-10-03","endDate":"2026-10-03","type":"Public",
"name":[{"language":"DE","text":"Tag der Deutschen Einheit"}]}
```
`scripts/calendar-snapshot.sh` normalisiert via jq:
```json
{"region":"DE-NI","event_type":"public_holiday","name_de":"Tag der Deutschen Einheit",
"name_en":null,"start_date":"2026-10-03","end_date":"2026-10-03"}
```
## Lizenz-Compliance
- API-Code: MIT
- Daten: ODbL (Open Database License)
Beides ist fuer kommerzielle Nutzung erlaubt. Die Quelle muss in einer
Lizenz-Aufstellung (SBOM) genannt werden — bereits in
`sbom/stundenplan/README.md` dokumentiert.