# 🧩 Functioneel Ontwerp (FO) – Real-Time Speech Transcription met Deepgram SDK **Projectnaam:** Real-Time Speech Transcription **Versie:** v2.0 (Editor-First Design) **Datum:** 24-11-2025 **Auteur:** Claude Code (met input van Colin) --- ## 1. Doel en relatie met het PRD 🎯 **Doel van dit document:** Dit Functioneel Ontwerp beschrijft de migratie van de huidige REST-based batch transcriptie naar real-time streaming transcriptie met de Deepgram SDK. Het document legt uit **hoe** de gebruiker (clinicus/behandelaar) de nieuwe real-time speech-to-text functionaliteit zal ervaren tijdens het dicteren van medische rapportages en behandelplannen. πŸ“˜ **Context:** - **Huidige situatie:** Audio wordt opgenomen als blob, na opname geΓΌpload en getranscribeerd (2-5+ seconden latency) - **Nieuwe situatie:** Audio wordt real-time gestreamed via WebSocket, tekst verschijnt live tijdens het spreken (<500ms latency) - **Belangrijkste verbetering:** Direct visuele feedback, professionele UX met waveform visualisatie, confidence indicators, en slimme auto-pause functionaliteit πŸ“„ **Relatie tot andere documenten:** - **Analyse:** `docs/specs/speech/analyse-deepgram.md` - Technische analyse van migratie impact - **Implementatie:** Te ontwikkelen Technisch Ontwerp (TO) - **Context:** Dit wordt gebruikt in Report Composer en Treatment Advice Form componenten --- ## 2. Overzicht van de belangrijkste onderdelen De nieuwe real-time speech transcriptie bestaat uit de volgende hoofdonderdelen: ### Core Components 1. **Rapportage Editor (full-width)** - Primaire werkgebied voor het maken en bewerken van rapportages 2. **Speech Recorder Component (streaming)** - Inline opname met WebSocket verbinding 3. **Quick Action Buttons** - Snelle knoppen voor veelgebruikte rapportage types 4. **Timeline Sidebar (opt-in)** - Collapsible geschiedenis van rapportages 5. **Filters (on-demand)** - Verborgen, te openen via zoeken ### Speech Features 6. **Waveform Visualizer** - Real-time audio volume visualisatie 7. **Confidence Indicators** - Markering van onzekere woorden 8. **Smart Insertion Logic** - Veilig invoegen in bestaande teksten 9. **Auto-Pause Mechanisme** - Automatisch pauzeren na stilte 10. **Connection Status Indicator** - Visuele feedback van verbindingsstatus ### Backend 11. **Token Proxy Endpoint** - Veilige API key management (server-side) --- ## 3. User Stories **User Story Template:** > Als [rol/gebruiker] wil ik [doel of actie] zodat [reden/waarde]. ### Primaire User Stories | ID | Rol | Doel / Actie | Verwachte waarde | Prioriteit | |----|------|---------------|------------------|-------------| | US-01 | Behandelaar | Real-time tekst zien tijdens dicteren | Direct feedback, weet dat het werkt | Hoog | | US-02 | Behandelaar | Waveform zien tijdens opname | Visual bevestiging dat microfoon werkt | Hoog | | US-03 | Behandelaar | Onzekere woorden gemarkeerd zien | Kan direct corrigeren tijdens dicteren | Hoog | | US-04 | Behandelaar | Veilig dicteren in bestaande rapportage | Geen risico op per ongeluk overschrijven | Hoog | | US-05 | Behandelaar | Automatisch pauzeren na stilte | Voorkomt lange stiltes, natuurlijke workflow | Middel | | US-06 | Behandelaar | Verbindingsstatus zien | Weet of transcriptie actief is | Middel | | US-07 | Behandelaar | Pauzeren en hervatten zonder data verlies | Flexibele workflow, kan onderbreken | Middel | | US-08 | Behandelaar | Partial transcript behouden bij fout | Verlies nooit werk, zelfs bij netwerkproblemen | Hoog | | **US-09** | **Behandelaar** | **Snel nieuwe rapportage starten met quick button** | **Minder clicks, snellere workflow** | **Hoog** | | **US-10** | **Behandelaar** | **Timeline alleen tonen als nodig** | **Geen afleiding tijdens schrijven** | **Hoog** | | **US-11** | **Behandelaar** | **Eenvoudig bestaande rapportage bekijken en editen** | **Geen verwarring tussen view/edit modes** | **Hoog** | | **US-12** | **Behandelaar** | **Filters alleen zien als ik zoek** | **Cleaner interface, minder overwhelm** | **Middel** | ### Uitgewerkte User Stories **US-01: Real-time feedback** > Als behandelaar wil ik de tekst real-time zien verschijnen tijdens het dicteren, zodat ik direct zie dat de transcriptie werkt en of medische termen correct worden herkend. **US-04: Veilig dicteren** > Als behandelaar wil ik veilig kunnen dicteren in een bestaande rapportage zonder risico op overschrijven, zodat ik vertrouwen heb dat mijn bestaande werk beschermd is. **US-08: Data behoud** > Als behandelaar wil ik dat mijn transcript behouden blijft als de verbinding wegvalt, zodat ik niet al mijn gedicteerde werk verlies bij netwerkproblemen. **US-09: Quick actions (v2)** > Als behandelaar wil ik met één klik een nieuwe "Vrije notitie" kunnen starten, zodat ik niet elke keer via een dropdown het type hoef te selecteren. **US-10: Timeline opt-in (v2)** > Als behandelaar wil ik de timeline alleen zien als ik ernaar zoek, zodat ik niet wordt afgeleid tijdens het schrijven van een nieuwe rapportage. **US-11: Unified view/edit (v2)** > Als behandelaar wil ik een rapportage kunnen openen om te lezen, en daarna direct kunnen editen zonder modal te sluiten en opnieuw te openen, zodat mijn workflow vloeiend blijft. **US-12: Filters on-demand (v2)** > Als behandelaar wil ik alleen filters zien als ik op 'Zoeken' klik, zodat mijn scherm niet vol staat met controls die ik zelden nodig heb. --- ## 4. Functionele werking per onderdeel ### 4.1 Rapportage Pagina Layout (Editor-First Design) **InitiΓ«le staat - Editor focus (geen timeline zichtbaar):** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ [< CliΓ«nten] Jan de Vries Screening Geb: 18-11-1972 21:14β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Nieuwe rapportage maken: β”‚ β”‚ [+ Vrije notitie] [+ Intake] [+ Behandelplan] [Andere... β–Ό] β”‚ β”‚ [πŸ“‹ Timeline] │← Toggle β”‚ [πŸ” Zoeken] │← Filters β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Type: Vrije notitie β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ 🎀 Opname β—― Niet verbonden [βš™] β”‚β”‚ β”‚ β”‚ [🎀 Start opname] β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ Beschrijf wat je wilt vastleggen... β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ [πŸ’Ύ Opslaan] [πŸ€– Analyseer met AI β–Ό] β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Key principles v2:** 1. **Editor krijgt volledige breedte** - Geen split attention 2. **Timeline is opt-in** - Klik [πŸ“‹ Timeline] om te openen 3. **Filters zijn hidden** - Klik [πŸ” Zoeken] om te openen 4. **Quick actions bovenaan** - Common types als directe knoppen 5. **Focus op creatie** - Primary task is nieuwe rapportage maken ### 4.2 Quick Action Buttons **Locatie:** Bovenaan editor, direct onder page header **Gedrag:** - Klik [+ Vrije notitie] β†’ Start direct nieuwe vrije notitie (type pre-selected) - Klik [+ Intake] β†’ Start direct nieuw intake verslag - Klik [+ Behandelplan] β†’ Start direct nieuw behandelplan - Klik [Andere... β–Ό] β†’ Dropdown met alle andere types **Visuele feedback na klik:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ [+ Vrije notitie] [+ Intake] [+ Behandelplan] [Andere... β–Ό] β”‚ β”‚ ↑ Active (emerald-500 background) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Editor updates naar: Type: Intake verslag ← Pre-selected [Textarea ready voor input] ``` **Smart defaults:** - Onthoud laatste type (localStorage) - Meest gebruikte types eerst (kan analytics-based worden) - Voor 90% van use cases: 1 click om te starten **Rationale:** - 80/20 regel: Meeste users maken dezelfde 3-4 types rapportages - Vermijdt dropdown navigeren elke keer - Snellere workflow (1 vs 2 clicks) ### 4.3 Timeline Sidebar (Opt-In) **Trigger:** Klik [πŸ“‹ Timeline] button rechtsboven **Layout met timeline open:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RAPPORTAGE EDITOR β”‚ πŸ“‹ TIJDLIJN [βœ•] β”‚ β”‚ β”‚ β”‚ β”‚ [+ Vrije notitie] [+ Intake] [...β–Ό] β”‚ [πŸ”] [_______________] │← Search β”‚ β”‚ β”‚ β”‚ Type: Vrije notitie β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚ πŸ“„ Vrije notitie β”‚β”‚ β”‚ [🎀 Speech recorder...] β”‚ β”‚ 23-11, 21:43 β”‚β”‚ β”‚ β”‚ β”‚ Dit is de eerste... β”‚β”‚ β”‚ [Textarea...] β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ [Bekijk rapport] ││← Single action β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ [Actions...] β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚ πŸ“„ Intake verslag β”‚β”‚ β”‚ β”‚ β”‚ 22-11, 14:20 β”‚β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 70% 30% ``` **Gedrag:** - Timeline slides in van rechts (300ms animation) - Editor width shrinks naar 70% (smooth transition) - Timeline is scrollbaar (independent scroll van editor) - Klik [βœ•] β†’ Timeline slides out, editor expands naar 100% **Timeline Card Design:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ πŸ“„ Vrije notitie β”‚ ← Icon + type β”‚ 23-11-2025, 21:43 β”‚ ← Timestamp β”‚ ongeveer 20 uur geleden β”‚ ← Relative time β”‚ ──────────────────────────── β”‚ β”‚ Dit is de eerste rapportage β”‚ ← Preview (first 2 lines) β”‚ voor Jan de Vries... β”‚ β”‚ β”‚ β”‚ [Bekijk rapport] β”‚ ← Single action (unified) β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Rationale - Single [Bekijk] button:** - Geen [Bewerk] button meer (verwarrend) - Klik rapport β†’ Opens in modal (read mode) - Modal heeft [✏️ Bewerken] knop als nodig - Unified view/edit flow (zie sectie 4.6) **State:** - Timeline open/closed state opgeslagen in localStorage - User preference persists tussen sessies - Optional: Resizable divider (drag tussen editor en timeline) ### 4.4 Filters (On-Demand) **Trigger:** Klik [πŸ” Zoeken] button rechtsboven **Gedrag optie A: Expandable filter bar** ``` Collapsed (default): β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ [+ Quick actions...] [πŸ“‹][πŸ” Zoeken]β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Klik [πŸ” Zoeken] β†’ Expanded: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ [+ Quick actions...] [πŸ“‹][πŸ” Zoeken]β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ πŸ” Filters β”‚ β”‚ Type: [Alle β–Ό] Auteur: [Alle β–Ό] Van: [__] T/m: [__] β”‚ β”‚ AI: β—‹ Alles β—‹ Met AI β—‹ Handmatig [Reset] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Gedrag optie B: Filter in timeline** ``` Timeline open + klik [πŸ”] in timeline header: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ πŸ“‹ TIJDLIJN [βœ•] β”‚ β”‚ β”‚ β”‚ [πŸ”] [_______________] │← Search always visible in timeline β”‚ β”‚ β”‚ [β–Ό Filters] │← Expandable advanced filters β”‚ β”‚ β”‚ [Rapportages...] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Aanbeveling: Optie B** (Filters in timeline sidebar) - Filters zijn contextual bij timeline - Niet op main editor (keeps editor clean) - Timeline is toch al opt-in, filters zijn secondary to that **Smart filter behavior:** - Bij < 10 rapportages: Geen filters nodig, hide completely - Bij > 10 rapportages: Toon [πŸ”] in timeline - Search is fuzzy: zoekt in title, content, type ### 4.5 Speech Recorder Component (Inline, Compact) **InitiΓ«le staat (niet aan het opnemen):** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 🎀 Opname β—― Niet verbonden [βš™] β”‚ β”‚ [🎀 Start opname] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Gedrag bij klikken op "Start opname":** 1. Systeem vraagt microfoon permissie (indien nog niet gegeven) 2. Cursor springt automatisch naar einde van tekstveld 3. Status indicator wordt ◐ Geel "Verbinden..." 4. WebSocket verbinding wordt opgezet met Deepgram 5. Status wordt ● Groen "Verbonden & streaming" 6. Waveform visualisatie start 7. Tekst verschijnt live tijdens spreken **Actieve opname staat:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Spraakopname β”‚ β”‚ ● Verbonden & streaming [βš™] β”‚ β”‚ β”‚ β”‚ De patiΓ«nt presenteert zich met β”‚ ← Final (zwart, normaal) β”‚ klachten van langdurige vermoeidh.. β”‚ ← Interim (grijs, italic) β”‚ β”‚ β”‚ ━━━━━━━━●━━━━━━━━━━━━━━━━━ β”‚ ← Waveform β”‚ β”‚ β”‚ [⏸ Pauzeer] [⏹ Stop] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Tekst differentiatie:** - **Interim tekst** (real-time, nog niet definitief): - Kleur: `text-slate-500` (grijs) - Font-style: `italic` - Font-weight: `400` (normaal) - Wordt continu geΓΌpdatet tijdens spreken - **Final tekst** (definitief, na zinsbeΓ«indiging): - Kleur: `text-slate-900` (zwart) - Font-style: `normal` - Font-weight: `500` (medium bold) - Locked in, wordt niet meer gewijzigd **Animaties:** - Nieuwe woorden fade in met 200ms ease-out - Interim β†’ Final transitie met 300ms spring animatie - Smooth scroll naar nieuwste tekst ### 4.2 Waveform Visualizer **Gedrag:** - Canvas-based visualisatie (60fps) - Toont audio volume in real-time - Bar-style waveform zoals WhatsApp voice messages - Smooth animaties met spring physics **Visuele feedback:** ``` Stil: ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Zacht: ▂▃▂▁▂▃▂▁▂▃▂▁▂▃▂▁▂▃▂ Normaal: β–„β–…β–†β–…β–„β–ƒβ–„β–…β–†β–…β–„β–ƒβ–„β–…β–†β–…β–„β–ƒβ–„ Luid: β–†β–‡β–ˆβ–‡β–†β–…β–†β–‡β–ˆβ–‡β–†β–…β–†β–‡β–ˆβ–‡β–†β–…β–† ``` **Kleuren:** - Bars: `slate-700` (standaard) - Active bar (huidige positie): `emerald-500` - Tijdens stilte: bars worden transparanter **Functie:** - Visuele bevestiging dat microfoon audio oppikt - Helpt gebruiker zien of ze hard genoeg spreken - Professional uitstraling (zoals moderne opname-apps) ### 4.3 Confidence Indicators **Wanneer getoond:** - Alleen voor final tekst (niet voor interim) - Automatisch voor woorden met confidence < 0.9 **Visuele markering:** **High confidence (β‰₯0.9):** Geen markering ``` De patiΓ«nt heeft een diagnose van GAD ``` **Medium confidence (0.7-0.9):** Gele onderstreping ``` De patiΓ«nt heeft een diagnose van ˜GAD˜ ↑ Hover tooltip: Zekerheid: 78% ``` **Low confidence (<0.7):** Oranje onderstreping + suggestie ``` De patiΓ«nt heeft een diagnose van ˜GAT˜ ↑ Hover tooltip: Zekerheid: 65% Bedoelde je: GAD, gat? Klik om te herhalen ``` **Interactie:** - Hover over gemarkeerd woord β†’ tooltip met confidence % - Klik op woord β†’ optie om dit deel opnieuw te dicteren - Kan genegeerd worden (is alleen suggestie) **Medische context:** - Medische afkortingen worden automatisch CAPS (DSM, SSRI, GAD) - Smart formatting voor Nederlandse interpunctie - PatiΓ«ntnamen uit context (indien beschikbaar via props) ### 4.4 Smart Insertion Logic (Overschrijf-preventie) **Probleem:** Gebruiker opent bestaande rapportage en wil dicteren β†’ risico dat bestaande tekst overschreven wordt. **Oplossing:** Automatische cursor-naar-einde + visuele feedback **Flow bij starten opname:** **Scenario A: Leeg tekstveld** ``` 1. User klikt [Start opname] 2. Start direct met opnemen 3. Tekst verschijnt vanaf begin ``` **Scenario B: Bestaand tekst, cursor aan einde** ``` 1. User klikt [Start opname] 2. Groen glow rond tekstgebied 3. Tekst verschijnt aan einde (waar cursor al stond) ``` **Scenario C: Bestaand tekst, cursor NIET aan einde** ``` 1. User klikt [Start opname] 2. Cursor springt automatisch naar einde 3. Korte notificatie: "Cursor verplaatst naar einde" 4. Groen glow rond tekstgebied 5. Tekst verschijnt aan einde ``` **Visuele feedback tijdens dictaat:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Rapportage β”‚ ← Groene border tijdens dictaat β”‚ [Bestaande tekst...] β”‚ β”‚ β”‚ β”‚ [Live transcriptie hier...] β”‚ β”‚ β–ˆ ← Cursor (groen bolletje) β”‚ β”‚ β”‚ β”‚ 🟒 Aan het dicteren β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **CSS/Styling tijdens dictaat-modus:** - Border: `border-emerald-500 border-2` - Subtle glow: `shadow-emerald-500/20` - Cursor indicator: Groen bolletje naast cursor **Na stoppen:** - Groene border verdwijnt - Tekst blijft staan - Cursor blijft op positie - Gebruiker kan handmatig verder typen/editen ### 4.6 Unified View/Edit Modal (Bestaande Rapportages) **Trigger:** Klik [Bekijk rapport] in timeline card **Modal opent in Read mode (default):** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Vrije notitie β”‚ β”‚ 23-11-2025, 21:43 β”‚ β”‚ β”‚ β”‚ [✏️] [πŸ“‹ Dupliceer] [πŸ—‘] [βœ•] │← Actions β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Dit is de eerste rapportage voor │← Read-only content β”‚ Jan de Vries op Γ© plek. β”‚ β”‚ β”‚ β”‚ [Content...] β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [Sluiten] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Klik [✏️ Bewerken] β†’ Modal wordt editable:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Vrije notitie (bewerken) β”‚ β”‚ 23-11-2025, 21:43 β”‚ β”‚ β”‚ β”‚ [πŸ’Ύ] [❌] [βœ•] │← Edit actions β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ 🎀 Opname β—― Niet verbonden [βš™] │← Speech recorder β”‚ [🎀 Start opname om door te gaan] β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Dit is de eerste rapportage voor β”‚ │← Editable textarea β”‚ β”‚ Jan de Vries op Γ© plek. β–ˆ β”‚ │← Cursor β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ [Kan verder typen of dicteren...] β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [πŸ’Ύ Opslaan wijzigingen] [❌ Annuleren] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Flow:** 1. User kli kt [Bekijk rapport] in timeline 2. Modal opent overlay over editor (70% width, centered) 3. **Default = Read mode:** Alleen lezen, geen edit 4. User klikt [✏️ Bewerken]: - Modal transformeert naar edit mode (smooth transition) - Speech recorder verschijnt bovenaan - Content wordt editable textarea - Actions veranderen naar [Opslaan]/[Annuleren] 5. User kan: - Typen in textarea - Dicteren via speech recorder (cursor gaat naar einde) - Klik [Opslaan] β†’ Save + modal blijft open (success toast) - Klik [Annuleren] β†’ Discard changes, terug naar read mode - Klik [βœ•] β†’ Close modal (met unsaved warning indien nodig) **Unsaved changes protection:** ``` User editeert text, klikt [βœ•] zonder te saven: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Niet opgeslagen wijzigingen β”‚ β”‚ β”‚ β”‚ Wil je de wijzigingen opslaan?β”‚ β”‚ β”‚ β”‚ [πŸ’Ύ Opslaan] β”‚ β”‚ [πŸ—‘ Verwijderen] β”‚ β”‚ [← Terug naar bewerken] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Rationale unified view/edit:** - Gebruiker hoeft niet te raden: view of edit? - Start altijd met lezen (meest voorkomend) - Als edit nodig: 1 click [✏️] - Same context, geen modal sluiten/heropenen - Clear state: read icons vs edit icons **Extra features in modal:** - [πŸ“‹ Dupliceer]: Kopieer rapport naar nieuwe rapportage in editor - [πŸ—‘ Verwijder]: Delete rapport (met confirmation) - Keyboard shortcuts: `E` = Edit, `Esc` = Close ### 4.7 Auto-Pause Mechanisme **Trigger:** 3 seconden stilte (geen spraak gedetecteerd) **Gedrag:** 1. Deepgram endpointing detecteert stilte 2. Na 3 seconden β†’ automatisch pauzeren 3. WebSocket blijft verbonden (geen reconnect nodig) 4. Audio streaming stopt 5. UI update naar "gepauzeerd" staat **Gepauzeerde staat:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Spraakopname β”‚ β”‚ ● Verbonden [βš™] β”‚ β”‚ β”‚ β”‚ [Transcriptie tot nu toe...] β”‚ β”‚ β”‚ β”‚ ⏸ Automatisch gepauzeerd β”‚ β”‚ (3 seconden stilte) β”‚ β”‚ β”‚ β”‚ [β–Ά Hervat opname] [⏹ Stop] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Hervatten:** - Klik [β–Ά Hervat opname] - Audio streaming start onmiddellijk (geen nieuwe verbinding) - Waveform hervat - Transcriptie gaat verder waar het stopte **Voordelen:** - Voorkomt lange stiltes in transcript - Natuurlijke workflow (denken tijdens dicteren) - Geen data verlies - Geen reconnection overhead **Configuratie:** - Deepgram endpointing: `3000ms` (3 seconden) - User kan niet handmatig instellen (fixed voor consistentie) ### 4.6 Connection Status Indicator **Altijd zichtbaar** in rechterbovenhoek van component: **Stati en kleuren:** | Status | Icoon | Kleur | Betekenis | |--------|-------|-------|-----------| | Niet verbonden | β—― | `text-slate-400` | Niet aan het opnemen | | Verbinden... | ◐ | `text-amber-500` | WebSocket aan het opzetten | | Verbonden | ● | `text-emerald-500` | Actief aan het streamen | | Herverbinden... | ⚠ | `text-orange-500` | Netwerk probleem, aan het reconnecten | | Fout | βœ• | `text-red-500` | Fout opgetreden | **Interactie:** - Geen interactie bij groen/grijs - Bij oranje (herverbinden): toon "Herverbinden... transcript blijft behouden" - Bij rood (fout): toon [Opnieuw proberen] button **Fout scenario met recovery:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Spraakopname β”‚ β”‚ βœ• Verbinding verloren [βš™] β”‚ β”‚ β”‚ β”‚ [Transcript tot nu toe behouden] β”‚ β”‚ β”‚ β”‚ ⚠ Netwerkfout: kon niet verbinden β”‚ β”‚ met Deepgram β”‚ β”‚ β”‚ β”‚ [πŸ”„ Opnieuw proberen] [πŸ’Ύ Bewaar] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Auto-reconnect logica:** - Bij netwerk drop: automatisch 3x reconnect proberen - Tussen pogingen: 1s, 2s, 4s backoff - Audio wordt gebufferd tijdens reconnect - Partial transcript altijd behouden - Na 3 pogingen: toon manual retry button ### 4.7 Pause & Resume Controls **Beschikbare acties tijdens opname:** **[⏸ Pauzeer]** - Handmatig pauzeren - Stopt audio streaming - Behoudt WebSocket verbinding - Transcript blijft zichtbaar - Kan hervatten zonder data verlies **[⏹ Stop]** - Definitief stoppen - Stopt audio streaming - Sluit WebSocket verbinding - Transcript wordt naar parent component gestuurd (via `onTranscript` callback) - Reset component naar initiΓ«le staat **[β–Ά Hervat]** - Hervatten na pause - Hervat audio streaming - Gaat verder waar gestopt - Geen nieuwe verbinding nodig **Flow voorbeeld:** ``` [Start] β†’ Opname loopt β†’ [Pauzeer] β†’ Gepauzeerd β†’ [Hervat] β†’ Opname loopt β†’ [Stop] β†’ Klaar ↓ (na 3s stilte: auto-pause) ``` --- ## 5. UI-overzicht (visuele structuur) - v2 Editor-First ### 5.1 Pagina Layout - Default (Geen Timeline) **Editor heeft volledige breedte, focus op creatie:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ [< CliΓ«nten] Jan de Vries Screening Geb: 18-11-1972 21:14 β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Nieuwe rapportage maken: β”‚ β”‚ [+ Vrije notitie] [+ Intake] [+ Behandelplan] [Andere... β–Ό] β”‚ β”‚ [πŸ“‹ Timeline] β”‚ β”‚ [πŸ” Zoeken] β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Type: Vrije notitie β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ 🎀 Opname ● Verbonden & streaming [βš™] β”‚β”‚ β”‚ β”‚ ━━━━━━━━●━━━━━━━━ [⏸ Pauzeer] [⏹ Stop] β”‚β”‚ ← Speech inline β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ De patiΓ«nt presenteert zich met klachten van β”‚β”‚ ← Live tekst β”‚ β”‚ langdurige vermoeidheid... β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ [πŸ’Ύ Opslaan] [πŸ€– Analyseer met AI β–Ό] β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 100% width ``` ### 5.2 Pagina Layout - Met Timeline Open **Timeline sidebar rechts, editor links (70/30 split):** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RAPPORTAGE EDITOR β”‚ πŸ“‹ TIJDLIJN [βœ•] β”‚ β”‚ β”‚ β”‚ β”‚ [+ Vrije notitie] [+ Intake] [...β–Ό] β”‚ [πŸ”] [_______________] β”‚ β”‚ β”‚ β”‚ β”‚ Type: Vrije notitie β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚ πŸ“„ Vrije notitie β”‚β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ 23-11, 21:43 β”‚β”‚ β”‚ β”‚ 🎀 Opname ● Verbonden [βš™] β”‚β”‚ β”‚ β”‚ Dit is de eerste... β”‚β”‚ β”‚ β”‚ ━━━━●━━━ [⏸][⏹] β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ [Bekijk rapport] β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ [Textarea met live tekst...] β”‚β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ πŸ“„ Intake verslag β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ 22-11, 14:20 β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ [Bekijk rapport] β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ [πŸ’Ύ][πŸ€– AI β–Ό] β”‚ β”‚ β”‚ β”‚ [+ Nieuwe rapportage] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 70% 30% ``` ### 5.3 Modal - View/Edit Unified **Modal overlay (70% viewport width, centered):** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Vrije notitie β”‚ β”‚ 23-11-2025, 21:43 β”‚ β”‚ β”‚ β”‚ [✏️ Bewerken] [πŸ“‹ Dupliceer] [πŸ—‘] [βœ•] β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Dit is de eerste rapportage voor │← Read mode β”‚ Jan de Vries op Γ© plek. β”‚ β”‚ β”‚ β”‚ Lorem ipsum dolor sit amet... β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [Sluiten] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ Klik [✏️ Bewerken] β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Vrije notitie (bewerken) β”‚ β”‚ 23-11-2025, 21:43 β”‚ β”‚ β”‚ β”‚ [πŸ’Ύ Opslaan] [❌ Annuleren] [βœ•] β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ 🎀 Opname β—― Niet verbonden [βš™] │← Speech added β”‚ [🎀 Start opname om door te gaan] β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Dit is de eerste rapportage voor β”‚ │← Editable β”‚ β”‚ Jan de Vries op Γ© plek. β–ˆ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Lorem ipsum dolor sit amet... β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [πŸ’Ύ Opslaan wijzigingen] [❌ Annuleren] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.4 Responsive Gedrag - v2 **Desktop (>1200px):** - Full layout zoals hierboven - Timeline 30%, Editor 70% (resizable optional) - Modal 70% viewport width **Laptop (1024px-1200px):** - Timeline 35%, Editor 65% - Modal 80% viewport width - Quick actions blijven horizontaal **Tablet (768px-1024px):** - Timeline 40%, Editor 60% - Of: Toggle tussen Timeline OR Editor (niet beide) - Modal 90% viewport width - Quick actions 2 regels (2x2 grid) **Mobile (<768px):** - Stack layout: - Header met patient info (sticky) - Quick actions (vertical stack of horizontal scroll) - Editor (full width) - Timeline in drawer (slide from bottom) - Modal fullscreen - Speech recorder compact (waveform smaller) ### 5.5 Interactie States **Editor tijdens dictaat:** - Groene border (`border-emerald-500`) - Subtle glow (`shadow-emerald-500/20`) - Cursor indicator groen bolletje **Timeline card - Active (being edited in modal):** - Emerald border (`border-emerald-500`) - Emerald background (`bg-emerald-50/50`) - Visual link naar open modal **Quick action button - Active:** - Emerald background (`bg-emerald-500`) - White text (`text-white`) - Bold font (`font-semibold`) **Timeline sidebar - States:** - Closed: Editor 100% width - Opening: 300ms slide-in animation from right - Open: Editor 70%, Timeline 30% - Closing: 300ms slide-out animation to right - Smooth width transitions on editor ### 5.6 Empty States **Timeline leeg:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ πŸ“‹ TIJDLIJN [βœ•] β”‚ β”‚ β”‚ β”‚ πŸ“„ β”‚ β”‚ Nog geen rapportages β”‚ β”‚ β”‚ β”‚ Maak je eerste β”‚ β”‚ rapportage in het β”‚ β”‚ editor paneel β†’ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ [+ Nieuwe rapportage] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Editor zonder type selected:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Kies een type om te beginnen: β”‚ β”‚ [+ Vrije notitie] [+ Intake] β”‚ β”‚ [+ Behandelplan] [Andere... β–Ό] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## 6. Interacties met AI (functionele beschrijving) ### 6.1 AI Context voor Speech Transcription **Deepgram AI features gebruikt:** | Feature | Configuratie | Doel | User-facing impact | |---------|--------------|------|-------------------| | Live Streaming | WebSocket | Real-time audio verwerking | Tekst verschijnt tijdens spreken | | Interim Results | `interim_results: true` | Voorlopige transcripties | Grijs/italic tekst live updates | | Smart Format | `smart_format: true` | Auto punctuatie/capitalisatie | Nederlandse interpunctie correct | | Endpointing | `endpointing: 3000` | Detecteer spraakpauzes | Auto-pause na 3 sec stilte | | Language | `language: nl` | Nederlandse taal model | Correcte Nederlandse herkenning | | Model | `model: nova-2` | Laatste Deepgram model | Beste accuracy voor Nederlands | | Utterances | `utterances: true` | Word-level timestamps + confidence | Confidence indicators per woord | ### 6.2 Confidence Score Processing **AI Output β†’ UI Mapping:** ```javascript // Deepgram stuurt per word: { word: "gegeneraliseerde", confidence: 0.76, start: 1.234, end: 1.789 } // UI toont: "gegeneraliseerde" met gele onderstreping Tooltip: "Zekerheid: 76%" ``` **Drempelwaarden:** - β‰₯0.9: Geen markering (high confidence) - 0.7-0.9: Gele onderstreping (medium confidence) - <0.7: Oranje markering + suggestie (low confidence) ### 6.3 Medical Terminology Enhancement (toekomstig) **Mogelijke AI uitbreidingen voor v2:** - Custom medical dictionary voor Nederlandse GGZ termen - Patient naam herkenning uit context - DSM-5 classificatie auto-correct - Medicatie namen CAPS formatting - Sectie detectie ("Anamnese:", "Diagnose:", etc.) **Niet in v1, maar voorbereid in architectuur** --- ## 7. Gebruikersrollen en rechten **Voor deze feature:** Geen specifieke rol-differentiatie nodig. **Aanname:** - Alle behandelaars die toegang hebben tot Report Composer en Treatment Advice Form kunnen spraakopname gebruiken - Geen aparte permissies voor speech-to-text - Eventueel: audit logging van dictaat gebruik (in toekomst) **Privacy overwegingen:** - Audio wordt **niet** opgeslagen op onze servers - Direct gestreamed naar Deepgram (SSL/TLS encrypted) - Transcript wordt opgeslagen als onderdeel van rapportage/behandelplan (bestaand gedrag) - Deepgram DPA (Data Processing Agreement) moet gecheckt worden voor GDPR/AVG compliance --- ## 8. Ontwerpkeuzes en Rationale - v2 Editor-First Design ### 8.1 Design Philosophy: v1 β†’ v2 Evolution **v1 Design (Afgewezen):** - Side-by-side timeline (35%) en editor (65%) - Filters altijd zichtbaar bovenaan - [Bewerk] en [Bekijk] als aparte knoppen - Type selector elke keer handmatig kiezen **Problemen met v1 (uit design review):** - **Split attention:** Gebruiker moet beide panelen monitoren - **Afleiding:** Timeline zichtbaar tijdens schrijven - **Complexity overload:** Filters, timeline, editor allemaal tegelijk - **Verwarrende flows:** Bewerk vs Bekijk decision upfront - **Slow workflow:** Te veel clicks voor veelvoorkomende taken **v2 Design (Gekozen):** - **Editor-first:** Full-width default, focus op creatie - **Opt-in complexity:** Timeline/filters alleen als nodig - **Unified view/edit:** Één knop, smooth transition - **Quick actions:** 1-click voor common types **Kernprincipes v2:** 1. **Primary task first** - Nieuwe rapportage maken is belangrijkste use case 2. **Progressive disclosure** - Toon features on-demand 3. **Minimize clicks** - Optimize voor 80% use cases 4. **No split attention** - Één focus area tegelijk ### 8.2 Besluit: Timeline Opt-In (Rechts Sidebar) **Gekozen:** Timeline als collapsible sidebar rechts **Rationale:** - **Editor is primair** - Nieuwe rapportage maken > oude bekijken - **Geen afleiding** - Timeline default closed tijdens schrijven - **Context on-demand** - Klik [πŸ“‹ Timeline] als referentie nodig - **Rechts placement** - Sidebar pattern (zoals VS Code, Notion) **Afgewezen alternatieven:** - **Timeline links (v1):** Suggereert dat timeline primair is (niet waar) - **Timeline altijd zichtbaar:** Leidt af, split attention - **Timeline als tab:** Te veel context switching, verlies editor inhoud **Design review insights:** - βœ… Frontend dev: "Minder complex dan side-by-side sync" - βœ… UX designer: "Opt-in vermindert cognitive load" - βœ… End user: "Ik wil niet afgeleid worden tijdens dicteren" ### 8.3 Besluit: Quick Action Buttons **Gekozen:** [+ Vrije notitie] [+ Intake] [+ Behandelplan] [Andere... β–Ό] **Rationale:** - **80/20 regel:** 3-4 types = 80% van gebruik - **1 click start:** Geen dropdown navigation - **Visual affordance:** Knoppen zijn duidelijker dan dropdown - **Remembers last used:** Meest gebruikte type highlighted **Data assumptions (te valideren):** - Vrije notities: ~50% van rapportages - Intake: ~25% - Behandelplan: ~15% - Overige: ~10% **Design review insights:** - βœ… End user: "Ik maak meestal vrije notities, dit bespaart clicks" - βœ… UX designer: "Duidelijke affordances, geen verborgen functionaliteit" ### 8.4 Besluit: Unified View/Edit Modal **Gekozen:** Single [Bekijk rapport] β†’ Modal met [✏️ Bewerken] optie **Rationale:** - **No upfront decision:** Gebruiker hoeft niet te kiezen tussen view/edit - **Natural flow:** Eerst lezen (meest common), dan editen als nodig - **Same context:** Blijf in dezelfde modal, geen context loss - **Clear states:** Read vs Edit visueel distinct **Afgewezen alternative (v1):** - **[Bewerk] + [Bekijk] buttons:** Verwarrend, user moet raden - **Direct edit:** Te risicovol, per ongeluk wijzigingen **Flow comparison:** | Scenario | v1 (split buttons) | v2 (unified modal) | |----------|------|------| | Rapport lezen | Klik [Bekijk] β†’ Modal | Klik [Bekijk] β†’ Modal | | Rapport editen | Klik [Bewerk] β†’ Editor laadt | Klik [Bekijk] β†’ [✏️] β†’ Editeer in modal | | Lezen, ziet fout, wil editen | [βœ•] Modal β†’ [Bewerk] β†’ Re-load | [✏️] β†’ Direct editbaar (1 click) | **v2 is beter:** Minder clicks voor "bekijken dan editen" flow (meest common) **Design review insights:** - βœ… End user: "Ik wil rapport eerst zien voordat ik edit" - βœ… UX designer: "Unified flow is duidelijker, minder decision fatigue" - βœ… Frontend dev: "Gemakkelijker state management, één component" ### 8.5 Besluit: Filters On-Demand (In Timeline) **Gekozen:** Filters verborgen, alleen in timeline wanneer >10 rapportages **Rationale:** - **Most users don't need filters:** <10 rapportages per patiΓ«nt typisch - **Contextual:** Filters horen bij zoeken in timeline, niet bij editor - **Clean interface:** Geen onnodige controls - **Smart detection:** Toon alleen als relevant **Gedrag:** - <10 rapportages: Geen filter UI, alleen search - >10 rapportages: [β–Ό Filters] expand optie verschijnt - Timeline closed: Filters niet zichtbaar (irrelevant) **Afgewezen alternative (v1):** - **Filters altijd zichtbaar bovenaan:** Neemt 60px ruimte, laag usage - **Filters in main toolbar:** Not contextual, altijd in zicht **Design review insights:** - βœ… End user: "Ik heb 5 rapportages, waarom zie ik al die filters?" - βœ… UX designer: "Progressive disclosure principle - toon als nodig" ### 8.6 Besluit: Speech Inline (Bij Textarea) **Gekozen:** Speech recorder compact, direct boven textarea **Rationale:** - **Proximity:** Bij waar tekst verschijnt (usability principle) - **Inline:** Geen popup/modal/sidebar - **Compact:** ~80px height collapsed, ~120px expanded - **Live preview:** Zie waveform + tekst samen **Design stays from original v1:** - βœ… Auto cursor-naar-einde (veilig, geen overschrijven) - βœ… Waveform visualizer (professional feedback) - βœ… Confidence indicators (medical term validation) - βœ… Auto-pause na 3 sec (natural pauses) **No changes needed:** Speech recorder design was good in v1 ### 8.7 Besluit: Mobile Strategy **Gekozen:** Stack + drawer pattern **Rationale:** - **Editor full-width:** Primary task has full screen - **Timeline in drawer:** Swipe up from bottom - **Quick actions:** Horizontal scroll or 2x2 grid - **Modal fullscreen:** Editing in modal takes full mobile screen **Alternative considered:** - **Tabs (Timeline | Editor):** Loses context, too much switching - **Shrink both panels:** Everything too small, unusable **Design review insights:** - βœ… UX designer: "Mobile needs different paradigm, not just responsive" - ⚠️ Frontend dev: "Drawer animation complexity, but doable" ### 8.8 Design Review Summary **v2 solves v1 critical issues:** 1. βœ… **No split attention** - Editor full-width default 2. βœ… **No confusion** - Unified view/edit flow 3. βœ… **Faster workflow** - Quick actions, 1-click common tasks 4. βœ… **Less overwhelming** - Opt-in timeline/filters 5. βœ… **Clear hierarchy** - Editor = primary, timeline = secondary **Remaining considerations:** - ⚠️ **Unsaved changes:** Need warning dialog (planned) - ⚠️ **Keyboard shortcuts:** Power users want efficiency (v2 feature) - ⚠️ **Resizable timeline:** Users have different preferences (optional v1.1) **Score evolution:** - v1 design (rejected): 6/10 (good ideas, poor execution) - v2 design (current): 8/10 (user-tested principles, clear hierarchy) ### 8.9 Implementation Priorities **Must have (v1):** 1. Editor-first layout with full-width 2. Quick action buttons (top 3 types) 3. Timeline opt-in sidebar (collapsible) 4. Unified modal (view β†’ edit flow) 5. Speech inline with all features (waveform, confidence, auto-pause) **Should have (v1.1):** 6. Filters in timeline (smart show/hide) 7. Unsaved changes protection dialog 8. Keyboard shortcuts (E=edit, Esc=close, etc.) 9. Resizable timeline divider **Nice to have (v2):** 10. Analytics-driven quick action order 11. Voice commands ("nieuwe paragraaf") 12. Duplicate rapport feature 13. Timeline infinite scroll/virtualization --- ## 9. Technische randvoorwaarden (interface met TO) **Deze sectie is input voor het Technisch Ontwerp:** ### 9.1 API/Props Interface **Speech Recorder Component Props:** ```typescript interface SpeechRecorderStreamingProps { onTranscript: (transcript: string) => void; // Callback voor final transcript onInterimTranscript?: (interim: string) => void; // Optional: interim updates onError?: (error: Error) => void; disabled?: boolean; className?: string; // Optional: context voor AI enhancement patientName?: string; documentType?: 'rapport' | 'behandelplan' | 'intake'; } ``` ### 9.2 Browser Requirements **Minimum support:** - Chrome/Edge 90+ (WebSocket + Web Audio API + MediaRecorder) - Firefox 88+ - Safari 14+ (mogelijk beperkte ondersteuning) **Fallback strategie:** - Feature detection voor WebSocket/Web Audio - Als niet ondersteund: terug naar oude REST API implementatie - Duidelijke melding: "Je browser ondersteunt geen real-time transcriptie" ### 9.3 Performance Requirements - Waveform: 60fps update rate - Transcript latency: <500ms van spraak tot tekst verschijnt - UI moet responsive blijven tijdens streaming (geen blocking) - Memory: max 50MB voor component (audio buffering) ### 9.4 Security Requirements - API key NOOIT in client code - Token-based authentication voor WebSocket - Tokens expire na 1 uur - Rate limiting op token endpoint (max 10 tokens/user/hour) - SSL/TLS voor alle verbindingen --- ## 10. Bijlagen & Referenties **Interne documenten:** - `docs/specs/speech/analyse-deepgram.md` - Technische analyse van migratie - `docs/templates/fo_template.md` - Template gebruikt voor dit document **Componenten die speech recorder gebruiken:** - `app/epd/patients/[id]/rapportage/components/report-composer.tsx` - `app/epd/patients/[id]/intakes/[intakeId]/behandeladvies/components/treatment-advice-form.tsx` **Bestaande implementatie:** - `components/speech-recorder.tsx` - Huidige REST-based versie - `app/api/deepgram/transcribe/route.ts` - Huidige server-side endpoint **Deepgram documentatie:** - [Live Streaming Audio](https://developers.deepgram.com/docs/live-streaming-audio) - [Interim Results](https://developers.deepgram.com/docs/interim-results) - [Endpointing](https://developers.deepgram.com/docs/endpointing) - [Smart Format](https://developers.deepgram.com/docs/smart-format) **Design System:** - shadcn/ui componenten (Button, Dialog, Toast) - Tailwind CSS styling - Lucide React icons --- ## 11. Open vragen en toekomstige iteraties ### Open vragen voor implementatie: - [ ] Deepgram DPA review voor AVG/GDPR compliance - [ ] Exacte placement: inline vs sidebar vs floating? (aanbeveling: inline) - [ ] Mobile UX: fullscreen tijdens opname of blijft in place? - [ ] Autosave integratie: triggert partial transcript autosave? ### Toekomstige v2 features: - Medical dictionary custom voor Nederlandse GGZ termen - Sectie auto-detectie ("Anamnese:", "Diagnose:", etc.) - Voice commands ("nieuwe paragraaf", "verwijder laatste zin") - Multi-speaker detection (als patiΓ«nt mee praat) - Playback functie van opgenomen audio (vereist lokale opslag) - Export naar audio file voor archivering --- **Status:** Ready for Technical Design **Next steps:** Technisch Ontwerp (TO) uitwerken + implementatie planning