diff --git a/components/swift/blocks/dagnotitie-block.tsx b/components/swift/blocks/dagnotitie-block.tsx
index b88cb4c..cea91ba 100644
--- a/components/swift/blocks/dagnotitie-block.tsx
+++ b/components/swift/blocks/dagnotitie-block.tsx
@@ -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
diff --git a/docs/swift/PROJECT-STATUS-2024-12-27.md b/docs/swift/archive/PROJECT-STATUS-2024-12-27.md
similarity index 100%
rename from docs/swift/PROJECT-STATUS-2024-12-27.md
rename to docs/swift/archive/PROJECT-STATUS-2024-12-27.md
diff --git a/docs/swift/keyboard-shortcuts-reference.md b/docs/swift/archive/keyboard-shortcuts-reference.md
similarity index 100%
rename from docs/swift/keyboard-shortcuts-reference.md
rename to docs/swift/archive/keyboard-shortcuts-reference.md
diff --git a/docs/swift/nextgen-epd-analyse-ephemeral-ui-perspectieven.md b/docs/swift/archive/nextgen-epd-analyse-ephemeral-ui-perspectieven.md
similarity index 100%
rename from docs/swift/nextgen-epd-analyse-ephemeral-ui-perspectieven.md
rename to docs/swift/archive/nextgen-epd-analyse-ephemeral-ui-perspectieven.md
diff --git a/docs/swift/nextgen-epd-claude-vision-epd.txt b/docs/swift/archive/nextgen-epd-claude-vision-epd.txt
similarity index 100%
rename from docs/swift/nextgen-epd-claude-vision-epd.txt
rename to docs/swift/archive/nextgen-epd-claude-vision-epd.txt
diff --git a/docs/swift/nextgen-epd-mvp-prioritering-ephemeral-ui.md b/docs/swift/archive/nextgen-epd-mvp-prioritering-ephemeral-ui.md
similarity index 100%
rename from docs/swift/nextgen-epd-mvp-prioritering-ephemeral-ui.md
rename to docs/swift/archive/nextgen-epd-mvp-prioritering-ephemeral-ui.md
diff --git a/docs/swift/nextgen-epd-onderzoeksverslag-ux-ui-patterns.md b/docs/swift/archive/nextgen-epd-onderzoeksverslag-ux-ui-patterns.md
similarity index 100%
rename from docs/swift/nextgen-epd-onderzoeksverslag-ux-ui-patterns.md
rename to docs/swift/archive/nextgen-epd-onderzoeksverslag-ux-ui-patterns.md
diff --git a/docs/swift/nextgen-epd-prd-ephemeral-ui-epd.md b/docs/swift/archive/nextgen-epd-prd-ephemeral-ui-epd.md
similarity index 100%
rename from docs/swift/nextgen-epd-prd-ephemeral-ui-epd.md
rename to docs/swift/archive/nextgen-epd-prd-ephemeral-ui-epd.md
diff --git a/docs/swift/nextgen-epd-waarde-analyse-ephemeral-ui.md b/docs/swift/archive/nextgen-epd-waarde-analyse-ephemeral-ui.md
similarity index 100%
rename from docs/swift/nextgen-epd-waarde-analyse-ephemeral-ui.md
rename to docs/swift/archive/nextgen-epd-waarde-analyse-ephemeral-ui.md
diff --git a/docs/swift/swift-fo-ai.md b/docs/swift/archive/swift-fo-ai.md
similarity index 100%
rename from docs/swift/swift-fo-ai.md
rename to docs/swift/archive/swift-fo-ai.md
diff --git a/docs/swift/swift-fo-diagnostiek-workflow.md b/docs/swift/archive/swift-fo-diagnostiek-workflow.md
similarity index 100%
rename from docs/swift/swift-fo-diagnostiek-workflow.md
rename to docs/swift/archive/swift-fo-diagnostiek-workflow.md
diff --git a/docs/swift/swift-prd.md b/docs/swift/archive/swift-prd.md
similarity index 100%
rename from docs/swift/swift-prd.md
rename to docs/swift/archive/swift-prd.md
diff --git a/docs/swift/swift-ux-diagnostiek-workflow.md b/docs/swift/archive/swift-ux-diagnostiek-workflow.md
similarity index 100%
rename from docs/swift/swift-ux-diagnostiek-workflow.md
rename to docs/swift/archive/swift-ux-diagnostiek-workflow.md
diff --git a/docs/swift/swift-ux-v2.1.md b/docs/swift/archive/swift-ux-v2.1.md
similarity index 100%
rename from docs/swift/swift-ux-v2.1.md
rename to docs/swift/archive/swift-ux-v2.1.md
diff --git a/docs/swift/taken-en-vragen-analyse.md b/docs/swift/archive/taken-en-vragen-analyse.md
similarity index 100%
rename from docs/swift/taken-en-vragen-analyse.md
rename to docs/swift/archive/taken-en-vragen-analyse.md
diff --git a/docs/swift/test-plan-e5-s2-error-handling.md b/docs/swift/archive/test-plan-e5-s2-error-handling.md
similarity index 100%
rename from docs/swift/test-plan-e5-s2-error-handling.md
rename to docs/swift/archive/test-plan-e5-s2-error-handling.md
diff --git a/docs/swift/test-plan-e5-s3-keyboard-shortcuts.md b/docs/swift/archive/test-plan-e5-s3-keyboard-shortcuts.md
similarity index 100%
rename from docs/swift/test-plan-e5-s3-keyboard-shortcuts.md
rename to docs/swift/archive/test-plan-e5-s3-keyboard-shortcuts.md
diff --git a/docs/swift/test-plan-epic3.md b/docs/swift/archive/test-plan-epic3.md
similarity index 100%
rename from docs/swift/test-plan-epic3.md
rename to docs/swift/archive/test-plan-epic3.md
diff --git a/docs/swift/to-swift-v1.md b/docs/swift/archive/to-swift-v1.md
similarity index 100%
rename from docs/swift/to-swift-v1.md
rename to docs/swift/archive/to-swift-v1.md
diff --git a/docs/swift/bouwplan-swift-v3.md b/docs/swift/bouwplan-swift-v3.md
new file mode 100644
index 0000000..455011d
--- /dev/null
+++ b/docs/swift/bouwplan-swift-v3.md
@@ -0,0 +1,1069 @@
+# π Mission Control β Bouwplan Swift v3.0
+
+π‘ **Transformatie:** Van Command Center naar Medical Scribe Chatbot Interface
+
+---
+
+**Projectnaam:** Swift Medical Scribe v3.0
+**Versie:** v3.0
+**Datum:** 27-12-2024
+**Auteur:** Colin Lit
+
+---
+
+## 1. Doel en context
+
+π― **Doel:** Swift transformeren van een command-line style interface naar een conversational medical scribe chatbot met split-screen layout (chat links, artifacts rechts).
+
+π **Context:**
+De huidige Swift v2.1 werkt met een command-line paradigma waar gebruikers kort commando's typen ("notitie jan medicatie"). Dit werkt goed, maar voelt transactioneel aan. Gebruikers willen doorvragen, context behouden, en natuurlijker interacteren met het systeem.
+
+**De transformatie:**
+- **Van:** Command-line input β Centered blocks β Recent strip
+- **Naar:** Chat conversation β Split-screen (40/60) β Artifacts rechts
+
+**Waarom deze verandering:**
+1. **Natuurlijkere interactie** β Voelt als praten met collega i.p.v. commando's typen
+2. **Context behoud** β Conversatiegeschiedenis blijft zichtbaar
+3. **Follow-up mogelijk** β Gebruiker kan doorvragen zonder opnieuw te beginnen
+4. **Bekende UX** β Lijkt op ChatGPT Canvas / Claude Artifacts (bekend voor gebruikers)
+
+**Referenties:**
+- **FO v3.0:** `fo-swift-medical-scribe-v3.md` β Functioneel ontwerp medical scribe
+- **Haalbaarheid:** `haalbaarheidsanalyse-v3.md` β Feasibility analysis (6-8 weken, haalbaar)
+- **UX Analyse:** `v3-redesign-met-huidige-styling.md` β Wat blijft vs. wijzigt
+- **UX v2.1:** `archive/swift-ux-v2.1.md` β Huidige UX/styling
+
+---
+
+## 2. Uitgangspunten
+
+### 2.1 Technische Stack
+
+**Frontend:**
+- Next.js 14 (App Router) β
Bestaand
+- React 18 met TypeScript β
Bestaand
+- Tailwind CSS + shadcn/ui β
Bestaand
+- Lucide Icons β
Bestaand
+- Zustand (state management) β
Bestaand
+
+**Backend & Database:**
+- Supabase (PostgreSQL + Auth) β
Bestaand
+- FHIR-inspired datamodel β
Bestaand
+- Row Level Security (RLS) β
Bestaand
+
+**AI/ML Services:**
+- Anthropic Claude API (Sonnet 4.5) β
Bestaand
+- Deepgram (speech-to-text) β
Bestaand
+- Streaming API responses (SSE) π Nieuw patroon voor chat
+
+**Hosting & Deploy:**
+- Vercel (production deployment) β
Bestaand
+- Environment variables via `.env.local` β
Bestaand
+
+**Nieuwe Dependencies:**
+- Geen nieuwe externe libraries nodig
+- Hergebruik van bestaande `/api/docs/chat` streaming pattern
+
+### 2.2 Projectkaders
+
+**Tijd:**
+- **Totaal:** 6-8 weken bouwtijd
+- **Fase 1 (Foundation):** Week 1-2
+- **Fase 2 (Chat API):** Week 3-4
+- **Fase 3 (Artifacts & Polish):** Week 5-6
+- **Fase 4 (Testing):** Week 7-8
+
+**Team:**
+- 1 developer (full-time)
+- AI assistant (Claude Code) voor development support
+
+**Scope:**
+- **In scope:** Alle P1 intents (dagnotitie, zoeken, overdracht, patient context)
+- **Out of scope:** P2/P3 intents blijven werken maar geen redesign
+- **Feature flag:** v3.0 achter feature flag zodat v2.1 beschikbaar blijft
+
+**Data:**
+- Alle bestaande Supabase data blijft werken
+- Geen database migraties nodig
+- Alleen nieuwe API endpoints + frontend components
+
+**Risicomanagement:**
+- Incremental rollout via feature flag
+- v2.1 blijft beschikbaar als fallback
+- A/B testing mogelijk voor user feedback
+
+### 2.3 Programmeer Uitgangspunten
+
+**Code Quality Principles:**
+
+- **DRY (Don't Repeat Yourself)**
+ - Herbruikbare chat components (`ChatMessage`, `ChatBubble`)
+ - Centrale config voor message types
+ - Shared utilities voor streaming responses
+
+- **KISS (Keep It Simple, Stupid)**
+ - Geen overengineering van chat state
+ - Eenvoudige Zustand store uitbreiding
+ - Geen nieuwe frameworks/libraries indien niet nodig
+
+- **SOC (Separation of Concerns)**
+ - Chat UI gescheiden van artifact logic
+ - Message rendering gescheiden van streaming logic
+ - API calls in dedicated `/lib/swift/chat-api.ts`
+
+- **YAGNI (You Aren't Gonna Need It)**
+ - Bouw alleen conversation features die in FO staan
+ - Geen "nice to have" features (bijv. message editing, reactions)
+ - Start met max 3 artifacts, niet meer
+
+**Development Practices:**
+
+- **Code Organization**
+ ```
+ components/swift/
+ βββ chat/ # π Nieuwe chat components
+ β βββ chat-panel.tsx
+ β βββ chat-message.tsx
+ β βββ chat-input.tsx
+ β βββ streaming-indicator.tsx
+ βββ artifacts/ # π Nieuwe artifact wrapper
+ β βββ artifact-container.tsx
+ β βββ artifact-tab.tsx
+ βββ blocks/ # β
Bestaand, blijft werken
+ β βββ dagnotitie-block.tsx
+ β βββ zoeken-block.tsx
+ β βββ overdracht-block.tsx
+ βββ command-center/ # π Wijzigt naar split-screen
+ βββ command-center.tsx
+ βββ context-bar.tsx # β
Blijft ongewijzigd
+ βββ offline-banner.tsx # β
Blijft ongewijzigd
+ ```
+
+- **Error Handling**
+ - Hergebruik bestaande `lib/swift/error-handler.ts`
+ - Chat-specific error states (connection lost, stream interrupted)
+ - User-friendly foutmeldingen in chat ("Er ging iets mis, probeer opnieuw")
+
+- **Security**
+ - API keys blijven server-side (Claude API key)
+ - Chat messages niet persistent opgeslagen (alleen in session state)
+ - RLS rules blijven gelden voor artifacts
+
+- **Performance**
+ - Virtual scrolling voor lange chat histories (>100 messages)
+ - Debounce op typing indicator (300ms)
+ - Lazy load artifacts (alleen renderen wanneer actief)
+ - Streaming responses via SSE (Server-Sent Events)
+
+- **Testing**
+ - Manual smoke tests voor alle chat flows
+ - Integration tests voor `/api/swift/chat` endpoint
+ - Edge case testing (stream interruption, long messages, etc.)
+
+**Voorbeeld implementatie:**
+```typescript
+// β
DRY - Herbruikbare message component
+interface ChatMessageProps {
+ type: 'user' | 'assistant' | 'system' | 'error';
+ content: string;
+ timestamp?: Date;
+}
+
+export function ChatMessage({ type, content, timestamp }: ChatMessageProps) {
+ const styles = MESSAGE_STYLES[type]; // Centrale config
+ return (
+
+ {/* ... */}
+
+ );
+}
+
+// β
SOC - API logic gescheiden
+// In /lib/swift/chat-api.ts
+export async function sendChatMessage(
+ message: string,
+ history: ChatMessage[]
+): Promise {
+ const response = await fetch('/api/swift/chat', {
+ method: 'POST',
+ body: JSON.stringify({ message, history }),
+ });
+ return response.body!;
+}
+
+// β
KISS - Simpele state management
+interface ChatState {
+ messages: ChatMessage[];
+ isStreaming: boolean;
+ addMessage: (msg: ChatMessage) => void;
+}
+
+const useChatStore = create((set) => ({
+ messages: [],
+ isStreaming: false,
+ addMessage: (msg) => set((s) => ({
+ messages: [...s.messages, msg]
+ })),
+}));
+```
+
+---
+
+## 3. Epics & Stories Overzicht
+
+π― **Doel:** De bouw opdelen in 6 logische epics met concrete deliverables.
+
+**Epic Structuur:**
+
+| Epic ID | Titel | Doel | Status | Stories | Story Points | Opmerkingen |
+|---------|-------|------|--------|---------|--------------|-------------|
+| E0 | Pre-work & Planning | Design tokens, component audit, system prompt | β³ To Do | 3 | 5 SP | Voorbereiding |
+| E1 | Foundation - Split-screen | Layout naar 40/60 split | β³ To Do | 4 | 13 SP | Week 1-2 |
+| E2 | Chat Panel & Messages | Chat UI zonder AI | β³ To Do | 5 | 13 SP | Week 2-3 |
+| E3 | Chat API & Medical Scribe | AI conversatie werkend | β³ To Do | 6 | 21 SP | Week 3-4 |
+| E4 | Artifact Area & Tabs | Meerdere artifacts mogelijk | β³ To Do | 4 | 13 SP | Week 5 |
+| E5 | AI-Filtering & Polish | Psychiater filtering, polish | β³ To Do | 5 | 13 SP | Week 6 |
+| E6 | Testing & Refinement | QA, bugs, performance | β³ To Do | 4 | 8 SP | Week 7-8 |
+
+**Totaal:** 31 stories, **86 Story Points** (~7 weken Γ 12 SP/week)
+
+**Belangrijk:**
+- β οΈ Voer niet in 1x het volledige plan uit. Bouw per epic en per story.
+- β οΈ Dependencies/migraties moeten eerst aan Colin worden gemeld.
+- Feature flag vanaf E1: `FEATURE_FLAG_SWIFT_V3=true` in `.env.local`
+
+---
+
+## 4. Epics & Stories (Uitwerking)
+
+### Epic 0 β Pre-work & Planning
+
+**Epic Doel:** Voorbereiding werk voordat development start. Design tokens verificatie, component audit, medical scribe system prompt.
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E0.S1 | Design tokens audit | Alle kleuren/spacing/typography gedocumenteerd in v3 doc | β³ | β | 1 |
+| E0.S2 | Component inventory | Lijst van alle blocks die herbruikbaar zijn | β³ | β | 2 |
+| E0.S3 | Medical scribe system prompt | Eerste versie prompt voor `/api/swift/chat`, getest met Claude | β³ | β | 2 |
+
+**Technical Notes:**
+- E0.S1: Check of alle tokens uit v2.1 nog kloppen voor v3.0
+- E0.S2: Maak lijst van blocks die NIET wijzigen vs. die WEL wijzigen
+- E0.S3: Prompt moet Nederlands zijn, vriendelijk maar professioneel, intent detection
+
+**Deliverable:** Planning document met component lijst + prompt v1
+
+---
+
+### Epic 1 β Foundation - Split-screen Layout
+
+**Epic Doel:** CommandCenter omzetten naar split-screen layout (40% chat, 60% artifacts).
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E1.S1 | Feature flag setup | `FEATURE_FLAG_SWIFT_V3` in `.env` + conditional rendering | β³ | E0.S2 | 1 |
+| E1.S2 | CommandCenter layout wijzigen | Split-screen grid (40/60), context bar blijft | β³ | E1.S1 | 5 |
+| E1.S3 | Placeholder componenten | ChatPanel (lege div), ArtifactArea (lege div) | β³ | E1.S2 | 2 |
+| E1.S4 | Responsive breakpoints | Desktop/tablet/mobile toggle tussen chat/artifact | β³ | E1.S3 | 5 |
+
+**Technical Notes:**
+```tsx
+// E1.S2 - Layout structuur
+
+
{/* Blijft ongewijzigd */}
+
+
+ {/* Chat Panel - 40% */}
+
+ {/* Placeholder in E1.S3 */}
+
+
+ {/* Artifact Area - 60% */}
+
+
{/* Placeholder in E1.S3 */}
+
+
+
+```
+
+**Responsive breakpoints (E1.S4):**
+- Desktop (>1200px): 40/60 split zichtbaar
+- Tablet (768-1200px): 45/55 split
+- Mobile (<768px): Toggle tussen chat en artifact (full screen)
+
+**Deliverable:** Split-screen layout zichtbaar, feature flag werkt, v2.1 nog beschikbaar
+
+---
+
+### Epic 2 β Chat Panel & Messages
+
+**Epic Doel:** Chat UI werkend krijgen zonder AI (hardcoded responses voor testing).
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E2.S1 | Store uitbreiding | `chatMessages`, `isStreaming` in swift-store.ts | β³ | E1.S4 | 2 |
+| E2.S2 | ChatMessage component | User/assistant/system/error message types met styling | β³ | E2.S1 | 3 |
+| E2.S3 | ChatPanel component | Scrollable message list, auto-scroll, scroll-lock | β³ | E2.S2 | 5 |
+| E2.S4 | ChatInput component | Tekst input onderaan chat (40% width), enter to send | β³ | E2.S3 | 2 |
+| E2.S5 | Keyboard shortcuts | βK focus, Escape clear, Enter submit | β³ | E2.S4 | 1 |
+
+**Technical Notes:**
+
+**E2.S1 - Store uitbreiding:**
+```typescript
+// stores/swift-store.ts
+interface SwiftStore {
+ // Bestaand
+ activePatient: Patient | null;
+ activeBlock: BlockType | null;
+ shift: ShiftType;
+
+ // Nieuw voor chat
+ chatMessages: ChatMessage[];
+ isStreaming: boolean;
+ pendingAction: Action | null;
+
+ // Actions
+ addChatMessage: (message: ChatMessage) => void;
+ clearChat: () => void;
+ setStreaming: (streaming: boolean) => void;
+}
+```
+
+**E2.S2 - Message styling:**
+```tsx
+// components/swift/chat/chat-message.tsx
+const MESSAGE_STYLES = {
+ user: {
+ container: 'self-end bg-amber-50 border-amber-200',
+ borderRadius: 'rounded-2xl rounded-tr-sm',
+ },
+ assistant: {
+ container: 'self-start bg-slate-100 border-slate-200',
+ borderRadius: 'rounded-2xl rounded-tl-sm',
+ },
+ system: {
+ container: 'self-center bg-transparent text-slate-500 text-sm',
+ borderRadius: '',
+ },
+ error: {
+ container: 'self-start bg-red-50 border-red-200',
+ borderRadius: 'rounded-2xl',
+ },
+};
+```
+
+**E2.S3 - Auto-scroll gedrag:**
+- Auto-scroll naar laatste message bij nieuwe message
+- Scroll-lock wanneer user omhoog scrollt (detecteer scroll position)
+- "β Scroll to bottom" knop verschijnt bij nieuwe messages tijdens scroll-lock
+
+**E2.S4 - Chat input:**
+- Onderaan chat panel (40% width)
+- Multi-line support (Shift+Enter voor new line)
+- Enter submit (tenzij Shift pressed)
+- Placeholder: "Typ of spreek..."
+
+**Deliverable:** Werkende chat UI (zonder AI), gebruiker kan typen en ziet messages verschijnen
+
+---
+
+### Epic 3 β Chat API & Medical Scribe
+
+**Epic Doel:** AI conversatie werkend krijgen met intent detection en artifact opening.
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E3.S1 | Chat API endpoint skeleton | `/api/swift/chat` route met SSE setup | β³ | E2.S5 | 3 |
+| E3.S2 | Streaming response logic | Claude API streaming werkt, chunks naar frontend | β³ | E3.S1 | 5 |
+| E3.S3 | Medical scribe system prompt | Prompt met role, intents, examples, Nederlands | β³ | E3.S2 | 3 |
+| E3.S4 | Intent detection in response | AI genereert action objects (intent + entities) | β³ | E3.S3 | 5 |
+| E3.S5 | Frontend streaming handling | useChatStream hook, message chunks renderen | β³ | E3.S4 | 3 |
+| E3.S6 | Artifact opening from chat | Action object opent juiste block met prefill | β³ | E3.S5 | 2 |
+
+**Technical Notes:**
+
+**E3.S1 - API Route:**
+```typescript
+// app/api/swift/chat/route.ts
+export async function POST(req: Request) {
+ const { message, messages, context } = await req.json();
+
+ // Streaming response
+ const encoder = new TextEncoder();
+ const stream = new ReadableStream({
+ async start(controller) {
+ // Claude API streaming logic
+ },
+ });
+
+ return new Response(stream, {
+ headers: {
+ 'Content-Type': 'text/event-stream',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ },
+ });
+}
+```
+
+**E3.S3 - 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
+
+Wanneer je een intent herkent, voeg een JSON action object toe:
+{
+ "type": "action",
+ "intent": "dagnotitie",
+ "entities": { "patient": "Jan de Vries", "category": "medicatie" },
+ "confidence": 0.95
+}
+
+Context:
+- Actieve patiΓ«nt: {{activePatient}}
+- Dienst: {{shift}}
+- Recente acties: {{recentActions}}
+```
+
+**E3.S4 - Action object format:**
+```typescript
+interface Action {
+ type: 'action';
+ intent: IntentType;
+ entities: {
+ patient?: string;
+ patientId?: string;
+ category?: VerpleegkundigCategory;
+ content?: string;
+ };
+ confidence: number;
+ artifact?: {
+ type: BlockType;
+ prefill: BlockPrefillData;
+ };
+}
+```
+
+**E3.S5 - Frontend streaming:**
+```typescript
+// lib/swift/use-chat-stream.ts
+export function useChatStream() {
+ const addMessage = useSwiftStore((s) => s.addChatMessage);
+ const setStreaming = useSwiftStore((s) => s.setStreaming);
+
+ const sendMessage = async (message: string) => {
+ setStreaming(true);
+ const response = await fetch('/api/swift/chat', {
+ method: 'POST',
+ body: JSON.stringify({ message, messages: /* ... */ }),
+ });
+
+ const reader = response.body!.getReader();
+ let accumulatedText = '';
+
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) break;
+
+ const chunk = new TextDecoder().decode(value);
+ accumulatedText += chunk;
+
+ // Update message in UI
+ addMessage({ type: 'assistant', content: accumulatedText });
+ }
+
+ setStreaming(false);
+ };
+
+ return { sendMessage };
+}
+```
+
+**E3.S6 - Artifact opening:**
+- Parse action object uit AI response
+- Open juiste block via `openBlock(artifact.type, artifact.prefill)`
+- Block verschijnt rechts in artifact area
+
+**Deliverable:** Werkende conversatie met AI, intents worden herkend, blocks openen
+
+---
+
+### Epic 4 β Artifact Area & Tabs
+
+**Epic Doel:** Meerdere artifacts tegelijk mogelijk met tabs, slide-in animaties.
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E4.S1 | ArtifactContainer component | Wrapper met tabs bovenaan, max 3 artifacts | β³ | E3.S6 | 5 |
+| E4.S2 | Artifact lifecycle management | Open/close/switch tussen artifacts in store | β³ | E4.S1 | 3 |
+| E4.S3 | Slide-in animatie | Artifact slide-in van rechts (200ms ease-out) | β³ | E4.S2 | 2 |
+| E4.S4 | Placeholder state | "Artifacts verschijnen hier" met voorbeelden | β³ | E4.S3 | 3 |
+
+**Technical Notes:**
+
+**E4.S1 - ArtifactContainer:**
+```tsx
+// components/swift/artifacts/artifact-container.tsx
+interface Artifact {
+ id: string;
+ type: BlockType;
+ prefill: BlockPrefillData;
+ title: string;
+}
+
+export function ArtifactContainer() {
+ const { openArtifacts, activeArtifactId } = useSwiftStore();
+
+ if (openArtifacts.length === 0) {
+ return ;
+ }
+
+ return (
+
+ {/* Tabs - alleen tonen bij >1 artifact */}
+ {openArtifacts.length > 1 && (
+
+ {openArtifacts.map((artifact) => (
+
+ ))}
+
+ )}
+
+ {/* Active artifact */}
+
+ {renderArtifact(activeArtifact)}
+
+
+ );
+}
+```
+
+**E4.S2 - Store uitbreiding:**
+```typescript
+interface SwiftStore {
+ // ... bestaand
+
+ // Artifact state
+ openArtifacts: Artifact[]; // Max 3
+ activeArtifactId: string | null;
+
+ // Actions
+ openArtifact: (artifact: Artifact) => void;
+ closeArtifact: (id: string) => void;
+ switchArtifact: (id: string) => void;
+}
+
+// Logic: max 3 artifacts, oudste wordt gesloten bij 4e
+const openArtifact = (artifact: Artifact) => {
+ set((state) => {
+ let artifacts = [...state.openArtifacts];
+ if (artifacts.length >= 3) {
+ artifacts = artifacts.slice(1); // Remove oldest
+ }
+ return {
+ openArtifacts: [...artifacts, artifact],
+ activeArtifactId: artifact.id,
+ };
+ });
+};
+```
+
+**E4.S3 - Animatie:**
+```css
+/* globals.css */
+@keyframes artifact-enter {
+ from {
+ transform: translateX(100%);
+ opacity: 0;
+ }
+ to {
+ transform: translateX(0);
+ opacity: 1;
+ }
+}
+
+.artifact-enter {
+ animation: artifact-enter 200ms ease-out;
+}
+```
+
+**E4.S4 - Placeholder:**
+```tsx
+function ArtifactPlaceholder() {
+ return (
+
+
π¬
+
Artifacts verschijnen hier
+
Vraag me iets, bijvoorbeeld:
+
+ - β’ "Notitie voor Jan: medicatie gegeven"
+ - β’ "Zoek Marie van den Berg"
+ - β’ "Maak overdracht voor deze dienst"
+
+
+ );
+}
+```
+
+**Deliverable:** Meerdere artifacts mogelijk, smooth transitions, placeholder state
+
+---
+
+### Epic 5 β AI-Filtering & Polish
+
+**Epic Doel:** AI-filtering voor psychiater overdracht, linked evidence, final polish.
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E5.S1 | AI-filtering psychiater | `/api/overdracht/generate` filtert op behandelrelevantie | β³ | E4.S4 | 5 |
+| E5.S2 | Linked evidence UI | Bronnotitie links in OverdrachtBlock, hover preview | β³ | E5.S1 | 3 |
+| E5.S3 | Voice input integratie | Bestaande Deepgram blijft werken in chat input | β³ | E2.S4 | 2 |
+| E5.S4 | Error states & offline | Chat error messages, offline banner margin fix | β³ | E3.S2 | 2 |
+| E5.S5 | Polish & animations | Smooth transitions, loading states, toast confirmations | β³ | E5.S4 | 1 |
+
+**Technical Notes:**
+
+**E5.S1 - AI-filtering:**
+```typescript
+// app/api/overdracht/generate/route.ts
+// Uitbreiden met filtering parameter
+interface GenerateOverdrachtRequest {
+ shift: ShiftType;
+ filterForRole?: 'psychiater' | 'verpleegkundige';
+}
+
+// AI prompt voor filtering
+const FILTER_PROMPT = `
+Analyseer deze verpleegkundige notities en selecteer ALLEEN behandelrelevante informatie voor de psychiater:
+
+WEL relevant:
+- Medicatie-issues (weigering, bijwerkingen)
+- Stemming/gedrag veranderingen
+- Risico-signalen (suΓ―cidale uitingen, agressie)
+- Psychotische symptomen
+
+NIET relevant:
+- Routine medicatie ("volgens schema")
+- ADL activiteiten ("gedoucht", "ontbijt")
+- Standaard observaties ("rustige dag")
+`;
+```
+
+**E5.S2 - Linked evidence:**
+```tsx
+// components/swift/shared/linked-evidence.tsx
+interface LinkedEvidenceProps {
+ sourceNotes: Report[];
+ highlightedText: string;
+}
+
+export function LinkedEvidence({ sourceNotes, highlightedText }: LinkedEvidenceProps) {
+ return (
+
+
+ {highlightedText}
+
+
+
+ {sourceNotes.map((note) => (
+
+
{note.author} - {note.timestamp}
+
{note.content}
+
+ ))}
+
+
+
+ );
+}
+```
+
+**E5.S3 - Voice input:**
+- Bestaande `use-swift-voice.ts` hook blijft werken
+- Integreren in ChatInput component
+- Mic icon rechts van input field
+- Live transcript verschijnt in input tijdens recording
+
+**E5.S4 - Error states:**
+```tsx
+// Error message types in chat
+const ERROR_MESSAGES = {
+ network: "Er ging iets mis met de verbinding. Probeer het opnieuw.",
+ stream_interrupted: "De verbinding werd onderbroken. Probeer je bericht opnieuw te versturen.",
+ rate_limit: "Even geduld, er zijn te veel aanvragen. Wacht 30 seconden.",
+ unknown: "Er is een fout opgetreden. Probeer het later opnieuw.",
+};
+```
+
+**Deliverable:** AI-filtering werkt, linked evidence klikbaar, voice input geΓ―ntegreerd
+
+---
+
+### Epic 6 β Testing & Refinement
+
+**Epic Doel:** Volledige QA, bug fixes, performance tuning, documentatie.
+
+| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
+|----------|--------------|---------------------|--------|------------------|--------------|
+| E6.S1 | Manual smoke tests | Alle P1 flows werken zonder crashes (checklist) | β³ | E5.S5 | 3 |
+| E6.S2 | Performance optimalisatie | Chat scroll performance, virtual scrolling >100 msgs | β³ | E6.S1 | 3 |
+| E6.S3 | Bug fixes | Alle gemelde bugs opgelost, edge cases getest | β³ | E6.S2 | 1 |
+| E6.S4 | Documentatie update | README, CLAUDE.md, migration guide | β³ | E6.S3 | 1 |
+
+**Technical Notes:**
+
+**E6.S1 - Test checklist:**
+```markdown
+### P1 Flow Tests
+
+**Dagnotitie via conversatie:**
+- [ ] User typt "Ik heb medicatie gegeven aan Jan"
+- [ ] AI herkent intent (dagnotitie) en patient (Jan)
+- [ ] DagnotatieBlock opent met prefill
+- [ ] User kan opslaan β Toast confirmation
+- [ ] Chat toont "β Notitie opgeslagen"
+
+**PatiΓ«nt zoeken:**
+- [ ] User typt "Zoek Marie van den Berg"
+- [ ] ZoekenBlock opent rechts
+- [ ] Patient search werkt
+- [ ] Selecteren patient β PatientContextCard opent
+
+**Overdracht maken:**
+- [ ] User typt "Maak overdracht"
+- [ ] OverdrachtBlock opent
+- [ ] AI genereert samenvattingen
+- [ ] Psychiater ziet alleen behandelrelevante info
+- [ ] Linked evidence klikbaar
+
+**Follow-up conversatie:**
+- [ ] User typt "Voeg toe: goed geslapen"
+- [ ] AI begrijpt context (laatste artifact = dagnotitie)
+- [ ] Tekst wordt toegevoegd aan artifact
+
+**Meerdere artifacts:**
+- [ ] User opent 3 artifacts achter elkaar
+- [ ] Tabs verschijnen bovenaan
+- [ ] Switching tussen artifacts werkt
+- [ ] 4e artifact openen β oudste sluit automatisch
+
+**Voice input:**
+- [ ] Mic icon werkt
+- [ ] Deepgram transcriptie verschijnt live
+- [ ] Pauze detectie β auto-submit
+- [ ] Voice message wordt verwerkt zoals typed message
+
+**Error handling:**
+- [ ] Offline β banner verschijnt
+- [ ] Stream interrupted β error message in chat
+- [ ] Rate limit β friendly message + retry suggestion
+- [ ] Network error β retry button
+```
+
+**E6.S2 - Performance:**
+- Virtual scrolling met `react-window` of `@tanstack/react-virtual` (>100 messages)
+- Debounce typing indicator (300ms)
+- Memoize message components (`React.memo`)
+- Lazy load artifacts (niet renderen tot actief)
+
+**E6.S3 - Edge cases:**
+- Zeer lange messages (>1000 chars)
+- Special characters in patient names
+- Concurrent artifact opening
+- Browser back/forward navigation
+- Tab close tijdens streaming
+
+**E6.S4 - Documentatie:**
+- Update `CLAUDE.md` met v3.0 architecture
+- Migration guide voor users (v2.1 β v3.0)
+- Developer README met chat API docs
+- Prompt versioning doc
+
+**Deliverable:** Production-ready v3.0, alle tests passed, gedocumenteerd
+
+---
+
+## 5. Kwaliteit & Testplan
+
+π― **Doel:** Borgen kwaliteit van v3.0 via gestructureerd testplan.
+
+### Test Types
+
+| Test Type | Scope | Tools | Verantwoordelijke |
+|-----------|-------|-------|-------------------|
+| **Manual Smoke Tests** | Alle P1 flows + edge cases | Checklist (zie E6.S1) | Developer |
+| **Integration Tests** | `/api/swift/chat` endpoint | Playwright / Jest | Developer |
+| **Performance Tests** | Chat scroll, streaming latency | Chrome DevTools, Lighthouse | Developer |
+| **User Acceptance** | Real-world flows met zorgmedewerkers | User feedback sessie | PM + Developer |
+| **Security Tests** | API keys, RLS, XSS in chat | Manual audit | Developer |
+
+### Test Coverage Targets
+
+- **Manual smoke tests:** 100% van P1 flows (dagnotitie, zoeken, overdracht, patient context)
+- **Integration tests:** `/api/swift/chat` endpoint (streaming, action generation)
+- **Performance:** Chat scroll <16ms frame time, streaming latency <500ms
+
+### Manual Test Checklist
+
+**Pre-deployment checklist:**
+- [ ] Feature flag `FEATURE_FLAG_SWIFT_V3=true` werkt
+- [ ] v2.1 nog steeds beschikbaar (fallback)
+- [ ] Alle P1 flows getest (zie E6.S1)
+- [ ] Edge cases getest (lange messages, concurrent actions, etc.)
+- [ ] Mobile responsive (toggle tussen chat/artifact)
+- [ ] Keyboard shortcuts werken (βK, Escape, Enter)
+- [ ] Voice input geΓ―ntegreerd en werkend
+- [ ] Error states tonen user-friendly messages
+- [ ] Offline banner werkt
+- [ ] Performance: scroll smooth, streaming <500ms latency
+- [ ] AI-filtering psychiater werkt (alleen behandelrelevante info)
+- [ ] Linked evidence klikbaar en toont bronnotities
+- [ ] Toast notifications bij save/error
+- [ ] Browser back/forward navigation werkt
+
+### Acceptance Criteria (MVP)
+
+**Minimaal werkend voor release:**
+1. β
Split-screen layout werkend (desktop/tablet/mobile)
+2. β
Conversatie met medical scribe voelt natuurlijk (niet robotisch)
+3. β
Artifacts openen binnen 2 sec na intent detection
+4. β
AI-filtering psychiater >85% accuracy (behandelrelevante info)
+5. β
Voice input geΓ―ntegreerd en werkend
+6. β
P1 flows (dagnotitie, zoeken, overdracht, patient context) 100% werkend
+7. β
Error handling: netwerk errors, offline, stream interrupted
+8. β
Performance: <500ms streaming latency, smooth scroll
+
+---
+
+## 6. Demo & Presentatieplan
+
+π― **Doel:** Presenteren van v3.0 aan stakeholders en users voor feedback.
+
+### Demo Scenario
+
+**Duur:** 15 minuten
+**Doelgroep:** Zorgmedewerkers (verpleegkundigen + psychiaters), product team
+**Locatie:** Vercel staging environment (`swift-v3-staging.vercel.app`)
+
+**Flow:**
+
+1. **Intro (2 min):**
+ - Context: "We hebben Swift getransformeerd naar een conversational interface"
+ - Toon v2.1 vs. v3.0 screenshot (voor/na)
+
+2. **Dagnotitie flow (3 min):**
+ - Typ: "Ik heb net medicatie gegeven aan Jan de Vries"
+ - AI herkent intent, DagnotatieBlock opent rechts met prefill
+ - Toon follow-up: "Voeg toe: hij voelt zich beter vandaag"
+ - Opslaan β Chat confirmation
+
+3. **PatiΓ«nt zoeken + context (3 min):**
+ - Typ: "Wie is Marie van den Berg?"
+ - ZoekenBlock opent, selecteer patient
+ - PatientContextCard toont laatste notities, vitals, diagnose
+ - Chat vraag: "Wat was er gisteren met Marie?"
+ - AI antwoordt met context uit notities
+
+4. **Overdracht met AI-filtering (4 min):**
+ - Typ: "Maak overdracht voor deze dienst"
+ - OverdrachtBlock opent
+ - Toon psychiater view: alleen behandelrelevante info
+ - Klik op linked evidence β bronnotitie preview
+ - Toon verschil tussen verpleegkundige vs. psychiater view
+
+5. **Voice input (2 min):**
+ - Klik mic icon
+ - Spreek: "Notitie voor Jan: bloeddruk gemeten, 135 over 85"
+ - Live transcript verschijnt
+ - DagnotatieBlock opent met prefill
+
+6. **Q&A (1 min):**
+ - Vragen beantwoorden
+ - Feedback verzamelen
+
+**Backup Plan:**
+- Lokale versie klaar bij internet/API issues
+- Pre-recorded video als complete fallback
+- Screenshots voor elk stap
+
+---
+
+## 7. Risico's & Mitigatie
+
+π― **Doel:** Risico's vroeg signaleren en mitigeren.
+
+| Risico | Kans | Impact | Mitigatie | Owner |
+|--------|------|--------|-----------|-------|
+| **AI prompt niet natuurlijk genoeg** | Hoog | Hoog | Iteratief testen met users, prompt versioning, A/B testing | Developer |
+| **Streaming latency >1s** | Middel | Hoog | Claude Haiku model overwegen (sneller), caching, local patterns voor snelle acties | Developer |
+| **Performance bij >100 messages** | Middel | Middel | Virtual scrolling, pagination, max 100 messages in view | Developer |
+| **Chat state memory leak** | Middel | Middel | Proper cleanup in useEffect, memory profiling | Developer |
+| **AI kosten te hoog** | Middel | Middel | Rate limiting, local pattern matching eerst, cache responses | PM |
+| **Mobile UX awkward** | Hoog | Middel | Extensive mobile testing, toggle UX refinement | Developer |
+| **v2.1 users niet willen switchen** | Hoog | Laag | Feature flag (optioneel), user onboarding, feedback loop | PM |
+| **Intent detection accuracy <80%** | Middel | Hoog | Hybrid approach (local + AI), confidence thresholds, fallback picker | Developer |
+| **Browser compatibility issues** | Laag | Middel | Test Chrome/Safari/Firefox, SSE polyfill if needed | Developer |
+| **Concurrent artifact state bugs** | Middel | Middel | Thorough testing, max 3 artifacts enforced, state validation | Developer |
+
+**Top 3 Risks & Mitigation:**
+
+1. **AI Prompt Engineering (Kans: Hoog, Impact: Hoog)**
+ - **Mitigatie:** Start met simpele prompt v1 in E0.S3, iteratief verfijnen met user feedback, prompt versioning (v1, v2, v3), A/B testing tussen prompts
+ - **Success metric:** >80% user satisfaction "voelt natuurlijk aan"
+
+2. **Performance - Streaming Latency (Kans: Middel, Impact: Hoog)**
+ - **Mitigatie:** Local patterns voor P1 intents (dagnotitie, zoeken) β <100ms, AI alleen voor complex/conversational, Claude Haiku overwegen, response caching
+ - **Success metric:** <500ms tot eerste AI token, <2s tot artifact open
+
+3. **Mobile UX Toggle (Kans: Hoog, Impact: Middel)**
+ - **Mitigatie:** Extensive mobile testing, bottom sheet voor artifact (native feel), swipe gestures, user testing met zorgmedewerkers
+ - **Success metric:** >70% mobile users vindt toggle intuΓ―tief
+
+---
+
+## 8. Evaluatie & Lessons Learned
+
+π― **Doel:** Reflecteren na elke epic en einde project.
+
+**Na elke epic (weekly retro):**
+- Wat ging goed deze week?
+- Welke blockers hadden we?
+- Welke AI-prompts werkten het beste?
+- Waar liepen we vertraging op?
+- Wat passen we aan voor volgende epic?
+
+**Na project (final retro):**
+
+**Te documenteren:**
+1. **Successen:**
+ - Welke componenten zijn herbruikbaar voor volgende projecten?
+ - Welke development patterns werkten goed?
+ - Welke AI-prompts waren meest effectief?
+
+2. **Uitdagingen:**
+ - Waar liepen we vast?
+ - Welke technical debt ontstond?
+ - Welke estimates waren te optimistisch/pessimistisch?
+
+3. **Metrics:**
+ - Actual time spent vs. estimated (story points)
+ - User satisfaction score (survey)
+ - Performance metrics (latency, scroll FPS)
+ - AI kosten (Claude API usage)
+
+4. **Next Steps:**
+ - P2/P3 features roadmap
+ - Technical debt payoff plan
+ - User feedback integration plan
+
+**Template voor lessons learned:**
+```markdown
+## Epic X - Lessons Learned
+
+### What went well
+- ...
+
+### What didn't go well
+- ...
+
+### Action items for next epic
+- ...
+
+### Reusable components/patterns
+- ...
+```
+
+---
+
+## 9. Referenties
+
+π― **Doel:** Koppelen aan overige Mission Control-documenten.
+
+**Mission Control Documents:**
+- **PRD Ephemeral UI:** `docs/swift/archive/nextgen-epd-prd-ephemeral-ui-epd.md` β Product vision
+- **FO v3.0:** `docs/swift/fo-swift-medical-scribe-v3.md` β Functioneel ontwerp medical scribe
+- **Haalbaarheid:** `docs/swift/haalbaarheidsanalyse-v3.md` β Feasibility analysis
+- **UX v2.1:** `docs/swift/archive/swift-ux-v2.1.md` β Huidige UX/styling
+- **UX Analyse v3:** `docs/swift/v3-redesign-met-huidige-styling.md` β Wat blijft vs. wijzigt
+- **Bouwplan v2:** `docs/swift/bouwplan-swift-v2.md` β Previous roadmap (v2.1)
+
+**Technical Resources:**
+- Repository: `https://github.com/[org]/mini-epd-prototype`
+- Staging: `https://swift-v3-staging.vercel.app` (to be created)
+- Production: `https://mini-epd.vercel.app` (existing)
+- Component Library: `components/swift/` folder
+- API Documentation: `/docs/api/` (to be created)
+
+**External References:**
+- [ChatGPT Canvas UX](https://altar.io/next-gen-of-human-ai-collaboration/) β Inspiration
+- [Claude Artifacts](https://docs.anthropic.com) β Pattern reference
+- [Abridge Linked Evidence](https://www.abridge.com/product) β Evidence linking pattern
+- [Anthropic Streaming API](https://docs.anthropic.com/en/api/streaming) β SSE implementation
+
+---
+
+## 10. Glossary & Abbreviations
+
+| Term | Betekenis |
+|------|-----------|
+| **Epic** | Grote feature of fase in development (bevat meerdere stories) |
+| **Story** | Kleine, uitvoerbare taak binnen een epic |
+| **Story Points** | Schatting van complexiteit (Fibonacci: 1, 2, 3, 5, 8, 13, 21) |
+| **SP** | Story Points (afkorting) |
+| **MVP** | Minimum Viable Product |
+| **P1/P2/P3** | Priority tiers (P1 = kritiek, P2 = belangrijk, P3 = waardevol) |
+| **SSE** | Server-Sent Events (streaming protocol) |
+| **DRY** | Don't Repeat Yourself |
+| **KISS** | Keep It Simple, Stupid |
+| **SOC** | Separation of Concerns |
+| **YAGNI** | You Aren't Gonna Need It |
+| **RLS** | Row Level Security (Supabase) |
+| **Intent** | Gebruikersintentie (dagnotitie, zoeken, overdracht, etc.) |
+| **Artifact** | UI-component die verschijnt in artifact area (block) |
+| **Block** | Herbruikbare UI-component (DagnotatieBlock, ZoekenBlock, etc.) |
+| **Prefill** | Vooringevulde data in artifact o.b.v. AI entity extraction |
+| **Medical Scribe** | AI-assistent die medische documentatie ondersteunt |
+| **Linked Evidence** | Klikbare links naar bronnotities in AI-samenvatting |
+
+---
+
+## 11. Story Points Reference
+
+**Fibonacci schaal voor story points:**
+
+| Points | Complexiteit | Geschatte tijd | Voorbeelden |
+|--------|--------------|----------------|-------------|
+| 1 | Trivial | 1-2 uur | Feature flag setup, config wijziging |
+| 2 | Simple | 2-4 uur | Component skeleton, store uitbreiding (1 field) |
+| 3 | Small | 4-8 uur | Simpele component met state, basic API endpoint |
+| 5 | Medium | 1-2 dagen | Complex component, API met business logic |
+| 8 | Large | 2-3 dagen | Feature met meerdere componenten, integrations |
+| 13 | Very Large | 3-5 dagen | Epic-level feature, major refactor |
+| 21 | Extra Large | 1 week+ | Waarschijnlijk te groot, split in kleinere stories |
+
+**Velocity tracking:**
+- **Target velocity:** ~12 SP per week (1 developer)
+- **Sprint length:** 1 week
+- **Total project:** 86 SP β 7 weken (met buffer = 8 weken)
+
+---
+
+**Versiehistorie:**
+
+| Versie | Datum | Auteur | Wijziging |
+|--------|-------|--------|-----------|
+| v1.0 | 27-12-2024 | Colin Lit | InitiΓ«le versie - complete bouwplan v3.0 |
diff --git a/docs/swift/fo-swift-medical-scribe-v3.md b/docs/swift/fo-swift-medical-scribe-v3.md
new file mode 100644
index 0000000..1e17e7c
--- /dev/null
+++ b/docs/swift/fo-swift-medical-scribe-v3.md
@@ -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 |
diff --git a/docs/swift/haalbaarheidsanalyse-v3.md b/docs/swift/haalbaarheidsanalyse-v3.md
new file mode 100644
index 0000000..9b11314
--- /dev/null
+++ b/docs/swift/haalbaarheidsanalyse-v3.md
@@ -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**
+
diff --git a/docs/swift/v3-redesign-met-huidige-styling.md b/docs/swift/v3-redesign-met-huidige-styling.md
new file mode 100644
index 0000000..e392879
--- /dev/null
+++ b/docs/swift/v3-redesign-met-huidige-styling.md
@@ -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
+
+```
+
+**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
diff --git a/mcp.json b/mcp.json
new file mode 100644
index 0000000..338e80a
--- /dev/null
+++ b/mcp.json
@@ -0,0 +1,11 @@
+{
+ "mcpServers": {
+ "supabase": {
+ "type": "http",
+ "url": "https://mcp.supabase.com/mcp?project_ref=dqugbrpwtisgyxscpefg",
+ "headers": {
+ "Authorization": "Bearer sbp_6598641b9c7afc57968d9a362088f506e9f3e20b"
+ }
+ }
+ }
+ }
\ No newline at end of file
diff --git a/supabase/check-patients.sql b/supabase/check-patients.sql
new file mode 100644
index 0000000..c0ff602
--- /dev/null
+++ b/supabase/check-patients.sql
@@ -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;
diff --git a/supabase/migrations/20251227_seed_verpleegkundige_overdracht_data.sql b/supabase/migrations/20251227_seed_verpleegkundige_overdracht_data.sql
new file mode 100644
index 0000000..131e52b
--- /dev/null
+++ b/supabase/migrations/20251227_seed_verpleegkundige_overdracht_data.sql
@@ -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)
+-- ============================================================================
diff --git a/supabase/migrations/20251227_seed_verpleegkundige_overdracht_data_v2.sql b/supabase/migrations/20251227_seed_verpleegkundige_overdracht_data_v2.sql
new file mode 100644
index 0000000..6478ecb
--- /dev/null
+++ b/supabase/migrations/20251227_seed_verpleegkundige_overdracht_data_v2.sql
@@ -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 $$;