namespace LehrerApp.Core.Models; public class Documentation : IHasAttachments { public Guid Id { get; set; } = Guid.NewGuid(); public Guid StudentId { get; set; } public Guid? GroupId { get; set; } /// Unterrichtssitzung, in der die Beobachtung entstanden ist. public Guid? ParticipationSessionId { get; set; } /// Optionaler Bezug auf die konkrete geplante Stunde. public Guid? LessonId { get; set; } public DocumentationType Type { get; set; } public DateOnly Date { get; set; } public string Title { get; set; } = ""; public string Content { get; set; } = ""; public List Participants { get; set; } = []; public AbsenceData? AbsenceData { get; set; } public SupportData? SupportData { get; set; } public ParentCallData? ParentCallData { get; set; } public ParentLetterData? ParentLetterData { get; set; } public List Attachments { get; set; } = []; /// Freie Labels zur Nachverfolgung, z.B. "Kritisch", "Nacharbeiten" — siehe `DocumentationTagDisplay`. public List Tags { get; set; } = []; /// Im Unterricht schnell erfasst und noch inhaltlich nachzuarbeiten. public bool IsDraft { get; set; } public bool IsConfidential { get; set; } /// Für die pädagogische Arbeit/Leistungsbewertung gedacht, aber nicht für den /// WebUntis-Klassenbuch-Abgleich vorgesehen - blendet den Eintrag im Abgleichsdialog /// (WebUntisDocumentationComparisonViewModel) aus dem Zwischenablage-Vorschlag aus. public bool ExcludeFromWebUntisSync { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; // Löschen entfernt den Eintrag nicht hart, sondern markiert ihn nur (Nachvollziehbarkeit, 5.1.4). public bool IsDeleted { get; set; } public DateTime? DeletedAt { get; set; } } public class AbsenceData { public int LessonCount { get; set; } public bool Excused { get; set; } public string? Reason { get; set; } } public class SupportData { public List Measures { get; set; } = []; public DateOnly? ReviewDate { get; set; } public SupportStatus Status { get; set; } = SupportStatus.Active; } /// Geplante Gesprächspunkte eines Elternanrufs, abgehakt in . public class ParentCallPoint { public Guid Id { get; set; } = Guid.NewGuid(); public string Text { get; set; } = ""; public bool IsDone { get; set; } } /// /// Elternanruf: Gesprächspunkte werden vorab geplant, dann im begleitenden Dialog während des /// Anrufs abgehakt und um Eindrücke/Ergänzungen zum Protokoll ergänzt. /// public class ParentCallData { public List Points { get; set; } = []; public string Impressions { get; set; } = ""; public bool IsConducted { get; set; } public DateOnly? ConductedDate { get; set; } } /// Elternbrief: Entwurf/Planung sowie Absende- und Rückmeldedaten. public class ParentLetterData { public string DraftContent { get; set; } = ""; public DateOnly? SentDate { get; set; } public bool ResponseReceived { get; set; } public DateOnly? ResponseDate { get; set; } public string ResponseNote { get; set; } = ""; } /// Datei-Anhang eines Dokumentationseintrags, im LiteDB-Dateispeicher abgelegt. public class DocumentAttachment { public string StorageId { get; set; } = ""; public string FileName { get; set; } = ""; public long SizeBytes { get; set; } public DateTime UploadedAt { get; set; } = DateTime.UtcNow; } /// /// Implementiert von jedem Modell mit Datei-Anhängen (aktuell und /// ). Anhang-Bytes reisen nicht im JSON-Sync-Ereignis mit, sondern als eigener /// Binärtransfer (siehe SyncEventPublisher/EventApplier/AttachmentSyncer in /// LehrerApp.Sync) — dieses Interface macht die Erkennung "hat dieses Modell Anhänge?" dort /// generisch statt hart auf einen einzelnen Modelltyp verdrahtet. /// public interface IHasAttachments { List Attachments { get; } } // Hinten angefügt, damit die numerischen Werte bereits gespeicherter LiteDB-Einträge stabil bleiben. public enum DocumentationType { Conversation, Incident, SupportPlan, Absence, ParentCall, ParentLetter, Planning } public enum SupportStatus { Active, Completed, Paused } public class WorkTask { public Guid Id { get; set; } = Guid.NewGuid(); public string Title { get; set; } = ""; public TaskCategory Category { get; set; } public Guid? GroupId { get; set; } public DateOnly? DueDate { get; set; } public int? EstimatedMinutes { get; set; } public WorkTaskStatus Status { get; set; } = WorkTaskStatus.Open; public string? Notes { get; set; } // Beim Abschließen (6.1.3) wird bei Weekly/Monthly automatisch die nächste Aufgabe erzeugt (6.1.4). public TaskRecurrence Recurrence { get; set; } = TaskRecurrence.None; /// Nutzer-Feedback: "Aufgaben" wirkt wie reine Zeiterfassung, dabei braucht man auch schlichte /// Erinnerungen ohne Zeitbezug (z.B. "morgen Ansage an die Klasse machen"). Reminder-Aufgaben /// laufen über dieselbe Liste/dasselbe Dashboard-Widget, werden aber nie mit einem /// TimeEntry verknüpft und fließen deshalb schon rein datenmodell-bedingt (WorkloadEvaluationViewModel /// wertet nur TimeEntry aus, nicht WorkTask) nicht in die Zeitauswertung (6.3) ein. public TaskKind Kind { get; set; } = TaskKind.WorkItem; /// Nutzer-Feedback: pädagogische Erinnerungen ("Ansage an die Klasse", "Material einsammeln") /// sollen sich je nach Dringlichkeit farblich absetzen können, unabhängig vom Fälligkeitsdatum. public TaskPriority Priority { get; set; } = TaskPriority.Normal; /// Optionale Abhak-Liste (Nutzer-Feedback: "Namensliste aller Kurs-Schüler" ODER freie /// Teil-Punkte, wahlweise). Beides läuft über denselben Listentyp — bei aus der Kursliste /// befüllten Einträgen ist StudentId gesetzt (Sprungziel zum Schüler), bei frei eingegebenen /// Einträgen bleibt es leer. Als verschachtelte LiteDB-Liste statt eigener Collection/JSON- /// String, siehe TODO.md-Nachtrag zu 6.1/9 — synct dadurch automatisch über den bestehenden /// Sync-Unterbau mit (EventPublisher serialisiert das ganze WorkTask-Dokument je Save()). public List ChecklistItems { get; set; } = []; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; } public class ChecklistItem { public Guid Id { get; set; } = Guid.NewGuid(); public string Label { get; set; } = ""; public bool IsDone { get; set; } /// Gesetzt, wenn der Eintrag aus der Kursliste befüllt wurde (Sprungziel zum Schüler); /// bei frei eingegebenen Einträgen null. public Guid? StudentId { get; set; } } public class TimeEntry { public Guid Id { get; set; } = Guid.NewGuid(); public Guid? TaskId { get; set; } public string Category { get; set; } = ""; public Guid? GroupId { get; set; } public DateOnly Date { get; set; } public TimeOnly? StartTime { get; set; } public TimeOnly? EndTime { get; set; } public int DurationMinutes { get; set; } public string? Description { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } public enum TaskCategory { Correction, Preparation, Admin, Meeting, Other, Teaching } public enum WorkTaskStatus { Open, InProgress, Done } public enum TaskRecurrence { None, Weekly, Monthly } public enum TaskKind { WorkItem, Reminder } public enum TaskPriority { Low, Normal, High }