WIP (unstable): lokaler Cache für Klassenlehrer-Fehlzeiten & Klassenbucheinträge

Nutzer-Feedback: die WebUntis-Berichtszeilen sind starr genug für ein eigenes
Datenmodell, Warnungen sollen sofort da sein statt bei jedem Öffnen neu
abgerufen zu werden - vor allem darf derselbe Bericht nicht mehrfach pro
Stunde abgerufen werden, nur weil die Ansicht mehrfach geöffnet wird (Sorge,
bei WebUntis aufzufallen).

Neue Modelle UntisAbsenceCacheEntry/UntisClassRegisterCacheEntry (1:1 zu den
bestehenden DTOs) + UntisCacheFetchState, bewusst nicht synchronisiert
(gleiches "kein db.OnChange"-Muster wie UntisSnapshotEntry/AnnualPlanEvent) -
jedes Gerät ruft WebUntis selbst ab, die Zeilenzahl wächst übers Schuljahr
gewollt an.

UntisReportCacheService: festes heißes Fenster der letzten 14 Tage, höchstens
stündlich automatisch aufgefrischt; alles Ältere gilt als endgültig und wird
dauerhaft aus dem Cache bedient. Die Entscheidungslogik (Plan) ist als reine,
ohne Repositories/HTTP testbare Funktion ausgelagert. Klassenlehrer-Ansichten
nutzen den Cache-Service statt WebUntisIntegrationService direkt; ein
zusätzlicher Button umgeht die Stundensperre bewusst für manuelle Abrufe.

Noch nicht mit echtem WebUntis-Zugang gegengeprüft (siehe TODO.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 23:10:01 +02:00
co-authored by Claude Sonnet 5
parent 056e864edd
commit 2b29dea824
13 changed files with 639 additions and 18 deletions
+25
View File
@@ -1337,6 +1337,31 @@ eigenen Unterricht abfragt und deshalb mit den regulären Lehrkraft-Rechten funk
ist jetzt optional (`UntisStudent.ExternKey`/`UntisStudentDto.ExternKey``int?`) — betraf auch
den bestehenden WebUntis-Klassenimport in der Kursansicht, der das aber schon immer über
`FirstNotEmpty` beim Weiterimport toleriert hatte und deshalb nicht auffiel.
- [x] **"Klassenlehrer"-Feature — lokaler Cache für Fehlzeiten & Klassenbucheinträge (August 2026):**
Nutzer-Feedback: die Berichtszeilen sind starr genug für ein eigenes Datenmodell, Warnungen
sollen sofort da sein statt bei jedem Öffnen neu abgerufen zu werden, und — wichtigstes Motiv —
derselbe Bericht darf nicht mehrfach pro Stunde abgerufen werden, nur weil die Ansicht mehrfach
geöffnet wird (Sorge, bei WebUntis aufzufallen). Neue Modelle `UntisAbsenceCacheEntry`/
`UntisClassRegisterCacheEntry` (1:1-Abbildung der bestehenden DTOs, `Date` als `int`/yyyyMMdd wie
dort, nicht `DateOnly`, um die LiteDB-`DateTime`-Kind-Tücke zu vermeiden) plus
`UntisCacheFetchState` (ein Datensatz je Klasse+Berichtsart: wann das "heiße" Fenster zuletzt
aufgefrischt wurde, wie weit die "kalte" Historie lückenlos zurückreicht).
**Bewusst nicht synchronisiert**`UntisAbsenceCacheRepository`/`UntisClassRegisterCacheRepository`/
`UntisCacheFetchStateRepository` rufen `db.OnChange` nie auf (Sync ist opt-in pro Repository,
siehe `UntisSnapshotRepository`/`AnnualPlanEventRepository` für dasselbe Muster) — jedes Gerät
ruft WebUntis ohnehin selbst ab, und die Zeilenzahl wächst übers Schuljahr absichtlich an
(gewollte Historie, kein Pruning).
Neuer Service `UntisReportCacheService`: festes heißes Fenster `[heute14, heute]`
(unabhängig vom angefragten Bereich), höchstens stündlich automatisch aufgefrischt (dort kann
sich der Status noch ändern, z. B. "ausstehend" → "entschuldigt"); alles davor gilt als endgültig
und wird, einmal abgerufen, dauerhaft aus dem Cache bedient. Die eigentliche Entscheidungslogik
(`UntisReportCacheService.Plan`) ist bewusst als reine, ohne Repositories/HTTP testbare Funktion
ausgelagert. `ClassTeacherOverviewViewModel`/`ClassTeacherDetailsViewModel` nutzen den Cache-Service
statt direkt `WebUntisIntegrationService`; das "Laden" in den Details respektiert die
Stunden-Sperre, ein zusätzlicher Button "Jetzt wirklich neu abrufen" umgeht sie bewusst
(`forceRefresh: true`) für den Fall, dass man sicher weiß, dass sich etwas geändert hat.
**Zurückgestellt:** Muster-Erkennung/Heuristiken über die gecachten Daten (vom Nutzer als Motiv
für den Cache genannt) — erst sinnvoll, wenn genug Historie im Cache liegt.
### 4.4 Wochen-/Tagesansicht
- [x] **4.4.1** Kalenderansicht über alle Gruppen: Woche und Tag — siehe Nachtrag zu 4.3