feat: add docs chat widget UI components (E3)
- Add useDocsChat hook with message state, streaming, error handling - Add ChatMessages component with auto-scroll and streaming cursor - Add ChatInput component with Enter/Shift+Enter support - Add DocsChatWidget floating container with amber styling - Add AI integration specs (PRD, FO, bouwplan) Implements Epic 3 of AI Documentatie Assistent feature. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
386
docs/specs/ai-integratie/fo-ai-docs-assistent-v1.md
Normal file
386
docs/specs/ai-integratie/fo-ai-docs-assistent-v1.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# Functioneel Ontwerp (FO) – AI Documentatie Assistent
|
||||
|
||||
**Projectnaam:** Mini-ECD – AI Documentatie Assistent
|
||||
**Versie:** v1.0
|
||||
**Datum:** 01-12-2025
|
||||
**Auteur:** Colin van der Heijden
|
||||
|
||||
---
|
||||
|
||||
## 1. Doel en relatie met het PRD
|
||||
|
||||
**Doel van dit document:**
|
||||
Dit Functioneel Ontwerp beschrijft **hoe** de AI Documentatie Assistent functioneel werkt — wat de gebruiker ziet, doet en ervaart. Waar het PRD (`prd-ai-docs-assistent-v1.md`) uitlegt *wat en waarom*, laat dit FO zien *hoe dit in de praktijk werkt*.
|
||||
|
||||
**Toelichting aan de lezer:**
|
||||
De AI Documentatie Assistent is een floating chat widget die eindgebruikers van het EPD helpt door vragen te beantwoorden op basis van de systeemdocumentatie. Dit is de eerste AI-integratie in het Mini-ECD prototype en dient als fundament voor toekomstige AI features.
|
||||
|
||||
---
|
||||
|
||||
## 2. Overzicht van de belangrijkste onderdelen
|
||||
|
||||
1. **Floating Trigger Button** — Amber knop rechtsonder om widget te openen
|
||||
2. **Chat Panel** — Uitklapbaar gesprekspaneel
|
||||
3. **Message List** — Weergave van conversatie (gebruiker + assistent)
|
||||
4. **Input Area** — Tekstveld voor vragen stellen
|
||||
5. **Streaming Response** — Real-time weergave van AI antwoorden
|
||||
|
||||
---
|
||||
|
||||
## 3. Userstories
|
||||
|
||||
| ID | Rol | Doel / Actie | Verwachte waarde | Prioriteit |
|
||||
|----|------|---------------|------------------|-------------|
|
||||
| US-01 | Behandelaar | Vraag stellen over EPD functie | Direct antwoord zonder zoeken | Hoog |
|
||||
| US-02 | Verpleegkundige | Uitleg krijgen over onbekende functie | Zelfstandig werken zonder collega's te storen | Hoog |
|
||||
| US-03 | Nieuwe medewerker | Systeem leren kennen via vragen | Interactieve onboarding | Hoog |
|
||||
| US-04 | Behandelaar | Vervolgvraag stellen | Context behouden in gesprek | Middel |
|
||||
| US-05 | Developer | Technische vraag over API | Snelle referentie zonder docs te openen | Middel |
|
||||
| US-06 | Alle gebruikers | Widget sluiten | Terug naar werk zonder afleiding | Hoog |
|
||||
|
||||
**User Story Details:**
|
||||
|
||||
> **US-01:** Als behandelaar wil ik een vraag kunnen stellen over het EPD zodat ik direct antwoord krijg zonder door documentatie te hoeven zoeken.
|
||||
|
||||
> **US-02:** Als verpleegkundige wil ik uitleg kunnen vragen over een functie die ik niet ken zodat ik zelfstandig verder kan werken.
|
||||
|
||||
> **US-03:** Als nieuwe medewerker wil ik via vragen het systeem leren kennen zodat ik sneller productief ben.
|
||||
|
||||
---
|
||||
|
||||
## 4. Functionele werking per onderdeel
|
||||
|
||||
### 4.1 Floating Trigger Button
|
||||
|
||||
**Locatie:** Rechtsonder in het scherm, altijd zichtbaar binnen EPD (`/epd/*` routes)
|
||||
|
||||
**Gedrag:**
|
||||
- Amber gradient knop (56x56px) met Sparkles icon
|
||||
- Hover: lichte kleurverandering
|
||||
- Klik: opent chat panel, knop verdwijnt
|
||||
- Altijd bovenop andere content (z-index: 50)
|
||||
|
||||
**States:**
|
||||
| State | Weergave |
|
||||
|-------|----------|
|
||||
| Default | Amber gradient met wit icon |
|
||||
| Hover | Donkerder amber |
|
||||
| Widget open | Knop verborgen |
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Chat Panel
|
||||
|
||||
**Afmetingen:** 384px breed × max 80vh hoog
|
||||
|
||||
**Structuur:**
|
||||
```
|
||||
┌────────────────────────────────────┐
|
||||
│ Header: titel + sluit-knop │
|
||||
├────────────────────────────────────┤
|
||||
│ │
|
||||
│ Message List (scrollbaar) │
|
||||
│ │
|
||||
│ │
|
||||
├────────────────────────────────────┤
|
||||
│ Input Area: tekstveld + verzenden │
|
||||
└────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Header:**
|
||||
- Sparkles icon + "Documentatie Assistent" tekst
|
||||
- X-knop rechts om te sluiten
|
||||
- Amber/amber-100 achtergrond gradient
|
||||
|
||||
**Gedrag bij openen:**
|
||||
1. Panel verschijnt met slide-in animatie (van onder)
|
||||
2. Welkomstbericht wordt getoond (indien eerste keer)
|
||||
3. Focus gaat naar input veld
|
||||
|
||||
**Gedrag bij sluiten:**
|
||||
- Klik op X-knop → panel verdwijnt
|
||||
- Trigger button verschijnt weer
|
||||
- Conversatie blijft behouden (sessie)
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Message List
|
||||
|
||||
**Weergave van berichten:**
|
||||
|
||||
| Type | Positie | Styling |
|
||||
|------|---------|---------|
|
||||
| Gebruiker | Rechts uitgelijnd | `bg-amber-100`, rounded |
|
||||
| Assistent | Links uitgelijnd | `bg-slate-100`, rounded |
|
||||
|
||||
**Welkomstbericht (eerste bericht):**
|
||||
```
|
||||
Hallo! Ik ben de documentatie assistent voor het Mini-ECD.
|
||||
|
||||
Stel gerust vragen over hoe het systeem werkt, bijvoorbeeld:
|
||||
• Hoe maak ik een nieuwe intake aan?
|
||||
• Hoe werkt de spraakherkenning?
|
||||
• Waar vind ik de screening resultaten?
|
||||
```
|
||||
|
||||
**Scroll gedrag:**
|
||||
- Automatisch scrollen naar nieuwste bericht
|
||||
- Gebruiker kan omhoog scrollen door historie
|
||||
- Bij nieuw bericht: scroll naar beneden
|
||||
|
||||
**Streaming weergave:**
|
||||
- Tekst verschijnt woord-voor-woord
|
||||
- Pulserende cursor aan einde tijdens streaming
|
||||
- Cursor verdwijnt wanneer response compleet is
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Input Area
|
||||
|
||||
**Componenten:**
|
||||
- Textarea (auto-resize, max 4 regels)
|
||||
- Verzend-knop (amber, pijl icon)
|
||||
|
||||
**Interacties:**
|
||||
|
||||
| Actie | Resultaat |
|
||||
|-------|-----------|
|
||||
| Enter | Verstuur bericht |
|
||||
| Shift + Enter | Nieuwe regel |
|
||||
| Klik verzend-knop | Verstuur bericht |
|
||||
| Leeg bericht versturen | Geen actie |
|
||||
|
||||
**States:**
|
||||
|
||||
| State | Textarea | Verzend-knop |
|
||||
|-------|----------|--------------|
|
||||
| Idle | Enabled, placeholder | Enabled (amber) |
|
||||
| Typing | Enabled, tekst zichtbaar | Enabled |
|
||||
| Loading | Disabled | Disabled (grijs) |
|
||||
| Error | Enabled | Enabled |
|
||||
|
||||
**Placeholder tekst:** "Stel een vraag..."
|
||||
|
||||
---
|
||||
|
||||
### 4.5 Streaming Response
|
||||
|
||||
**Proces:**
|
||||
1. Gebruiker verstuurt vraag
|
||||
2. Input wordt disabled
|
||||
3. Nieuw assistent-bericht verschijnt (leeg)
|
||||
4. Tekst streamt woord-voor-woord in
|
||||
5. Bij completion: input wordt enabled
|
||||
|
||||
**Visuele feedback tijdens streaming:**
|
||||
- Pulserende cursor (`▊`) aan einde van tekst
|
||||
- Tekst verschijnt met ~50ms interval per chunk
|
||||
|
||||
**Timeout:**
|
||||
- Na 30 seconden zonder response: toon foutmelding
|
||||
- Gebruiker kan opnieuw proberen
|
||||
|
||||
---
|
||||
|
||||
## 5. UI-overzicht (visuele structuur)
|
||||
|
||||
### Widget Gesloten
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ EPD Interface │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ ┌─────┐ │
|
||||
│ │ ✨ │ │
|
||||
│ └─────┘ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
↑
|
||||
Trigger Button
|
||||
```
|
||||
|
||||
### Widget Open
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ EPD Interface │
|
||||
│ │
|
||||
│ ┌────────────────────────┤
|
||||
│ │ ✨ Docs Assistent ✕ │
|
||||
│ ├────────────────────────┤
|
||||
│ │ Welkomstbericht... │
|
||||
│ │ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ Hoe maak ik... │←──│── User
|
||||
│ │ └──────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌──────────────────┐ │
|
||||
│ │ │ Om een intake... │←──│── Assistant
|
||||
│ │ │ ... │ │
|
||||
│ │ └──────────────────┘ │
|
||||
│ ├────────────────────────┤
|
||||
│ │ [Stel een vraag...] ➤ │
|
||||
│ └────────────────────────┘
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Interacties met AI (functionele beschrijving)
|
||||
|
||||
| Locatie | AI-actie | Trigger | Output |
|
||||
|---------|----------|---------|--------|
|
||||
| Chat widget | Vraag beantwoorden | Gebruiker verstuurt bericht | Streaming tekst-antwoord |
|
||||
| Chat widget | Vervolgvraag beantwoorden | Gebruiker stuurt vervolgvraag | Context-aware antwoord |
|
||||
| Chat widget | Buiten scope afhandelen | Vraag niet in documentatie | Eerlijk "weet ik niet" + suggesties |
|
||||
|
||||
### AI Gedragsregels
|
||||
|
||||
**Wel doen:**
|
||||
- Antwoorden baseren op de 14 MDX documentatiebestanden
|
||||
- Nederlands schrijven
|
||||
- Bullet points gebruiken voor stappen
|
||||
- Verwijzen naar specifieke menu's en knoppen
|
||||
- Eerlijk zeggen als informatie ontbreekt
|
||||
|
||||
**Niet doen:**
|
||||
- Informatie verzinnen die niet in de documentatie staat
|
||||
- Medisch advies geven
|
||||
- Behandelsuggesties doen
|
||||
- Engels antwoorden (tenzij gevraagd)
|
||||
|
||||
### Beschikbare Knowledge Base
|
||||
|
||||
De assistent heeft toegang tot deze documentatie:
|
||||
|
||||
| Bestand | Onderwerp |
|
||||
|---------|-----------|
|
||||
| `authentication.mdx` | Inloggen en authenticatie |
|
||||
| `client-management.mdx` | Cliëntbeheer |
|
||||
| `intake-system.mdx` | Intake proces |
|
||||
| `screening-system.mdx` | Screening functionaliteit |
|
||||
| `treatment-planning.mdx` | Behandelplannen |
|
||||
| `interface-design.mdx` | UI uitleg |
|
||||
| `spraakgestuurde-verslaglegging.mdx` | Spraakfuncties (NL) |
|
||||
| `voice-controlled-reporting.mdx` | Spraakfuncties (EN) |
|
||||
| `verpleegkundige-overdracht.mdx` | Overdracht workflow |
|
||||
| `fhir-datamodel.mdx` | Data model |
|
||||
| `fhir-api.mdx` | API documentatie |
|
||||
| `release-notes-system.mdx` | Release notes |
|
||||
| `build-errors-fix.mdx` | Troubleshooting |
|
||||
| `webpack-module-resolution.mdx` | Technische docs |
|
||||
|
||||
---
|
||||
|
||||
## 7. Gebruikersrollen en rechten
|
||||
|
||||
| Rol | Toegang tot widget | Beperkingen |
|
||||
|-----|-------------------|-------------|
|
||||
| Behandelaar | Ja, binnen EPD | Geen |
|
||||
| Verpleegkundige | Ja, binnen EPD | Geen |
|
||||
| Admin | Ja, binnen EPD | Geen |
|
||||
| Niet-ingelogd | Nee | Widget niet zichtbaar |
|
||||
|
||||
**Authenticatie:** Widget is alleen zichtbaar voor ingelogde gebruikers binnen `/epd/*` routes.
|
||||
|
||||
---
|
||||
|
||||
## 8. Error States en Edge Cases
|
||||
|
||||
### Error States
|
||||
|
||||
| Situatie | Weergave | Gebruikersactie |
|
||||
|----------|----------|-----------------|
|
||||
| API timeout (>30s) | "Het duurt langer dan verwacht. Probeer het opnieuw." | Retry knop |
|
||||
| API error | "Er ging iets mis. Probeer het later opnieuw." | Retry knop |
|
||||
| Netwerk offline | "Geen internetverbinding." | - |
|
||||
| Rate limit | "Te veel verzoeken. Wacht even." | Automatisch retry |
|
||||
|
||||
### Edge Cases
|
||||
|
||||
| Situatie | Gedrag |
|
||||
|----------|--------|
|
||||
| Zeer lange vraag (>2000 chars) | Vraag wordt afgekapt met waarschuwing |
|
||||
| Lege vraag | Verzenden geblokkeerd |
|
||||
| Alleen spaties | Behandeld als lege vraag |
|
||||
| Snelle opeenvolgende vragen | Vorige request wordt geannuleerd |
|
||||
| Browser tab wisselen | Streaming gaat door |
|
||||
| Page refresh | Conversatie verloren (sessie-based) |
|
||||
|
||||
---
|
||||
|
||||
## 9. Bijlagen & Referenties
|
||||
|
||||
### Project Documentatie
|
||||
|
||||
- PRD AI Documentatie Assistent (`prd-ai-docs-assistent-v1.md`)
|
||||
- PRD AI Pre-fill Behandelplan (`prd-ai-prefill-behandelplan-v1.md`)
|
||||
- UX Stylesheet (`ux-stylesheet.md`)
|
||||
- Technisch Ontwerp Mini-ECD (`to-mini-ecd-v1_2.md`)
|
||||
|
||||
### Externe Referenties
|
||||
|
||||
- [Claude API Documentation](https://docs.anthropic.com)
|
||||
- [Anthropic Streaming Guide](https://docs.anthropic.com/en/api/streaming)
|
||||
|
||||
---
|
||||
|
||||
## Appendix A: Conversatie Voorbeelden
|
||||
|
||||
### Voorbeeld 1: Intake Vraag
|
||||
|
||||
**Gebruiker:** "Hoe maak ik een nieuwe intake aan?"
|
||||
|
||||
**Assistent:**
|
||||
```
|
||||
Om een nieuwe intake aan te maken:
|
||||
|
||||
1. Ga naar het cliëntdossier via **Cliënten** in het hoofdmenu
|
||||
2. Selecteer de gewenste cliënt
|
||||
3. Klik op het tabblad **Intake**
|
||||
4. Klik op de knop **Nieuwe Intake**
|
||||
5. Vul de intake-informatie in het formulier
|
||||
6. Klik op **Opslaan** om de intake te bewaren
|
||||
|
||||
Je kunt ook spraakherkenning gebruiken om de intake
|
||||
in te spreken via de microfoon-knop.
|
||||
```
|
||||
|
||||
### Voorbeeld 2: Buiten Scope
|
||||
|
||||
**Gebruiker:** "Wat is de beste behandeling voor depressie?"
|
||||
|
||||
**Assistent:**
|
||||
```
|
||||
Die informatie heb ik niet. Ik kan alleen helpen met
|
||||
vragen over hoe het Mini-ECD systeem werkt.
|
||||
|
||||
Misschien kan ik je helpen met:
|
||||
• Hoe maak ik een behandelplan aan?
|
||||
• Hoe voeg ik een diagnose toe?
|
||||
• Hoe werkt de screening functie?
|
||||
```
|
||||
|
||||
### Voorbeeld 3: Technische Vraag
|
||||
|
||||
**Gebruiker:** "Welke FHIR resources worden ondersteund?"
|
||||
|
||||
**Assistent:**
|
||||
```
|
||||
Het Mini-ECD ondersteunt de volgende FHIR R4 resources:
|
||||
|
||||
**Kern resources:**
|
||||
• Patient — Cliëntgegevens
|
||||
• Practitioner — Behandelaren
|
||||
• Encounter — Contactmomenten
|
||||
• Condition — Diagnoses/problemen
|
||||
• Observation — Metingen en observaties
|
||||
• CarePlan — Behandelplannen
|
||||
|
||||
Zie de API documentatie voor endpoints en voorbeelden.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Document gegenereerd als onderdeel van AI Speedrun — Week 3*
|
||||
Reference in New Issue
Block a user