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:
@@ -0,0 +1,65 @@
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Lokal zwischengespeicherte Zeile aus dem WebUntis-Bericht "Fehlzeiten pro Schüler*in"
|
||||
/// (Klassenlehrer-Feature, siehe TODO.md) — 1:1-Abbildung von `UntisClassAbsenceEntryDto`
|
||||
/// (LehrerApp.Desktop), damit Fehlzeiten nicht bei jedem Öffnen der Ansicht neu abgerufen werden
|
||||
/// müssen. <c>Date</c> bewusst als <c>int</c> (yyyyMMdd) wie die DTOs statt <c>DateOnly</c>/
|
||||
/// <c>DateTime</c> — vermeidet die LiteDB-<c>DateTime</c>-Kind-Tücke (siehe CLAUDE.md) und ist
|
||||
/// direkt für Bereichs-Queries nutzbar.
|
||||
/// </summary>
|
||||
public class UntisAbsenceCacheEntry
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public string ClassName { get; set; } = "";
|
||||
public string StudentName { get; set; } = "";
|
||||
public int? ExternKey { get; set; }
|
||||
public int Date { get; set; }
|
||||
public int AbsentPeriods { get; set; }
|
||||
public int AbsentMinutes { get; set; }
|
||||
public string? TeacherUsernames { get; set; }
|
||||
public string? Subject { get; set; }
|
||||
public string? AbsenceReason { get; set; }
|
||||
public string? Note { get; set; }
|
||||
public int? EntryId { get; set; }
|
||||
public string? HandledOn { get; set; }
|
||||
public bool Counts { get; set; }
|
||||
public string? ExcuseNote { get; set; }
|
||||
public int? PeriodNumber { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public bool CountsAsFullDay { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Lokal zwischengespeicherte Zeile aus dem "-alle-"-Klassenbuchbericht, gefiltert auf
|
||||
/// Einträge anderer Lehrkräfte (Klassenlehrer-Feature) — 1:1-Abbildung von
|
||||
/// `UntisForeignClassRegisterEventDto` (LehrerApp.Desktop).</summary>
|
||||
public class UntisClassRegisterCacheEntry
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public string ClassName { get; set; } = "";
|
||||
public int Date { get; set; }
|
||||
public string? Subject { get; set; }
|
||||
public string StudentName { get; set; } = "";
|
||||
public string? TeacherUsername { get; set; }
|
||||
public string? CategoryName { get; set; }
|
||||
public string? CategoryGroup { get; set; }
|
||||
public string? Text { get; set; }
|
||||
}
|
||||
|
||||
public enum UntisCacheKind { Absences, ClassRegister }
|
||||
|
||||
/// <summary>
|
||||
/// Ein Datensatz pro (<see cref="ClassName"/>, <see cref="Kind"/>): wann das "heiße" Fenster
|
||||
/// (die letzten Tage, deren Status sich noch ändern kann) zuletzt aufgefrischt wurde, und wie weit
|
||||
/// die "kalte", als endgültig angenommene Historie bereits lückenlos zurückreicht. Getrennt von den
|
||||
/// Cache-Zeilen selbst, weil ein Fenster ohne Treffer (z.B. eine ereignislose Woche) sonst keine
|
||||
/// Zeile hinterließe, aus der sich "zuletzt abgerufen am…" ableiten ließe.
|
||||
/// </summary>
|
||||
public class UntisCacheFetchState
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public string ClassName { get; set; } = "";
|
||||
public UntisCacheKind Kind { get; set; }
|
||||
public DateTime? HotWindowFetchedAt { get; set; }
|
||||
public int? ColdCoverageStartDate { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user