Table of Contents
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Architektur
Datenfluss
PWA (Mikro/Text)
│ Audio bzw. Text (+ OIDC-Bearer-Token)
▼
FastAPI Backend
│
├─► faster-whisper Audio → Text (deutsch) [nur bei Sprachaufnahme]
│
├─► OpenRouter LLM Text → strukturiertes JSON
│
▼
Review-Karte (Frontend) Nutzer bestätigt / korrigiert
│
▼
CalDAV → Nextcloud VEVENT (Termin) / VTODO (Aufgabe)
authentik (OIDC) hängt vorne an PWA und Backend: die PWA holt per Authorization Code + PKCE ein Token, das Backend validiert es bei jedem Request gegen die JWKS von authentik.
Komponenten
| Teil | Technik | Aufgabe |
|---|---|---|
| Frontend | React + Vite + vite-plugin-pwa | Erfassung, Review, Einstellungen, PWA-Installierbarkeit |
| Backend | FastAPI | Orchestrierung, Token-Prüfung |
| STT | faster-whisper (large-v3-turbo) |
Audio → Text |
| LLM | OpenRouter (OpenAI-kompatibel) | Text → strukturierter Eintrag |
| Kalender | CalDAV (python caldav + icalendar) |
Schreiben in Nextcloud |
| Auth | authentik OIDC | Zugangsschutz |
Wichtige Designentscheidungen
- Single-Tenant: genau eine Nextcloud. Die CalDAV-Zugangsdaten liegen als Secret in der
.env(Nextcloud-App-Passwort) – kein verschlüsselter Pro-Nutzer-Speicher, keine eigene Datenbank nötig. - OIDC ≠ CalDAV-Auth: OIDC sichert nur die App. Das Schreiben in die Nextcloud läuft über das CalDAV-App-Passwort, da Nextcloud-CalDAV kein OIDC spricht.
- Review-Schritt ist Pflicht: STT und LLM können sich bei Eigennamen und Uhrzeiten irren. Vor dem Schreiben sieht der Nutzer das Ergebnis und kann es korrigieren.
- Relative Zeiten: Das Backend gibt dem LLM den aktuellen Zeitpunkt, Wochentag und die Zeitzone mit, damit Angaben wie „morgen 15 Uhr" korrekt aufgelöst werden.
- Konfigurierbares Modell: Das LLM-Modell wird nicht hart kodiert, sondern zur Laufzeit aus einer kleinen JSON-Datei gelesen und ist über die Einstellungen in der App umstellbar.
Container
docker compose startet zwei Dienste:
- backend – FastAPI/uvicorn, intern auf Port 8000, mit Volumes für den Whisper-Modell-Cache und die Laufzeit-Einstellungen.
- frontend – nginx, liefert das gebaute React-Bundle aus und proxyt
/apiintern auf das Backend. Nach außen ist nur dieser Dienst (Port 8080) sichtbar – davor gehört ein Reverse Proxy mit HTTPS.