Add tmpdata/ to .gitignore
Add design principles section to projektplan.md
This commit is contained in:
@@ -35,6 +35,22 @@ Webinterface (Browser) → nginx → Axum (SSE für Live-Updates)
|
||||
|
||||
---
|
||||
|
||||
## Design-Prinzipien
|
||||
|
||||
### Filesystem ist Source of Truth (SoT)
|
||||
|
||||
Der Zustand eines Falls wird **ausschließlich aus dem Dateisystem** abgeleitet, nicht aus einer parallelen Sidecar- oder Metadaten-Datei. Ordnerlage (`open/` vs. `done/`) plus Dateiexistenz (`.m4a`, `.transcript.txt`, `oneliner.txt`, `document_vN.md`, `.remove`) bestimmen jederzeit eindeutig, was als Nächstes zu tun ist.
|
||||
|
||||
**Konsequenzen**:
|
||||
- Keine State-Duplizierung (kein `state.json`, keine DB). Der zu synchronisierende Zweitstand fehlt ersatzlos — also kann er auch nicht drift.
|
||||
- Recovery-Scan nach Restart ist trivial: finde `.m4a` ohne `.transcript.txt` → transkribieren. Natürliche Idempotenz, kein Crash-Recovery-Protokoll.
|
||||
- Crash mitten in Whisper = `.transcript.txt` fehlt = nächster Lauf macht's nochmal. Keine Intermediate-States, die rückwärts abgewickelt werden müssten.
|
||||
- Manuelle Reparatur möglich: Datei löschen, neu triggern. Kein „state irgendwie auf Received setzen".
|
||||
|
||||
**Bewusst verzichtet** auf: retry-Budget, Failed-Kategorie mit Error-Details. Wenn ein Audio dauerhaft an Whisper scheitert, loggt der Server im Crash-Loop — das fällt sofort auf und wird manuell entfernt. Diese Kategorie wird erst eingeführt, wenn ein realer Bedarf entsteht (z.B. hochvolumiger Betrieb).
|
||||
|
||||
---
|
||||
|
||||
## Komponenten
|
||||
|
||||
### 1. Pixel Watch App (Wear OS / Kotlin)
|
||||
@@ -882,3 +898,4 @@ axum-extra = { version = "0.12", features = ["cookie"] } # passend zu axum 0.8
|
||||
| Test-Client für Watch-Flow | Erst ab Phase 5 mit echter Hardware | `scripts/dictate.sh` ab Phase 2/3 als Stand-in (ffmpeg + curl + interaktiver c/n/r/q-Loop) | Erlaubt End-to-End-Tests der Server-Pipeline ohne Watch-Hardware, solange die Pixel Watch nicht verfügbar ist. |
|
||||
| Admin-Log vs. Arzt-UI | Nur Arzt-UI geplant | Zusätzlich frühes Admin-Log unter `/web/` (flache Liste aller Fälle, Transkripte, Oneliner) | Gebaut, bevor das Arzt-UI (Session, States, Fall-Detail) existiert, um die Pipeline während Entwicklung inspizieren zu können. Soll bleiben, aber später hinter `role = "admin"` geschützt; das Arzt-UI wird separat entwickelt. |
|
||||
| Hotwords | Nicht vorgesehen | Per-User-Feld `[user.whisper].hotwords` bleibt **im Code**, wird aber **nicht als Feature angeboten** | Erstes Ad-hoc-Experiment sah 8/8 vs. 3/8 aus. Regress-Lauf über 10 kuratierte Fixtures (`scripts/regress_whisper.sh`) widerlegte das: ohne Hotwords 12/257 Wortfehler (~4.7% WER), mit Hotwords 14/257 — leicht schlechter. Hotwords schluckten sogar Funktionswörter wie „Beginn mit" und „mittels". Kein belegter Nutzen, dafür zusätzliche Bedienkomplexität pro Arzt. KISS: wir lassen die Leitung durchverdrahtet (kein Code-Rückbau), aber bewerben/konfigurieren es nicht. Re-evaluiert, sobald ein konkreter Fachvokabular-Bedarf auftaucht. |
|
||||
| Case-State-Machine | Nicht vorgesehen | **Verworfen**: explizite State-Machine + `state.json`-Sidecar (Received/Transcribing/Transcribed/Evaluating/Evaluated/Closed/Failed) wurde gebaut und nach Live-Test wieder entfernt. FS bleibt einzige Wahrheitsquelle. | Der Sidecar führte sofort zu Datendrift: bei jeder Schema-/Code-Änderung waren Bestandsfälle inkonsistent (State sagt „fertig", aber `.m4a` ohne `.transcript.txt` vorhanden). Recovery hätte Self-Healing-Checks gegen die FS-Invariante gebraucht — womit `state.json` zur bloßen Cache-Kopie wird und ihre eigentliche Daseinsberechtigung verliert. Erkenntnis in `docs/projektplan.md` → „Design-Prinzipien: Filesystem ist SoT" festgehalten. |
|
||||
|
||||
Reference in New Issue
Block a user