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>
66 lines
2.9 KiB
C#
66 lines
2.9 KiB
C#
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; }
|
|
}
|