feat: rapportage UI refactor, speech streaming, docs & seed data
Rapportage: - Refactor workspace into modular components (quick-actions, timeline-card, timeline-sidebar) - Add updateReport action for inline editing - Improve report timeline with better UX Speech: - Add Deepgram token API endpoint - Add use-deepgram-streaming hook - Add confidence-text component Docs: - Add architecture documentation - Add performance optimization plan - Add speech specs and seed data docs Scripts & Data: - Add seed-reports script and migration - Update AGENTS.md guidelines 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
196
docs/specs/speech/analyse-deepgram.md
Normal file
196
docs/specs/speech/analyse-deepgram.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# Analyse: Migratie naar Deepgram SDK
|
||||
|
||||
## Huidige situatie
|
||||
|
||||
### Huidige implementatie
|
||||
|
||||
- REST API via directe `fetch()` naar `https://api.deepgram.com/v1/listen`
|
||||
- Audio wordt opgenomen met `MediaRecorder`, opgeslagen als Blob
|
||||
- Na opname wordt het hele bestand geüpload via FormData
|
||||
- Server-side route handler (`app/api/deepgram/transcribe/route.ts`) verwerkt de upload
|
||||
- Geen streaming; alles gebeurt na de opname
|
||||
|
||||
### Componenten betrokken
|
||||
|
||||
- `components/speech-recorder.tsx` - Client-side opname component
|
||||
- `app/api/deepgram/transcribe/route.ts` - Server-side API route
|
||||
|
||||
---
|
||||
|
||||
## Impact van Deepgram SDK
|
||||
|
||||
### 1. Architectuurwijziging: REST → WebSocket streaming
|
||||
|
||||
**Huidige flow:**
|
||||
```
|
||||
Browser → MediaRecorder → Blob → FormData → POST /api/deepgram/transcribe → Deepgram REST API → Transcript
|
||||
```
|
||||
|
||||
**Nieuwe flow met SDK:**
|
||||
```
|
||||
Browser → Microfoon stream → Deepgram SDK (WebSocket) → Real-time transcript chunks → UI update
|
||||
```
|
||||
|
||||
**Impact:**
|
||||
- Streaming vereist een WebSocket-verbinding
|
||||
- Real-time updates tijdens opname (niet alleen na opname)
|
||||
- Client-side SDK nodig (niet alleen server-side)
|
||||
- Server route kan worden vereenvoudigd of verwijderd
|
||||
|
||||
### 2. Client-side SDK vereist
|
||||
|
||||
**Wat er moet gebeuren:**
|
||||
- Deepgram SDK installeren: `@deepgram/sdk` of `@deepgram/browser-sdk`
|
||||
- Client-side WebSocket-verbinding opzetten
|
||||
- Audio stream direct naar Deepgram sturen (niet via server)
|
||||
- Real-time transcript chunks ontvangen en verwerken
|
||||
|
||||
**Overwegingen:**
|
||||
- **API key:** moet client-side beschikbaar zijn (met `NEXT_PUBLIC_` prefix) of via een proxy/token endpoint
|
||||
- **Security:** API key niet direct in client code plaatsen; gebruik een proxy endpoint die tokens uitreikt
|
||||
|
||||
### 3. Component herstructurering
|
||||
|
||||
**`speech-recorder.tsx` wijzigingen:**
|
||||
- Verwijder `MediaRecorder` blob-opslag (of behoud voor lokale backup)
|
||||
- Verwijder FormData upload naar `/api/deepgram/transcribe`
|
||||
- Voeg Deepgram SDK WebSocket-verbinding toe
|
||||
- Implementeer real-time transcript updates tijdens opname
|
||||
- Update state management voor streaming chunks
|
||||
- Voeg error handling toe voor WebSocket-verbindingen
|
||||
|
||||
**Nieuwe functionaliteit:**
|
||||
- Real-time transcript updates tijdens opname
|
||||
- Mogelijkheid tot pauzeren/hervatten zonder verbinding te verbreken
|
||||
- Endpointing (automatische detectie van spraakpauzes)
|
||||
- Betere error handling voor netwerkproblemen
|
||||
|
||||
### 4. Server-side route aanpassing
|
||||
|
||||
**Opties voor `/api/deepgram/transcribe/route.ts`:**
|
||||
|
||||
**Optie A: Verwijderen**
|
||||
- Als alles client-side gebeurt, is deze route niet meer nodig
|
||||
- Vereist client-side API key exposure (niet aanbevolen)
|
||||
|
||||
**Optie B: Proxy voor API key security**
|
||||
- Route wordt een proxy die tokens uitreikt of de verbinding proxyt
|
||||
- Client maakt verbinding via deze proxy
|
||||
- API key blijft server-side
|
||||
|
||||
**Optie C: Hybride**
|
||||
- Streaming via client-side SDK
|
||||
- Fallback naar REST API voor batch-verwerking
|
||||
- Route behouden voor backward compatibility
|
||||
|
||||
### 5. State management wijzigingen
|
||||
|
||||
**Huidige state:**
|
||||
- `isRecording` - boolean
|
||||
- `isUploading` - boolean
|
||||
- `error` - string
|
||||
- `chunksRef` - Blob array
|
||||
|
||||
**Nieuwe state nodig:**
|
||||
- `isStreaming` - WebSocket verbinding status
|
||||
- `transcriptChunks` - Array van real-time transcript delen
|
||||
- `connectionStatus` - 'connecting', 'connected', 'disconnected', 'error'
|
||||
- `partialTranscript` - Huidige incomplete transcript
|
||||
- `finalTranscript` - Voltooide transcripties
|
||||
|
||||
### 6. Error handling uitbreiding
|
||||
|
||||
**Nieuwe error scenarios:**
|
||||
- WebSocket verbindingsfouten
|
||||
- Netwerk onderbrekingen tijdens streaming
|
||||
- Deepgram quota/rate limiting tijdens live sessie
|
||||
- Microfoon toegang tijdens actieve stream
|
||||
- Herverbindingslogica nodig
|
||||
|
||||
### 7. UX verbeteringen mogelijk
|
||||
|
||||
**Met streaming beschikbaar:**
|
||||
- Real-time tekst tijdens spreken
|
||||
- Visual feedback per woord/chunk
|
||||
- Lagere latency (<500ms per chunk vs 2+ seconden voor hele opname)
|
||||
- Mogelijkheid tot directe correcties tijdens opname
|
||||
- Pauzeren/hervatten zonder opnieuw opnemen
|
||||
|
||||
### 8. Dependencies
|
||||
|
||||
**Te installeren:**
|
||||
```json
|
||||
"@deepgram/sdk": "^latest" // of "@deepgram/browser-sdk"
|
||||
```
|
||||
|
||||
**Mogelijk te verwijderen:**
|
||||
- Geen directe fetch naar Deepgram REST API meer nodig
|
||||
- FormData handling kan worden vereenvoudigd
|
||||
|
||||
### 9. Configuratie wijzigingen
|
||||
|
||||
**Environment variables:**
|
||||
- `DEEPGRAM_API_KEY` blijft nodig
|
||||
- Overweeg `NEXT_PUBLIC_DEEPGRAM_API_KEY` alleen als je client-side direct verbindt (niet aanbevolen)
|
||||
- Beter: proxy endpoint die tokens uitreikt
|
||||
|
||||
**Deepgram configuratie:**
|
||||
- Model: `nova-2` (blijft hetzelfde)
|
||||
- Language: `nl` (blijft hetzelfde)
|
||||
- Nieuwe opties: `endpointing`, `interim_results`, `punctuate`, `smart_format`
|
||||
|
||||
### 10. Backward compatibility
|
||||
|
||||
**Overwegingen:**
|
||||
- Bestaande code die `/api/deepgram/transcribe` gebruikt
|
||||
- Migratiepad voor andere componenten
|
||||
- Fallback mechanisme als streaming faalt
|
||||
|
||||
---
|
||||
|
||||
## Aanbevolen migratiepad
|
||||
|
||||
### Fase 1: Voorbereiding
|
||||
1. Deepgram SDK installeren
|
||||
2. Proxy endpoint maken voor secure token/key management
|
||||
3. Test implementatie maken naast bestaande REST implementatie
|
||||
|
||||
### Fase 2: Core streaming
|
||||
1. WebSocket verbinding opzetten in `speech-recorder.tsx`
|
||||
2. Real-time transcript updates implementeren
|
||||
3. Basis error handling toevoegen
|
||||
|
||||
### Fase 3: UX verbeteringen
|
||||
1. Visual feedback voor real-time updates
|
||||
2. Pauzeren/hervatten functionaliteit
|
||||
3. Endpointing configureren
|
||||
|
||||
### Fase 4: Cleanup
|
||||
1. Oude REST API route verwijderen of deprecaten
|
||||
2. Code cleanup
|
||||
3. Documentatie updaten
|
||||
|
||||
---
|
||||
|
||||
## Risico's en aandachtspunten
|
||||
|
||||
1. **Security:** API key niet direct in client code
|
||||
2. **Kosten:** Streaming kan meer API calls genereren
|
||||
3. **Netwerk:** WebSocket vereist stabiele verbinding
|
||||
4. **Browser compatibiliteit:** WebSocket en MediaStream API support
|
||||
5. **Testing:** Complexer dan REST (real-time flows)
|
||||
|
||||
---
|
||||
|
||||
## Conclusie
|
||||
|
||||
De migratie vereist:
|
||||
- Architectuurwijziging van REST naar WebSocket streaming
|
||||
- Client-side SDK integratie
|
||||
- Herstructurering van `speech-recorder.tsx`
|
||||
- Aanpassing/verwijdering van server route
|
||||
- Uitgebreidere state management
|
||||
- Betere error handling
|
||||
- Security overwegingen voor API key management
|
||||
|
||||
**De belangrijkste winst:** real-time transcriptie tijdens opname in plaats van alleen na opname, wat beter aansluit bij de live transcriptie-vereisten in de documentatie.
|
||||
1256
docs/specs/speech/bouwplan-realtime-speech.md
Normal file
1256
docs/specs/speech/bouwplan-realtime-speech.md
Normal file
File diff suppressed because it is too large
Load Diff
1213
docs/specs/speech/fo-realtime-speech-deepgram.md
Normal file
1213
docs/specs/speech/fo-realtime-speech-deepgram.md
Normal file
File diff suppressed because it is too large
Load Diff
177
docs/specs/speech/test-checklist-e6.md
Normal file
177
docs/specs/speech/test-checklist-e6.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# 🧪 Test Checklist - Epic 6: Integration & Testing
|
||||
|
||||
**Datum:** 24-11-2025
|
||||
**Tester:** [Naam]
|
||||
|
||||
---
|
||||
|
||||
## E6.S1 - Component Integration Tests
|
||||
|
||||
### Speech Recorder in Editor (report-composer.tsx)
|
||||
|
||||
| Test | Verwacht | ✅/❌ | Opmerkingen |
|
||||
|------|----------|-------|-------------|
|
||||
| Start opname → Cursor naar einde | Cursor springt naar einde van textarea | | |
|
||||
| Start opname → Groene border | Textarea krijgt emerald border + shadow | | |
|
||||
| Interim tekst → Grijs italic onder textarea | Live preview tijdens spreken | | |
|
||||
| Stop opname → Border reset | Normale border keert terug | | |
|
||||
| Transcript → Append aan content | Tekst wordt toegevoegd aan einde | | |
|
||||
|
||||
### Speech Recorder in Modal (report-view-edit-modal.tsx)
|
||||
|
||||
| Test | Verwacht | ✅/❌ | Opmerkingen |
|
||||
|------|----------|-------|-------------|
|
||||
| Edit mode → Speech recorder zichtbaar | Recorder verschijnt in bg-slate-50 sectie | | |
|
||||
| Start opname → Groene border op textarea | Modal textarea krijgt emerald border | | |
|
||||
| Transcript → Append aan content | Tekst wordt toegevoegd | | |
|
||||
| Stop → Unsaved indicator verschijnt | Amber bolletje + tekst | | |
|
||||
|
||||
### State Synchronization
|
||||
|
||||
| Test | Verwacht | ✅/❌ | Opmerkingen |
|
||||
|------|----------|-------|-------------|
|
||||
| Nieuwe rapportage → Verschijnt in timeline | Report toegevoegd bovenaan lijst | | |
|
||||
| Edit rapport → Timeline card update | Content preview update na save | | |
|
||||
| Delete rapport → Verdwijnt uit timeline | Card verwijderd uit lijst | | |
|
||||
| Duplicate → Content naar editor | Inhoud gekopieerd naar composer | | |
|
||||
|
||||
---
|
||||
|
||||
## E6.S2 - Dutch Medical Terms Test
|
||||
|
||||
### GGZ Terminologie Test
|
||||
|
||||
Spreek elk woord/zin in en controleer transcriptie:
|
||||
|
||||
| Term | Correct? | Confidence | Opmerkingen |
|
||||
|------|----------|------------|-------------|
|
||||
| "gegeneraliseerde angststoornis" | | | |
|
||||
| "SSRI medicatie" | | | |
|
||||
| "DSM-5 classificatie" | | | |
|
||||
| "cognitieve gedragstherapie" | | | |
|
||||
| "EMDR behandeling" | | | |
|
||||
| "traumaverwerking" | | | |
|
||||
| "depressieve episode" | | | |
|
||||
| "bipolaire stoornis" | | | |
|
||||
| "schizofrenie" | | | |
|
||||
| "persoonlijkheidsstoornis" | | | |
|
||||
| "dissociatieve identiteitsstoornis" | | | |
|
||||
| "borderline persoonlijkheidsstoornis" | | | |
|
||||
| "obsessief-compulsieve stoornis" | | | |
|
||||
| "PTSS post-traumatische stressstoornis" | | | |
|
||||
| "anorexia nervosa" | | | |
|
||||
|
||||
### Medische Zinnen Test
|
||||
|
||||
| Zin | Correct? | Issues |
|
||||
|----|----------|--------|
|
||||
| "De patiënt presenteert zich met klachten van angst en depressie" | | |
|
||||
| "Behandeladvies: cognitieve gedragstherapie, 12 sessies" | | |
|
||||
| "Diagnose volgens DSM-5: gegeneraliseerde angststoornis (F41.1)" | | |
|
||||
| "Patiënt is gestart met SSRI medicatie (sertraline 50mg)" | | |
|
||||
| "Verwijzing naar EMDR therapeut voor traumaverwerking" | | |
|
||||
|
||||
---
|
||||
|
||||
## E6.S3 - Browser Compatibility
|
||||
|
||||
### Desktop Browsers
|
||||
|
||||
| Browser | Versie | WebSocket | Web Audio | MediaRecorder | Streaming | Opmerkingen |
|
||||
|---------|--------|-----------|-----------|---------------|-----------|-------------|
|
||||
| Chrome | | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | |
|
||||
| Firefox | | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | |
|
||||
| Safari | | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | |
|
||||
| Edge | | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | |
|
||||
|
||||
### Mobile Browsers
|
||||
|
||||
| Browser | Versie | Mic Access | Streaming | UI Responsive | Opmerkingen |
|
||||
|---------|--------|------------|-----------|---------------|-------------|
|
||||
| Chrome Mobile | | ✅/❌ | ✅/❌ | ✅/❌ | |
|
||||
| Safari iOS | | ✅/❌ | ✅/❌ | ✅/❌ | |
|
||||
|
||||
---
|
||||
|
||||
## E6.S4 - Bug Bash & Polish
|
||||
|
||||
### Happy Flow Tests
|
||||
|
||||
**Test 1: Nieuwe Rapportage**
|
||||
- [ ] Pagina laadt met editor full-width
|
||||
- [ ] Quick action buttons zichtbaar
|
||||
- [ ] Klik [+ Vrije notitie] → Type geselecteerd
|
||||
- [ ] Start opname → Verbinding binnen 2 sec
|
||||
- [ ] Spreek → Real-time tekst verschijnt
|
||||
- [ ] Interim tekst is grijs italic
|
||||
- [ ] Final tekst is zwart
|
||||
- [ ] Stop → Transcript compleet
|
||||
- [ ] Klik Opslaan → Toast verschijnt
|
||||
- [ ] Rapportage in timeline (na refresh of real-time)
|
||||
|
||||
**Test 2: Bestaande Bewerken**
|
||||
- [ ] Klik [Tijdlijn] → Sidebar slides in (smooth)
|
||||
- [ ] Rapportages zichtbaar met preview
|
||||
- [ ] Klik [Bekijk rapport] → Modal opent (read mode)
|
||||
- [ ] Klik [✏️ Bewerken] → Edit mode (smooth transitie)
|
||||
- [ ] Speech recorder verschijnt
|
||||
- [ ] Dicteer → Tekst append aan einde
|
||||
- [ ] Klik [Opslaan] → Toast + modal blijft open
|
||||
- [ ] Klik [✕] → Modal sluit
|
||||
|
||||
**Test 3: Unsaved Changes**
|
||||
- [ ] Edit rapport → Type tekst
|
||||
- [ ] Klik [✕] → Dialog verschijnt
|
||||
- [ ] Klik [Terug] → Modal blijft open, tekst intact
|
||||
- [ ] Klik [Opslaan en sluiten] → Saved + modal sluit
|
||||
- [ ] OF Klik [Wijzigingen verwijderen] → Discard + modal sluit
|
||||
|
||||
**Test 4: Network Resilience**
|
||||
- [ ] Start opname
|
||||
- [ ] Spreek 5 seconden
|
||||
- [ ] Disconnect wifi (of throttle in DevTools)
|
||||
- [ ] Status indicator wordt oranje "Herverbinden..."
|
||||
- [ ] Partial transcript blijft zichtbaar
|
||||
- [ ] Reconnect → Groen "Verbonden"
|
||||
- [ ] Kan verder dicteren
|
||||
|
||||
### Known Issues / Bugs
|
||||
|
||||
| # | Beschrijving | Prioriteit | Status |
|
||||
|---|--------------|------------|--------|
|
||||
| 1 | | | |
|
||||
| 2 | | | |
|
||||
| 3 | | | |
|
||||
|
||||
### UI Polish Items
|
||||
|
||||
| # | Item | Status |
|
||||
|---|------|--------|
|
||||
| 1 | Loading states consistent | |
|
||||
| 2 | Error messages user-friendly | |
|
||||
| 3 | Animations smooth (300ms) | |
|
||||
| 4 | Keyboard navigation (Escape) | |
|
||||
| 5 | Focus management correct | |
|
||||
|
||||
---
|
||||
|
||||
## Test Summary
|
||||
|
||||
| Category | Pass | Fail | Blocked |
|
||||
|----------|------|------|---------|
|
||||
| E6.S1 Component Integration | | | |
|
||||
| E6.S2 Dutch Medical Terms | | | |
|
||||
| E6.S3 Browser Compatibility | | | |
|
||||
| E6.S4 Bug Bash & Polish | | | |
|
||||
|
||||
**Overall Status:** ⏳ In Progress / ✅ Pass / ❌ Fail
|
||||
|
||||
**Notes:**
|
||||
|
||||
|
||||
---
|
||||
|
||||
**Sign-off:**
|
||||
- Developer:
|
||||
- Date:
|
||||
|
||||
Reference in New Issue
Block a user