redesigdn docs

This commit is contained in:
colinislit
2025-12-27 13:17:00 +01:00
parent 33c6698870
commit c77f1eb554
27 changed files with 3741 additions and 3 deletions

View File

@@ -0,0 +1,987 @@
# 🧩 Functioneel Ontwerp (FO) — Swift: Contextual UI EPD
**Projectnaam:** Swift — Contextual UI EPD
**Versie:** v1.0
**Datum:** 23-12-2024
**Auteur:** Colin Lit
---
## 1. Doel en relatie met het PRD
🎯 **Doel van dit document:**
Dit Functioneel Ontwerp beschrijft **hoe** Swift uit het PRD functioneel werkt — wat de gebruiker ziet, doet en ervaart. Waar het PRD het concept en de architectuur beschrijft, laat dit FO zien hoe elke interactie in de praktijk werkt.
📘 **Relatie met andere documenten:**
- **PRD:** `nextgen-epd-prd-ephemeral-ui-epd.md` — Wat en waarom
- **UX/UI:** `ux-ui-design-ephemeral-ui-epd-v2.1.md` — Visuele specificaties
- **Taken analyse:** `taken-en-vragen-analyse.md` — Frequentie en prioritering
**Kernprincipe:**
> De gebruiker navigeert niet door menu's. De gebruiker spreekt of typt een intentie — en het juiste bouwblok verschijnt, voorgevuld met relevante data.
---
## 2. Overzicht van de belangrijkste onderdelen
🎯 **Doel:** Overzicht van alle modules en hun relaties.
### 2.1 Systeemcomponenten
| # | Component | Beschrijving | Type |
|---|-----------|--------------|------|
| 1 | **Command Center** | Hoofdscherm met één input | Scherm |
| 2 | **Context Bar** | Dienst, patiënt, user info | UI Zone |
| 3 | **Canvas Area** | Waar blocks verschijnen | UI Zone |
| 4 | **Recent Strip** | Laatste acties quick access | UI Zone |
| 5 | **Command Input** | Tekst + voice input | UI Zone |
| 6 | **Intent Engine** | Classificeert gebruikersinput | Backend |
| 7 | **Context Manager** | Beheert sessie context | Backend |
### 2.2 Bouwblokken (Blocks)
| Prio | Block | Functie | Trigger voorbeelden |
|------|-------|---------|---------------------|
| P1 | **DagnotatieBlock** | Snelle notitie invoer | "notitie jan medicatie" |
| P1 | **ZoekenBlock** | Patiënt zoeken | "zoek marie" |
| P1 | **PatientContextCard** | Patiënt overzicht | Na zoeken / selectie |
| P1 | **OverdrachtBlock** | Dienst overdracht | "overdracht maken" |
| P2 | **RapportageBlock** | Behandelrapportage | "gesprek gehad met jan" |
| P2 | **AgendaBlock** | Afspraken | "mijn afspraken" |
| P2 | **MetingenBlock** | Vitale functies | "bloeddruk invoeren" |
| P3 | **IntakeWizard** | Nieuwe patiënt intake | "nieuwe intake" |
| P3 | **BehandelplanBlock** | Behandelplan | "behandelplan jan" |
| P3 | **RisicoBlock** | Risicotaxatie | "risico jan" |
| P3 | **ContactenBlock** | Contactpersonen | "contacten jan" |
### 2.3 Systeem Blocks
| Block | Functie | Trigger |
|-------|---------|---------|
| **HelpBlock** | Hulp en voorbeelden | "help", "wat kan ik" |
| **FallbackPicker** | Visuele keuze bij onduidelijkheid | Lage confidence |
---
## 3. User Stories
🎯 **Doel:** Beschrijven wat gebruikers moeten kunnen doen, vanuit hun perspectief.
### 3.1 P1: Kritieke Stories (MVP Week 1-2)
| ID | Rol | Doel / Actie | Verwachte waarde | Prio |
|----|-----|--------------|------------------|------|
| US-01 | Verpleegkundige | Dagnotitie maken door te spreken/typen | Registratie in 15 sec ipv 5 min | 🔴 P1 |
| US-02 | Verpleegkundige | Patiënt zoeken op naam | Direct vinden zonder navigatie | 🔴 P1 |
| US-03 | Verpleegkundige | Patiënt context zien na selectie | Alles relevante in één oogopslag | 🔴 P1 |
| US-04 | Verpleegkundige | Overdracht maken einde dienst | Complete overdracht in 5 min | 🔴 P1 |
| US-05 | Alle gebruikers | Weten wat het systeem kan | "help" toont mogelijkheden | 🔴 P1 |
| US-06 | Alle gebruikers | Kiezen als systeem niet begrijpt | Visuele fallback picker | 🔴 P1 |
### 3.2 P2: Belangrijke Stories (MVP Week 3-4)
| ID | Rol | Doel / Actie | Verwachte waarde | Prio |
|----|-----|--------------|------------------|------|
| US-07 | Behandelaar | Rapportage schrijven na gesprek | Dicteren + AI samenvatting | 🟡 P2 |
| US-08 | Behandelaar | Agenda bekijken | Afspraken vandaag/week | 🟡 P2 |
| US-09 | Verpleegkundige | Meting invoeren | Vitals met trend indicator | 🟡 P2 |
| US-10 | Behandelaar | Diagnose/plan van patiënt zien | Via PatientContextCard | 🟡 P2 |
### 3.3 P3: Post-MVP Stories
| ID | Rol | Doel / Actie | Verwachte waarde | Prio |
|----|-----|--------------|------------------|------|
| US-11 | Behandelaar | Nieuwe intake starten | Wizard begeleidt proces | 🟢 P3 |
| US-12 | Behandelaar | Behandelplan maken/bewerken | AI-gegenereerd, bewerkbaar | 🟢 P3 |
| US-13 | Verpleegkundige | Risicotaxatie invullen | Gestructureerd formulier | 🟢 P3 |
| US-14 | Behandelaar | Contactpersonen beheren | Noodcontact, familie | 🟢 P3 |
---
## 4. Functionele werking per onderdeel
🎯 **Doel:** Per component beschrijven wat de gebruiker kan doen en wat het systeem doet.
### 4.1 Command Center (Hoofdscherm)
**Beschrijving:**
Het enige scherm van de applicatie. Geen sidebar, geen menu's. Alles gebeurt via één input.
**Layout:**
```
┌─────────────────────────────────────────────────────────────────┐
│ [Context Bar: Dienst | Patiënt dropdown | User] 48px │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [Active Block Area] │
│ Blocks verschijnen hier │
│ Centered, responsive width │
│ Flex │
├─────────────────────────────────────────────────────────────────┤
│ [Recent Strip: laatste acties als badges] 48px │
├─────────────────────────────────────────────────────────────────┤
│ [Command Input: 🎤 Typ of spreek wat je wilt doen...] 64px │
└─────────────────────────────────────────────────────────────────┘
```
**Gedrag:**
- Bij laden: Command Input heeft focus
- Keyboard shortcut `⌘K` focust input vanaf elke plek
- Blocks verschijnen met fade+scale animatie
- Slechts één block actief tegelijk (of gestapeld met z-index)
---
### 4.2 Context Bar
**Functie:** Toont essentiële context: welke dienst, welke patiënt actief, wie ingelogd.
**Elementen:**
| Element | Locatie | Gedrag |
|---------|---------|--------|
| Dienst indicator | Links | "🌅 Ochtend \| 8 ptn" — kleur per shift |
| Actieve patiënt | Midden-rechts | Dropdown voor quick-switch |
| User | Rechts | Initialen, klik → logout |
**Dienst bepaling:**
| Dienst | Tijd | Kleur | Icon |
|--------|------|-------|------|
| Ochtend | 07:00-15:00 | Amber #F59E0B | 🌅 |
| Middag | 15:00-23:00 | Blue #3B82F6 | 🌤️ |
| Nacht | 23:00-07:00 | Indigo #6366F1 | 🌙 |
**Patiënt Dropdown:**
- Toont huidige selectie (of "Geen patiënt")
- Recent bekeken patiënten (max 5)
- Zoek optie onderaan
- "Clear" optie om selectie te wissen
---
### 4.3 Command Input
**Functie:** Het hart van de interface — tekst én voice input.
**States:**
| State | Weergave | Trigger |
|-------|----------|---------|
| Default | "🎤 Typ of spreek wat je wilt doen..." | — |
| Typing | Cursor, getypte tekst | Keyboard input |
| Listening | 🔴 + waveform + live transcript | Mic click of spatie (bij leeg) |
| Processing | ⏳ spinner + "Even kijken..." | Na submit |
**Acties:**
| Input | Actie |
|-------|-------|
| `Enter` | Submit naar Intent Engine |
| `Escape` | Clear input / close block |
| `↑` | Vorige command (history) |
| `Space` (leeg) | Start voice |
| Mic click | Toggle voice recording |
**Voice Flow:**
1. User klikt mic of drukt spatie (bij lege input)
2. Deepgram start streaming transcription
3. Live transcript verschijnt in input
4. Pauze detectie (1.5 sec stilte) → auto-submit
5. Of user klikt "Stop" → submit
---
### 4.4 Intent Engine
**Functie:** Classificeert gebruikersinput naar intent + entities.
**Input:**
```typescript
{
text: string; // "notitie jan medicatie gegeven"
context: {
activePatient?: Patient;
currentShift: 'ochtend' | 'middag' | 'nacht';
recentPatients: Patient[];
}
}
```
**Output:**
```typescript
{
intent: IntentType; // 'dagnotitie'
confidence: number; // 0.94
entities: {
patientName?: string; // "jan"
patientId?: string; // "uuid-123" (als gevonden)
category?: string; // "medicatie"
content?: string; // "gegeven"
date?: string;
};
clarificationNeeded: boolean;
clarificationQuestion?: string;
}
```
**Intent Types:**
| Intent | Block | Confidence drempel |
|--------|-------|-------------------|
| `dagnotitie` | DagnotatieBlock | 0.7 |
| `zoeken` | ZoekenBlock | 0.7 |
| `overdracht` | OverdrachtBlock | 0.8 |
| `rapportage` | RapportageBlock | 0.7 |
| `agenda` | AgendaBlock | 0.7 |
| `metingen` | MetingenBlock | 0.7 |
| `intake` | IntakeWizard | 0.8 |
| `behandelplan` | BehandelplanBlock | 0.8 |
| `risico` | RisicoBlock | 0.8 |
| `patient_info` | PatientContextCard | 0.7 |
| `help` | HelpBlock | 0.9 |
| `onbekend` | FallbackPicker | < 0.5 |
**Clarification Flow:**
- Confidence < drempel → vraag om verduidelijking
- Meerdere patient matches → toon selector
- Geen patient bij patient-required intent → vraag welke patient
---
### 4.5 DagnotatieBlock
**Functie:** Snelle notitie invoer — meest gebruikte actie (10-20x per dag).
**Trigger patterns:**
- "notitie [patient]"
- "[patient] medicatie gegeven"
- "incident bij [patient]"
- "[patient] heeft goed gegeten"
**Pre-fill logica:**
| Extracted | Pre-fill |
|-----------|----------|
| patient_name → match | Patient selector |
| "medicatie" keyword | Category = Medicatie |
| "gegeten", "ADL" | Category = ADL |
| "incident", "agressie" | Category = Incident |
| Overige tekst | Notitie veld |
**Form velden:**
| Veld | Type | Verplicht | Default |
|------|------|-----------|---------|
| Patient | Dropdown + search | Ja | Pre-filled of activePatient |
| Categorie | Button group | Ja | Extracted of Algemeen |
| Notitie | Textarea | Ja | Extracted content |
| Tijd | Time picker | Ja | Nu |
| In overdracht | Checkbox | Nee | false |
**Categorieën:**
| Categorie | Icon | Kleur | Keyboard |
|-----------|------|-------|----------|
| Medicatie | 💊 | Amber | 1 |
| ADL | 🍽️ | Green | 2 |
| Observatie | 👁️ | Blue | 3 |
| Incident | ⚠️ | Red | 4 |
| Algemeen | 💬 | Gray | 5 |
**Acties:**
| Knop | Actie | Keyboard |
|------|-------|----------|
| Opslaan | POST naar API, sluit block | `⌘Enter` |
| Annuleren | Sluit block zonder opslaan | `Escape` |
**Na opslaan:**
1. Toast: "✓ Notitie opgeslagen"
2. Block verdwijnt (200ms animatie)
3. Recent strip: badge "[📝 Jan-Med]"
4. Input krijgt focus voor volgende actie
**API:**
```
POST /api/reports
Body: {
patient_id: string,
type: 'nursing_log',
category: string,
content: string,
timestamp: datetime,
include_in_handover: boolean
}
```
---
### 4.6 ZoekenBlock
**Functie:** Patiënt zoeken en selecteren.
**Trigger patterns:**
- "zoek [naam]"
- "wie is [naam]"
- "vind [naam]"
**Gedrag:**
1. Block opent met zoekterm pre-filled
2. Live search (debounced 300ms)
3. Resultaten tonen met relevante info
4. Klik of Enter selecteert patiënt
**Resultaat card bevat:**
- Naam (highlighted match)
- Leeftijd
- Kamer/locatie
- Laatste activiteit ("2 uur geleden")
- Alert badge indien aanwezig
**Na selectie:**
1. ZoekenBlock sluit
2. PatientContextCard opent automatisch
3. Context Bar update: patient dropdown toont selectie
4. Recent strip: badge "[🔍 Jan]"
**Empty state:**
"Geen patiënten gevonden voor '[zoekterm]'"
**API:**
```
GET /api/patients/search?q={zoekterm}
Response: Patient[] met relevance score
```
---
### 4.7 PatientContextCard
**Functie:** Compact overzicht van alles relevant voor één patiënt.
**Trigger:**
- Automatisch na patiënt selectie
- "info [patient]", "dossier [patient]"
- Klik op patiënt in dropdown
**Secties (adaptive - alleen tonen als data aanwezig):**
| Sectie | Data | Bron |
|--------|------|------|
| Header | Naam, leeftijd, kamer, opnamedatum | patients |
| Alert | Actieve alerts/risico's | risk_assessments |
| Laatste notities | 3 meest recente | reports |
| Vitals | Vandaag gemeten | vitals |
| Diagnose | Hoofddiagnose + ernst | conditions |
| Behandelplan | Status, sessie X/Y, volgende eval | care_plans |
| Contacten | Primaire contact | contacts |
**Quick Actions (onderaan):**
```
[📝 Notitie] [📋 Rapport] [📊 Meting] [📄 Plan] [📞 Contact]
```
Klik op quick action → opent betreffende block met patient pre-filled.
**API:**
```
GET /api/patients/{id}/context
Response: {
patient: Patient,
alerts: Alert[],
recentNotes: Report[],
vitals: Vital[],
diagnosis: Condition,
carePlan: CarePlan,
contacts: Contact[]
}
```
---
### 4.8 OverdrachtBlock
**Functie:** Multi-patiënt overdracht met AI-samenvattingen.
**Trigger patterns:**
- "overdracht maken"
- "dienst klaar"
- "samenvatting voor collega"
**Proactive trigger:**
- 30 minuten voor dienst einde → suggestie banner
**Layout:**
- Header: "Overdracht [Ochtend] → [Middag]" + tijdrange
- Accordion per patiënt (expanded als alert aanwezig)
- AI samenvatting per patiënt
- Bronverwijzingen naar originele notities
- Footer: Kopieer / E-mail / Afronden
**Per patiënt accordion:**
| Element | Beschrijving |
|---------|--------------|
| Header | Naam + alert badge |
| Summary | AI-gegenereerde samenvatting |
| Bronnen | "📎 3 notities" — klik opent details |
| Bewerken | Inline edit van samenvatting |
**AI Samenvatting:**
- Gegenereerd op basis van: nursing_logs, vitals, rapportages
- Tijdrange: huidige dienst (default 8 uur)
- Max 3 zinnen per patiënt
- Aandachtspunten prominent
**Acties:**
| Knop | Actie |
|------|-------|
| Kopieer alles | Alle samenvattingen naar clipboard |
| E-mail | Open mail client met content |
| Afronden | Markeer overdracht compleet |
**API:**
```
POST /api/overdracht/generate
Body: {
patientIds: string[],
shiftStart: datetime,
shiftEnd: datetime
}
Response: {
summaries: { patientId: string, summary: string, sources: Source[] }[]
}
```
---
### 4.9 RapportageBlock
**Functie:** Uitgebreide behandelrapportage met rich text en AI.
**Trigger patterns:**
- "rapportage"
- "gesprek gehad met [patient]"
- "behandelgesprek"
**Form velden:**
| Veld | Type | Default |
|------|------|---------|
| Patient | Dropdown | Pre-filled of activePatient |
| Type | Button group | Gesprek |
| Inhoud | Rich text (TipTap) | Leeg of transcript |
| Datum/tijd | DateTime | Nu |
**Rapportage types:**
- Gesprek
- Evaluatie
- Telefonisch
- Consult
- Familie
**Rich text toolbar:**
- Bold, Italic
- Bullet list, Numbered list
- Quote
- H1, H2
- 🎤 Dicteer knop
**AI acties:**
| Actie | Beschrijving | Output |
|-------|--------------|--------|
| ✨ Samenvatten | Bullets van kernpunten | Zijpaneel |
| 📖 B1-niveau | Herschrijf leesbaar | Zijpaneel |
| 🔍 Problemen | Extraheer klinische issues | Zijpaneel |
**AI Zijpaneel:**
- Verschijnt rechts van editor
- Preview van AI output
- Knoppen: Invoegen, Kopiëren, Verwerp
**API:**
```
POST /api/reports
Body: {
patient_id: string,
type: 'rapportage',
subtype: string,
content: string (HTML),
timestamp: datetime
}
```
---
### 4.10 AgendaBlock
**Functie:** Afspraken overzicht en beheer.
**Trigger patterns:**
- "agenda"
- "afspraken vandaag"
- "wie zie ik deze week"
- "afspraken [patient]"
**Layout:**
- Navigatie: [◀ Gisteren] [Vandaag] [Morgen ▶]
- View toggle: [Dag] [Week]
- Lijst van afspraken met tijden
**Per afspraak:**
- Tijd (09:00 - 09:50)
- Patiëntnaam
- Type afspraak
- Quick actions: [Open dossier] [Notitie]
**Acties:**
- Klik op afspraak → open PatientContextCard
- [+ Nieuwe afspraak] → AfspraakBlock (P4)
**API:**
```
GET /api/appointments?date={date}&practitionerId={id}
Response: Appointment[]
```
---
### 4.11 MetingenBlock
**Functie:** Vitale functies invoeren.
**Trigger patterns:**
- "bloeddruk invoeren"
- "meting [patient]"
- "vitals"
- "temperatuur"
**Form velden:**
| Veld | Type | Validatie |
|------|------|-----------|
| Patient | Dropdown | Verplicht |
| Type | Button group | Verplicht |
| Waarde(s) | Number input(s) | Per type |
| Tijd | DateTime | Default: nu |
| Opmerking | Textarea | Optioneel |
**Meting types:**
| Type | Velden | Eenheid |
|------|--------|---------|
| Bloeddruk | Systolisch, Diastolisch | mmHg |
| Pols | BPM | /min |
| Temperatuur | Temp | °C |
| Gewicht | Kg | kg |
| Glucose | mmol/L | mmol/L |
| Saturatie | % | SpO2 |
**Trend indicator:**
Na invoer: vergelijk met vorige meting
- ↑ Hoger dan vorige
- ↓ Lager dan vorige
- → Gelijk
**API:**
```
POST /api/vitals
Body: {
patient_id: string,
type: string,
values: Record<string, number>,
timestamp: datetime,
notes?: string
}
```
---
### 4.12 HelpBlock
**Functie:** Toont wat het systeem kan.
**Trigger patterns:**
- "help"
- "wat kan ik doen"
- "hoe werkt dit"
**Inhoud:**
Gegroepeerde voorbeelden per categorie:
- 📝 Notities: "notitie jan medicatie"
- 🔍 Zoeken: "zoek marie"
- 🔄 Overdracht: "overdracht maken"
- 📋 Rapportage: "gesprek gehad"
- 📅 Agenda: "afspraken vandaag"
- etc.
---
### 4.13 FallbackPicker
**Functie:** Visuele keuze wanneer intent onduidelijk is.
**Trigger:**
- Intent confidence < 0.5
- Intent = 'onbekend'
**Layout:**
Grid van 8-10 opties met icon + label.
Keyboard shortcuts 1-9 voor snelle selectie.
**Opties:**
```
[📝 Notitie] [🔍 Zoeken] [🔄 Overdracht] [📋 Rapport]
[📅 Agenda] [📊 Meting] [👤 Dossier] [📄 Intake]
[⚠️ Risico] [💡 Help]
```
---
### 4.14 Recent Strip
**Functie:** Quick access naar recente acties.
**Gedrag:**
- Max 5 badges zichtbaar
- Nieuwste links
- Horizontal scroll voor meer
- Klik = heropen context
**Badge types:**
| Type | Icon | Kleur | Klik actie |
|------|------|-------|------------|
| Dagnotitie | 📝 | Category kleur | Open PatientContextCard |
| Zoeken | 🔍 | Gray | Open PatientContextCard |
| Overdracht | 🔄 | Blue | Open OverdrachtBlock |
| Rapportage | 📋 | Green | Open RapportageBlock |
---
## 5. UI-overzicht (visuele structuur)
🎯 **Doel:** Globale schermopbouw en component hiërarchie.
### 5.1 Hoofdlayout
```
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 🌅 Ochtend | 8 ptn Jan de Vries ▼ 👤 SV │ │
│ └───────────────────────────────────────────────────────────┘ │
│ CONTEXT BAR (48px) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ │
│ ┌─────────────────────┐ │
│ │ │ │
│ │ ACTIVE BLOCK │ │
│ │ (Small: 480px) │ │
│ │ (Medium: 640px) │ │
│ │ (Large: 900px) │ │
│ │ │ │
│ └─────────────────────┘ │
│ │
│ CANVAS AREA (flex) │
│ │
├─────────────────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Recent: [📝 Jan-Med] [🔄 Overdracht] [🔍 Marie] │ │
│ └───────────────────────────────────────────────────────────┘ │
│ RECENT STRIP (48px) │
├─────────────────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 🎤 Typ of spreek wat je wilt doen... ⌘K │ │
│ └───────────────────────────────────────────────────────────┘ │
│ COMMAND INPUT (64px) │
└─────────────────────────────────────────────────────────────────┘
```
### 5.2 Block Sizes
| Size | Max-width | Use case |
|------|-----------|----------|
| Small | 480px | Quick entry (notitie, zoeken, meting) |
| Medium | 640px | Forms (rapportage, behandelplan) |
| Large | 900px | Overzichten (overdracht, agenda) |
| XLarge | 1100px | Wizards (intake) |
### 5.3 Block Container
Alle blocks gebruiken dezelfde wrapper:
```
┌─────────────────────────────────────────────────────────────────┐
│ [Icon] [Title] [] [×] │
├─────────────────────────────────────────────────────────────────┤
│ │
│ BLOCK CONTENT │
│ │
├─────────────────────────────────────────────────────────────────┤
│ [Cancel] [Save] │
└─────────────────────────────────────────────────────────────────┘
```
---
## 6. Interacties met AI (functionele beschrijving)
🎯 **Doel:** Waar AI in de flow voorkomt en wat de gebruiker ziet.
### 6.1 Intent Classification
| Locatie | Trigger | Input | Output |
|---------|---------|-------|--------|
| Command Input | Submit | Tekst/transcript | Intent + entities + confidence |
### 6.2 Content AI
| Locatie | AI-actie | Trigger | Output |
|---------|----------|---------|--------|
| RapportageBlock | Samenvatten | Klik knop | Bullets in zijpaneel |
| RapportageBlock | B1-niveau | Klik knop | Herschreven tekst |
| RapportageBlock | Extract problemen | Klik knop | Categorie + severity |
| OverdrachtBlock | Genereer samenvatting | Per patiënt accordion | 3-zin summary |
| BehandelplanBlock | Genereer plan | Klik knop | Doelen + interventies |
| IntakeWizard | Suggestie diagnose | Na anamnese stap | ICD-10 code + rationale |
### 6.3 AI Response Handling
**Alle AI outputs:**
1. Tonen in dedicated preview area (niet direct in form)
2. User moet expliciet accepteren/invoegen
3. Bewerken altijd mogelijk
4. Annuleren zonder gevolgen
**Loading state:**
- Skeleton loader in output area
- "AI denkt na..." indicator
- Non-blocking (user kan annuleren)
**Error handling:**
- "Kon niet verwerken. Probeer opnieuw."
- Retry knop
- Fallback naar handmatige invoer
---
## 7. Proactieve Triggers
🎯 **Doel:** Wanneer het systeem zelf UI toont zonder expliciete vraag.
| Trigger | Conditie | Actie |
|---------|----------|-------|
| Dienst start | Login of shift wissel | Suggestie: OverdrachtLezenBlock |
| Dienst einde | 30 min voor einde | Banner: "Overdracht maken?" |
| Patiënt geselecteerd | Na zoeken/klik | Auto-open PatientContextCard |
| Afspraak nadert | 15 min voor afspraak | Suggestie: patiënt openen |
| Alert aanwezig | Patiënt met actief risico | Alert banner in PatientContextCard |
**Suggestie Banner:**
```
┌───────────────────────────────────────────────────────────────┐
│ 🕐 Dienst eindigt over 30 min. Overdracht maken? │
│ [Ja] [Later] [×] │
└───────────────────────────────────────────────────────────────┘
```
- Niet-blokkerend (user kan negeren)
- "Later" = herinner over 15 min
- "×" = niet meer voor deze dienst
---
## 8. States & Error Handling
### 8.1 Block States
| State | Weergave |
|-------|----------|
| Loading | Skeleton loader |
| Ready | Form/content |
| Submitting | Disabled + spinner |
| Success | Toast + close |
| Error | Inline error message |
### 8.2 Network Errors
| Situatie | Gedrag |
|----------|--------|
| API timeout | "Verbinding verbroken. Probeer opnieuw." + retry |
| 401 Unauthorized | Redirect naar login |
| 500 Server error | "Er ging iets mis. Probeer later opnieuw." |
| Offline | Banner bovenin: "Geen internetverbinding" |
### 8.3 Validation Errors
| Veld | Validatie | Foutmelding |
|------|-----------|-------------|
| Patient | Verplicht | "Selecteer een patiënt" |
| Notitie | Min 5 karakters | "Voer een notitie in" |
| Bloeddruk | 50-250 / 30-150 | "Waarde buiten bereik" |
---
## 9. Gebruikersrollen en rechten
🎯 **Doel:** Welke rollen toegang hebben tot welke onderdelen.
| Rol | Toegang | Beperkingen |
|-----|---------|-------------|
| Verpleegkundige | Dagnotitie, Zoeken, Overdracht, Metingen | Geen behandelplan bewerken |
| Behandelaar | Alle blocks | Alleen eigen patiënten bewerken |
| Psychiater | Alle blocks + diagnose | Alleen eigen patiënten |
| Demo-user | Alle blocks (fictieve data) | Alleen lezen |
---
## 10. Keyboard Shortcuts
| Shortcut | Actie | Scope |
|----------|-------|-------|
| `⌘K` | Focus command input | Global |
| `Escape` | Sluit actieve block | Block open |
| `Enter` | Submit form | Form focused |
| `⌘Enter` | Opslaan | In form |
| `1-5` | Selecteer categorie | DagnotatieBlock |
| `1-9` | Selecteer optie | FallbackPicker |
| `↑` `↓` | Navigeer resultaten | ZoekenBlock |
| `Space` | Start voice (lege input) | Command Input |
---
## 11. Navigatie & Toegang
🎯 **Doel:** Beschrijven hoe gebruikers Swift bereiken en kiezen.
### 11.1 User Journey naar Swift
```
LANDINGSPAGINA (/)
│ Storytelling + Demo
LOGIN PAGINA (/login)
│ ┌─────────────────────────────────────┐
│ │ Kies je werkwijze: │
│ │ │
│ │ ○ ✨ Swift — Spreek of typ │
│ │ ○ 📋 Klassiek — Menu's en forms │
│ │ │
│ │ ☐ Onthoud mijn keuze │
│ └─────────────────────────────────────┘
├──────────────────┬───────────────────┐
▼ ▼ │
/epd/swift /epd/dashboard │
(Command Center) (Klassiek EPD) │
GEEN TOGGLE ◄──────────┘
binnen interface
```
### 11.2 Landingspagina Elementen
De landingspagina introduceert Swift via storytelling:
| Element | Functie |
|---------|---------|
| **Hero** | Probleem: "40% admin tijd" → Oplossing: "1 zin, klaar" |
| **Interactive Demo** | Probeer Swift zonder login |
| **Side-by-side** | 12 klikken klassiek vs 1 zin Swift |
| **Video** | Demo van dagnotitie flow |
| **CTA** | "Aan de slag" → /login |
### 11.3 Login Pagina met Interface Keuze
De login pagina bevat een interface selector:
```
┌─────────────────────────────────────────────────────────────────┐
│ │
│ [Bestaand login formulier - email, wachtwoord] │
│ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ Kies je werkwijze: │
│ │
│ ┌───────────────────────┐ ┌───────────────────────┐ │
│ │ ✨ Swift │ │ 📋 Klassiek │ │
│ │ │ │ │ │
│ │ Spreek of typ wat je │ │ Vertrouwde menu's │ │
│ │ wilt — het systeem │ │ en formulieren │ │
│ │ begrijpt │ │ │ │
│ │ │ │ │ │
│ │ "notitie jan med" → │ │ Dashboard → Patient │ │
│ │ klaar in 15 sec │ │ → Tab → Form → Save │ │
│ └───────────────────────┘ └───────────────────────┘ │
│ │
│ ☐ Onthoud mijn keuze │
│ │
│ [Inloggen] │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### 11.4 Redirect Gedrag
| Situatie | Gedrag |
|----------|--------|
| Nieuwe user, geen preference | Toon keuze op login pagina |
| User met preference + "onthoud" | Direct door naar gekozen interface |
| User naar `/epd` | Redirect naar preference of dashboard |
| Uitgelogd | Terug naar login met keuze optie |
### 11.5 Geen Toggle in Interface
Er is **geen mogelijkheid** om binnen Swift of Klassiek EPD te wisselen naar de andere interface:
- Geen toggle button in Swift
- Geen toggle button in Klassiek EPD
- Om te wisselen: uitloggen → opnieuw inloggen → andere keuze
**Rationale:**
- Voorkomt verwarring over "waar ben ik"
- Gebruiker committed aan één ervaring
- Admin kan preference aanpassen indien nodig
### 11.6 Admin Beheer
Alleen admins kunnen de interface preference van andere users wijzigen:
| Actie | Wie | Waar |
|-------|-----|------|
| Eigen preference instellen | Alle users | Login pagina |
| Preference andere user wijzigen | Admin | Admin panel |
| Geforceerd naar Swift/Klassiek | Admin | Admin panel |
---
## 12. Bijlagen & Referenties
**Projectdocumenten:**
- PRD: `swift-prd.md`
- UX/UI: `swift-ux-v2.1.md`
- TO: `to-swift-v1.md`
- Taken analyse: `taken-en-vragen-analyse.md`
**Bestaande documentatie:**
- Database schema: Supabase migrations
- Bestaande FO overdracht: `fo-overdracht-dashboard-v1_1.md` (archive)
---
## Wijzigingslog
| Versie | Datum | Wijzigingen |
|--------|-------|-------------|
| 1.0 | 23-12-2024 | Initiële versie op basis van PRD en UX/UI v2.1 |
| 1.1 | 23-12-2024 | Hernoemd naar Swift, toegevoegd: Navigatie & Toegang sectie |