Baustein 7: TODO.md-Korrektur (Kapitel 10)
- 10.1.4/10.1.5 abgehakt (SyncStatusViewModel/SyncStatusBar waren bereits vorhanden, aber in der Checkliste noch nicht als erledigt markiert) - 10.1.6 abgehakt mit Umsetzungsnotiz (Baustein 2-4) - Neuer Punkt 10.1.7 fuer den zuvor komplett fehlenden, in der Checkliste nicht erfassten Inbound-Apply-Baustein (Baustein 5) - Neuer Punkt 10.1.8 fuer Anhang-Sync (Baustein 6) - 10.2.1 abgehakt mit Umsetzungsnotiz (Baustein 1) - Neuer Punkt 10.3.4 fuer die bewusst akzeptierte v1-Einschraenkung beim Regel-Bypass im Event-Applier Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1306,14 +1306,67 @@ ist aber nur aktiv, wenn eine Server-URL konfiguriert ist.
|
||||
- [ ] **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.1.6** Lokale Schreibvorgänge atomar an die Outbox (`EventQueue`) anbinden — aktuell ist
|
||||
- [x] **10.1.4** Manuelles Auslösen einer vollständigen Synchronisation.
|
||||
|
||||
**Umsetzung:** War bereits vorhanden (`SyncStatusViewModel.SyncNowCommand`,
|
||||
`SyncStatusBar` in `MainWindow.axaml`), nur hier noch nicht abgehakt.
|
||||
- [x] **10.1.5** Statusanzeige erweitern: letzter Sync, Anzahl wartender Events, Fehlerzustand.
|
||||
|
||||
**Umsetzung:** War bereits vorhanden (`SyncStatusViewModel`/`SyncStatusBar`), nur hier noch
|
||||
nicht abgehakt.
|
||||
- [x] **10.1.6** Lokale Schreibvorgänge atomar an die Outbox (`EventQueue`) anbinden — aktuell ist
|
||||
das Sync-Grundgerüst registriert, die Repositories erzeugen aber noch keine Sync-Ereignisse.
|
||||
|
||||
**Umsetzung:** `LiteDbContext.OnChange`-Hook (Sync-agnostisch, kein Verweis auf
|
||||
`LehrerApp.Sync` aus `LehrerApp.Data`) — alle 27 Repositories rufen ihn nach Save/Delete auf,
|
||||
Kaskaden (`GroupRepository.Delete` u.a.) und Batch-Methoden (`SaveMany`/`DeleteBySession`)
|
||||
feuern genau ein Ereignis pro betroffener Entität statt pro Collection-Zugriff. In
|
||||
`AppBootstrapper` an `SyncEventPublisher.Publish` gehängt, das den Hook in ein
|
||||
AES-verschlüsseltes `EventQueue.Enqueue` übersetzt.
|
||||
- [x] **10.1.7** Eingehende Sync-Ereignisse tatsächlich auf die lokale Datenbank anwenden.
|
||||
|
||||
Bisher komplett fehlender, in dieser Checkliste nicht erfasster Baustein: selbst mit 10.1.6
|
||||
hätte `SyncEngine.PullAsync` empfangene Ereignisse nur zur Konflikterkennung genutzt, nie in
|
||||
die lokale LiteDB geschrieben — ankommende Änderungen von anderen Geräten wären nirgends
|
||||
sichtbar geworden.
|
||||
|
||||
**Umsetzung:** Neu `LehrerApp.Sync/EventApplier.cs` — entschlüsselt, dispatcht über eine
|
||||
explizite `EntityType`-Tabelle, schreibt **immer direkt auf die rohe LiteDB-Collection**,
|
||||
nie über eine Repository-Save/Delete-Methode (sonst würde der 10.1.6-Hook die gerade
|
||||
angewendete Änderung als neues ausgehendes Ereignis re-enqueuen — Sync-Ping-Pong). Ein
|
||||
gemeinsames Suppress-Flag wurde geprüft und verworfen (Timer-Thread vs. UI-Thread — ein Flag
|
||||
könnte einen echten Nutzer-Save währenddessen verschlucken); der direkte Collection-Zugriff
|
||||
ist zustandslos und dadurch korrekt. Kaskaden-Fälle nutzen dieselben internen
|
||||
`LiteDbContext`-Hilfsmethoden wie die Repositories. Mit dediziertem Loop-Prevention-Test
|
||||
abgesichert (`EventApplierTests`).
|
||||
|
||||
**Bekannte v1-Einschränkung:** weiche Geschäftsregeln (`ArchivedGroupWriteGuard`,
|
||||
Namens-Eindeutigkeit bei Aspekten u.ä.) werden auf diesem Pfad nicht geprüft — nur harte
|
||||
LiteDB-Unique-Constraints greifen noch und führen zum Überspringen des einzelnen Ereignisses.
|
||||
Für Einzel-/Wenig-Geräte-Nutzung akzeptiert, siehe 10.3.4.
|
||||
- [x] **10.1.8** Datei-Anhänge (Dokumentation) über den laufenden Sync mitschicken.
|
||||
|
||||
**Umsetzung:** Eigener, unverschlüsselt im JSON-Ereigniskanal nicht mitgeführter Binärkanal
|
||||
(würde ihn für Fotos/Scans stark aufblähen) — neue Endpunkte
|
||||
`POST/GET /api/sync/attachments/{storageId}` in `LehrerApp.Api`, neue
|
||||
`EventQueue`-Warteliste für ausstehende Uploads, `AttachmentSyncer` (Upload, in
|
||||
`SyncEngine.SyncNowAsync` nach dem Event-Push) und `EventApplier` (Download fehlender
|
||||
Anhänge nach Anwenden eines `Documentation`-Ereignisses). Original-`StorageId` bleibt beim
|
||||
Download erhalten (roher `db.Attachments.Upload`-Aufruf statt `IAttachmentStorage.Upload`,
|
||||
das immer eine neue Id vergäbe).
|
||||
|
||||
### 10.2 Server
|
||||
- [ ] **10.2.1** Benutzerverwaltung/Registrierung prüfen und absichern
|
||||
- [x] **10.2.1** Benutzerverwaltung/Registrierung prüfen und absichern
|
||||
([Endpoints.cs](LehrerApp.Api/Endpoints/Endpoints.cs)).
|
||||
|
||||
**Umsetzung:** `/api/auth/login` und `/api/auth/register` akzeptierten zuvor jeden
|
||||
beliebigen Nutzernamen/Passwort und stellten ein gültiges 30-Tage-JWT aus (unadressierte
|
||||
`// TODO`-Kommentare im Code) — konkrete, ausnutzbare Lücke bei echtem Deployment. Neu
|
||||
`PasswordHasher` (PBKDF2, Salt pro Nutzer — kein neues NuGet-Paket, gleiche BCL-Technik wie
|
||||
`SyncCrypto`) und `UserStore` (LiteDB-Collection `users`). `/api/auth/register` ersatzlos
|
||||
entfernt (kein offener Registrierungs-Endpunkt für ein Einzel-/Familien-Deployment); neue
|
||||
Nutzer werden per CLI angelegt (`dotnet LehrerApp.Api.dll create-user <name>`, dokumentiert
|
||||
in `docker/README.md`), damit keine zusätzliche unauthentifizierte Angriffsfläche entsteht.
|
||||
- [ ] **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.
|
||||
@@ -1323,6 +1376,12 @@ ist aber nur aktiv, wenn eine Server-URL konfiguriert ist.
|
||||
- [ ] **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.
|
||||
- [ ] **10.3.4** Bekannte v1-Einschränkung aus 10.1.7: weiche Geschäftsregeln greifen beim Anwenden
|
||||
eingehender Sync-Ereignisse nicht, nur harte LiteDB-Unique-Constraints. Bei mehreren eigenen
|
||||
Geräten in Randfällen möglich, dass sich Datenstände leicht unterscheiden. Für v1 bewusst
|
||||
akzeptiert (Einzel-/Wenig-Geräte-Nutzung) — falls das je zum echten Problem wird, müsste der
|
||||
Event-Applier dieselben Validierungen wie die Repository-Save-Methoden durchlaufen, ohne
|
||||
dabei erneut ein Sync-Ereignis auszulösen.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user