redesigdn docs
This commit is contained in:
@@ -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
|
||||
|
||||
1069
docs/swift/bouwplan-swift-v3.md
Normal file
1069
docs/swift/bouwplan-swift-v3.md
Normal file
File diff suppressed because it is too large
Load Diff
742
docs/swift/fo-swift-medical-scribe-v3.md
Normal file
742
docs/swift/fo-swift-medical-scribe-v3.md
Normal 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 |
|
||||
437
docs/swift/haalbaarheidsanalyse-v3.md
Normal file
437
docs/swift/haalbaarheidsanalyse-v3.md
Normal 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**
|
||||
|
||||
666
docs/swift/v3-redesign-met-huidige-styling.md
Normal file
666
docs/swift/v3-redesign-met-huidige-styling.md
Normal 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
11
mcp.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?project_ref=dqugbrpwtisgyxscpefg",
|
||||
"headers": {
|
||||
"Authorization": "Bearer sbp_6598641b9c7afc57968d9a362088f506e9f3e20b"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
supabase/check-patients.sql
Normal file
10
supabase/check-patients.sql
Normal 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;
|
||||
@@ -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)
|
||||
-- ============================================================================
|
||||
@@ -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 $$;
|
||||
Reference in New Issue
Block a user