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

@@ -169,9 +169,7 @@ export function DagnotatieBlock({ prefill }: DagnotitieBlockProps) {
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const handleSave = useCallback(async () => {
if (!patientId) {
toast({
variant: 'destructive',
@@ -243,6 +241,11 @@ export function DagnotatieBlock({ prefill }: DagnotitieBlockProps) {
} finally {
setIsSubmitting(false);
}
}, [patientId, content, category, includeInHandover, patientName, toast, closeBlock]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await handleSave();
};
// Keyboard shortcut: Cmd/Ctrl+Enter to save

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,742 @@
# 🧩 Functioneel Ontwerp (FO) — Swift Medical Scribe Chatbot
**Projectnaam:** Swift — Medical Scribe Chatbot Interface
**Versie:** v3.0
**Datum:** 27-12-2024
**Auteur:** Colin Lit
---
## 1. Doel en relatie met het PRD
🎯 **Doel van dit document:**
Dit Functioneel Ontwerp beschrijft het **redesign** van Swift naar een medical scribe chatbot interface. De gebruiker voert een natuurlijke conversatie met een AI-assistent die intents herkent, acties uitvoert, en relevante UI-componenten toont in een split-screen layout.
📘 **Relatie met andere documenten:**
- **PRD:** `nextgen-epd-prd-ephemeral-ui-epd.md` — Ephemeral UI visie
- **UX/UI:** `swift-ux-v2.1.md` — Visuele specificaties (wordt herzien)
- **UX Research:** `nextgen-epd-onderzoeksverslag-ux-ui-patterns.md` — Marktanalyse
- **Bouwplan:** `bouwplan-swift-v2.md` — Development roadmap
**Kernprincipe:**
> De gebruiker voert een natuurlijke conversatie met een medical scribe assistent. De assistent herkent intents, voert acties uit, en toont relevante UI-componenten (artifacts) rechts in beeld. De conversatie blijft zichtbaar en doorlopend — zoals ChatGPT Canvas of Claude Artifacts.
**Belangrijkste wijzigingen t.o.v. v2.0:**
| Aspect | v2.0 (Command Center) | v3.0 (Medical Scribe) |
|--------|----------------------|----------------------|
| Input model | Command-line stijl | Natuurlijke conversatie |
| UI paradigma | Blocks die verschijnen/verdwijnen | Chat links, artifacts rechts |
| Context | Per commando | Doorlopende conversatiegeschiedenis |
| AI rol | Intent classifier | Converserende medical scribe |
| Interactie | Transactioneel | Relationeel, follow-up mogelijk |
---
## 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 split-screen layout | Scherm |
| 2 | **Context Bar** | Dienst, actieve patiënt, user info | UI Zone |
| 3 | **Chat Panel** | Doorlopende conversatie (links, 40%) | UI Zone |
| 4 | **Artifact Area** | Waar blocks verschijnen (rechts, 60%) | UI Zone |
| 5 | **Chat Input** | Tekst + voice input (onderaan chat) | UI Zone |
| 6 | **Chat API** | Medical scribe chatbot endpoint | Backend |
| 7 | **Intent Engine** | Herkent intents in conversatie (hybrid) | Backend |
| 8 | **Context Manager** | Beheert sessie context + chat history | Backend |
### 2.2 Artifacts (Bouwblokken)
| Prio | Artifact | Functie | Trigger voorbeelden |
|------|----------|---------|---------------------|
| P1 | **DagnotatieBlock** | Snelle notitie invoer | "medicatie gegeven aan jan" |
| P1 | **ZoekenBlock** | Patiënt zoeken | "wie is jan de vries" |
| P1 | **PatientContextCard** | Patiënt overzicht | Na zoeken / selectie |
| P1 | **OverdrachtBlock** | Dienst overdracht met AI-filtering | "maak overdracht" |
| P2 | **RapportageBlock** | Behandelrapportage | "gesprek gehad met jan" |
| P2 | **AgendaBlock** | Afspraken | "mijn afspraken vandaag" |
| P2 | **MetingenBlock** | Vitale functies | "bloeddruk invoeren" |
**Belangrijk:** Artifacts blijven functioneel hetzelfde als v2.0 blocks, maar verschijnen nu rechts in een persistent panel.
### 2.3 Rol-specifieke Views
| Rol | Primaire workflow | Artifact focus |
|-----|-------------------|----------------|
| **Verpleegkundige** | Notities maken tijdens dienst | DagnotatieBlock, RapportageBlock |
| **Psychiater** | Gefilterde overdracht lezen | OverdrachtBlock met AI-samenvatting |
---
## 3. User Stories
🎯 **Doel:** Beschrijven wat gebruikers moeten kunnen doen, vanuit hun perspectief.
### 3.1 Nieuwe Stories (v3.0)
| ID | Rol | Doel / Actie | Verwachte waarde | Prio |
|----|-----|--------------|------------------|------|
| US-15 | Alle gebruikers | Natuurlijke conversatie voeren met assistent | Voelt als praten met collega | 🔴 P1 |
| US-16 | Alle gebruikers | Conversatiegeschiedenis zien | Context behouden tijdens werk | 🔴 P1 |
| US-17 | Alle gebruikers | Doorvragen zonder opnieuw te beginnen | Flexibele workflow | 🔴 P1 |
| US-18 | Alle gebruikers | Assistent stelt verduidelijkingsvragen | Minder fouten, betere data | 🟡 P2 |
| US-19 | Alle gebruikers | Meerdere acties in één conversatie | Efficiënte workflow | 🟡 P2 |
| US-20 | Verpleegkundige | Notities maken via spraak of typen | Hands-free documentatie | 🔴 P1 |
| US-21 | Verpleegkundige | Zien welke notities relevant zijn voor psychiater | Transparantie in filtering | 🟡 P2 |
| US-22 | Psychiater | Alleen behandelrelevante info zien | Geen ruis, focus op behandeling | 🔴 P1 |
| US-23 | Psychiater | Doorklikken naar originele bron | Verificatie en context | 🔴 P1 |
### 3.2 Bestaande Stories (herzien)
| ID | Rol | Doel / Actie | Wijziging v3.0 |
|----|-----|--------------|----------------|
| US-01 | Verpleegkundige | Dagnotitie maken | Via conversatie: "Ik heb medicatie gegeven aan Jan" |
| US-02 | Verpleegkundige | Patiënt zoeken | Via conversatie: "Wie is Jan de Vries?" |
| US-04 | Verpleegkundige | Overdracht maken | Via conversatie: "Maak overdracht voor deze dienst" |
---
## 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:**
Split-screen layout met chat links (40%) en artifacts rechts (60%). De gebruiker voert een natuurlijke conversatie met de medical scribe assistent.
**Layout:**
```
┌─────────────────────────────────────────────────────────────────┐
│ 🕐 Ochtend | 8 ptn Jan de Vries ▼ 👤 SV │
│ CONTEXT BAR │
├──────────────────────────────┬──────────────────────────────────┤
│ │ │
│ CHAT PANEL (40%) │ ARTIFACT AREA (60%) │
│ │ │
│ 👤 "Ik heb net medicatie │ ┌────────────────────────────┐ │
│ gegeven aan Jan" │ │ 📝 Dagnotitie │ │
│ │ │ │ │
│ 🤖 Ik maak een dagnotitie │ │ Patiënt: Jan de Vries ✓ │ │
│ voor Jan de Vries. │ │ Categorie: Medicatie ✓ │ │
│ Categorie: Medicatie. │ │ │ │
│ │ │ Notitie: │ │
│ Wil je nog iets │ │ ┌────────────────────────┐│ │
│ toevoegen? │ │ │ medicatie gegeven ││ │
│ │ │ └────────────────────────┘│ │
│ 👤 "Nee, opslaan" │ │ │ │
│ │ │ ☐ Relevant voor psychiater │ │
│ 🤖 ✓ Notitie opgeslagen │ │ │ │
│ voor Jan de Vries. │ │ [Annuleren] [💾 Opslaan] │ │
│ │ └────────────────────────────┘ │
│ │ │
├──────────────────────────────┤ │
│ 💬 Typ of spreek... 🎤 │ │
└──────────────────────────────┴──────────────────────────────────┘
```
**Gedrag:**
- Bij laden: Chat input heeft focus, artifact area toont placeholder
- Keyboard shortcut `⌘K` focust chat input vanaf elke plek
- Artifacts verschijnen rechts met slide-in animatie (200ms)
- Chat blijft zichtbaar en scrollbaar tijdens werk met artifacts
- Meerdere artifacts mogelijk via tabs (max 3 tegelijk)
**States:**
| State | Chat Panel | Artifact Area |
|-------|------------|---------------|
| Initial | Welcome message | Placeholder: "Artifacts verschijnen hier" |
| Conversing | Chat history + streaming response | Ongewijzigd of artifact |
| Action triggered | Chat continues | Artifact slide-in |
| Working | Chat beschikbaar | Artifact actief |
| Completed | Success message in chat | Artifact sluit of blijft |
---
### 4.2 Context Bar
**Functie:** Toont essentiële context: dienst, actieve patiënt, gebruiker.
**Elementen:**
| Element | Beschrijving | Interactie |
|---------|--------------|------------|
| Dienst indicator | 🕐 Ochtend / Middag / Nacht + patiëntentelling | Geen |
| Actieve patiënt | Dropdown met recent geselecteerde patiënten | Klik opent selector |
| User info | Avatar + initialen | Klik opent menu |
**Dienst kleuren:**
| Dienst | Tijd | Kleur |
|--------|------|-------|
| Ochtend | 07:00-15:00 | Amber (#F59E0B) |
| Middag | 15:00-23:00 | Blue (#3B82F6) |
| Nacht | 23:00-07:00 | Indigo (#6366F1) |
---
### 4.3 Chat Panel
**Functie:** Toont doorlopende conversatie met medical scribe assistent.
**Elementen:**
| Element | Beschrijving |
|---------|--------------|
| Chat Messages | Scrollbare lijst van user en assistant messages |
| Message Bubbles | User: rechts, amber bg / Assistant: links, slate bg |
| Streaming Indicator | Pulsating dots tijdens AI response |
| Action Links | Klikbare links naar gerelateerde artifacts |
| Timestamps | Optioneel, alleen bij pauzes >5 minuten |
**Message Types:**
| Type | Weergave | Voorbeeld |
|------|----------|-----------|
| User message | Rechts, amber | "medicatie gegeven aan jan" |
| Assistant text | Links, slate | "Ik maak een dagnotitie..." |
| Assistant action | Links, met icon | "📝 Dagnotitie geopend" (klikbaar) |
| System message | Centered, subtle | "✓ Notitie opgeslagen" |
| Error message | Links, red border | "Er ging iets mis. Probeer opnieuw." |
**Gedrag:**
- Auto-scroll naar laatste message
- Scroll-lock wanneer gebruiker omhoog scrollt
- "Scroll to bottom" knop bij nieuwe messages
- Max 100 messages in view (pagination voor oudere)
---
### 4.4 Chat Input
**Functie:** Tekst + voice input voor conversatie met medical scribe.
**States:**
| State | Weergave | Trigger |
|-------|----------|---------|
| Default | "Typ of spreek..." + mic icon | — |
| Typing | Cursor + getypte tekst | Keyboard input |
| Listening | 🔴 + waveform + live transcript | Mic click of spatie |
| Processing | Disabled, "Denkt na..." | Na submit |
| Streaming | Disabled, streaming in chat | Tijdens AI response |
**Keyboard Shortcuts:**
| Key | Actie |
|-----|-------|
| `Enter` | Submit message |
| `⌘Enter` / `Ctrl+Enter` | Force submit (ook tijdens streaming) |
| `Escape` | Clear input / cancel voice |
| `↑` | Vorige message (edit history) |
| `Space` (leeg) | Start voice recording |
| `⌘K` | Focus input |
**Voice Flow:**
1. User klikt mic of drukt spatie (bij lege input)
2. Deepgram start streaming transcription
3. Live transcript verschijnt in input field
4. Pauze detectie (1.5 sec stilte) → auto-submit
5. Of user klikt "Stop" → submit
---
### 4.5 Artifact Area
**Functie:** Toont actieve artifacts (blocks) rechts van de chat.
**Layout opties:**
| Situatie | Weergave |
|----------|----------|
| Geen artifact | Placeholder met voorbeelden |
| Eén artifact | Full width, centered |
| Meerdere artifacts | Tabs bovenaan (max 3) |
**Artifact Lifecycle:**
```
┌─────────────────────────────────────────────────────────────┐
│ 1. Intent detected in chat │
│ → AI response: "Ik maak een dagnotitie..." │
│ → Action object attached to response │
├─────────────────────────────────────────────────────────────┤
│ 2. Artifact appears │
│ → Slide-in animation (200ms, from right) │
│ → Pre-filled with extracted entities │
│ → Focus moves to first editable field │
├─────────────────────────────────────────────────────────────┤
│ 3. User interacts │
│ → Edits fields in artifact │
│ → Can continue chatting (e.g., "voeg toe: sliep goed") │
│ → Chat updates artifact in real-time │
├─────────────────────────────────────────────────────────────┤
│ 4. User saves or cancels │
│ → Success: toast + chat confirmation + artifact closes │
│ → Cancel: artifact closes, no confirmation │
└─────────────────────────────────────────────────────────────┘
```
**Placeholder State:**
```
┌────────────────────────────────────────────────────────────┐
│ │
│ 💬 Artifacts verschijnen hier │
│ │
│ Vraag me iets, bijvoorbeeld: │
│ • "Notitie voor Jan: medicatie gegeven" │
│ • "Zoek Marie van den Berg" │
│ • "Maak overdracht voor deze dienst" │
│ │
└────────────────────────────────────────────────────────────┘
```
---
### 4.6 Medical Scribe Chat API
**Functie:** Chatbot endpoint die conversatie voert en intents herkent.
**Endpoint:** `POST /api/swift/chat`
**Request:**
```typescript
interface ChatRequest {
message: string; // User message
messages: ChatMessage[]; // Conversation history (max 20)
context: {
activePatient?: Patient; // Currently selected patient
shift: 'ochtend' | 'middag' | 'nacht';
userId: string;
recentActions: RecentAction[]; // Last 5 actions
};
}
```
**Response (Server-Sent Events):**
```typescript
// Text chunk (streaming)
{ type: 'text', content: string }
// Action detected (end of response)
{
type: 'action',
intent: Intent,
entities: ExtractedEntities,
confidence: number,
artifact?: {
type: ArtifactType,
prefill: PrefillData
}
}
// Done
{ type: 'done' }
```
**System Prompt (samenvatting):**
```
Je bent een medische assistent (medical scribe) voor Swift, een Nederlands GGZ EPD.
Je rol:
- Help zorgmedewerkers met documentatie en administratie
- Voer natuurlijke gesprekken in het Nederlands
- Herken intents en voer acties uit wanneer nodig
- Stel verduidelijkingsvragen bij onduidelijkheid
- Wees vriendelijk maar professioneel
Intents die je herkent:
- dagnotitie: notitie maken voor patiënt
- zoeken: patiënt zoeken
- rapportage: behandelrapportage schrijven
- overdracht: dienst overdracht maken
- metingen: vitale functies invoeren
- agenda: afspraken bekijken
Wanneer je een intent herkent, voeg een JSON action object toe aan je response.
Huidige context:
- Actieve patiënt: {activePatient}
- Dienst: {shift}
- Recente acties: {recentActions}
```
---
### 4.7 Intent Engine (Hybrid)
**Functie:** Herkent intents in conversatie met two-tier approach.
**Tier 1: Local Pattern Matching (<50ms)**
| Pattern | Intent | Entities |
|---------|--------|----------|
| "notitie [naam]" | dagnotitie | patient: naam |
| "zoek [naam]" | zoeken | query: naam |
| "overdracht" | overdracht | — |
| "bloeddruk [naam]" | metingen | patient: naam, type: bloeddruk |
**Tier 2: AI Classification (via Chat API)**
Wanneer local patterns geen match geven of confidence <0.8, bepaalt de Chat API het intent op basis van conversatie-context.
**Voorbeelden:**
| Conversatie | Intent | Methode |
|-------------|--------|---------|
| "notitie jan medicatie" | dagnotitie | Local (direct match) |
| "Ik heb net een gesprek gehad" | rapportage | AI (context needed) |
| "Hij geeft aan zich beter te voelen" | (context) | AI (follow-up) |
| "Wie was die mevrouw van kamer 12?" | zoeken | AI (indirect) |
---
### 4.8 AI-Filtering voor Psychiater (Overdracht)
**Functie:** Filtert verpleegkundige rapportages naar behandelrelevante informatie.
**Wat WEL naar psychiater gaat:**
| Categorie | Voorbeelden |
|-----------|-------------|
| Medicatie-issues | Weigering, bijwerkingen, therapierespons |
| Stemming/gedrag verandering | t.o.v. baseline, significante shifts |
| Risico-signalen | Suïcidale uitingen, zelfbeschadiging, agressie |
| Signaleringsplan triggers | Oranje/rood fase signalen |
| Psychotische symptomen | Hallucinaties, wanen |
| Behandelplan stagnatie | Geen voortgang op doelen |
**Wat NIET naar psychiater gaat:**
| Categorie | Voorbeelden |
|-----------|-------------|
| Routine medicatie | "Medicatie volgens schema ingenomen" |
| ADL activiteiten | "Heeft gedoucht", "Ontbijt genuttigd" |
| Standaard observaties | "Rustige dag", "Goed geslapen" |
| Sociale activiteiten | "Bezoek gehad", "Mee naar dagactiviteit" |
**Linked Evidence:**
Elke zin in de AI-samenvatting linkt naar de originele verpleegkundige notitie. De psychiater kan hover-to-preview of click-to-expand gebruiken.
**UI in OverdrachtBlock:**
```
┌────────────────────────────────────────────────────────────┐
│ 🔄 Overdracht Ochtend → Middag [×] │
│ 07:00 - 15:00 | 8 patiënten │
├────────────────────────────────────────────────────────────┤
│ │
│ Behandelrelevant (3 patiënten) │
│ ─────────────────────────────────────────────────────── │
│ │
│ ▼ Jan de Vries ⚠️ Alert │
│ Weigerde ochtendmedicatie. Geeft aan last te hebben │
│ van bijwerkingen (duizeligheid). Stemming somberder │
│ dan gisteren. │
│ 📎 3 bronnotities [Bekijk bronnen] │
│ │
│ ▶ Marie van den Berg │
│ ▶ Piet Jansen │
│ │
│ ─────────────────────────────────────────────────────── │
│ Geen bijzonderheden (5 patiënten) │
│ [Toon allen ▼] │
│ │
├────────────────────────────────────────────────────────────┤
│ [📋 Kopieer] [📤 Naar EPD] [✓ Gezien] │
└────────────────────────────────────────────────────────────┘
```
---
## 5. User Flows
🎯 **Doel:** Laten zien hoe de gebruiker stap-voor-stap door het systeem gaat.
### Flow 1: Dagnotitie via Conversatie
```
┌─────────────────────────────────────────────────────────────┐
│ 1. Verpleegkundige opent Swift │
│ → Chat: welcome message │
│ → Artifact: placeholder │
├─────────────────────────────────────────────────────────────┤
│ 2. Verpleegkundige typt: "Medicatie gegeven aan Jan" │
│ → Message verschijnt in chat │
├─────────────────────────────────────────────────────────────┤
│ 3. AI Response (streaming): │
│ "Ik maak een dagnotitie voor Jan de Vries. │
│ Categorie: Medicatie. Wil je nog iets toevoegen?" │
│ → Action: intent=dagnotitie, patient=Jan, cat=Medicatie │
├─────────────────────────────────────────────────────────────┤
│ 4. DagnotatieBlock verschijnt rechts: │
│ → Patient: Jan de Vries ✓ (pre-filled) │
│ → Categorie: Medicatie ✓ (pre-filled) │
│ → Text: "Medicatie gegeven" (pre-filled) │
├─────────────────────────────────────────────────────────────┤
│ 5. Verpleegkundige: "Nee, opslaan" │
│ → Of: klikt direct op Opslaan knop │
├─────────────────────────────────────────────────────────────┤
│ 6. Resultaat: │
│ → Toast: "✓ Notitie opgeslagen" │
│ → Chat: "Notitie opgeslagen voor Jan de Vries." │
│ → Artifact sluit (of blijft voor volgende) │
├─────────────────────────────────────────────────────────────┤
│ TIJD: ~15 seconden │
└─────────────────────────────────────────────────────────────┘
```
### Flow 2: Overdracht met AI-Filtering (Psychiater)
```
┌─────────────────────────────────────────────────────────────┐
│ 1. Psychiater opent Swift │
│ → Chat: "Goedemorgen! Wil je de overdracht bekijken?" │
├─────────────────────────────────────────────────────────────┤
│ 2. Psychiater: "Ja, laat zien" │
│ → Of: "Overdracht ochtend" │
├─────────────────────────────────────────────────────────────┤
│ 3. AI Response: │
│ "Ik haal de overdracht op. 3 patiënten hebben │
│ behandelrelevante updates." │
│ → OverdrachtBlock verschijnt rechts │
├─────────────────────────────────────────────────────────────┤
│ 4. OverdrachtBlock toont: │
│ → Gefilterde samenvatting (alleen behandelrelevant) │
│ → Patiënten gesorteerd op urgentie │
│ → "Geen bijzonderheden" sectie ingeklapt │
├─────────────────────────────────────────────────────────────┤
│ 5. Psychiater klikt op "📎 3 bronnotities" bij Jan │
│ → Slide-in panel met originele verpleegkundige notities │
│ → Timestamps en auteurs zichtbaar │
├─────────────────────────────────────────────────────────────┤
│ 6. Psychiater in chat: "Wat was er gisteren met Jan?" │
│ → AI antwoordt met context uit eerdere notities │
│ → Geen nieuw artifact nodig │
├─────────────────────────────────────────────────────────────┤
│ 7. Psychiater klikt "✓ Gezien" │
│ → Overdracht gemarkeerd als gelezen │
│ → Chat: "Overdracht gemarkeerd als gezien." │
└─────────────────────────────────────────────────────────────┘
```
### Flow 3: Rapportage met Verduidelijkingsvragen
```
┌─────────────────────────────────────────────────────────────┐
│ 1. Verpleegkundige: "Ik heb een gesprek gehad" │
├─────────────────────────────────────────────────────────────┤
│ 2. AI: "Met welke patiënt had je het gesprek?" │
│ → Geen artifact (verduidelijking nodig) │
├─────────────────────────────────────────────────────────────┤
│ 3. Verpleegkundige: "Jan" │
├─────────────────────────────────────────────────────────────┤
│ 4. AI: "Ik maak een rapportage voor Jan de Vries. │
│ Wat wil je vastleggen?" │
│ → RapportageBlock verschijnt rechts (leeg) │
├─────────────────────────────────────────────────────────────┤
│ 5. Verpleegkundige: "Hij voelt zich beter, minder angstig" │
│ → Tekst verschijnt in RapportageBlock │
├─────────────────────────────────────────────────────────────┤
│ 6. AI: "Genoteerd. Wil je dit als voortgangsgesprek │
│ opslaan of is er meer?" │
├─────────────────────────────────────────────────────────────┤
│ 7. Verpleegkundige: "Opslaan als voortgang" │
│ → Rapportage opgeslagen met tag "Voortgangsgesprek" │
│ → Toast + chat confirmation │
└─────────────────────────────────────────────────────────────┘
```
---
## 6. Interacties met AI
🎯 **Doel:** Uitleggen waar AI in de flow voorkomt en wat de gebruiker ziet.
| Locatie | AI-actie | Trigger | Output |
|---------|----------|---------|--------|
| Chat | Conversatie + intent detection | Elke user message | Streaming text + action object |
| Chat | Verduidelijkingsvraag | Onduidelijke intent | Vraag in chat (geen artifact) |
| Chat | Follow-up verwerking | User antwoord op vraag | Update artifact of nieuwe info |
| OverdrachtBlock | Relevantie-filtering | "overdracht" intent | Gefilterde samenvatting |
| OverdrachtBlock | Samenvatting generatie | Per patiënt | Behandelrelevante bullets |
| RapportageBlock | Tekst structureren | "Structureer" knop | Gestructureerde tekst |
| RapportageBlock | B1-niveau herschrijven | "Vereenvoudig" knop | Herschreven tekst |
**Confidence Thresholds:**
| Confidence | Actie |
|------------|-------|
| >0.9 | Direct artifact openen met prefill |
| 0.7-0.9 | Artifact openen + bevestigingsvraag in chat |
| 0.5-0.7 | Verduidelijkingsvraag in chat, geen artifact |
| <0.5 | Fallback: "Ik begrijp je niet helemaal. Kun je het anders formuleren?" |
---
## 7. Gebruikersrollen en rechten
🎯 **Doel:** Beschrijven welke rollen toegang hebben tot welke onderdelen.
| Rol | Toegang | Artifacts | AI-filtering |
|-----|---------|-----------|--------------|
| **Verpleegkundige** | Eigen dienst patiënten | Alle P1/P2 artifacts | Input: alle notities |
| **Psychiater** | Alle patiënten in behandeling | OverdrachtBlock (read), PatientContextCard | Output: gefilterde samenvatting |
| **Behandelaar** | Eigen caseload | Alle artifacts | Beide views beschikbaar |
**Permissies per Artifact:**
| Artifact | Verpleegkundige | Psychiater | Behandelaar |
|----------|-----------------|------------|-------------|
| DagnotatieBlock | ✅ Create | ❌ | ✅ Create |
| RapportageBlock | ✅ Create | 👁️ Read | ✅ Create |
| OverdrachtBlock | ✅ Create | 👁️ Read (filtered) | ✅ Both |
| PatientContextCard | 👁️ Read | 👁️ Read | 👁️ Read |
---
## 8. Technische Specificaties
### 8.1 API Routes
| Route | Method | Functie | Status |
|-------|--------|---------|--------|
| `/api/swift/chat` | POST | Medical scribe chatbot | 🆕 Nieuw |
| `/api/swift/overdracht/generate` | POST | AI-gefilterde overdracht | 🔄 Herzien |
| `/api/intent/classify` | POST | Intent classification | ✅ Bestaat |
| `/api/patients/search` | GET | Patient search | ✅ Bestaat |
| `/api/reports` | POST | Report opslaan | ✅ Bestaat |
### 8.2 Store Uitbreiding
```typescript
interface SwiftStore {
// Bestaande state
activePatient: Patient | null;
activeBlock: BlockType | null;
shift: 'ochtend' | 'middag' | 'nacht';
// Chat state (nieuw)
chatMessages: ChatMessage[];
isStreaming: boolean;
pendingAction: Action | null;
// Artifact state (nieuw)
openArtifacts: Artifact[]; // Max 3
activeArtifactId: string | null;
// Actions
addChatMessage: (message: ChatMessage) => void;
processAction: (action: Action) => void;
openArtifact: (artifact: Artifact) => void;
closeArtifact: (id: string) => void;
}
```
### 8.3 Component Structuur
```
components/swift/
├── command-center/
│ ├── command-center.tsx # Split-screen container
│ ├── context-bar.tsx # Header met dienst/patient
│ ├── chat-panel.tsx # 🆕 Chat messages
│ ├── chat-input.tsx # Herzien: conversational
│ └── artifact-area.tsx # 🆕 Artifact container
├── chat/
│ ├── chat-message.tsx # 🆕 Individual message
│ ├── chat-action-link.tsx # 🆕 Clickable action
│ └── streaming-indicator.tsx # 🆕 Typing dots
├── artifacts/
│ ├── artifact-container.tsx # 🆕 Wrapper met tabs
│ ├── dagnotitie-block.tsx # Bestaand
│ ├── zoeken-block.tsx # Bestaand
│ ├── overdracht-block.tsx # Herzien: met filtering UI
│ ├── rapportage-block.tsx # Bestaand
│ └── patient-context-card.tsx # Bestaand
└── shared/
├── linked-evidence.tsx # 🆕 Bron-verwijzing component
└── relevance-badge.tsx # 🆕 "Behandelrelevant" indicator
```
---
## 9. UI Specificaties
### 9.1 Layout Breakpoints
| Viewport | Chat Panel | Artifact Area |
|----------|------------|---------------|
| Desktop (>1200px) | 40% | 60% |
| Tablet (768-1200px) | 45% | 55% |
| Mobile (<768px) | Full screen toggle | Full screen toggle |
### 9.2 Chat Message Styling
| Element | User Message | Assistant Message |
|---------|--------------|-------------------|
| Alignment | Right | Left |
| Background | Amber-50 (#FFFBEB) | Slate-100 (#F1F5F9) |
| Border | Amber-200 | Slate-200 |
| Max width | 80% | 80% |
| Border radius | 16px (top-right: 4px) | 16px (top-left: 4px) |
### 9.3 Artifact Animation
```css
/* Slide-in from right */
@keyframes artifact-enter {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.artifact-enter {
animation: artifact-enter 200ms ease-out;
}
```
---
## 10. Bijlagen & Referenties
🎯 **Doel:** Linken naar overige documenten.
### Project Documentatie
- PRD Ephemeral UI: `nextgen-epd-prd-ephemeral-ui-epd.md`
- UX/UI Specs: `swift-ux-v2.1.md`
- UX Research: `nextgen-epd-onderzoeksverslag-ux-ui-patterns.md`
- Bouwplan: `bouwplan-swift-v2.md`
- Project Status: `PROJECT-STATUS-2024-12-27.md`
### Externe Referenties
- [ChatGPT Canvas UX Analysis](https://altar.io/next-gen-of-human-ai-collaboration/)
- [Claude Artifacts Documentation](https://docs.anthropic.com)
- [Abridge Linked Evidence](https://www.abridge.com/product)
- [GGZ Zorgstandaarden](https://www.ggzstandaarden.nl)
---
## Wijzigingslog
| Versie | Datum | Wijzigingen |
|--------|-------|-------------|
| v2.0 | 23-12-2024 | Command Center met ephemeral blocks |
| v2.1 | 23-12-2024 | Prioriteitenlijst, intent mapping, P3 blocks |
| v3.0 | 27-12-2024 | **Redesign:** Chat + Artifact interface, Medical Scribe conversatie, AI-filtering voor psychiater |

View File

@@ -0,0 +1,437 @@
# 📊 Haalbaarheidsanalyse: Swift Medical Scribe v3.0
**Datum:** 27-12-2024
**Document:** `fo-swift-medical-scribe-v3.md`
**Auteur:** AI Assistant
---
## Executive Summary
Het v3.0 redesign van Swift naar een medical scribe chatbot interface is **haalbaar**, maar vereist significante architecturale wijzigingen. De bestaande foundation (Command Center, blocks, intent classification) kan worden hergebruikt, maar de conversatie-laag en split-screen layout zijn nieuw.
**Kernbevindingen:**
-**Sterke foundation:** Bestaande blocks, intent API, en voice input kunnen worden hergebruikt
- ⚠️ **Grote wijzigingen:** Conversatie-interface, chat API, en split-screen layout zijn nieuw
-**AI-infrastructuur:** Streaming chat API bestaat al (docs-chat), kan worden aangepast
- ⚠️ **Complexiteit:** Conversatiegeschiedenis en context management vereisen nieuwe state management
**Geschatte effort:** 6-8 weken (1 developer, full-time)
---
## 1. Inventarisatie Bestaande Componenten
### 1.1 ✅ Wat bestaat al en kan worden hergebruikt
| Component | Status | Locatie | Hergebruik |
|-----------|--------|---------|------------|
| **Command Center** | ✅ Done | `components/swift/command-center/` | ⚠️ Layout wijzigen naar split-screen |
| **Context Bar** | ✅ Done | `components/swift/command-center/context-bar.tsx` | ✅ Direct hergebruikbaar |
| **Blocks (Artifacts)** | ✅ Done | `components/swift/blocks/` | ✅ Direct herbruikbaar |
| **Intent Classification** | ✅ Done | `/api/intent/classify` | ✅ Herbruikbaar, maar moet worden uitgebreid |
| **Voice Input** | ✅ Done | `lib/swift/use-swift-voice.ts` | ✅ Direct herbruikbaar |
| **Swift Store** | ✅ Done | `stores/swift-store.ts` | ⚠️ Uitbreiden met chat state |
| **Overdracht API** | ✅ Done | `/api/overdracht/generate` | ✅ Bestaat, maar AI-filtering voor psychiater moet worden toegevoegd |
| **Streaming Chat API** | ✅ Bestaat | `/api/docs/chat` | ✅ Pattern kan worden gekopieerd |
### 1.2 🆕 Wat nieuw moet worden gebouwd
| Component | Complexiteit | Geschatte Effort |
|-----------|-------------|------------------|
| **Chat Panel** | Medium | 1 week |
| **Chat Input (conversational)** | Low | 3 dagen |
| **Chat API (`/api/swift/chat`)** | High | 1.5 week |
| **Artifact Area (split-screen)** | Medium | 1 week |
| **Chat Message Components** | Low | 3 dagen |
| **Conversation History Management** | Medium | 1 week |
| **AI-filtering voor psychiater** | Medium | 1 week |
| **Linked Evidence UI** | Low | 3 dagen |
**Totaal nieuwe componenten:** ~6-7 weken
---
## 2. Gedetailleerde Analyse per Sectie
### 2.1 Command Center → Split-Screen Layout
**Huidige situatie:**
- 4-zone layout: Context Bar | Canvas Area | Recent Strip | Command Input
- Blocks verschijnen in Canvas Area (centered, full-width)
**Vereiste wijziging:**
- Split-screen: Chat Panel (40%) links, Artifact Area (60%) rechts
- Recent Strip kan worden verwijderd of geïntegreerd in chat
**Haalbaarheid:****Goed**
- Layout wijziging is relatief eenvoudig met CSS Grid/Flexbox
- Bestaande blocks blijven werken, alleen positioning wijzigt
- **Effort:** 3-5 dagen
**Risico's:**
- Responsive design voor mobile/tablet vereist toggle tussen chat en artifact
- Keyboard shortcuts moeten worden aangepast
---
### 2.2 Chat Panel & Conversatie
**Huidige situatie:**
- Geen chat interface
- Command Input stuurt direct naar intent classification
**Vereiste wijziging:**
- Nieuwe Chat Panel component met message bubbles
- Conversatiegeschiedenis (max 100 messages)
- Streaming responses (zoals docs-chat)
**Haalbaarheid:****Goed**
- Pattern bestaat al in `components/docs-chat/`
- `use-docs-chat.ts` hook kan worden aangepast voor Swift
- **Effort:** 1 week
**Risico's:**
- Performance bij lange conversaties (pagination nodig)
- State management voor chat history (Zustand store uitbreiden)
---
### 2.3 Medical Scribe Chat API
**Huidige situatie:**
- `/api/intent/classify` retourneert alleen intent + entities
- Geen conversatie, geen streaming
**Vereiste wijziging:**
- Nieuwe `/api/swift/chat` endpoint
- Streaming responses (SSE)
- Conversatiegeschiedenis als input
- Action objects in response (intent + entities + artifact prefill)
**Haalbaarheid:** ⚠️ **Middelmatig**
- Pattern bestaat in `/api/docs/chat` (streaming met Claude)
- Moet worden uitgebreid met:
- Intent detection tijdens conversatie
- Action object generation
- Context management (activePatient, shift, recentActions)
- **Effort:** 1.5 week
**Risico's:**
- AI prompt engineering voor medical scribe persona
- Performance bij hoge load (rate limiting nodig)
- Kosten (Claude API calls per message)
**Aanbeveling:**
```typescript
// Hybrid approach: local intent first, AI voor conversatie
1. Local pattern matching (<50ms) direct action
2. Als geen match AI chat API met conversatie context
3. AI detecteert intent + genereert response + action object
```
---
### 2.4 Intent Engine (Hybrid)
**Huidige situatie:**
- Two-tier: local patterns → AI fallback
- Werkt goed voor directe commando's
**Vereiste wijziging:**
- Local patterns blijven voor snelle acties
- AI chat API voor conversatie + follow-up vragen
- Confidence thresholds voor artifact opening
**Haalbaarheid:****Goed**
- Bestaande intent classifier blijft werken
- Chat API gebruikt AI voor conversatie + intent detection
- **Effort:** 3 dagen (integratie)
---
### 2.5 Artifact Area (Split-Screen)
**Huidige situatie:**
- Blocks verschijnen centered in Canvas Area
- Eén block tegelijk
**Vereiste wijziging:**
- Artifacts rechts (60% width)
- Meerdere artifacts mogelijk (tabs, max 3)
- Slide-in animatie van rechts
**Haalbaarheid:****Goed**
- Bestaande blocks blijven werken
- Nieuwe wrapper component met tabs
- **Effort:** 1 week
**Risico's:**
- State management voor meerdere open artifacts
- Tab switching UX
---
### 2.6 AI-Filtering voor Psychiater
**Huidige situatie:**
- `/api/overdracht/generate` genereert samenvatting voor alle notities
- Geen filtering op behandelrelevantie
**Vereiste wijziging:**
- AI-filtering: alleen behandelrelevante notities
- Linked evidence: elke zin linkt naar bronnotitie
- UI: "Behandelrelevant" vs "Geen bijzonderheden" secties
**Haalbaarheid:** ⚠️ **Middelmatig**
- AI prompt moet worden uitgebreid met filtering criteria
- Linked evidence vereist tracking van bronnotities per zin
- **Effort:** 1 week
**Risico's:**
- AI filtering accuracy (false negatives = belangrijke info gemist)
- Linked evidence parsing (welke zin komt van welke notitie?)
**Aanbeveling:**
- Start met simpele keyword-based filtering als fallback
- AI filtering als primary, met optie om "alles te tonen"
---
### 2.7 Store Uitbreiding
**Huidige situatie:**
```typescript
interface SwiftStore {
activePatient: Patient | null;
activeBlock: BlockType | null;
prefillData: BlockPrefillData;
// ... geen chat state
}
```
**Vereiste wijziging:**
```typescript
interface SwiftStore {
// Bestaand
activePatient: Patient | null;
activeBlock: BlockType | null;
// Nieuw: Chat state
chatMessages: ChatMessage[];
isStreaming: boolean;
pendingAction: Action | null;
// Nieuw: Artifact state
openArtifacts: Artifact[]; // Max 3
activeArtifactId: string | null;
}
```
**Haalbaarheid:****Goed**
- Zustand store is makkelijk uit te breiden
- **Effort:** 2 dagen
---
## 3. Technische Risico's & Uitdagingen
### 3.1 🔴 Hoge Risico's
| Risico | Impact | Mitigatie |
|--------|--------|-----------|
| **AI Prompt Engineering** | High | Medical scribe persona moet natuurlijk klinken, maar ook betrouwbaar zijn. Iteratief testen met echte gebruikers. |
| **Performance bij lange conversaties** | Medium | Pagination voor chat history, max 100 messages in view. Virtual scrolling overwegen. |
| **AI Kosten** | Medium | Rate limiting, caching van responses waar mogelijk. Local patterns gebruiken voor snelle acties. |
| **State Management Complexiteit** | Medium | Duidelijke scheiding tussen chat state en artifact state. UseReducer overwegen voor complexe state. |
### 3.2 🟡 Middelmatige Risico's
| Risico | Impact | Mitigatie |
|--------|--------|-----------|
| **Responsive Design** | Medium | Mobile: toggle tussen chat en artifact. Tablet: 45/55 split. |
| **Linked Evidence Parsing** | Medium | AI moet structured output geven met bronverwijzingen per zin. Fallback: keyword matching. |
| **Conversatie Context Verlies** | Low | Context manager bewaart actieve patiënt, shift, recente acties. Max 20 messages in API call. |
### 3.3 🟢 Lage Risico's
| Risico | Impact | Mitigatie |
|--------|--------|-----------|
| **Block Migratie** | Low | Bestaande blocks blijven werken, alleen wrapper wijzigt. |
| **Voice Input** | Low | Bestaande implementatie blijft werken. |
---
## 4. Migratie Strategie
### 4.1 Fase 1: Foundation (Week 1-2)
- ✅ Split-screen layout implementeren
- ✅ Chat Panel component bouwen
- ✅ Store uitbreiden met chat state
- ✅ Basis chat API endpoint
**Deliverable:** Werkende split-screen met chat (zonder AI)
### 4.2 Fase 2: Chat API & Conversatie (Week 3-4)
- ✅ Medical scribe chat API implementeren
- ✅ Streaming responses
- ✅ Intent detection in conversatie
- ✅ Action object generation
**Deliverable:** Werkende conversatie met artifact opening
### 4.3 Fase 3: Artifact Area (Week 5)
- ✅ Artifact Area component met tabs
- ✅ Meerdere artifacts ondersteuning
- ✅ Slide-in animaties
**Deliverable:** Meerdere artifacts tegelijk mogelijk
### 4.4 Fase 4: AI-Filtering & Polish (Week 6-7)
- ✅ AI-filtering voor psychiater overdracht
- ✅ Linked evidence UI
- ✅ Error handling & edge cases
- ✅ Performance optimalisatie
**Deliverable:** Volledige v3.0 functionaliteit
### 4.5 Fase 5: Testing & Refinement (Week 8)
- ✅ User testing
- ✅ Bug fixes
- ✅ Performance tuning
- ✅ Documentatie
**Deliverable:** Production-ready v3.0
---
## 5. Aanbevelingen
### 5.1 ✅ Doen
1. **Hergebruik bestaande patterns**
- Kopieer `use-docs-chat.ts` hook als basis voor Swift chat
- Hergebruik streaming pattern van `/api/docs/chat`
2. **Incrementele migratie**
- Behoud oude Command Center tijdens ontwikkeling
- Feature flag voor nieuwe interface
- A/B testing mogelijkheid
3. **Local-first approach**
- Gebruik local patterns voor snelle acties (zoals nu)
- AI alleen voor conversatie en complexe queries
4. **Performance monitoring**
- Track AI API response times
- Monitor chat history size
- Alert bij lange conversaties
### 5.2 ⚠️ Overwegen
1. **Hybrid Intent Detection**
- Local patterns voor P1 intents (dagnotitie, zoeken)
- AI chat voor P2 intents en follow-up vragen
2. **Conversation Context Window**
- Max 20 messages in API call (zoals gespecificeerd)
- Summarization voor oudere messages
3. **Artifact Persistence**
- Sla open artifacts op in localStorage
- Herstel bij page reload
### 5.3 ❌ Niet Doen (YAGNI)
1. **Geen volledige rewrite**
- Bestaande blocks blijven werken
- Alleen wrapper en layout wijzigen
2. **Geen nieuwe voice engine**
- Bestaande Deepgram implementatie is voldoende
3. **Geen real-time collaboration**
- Niet nodig voor MVP
---
## 6. Conclusie
### Haalbaarheid: ✅ **HAALBAAR**
Het v3.0 redesign is haalbaar binnen 6-8 weken met 1 developer. De bestaande foundation is sterk en kan worden hergebruikt. De grootste uitdagingen zijn:
1. **Chat API ontwikkeling** (1.5 week)
2. **AI prompt engineering** (iteratief, doorlopend)
3. **State management complexiteit** (manageable met Zustand)
### Success Criteria
- [ ] Split-screen layout werkt op desktop/tablet/mobile
- [ ] Conversatie voelt natuurlijk (niet robotisch)
- [ ] Artifacts openen binnen 2 seconden na intent detection
- [ ] AI-filtering voor psychiater heeft >90% accuracy
- [ ] Performance: <500ms voor local patterns, <3s voor AI responses
### Volgende Stappen
1.**Go/No-Go beslissing** op basis van deze analyse
2.**Bouwplan v3.0** opstellen met gedetailleerde stories
3.**Sprint planning** voor Fase 1-5
4.**AI prompt engineering** starten (parallel met development)
---
## Bijlagen
### A. Bestaande Componenten Overzicht
```
components/swift/
├── command-center/
│ ├── command-center.tsx ✅ Herbruikbaar (layout wijzigen)
│ ├── context-bar.tsx ✅ Direct herbruikbaar
│ ├── command-input.tsx ⚠️ Aanpassen naar chat input
│ ├── canvas-area.tsx ⚠️ Vervangen door artifact-area
│ └── recent-strip.tsx ❓ Verwijderen of integreren
├── blocks/
│ ├── dagnotitie-block.tsx ✅ Direct herbruikbaar
│ ├── zoeken-block.tsx ✅ Direct herbruikbaar
│ ├── overdracht-block.tsx ⚠️ Uitbreiden met AI-filtering
│ └── patient-context-card.tsx ✅ Direct herbruikbaar
```
### B. Nieuwe Componenten Overzicht
```
components/swift/
├── chat/ 🆕 Nieuw
│ ├── chat-panel.tsx
│ ├── chat-message.tsx
│ ├── chat-action-link.tsx
│ └── streaming-indicator.tsx
├── artifacts/ 🆕 Nieuw
│ ├── artifact-container.tsx (wrapper met tabs)
│ └── artifact-tab.tsx
└── shared/ 🆕 Nieuw
├── linked-evidence.tsx
└── relevance-badge.tsx
```
### C. API Routes Overzicht
```
app/api/
├── swift/ 🆕 Nieuw
│ └── chat/
│ └── route.ts (medical scribe chatbot)
├── intent/
│ └── classify/ ✅ Bestaat (herbruikbaar)
└── overdracht/
└── generate/ ✅ Bestaat (uitbreiden met filtering)
```
---
**Einde analyse**

View File

@@ -0,0 +1,666 @@
# 🎨 Swift v3.0 Redesign — Van Command Center naar Medical Scribe
**Datum:** 27-12-2024
**Versie:** v3.0 Design Specification
**Samengesteld door:** AI Assistant
---
## 📋 Inhoudsopgave
1. [Executive Summary](#executive-summary)
2. [Van v2.1 naar v3.0: Wat verandert](#van-v21-naar-v30-wat-verandert)
3. [Huidige UX/Styling (v2.1)](#huidige-uxstyling-v21)
4. [Nieuwe UX/Styling (v3.0)](#nieuwe-uxstyling-v30)
5. [Wat blijft hetzelfde](#wat-blijft-hetzelfde)
6. [Wat wijzigt](#wat-wijzigt)
7. [Implementatie Strategie](#implementatie-strategie)
8. [Design Tokens & Styling](#design-tokens--styling)
---
## Executive Summary
Swift v3.0 transformeert van een **command-line style interface** naar een **conversational medical scribe chatbot**. De kernprincipes van Ephemeral UI blijven behouden, maar de interactie verschuift van transactioneel naar relationeel.
### Kernveranderingen
| Aspect | v2.1 (Command Center) | v3.0 (Medical Scribe) |
|--------|----------------------|----------------------|
| **Input model** | Command-line ("notitie jan medicatie") | Natuurlijke conversatie ("Ik heb medicatie gegeven aan Jan") |
| **UI paradigma** | Centered blocks (ephemeral) | Split-screen: Chat (40%) + Artifacts (60%) |
| **Context** | Per commando | Doorlopende conversatiegeschiedenis |
| **AI rol** | Intent classifier | Converserende medical scribe |
| **Interactie** | Transactioneel (one-shot) | Relationeel (follow-up mogelijk) |
### Wat blijft
**Ephemeral UI principe** — UI verschijnt/verdwijnt wanneer nodig
**Alle bestaande blocks** — DagnotatieBlock, ZoekenBlock, OverdrachtBlock, etc.
**Color system** — Shift colors, category colors, design tokens
**Keyboard shortcuts** — ⌘K, Escape, Enter, 1-9
**Voice input** — Deepgram integratie blijft werken
**Context Bar** — Shift, patient, user info
### Wat wijzigt
🔄 **Layout** — 4-zone → Split-screen (chat + artifacts)
🔄 **Input** — Command input → Chat input met conversatie
🔄 **Canvas Area** → Artifact Area (rechts, 60%)
🔄 **Recent Strip** → Optioneel (kan geïntegreerd in chat)
🔄 **AI Engine** — Intent classifier → Medical scribe chatbot
---
## Van v2.1 naar v3.0: Wat verandert
### v2.1 Layout (Huidig)
```
┌─────────────────────────────────────────────────────────────────┐
│ 🕐 Ochtend | 8 ptn Jan de Vries ▼ 👤 SV │ ← Context Bar (48px)
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ │
│ │ │ │
│ │ ACTIVE BLOCK │ │ ← Canvas Area (flex)
│ │ (centered) │ │
│ │ │ │
│ └─────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────┤
│ Recent: [📝 Jan-Med] [🔄 Overdracht] [🔍 Marie] │ ← Recent Strip (48px)
├─────────────────────────────────────────────────────────────────┤
│ 🎤 Typ of spreek wat je wilt doen... ⌘K │ ← Command Input (64px)
└─────────────────────────────────────────────────────────────────┘
```
### v3.0 Layout (Nieuw)
```
┌─────────────────────────────────────────────────────────────────┐
│ 🕐 Ochtend | 8 ptn Jan de Vries ▼ 👤 SV │ ← Context Bar (48px)
├──────────────────────────────┬──────────────────────────────────┤
│ │ │
│ CHAT PANEL (40%) │ ARTIFACT AREA (60%) │
│ │ │
│ 👤 "Ik heb net medicatie │ ┌────────────────────────────┐ │
│ gegeven aan Jan" │ │ 📝 Dagnotitie │ │
│ │ │ │ │
│ 🤖 Ik maak een dagnotitie │ │ Patiënt: Jan de Vries ✓ │ │
│ voor Jan de Vries. │ │ Categorie: Medicatie ✓ │ │
│ Categorie: Medicatie. │ │ │ │
│ │ │ [Opslaan] │ │
│ Wil je nog iets │ └────────────────────────────┘ │
│ toevoegen? │ │
│ │ │
│ 👤 "Nee, opslaan" │ │
│ │ │
│ 🤖 ✓ Notitie opgeslagen │ │
│ │ │
├──────────────────────────────┤ │
│ 💬 Typ of spreek... 🎤 │ │ ← Chat Input (64px)
└──────────────────────────────┴──────────────────────────────────┘
```
---
## Huidige UX/Styling (v2.1)
### Layout Zones
| Zone | Hoogte | Functie | Component |
|------|--------|---------|-----------|
| **Context Bar** | 48px (h-12) | Dienst, actieve patiënt, user | `context-bar.tsx` |
| **Canvas Area** | flex-1 | Waar blocks verschijnen (centered) | `canvas-area.tsx` |
| **Recent Strip** | 48px (h-12) | Laatste acties, quick access | `recent-strip.tsx` |
| **Command Input** | 64px (h-16) | Command-line style input + voice | `command-input.tsx` |
### Context Bar (Blijft grotendeels hetzelfde)
**Huidige implementatie:**
```tsx
<header className="h-12 border-b border-slate-200 flex items-center px-4 justify-between">
{/* Left: Logo + Shift */}
<div className="flex items-center gap-4">
<Link href="/epd">Swift</Link>
<ShiftIcon /> {/* Sunrise/Sun/Sunset/Moon */}
<span>{shiftLabel}</span> {/* Ochtenddienst/Middagdienst/etc. */}
</div>
{/* Center: Active Patient */}
<div className="flex items-center gap-2">
<Avatar>{initials}</Avatar>
<span>{patientName}</span>
<button onClick={clearPatient}><X /></button>
</div>
{/* Right: User */}
<div className="flex items-center gap-2">
<User />
<span>Verpleegkundige</span>
</div>
</header>
```
**Dienst kleuren:**
| Dienst | Tijd | Kleur | Icon |
|--------|------|-------|------|
| Ochtend | 07:00-15:00 | `text-amber-600` (#F59E0B) | Sunrise |
| Middag | 15:00-23:00 | `text-yellow-600` (#3B82F6) | Sun |
| Avond | 15:00-23:00 | `text-orange-600` | Sunset |
| Nacht | 23:00-07:00 | `text-indigo-600` (#6366F1) | Moon |
### Command Input (Wijzigt naar Chat Input)
**Huidige states:**
- **Default**: "Typ of spreek wat je wilt doen..." + mic icon
- **Typing**: Tekst + cursor
- **Listening**: 🔴 + waveform + live transcript
- **Processing**: "Even kijken wat je bedoelt..."
**Styling:**
```css
height: 64px (h-16)
background: #FFFFFF
border: 1px #E2E8F0, 2px #3B82F6 (focus)
border-radius: 16px
shadow: lg
font-size: 18px
position: fixed bottom, 24px padding
```
### Block Styling (Blijft hetzelfde)
**Block sizes:**
| Size | Max-width | Use case |
|------|-----------|----------|
| Small | 480px | Quick entry (notitie, zoeken, meting) |
| Medium | 640px | Forms (rapportage, behandelplan) |
| Large | 900px | Overzichten (overdracht, patiëntenlijst) |
| XLarge | 1100px | Wizards (intake volledig) |
**Categorie kleuren (verpleegkundig):**
| Categorie | Background | Accent | Icon | Keyboard |
|-----------|------------|--------|------|----------|
| Medicatie | `#FEF6DC` | `#F59E0B` | 💊 | 1 |
| ADL | `#E8F8EF` | `#16A34A` | 🍽️ | 2 |
| Observatie | `#EFF6FF` | `#3B82F6` | 👁️ | 3 |
| Incident | `#FEF2F2` | `#DC2626` | ⚠️ | 4 |
| Algemeen | `#F1F5F9` | `#64748B` | 💬 | 5 |
### Keyboard Shortcuts (Blijft hetzelfde)
| Key | Action |
|-----|--------|
| `⌘K` / `Ctrl+K` | Focus command input (blijft focus chat input) |
| `Escape` | Close active block (blijft) |
| `Enter` | Submit (blijft) |
| `⌘Enter` / `Ctrl+Enter` | Quick submit (blijft) |
| `↑` `↓` | Navigate results / history |
| `1-9` | Quick select in FallbackPicker |
| `Space` (empty input) | Start voice (blijft) |
### Voice Input (Blijft hetzelfde)
**Flow:**
1. User klikt mic of drukt spatie (bij lege input)
2. Deepgram start streaming transcription
3. Live transcript verschijnt in input field
4. Pauze detectie (1.5 sec stilte) → auto-submit
5. Of user klikt "Stop" → submit
---
## Nieuwe UX/Styling (v3.0)
### Layout Zones (Gewijzigd)
| Zone | Breedte | Functie | Component |
|------|---------|---------|-----------|
| **Context Bar** | 100% x 48px | Dienst, actieve patiënt, user | `context-bar.tsx` (ongewijzigd) |
| **Chat Panel** | 40% x flex | Conversatie met medical scribe | `chat-panel.tsx` (nieuw) |
| **Artifact Area** | 60% x flex | Waar blocks/artifacts verschijnen | `artifact-area.tsx` (nieuw) |
| **Chat Input** | 40% x 64px | Conversational input + voice | `chat-input.tsx` (herzien) |
### Chat Panel (Nieuw)
**Message Types:**
| Type | Alignment | Background | Border | Icon |
|------|-----------|------------|--------|------|
| User message | Right | Amber-50 (#FFFBEB) | Amber-200 | 👤 |
| Assistant text | Left | Slate-100 (#F1F5F9) | Slate-200 | 🤖 |
| Assistant action | Left | Slate-100 | Slate-200 | 📝/🔍/🔄 (klikbaar) |
| System message | Center | - | - | ✓ |
| Error message | Left | Red-50 | Red-200 | ⚠️ |
**Message Styling:**
```css
/* User message */
.message-user {
align-self: flex-end;
background: #FFFBEB;
border: 1px solid #FED7AA;
border-radius: 16px;
border-top-right-radius: 4px;
max-width: 80%;
padding: 12px 16px;
margin: 4px 0;
}
/* Assistant message */
.message-assistant {
align-self: flex-start;
background: #F1F5F9;
border: 1px solid #CBD5E1;
border-radius: 16px;
border-top-left-radius: 4px;
max-width: 80%;
padding: 12px 16px;
margin: 4px 0;
}
```
**Gedrag:**
- Auto-scroll naar laatste message
- Scroll-lock wanneer gebruiker omhoog scrollt
- "Scroll to bottom" knop bij nieuwe messages (↓)
- Max 100 messages in view (pagination voor oudere)
- Streaming indicator tijdens AI response (pulsating dots)
### Chat Input (Herzien)
**States (blijven grotendeels hetzelfde):**
| State | Weergave | Trigger |
|-------|----------|---------|
| Default | "Typ of spreek..." + mic icon | — |
| Typing | Cursor + getypte tekst | Keyboard input |
| Listening | 🔴 + waveform + live transcript | Mic click of spatie |
| Processing | Disabled, "Denkt na..." | Na submit |
| Streaming | Disabled, streaming in chat | Tijdens AI response |
**Keyboard Shortcuts (uitgebreid):**
| Key | Actie |
|-----|-------|
| `Enter` | Submit message |
| `⌘Enter` / `Ctrl+Enter` | Force submit (ook tijdens streaming) |
| `Escape` | Clear input / cancel voice |
| `↑` | Vorige message (edit history) |
| `Space` (leeg) | Start voice recording |
| `⌘K` | Focus input |
### Artifact Area (Nieuw)
**Layout opties:**
| Situatie | Weergave |
|----------|----------|
| Geen artifact | Placeholder met voorbeelden |
| Eén artifact | Full width, centered |
| Meerdere artifacts | Tabs bovenaan (max 3) |
**Placeholder State:**
```
┌────────────────────────────────────────────────────────────┐
│ │
│ 💬 Artifacts verschijnen hier │
│ │
│ Vraag me iets, bijvoorbeeld: │
│ • "Notitie voor Jan: medicatie gegeven" │
│ • "Zoek Marie van den Berg" │
│ • "Maak overdracht voor deze dienst" │
│ │
└────────────────────────────────────────────────────────────┘
```
**Artifact Lifecycle:**
1. Intent detected in chat → AI response: "Ik maak een dagnotitie..."
2. Artifact appears → Slide-in animation (200ms, from right)
3. Pre-filled met extracted entities
4. User interacts → Edits fields, kan blijven chatten
5. User saves → Toast + chat confirmation + artifact closes (optioneel)
**Artifact Animation:**
```css
@keyframes artifact-enter {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.artifact-enter {
animation: artifact-enter 200ms ease-out;
}
```
### Responsive Breakpoints (Nieuw)
| Viewport | Chat Panel | Artifact Area |
|----------|------------|---------------|
| Desktop (>1200px) | 40% | 60% |
| Tablet (768-1200px) | 45% | 55% |
| Mobile (<768px) | Full screen toggle | Full screen toggle |
---
## Wat blijft hetzelfde
### ✅ Components die NIET wijzigen
1. **Context Bar**`context-bar.tsx`
- Shift indicator met kleuren
- Patient selector
- User info
2. **Alle Block componenten**`blocks/*.tsx`
- `DagnotatieBlock`
- `ZoekenBlock`
- `OverdrachtBlock` ✅ (wel uitbreiding AI-filtering)
- `RapportageBlock`
- `AgendaBlock`
- `MetingenBlock`
- `PatientContextCard`
3. **Voice Input**`lib/swift/use-swift-voice.ts`
- Deepgram streaming transcription
- Live transcript
- Pauze detectie
4. **Store**`stores/swift-store.ts`
- activePatient, shift, activeBlock
- Wordt uitgebreid, maar bestaande state blijft
5. **Design Tokens**
- Color palette
- Category colors
- Shift colors
- Typography
- Spacing
### ✅ Gedrag dat NIET wijzigt
- Keyboard shortcuts (⌘K, Escape, Enter, etc.)
- Voice recording flow
- Block prefill logic
- Patient search
- Category selection (1-9 keys)
- Toast notifications
- Error handling (offline banner, retry logic)
---
## Wat wijzigt
### 🔄 Components die WIJZIGEN
1. **CommandCenter**`command-center.tsx`
- **Van:** 4-zone layout (context | canvas | recent | input)
- **Naar:** Split-screen layout (context | chat+artifact | input)
- **Effort:** 3-5 dagen
2. **CommandInput****ChatInput**`command-input.tsx`
- **Van:** Single-line command input
- **Naar:** Multi-line chat input (onderaan chat panel, 40% width)
- **Blijft:** Voice input, keyboard shortcuts, states
- **Effort:** 3 dagen
3. **CanvasArea****ArtifactArea**`canvas-area.tsx`
- **Van:** Centered block display
- **Naar:** Right-side artifact area (60% width) met tabs
- **Effort:** 1 week
4. **RecentStrip**`recent-strip.tsx`
- **Van:** Fixed bar onderaan canvas
- **Naar:** Optioneel (kan geïntegreerd in chat history of verwijderd)
- **Effort:** 1 dag (verwijderen of integreren)
### 🆕 Components die NIEUW zijn
1. **ChatPanel**`chat-panel.tsx`
- Scrollable message list
- User/assistant message bubbles
- Streaming indicator
- Action links
- **Effort:** 1 week
2. **ChatMessage**`chat-message.tsx`
- Message bubble component
- Different types (user, assistant, system, error)
- **Effort:** 2 dagen
3. **StreamingIndicator**`streaming-indicator.tsx`
- Pulsating dots tijdens AI response
- **Effort:** 1 dag
4. **ChatActionLink**`chat-action-link.tsx`
- Klikbare links in assistant messages naar artifacts
- **Effort:** 1 dag
5. **ArtifactContainer**`artifact-container.tsx`
- Wrapper met tabs (max 3 artifacts)
- Tab switching
- **Effort:** 3 dagen
6. **LinkedEvidence**`linked-evidence.tsx`
- Voor OverdrachtBlock: links naar bronnotities
- **Effort:** 2 dagen
### 🔄 Backend/API die WIJZIGT
1. **Intent Classification**`/api/intent/classify`
- **Van:** Simple pattern matching + AI fallback
- **Naar:** Blijft werken, maar wordt geïntegreerd in chat API
- **Effort:** 1 dag (integratie)
2. **Nieuwe Chat API**`/api/swift/chat`
- Medical scribe chatbot endpoint
- Streaming responses (SSE)
- Conversatiegeschiedenis als input
- Action objects in response
- **Effort:** 1.5 week
3. **Overdracht AI-Filtering**`/api/overdracht/generate`
- **Van:** Alle notities samenvatten
- **Naar:** + Filtering op behandelrelevantie (voor psychiater)
- **Effort:** 1 week
---
## Implementatie Strategie
### Fase 1: Foundation (Week 1-2)
**Doel:** Split-screen layout werkend krijgen zonder chat functionaliteit
**Taken:**
1. CommandCenter layout wijzigen naar split-screen (40/60)
2. ChatPanel skeleton (nog zonder AI, gewoon tekst weergave)
3. ArtifactArea component (wrapper voor bestaande blocks)
4. Store uitbreiden met chat state (chatMessages, isStreaming)
**Deliverable:** Split-screen layout zichtbaar, bestaande blocks werken in artifact area
**Risico's:**
- Responsive design voor mobile/tablet
- Block positioning in artifact area (60% width i.p.v. centered)
---
### Fase 2: Chat API & Conversatie (Week 3-4)
**Doel:** Conversatie met medical scribe werkend krijgen
**Taken:**
1. Chat API endpoint bouwen (`/api/swift/chat`)
2. Medical scribe system prompt
3. Streaming responses (SSE) implementeren
4. ChatMessage componenten bouwen
5. Intent detection in conversatie
6. Action object generation
**Deliverable:** Werkende conversatie die artifacts kan openen
**Risico's:**
- AI prompt engineering (natuurlijk klinken + betrouwbaar)
- Performance bij lange conversaties
- Kosten (Claude API calls)
---
### Fase 3: Artifact Area & Polish (Week 5-6)
**Doel:** Meerdere artifacts, polish, AI-filtering
**Taken:**
1. Meerdere artifacts ondersteuning (tabs, max 3)
2. Slide-in animaties
3. AI-filtering voor psychiater overdracht
4. Linked evidence UI
5. Error handling & edge cases
6. Performance optimalisatie
**Deliverable:** Volledige v3.0 functionaliteit
---
### Fase 4: Testing & Refinement (Week 7-8)
**Doel:** Production-ready maken
**Taken:**
1. User testing
2. Bug fixes
3. Performance tuning
4. Documentatie
5. Migration plan (feature flag)
**Deliverable:** Production-ready v3.0
---
## Design Tokens & Styling
### Colors (Blijft hetzelfde)
```css
/* App colors */
--bg-app: #F8FAFC;
--bg-surface: #FFFFFF;
--text-primary: #0F172A;
--text-secondary: #475569;
--border: #E2E8F0;
--brand: #3B82F6;
--success: #16A34A;
--warning: #EAB308;
--error: #DC2626;
/* Shift colors */
--shift-ochtend: #F59E0B;
--shift-middag: #EAB308;
--shift-avond: #FB923C;
--shift-nacht: #6366F1;
/* Category colors */
--cat-medicatie-bg: #FEF6DC;
--cat-medicatie-accent: #F59E0B;
--cat-adl-bg: #E8F8EF;
--cat-adl-accent: #16A34A;
--cat-observatie-bg: #EFF6FF;
--cat-observatie-accent: #3B82F6;
--cat-incident-bg: #FEF2F2;
--cat-incident-accent: #DC2626;
--cat-algemeen-bg: #F1F5F9;
--cat-algemeen-accent: #64748B;
```
### Chat Message Colors (Nieuw)
```css
/* Chat message colors */
--chat-user-bg: #FFFBEB;
--chat-user-border: #FED7AA;
--chat-assistant-bg: #F1F5F9;
--chat-assistant-border: #CBD5E1;
--chat-system-text: #64748B;
--chat-error-bg: #FEF2F2;
--chat-error-border: #FECACA;
```
### Typography (Blijft hetzelfde)
```css
/* Font sizes */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
/* Font weights */
--font-normal: 400;
--font-medium: 500;
--font-semibold: 600;
--font-bold: 700;
```
### Spacing (Blijft hetzelfde)
```css
/* Spacing scale */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
```
### Border Radius (Blijft hetzelfde)
```css
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 16px;
--radius-full: 9999px;
```
---
## Conclusie
Het v3.0 redesign is **haalbaar binnen 6-8 weken** omdat:
1.**Sterke foundation** — Alle blocks, voice input, design tokens blijven werken
2.**Incrementele wijziging** — Geen complete rewrite, layout + conversatie laag toevoegen
3.**Bestaande patterns** — Chat API pattern bestaat al (`/api/docs/chat`)
4.**Design continuïteit** — Kleuren, typography, spacing blijven hetzelfde
**Grootste uitdagingen:**
- Medical scribe prompt engineering (natuurlijk + betrouwbaar)
- Chat state management (Zustand store uitbreiden)
- Performance bij lange conversaties
**Grootste voordelen:**
- Natuurlijkere interactie (relationeel i.p.v. transactioneel)
- Follow-up vragen mogelijk
- Context behouden tijdens werk
- Overeenkomsten met ChatGPT/Claude (bekend voor gebruikers)
---
## Referenties
- **FO v3.0:** `fo-swift-medical-scribe-v3.md` — Functioneel ontwerp
- **Haalbaarheid:** `haalbaarheidsanalyse-v3.md` — Feasibility analysis
- **UX v2.1:** `archive/swift-ux-v2.1.md` — Huidige UX/styling
- **Bouwplan v2:** `bouwplan-swift-v2.md` — Development roadmap

11
mcp.json Normal file
View File

@@ -0,0 +1,11 @@
{
"mcpServers": {
"supabase": {
"type": "http",
"url": "https://mcp.supabase.com/mcp?project_ref=dqugbrpwtisgyxscpefg",
"headers": {
"Authorization": "Bearer sbp_6598641b9c7afc57968d9a362088f506e9f3e20b"
}
}
}
}

View File

@@ -0,0 +1,10 @@
-- Check welke patiënten er in de database zitten
SELECT
id,
name_given,
name_family,
name_prefix,
birth_date
FROM patients
ORDER BY created_at DESC
LIMIT 20;

View File

@@ -0,0 +1,398 @@
-- ============================================================================
-- SEED VERPLEEGKUNDIGE OVERDRACHT DATA
-- ============================================================================
-- Created: 2024-12-27
-- Purpose: Populate reports table with realistic nursing handover data
-- to demonstrate the verpleegkundige overdracht (nursing handover) features
-- ============================================================================
DO $$
DECLARE
patient_colin_id UUID;
patient_jan_id UUID;
patient_optimus_id UUID;
practitioner_sarah_id UUID := '10000000-0000-0000-0000-000000000001'::uuid;
practitioner_mark_id UUID := '10000000-0000-0000-0000-000000000002'::uuid;
practitioner_lisa_id UUID := '10000000-0000-0000-0000-000000000003'::uuid;
-- Datums voor realistische tijdlijn
vandaag DATE := CURRENT_DATE;
gisteren DATE := CURRENT_DATE - INTERVAL '1 day';
eergisteren DATE := CURRENT_DATE - INTERVAL '2 days';
BEGIN
-- Get patient IDs
SELECT id INTO patient_colin_id FROM patients WHERE name_family = 'Lit' AND 'Colin' = ANY(name_given);
SELECT id INTO patient_jan_id FROM patients WHERE name_family = 'de Vriesh' AND 'Jan' = ANY(name_given);
SELECT id INTO patient_optimus_id FROM patients WHERE name_family = 'Prime' AND 'Optimus' = ANY(name_given);
-- ============================================================================
-- VANDAAG - Diverse rapportages gedurende de dag
-- ============================================================================
-- NACHT (02:00) - Colin - Observatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Patiënt slaapt rustig. Geen bijzonderheden.',
practitioner_lisa_id,
vandaag + TIME '02:00:00',
gisteren, -- Nachtdienst hoort bij vorige dag
false,
jsonb_build_object('category', 'observatie')
) ON CONFLICT DO NOTHING;
-- OCHTEND (07:30) - Colin - ADL
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Patiënt zelfstandig gedoucht en aangekleed. Heeft ontbijt genuttigd (brood, yoghurt). Stemming lijkt iets somberder dan gisteren.',
practitioner_sarah_id,
vandaag + TIME '07:30:00',
vandaag,
true, -- Belangrijk voor overdracht: stemming somberder
jsonb_build_object('category', 'adl')
) ON CONFLICT DO NOTHING;
-- OCHTEND (08:15) - Colin - Medicatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Ochtendmedicatie toegediend: Sertraline 50mg. Patiënt heeft goed ingenomen.',
practitioner_sarah_id,
vandaag + TIME '08:15:00',
vandaag,
false,
jsonb_build_object('category', 'medicatie')
) ON CONFLICT DO NOTHING;
-- OCHTEND (10:00) - Jan - Gedragsobservatie (belangrijk!)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt geagiteerd en gespannen. Heeft meerdere keren om geruststelling gevraagd. Gesprek gevoerd, maar blijft piekeren over gezondheid. Ademhalingsoefening gedaan.',
practitioner_sarah_id,
vandaag + TIME '10:00:00',
vandaag,
true, -- Belangrijk voor overdracht
jsonb_build_object('category', 'gedrag')
) ON CONFLICT DO NOTHING;
-- OCHTEND (11:00) - Optimus - Observatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt werkt geconcentreerd aan zijn cognitieve oefeningen. Sociaal contact beperkt, maar dit lijkt karakteristiek voor hem.',
practitioner_sarah_id,
vandaag + TIME '11:00:00',
vandaag,
false,
jsonb_build_object('category', 'observatie')
) ON CONFLICT DO NOTHING;
-- MIDDAG (13:30) - Jan - Medicatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Middagmedicatie toegediend: Oxazepam 10mg (SOS, ivm toegenomen angst). Effect na 30 min: patiënt rustiger.',
practitioner_mark_id,
vandaag + TIME '13:30:00',
vandaag,
true, -- SOS medicatie is belangrijk
jsonb_build_object('category', 'medicatie')
) ON CONFLICT DO NOTHING;
-- MIDDAG (14:00) - Colin - Gedragsobservatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Patiënt heeft deelgenomen aan groepstherapie. Gaf aan zich vandaag moe te voelen. Heeft zich teruggetrokken op kamer na de sessie.',
practitioner_mark_id,
vandaag + TIME '14:00:00',
vandaag,
false,
jsonb_build_object('category', 'gedrag')
) ON CONFLICT DO NOTHING;
-- MIDDAG (15:00) - Optimus - ADL
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt neemt zelfstandig maaltijden. Blijft voorkeur houden voor vaste routine en structuur.',
practitioner_mark_id,
vandaag + TIME '15:00:00',
vandaag,
false,
jsonb_build_object('category', 'adl')
) ON CONFLICT DO NOTHING;
-- AVOND (18:30) - Colin - Medicatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Avondmedicatie toegediend: Sertraline 50mg, Melatonine 3mg. Goed ingenomen.',
practitioner_lisa_id,
vandaag + TIME '18:30:00',
vandaag,
false,
jsonb_build_object('category', 'medicatie')
) ON CONFLICT DO NOTHING;
-- AVOND (19:45) - Jan - Observatie (belangrijk!)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Na avondeten gesprek met partner (Emma) via telefoon. Gesprek verliep goed. Patiënt minder gespannen daarna. Belangrijk: oefent met minder vaak bellen om geruststelling.',
practitioner_lisa_id,
vandaag + TIME '19:45:00',
vandaag,
true, -- Positieve ontwikkeling
jsonb_build_object('category', 'observatie')
) ON CONFLICT DO NOTHING;
-- ============================================================================
-- GISTEREN - Volledige dag voor context
-- ============================================================================
-- OCHTEND (08:00) - Colin - ADL (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Patiënt wakker om 07:00. Gedoucht en aangekleed zonder problemen. Ontbijt goed gegeten.',
practitioner_sarah_id,
gisteren + TIME '08:00:00',
gisteren,
false,
jsonb_build_object('category', 'adl')
) ON CONFLICT DO NOTHING;
-- OCHTEND (09:00) - Colin - Medicatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Ochtendmedicatie: Sertraline 50mg toegediend en ingenomen.',
practitioner_sarah_id,
gisteren + TIME '09:00:00',
gisteren,
false,
jsonb_build_object('category', 'medicatie')
) ON CONFLICT DO NOTHING;
-- MIDDAG (13:00) - Jan - Incident (belangrijk!)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt in paniek ivm vermeende hartkloppingen. Vitale functies gecontroleerd (bloeddruk, hartslag normaal). Arts geïnformeerd. Na gesprek en ademhalingsoefeningen gekalmeerd.',
practitioner_mark_id,
gisteren + TIME '13:00:00',
gisteren,
true,
jsonb_build_object('category', 'incident')
) ON CONFLICT DO NOTHING;
-- MIDDAG (14:30) - Colin - Gedragsobservatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Therapiesessie met psycholoog. Patiënt gaf na afloop aan zich begrepen te voelen. Stemming leek opgewekt.',
practitioner_mark_id,
gisteren + TIME '14:30:00',
gisteren,
false,
jsonb_build_object('category', 'gedrag')
) ON CONFLICT DO NOTHING;
-- AVOND (20:00) - Jan - Medicatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Avondmedicatie: Paroxetine 20mg, Melatonine 3mg toegediend.',
practitioner_lisa_id,
gisteren + TIME '20:00:00',
gisteren,
false,
jsonb_build_object('category', 'medicatie')
) ON CONFLICT DO NOTHING;
-- AVOND (21:30) - Optimus - Observatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt leest op kamer. Geeft aan niet moe te zijn. Gaat naar bed rond 23:00 (vaste routine).',
practitioner_lisa_id,
gisteren + TIME '21:30:00',
gisteren,
false,
jsonb_build_object('category', 'observatie')
) ON CONFLICT DO NOTHING;
-- ============================================================================
-- EERGISTEREN - Enkele belangrijke rapportages voor geschiedenis
-- ============================================================================
-- OCHTEND (10:00) - Colin - Gedragsobservatie (eergisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Intake gesprek met familie. Moeder op bezoek. Goed contact. Patiënt emotioneel maar opgelucht na gesprek.',
practitioner_sarah_id,
eergisteren + TIME '10:00:00',
eergisteren,
true, -- Belangrijk: familiecontact
jsonb_build_object('category', 'gedrag')
) ON CONFLICT DO NOTHING;
-- MIDDAG (14:00) - Jan - Gedragsobservatie (eergisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Mindfulness groep. Patiënt heeft moeite met stilzitten en concentratie. Blijft piekeren. Individuele nabespreking gehad.',
practitioner_mark_id,
eergisteren + TIME '14:00:00',
eergisteren,
false,
jsonb_build_object('category', 'gedrag')
) ON CONFLICT DO NOTHING;
-- AVOND (19:00) - Optimus - ADL (eergisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt heeft zelfstandig avondmaaltijd gebruikt. Keurig opgeruimd. Houdt zich goed aan afdelingregels.',
practitioner_lisa_id,
eergisteren + TIME '19:00:00',
eergisteren,
false,
jsonb_build_object('category', 'adl')
) ON CONFLICT DO NOTHING;
-- ============================================================================
-- Extra rapportages voor diversiteit - 3 dagen geleden
-- ============================================================================
-- Medicatie wijziging (belangrijk voor overdracht)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_colin_id, 'verpleegkundig',
'Medicatie aangepast door psychiater: Sertraline verhoogd van 25mg naar 50mg. Start vandaag. Extra observatie op bijwerkingen.',
practitioner_sarah_id,
CURRENT_DATE - INTERVAL '3 days' + TIME '10:00:00',
CURRENT_DATE - INTERVAL '3 days',
true, -- Medicatiewijziging is altijd belangrijk
jsonb_build_object('category', 'medicatie')
) ON CONFLICT DO NOTHING;
-- Incident met goede afloop
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt wilde afdeling verlaten tijdens piekmoment. Gesprek gevoerd over contractafspraken. Patiënt kon uiteindelijk zelf kalmeren en bleef. Geen dwangmiddelen nodig.',
practitioner_mark_id,
CURRENT_DATE - INTERVAL '3 days' + TIME '15:30:00',
CURRENT_DATE - INTERVAL '3 days',
true,
jsonb_build_object('category', 'incident')
) ON CONFLICT DO NOTHING;
RAISE NOTICE '✓ Seeded verpleegkundige overdracht rapportages';
RAISE NOTICE ' - Colin Lit: % rapportages', (SELECT COUNT(*) FROM reports WHERE patient_id = patient_colin_id AND type = 'verpleegkundig');
RAISE NOTICE ' - Jan de Vriesh: % rapportages', (SELECT COUNT(*) FROM reports WHERE patient_id = patient_jan_id AND type = 'verpleegkundig');
RAISE NOTICE ' - Optimus Prime: % rapportages', (SELECT COUNT(*) FROM reports WHERE patient_id = patient_optimus_id AND type = 'verpleegkundig');
RAISE NOTICE ' - Overdracht items: %', (SELECT COUNT(*) FROM reports WHERE type = 'verpleegkundig' AND include_in_handover = true);
END $$;
-- ============================================================================
-- VERIFICATION
-- ============================================================================
DO $$
DECLARE
verpleegkundig_count INTEGER;
overdracht_count INTEGER;
categories_count INTEGER;
BEGIN
SELECT COUNT(*) INTO verpleegkundig_count
FROM reports
WHERE type = 'verpleegkundig' AND deleted_at IS NULL;
SELECT COUNT(*) INTO overdracht_count
FROM reports
WHERE type = 'verpleegkundig' AND include_in_handover = true AND deleted_at IS NULL;
SELECT COUNT(DISTINCT structured_data->>'category') INTO categories_count
FROM reports
WHERE type = 'verpleegkundig' AND deleted_at IS NULL;
RAISE NOTICE '=== VERPLEEGKUNDIGE OVERDRACHT SEED SUMMARY ===';
RAISE NOTICE 'Totaal verpleegkundige rapportages: %', verpleegkundig_count;
RAISE NOTICE 'Overdracht items (include_in_handover=true): %', overdracht_count;
RAISE NOTICE 'Verschillende categorieën: %', categories_count;
IF verpleegkundig_count >= 20 THEN
RAISE NOTICE '✓ Verpleegkundige overdracht data succesvol ingevoerd!';
ELSE
RAISE WARNING '⚠ Mogelijk niet alle data ingevoerd';
END IF;
END $$;
-- ============================================================================
-- SUMMARY
-- ============================================================================
-- ✓ Realistische verpleegkundige rapportages over 4 dagen
-- ✓ Alle categorieën vertegenwoordigd:
-- - medicatie (medicatie toediening, wijzigingen)
-- - adl (douchen, eten, zelfverzorging)
-- - gedrag (observaties, groepstherapie, gesprekken)
-- - incident (paniek, conflict, crises)
-- - observatie (algemene observaties)
-- ✓ Verschillende tijdstippen (nacht, ochtend, middag, avond)
-- ✓ Include_in_handover flags voor belangrijke items
-- ✓ Shift_date correct berekend (nachtdienst voor 07:00 = vorige dag)
--
-- GEBRUIK:
-- - Verpleegkundige overdracht module (/epd/verpleegrapportage)
-- - Timeline visualisatie per dagdeel
-- - AI samenvatting generatie
-- - Handover filtering (include_in_handover=true)
-- ============================================================================

View File

@@ -0,0 +1,402 @@
-- ============================================================================
-- SEED VERPLEEGKUNDIGE OVERDRACHT DATA (Aangepaste versie)
-- ============================================================================
-- Created: 2024-12-27
-- Purpose: Populate reports table with realistic nursing handover data
-- Works with existing patients in your database
-- ============================================================================
DO $$
DECLARE
-- Use existing patients from your database
patient_piet_id UUID := '2abadccb-7c29-4ea4-94b1-538a3927824c'::uuid; -- Piet Janssen
patient_jan_id UUID := 'd16935c9-e0fe-4972-832f-175b7a38f9b9'::uuid; -- Jan de Vriesh
patient_optimus_id UUID := 'a94ac0ce-ff90-404b-ac62-592db93df76e'::uuid; -- Optimus Prime
-- Practitioners (assuming these exist from your setup)
practitioner_sarah_id UUID := '10000000-0000-0000-0000-000000000001'::uuid;
practitioner_mark_id UUID := '10000000-0000-0000-0000-000000000002'::uuid;
practitioner_lisa_id UUID := '10000000-0000-0000-0000-000000000003'::uuid;
-- Datums voor realistische tijdlijn
vandaag DATE := CURRENT_DATE;
gisteren DATE := CURRENT_DATE - INTERVAL '1 day';
eergisteren DATE := CURRENT_DATE - INTERVAL '2 days';
BEGIN
-- ============================================================================
-- VANDAAG - Diverse rapportages gedurende de dag
-- ============================================================================
-- NACHT (02:00) - Piet - Observatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Patiënt slaapt rustig. Geen bijzonderheden.',
practitioner_lisa_id,
vandaag + TIME '02:00:00',
gisteren, -- Nachtdienst hoort bij vorige dag
false,
jsonb_build_object('category', 'observatie')
);
-- OCHTEND (07:30) - Piet - ADL
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Patiënt zelfstandig gedoucht en aangekleed. Heeft ontbijt genuttigd (brood, yoghurt). Stemming lijkt iets somberder dan gisteren.',
practitioner_sarah_id,
vandaag + TIME '07:30:00',
vandaag,
true, -- Belangrijk voor overdracht: stemming somberder
jsonb_build_object('category', 'adl')
);
-- OCHTEND (08:15) - Piet - Medicatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Ochtendmedicatie toegediend: Sertraline 50mg. Patiënt heeft goed ingenomen.',
practitioner_sarah_id,
vandaag + TIME '08:15:00',
vandaag,
false,
jsonb_build_object('category', 'medicatie')
);
-- OCHTEND (10:00) - Jan - Gedragsobservatie (belangrijk!)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt geagiteerd en gespannen. Heeft meerdere keren om geruststelling gevraagd. Gesprek gevoerd, maar blijft piekeren over gezondheid. Ademhalingsoefening gedaan.',
practitioner_sarah_id,
vandaag + TIME '10:00:00',
vandaag,
true, -- Belangrijk voor overdracht
jsonb_build_object('category', 'gedrag')
);
-- OCHTEND (11:00) - Optimus - Observatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt werkt geconcentreerd aan zijn cognitieve oefeningen. Sociaal contact beperkt, maar dit lijkt karakteristiek voor hem.',
practitioner_sarah_id,
vandaag + TIME '11:00:00',
vandaag,
false,
jsonb_build_object('category', 'observatie')
);
-- MIDDAG (13:30) - Jan - Medicatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Middagmedicatie toegediend: Oxazepam 10mg (SOS, ivm toegenomen angst). Effect na 30 min: patiënt rustiger.',
practitioner_mark_id,
vandaag + TIME '13:30:00',
vandaag,
true, -- SOS medicatie is belangrijk
jsonb_build_object('category', 'medicatie')
);
-- MIDDAG (14:00) - Piet - Gedragsobservatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Patiënt heeft deelgenomen aan groepstherapie. Gaf aan zich vandaag moe te voelen. Heeft zich teruggetrokken op kamer na de sessie.',
practitioner_mark_id,
vandaag + TIME '14:00:00',
vandaag,
false,
jsonb_build_object('category', 'gedrag')
);
-- MIDDAG (15:00) - Optimus - ADL
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt neemt zelfstandig maaltijden. Blijft voorkeur houden voor vaste routine en structuur.',
practitioner_mark_id,
vandaag + TIME '15:00:00',
vandaag,
false,
jsonb_build_object('category', 'adl')
);
-- AVOND (18:30) - Piet - Medicatie
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Avondmedicatie toegediend: Sertraline 50mg, Melatonine 3mg. Goed ingenomen.',
practitioner_lisa_id,
vandaag + TIME '18:30:00',
vandaag,
false,
jsonb_build_object('category', 'medicatie')
);
-- AVOND (19:45) - Jan - Observatie (belangrijk!)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Na avondeten gesprek met partner (Emma) via telefoon. Gesprek verliep goed. Patiënt minder gespannen daarna. Belangrijk: oefent met minder vaak bellen om geruststelling.',
practitioner_lisa_id,
vandaag + TIME '19:45:00',
vandaag,
true, -- Positieve ontwikkeling
jsonb_build_object('category', 'observatie')
);
-- ============================================================================
-- GISTEREN - Volledige dag voor context
-- ============================================================================
-- OCHTEND (08:00) - Piet - ADL (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Patiënt wakker om 07:00. Gedoucht en aangekleed zonder problemen. Ontbijt goed gegeten.',
practitioner_sarah_id,
gisteren + TIME '08:00:00',
gisteren,
false,
jsonb_build_object('category', 'adl')
);
-- OCHTEND (09:00) - Piet - Medicatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Ochtendmedicatie: Sertraline 50mg toegediend en ingenomen.',
practitioner_sarah_id,
gisteren + TIME '09:00:00',
gisteren,
false,
jsonb_build_object('category', 'medicatie')
);
-- MIDDAG (13:00) - Jan - Incident (belangrijk!)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt in paniek ivm vermeende hartkloppingen. Vitale functies gecontroleerd (bloeddruk, hartslag normaal). Arts geïnformeerd. Na gesprek en ademhalingsoefeningen gekalmeerd.',
practitioner_mark_id,
gisteren + TIME '13:00:00',
gisteren,
true,
jsonb_build_object('category', 'incident')
);
-- MIDDAG (14:30) - Piet - Gedragsobservatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Therapiesessie met psycholoog. Patiënt gaf na afloop aan zich begrepen te voelen. Stemming leek opgewekt.',
practitioner_mark_id,
gisteren + TIME '14:30:00',
gisteren,
false,
jsonb_build_object('category', 'gedrag')
);
-- AVOND (20:00) - Jan - Medicatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Avondmedicatie: Paroxetine 20mg, Melatonine 3mg toegediend.',
practitioner_lisa_id,
gisteren + TIME '20:00:00',
gisteren,
false,
jsonb_build_object('category', 'medicatie')
);
-- AVOND (21:30) - Optimus - Observatie (gisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt leest op kamer. Geeft aan niet moe te zijn. Gaat naar bed rond 23:00 (vaste routine).',
practitioner_lisa_id,
gisteren + TIME '21:30:00',
gisteren,
false,
jsonb_build_object('category', 'observatie')
);
-- ============================================================================
-- EERGISTEREN - Enkele belangrijke rapportages voor geschiedenis
-- ============================================================================
-- OCHTEND (10:00) - Piet - Gedragsobservatie (eergisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Intake gesprek met familie. Moeder op bezoek. Goed contact. Patiënt emotioneel maar opgelucht na gesprek.',
practitioner_sarah_id,
eergisteren + TIME '10:00:00',
eergisteren,
true, -- Belangrijk: familiecontact
jsonb_build_object('category', 'gedrag')
);
-- MIDDAG (14:00) - Jan - Gedragsobservatie (eergisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Mindfulness groep. Patiënt heeft moeite met stilzitten en concentratie. Blijft piekeren. Individuele nabespreking gehad.',
practitioner_mark_id,
eergisteren + TIME '14:00:00',
eergisteren,
false,
jsonb_build_object('category', 'gedrag')
);
-- AVOND (19:00) - Optimus - ADL (eergisteren)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Patiënt heeft zelfstandig avondmaaltijd gebruikt. Keurig opgeruimd. Houdt zich goed aan afdelingregels.',
practitioner_lisa_id,
eergisteren + TIME '19:00:00',
eergisteren,
false,
jsonb_build_object('category', 'adl')
);
-- ============================================================================
-- Extra rapportages voor diversiteit - 3 dagen geleden
-- ============================================================================
-- Medicatie wijziging (belangrijk voor overdracht)
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Medicatie aangepast door psychiater: Sertraline verhoogd van 25mg naar 50mg. Start vandaag. Extra observatie op bijwerkingen.',
practitioner_sarah_id,
CURRENT_DATE - INTERVAL '3 days' + TIME '10:00:00',
CURRENT_DATE - INTERVAL '3 days',
true, -- Medicatiewijziging is altijd belangrijk
jsonb_build_object('category', 'medicatie')
);
-- Incident met goede afloop
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt wilde afdeling verlaten tijdens piekmoment. Gesprek gevoerd over contractafspraken. Patiënt kon uiteindelijk zelf kalmeren en bleef. Geen dwangmiddelen nodig.',
practitioner_mark_id,
CURRENT_DATE - INTERVAL '3 days' + TIME '15:30:00',
CURRENT_DATE - INTERVAL '3 days',
true,
jsonb_build_object('category', 'incident')
);
-- Extra rapportages voor meer volume
-- VANDAAG - Extra observaties
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_piet_id, 'verpleegkundig',
'Patiënt wandelt buiten met medepatiënt. Ziet er ontspannen uit.',
practitioner_mark_id,
vandaag + TIME '16:00:00',
vandaag,
false,
jsonb_build_object('category', 'observatie')
);
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_jan_id, 'verpleegkundig',
'Patiënt heeft deelgenomen aan creatieve therapie. Maakte schilderij. Leek meer ontspannen tijdens activiteit.',
practitioner_mark_id,
vandaag + TIME '16:30:00',
vandaag,
false,
jsonb_build_object('category', 'gedrag')
);
INSERT INTO reports (
patient_id, type, content, created_by, created_at, shift_date,
include_in_handover, structured_data
) VALUES (
patient_optimus_id, 'verpleegkundig',
'Avondmedicatie: Melatonine 3mg ingenomen.',
practitioner_lisa_id,
vandaag + TIME '21:00:00',
vandaag,
false,
jsonb_build_object('category', 'medicatie')
);
RAISE NOTICE '✓ Verpleegkundige overdracht rapportages toegevoegd';
END $$;
-- ============================================================================
-- VERIFICATION
-- ============================================================================
DO $$
DECLARE
verpleegkundig_count INTEGER;
overdracht_count INTEGER;
BEGIN
SELECT COUNT(*) INTO verpleegkundig_count
FROM reports
WHERE type = 'verpleegkundig' AND deleted_at IS NULL;
SELECT COUNT(*) INTO overdracht_count
FROM reports
WHERE type = 'verpleegkundig' AND include_in_handover = true AND deleted_at IS NULL;
RAISE NOTICE '=== VERPLEEGKUNDIGE OVERDRACHT SEED SUMMARY ===';
RAISE NOTICE 'Totaal verpleegkundige rapportages: %', verpleegkundig_count;
RAISE NOTICE 'Overdracht items (belangrijk): %', overdracht_count;
RAISE NOTICE '✓ Data succesvol ingevoerd!';
END $$;