fix: personenbezogene Daten aus Companion-Klartextkanal ausschließen

- PlainEventStore.Allowed: Grade/ExamResult entfernt (beide tragen
  StudentId + Notenwert/-kommentar, PlainSyncEvent.Payload läuft aber
  als Klartext-JSON über den Server, anders als der AES-256-GCM-
  verschlüsselte Desktop-Kanal). Nur noch WorkTask/Lesson erlaubt.
- Regressionstest PlainEventStoreTests ergänzt.
- TODO.md 10.3.3 abgehakt, inkl. deutlichem Warnhinweis: die geplante
  Mitarbeitsnoten-Erfassung per Companion-App ist damit bewusst
  blockiert, bis 10.3.1 (Schlüsselaustausch) + eine echte Payload-
  Verschlüsselung für PlainSyncEvent existieren.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 23:27:08 +02:00
co-authored by Claude Sonnet 5
parent e679be7e9d
commit 858499e8ec
3 changed files with 77 additions and 4 deletions
+19 -2
View File
@@ -1411,8 +1411,25 @@ die Docker-Verifikation unter 10.2.4 (kein Docker im Entwicklungsstand verfügba
### 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.
- [x] **10.3.3** Prüfen, welche Daten unverschlüsselt über `PlainEventStore` laufen —
personenbezogene Daten dürfen das nicht. `Grade`/`ExamResult` (beide mit `StudentId` plus
Notenwert/-kommentar) trugen bisher personenbezogene Daten im Klartext über den
Companion/WebApp-Kanal (`PlainSyncEvent.Payload` ist unverschlüsseltes JSON, anders als der
AES-256-GCM-verschlüsselte Desktop-Kanal — der Server sieht den Klartext also nicht nur
während der Übertragung, sondern speichert ihn auch dauerhaft unverschlüsselt in der
EventStore-Collection). Aus `PlainEventStore.Allowed` entfernt — nur noch `WorkTask`/`Lesson`
(reine Lehrer-Planungsdaten ohne `StudentId`) laufen über diesen Kanal.
> ⚠️ **BEWUSSTE BLOCKADE, gehört zu geplanter Companion-App-Funktion:** Mitarbeitsnoten
> sollen laut Plan später über eine Companion-App erfassbar sein — das ist genau `Grade` mit
> `Category = Participation`. **Das geht mit dem aktuellen Stand nicht**, und zwar absichtlich:
> `PlainEventStore.Push` lehnt `Grade`/`ExamResult`-Events NICHT mit einem Fehler/4xx ab,
> sondern **schluckt sie still** — `Success = true`, das Event landet nur in
> `RejectedEventIds` statt gespeichert zu werden. Wer das nicht kennt, sucht stundenlang,
> warum Mitarbeitsnoten aus der Companion-App im Server nie ankommen. Bevor eine
> Companion-App Noten schreiben soll, muss zuerst 10.3.1 (Schlüsselaustausch) + eine echte
> Payload-Verschlüsselung für `PlainSyncEvent` gebaut werden — erst danach `Grade` wieder in
> `PlainEventStore.Allowed` aufnehmen.
- [ ] **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