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 }
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 }