Stundenverlaufsplan: Viewer und Alternativpfad-Katalog (Kapitel 4.2 Nachtrag)

Schreibgeschützter LessonViewerDialog (größere Schrift, ohne Bearbeitungs-/Verlängern-/
Verschieben-Funktion) für den Einsatz während des Unterrichtens, erreichbar über "Anzeigen"
im Stunden-Toolbar.

Alternative Unterrichtsabläufe (z.B. Kurzversion bei Zeitmangel) laufen jetzt über einen
echten Katalog (neues Modell AlternativeLessonPath: Name + Beschreibung) statt Freitext direkt
an der Phase: im Verlaufsplan-Editor eine kompakte, farbig unterstützte Checkbox statt einer
durchgehend sichtbaren Eingabespalte, Zuordnung/Neuanlage über einen eigenen Dialog. Der Viewer
gruppiert Phasen entsprechend und zeigt die hinterlegte Beschreibung. Schema-Migration v3→v4
führt bestehende Freitextwerte verlustfrei in Katalogeinträge über.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 01:53:12 +02:00
co-authored by Claude Sonnet 5
parent de6ea001e7
commit ee1a47641e
22 changed files with 904 additions and 33 deletions
+20 -6
View File
@@ -100,8 +100,17 @@ der Praxis ist es mal ein Materialfluss-Pfeil ("AB001->S"), mal nur eine Sozialf
Stunden verwendete Werte dienen nur als Autovervollständigungs-Vorschläge, erzwingen aber keine
Struktur.
`LiteDbContext`-Schema-Version 3 führt zwei aufeinanderfolgende, unabhängig versionierte
Migrationsschritte für dieses Feld:
`AlternativePathId` (`Guid?`, `null` = Hauptweg) verweist auf einen Eintrag im eigenständigen
Katalog `AlternativeLessonPath` (Name + optionale `Description`, verwaltet über
`IAlternativeLessonPathRepository`) — anders als `Shorthand` bewusst kein Freitext direkt am
Phasen-Datensatz: die Zuordnung muss zuverlässig gruppierbar sein (`LessonViewerViewModel`
gruppiert danach für die Anzeige) und soll eine wiederverwendbare Erklärung tragen können ("wann
nimmt man diesen Weg"), was ein reines Freitextfeld nicht sauber leisten kann. Kein
Fork-Punkt-Bezug zum Hauptweg: jede Gruppe wird beim Anzeigen unabhängig ab `Lesson.StartTime`
durchgerechnet, nicht ab einer gemeinsamen Verzweigungsstelle.
`LiteDbContext`-Schema-Version 4 führt drei aufeinanderfolgende, unabhängig versionierte
Migrationsschritte für dieses Feld bzw. seine Vorstufen:
- **v1→v2** (`MigrateLessonPhases()`): führt bereits gespeicherte alte Stunden (einzelnes
`Phase`-Feld, `Methods`/`Materials`-Listen) verlustfrei in eine einzige synthetisierte
`LessonPhaseStep`-Zeile zusammen (`Name` = altes `Phase`, `Activity` = alte `Methods` verbunden,
@@ -109,11 +118,16 @@ Migrationsschritte für dieses Feld:
- **v2→v3** (`MigrateLessonShorthand()`): das ursprünglich als Von/Nach-Paar (`ShorthandFrom`/
`ShorthandTo`) modellierte Kurzsymbol wird auf das einzelne Freitextfeld zusammengeführt (beide
gesetzt → `"Von->Nach"`, nur eines gesetzt → dieser Einzelwert).
- **v3→v4** (`MigrateLessonAlternativePaths()`): das ursprünglich als Freitext (`AlternativePath`,
string) modellierte Kennzeichen für den alternativen Ablauf wird pro distinktem Namen zu einem
`AlternativeLessonPath`-Katalogeintrag zusammengeführt (derselbe Name über mehrere Stunden hinweg
referenziert denselben, wiederverwendeten Eintrag) und die Phase auf `AlternativePathId`
umgestellt.
Beide Migrationen lesen dafür die rohe `BsonDocument`-Repräsentation der `lessons`-Collection statt
der typisierten `Lessons`-Collection — nach jeder Modelländerung kennt die typisierte `Lesson`-
Klasse die alten Feldnamen nicht mehr, ein Zugriff darüber hätte sie beim Deserialisieren bereits
verworfen, bevor sie gelesen werden können.
Alle drei Migrationen lesen dafür die rohe `BsonDocument`-Repräsentation der `lessons`-Collection
statt der typisierten `Lessons`-Collection — nach jeder Modelländerung kennt die typisierte
`Lesson`-Klasse die alten Feldnamen nicht mehr, ein Zugriff darüber hätte sie beim Deserialisieren
bereits verworfen, bevor sie gelesen werden können.
## Eindeutige Schlüssel