Klassenlehrer: Fehlquote nutzt echten WebUntis-Ferienkalender + Sommerferien-Näherung, Diagnose-Logging
CI / build-and-test (push) Canceled after 0s
CI / build-and-test (push) Canceled after 0s
Nutzer-Verifikation deckte auf, dass WebUntis' getHolidays für dieses Konto nie einen Sommerferien-Eintrag liefert (11 Jahre Kontohistorie geprüft, kein einziger Juli-/August-Zeitraum dabei) - vermutlich weil die Sommerferien WebUntis-intern zwischen zwei Schuljahres-Datensätzen liegen statt in einem. Die reine Ferienkalender-Abfrage aus dem letzten Commit kann diese Lücke also nicht schließen: der frühere heuristische Ansatz (frühester Fehlzeiten-Eintrag der Klasse als Näherung für den ersten Unterrichtstag) ist deshalb zusätzlich wieder da, kombiniert mit dem echten Ferienkalender für den Rest des Jahres. Herkunft des Nenners jetzt im Tooltip sichtbar (angenommener Unterrichtsbeginn, abgezogene Ferientage) statt nur intern verrechnet, plus Logging jedes Ferienabrufs (Erfolg oder Fehler) - sonst wäre der falsche Wert wieder unbemerkt geblieben. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1704,30 +1704,45 @@ eigenen Unterricht abfragt und deshalb mit den regulären Lehrkraft-Rechten funk
|
||||
tatsächlichen Sommerferien enden je nach Bundesland/Jahr aber erst Wochen später, und kurz nach
|
||||
Schuljahresbeginn macht diese Restferienzeit einen großen Teil des bis dahin "verstrichenen"
|
||||
Zeitraums aus (rechnerisch: absolut korrekte Fehlzeiten-Zähler, aber ein um mehrere Wochen zu
|
||||
großer Nenner). Erster Fix-Versuch (`EstimateTermStart`, frühester Fehlzeiten-Eintrag der Klasse
|
||||
als Näherung für den ersten Unterrichtstag) kam ohne zusätzlichen WebUntis-Abruf aus, war aber
|
||||
nur eine Näherung. Nutzer-Hinweis: WebUntis kennt den echten Ferienkalender bereits
|
||||
(`getHolidays`-Bericht, in `LehrerApp.WebUntis/WebUntisClient.GetHolidaysAsync` schon
|
||||
implementiert, aber bis dahin nirgends im Desktop verdrahtet) — `EstimateTermStart` durch den
|
||||
echten Kalender ersetzt:
|
||||
- `WebUntisIntegrationService.GetHolidaysAsync` (neuer `UntisHolidayDto`) als dünner Wrapper,
|
||||
gleiches Muster wie `GetSchoolYearsAsync`.
|
||||
- Cache dafür bewusst nicht über die LiteDB-Tabellen von `UntisReportCacheService` (deren
|
||||
heißes/kaltes Fenster ist auf sich laufend ändernde Fehlzeiten/Klassenbucheinträge
|
||||
zugeschnitten) — Ferien ändern sich innerhalb eines Schuljahrs praktisch nie. Stattdessen
|
||||
einfacher tagesgenauer Cache direkt in `WebUntisSettingsService`
|
||||
(`CachedUntisHoliday`-Liste + `HolidaysFetchedAt`, unverschlüsselt, kein Geheimnis anders als
|
||||
iCal-URL/API-Zugangsdaten in derselben Datei). Schlägt der Live-Abruf fehl, wird der zuletzt
|
||||
bekannte Stand weiterverwendet statt die ganze Übersicht mit einem Fehler zu blockieren.
|
||||
- `ClassTeacherOverviewViewModel.CountSchoolWeekdays` (ersetzt `CountWeekdays`) zählt Werktage
|
||||
zwischen Schuljahresbeginn und heute abzüglich aller Ferienzeiträume — behebt damit nicht nur
|
||||
die große Verzerrung kurz nach Schuljahresbeginn, sondern nebenbei auch die bislang akzeptierte
|
||||
kleinere Ungenauigkeit durch Herbst-/Weihnachts-/Osterferien im weiteren Jahresverlauf (oben
|
||||
unter "Trend & Fehlquote" noch als bewusste Vereinfachung dokumentiert — damit erledigt).
|
||||
Reine, ohne ViewModel-Zustand testbare Kernlogik, gleiches Muster wie
|
||||
`DetectWeekdayPatterns`/`DetectLatePatterns`.
|
||||
Neue Abhängigkeit `WebUntisIntegrationService` in `ClassTeacherOverviewViewModel` (bereits als
|
||||
Singleton registriert, nur Konstruktor-Injection ergänzt).
|
||||
großer Nenner). Mehrstufig gelöst, jede Stufe durch Nutzer-Feedback ausgelöst:
|
||||
1. Erster Versuch: `EstimateTermStart` (frühester Fehlzeiten-Eintrag der ganzen Klasse als
|
||||
Näherung für den tatsächlichen ersten Unterrichtstag) — ohne zusätzlichen WebUntis-Abruf, aber
|
||||
nur eine Näherung.
|
||||
2. Nutzer-Hinweis: WebUntis kennt den echten Ferienkalender bereits (`getHolidays`-Bericht, in
|
||||
`LehrerApp.WebUntis/WebUntisClient.GetHolidaysAsync` schon implementiert, aber bis dahin
|
||||
nirgends im Desktop verdrahtet). Verdrahtet über `WebUntisIntegrationService.GetHolidaysAsync`
|
||||
(neuer `UntisHolidayDto`, gleiches Muster wie `GetSchoolYearsAsync`), gecacht (nicht über die
|
||||
LiteDB-Tabellen von `UntisReportCacheService` — deren heißes/kaltes Fenster ist auf sich
|
||||
laufend ändernde Fehlzeiten zugeschnitten, Ferien ändern sich dagegen innerhalb eines
|
||||
Schuljahrs praktisch nie — sondern einfacher tagesgenauer Cache direkt in
|
||||
`WebUntisSettingsService`: `CachedUntisHoliday`-Liste + `HolidaysFetchedAt`, unverschlüsselt,
|
||||
kein Geheimnis anders als iCal-URL/API-Zugangsdaten in derselben Datei). Neue
|
||||
`ClassTeacherOverviewViewModel.CountSchoolWeekdays` zieht Ferienzeiträume von der
|
||||
Werktagszählung ab.
|
||||
3. **Nutzer-Verifikation deckte auf: `getHolidays` liefert für dieses Konto nie einen
|
||||
Sommerferien-Eintrag** — geprüft anhand der tatsächlich gecachten Antwort (179 Einträge,
|
||||
11 Jahre Historie ab 2015): Herbst-/Weihnachts-/Osterferien und einzelne bewegliche
|
||||
Ferientage sind lückenlos dabei, aber kein einziger Juli-/August-Zeitraum, in keinem der
|
||||
11 Jahre. Vermutlich weil die Sommerferien WebUntis-intern zwischen zwei
|
||||
Schuljahres-Datensätzen liegen (die bei 1.8./31.7. enden) statt "in" einem davon — WebUntis
|
||||
scheint sie deshalb keinem Schuljahr zuzuordnen. `CountSchoolWeekdays` (Ferien innerhalb eines
|
||||
Zeitraums abziehen) kann diese Lücke also grundsätzlich nicht schließen, unabhängig von
|
||||
Caching oder Implementierung. `EstimateTermStart` bleibt deshalb zusätzlich bestehen (behebt
|
||||
die Sommerferien-Lücke am Startpunkt), `CountSchoolWeekdays` läuft ab diesem geschätzten
|
||||
Starttag (behebt Herbst-/Weihnachts-/Osterferien & bewegliche Ferientage innerhalb des
|
||||
restlichen Jahres — oben unter "Trend & Fehlquote" noch als bewusste Vereinfachung
|
||||
dokumentiert, für den Teil jetzt erledigt). Beide Kombinationen als Regressionstest
|
||||
festgehalten (`CountSchoolWeekdays_AbEchtemTerminstartOhneSommerferienEintragStimmtMitBeobachtungUeberein`)
|
||||
mit den vom Nutzer nachgezählten echten Werten (13 Schultage seit 13.08.2026).
|
||||
- Herkunft des Nenners jetzt direkt im Tooltip nachvollziehbar statt nur intern verrechnet:
|
||||
`ClassTeacherRosterRow.TermStart` ("seit dd.MM.") und `HolidayWeekdaysExcluded`
|
||||
("X Ferientage abgezogen") — Lehre aus diesem Vorfall, bei dem der falsche Wert sonst erneut
|
||||
unbemerkt geblieben wäre.
|
||||
- `AppLogger` (optional, DI) protokolliert jeden `GetHolidaysAsync`-Aufruf: bei Erfolg Name +
|
||||
Zeitraum jedes geladenen Ferieneintrags, bei Fehlschlag die Exception — nächster Diagnoseschritt
|
||||
wäre sonst wieder nur stilles Rätselraten gewesen.
|
||||
Neue Abhängigkeiten `WebUntisIntegrationService`, `AppLogger?` in `ClassTeacherOverviewViewModel`
|
||||
(beide bereits als Singleton registriert, nur Konstruktor-Injection ergänzt).
|
||||
**Nicht behoben, weil mit den vorhandenen Daten nicht erkennbar:** Kolleg*innen, die die
|
||||
Anwesenheitsliste nur sporadisch führen, drücken die Quote auf dieselbe Weise (fehlende
|
||||
Fehlzeiten-Einträge an Tagen mit tatsächlichem Unterricht) — von echter Anwesenheit ist das aus
|
||||
|
||||
Reference in New Issue
Block a user