Files
triqura-ecd/docs/swift/bouwplan-swift-v1.md
colinislit 3e94271827 feat: complete E2.S5 Input → Block wiring
- Implementeer handleSubmit met API call naar /api/intent/classify
- Voeg error handling en fallback naar dagnotitie toe
- Integreer openBlock en addRecentAction
- Update bouwplan: Epic 2 compleet (33 SP done, 46%)
2025-12-24 08:44:40 +01:00

18 KiB

Mission Control — Bouwplan Swift v1.0

Projectnaam: Swift — Contextual UI EPD Versie: v1.0 Datum: 23-12-2024 Auteur: Colin Lit / Development Team


1. Doel en context

1.1 Projectdoel

Swift is een Contextual UI interface voor het Mini-EPD systeem. In plaats van navigatie door menu's spreekt of typt de gebruiker een intentie — en het juiste UI-blok verschijnt voorgevuld met relevante data.

Kernbelofte:

Van 12 klikken en 3 minuten naar 1 zin en 15 seconden.

1.2 Business Case

Metric Huidig Met Swift Besparing
Dagnotitie maken 3-5 min 15 sec 95%
Patiënt zoeken 1-2 min 5 sec 95%
Overdracht maken 20-30 min 5 min 80%
Rapportage schrijven 8-15 min 2-3 min 75%

Per verpleegkundige per dag: ~4 uur terug naar zorg

1.3 Relatie met Documentatie

Document Beschrijft Locatie
PRD Product visie, requirements swift-prd.md
FO Functionele flows, blocks swift-fo-ai.md
TO Technische architectuur to-swift-v1.md
UX Visuele specificaties swift-ux-v2.1.md

2. Uitgangspunten

2.1 Technische Stack

Bestaand (hergebruiken):

Component Technologie Versie
Framework Next.js 14.2.18
UI Library React 18.3.1
Styling TailwindCSS 3.4.18
Components shadcn/ui -
Command Palette cmdk 1.1.1
Animations framer-motion 12.23.24
Database Supabase 2.81.1
Speech-to-Text Deepgram 4.11.2
AI Claude API -
Validation Zod 4.1.12
Forms react-hook-form 7.66.1

Nieuw toe te voegen:

Component Technologie Versie Reden
State Management Zustand ^4.5.0 Lightweight, TypeScript-first

2.2 Projectkaders

Kader Waarde
Bouwtijd 4 weken (4 sprints)
Team 1 developer
Scope MVP: P1 blocks (dagnotitie, zoeken, overdracht)
Data Bestaande Supabase database
Doel Werkende demo + user testing

2.3 Programmeer Uitgangspunten

Code Quality Principles:

  • DRY (Don't Repeat Yourself)

    • Herbruikbare block componenten
    • Centrale intent classificatie logica
    • Shared hooks voor common patterns
  • KISS (Keep It Simple, Stupid)

    • Local-first intent classificatie (regex)
    • AI alleen als fallback
    • Minimale state complexity
  • SOC (Separation of Concerns)

    • UI blocks gescheiden van intent logic
    • API routes gescheiden van business logic
    • Store slices per domein
  • YAGNI (You Aren't Gonna Need It)

    • Alleen P1 blocks in MVP
    • Geen toggle tussen interfaces
    • Geen advanced analytics in v1

Development Practices:

// ✅ Goede structuur voor Swift components
components/
├── swift/
   ├── command-center/
      ├── command-center.tsx      // Main container
      ├── command-input.tsx       // Input component
      └── index.ts                // Barrel export
   └── blocks/
       ├── dagnotitie-block.tsx
       ├── zoeken-block.tsx
       └── index.ts

// ✅ Store slice pattern
stores/
└── swift-store.ts                   // Single store file

// ✅ Intent classification
lib/
└── swift/
    ├── intent-classifier.ts         // Local classification
    ├── intent-classifier-ai.ts      // AI fallback
    └── types.ts                     // Type definitions

3. Epics & Stories Overzicht

Epic ID Titel Doel Status Stories Effort
E0 Setup & Foundation Zustand, routing, base layout Done 4 8 SP
E1 Command Center Input, voice, context bar Done 5 13 SP
E2 Intent Classification Local + AI fallback + wiring In Progress 5 12 SP
E3 P1 Blocks Dagnotitie, Zoeken, Overdracht To Do 6 21 SP
E4 Navigation & Auth Login keuze, routing, preferences To Do 4 8 SP
E5 Polish & Testing Animaties, error handling, tests To Do 4 8 SP

Totaal: 28 stories, 70 story points (31 SP done, 39 SP remaining)

Belangrijk:

  • Bouw per epic en per story, niet alles tegelijk
  • Dependencies installeren: eerst aan Colin melden
  • Database migraties: eerst aan Colin melden

4. Epics & Stories (Uitwerking)

Epic 0 — Setup & Foundation

Epic Doel: Werkende development omgeving met Zustand store en Swift routing.

Story ID Beschrijving Acceptatiecriteria Status Afh. SP
E0.S1 Zustand installeren pnpm add zustand succesvol, import werkt 1
E0.S2 Swift store opzetten stores/swift-store.ts met basis state E0.S1 2
E0.S3 Swift route aanmaken /epd/swift route met eigen layout E0.S2 2
E0.S4 Swift folder structuur components/swift/, lib/swift/ aangemaakt E0.S3 3

Technical Notes:

# E0.S1: Dependency installatie
pnpm add zustand
// E0.S2: Store structuur
// stores/swift-store.ts
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';

interface SwiftStore {
  // Context
  activePatient: Patient | null;
  shift: 'nacht' | 'ochtend' | 'middag' | 'avond';

  // Block state
  activeBlock: BlockType | null;
  prefillData: Record<string, unknown>;

  // Actions
  setActivePatient: (patient: Patient | null) => void;
  openBlock: (type: BlockType, prefill?: Record<string, unknown>) => void;
  closeBlock: () => void;
}

Epic 1 — Command Center

Epic Doel: Werkende command center met tekst en voice input.

Story ID Beschrijving Acceptatiecriteria Status Afh. SP
E1.S1 Command Center layout 4-zone layout (context, canvas, recent, input) E0.S4 3
E1.S2 Context Bar Dienst, patiënt dropdown, user info E1.S1 2
E1.S3 Command Input Tekst input met placeholder, focus state E1.S1 2
E1.S4 Voice Input integratie Deepgram streaming in command input E1.S3 3
E1.S5 Recent Strip Laatste 5 acties als chips E1.S1 3

Technical Notes:

Command Center Layout:
┌─────────────────────────────────────────┐
│ Context Bar (48px)                       │
├─────────────────────────────────────────┤
│                                         │
│ Canvas Area (flex)                      │
│                                         │
├─────────────────────────────────────────┤
│ Recent Strip (48px)                     │
├─────────────────────────────────────────┤
│ Command Input (64px, fixed bottom)      │
└─────────────────────────────────────────┘

Epic 2 — Intent Classification

Epic Doel: Two-tier intent classificatie (local + AI fallback).

Story ID Beschrijving Acceptatiecriteria Status Afh. SP
E2.S1 Local classifier Regex patterns voor P1 intents, <50ms E0.S4 3
E2.S2 Entity extraction Patient naam, categorie uit input E2.S1 3
E2.S3 AI fallback Claude Haiku bij confidence <0.8 E2.S2 2
E2.S4 Intent API route POST /api/intent/classify E2.S3 2
E2.S5 Input → Block wiring CommandInput submit → API → openBlock E2.S4 2

Technical Notes:

// E2.S1: Local classifier patterns
const INTENT_PATTERNS = {
  dagnotitie: [
    /^notitie\s+(\w+)/i,
    /^(\w+)\s+(medicatie|adl|gedrag|incident)/i,
    /dagnotitie/i,
  ],
  zoeken: [
    /^zoek\s+(\w+)/i,
    /^wie is\s+(\w+)/i,
    /^vind\s+(\w+)/i,
  ],
  overdracht: [
    /^overdracht/i,
    /^dienst (klaar|afronden)/i,
    /^wat moet ik weten/i,
  ],
};

// E2.S5: Input → Block wiring
// In CommandInput.handleSubmit:
const handleSubmit = async () => {
  const response = await fetch('/api/intent/classify', {
    method: 'POST',
    body: JSON.stringify({ input: inputValue }),
  });
  const { intent, confidence, entities } = await response.json();

  if (intent !== 'unknown' && confidence >= 0.5) {
    openBlock(intent, entities);  // Open juiste block met prefill
  } else {
    // Toon FallbackPicker (E4.S4)
  }
};

Epic 3 — P1 Blocks

Epic Doel: Werkende DagnotatieBlock, ZoekenBlock en OverdrachtBlock.

Story ID Beschrijving Acceptatiecriteria Status Afh. SP
E3.S1 Block Container Animatie wrapper, close button, sizes E1.S1 2
E3.S2 DagnotatieBlock Patient, categorie, tekst, opslaan E3.S1, E2.S2 5
E3.S3 Patient search API GET /api/patients/search?q= fuzzy search E0.S4 3
E3.S4 ZoekenBlock Input, resultaten, selectie → store E3.S1, E3.S3 3
E3.S5 PatientContextCard Na selectie: notities, vitals, diagnose E3.S4 5
E3.S6 OverdrachtBlock AI samenvatting per patiënt (bestaande API) E3.S1 3

Technical Notes:

// E3.S2: DagnotatieBlock prefill
interface DagnotitieBlockProps {
  prefill?: {
    patientId?: string;
    patientName?: string;
    category?: VerpleegkundigCategory;
    content?: string;
  };
  onSave: () => void;
  onCancel: () => void;
}

// Gebruikt bestaande POST /api/reports

Epic 4 — Navigation & Auth

Epic Doel: Login pagina met interface keuze, routing naar Swift/Klassiek.

Story ID Beschrijving Acceptatiecriteria Status Afh. SP
E4.S1 Login form uitbreiden Interface selector (Swift/Klassiek) E0.S3 2
E4.S2 Preference opslag user_metadata.preferred_interface E4.S1 2
E4.S3 Redirect middleware /epd → preference route E4.S2 2
E4.S4 Fallback Picker Visuele keuze bij lage confidence E3.S1 2

Technical Notes:

// E4.S2: Preference in Supabase
await supabase.auth.updateUser({
  data: {
    preferred_interface: 'swift', // of 'classic'
    remember_interface_choice: true,
  },
});

Epic 5 — Polish & Testing

Epic Doel: Gepolijste UX met animaties, error handling en tests.

Story ID Beschrijving Acceptatiecriteria Status Afh. SP
E5.S1 Block animaties Slide up/down met framer-motion E3.S1 2
E5.S2 Error handling Network errors, validation, toasts E3.S6 2
E5.S3 Keyboard shortcuts Cmd+K focus, Escape close, Enter submit E1.S3 2
E5.S4 Smoke tests Happy flow tests voor alle P1 blocks E5.S2 2

Technical Notes:

// E5.S1: Framer Motion animaties
const blockVariants = {
  hidden: { opacity: 0, y: 20, scale: 0.95 },
  visible: { opacity: 1, y: 0, scale: 1 },
  exit: { opacity: 0, y: 20, scale: 0.95 },
};

// E5.S3: Keyboard shortcuts
useEffect(() => {
  const handleKeyDown = (e: KeyboardEvent) => {
    if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
      e.preventDefault();
      inputRef.current?.focus();
    }
    if (e.key === 'Escape') {
      closeBlock();
    }
  };
  window.addEventListener('keydown', handleKeyDown);
  return () => window.removeEventListener('keydown', handleKeyDown);
}, []);

5. Kwaliteit & Testplan

5.1 Test Types

Test Type Scope Tools Wanneer
Unit Tests Intent classifier, entity extraction Vitest E2
Integration Tests API endpoints Vitest + MSW E2, E3
Component Tests Blocks, Command Center React Testing Library E3, E5
E2E Tests Complete flows Playwright (optioneel) E5
Manual Tests Demo scenarios Checklist E5

5.2 Test Coverage Targets

Area Target Reden
Intent classifier 90%+ Kritiek voor UX
API routes 80%+ Data integrity
UI components 60%+ Belangrijkste flows

5.3 Manual Test Checklist (MVP Demo)

Happy Flows:

  • User kan inloggen en Swift kiezen
  • Command input krijgt focus met Cmd+K
  • "notitie jan medicatie" → DagnotatieBlock opent met prefill
  • Dagnotitie opslaan → toast + block sluit
  • "zoek marie" → ZoekenBlock met resultaten
  • Patiënt selecteren → PatientContextCard
  • "overdracht" → OverdrachtBlock met AI samenvatting
  • Voice input → transcript in command input

Error Scenarios:

  • Onbekende intent → FallbackPicker
  • Network error → toast met retry
  • Lege notitie → validation error
  • Geen zoekresultaten → "Geen patiënten gevonden"

6. Demo & Presentatieplan

6.1 Demo Scenario

Duur: 10 minuten Doelgroep: Zorgprofessionals, management Locatie: Live op Vercel

Flow:

1. INTRO (1 min)
   "40% van je tijd gaat naar administratie.
    Wat als je gewoon kon zeggen wat je wilt?"

2. CONTRAST (2 min)
   Klassiek EPD: Dashboard → Patiënten → Jan → Rapportages →
                 Nieuwe → Type → Tekst → Opslaan
   Swift: "notitie jan medicatie gegeven" → Opslaan

3. DAGNOTITIE FLOW (2 min)
   - Typ: "notitie jan medicatie uitgereikt"
   - Block verschijnt voorgevuld
   - Één klik: opgeslagen

4. VOICE DEMO (2 min)
   - Klik microfoon
   - Spreek: "marie had een rustige nacht, goed geslapen"
   - Block verschijnt met transcript

5. OVERDRACHT (2 min)
   - "overdracht"
   - AI genereert samenvatting per patiënt
   - Toon bronverwijzingen

6. AFSLUITING (1 min)
   - Tijdsbesparing recap
   - Vragen

6.2 Backup Plan

Probleem Oplossing
Internet issues Localhost met demo data
Voice niet werkt Type-only demo
AI API down Pre-cached responses
Complete failure Video recording

7. Risico's & Mitigatie

Risico Kans Impact Mitigatie Owner
Voice accuracy NL Middel Hoog Deepgram NL model, fallback naar tekst Dev
Intent misclassificatie Middel Hoog Two-tier systeem, FallbackPicker Dev
AI latency Laag Middel Local-first, Haiku model Dev
User adoption Middel Middel Keuze behouden, geen dwang Product
Scope creep Hoog Hoog Strict P1-only, backlog voor rest Dev
Performance Laag Middel Code splitting, lazy loading Dev

8. Sprint Planning

Sprint 1 (Week 1): Foundation

  • E0: Setup & Foundation (8 SP)
  • E1.S1-S3: Command Center basics (7 SP)
  • Deliverable: Swift route met command input

Sprint 2 (Week 2): Intent & Blocks

  • E1.S4-S5: Voice + Recent (6 SP)
  • E2: Intent Classification (10 SP)
  • Deliverable: Werkende intent classificatie

Sprint 3 (Week 3): P1 Blocks

  • E3: Alle P1 blocks (21 SP)
  • Deliverable: DagnotatieBlock, ZoekenBlock, OverdrachtBlock

Sprint 4 (Week 4): Polish & Ship

  • E4: Navigation & Auth (8 SP)
  • E5: Polish & Testing (8 SP)
  • Deliverable: Demo-ready MVP

9. Definition of Done

Een story is Done wanneer:

  • Code geschreven en werkend
  • TypeScript types correct
  • Component responsive (mobile + desktop)
  • Error states afgehandeld
  • Toegankelijkheid basics (focus, labels)
  • Getest in Chrome + Safari
  • PR reviewed (indien team)
  • Gemerged naar main

Een epic is Done wanneer:

  • Alle stories Done
  • Integration test passed
  • Demo scenario werkt

10. Referenties

Project Documenten

  • PRD: docs/swift/swift-prd.md
  • FO: docs/swift/swift-fo-ai.md
  • TO: docs/swift/to-swift-v1.md
  • UX: docs/swift/swift-ux-v2.1.md

Bestaande Code Referenties

  • Command component: components/ui/command.tsx
  • Speech streaming: components/speech-recorder-streaming.tsx
  • Overdracht API: app/api/overdracht/generate/route.ts
  • Report types: lib/types/report.ts

External


11. Glossary

Term Betekenis
Swift Projectnaam voor Contextual UI EPD
Command Center Hoofdscherm met één input
Block Ephemeral UI component (dagnotitie, zoeken, etc.)
Intent Gebruikersintentie (dagnotitie, zoeken, overdracht)
Entity Geëxtraheerde data (patiëntnaam, categorie)
Prefill Vooraf ingevulde data in block
Klassiek EPD Traditionele menu-gebaseerde interface
P1 Prioriteit 1 (MVP scope)
SP Story Points (Fibonacci: 1, 2, 3, 5, 8)

Versiehistorie:

Versie Datum Auteur Wijziging
v1.0 23-12-2024 Colin Lit Initiële versie
v1.1 23-12-2024 Claude E0 + E1 voltooid (21 SP)
v1.2 23-12-2024 Claude E2.S1 + E2.S2 voltooid (27 SP)
v1.3 23-12-2024 Claude E2.S3 AI fallback voltooid (29 SP)
v1.4 23-12-2024 Claude E2.S1-S4 voltooid (31 SP)
v1.5 24-12-2024 Claude E2.S5 toegevoegd: Input → Block wiring (+2 SP)