CLAUDE.md mit Projektkonventionen für künftige Claude-Code-Sitzungen. Wiederkehrende UI-Muster konsolidiert: neue PageHeader-Control für Titel/Untertitel in den Listen- und Detailansichten, globale Styles für Dialog-Titel und Leerlisten-Hinweise statt inline wiederholter Werte. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
646 lines
41 KiB
Markdown
646 lines
41 KiB
Markdown
# LehrerApp — Entwicklungs-Roadmap
|
||
|
||
Strukturierte ToDo-Liste aller offenen Entwicklungsschritte.
|
||
Jeder Punkt ist so formuliert, dass er einzeln an einen Agenten übergeben werden kann.
|
||
|
||
**Stand:** 2026-08-04
|
||
**Legende:** `[ ]` offen · `[~]` teilweise umgesetzt · `[x]` fertig
|
||
|
||
---
|
||
|
||
## 0. Konventionen für alle Aufgaben
|
||
|
||
Diese Regeln gelten für jede Aufgabe unten und müssen nicht wiederholt werden.
|
||
|
||
- **MVVM:** Logik in ViewModels (`CommunityToolkit.Mvvm`, `[ObservableProperty]` / `[RelayCommand]`),
|
||
Views enthalten nur Binding. Kein Code-Behind außer Dialog-Verdrahtung.
|
||
- **DI:** Neue Repositories/Services/ViewModels in `LehrerApp.Desktop/AppBootstrapper.cs` registrieren.
|
||
Repositories + Listen-VMs = Singleton, Detail-/Dialog-VMs = Transient.
|
||
- **Daten:** Neue Collections in `LehrerApp.Data/LiteDbContext.cs` anlegen, Indexe in `EnsureIndexes()`.
|
||
Interface nach `LehrerApp.Core/Interfaces/IRepositories.cs`, Implementierung nach
|
||
`LehrerApp.Data/Repositories/AllRepositories.cs`.
|
||
- **Dialoge:** `Window` mit `Close(true/false)`, DataContext manuell gesetzt (Muster siehe
|
||
[AddGroupDialog.axaml.cs](LehrerApp.Desktop/Views/Groups/AddGroupDialog.axaml.cs)).
|
||
- **Sprache:** Alle UI-Texte auf Deutsch. Datumsformat `dd.MM.yyyy`, Kultur `de-DE`.
|
||
- **Modelle:** `UpdatedAt` bei jedem Speichern setzen (Grundlage für Sync-Konfliktauflösung).
|
||
|
||
---
|
||
|
||
## 1. Klausuren & Leistungsüberprüfungen
|
||
|
||
Modelle `Exam`, `ExamTask`, `GradingKeyEntry`, `ExamResult` existieren bereits in
|
||
[Exam.cs](LehrerApp.Core/Models/Exam.cs), Repositories ebenfalls. Die komplette UI fehlt.
|
||
|
||
**Niveaudifferenzierung (E/G/Förder) ist bereits umgesetzt** — nicht aus dieser Liste, sondern
|
||
ein separater Bedarf (Nachteilsausgleich/Binnendifferenzierung): `LearningGroup.IsDifferentiated`
|
||
(Checkbox in den Stammdaten) blendet eine Niveau-Zuordnung je Schüler ein (`GroupMembership.Niveau`,
|
||
Schüler-Tab). Klausuren bekommen optional ein `Niveau`; Punkteeingabe und Auswertung filtern dann
|
||
automatisch auf die passenden Schüler. Workflow: G-Klausur normal anlegen, per "Duplizieren"
|
||
(1.1.4) die E-Variante mit eigenen Aufgaben/Punkten ableiten (Niveau wird beim Duplizieren bewusst
|
||
zurückgesetzt). Vollständig individuelle Förderklausuren (nur für einen einzelnen Schüler) laufen
|
||
pragmatisch über "Abwesend" bei den übrigen Schülern statt über eine eigene Schüler-Zuordnung.
|
||
|
||
### 1.1 Klausur anlegen und verwalten
|
||
- [x] **1.1.1** Dialog `AddExamDialog` — Titel, Datum, Fach, Klausurnummer, Notizen.
|
||
Ersetzt den TODO-Stub `AddExam()` in [GroupViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/GroupViewModels.cs).
|
||
Umgesetzt als `ExamDialog`/`ExamDialogViewModel`.
|
||
- [x] **1.1.2** Klausur bearbeiten/löschen (Kontextmenü im Klausuren-Tab, Löschen mit Rückfrage).
|
||
- [x] **1.1.3** Statuswechsel `Planned → Conducted → Graded → Returned` per Button,
|
||
inkl. Farbcodierung des Status im DataGrid.
|
||
- [x] **1.1.4** Klausur aus bestehender Klausur duplizieren (Aufgaben + Notenschlüssel übernehmen,
|
||
neues Datum) — für Parallelkurse.
|
||
|
||
### 1.2 Aufgabenstruktur (`ExamTask`)
|
||
- [x] **1.2.1** Editor für die Aufgabenliste: Nr., Titel, Maximalpunkte, Gewichtung.
|
||
Zeilen hinzufügen/entfernen/umsortieren. Umgesetzt im `ExamDialog` (Teil von 1.1.1).
|
||
- [x] **1.2.2** Automatische Anzeige der Gesamtpunktzahl, Warnung bei 0 Punkten.
|
||
- [ ] **1.2.3** Optional: Teilaufgaben (a/b/c) — erfordert Modellerweiterung, vorher entscheiden.
|
||
- [x] **1.2.4** Zuordnung von Kompetenzen (`CompetencyItem`) zu einzelnen Aufgaben —
|
||
Voraussetzung für die Kompetenzauswertung in 8.3.
|
||
|
||
### 1.3 Notenschlüssel
|
||
- [x] **1.3.1** Editor für `GradingKey` mit Vorbelegung aus
|
||
`GradingService.DefaultKey1To6()` / `DefaultKey0To15()` je nach `GradingSystem` der Gruppe.
|
||
Umgesetzt im `ExamDialog` (Teil von 1.1.1), analog zum Aufgaben-Editor.
|
||
- [x] **1.3.2** Notenschlüssel als wiederverwendbare Vorlage speichern (neues Modell
|
||
`GradingKeyTemplate` + Repository) und in Einstellungen verwalten.
|
||
- [x] **1.3.3** Live-Vorschau: Punktegrenzen absolut anzeigen (z.B. "Note 2 ab 45 von 60 P.").
|
||
- [x] **1.3.4** Validierung: lückenlose, absteigende Prozentgrenzen, keine Dopplungen
|
||
(`GradingService.ValidateGradingKey`).
|
||
|
||
### 1.4 Punkteeingabe & Korrektur
|
||
- [x] **1.4.1** Eingaberaster: Zeilen = Schüler, Spalten = Aufgaben, letzte Spalte Summe + Note.
|
||
Note wird live über `GradingService.CalculateGrade()` berechnet.
|
||
Umgesetzt als eigener Dialog `ExamGradingDialog`, erreichbar über "Punkte eingeben"
|
||
im Klausuren-Tab (Button/Kontextmenü bei ausgewählter Klausur).
|
||
- [x] **1.4.2** Tastaturnavigation: Tab bewegt sich nativ zur nächsten Zelle, Enter/Pfeil-Hoch/
|
||
Pfeil-Runter springen zur gleichen Spalte in der Nachbarzeile, direkte Zifferneingabe
|
||
und halbe Punkte (Komma oder Punkt) erlaubt.
|
||
- [x] **1.4.3** Kennzeichnung "Abwesend" (`ExamResult.Absent`) per Checkbox — Note zeigt "abwesend"
|
||
statt einer berechneten Note. Ausschluss aus Statistiken über 1.5 umgesetzt.
|
||
- [x] **1.4.4** Kommentarfeld pro Schüler (`ExamResult.Comment`).
|
||
- [x] **1.4.5** Validierung: Punkte < 0 oder > Maximalpunkte der Aufgabe wird rot markiert und nicht
|
||
gespeichert (`PointsCell.TrySetValue`).
|
||
- [x] **1.4.6** Autosave nach jeder Zelle (kein expliziter Speichern-Button nötig).
|
||
|
||
### 1.5 Klausurauswertung
|
||
- [x] **1.5.1** Notenspiegel (Häufigkeitsverteilung als Balken), Durchschnitt, Median,
|
||
Anteil unter 4 / unter 5 Punkten. Umgesetzt als neuer Dialog `ExamEvaluationDialog`,
|
||
erreichbar über "Auswertung" im Klausuren-Tab. Bei Notensystem 1–6 zeigt der Schwellenwert
|
||
sinngemäß "Anteil nicht ausreichend (Note 5/6)" statt der Punktegrenzen. Abwesende werden
|
||
aus allen Statistiken ausgeschlossen (löst damit auch den Hinweis aus 1.4.3 ein).
|
||
- [x] **1.5.2** Aufgabenanalyse: durchschnittlicher Erfüllungsgrad pro Aufgabe in Prozent,
|
||
Kennzeichnung auffällig schwacher Aufgaben (Ø < 50 %, rot markiert).
|
||
- [x] **1.5.3** Notenschlüssel nachträglich verschieben und Auswirkung sofort im Notenspiegel sehen —
|
||
Änderungen wirken sich live aus, erst "Übernehmen" schreibt sie in die Klausur zurück.
|
||
- [x] **1.5.4** Export der Auswertung — als eigenständiger CSV-Export direkt im Dialog umgesetzt
|
||
(analog zum bestehenden JSON-Export der Kompetenzkataloge), nicht über eine gemeinsame
|
||
Export-Infrastruktur, da Kapitel 11 ("Bisher nicht vorhanden — komplett neu") noch aussteht.
|
||
|
||
---
|
||
|
||
## 2. Noten & Zeugnisnoten
|
||
|
||
Modell `Grade` existiert in [Planning.cs](LehrerApp.Core/Models/Planning.cs), `GradeRepository` ebenfalls.
|
||
Der Tab "Noten" in [GroupDetailView.axaml](LehrerApp.Desktop/Views/Groups/GroupDetailView.axaml) ist jetzt
|
||
vollständig umgesetzt (siehe unten), ebenso der gleichnamige Tab im Schülerdetail (2.5).
|
||
|
||
### 2.1 Notenübersicht der Gruppe
|
||
- [x] **2.1.1** Matrix: Zeilen = Schüler, Spalten = alle Leistungen (Klausuren, Mitarbeit je Halbjahr,
|
||
sonstige Noten). Zelle zeigt Note/Punkte.
|
||
- [x] **2.1.2** Spalte "Gesamt" mit gewichtetem Durchschnitt über `GradingService.WeightedAverage()`.
|
||
- [x] **2.1.3** Sortierung nach Name / Gesamtnote, Umschalten Noten ↔ Punkte.
|
||
- [x] **2.1.4** Halbjahresfilter (H1 / H2 / Gesamtjahr), berücksichtigt `GroupMembership.Period`.
|
||
|
||
### 2.2 Einzelnoten pflegen
|
||
- [x] **2.2.1** Dialog "Note hinzufügen": Kategorie (`GradeCategory`), Wert, Datum, Gewichtung, Notiz.
|
||
- [x] **2.2.2** Note bearbeiten / löschen mit Historie (wer/wann geändert) — mindestens `CreatedAt` sichtbar.
|
||
- [x] **2.2.3** Sammelerfassung: eine Note (z.B. Hausaufgabenkontrolle) für die ganze Gruppe auf einmal.
|
||
|
||
### 2.3 Gewichtungsschema
|
||
- [x] **2.3.1** Neues Modell `GradingScheme` je Gruppe: prozentuale Anteile von
|
||
Klausuren / Mitarbeit / sonstige Leistungen (z.B. 50/40/10).
|
||
- [x] **2.3.2** UI zur Bearbeitung, Validierung auf Summe 100 %.
|
||
- [x] **2.3.3** Voreinstellung je Gruppentyp (`Class` vs. `Course`) in den Einstellungen.
|
||
|
||
### 2.4 Zeugnisnote
|
||
- [x] **2.4.1** Berechnung der Zeugnisnote aus Schema (2.3) + allen Teilnoten,
|
||
Rundungsregel konfigurierbar (kaufmännisch / pädagogisch abweichbar).
|
||
- [x] **2.4.2** Manuelles Übersteuern mit Pflicht-Begründung (pädagogischer Spielraum).
|
||
- [x] **2.4.3** Zeugnisnoten-Ansicht mit Sperren/Festschreiben zum Konferenztermin.
|
||
- [x] **2.4.4** Export der Zeugnisnotenliste (siehe 11.2).
|
||
|
||
### 2.5 Notenentwicklung
|
||
- [x] **2.5.1** Verlaufsdiagramm pro Schüler über das Schuljahr (im Schülerdetail).
|
||
- [x] **2.5.2** Auffälligkeiten markieren: Abfall um ≥ 1 Note, Versetzungsgefährdung (Note 5/6).
|
||
|
||
Umgesetzt über [GradeOverviewViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/GradeOverviewViewModels.cs)
|
||
(Matrix-Tab, Einzelnoten-Dialoge), [ReportGradeViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/ReportGradeViewModels.cs)
|
||
(Zeugnisnoten-Dialog) und die neuen Modelle `GradingScheme`/`ReportGrade` in
|
||
[Planning.cs](LehrerApp.Core/Models/Planning.cs). Das Gewichtungsschema wird pro Gruppe gesucht, sonst
|
||
die Voreinstellung des Gruppentyps (Einstellungen → Notenschema), sonst ein Fallback 50/40/10 verwendet;
|
||
Bereiche ohne Werte werden bei der Berechnung ausgelassen und die verbleibenden Prozentanteile neu normiert
|
||
(`GradingService.CalculateReportGrade()`). Notenentwicklung im Schülerdetail zeigt ein einfaches
|
||
Balken-Sparkline je Lerngruppe über alle Klausur- und Einzelnoten-Einträge chronologisch.
|
||
|
||
---
|
||
|
||
## 3. Mündliche Mitarbeit — offene Punkte
|
||
|
||
Grundfunktion ist umgesetzt (Sitzungen, Raster, Schnelleingabe-Dialog).
|
||
Siehe [ParticipationViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/ParticipationViewModels.cs).
|
||
|
||
### 3.1 Aspekte konfigurieren
|
||
- [ ] **3.1.1** UI zum Anlegen/Bearbeiten/Löschen von `ParticipationAspect` **pro Gruppe**
|
||
(Fach Chemie: z.B. "Experiment", "Protokoll") — `GroupId = null` bleibt global.
|
||
- [ ] **3.1.2** Reihenfolge der Aspekte per Drag & Drop oder Hoch/Runter-Buttons festlegen
|
||
(bestimmt auch die Q/W/E/R/T-Belegung im Schnelleingabe-Dialog).
|
||
- [ ] **3.1.3** Aspekt-Typen `Scale3`, `Binary`, `Points` in Raster und Dialog vollständig unterstützen
|
||
(bisher primär `Scale5`).
|
||
- [ ] **3.1.4** Aspekt deaktivieren statt löschen, damit alte Einträge gültig bleiben.
|
||
|
||
### 3.2 Aggregation zur Mitarbeitsnote
|
||
- [x] **3.2.1** Gewichtung je Aspekt konfigurierbar (z.B. Qualität 50 %, Quantität 30 %, Experiment 20 %).
|
||
- [x] **3.2.2** Berechnung einer Mitarbeitsnote je Halbjahr aus allen Sitzungen,
|
||
Ausgabe als Note bzw. Punkte je nach `GradingSystem` der Gruppe.
|
||
- [x] **3.2.3** Umgang mit fehlenden Werten festlegen (nicht bewertet ≠ schlecht bewertet).
|
||
- [x] **3.2.4** Übernahme der berechneten Mitarbeitsnote als `Grade` mit
|
||
`Category = Participation` (Anbindung an 2.1).
|
||
- [x] **3.2.5** Trendanzeige pro Schüler (Entwicklung über die Sitzungen hinweg).
|
||
|
||
Umgesetzt über den neuen Dialog "Ø Mitarbeitsnote" im Mitarbeit-Tab
|
||
([ParticipationGradeViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/ParticipationGradeViewModels.cs),
|
||
[ParticipationGradeDialog.axaml](LehrerApp.Desktop/Views/Groups/ParticipationGradeDialog.axaml)):
|
||
Zeitraum wählbar (Gesamtjahr/H1/H2), Aspekt-Gewichtung live editierbar (`ParticipationAspect.Weight`,
|
||
da die eigentliche Aspekt-Verwaltung aus 3.1 noch fehlt), Mapping der Bewertungsskala (-2..+2) auf
|
||
Note/Punkte über `GradingService.ParticipationGrade()`, einfache Trendanzeige (↑/↓/→) durch Vergleich
|
||
der ersten mit der zweiten Hälfte der Sitzungen. "Übernehmen" aktualisiert eine bestehende
|
||
Mitarbeit-Note für denselben Zeitraum statt sie zu duplizieren (erkannt über den `Grade.Note`-Tag).
|
||
|
||
### 3.3 Sitzungen
|
||
- [ ] **3.3.1** Sitzung automatisch aus einer geplanten `Lesson` erzeugen
|
||
(Datum + Thema übernehmen) — Abhängigkeit zu 4.2.
|
||
- [x] **3.3.2** Anwesenheit in der Sitzung erfassen — als `ParticipationEntry.Attendance`
|
||
(krank: Entschuldigung offen/entschuldigt/unentschuldigt), nicht als "verspätet"; siehe unten.
|
||
Vorgriff auf 5.2, ersetzt dessen 5.2.1/5.2.4 aber nicht vollständig (kein Fehlzeitenmodul
|
||
über alle Stundentypen hinweg, nur innerhalb von Mitarbeit-Sitzungen).
|
||
- [ ] **3.3.3** Sitzung bearbeiten/löschen inkl. Rückfrage bei vorhandenen Bewertungen.
|
||
- [ ] **3.3.4** Sitzungen mehrerer Gruppen im Kalenderüberblick.
|
||
|
||
### Abschnittsnoten & Mitarbeits-Assistent (nicht aus dieser Liste, eigener Workflow-Bedarf)
|
||
|
||
Ergänzt den Workflow "regelmäßig (alle 4–7 Wochen) mündliche Noten zu einer Abschnittsnote
|
||
zusammenziehen, daraus die Halbjahresnote bilden":
|
||
|
||
- `ParticipationEntry.HomeworkMissing` (bool) und `.Attendance` (`AttendanceStatus?`:
|
||
`ExcusePending`/`Excused`/`Unexcused`) — editierbar direkt im Bewertungsraster
|
||
([ParticipationTabView.axaml](LehrerApp.Desktop/Views/Groups/ParticipationTabView.axaml), Spalten
|
||
"HA"/"Anwesenheit") und im neuen Mitarbeits-Assistenten. `ExcusePending` ist bewusst ein
|
||
Zwischenzustand, da die Entschuldigung meist erst später eintrifft.
|
||
- Neues Modell `ParticipationSection` (Abschnitt: Start/Ende/Bezeichnung je Gruppe) — nur
|
||
abgeschlossene Abschnitte werden gespeichert, der laufende Zeitraum ergibt sich aus dem Ende
|
||
des letzten Abschnitts bis heute.
|
||
- Neues Fenster **Mitarbeits-Assistent**
|
||
([ParticipationWizardViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/ParticipationWizardViewModels.cs),
|
||
[ParticipationWizardDialog.axaml](LehrerApp.Desktop/Views/Groups/ParticipationWizardDialog.axaml)):
|
||
Zeitleiste je Schüler (Sitzungen als Bewertungs-Badges, Klausurtermine, Symbole für Hausaufgaben/
|
||
Bemerkung/Anwesenheit), gruppiert nach Abschnitten. "Abschnitt abschließen" berechnet für alle
|
||
Schüler einen Notenvorschlag aus den Sitzungen im Zeitraum und speichert ihn als `Grade`
|
||
(`Category = Participation`, `Note = "Abschnitt: <Bezeichnung>"`), individuell nachjustierbar.
|
||
"Halbjahresnote aus Abschnitten übernehmen" mittelt die Abschnittsnoten eines Zeitraums und
|
||
speichert sie über denselben `Grade.Note`-Tag wie der bestehende "Ø Mitarbeitsnote"-Dialog (3.2) —
|
||
beide Wege sind kompatibel, der Assistent baut auf 3.2 auf statt es zu ersetzen.
|
||
- Dashboard-Kachel "Offene Entschuldigungen": listet alle `ExcusePending`-Einträge der letzten
|
||
21 Tage gruppenübergreifend mit Direktauflösung; ältere Einträge werden ausgeblendet statt
|
||
automatisch entschieden (pädagogische Entscheidung bleibt bei der Lehrkraft).
|
||
|
||
---
|
||
|
||
## 4. Unterrichtsplanung
|
||
|
||
Modelle `Unit` und `Lesson` existieren, `UnitRepository`/`LessonRepository` ebenfalls.
|
||
Navigationspunkt "Unterrichtsplanung" ist ein `PlaceholderViewModel`
|
||
([MainWindowViewModel.cs:41](LehrerApp.Desktop/ViewModels/MainWindowViewModel.cs#L41)).
|
||
|
||
### 4.1 Unterrichtseinheiten (`Unit`)
|
||
- [ ] **4.1.1** Listenansicht der Einheiten je Gruppe mit Status und Zeitraum
|
||
(ersetzt den Platzhalter im Tab "Planung").
|
||
- [ ] **4.1.2** Dialog Einheit anlegen/bearbeiten: Titel, Fach, Zeitraum, Status, Notizen.
|
||
- [ ] **4.1.3** Kompetenzen aus dem Katalog (siehe 8) einer Einheit zuordnen — Mehrfachauswahl.
|
||
- [ ] **4.1.4** Einheit als Vorlage speichern und in eine andere Gruppe kopieren
|
||
(inkl. Stunden, ohne Datumsbezug).
|
||
- [ ] **4.1.5** Fortschrittsanzeige: gehaltene / geplante Stunden der Einheit.
|
||
|
||
### 4.2 Einzelstunden (`Lesson`)
|
||
- [ ] **4.2.1** Stundenliste innerhalb einer Einheit, sortiert nach Datum/Stundennummer.
|
||
- [ ] **4.2.2** Stundeneditor: Thema, Phase, Methoden, Materialien, Hausaufgabe.
|
||
Methoden/Materialien als Chips mit Autovervollständigung aus bisherigen Einträgen.
|
||
- [ ] **4.2.3** Status `Planned → Conducted` setzen, Reflexionsfeld nach der Stunde.
|
||
- [ ] **4.2.4** Stunden verschieben (z.B. bei Ausfall) — Folgestunden automatisch nachrücken.
|
||
- [ ] **4.2.5** Stunden serienweise aus dem Stundenplan (4.3) erzeugen.
|
||
|
||
### 4.3 Stundenplan
|
||
- [ ] **4.3.1** Neues Modell `TimetableSlot` (Gruppe, Wochentag, Stunde, Raum) + Repository.
|
||
- [ ] **4.3.2** Wochenstundenplan-Ansicht als Raster mit Farbcodierung je Gruppe.
|
||
- [ ] **4.3.3** Bearbeitung per Klick/Drag im Raster.
|
||
- [ ] **4.3.4** Abgleich mit `LearningGroup.HoursPerWeek` (Warnung bei Abweichung).
|
||
- [ ] **4.3.5** Schulferien und Feiertage hinterlegen (Bundesland wählbar) und aus der Planung ausnehmen.
|
||
|
||
### 4.4 Wochen-/Tagesansicht
|
||
- [ ] **4.4.1** Kalenderansicht über alle Gruppen: Woche und Tag.
|
||
- [ ] **4.4.2** Sprung von einer Stunde direkt in die Mitarbeitserfassung dieser Gruppe.
|
||
- [ ] **4.4.3** Anzeige anstehender Klausurtermine und Abgabefristen im Kalender.
|
||
|
||
---
|
||
|
||
## 5. Schülerdokumentation
|
||
|
||
Modelle `Documentation`, `AbsenceData`, `SupportData` existieren, Repository ebenfalls.
|
||
Der Tab "Dokumentation" in der Gruppenansicht ist ein Platzhalter, im Schülerdetail
|
||
werden `DocEntry`-Einträge bereits gelesen.
|
||
|
||
### 5.1 Einträge erfassen
|
||
- [ ] **5.1.1** Dialog "Dokumentation hinzufügen" mit Typwahl
|
||
(`Conversation`, `Incident`, `SupportPlan`, `Absence`) und typabhängigen Feldern.
|
||
- [ ] **5.1.2** Teilnehmerliste (`Participants`) bei Gesprächen erfassen.
|
||
- [ ] **5.1.3** Kennzeichen "vertraulich" (`IsConfidential`) mit Ausblenden in Übersichten.
|
||
- [ ] **5.1.4** Bearbeiten/Löschen mit Rückfrage; gelöschte Einträge nicht hart entfernen,
|
||
sondern als gelöscht markieren (Nachvollziehbarkeit).
|
||
|
||
### 5.2 Fehlzeiten
|
||
- [ ] **5.2.1** Schnelle Abwesenheitserfassung je Stunde (entschuldigt/unentschuldigt).
|
||
- [ ] **5.2.2** Fehlzeitenbilanz je Schüler und Halbjahr (Summe Stunden, Quote).
|
||
- [ ] **5.2.3** Schwellenwert-Warnung (z.B. > 20 % Fehlzeiten) im Schülerdetail und Dashboard.
|
||
- [ ] **5.2.4** Nachträgliches Entschuldigen mit Frist-Hinweis.
|
||
|
||
### 5.3 Förderpläne
|
||
- [ ] **5.3.1** Förderplan anlegen: Maßnahmenliste, Überprüfungsdatum, Status.
|
||
- [ ] **5.3.2** Wiedervorlage: fällige Überprüfungen erscheinen im Dashboard.
|
||
- [ ] **5.3.3** Verlaufsdokumentation zum Förderplan (mehrere Einträge über die Zeit).
|
||
|
||
### 5.4 Datenschutz
|
||
- [ ] **5.4.1** Vertrauliche Einträge nur nach zusätzlicher Bestätigung anzeigen.
|
||
- [ ] **5.4.2** Löschfristen definieren und abgelaufene Einträge zum Löschen vorschlagen.
|
||
- [ ] **5.4.3** Export einzelner Schülerdaten für Auskunftsersuchen (Art. 15 DSGVO).
|
||
|
||
---
|
||
|
||
## 6. Arbeitszeit & Aufgaben
|
||
|
||
Modelle `WorkTask` und `TimeEntry` existieren, Repositories ebenfalls.
|
||
Navigationspunkt "Arbeitszeit" ist ein `PlaceholderViewModel`.
|
||
|
||
### 6.1 Aufgabenverwaltung
|
||
- [ ] **6.1.1** Aufgabenliste mit Filter nach Status, Kategorie, Gruppe und Fälligkeit.
|
||
- [ ] **6.1.2** Aufgabe anlegen/bearbeiten: Titel, Kategorie, Gruppe, Fälligkeit,
|
||
geschätzte Dauer, Notizen.
|
||
- [ ] **6.1.3** Status per Klick wechseln (`Open → InProgress → Done`), erledigte ausblenden.
|
||
- [ ] **6.1.4** Wiederkehrende Aufgaben (wöchentlich/monatlich).
|
||
- [ ] **6.1.5** Automatische Aufgabe "Klausur korrigieren" beim Statuswechsel einer Klausur
|
||
auf `Conducted` (Anbindung an 1.1.3).
|
||
|
||
### 6.2 Zeiterfassung
|
||
- [ ] **6.2.1** Timer starten/stoppen mit Zuordnung zu Aufgabe oder Kategorie.
|
||
- [ ] **6.2.2** Manuelle Nacherfassung eines Zeitblocks (Datum, Von–Bis oder Dauer).
|
||
- [ ] **6.2.3** Wochenübersicht der erfassten Zeit, Summen je Kategorie.
|
||
- [ ] **6.2.4** Schätzung vs. tatsächliche Dauer je Aufgabe vergleichen.
|
||
|
||
### 6.3 Auswertung
|
||
- [ ] **6.3.1** Monats-/Jahresauswertung nach Kategorie und Gruppe (Diagramm + Tabelle).
|
||
- [ ] **6.3.2** Abgleich mit der Pflichtstundenzahl (in Einstellungen hinterlegt).
|
||
- [ ] **6.3.3** Export der Arbeitszeitauswertung (siehe 11.2).
|
||
|
||
---
|
||
|
||
## 7. Schüler & Gruppen — Verfeinerungen
|
||
|
||
Grundfunktionen sind vorhanden ([StudentViewModels.cs](LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs),
|
||
[GroupViewModels.cs](LehrerApp.Desktop/ViewModels/Groups/GroupViewModels.cs)).
|
||
Niveau-Zuordnung je Schüler (E/G/Förder, `GroupMembership.Niveau`) ist bereits umgesetzt, siehe
|
||
Hinweis in Kapitel 1 — betrifft auch Kurse, nicht nur Klassen.
|
||
|
||
### 7.1 Schüler
|
||
- [ ] **7.1.1** Schüler löschen / auf inaktiv setzen inkl. Hinweis auf verknüpfte Daten.
|
||
- [ ] **7.1.2** Suche in der Schülerliste (Name, Gruppe) mit Sofortfilter.
|
||
- [ ] **7.1.3** Foto/Avatar je Schüler (optional, lokal gespeichert) für schnellere Zuordnung.
|
||
- [ ] **7.1.4** Serienbrieffelder aus Kontaktdaten (Anrede, Adresse) für Elternbriefe.
|
||
- [ ] **7.1.5** Sitzplan je Gruppe (Raster mit Drag & Drop), Sprung von Sitzplatz zur Bewertung.
|
||
|
||
### 7.2 Gruppen
|
||
- [x] **7.2.1** Gruppe bearbeiten und löschen — bereits vorhanden (`EditGroupCommand`/`DeleteGroupCommand`/
|
||
`ToggleArchiveCommand` in `GroupListViewModel`), nicht Teil der aktuellen Klausuren-Arbeit,
|
||
beim Review aber bestätigt.
|
||
- [ ] **7.2.2** Gruppe ins neue Schuljahr übernehmen: Kopie mit gleicher Schülerschaft,
|
||
neues `SchoolYear`, neue `GroupMembership`-Einträge.
|
||
- [ ] **7.2.3** Schüler aus einer Gruppe entfernen (`GroupMembership.LeftAt` setzen statt löschen).
|
||
- [ ] **7.2.4** Umgang mit `MembershipPeriod.Custom` in allen Auswertungen prüfen
|
||
(Schüler zählt nur im belegten Zeitraum).
|
||
- [ ] **7.2.5** Archivansicht abgeschlossener Schuljahre (schreibgeschützt).
|
||
|
||
### 7.3 Import
|
||
- [ ] **7.3.1** CSV-Import von Schülerlisten mit Spaltenzuordnung im Dialog.
|
||
- [ ] **7.3.2** Dublettenerkennung beim Import (Name + Geburtsdatum), Zusammenführen anbieten.
|
||
- [ ] **7.3.3** Import-Vorschau mit Fehlerliste vor dem endgültigen Übernehmen.
|
||
|
||
---
|
||
|
||
## 8. Kompetenzen
|
||
|
||
Katalogverwaltung und JSON-Import existieren in
|
||
[SettingsViewModel.cs](LehrerApp.Desktop/ViewModels/Settings/SettingsViewModel.cs),
|
||
Format dokumentiert in [Kompetenzkatalog-KI-Prompt.md](docs/Kompetenzkatalog-KI-Prompt.md).
|
||
|
||
### 8.1 Katalogverwaltung
|
||
- [ ] **8.1.1** Kompetenzen innerhalb eines Bereichs umsortieren (`SortOrder` bearbeitbar machen).
|
||
- [ ] **8.1.2** Katalog exportieren (JSON) — Gegenstück zum vorhandenen Import.
|
||
- [ ] **8.1.3** Katalog von einer Jahrgangsstufe in eine andere kopieren.
|
||
- [ ] **8.1.4** Import-Konflikte behandeln: Merge statt Ersetzen anbieten.
|
||
|
||
### 8.2 Verwendung im Unterricht
|
||
- [ ] **8.2.1** Kompetenzen einer Unterrichtseinheit zuordnen (siehe 4.1.3).
|
||
- [x] **8.2.2** Kompetenzen einzelnen Klausuraufgaben zuordnen — umgesetzt mit 1.2.4.
|
||
- [ ] **8.2.3** Abdeckungsübersicht: welche Kompetenzen wurden im Schuljahr behandelt/geprüft?
|
||
|
||
### 8.3 Kompetenzorientierte Auswertung
|
||
- [ ] **8.3.1** Kompetenzprofil je Schüler aus Klausuraufgaben-Ergebnissen berechnen.
|
||
- [ ] **8.3.2** Gruppenübersicht: durchschnittlicher Erfüllungsgrad je Kompetenz,
|
||
Identifikation von Wiederholungsbedarf.
|
||
- [ ] **8.3.3** Kompetenzbericht je Schüler als Ausdruck/Export.
|
||
|
||
---
|
||
|
||
## 9. Dashboard
|
||
|
||
Basis vorhanden in [DashboardViewModel.cs](LehrerApp.Desktop/ViewModels/DashboardViewModel.cs).
|
||
Kleiner Monatskalender ist bereits umgesetzt (Farbcodierung Unterricht/Klausur,
|
||
Hervorhebung "eigene Klasse" über `LearningGroup.IsOwnClass`, feste Kartenbreite/-position).
|
||
|
||
- [ ] **9.1** Heutige Stunden mit Uhrzeit und Raum anzeigen (Abhängigkeit zu 4.3).
|
||
- [ ] **9.2** Direkter Absprung von einer Stunde in Mitarbeitserfassung bzw. Stundenplanung.
|
||
- [ ] **9.3** Kachel "Anstehende Termine": Klausuren, Förderplan-Überprüfungen, Abgabefristen.
|
||
- [ ] **9.4** Kachel "Offene Korrekturen" mit Fortschritt (x von y Klausuren bewertet).
|
||
- [ ] **9.5** Kachel "Auffälligkeiten": Fehlzeitenüberschreitungen, Notenabfall, Versetzungsgefährdung.
|
||
- [ ] **9.6** Dashboard-Kacheln ein-/ausblendbar und in der Reihenfolge konfigurierbar.
|
||
- [ ] **9.7** Automatische Aktualisierung beim Zurücknavigieren (aktuell nur manueller Refresh).
|
||
- [ ] **9.8** Kalender-Detailansicht: Tag im Monatskalender anklickbar/auswählbar, zeigt in
|
||
einem angrenzenden Feld die Termine dieses Tages (Unterricht, Klausuren, perspektivisch
|
||
Konferenzen/Sondertermine) mit Details und Sprungmöglichkeit in die jeweilige Ansicht.
|
||
Sinnvoll erst, wenn weitere Terminarten existieren — Abhängigkeit zu Kapitel 4
|
||
(Unterrichtsplanung/Termine) sowie ggf. einem neuen Termine-Modell.
|
||
|
||
---
|
||
|
||
## 10. Sync & Server
|
||
|
||
Grundgerüst existiert in [LehrerApp.Sync](LehrerApp.Sync/) und [LehrerApp.Api](LehrerApp.Api/),
|
||
ist aber nur aktiv, wenn eine Server-URL konfiguriert ist.
|
||
|
||
### 10.1 Client
|
||
- [ ] **10.1.1** Sync-Einrichtung in den Einstellungen: Server-URL, Login, Token speichern.
|
||
- [ ] **10.1.2** Verbindungstest mit klarer Fehlermeldung (nicht erreichbar / Token ungültig).
|
||
- [ ] **10.1.3** Konfliktanzeige in der UI — was `ConflictResolver` entscheidet, muss sichtbar sein.
|
||
- [ ] **10.1.4** Manuelles Auslösen einer vollständigen Synchronisation.
|
||
- [ ] **10.1.5** Statusanzeige erweitern: letzter Sync, Anzahl wartender Events, Fehlerzustand.
|
||
|
||
### 10.2 Server
|
||
- [ ] **10.2.1** Benutzerverwaltung/Registrierung prüfen und absichern
|
||
([Endpoints.cs](LehrerApp.Api/Endpoints/Endpoints.cs)).
|
||
- [ ] **10.2.2** Rate Limiting und Request-Größenbegrenzung.
|
||
- [ ] **10.2.3** Serverseitiges Backup der Event-/Snapshot-Dateien.
|
||
- [ ] **10.2.4** Docker-Setup in [docker/](docker/) verifizieren und dokumentieren.
|
||
|
||
### 10.3 Verschlüsselung
|
||
- [ ] **10.3.1** Schlüsselübertragung auf ein zweites Gerät (QR-Code oder Passphrase).
|
||
- [ ] **10.3.2** Warnung und Wiederherstellungspfad bei verlorenem Schlüssel.
|
||
- [ ] **10.3.3** Prüfen, welche Daten unverschlüsselt über `PlainEventStore` laufen —
|
||
personenbezogene Daten dürfen das nicht.
|
||
|
||
---
|
||
|
||
## 11. Export, Druck & Berichte
|
||
|
||
Bisher nicht vorhanden — komplett neu.
|
||
|
||
- [ ] **11.1** Basisinfrastruktur: Export-Service mit Formatwahl und Speicherdialog.
|
||
- [ ] **11.2** CSV-Export für Notenlisten, Klausurauswertung, Arbeitszeit, Fehlzeiten.
|
||
- [ ] **11.3** PDF-Erzeugung (Bibliothek auswählen — z.B. QuestPDF) mit einheitlichem Layout.
|
||
- [ ] **11.4** Druckvorlagen: Notenliste, Klausur-Notenspiegel, Sitzplan, Kompetenzbericht,
|
||
Schülerdokumentation.
|
||
- [ ] **11.5** Serienbrief/Elternbrief aus Kontaktdaten (Abhängigkeit zu 7.1.4).
|
||
- [ ] **11.6** Vollständiger Datenexport eines Schuljahres (Archivierung).
|
||
|
||
---
|
||
|
||
## 12. Einstellungen & Stammdaten
|
||
|
||
Fächer- und Kompetenzverwaltung existiert bereits in
|
||
[SettingsView.axaml](LehrerApp.Desktop/Views/Settings/SettingsView.axaml).
|
||
|
||
- [ ] **12.1** Lehrerprofil: Name, Kürzel, Schule, Pflichtstundenzahl.
|
||
- [ ] **12.2** Schuljahr-Einstellungen: Beginn/Ende, Halbjahresgrenze, Ferien
|
||
(`SchoolYearService` erweitern).
|
||
- [ ] **12.3** Standard-Notenschlüssel und Standard-Gewichtungsschema hinterlegen (2.3.3, 1.3.2).
|
||
- [ ] **12.4** Darstellung: Hell/Dunkel-Modus, Schriftgröße.
|
||
- [ ] **12.5** Speicherort der Datenbank anzeigen und ändern.
|
||
- [ ] **12.6** Backup-Verwaltung (siehe 13.3) in den Einstellungen zugänglich machen.
|
||
|
||
---
|
||
|
||
## 13. Technische Basis
|
||
|
||
### 13.1 Tests
|
||
- [x] **13.1.1** Testprojekt `LehrerApp.Tests` angelegt (referenziert `LehrerApp.Core`, analog zu
|
||
[LehrerApp.Data.Tests](LehrerApp.Data.Tests/LehrerApp.Data.Tests.csproj) für die Datenschicht).
|
||
Noch ohne Testfälle — folgt mit 13.1.2ff.
|
||
- [x] **13.1.2** Unit-Tests für `GradingService` (Notenschlüssel-Grenzfälle, gewichteter Schnitt) —
|
||
41 Tests in [GradingServiceTests.cs](LehrerApp.Tests/GradingServiceTests.cs), deckt
|
||
`CalculateGrade`, `ValidateGradingKey`, `WeightedAverage`, `RoundToGrade`, `ParticipationGrade`,
|
||
`ValidateGradingScheme` und `CalculateReportGrade` ab.
|
||
- [x] **13.1.3** Unit-Tests für `SchoolYearService` (Jahreswechsel, Schuljahresgrenze) —
|
||
13 Tests in [SchoolYearServiceTests.cs](LehrerApp.Tests/SchoolYearServiceTests.cs).
|
||
Dafür `CurrentSchoolYear`/`RecentSchoolYears` um ein optionales `today`-Parameter
|
||
erweitert (Default weiterhin `DateTime.Today`), um den 1.-August-Wechsel deterministisch
|
||
zu testen, ohne bestehende Aufrufer zu ändern.
|
||
- [x] **13.1.4** Repository-Tests gegen eine In-Memory-LiteDB — `LiteDbContext` um einen
|
||
`Stream`-Konstruktor erweitert (`new LiteDatabase(stream)`, kein Datei-I/O nötig),
|
||
19 Tests in [RepositoryTests.cs](LehrerApp.Data.Tests/RepositoryTests.cs): u.a.
|
||
Kaskadenlöschung bei `GroupRepository.Delete`/`ExamRepository.Delete`/
|
||
`ParticipationSessionRepository.Delete`, Eindeutigkeitsprüfungen (`GroupMembership`,
|
||
`ParticipationEntry`), Fach-Validierung (Trimmen, Duplikate, Löschsperre bei Verwendung),
|
||
`GradingScheme`-Auflösung gruppenspezifisch vs. Voreinstellung.
|
||
- [x] **13.1.5** Tests für die Mitarbeits-Aggregation (3.2) und Zeugnisnotenberechnung (2.4) —
|
||
neues Testprojekt `LehrerApp.Desktop.Tests` (referenziert `LehrerApp.Desktop`, damit
|
||
ViewModel-Logik ohne echtes UI getestet werden kann), gemeinsame Fakes in
|
||
[Fakes.cs](LehrerApp.Desktop.Tests/Fakes.cs). 9 Tests für
|
||
[ParticipationGradeAggregationTests.cs](LehrerApp.Desktop.Tests/ParticipationGradeAggregationTests.cs)
|
||
(gewichtetes Mittel, "nicht bewertet" ≠ schlechte Note, Trend, Aspektgewicht 0, Halbjahresfilter,
|
||
Übernehmen-Update-statt-Duplikat) und 9 für
|
||
[ReportGradeCalculationTests.cs](LehrerApp.Desktop.Tests/ReportGradeCalculationTests.cs)
|
||
(Schema-Auflösung gruppenspezifisch/Voreinstellung/Fallback, Pflicht-Begründung beim
|
||
Übersteuern, Festschreiben friert den Stand ein, Rundungsregel).
|
||
- [x] **13.1.6** Tests für `ConflictResolver` — neues Testprojekt `LehrerApp.Sync.Tests`,
|
||
10 Tests in [ConflictResolverTests.cs](LehrerApp.Sync.Tests/ConflictResolverTests.cs)
|
||
(Desktop schlägt Companion immer, Gleichstand nach Zeitstempel, kein Konflikt bei
|
||
unterschiedlicher Entität/gleichem Gerät). Dabei zwei echte Fehler gefunden und behoben:
|
||
(1) `SyncEvent` hatte keine `[BsonId]`-Markierung auf `EventId` — LiteDB vergab dadurch
|
||
einen eigenen, unabhängigen `_id`, wodurch `EventQueue.Acknowledge()` nie etwas aus der
|
||
Queue löschte (verlorene Konflikte blieben für immer offen). (2) `ConflictResolver` verglich
|
||
`local.Timestamp` (aus LiteDB, `Kind=Local` mit verschobenen Ticks) direkt mit
|
||
`remote.Timestamp` (`Kind=Utc`) — `DateTime`-Vergleiche ignorieren `Kind` und vergleichen
|
||
nur rohe Ticks, wodurch die Gleichstand-Regel außerhalb von UTC+0 falsch entschied. Fix:
|
||
`.ToUniversalTime()` auf beiden Seiten vor dem Vergleich.
|
||
|
||
### 13.2 Fehlerbehandlung & Logging
|
||
- [x] **13.2.1** Zentrale Exception-Behandlung mit verständlicher Fehlermeldung statt Absturz —
|
||
[GlobalExceptionHandler.cs](LehrerApp.Desktop/Services/GlobalExceptionHandler.cs).
|
||
`Dispatcher.UIThread.UnhandledException` fängt Fehler aus Befehlen/Ereignis-Handlern auf
|
||
dem UI-Thread ab, protokolliert sie und setzt `Handled = true` — die App stürzt dabei
|
||
nachweislich nicht ab (per Headless-Test verifiziert: Fehler in einem Dispatcher-Callback
|
||
wird geloggt + als Toast angezeigt, App läuft weiter). `AppDomain.UnhandledException` und
|
||
`TaskScheduler.UnobservedTaskException` sind Sicherheitsnetze für Fehler außerhalb des
|
||
UI-Threads — dort kann ein bereits "IsTerminating"-Fehler nicht mehr verhindert werden,
|
||
wird aber vollständig protokolliert.
|
||
- [x] **13.2.2** Logging in Datei im App-Datenverzeichnis, mit Rotation —
|
||
[AppLogger.cs](LehrerApp.Core/Services/AppLogger.cs), tägliche Datei unter
|
||
`<AppData>/LehrerApp/logs/`, Dateien älter als 14 Tage werden beim Start gelöscht.
|
||
6 Tests in [AppLoggerTests.cs](LehrerApp.Tests/AppLoggerTests.cs).
|
||
- [x] **13.2.3** Einheitliche Benachrichtigungen (Toast/Snackbar) für Erfolg und Fehler —
|
||
[NotificationService.cs](LehrerApp.Desktop/Services/NotificationService.cs), Overlay unten
|
||
rechts in [MainWindow.axaml](LehrerApp.Desktop/Views/MainWindow.axaml), blendet sich nach
|
||
3 s (Erfolg) bzw. 6 s (Fehler) automatisch aus. Aktuell an den globalen Exception-Handler
|
||
angebunden; bestehende Dialoge zeigen Erfolg/Fehler weiterhin über ihre eigenen
|
||
Statuszeilen (`StatusMessage`/`ValidationMessage`) — eine Umstellung dieser bestehenden
|
||
Stellen auf Toasts wäre ein eigener, größerer Umbau über viele Dateien hinweg und ist
|
||
bewusst nicht Teil dieser Aufgabe.
|
||
- [x] **13.2.4** Validierungsmeldungen einheitlich an den Eingabefeldern statt in Sammel-Labels.
|
||
Alle Dialoge mit Formularfeldern umgestellt: `AddStudentDialog`, `ContactEditDialog`,
|
||
`AddGroupDialog`, `StudentGradesDialog` (`GradeEditItem`), `CollectiveGradeDialog`,
|
||
`ExamDialog`, `AddSessionDialog`, `ParticipationWizardDialog` (Abschnitt-Formular),
|
||
Einstellungen (Fach anlegen, Notenschlüssel-Vorlage anlegen, Notenschlüssel-Editor).
|
||
Muster: pro Feld eine `{Feld}Error`-Property, `Save()` leert alle Fehler-Properties am
|
||
Anfang, sammelt alle Verstöße über eine lokale `valid`-Variable statt beim ersten Fehler
|
||
zurückzukehren, und bricht erst am Ende mit `if (!valid) return;` ab — so werden mehrere
|
||
Fehler gleichzeitig angezeigt. Bewusst als Sammel-Meldung belassen, wo die Meldung sich auf
|
||
eine Kombination mehrerer Felder bezieht statt auf ein einzelnes Feld: `GradingKeyValidation`
|
||
(Notenschlüssel-Tabelle als Ganzes), `GradingSchemeEditItem.ValidationMessage`
|
||
(Summe der drei Prozent-Felder muss 100 ergeben), `ReportGradeRow.ValidationMessage`
|
||
(Override-Wert + Begründung gehören zusammen), `CatalogValidation`
|
||
(Kompetenzkatalog-Panel: Fachauswahl, Bereichsname und JSON-Import teilen sich einen
|
||
Status-Bereich), `AddStudentToGroupDialogViewModel.ValidationMessage` (einzige Prüfung
|
||
"Schüler ausgewählt?", kein Textfeld zum Andocken vorhanden).
|
||
|
||
### 13.3 Datensicherheit
|
||
- [x] **13.3.1** Automatisches lokales Backup der LiteDB beim Start (rollierend, letzte 10) —
|
||
[BackupService.cs](LehrerApp.Core/Services/BackupService.cs). Reine Dateikopie nach
|
||
`<AppData>/LehrerApp/backups/`, läuft in `AppBootstrapper.BuildServices()` **vor** dem
|
||
Öffnen der Datenbank (unabhängig von Verschlüsselung, kein LiteDB-Handle nötig). Behält
|
||
standardmäßig die letzten 10 Backups, ältere werden entfernt. 6 Tests in
|
||
[BackupServiceTests.cs](LehrerApp.Tests/BackupServiceTests.cs).
|
||
- [x] **13.3.2** Wiederherstellung aus einem Backup über die Einstellungen — neuer Tab
|
||
"Sicherheit" in [SettingsView.axaml](LehrerApp.Desktop/Views/Settings/SettingsView.axaml)
|
||
listet vorhandene Backups mit Zeitstempel/Größe, "Wiederherstellen" fragt über einen neuen
|
||
generischen [ConfirmDialog](LehrerApp.Desktop/Views/Shared/ConfirmDialog.axaml) nach,
|
||
kopiert das Backup über die aktive Datenbankdatei und startet die App danach automatisch
|
||
neu (`AppBootstrapper.RestartApplication()`) — ein laufender LiteDB-Verbindung kann nicht
|
||
sicher "heiß" auf eine andere Datei umgehängt werden.
|
||
- [x] **13.3.3** Schema-Migration mit Versionsnummer — `LiteDbContext` schreibt die
|
||
Schema-Version in eine `meta`-Collection und führt Migrationsschritte nur noch aus, wenn
|
||
die gespeicherte Version dahinter liegt (`RunVersionedMigrations`), statt wie bisher bei
|
||
jedem Start erneut über alle Daten zu laufen. Die bestehenden (bereits idempotenten)
|
||
Migrationsschritte wurden als Version-1-Schritt gebündelt, für zukünftige
|
||
Schema-Änderungen ergänzt man einen weiteren `if (version < N)`-Block. 2 Tests in
|
||
[LiteDbContextTests.cs](LehrerApp.Data.Tests/LiteDbContextTests.cs).
|
||
- [x] **13.3.4** Optionale Verschlüsselung der lokalen Datenbank —
|
||
[DatabaseEncryptionService.cs](LehrerApp.Data/DatabaseEncryptionService.cs). Passwort
|
||
setzen/ändern/entfernen läuft über eine Kopie (neue Datei mit Zielpasswort anlegen, alle
|
||
Collections umkopieren, Datei austauschen) statt über `LiteDatabase.Rebuild(...)` mit
|
||
Passwort — das ist in LiteDB 5.0.21 nachweislich fehlerhaft (per Skript verifiziert: wirft
|
||
"this data file is encrypted" beim Rebuild einer unverschlüsselten Datei). Ist die
|
||
Datenbank verschlüsselt, fragt ein eigenes Fenster
|
||
([DbPasswordPromptWindow](LehrerApp.Desktop/Views/DbPasswordPromptWindow.axaml)) das
|
||
Passwort ab, **bevor** `AppBootstrapper.BuildServices()` (und damit das Öffnen der
|
||
Datenbank) läuft — siehe `App.axaml.cs`. Ändern/Entfernen des Passworts läuft über
|
||
Einstellungen → Sicherheit, jeweils mit Neustart der App danach. 4 Tests in
|
||
[DatabaseEncryptionServiceTests.cs](LehrerApp.Data.Tests/DatabaseEncryptionServiceTests.cs).
|
||
- [x] **13.3.5** App-Sperre nach Inaktivität —
|
||
[AppLockService.cs](LehrerApp.Core/Services/AppLockService.cs) (eigenes, gesalzenes
|
||
PBKDF2-Passwort, unabhängig von einer eventuellen Datenbank-Verschlüsselung) +
|
||
[AppLockViewModel.cs](LehrerApp.Desktop/ViewModels/AppLockViewModel.cs) (Inaktivitäts-Timer,
|
||
Sperrbildschirm-Logik). Maus-/Tastatureingaben im Hauptfenster setzen den Timer zurück
|
||
([MainWindow.axaml.cs](LehrerApp.Desktop/Views/MainWindow.axaml.cs)); läuft er ab, blendet
|
||
ein Overlay in [MainWindow.axaml](LehrerApp.Desktop/Views/MainWindow.axaml) die gesamte
|
||
Oberfläche aus, bis das Passwort stimmt. Einstellbar (aktiv/inaktiv, Zeit, Passwort) über
|
||
Einstellungen → Sicherheit, wirkt sofort ohne Neustart. 2 Tests in
|
||
[AppLockViewModelTests.cs](LehrerApp.Desktop.Tests/AppLockViewModelTests.cs) (reine
|
||
Unlock-Logik; der zeitbasierte Inaktivitäts-Timer selbst ist nicht automatisiert getestet).
|
||
**Hinweis:** `RestartApplication()` startet den Prozess über `Environment.ProcessPath`
|
||
neu — im veröffentlichten Programm korrekt, im Entwicklungsbetrieb über `dotnet run`
|
||
zeigt `ProcessPath` auf den `dotnet`-Host statt auf die App, ein Neustart über die
|
||
Einstellungen ist dort also nur in einer veröffentlichten Build (`dotnet publish`)
|
||
sinnvoll zu testen.
|
||
|
||
### 13.4 Codepflege
|
||
- [x] **13.4.1** `CLAUDE.md` mit Projektkonventionen anlegen (`/init`) — [CLAUDE.md](CLAUDE.md).
|
||
- [ ] **13.4.2** `AllRepositories.cs` und `IRepositories.cs` in Themendateien aufteilen,
|
||
sobald weitere Repositories dazukommen. Aktuell (319 bzw. 154 Zeilen für ~20 Repositories)
|
||
noch nicht unübersichtlich genug, um die Bedingung auszulösen — bewusst zurückgestellt.
|
||
- [x] **13.4.3** Wiederkehrende UI-Muster als wiederverwendbare Controls/Styles.
|
||
Bestandsaufnahme vor der Umsetzung ergab drei echte Duplikate (Suchleiste dagegen nur 3×
|
||
und jedes Mal eine simple `TextBox` ohne gemeinsames Chrome — Extraktion lohnt sich dort
|
||
nicht):
|
||
- Seiten-Kopfzeile (Titel 22px SemiBold + optionaler Untertitel) war identisch in
|
||
`GroupListView`, `StudentListView`, `GroupDetailView`, `StudentDetailView`,
|
||
`SettingsView` nachgebaut → neue
|
||
[PageHeader](LehrerApp.Desktop/Views/Shared/PageHeader.axaml)-Control, dort eingesetzt.
|
||
- Dialog-Titel (`FontSize="18" FontWeight="SemiBold"` als erstes Element) kam in 16
|
||
Dialogen jeweils inline vor → globale Style-Klasse `TextBlock.dialogtitle`
|
||
([App.axaml](LehrerApp.Desktop/App.axaml)).
|
||
- Leerlisten-Hinweis ("Noch keine …") kam an 10 Stellen vor, dabei war Opacity/FontSize
|
||
bereits leicht auseinandergedriftet (0.35 vs. 0.4, 12 vs. 13) → globale Style-Klasse
|
||
`TextBlock.emptyhint`, normalisiert alle Stellen auf einen Wert.
|
||
Absichtlich nicht angefasst: die vier Views mit eigenen lokalen `<Style Selector=>`-Blöcken
|
||
(MainWindow, DashboardView, StudentDetailView, ExamEvaluationDialog) sind jeweils
|
||
einzigartige Spezial-Visualisierungen (Kalenderzellen, Sparkline, Balkendiagramm,
|
||
Toast/Drawer) ohne Duplikate untereinander.
|
||
- [x] **13.4.4** Konverter und Styles zentralisieren. Bei der Bestandsaufnahme für 13.4.3 zeigte
|
||
sich: es gibt keine einzige eigene `IValueConverter`-Implementierung im Projekt — überall
|
||
werden bereits konsistent Avalonias eingebaute statische Konverter (`StringConverters`,
|
||
`BoolConverters`, `ObjectConverters`) verwendet. Nichts zu zentralisieren; die
|
||
Style-Duplikate wurden im Zuge von 13.4.3 behoben (siehe oben).
|
||
|
||
---
|
||
|
||
## 14. UX-Querschnitt
|
||
|
||
- [ ] **14.1** Tastaturbedienung durchgängig: alle Hauptfunktionen ohne Maus erreichbar
|
||
(Vorbild: Mitarbeit-Schnelleingabe).
|
||
- [ ] **14.2** Globale Suche (Schüler, Gruppe, Klausur) über Tastenkürzel.
|
||
- [ ] **14.3** Rückgängig-Funktion für Löschvorgänge (mindestens Bestätigungsdialog überall).
|
||
- [ ] **14.4** Ladeanzeigen bei längeren Operationen (Import, Sync, Export).
|
||
- [ ] **14.5** Leere Zustände mit Handlungsaufforderung statt leerer Tabellen.
|
||
- [ ] **14.6** Fenstergröße und Spaltenbreiten über Sitzungen hinweg merken.
|
||
- [ ] **14.7** Bedienung auf Touch-Geräten prüfen (Tablet im Unterricht).
|
||
|
||
---
|
||
|
||
## 15. Auslieferung
|
||
|
||
- [ ] **15.1** Release-Build und Signierung für macOS.
|
||
- [ ] **15.2** Windows-Build prüfen (Zielplattform klären).
|
||
- [ ] **15.3** Versionierung und Changelog-Pflege.
|
||
- [ ] **15.4** Update-Mechanismus oder zumindest Versionsprüfung beim Start.
|
||
- [ ] **15.5** Kurze Bedienanleitung für den Eigengebrauch.
|
||
|
||
---
|
||
|
||
## Empfohlene Reihenfolge
|
||
|
||
Die Abschnitte sind thematisch, nicht chronologisch nummeriert. Sinnvolle Bearbeitungsreihenfolge:
|
||
|
||
1. **Kapitel 1** (Klausuren) — größte funktionale Lücke, viele andere Punkte hängen daran.
|
||
2. **Kapitel 3.2** (Mitarbeit-Aggregation) — kurz, macht das bestehende Feature erst nutzbar.
|
||
3. **Kapitel 2** (Noten & Zeugnisnoten) — braucht 1 und 3.2 als Datenquellen.
|
||
4. **Kapitel 13.1–13.2** (Tests, Fehlerbehandlung) — bevor die Codebasis weiter wächst.
|
||
5. **Kapitel 4** (Planung) und **Kapitel 5** (Dokumentation) — unabhängig, gut parallelisierbar.
|
||
6. **Kapitel 6** (Arbeitszeit), **11** (Export), **10** (Sync) — danach.
|