redesigdn docs
This commit is contained in:
987
docs/swift/archive/swift-fo-ai.md
Normal file
987
docs/swift/archive/swift-fo-ai.md
Normal 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 |
|
||||
Reference in New Issue
Block a user