- Add intake intents to action-parser schema and routing - Add navigation handler in command-center for intake_navigeer intent - Navigate to patient intakes page with toast feedback - Update bouwplan: E5 now complete (6/7 epics done) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
39 KiB
FO/TO/Bouwplan: Cortex Intake Blocks MVP
Projectnaam: Cortex Intake Blocks - MVP Versie: v1.0 Datum: 03-02-2026 Auteur: Colin Lit (met AI-assistentie)
1. Doel en Context
1.1 Doel van dit document
Dit gecombineerde document beschrijft de functionele specificaties, technische architectuur en bouwplan voor de MVP van Cortex Intake Blocks. Het combineert FO, TO en Bouwplan in één referentiedocument.
1.2 Context
De Cortex Command Center heeft werkende intents voor dagnotities, zoeken en overdracht. De 26 intake-gerelateerde intents ontbreken volledig (zie gap-analyse-intake-cortex.md).
Dit document beschrijft de MVP fase: de 4 meest waardevolle blocks die het intake-proces via spraak ontsluiten.
1.3 Relatie met andere documenten
| Document | Relatie |
|---|---|
intake-process-intents.md |
Volledige intent definities (26 intents) |
gap-analyse-intake-cortex.md |
Analyse wat ontbreekt |
fo-to-cortex-shared-components.md |
Shared components (gebouwd) |
bouwplan-cortex-shared-components.md |
Bouwplan shared components (afgerond) |
1.4 Scope
In scope (MVP):
IntakeStatusBlock- Checklist voortgangRisicoBlock- Risico's met severity levelsDiagnoseBlock- Diagnoses lijstintake_navigeerintent - Navigatie naar tabs
Buiten scope (Fase 2+):
- ScreeningBlock, KindcheckBlock, AnamneseBlock
- BehandeladviesBlock, IntakeListBlock
- IntakeSamenvattingBlock (AI)
- Actie-intents (toevoegen via spraak)
1.5 Roadmap: Alle Intake Fases
Let op: Dit MVP dekt alleen Fase 3. De overige fases staan hieronder gepland voor toekomstige iteraties.
Overzicht Fases
┌─────────────────────────────────────────────────────────────────────────────┐
│ INTAKE PROCES ROADMAP │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ FASE 1 │ │ FASE 2 │ │ FASE 3 │ │ FASE 4 │ │
│ │ SCREENING │───▶│ INTAKE START │───▶│ UITVOERING │───▶│ AFSLUITEN │ │
│ │ │ │ │ │ │ │ │ │
│ │ ⏳ Later │ │ ⏳ Later │ │ ✅ MVP │ │ ⏳ Later │ │
│ │ 4 intents │ │ 2 intents │ │ 4 intents │ │ 3 intents │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Fase 1: Screening (⏳ Toekomstig)
| Intent | Type | Beschrijving | Block |
|---|---|---|---|
screening_query |
Query | Toon screening overzicht | ScreeningBlock |
hulpvraag_invoer |
Actie | Hulpvraag invullen | - |
screening_besluit |
Actie | Geschikt/niet geschikt | - |
screening_activiteit |
Actie | Activiteit toevoegen | - |
Prioriteit: Middel (eenmalige actie per patiënt)
Fase 2: Intake Starten (⏳ Toekomstig)
| Intent | Type | Beschrijving | Block |
|---|---|---|---|
intake_starten |
Actie | Nieuwe intake aanmaken | NewIntakeForm |
intake_lijst |
Query | Alle intakes van patiënt | IntakeListBlock |
Prioriteit: Middel (eenmalige actie per intake)
Fase 3: Intake Uitvoering (✅ MVP)
| Intent | Type | Beschrijving | Block | Status |
|---|---|---|---|---|
intake_status |
Query | Checklist voortgang | IntakeStatusBlock | ✅ MVP |
intake_navigeer |
Navigatie | Naar specifieke tab | - | ✅ MVP |
risico_query |
Query | Risico's tonen | RisicoBlock | ✅ MVP |
diagnose_query |
Query | Diagnoses tonen | DiagnoseBlock | ✅ MVP |
kindcheck_query |
Query | Kindcheck status | KindcheckBlock | ⏳ Fase 3b |
anamnese_query |
Query | Anamnese overzicht | AnamneseBlock | ⏳ Fase 3b |
behandeladvies_query |
Query | Behandeladvies | BehandeladviesBlock | ⏳ Fase 3b |
contacten_query |
Query | Contactmomenten | - | ⏳ Fase 3c |
onderzoeken_query |
Query | Onderzoeken | - | ⏳ Fase 3c |
rom_query |
Query | ROM scores | - | ⏳ Fase 3c |
*_toevoegen (6x) |
Actie | Data invoeren via spraak | - | ⏳ Fase 3d |
Fase 4: Intake Afsluiten (⏳ Toekomstig)
| Intent | Type | Beschrijving | Block |
|---|---|---|---|
intake_afsluiten |
Actie | Intake afronden | - |
intake_samenvatting |
Query | AI-samenvatting | IntakeSamenvattingBlock |
intake_checklist |
Query | Wat nog te doen | IntakeStatusBlock (hergebruik) |
Prioriteit: Middel-Hoog (AI-samenvatting is waardevol)
Iteratie Planning
| Iteratie | Fases | Intents | Geschatte effort |
|---|---|---|---|
| MVP (nu) | 3a | 4 | 16 uur |
| Iteratie 2 | 3b | +3 | 8 uur |
| Iteratie 3 | 1 + 4 | +7 | 12 uur |
| Iteratie 4 | 2 + 3c | +5 | 10 uur |
| Iteratie 5 | 3d (acties) | +6 | 16 uur |
| Totaal | Alle | 26 | ~62 uur |
2. Overzicht MVP Blocks
┌─────────────────────────────────────────────────────────────────┐
│ CORTEX MVP │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "Wat moet ik nog doen?" "Wat zijn de risico's?" │
│ ↓ ↓ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ IntakeStatus │ │ RisicoBlock │ │
│ │ Block │ │ │ │
│ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │
│ │ │ ✅ Algemeen │ │ │ │Suïcide [M] │ │ │
│ │ │ ❌ Kindcheck│ │ │ │Agressie [L] │ │ │
│ │ │ ❌ Risico │ │ │ └─────────────┘ │ │
│ │ │ ✅ Diagnose │ │ │ │ │
│ │ └─────────────┘ │ │ [Bekijk] [+] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ "Welke diagnoses?" "Ga naar risicotaxatie" │
│ ↓ ↓ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ DiagnoseBlock │ │ Navigation │ │
│ │ │ │ (geen block) │ │
│ │ ┌─────────────┐ │ │ │ │
│ │ │F32.1 Depr. │ │ │ router.push() │ │
│ │ │F41.1 Angst │ │ │ naar intake tab │ │
│ │ └─────────────┘ │ │ │ │
│ │ [Bekijk] [+] │ └─────────────────┘ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
3. User Stories
| ID | Rol | Doel / Actie | Verwachte waarde | Prioriteit |
|---|---|---|---|---|
| US-IB-01 | Behandelaar | "Wat moet ik nog doen?" vragen | Ziet checklist van intake voortgang | Hoog |
| US-IB-02 | Behandelaar | "Wat zijn de risico's?" vragen | Ziet risico's met severity levels | Hoog |
| US-IB-03 | Behandelaar | "Welke diagnoses heeft Jan?" vragen | Ziet diagnoses met ICD-10 codes | Hoog |
| US-IB-04 | Behandelaar | "Ga naar diagnose" zeggen | Navigeert direct naar diagnose tab | Hoog |
| US-IB-05 | Behandelaar | Op "Bekijk in dossier" klikken | Opent volledige EPD view | Middel |
| US-IB-06 | Behandelaar | Zien welke secties verplicht zijn | Weet wat minimaal ingevuld moet | Middel |
4. Functionele Specificaties per Block
4.1 IntakeStatusBlock
Intent: intake_status
Trigger voorbeelden: "Wat moet ik nog doen?", "Is de intake compleet?", "Intake checklist"
Functioneel gedrag:
- Context check: Block vereist actieve intake (intakeId)
- Data laden: Haal completion status op per sectie
- Weergave:
- Progress bar met percentage
- Lijst van alle 9 secties met status (✅/❌)
- Verplichte secties gemarkeerd
- Onvolledige verplichte secties highlighted (amber)
- Interactie:
- Klik op sectie → navigeer naar die tab in EPD
- "Intake afsluiten" knop (disabled als niet compleet)
Visueel:
┌─────────────────────────────────────────────────────┐
│ Intake Status - Jan de Vries [X] │
├─────────────────────────────────────────────────────┤
│ │
│ Voortgang 6/9 (67%) │
│ [████████████░░░░░░] │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ ⚠️ Nog te voltooien (3) │ │
│ │ │ │
│ │ Kindcheck [>] │ │
│ │ Risicotaxatie [>] │ │
│ │ Behandeladvies [>] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ✅ Algemeen │
│ ✅ Contactmomenten │
│ ❌ Kindcheck [Verplicht] │
│ ❌ Risicotaxatie [Verplicht] │
│ ✅ Anamnese │
│ ✅ Onderzoeken │
│ ✅ ROM │
│ ✅ Diagnose │
│ ❌ Behandeladvies [Verplicht] │
│ │
└─────────────────────────────────────────────────────┘
States:
- Loading:
BlockLoadingmet "Status laden..." - Error:
BlockErrormet retry - No intake:
BlockEmptymet "Geen actieve intake gevonden" - Complete: Groene banner "Intake is compleet!"
4.2 RisicoBlock
Intent: risico_query
Trigger voorbeelden: "Wat zijn de risico's?", "Risico's van Jan", "Toon risicotaxatie"
Functioneel gedrag:
- Context check: Block vereist actieve patient (patientId) en intake (intakeId)
- Data laden: Haal risico assessments op
- Weergave:
- Lijst van risico's met type en severity level
- Color-coded badges (groen/oranje/rood)
- Datum en beoordelaar per risico
- Interactie:
- "Bekijk in dossier" → navigeer naar risicotaxatie tab
- "Toevoegen" → navigeer naar risicotaxatie tab (fase 2: inline toevoegen)
Risico levels en kleuren:
| Level | Badge | Kleur |
|---|---|---|
| Laag | success |
Groen |
| Gemiddeld/Matig | warning |
Oranje |
| Hoog | danger |
Rood |
| Zeer hoog | danger |
Rood |
Visueel:
┌─────────────────────────────────────────────────────┐
│ Risicotaxatie [X] │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ ⚠️ Huidige risico's (3) │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Suïcidaliteit [Matig] │ │ │
│ │ │ 12 jan 2026 • Dr. Jansen │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Agressie [Laag] │ │ │
│ │ │ 10 jan 2026 • Dr. Bakker │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Zelfverwaarlozing [Laag] │ │ │
│ │ │ 10 jan 2026 • Dr. Bakker │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ───────────────────────────────────────────────── │
│ [🔗 Bekijk in dossier] [+ Toevoegen] │
│ │
└─────────────────────────────────────────────────────┘
States:
- Loading:
BlockLoadingmet "Risico's laden..." - Error:
BlockErrormet retry - No patient:
BlockEmptymet "Selecteer eerst een patiënt" - No risks:
BlockEmptymet "Geen risico's geregistreerd" + actie
4.3 DiagnoseBlock
Intent: diagnose_query
Trigger voorbeelden: "Welke diagnoses?", "Diagnose van Jan", "Toon diagnoses"
Functioneel gedrag:
- Context check: Block vereist patient en intake
- Data laden: Haal diagnoses op met ICD-10 codes
- Weergave:
- Hoofddiagnose vs bijdiagnoses
- ICD-10 code + omschrijving
- Datum vastgesteld
- Interactie:
- "Bekijk in dossier" → navigeer naar diagnose tab
- "Toevoegen" → navigeer naar diagnose tab
Visueel:
┌─────────────────────────────────────────────────────┐
│ Diagnoses [X] │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 🏥 Hoofddiagnose │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ F32.1 Depressieve stoornis, matig │ │ │
│ │ │ 15 jan 2026 │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 📋 Nevendiagnoses (2) │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ F41.1 Gegeneraliseerde angststoornis │ │ │
│ │ │ 15 jan 2026 │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Z73.0 Burnout │ │ │
│ │ │ 12 jan 2026 │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ───────────────────────────────────────────────── │
│ [🔗 Bekijk in dossier] [+ Toevoegen] │
│ │
└─────────────────────────────────────────────────────┘
4.4 Intake Navigatie (geen block)
Intent: intake_navigeer
Trigger voorbeelden: "Ga naar diagnose", "Open kindcheck", "Naar risicotaxatie"
Functioneel gedrag:
- Context check: Vereist actieve patient en intake
- Tab mapping: Parse target tab uit input
- Navigatie:
router.push()naar correcte URL - Feedback: Toast "Navigeren naar [tab]..."
Tab mapping:
| Input keywords | Target tab | URL path |
|---|---|---|
| algemeen, basis | algemeen | /intakes/[id] |
| contact, gesprek | contactmomenten | /intakes/[id]/contacts |
| kindcheck, kinderen | kindcheck | /intakes/[id]/kindcheck |
| risico, risicotaxatie | risicotaxatie | /intakes/[id]/risks |
| anamnese, voorgeschiedenis | anamnese | /intakes/[id]/anamnese |
| onderzoek | onderzoeken | /intakes/[id]/examinations |
| rom, vragenlijst | rom | /intakes/[id]/rom |
| diagnose | diagnose | /intakes/[id]/diagnosis |
| behandeladvies, advies | behandeladvies | /intakes/[id]/advice |
5. Technische Architectuur
5.1 Component Structuur
components/cortex/blocks/
├── block-container.tsx ✅ Bestaat
├── intake-status-block.tsx 🆕 Nieuw
├── risico-block.tsx 🆕 Nieuw
├── diagnose-block.tsx 🆕 Nieuw
└── ... (bestaande blocks)
lib/cortex/
├── types.ts 📝 Update (nieuwe intents)
├── reflex-classifier.ts 📝 Update (nieuwe patterns)
├── handlers/
│ └── intake-navigator.ts 🆕 Nieuw (navigatie handler)
└── hooks/
├── use-block-data.ts ✅ Bestaat (shared components)
└── use-intake-context.ts ✅ Bestaat (shared components)
app/api/cortex/
├── intake/
│ ├── [intakeId]/
│ │ ├── status/route.ts 🆕 Nieuw
│ │ ├── risks/route.ts 🆕 Nieuw
│ │ └── diagnoses/route.ts 🆕 Nieuw
5.2 Data Flow
User Input Cortex EPD
│ │ │
│ "Wat zijn de risico's?" │ │
│ ─────────────────────────> │
│ │ │
│ Reflex Classifier │
│ intent: risico_query │
│ confidence: 0.95 │
│ │ │
│ Open RisicoBlock │
│ │ │
│ │ GET /api/cortex/intake/ │
│ │ {id}/risks │
│ │ ─────────────────────────────>
│ │ │
│ │ getRiskAssessments() │
│ │ <─────────────────────────────
│ │ │
│ Render RisicoBlock │ │
│ <───────────────────────── │
5.3 Bestaande Data Functies
Deze server actions bestaan al en kunnen hergebruikt worden:
| Functie | Bestand | Gebruikt door |
|---|---|---|
getIntakeById() |
lib/actions/intake-actions.ts |
IntakeStatusBlock |
getRiskAssessments() |
lib/actions/intake-actions.ts |
RisicoBlock |
getDiagnoses() |
lib/actions/intake-actions.ts |
DiagnoseBlock |
getKindcheck() |
lib/actions/intake-actions.ts |
IntakeStatusBlock |
getTreatmentAdvice() |
lib/actions/intake-actions.ts |
IntakeStatusBlock |
6. API Ontwerp
6.1 Nieuwe Endpoints
GET /api/cortex/intake/[intakeId]/status
Doel: Intake completion status voor IntakeStatusBlock
Response:
interface IntakeStatusResponse {
intakeId: string;
intakeTitle: string;
patientId: string;
patientName: string;
completedCount: number;
totalCount: number;
sections: Array<{
key: string; // 'algemeen' | 'kindcheck' | etc.
label: string; // 'Kindcheck'
completed: boolean;
required: boolean;
path: string; // 'kindcheck' (for URL)
}>;
}
Logica per sectie:
| Sectie | Completed wanneer | Verplicht |
|---|---|---|
| algemeen | Intake bestaat | ✅ |
| contactmomenten | ≥1 contact | ❌ |
| kindcheck | hasChildren !== null |
✅* |
| risicotaxatie | ≥1 risico assessment | ✅ |
| anamnese | ≥1 anamnese entry | ✅ |
| onderzoeken | ≥1 onderzoek | ❌ |
| rom | ≥1 ROM meting | ❌ |
| diagnose | ≥1 diagnose | ✅ |
| behandeladvies | advice niet leeg | ✅ |
*Kindcheck wettelijk verplicht bij patiënten met kinderen
GET /api/cortex/intake/[intakeId]/risks
Doel: Risico assessments voor RisicoBlock
Response:
interface RisksResponse {
intakeId: string;
patientId: string;
risks: Array<{
id: string;
type: string; // 'suicidaliteit' | 'agressie' | etc.
typeLabel: string; // 'Suïcidaliteit'
level: string; // 'laag' | 'gemiddeld' | 'hoog' | 'zeer_hoog'
levelLabel: string; // 'Matig'
rationale?: string;
assessedAt: string; // ISO date
assessedBy?: string; // Naam beoordelaar
}>;
}
GET /api/cortex/intake/[intakeId]/diagnoses
Doel: Diagnoses voor DiagnoseBlock
Response:
interface DiagnosesResponse {
intakeId: string;
patientId: string;
primaryDiagnosis: Diagnosis | null;
secondaryDiagnoses: Diagnosis[];
}
interface Diagnosis {
id: string;
code: string; // ICD-10 code: 'F32.1'
description: string; // 'Depressieve stoornis, matig'
isPrimary: boolean;
diagnosedAt: string; // ISO date
diagnosedBy?: string;
}
7. Intent & Pattern Configuratie
7.1 Nieuwe Intent Types
// lib/cortex/types.ts - toevoegen aan CortexIntent
type CortexIntent =
| 'dagnotitie'
| 'zoeken'
| 'overdracht'
| 'agenda_query'
| 'create_appointment'
| 'cancel_appointment'
| 'reschedule_appointment'
// MVP Intake intents
| 'intake_status' // 🆕
| 'risico_query' // 🆕
| 'diagnose_query' // 🆕
| 'intake_navigeer' // 🆕
| 'unknown';
7.2 Reflex Patterns
// lib/cortex/reflex-classifier.ts - toevoegen
// intake_status
{ pattern: /^(wat\s+)?moet\s+ik\s+nog\s+(doen|invullen)/i, intent: 'intake_status', weight: 1.0 },
{ pattern: /^is\s+(de\s+)?intake\s+compleet/i, intent: 'intake_status', weight: 0.95 },
{ pattern: /^intake\s+(checklist|status|voortgang)/i, intent: 'intake_status', weight: 0.9 },
{ pattern: /^welke\s+secties\s+(zijn|nog)/i, intent: 'intake_status', weight: 0.85 },
// risico_query
{ pattern: /^(wat\s+zijn\s+)?(de\s+)?risico'?s/i, intent: 'risico_query', weight: 1.0 },
{ pattern: /^(toon|show)\s+risico/i, intent: 'risico_query', weight: 0.95 },
{ pattern: /^risicotaxatie/i, intent: 'risico_query', weight: 0.9 },
// diagnose_query
{ pattern: /^(welke\s+)?diagnose[ns]?(\s+heeft)?/i, intent: 'diagnose_query', weight: 1.0 },
{ pattern: /^(toon|show)\s+diagnose/i, intent: 'diagnose_query', weight: 0.95 },
{ pattern: /^wat\s+is\s+(de\s+)?diagnose/i, intent: 'diagnose_query', weight: 0.9 },
// intake_navigeer
{ pattern: /^ga\s+naar\s+(de\s+)?(risico|diagnose|kindcheck|anamnese|rom|behandel)/i, intent: 'intake_navigeer', weight: 1.0 },
{ pattern: /^open\s+(de\s+)?(risico|diagnose|kindcheck|anamnese)/i, intent: 'intake_navigeer', weight: 0.95 },
{ pattern: /^naar\s+(risico|diagnose|kindcheck)/i, intent: 'intake_navigeer', weight: 0.9 },
7.3 Block Configs
// lib/cortex/types.ts - toevoegen aan BLOCK_CONFIGS
'intake-status': {
type: 'intake-status',
title: 'Intake Status',
size: 'md',
icon: 'ClipboardList',
},
'risico-query': {
type: 'risico-query',
title: 'Risicotaxatie',
size: 'md',
icon: 'AlertTriangle',
},
'diagnose-query': {
type: 'diagnose-query',
title: 'Diagnoses',
size: 'md',
icon: 'Stethoscope',
},
8. Epics & Stories
8.1 Overzicht
| Epic ID | Titel | Doel | Stories | Geschat | Status |
|---|---|---|---|---|---|
| E0 | Intent Setup | Types, patterns, configs | 3 | 2 uur | ✅ Done |
| E1 | API Routes | Endpoints voor data | 3 | 3 uur | ✅ Done |
| E2 | IntakeStatusBlock | Checklist block | 2 | 3 uur | ✅ Done |
| E3 | RisicoBlock | Risico's block | 2 | 2 uur | ✅ Done |
| E4 | DiagnoseBlock | Diagnoses block | 2 | 2 uur | ✅ Done |
| E5 | Navigatie | intake_navigeer handler | 2 | 2 uur | ✅ Done |
| E6 | Integratie | Canvas-area + testing | 2 | 2 uur | ⚠️ Partial |
Totaal geschat: ~16 uur (2 werkdagen) Status: MVP functioneel (6/7 epics done), E2E testing nog te doen
8.2 Epic 0 — Intent Setup ✅
Doel: Cortex kan de nieuwe intents herkennen.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E0.S1 | Intent types toevoegen | 4 nieuwe intents in CortexIntent type |
✅ | 1 |
| E0.S2 | Reflex patterns toevoegen | Patterns voor alle 4 intents, confidence ≥0.85 | ✅ | 2 |
| E0.S3 | Block configs toevoegen | BLOCK_CONFIGS voor 3 blocks | ✅ | 1 |
Afhankelijkheden: Geen
Geïmplementeerd: lib/cortex/types.ts, reflex-classifier.ts, intent-classifier.ts, intent-labels.ts
8.3 Epic 1 — API Routes ✅
Doel: Backend endpoints voor block data.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E1.S1 | /api/cortex/intake/status |
Returns completion status, tested | ✅ | 3 |
| E1.S2 | /api/cortex/intake/risico |
Returns risks array, tested | ✅ | 2 |
| E1.S3 | /api/cortex/intake/diagnose |
Returns diagnoses, tested | ✅ | 2 |
Afhankelijkheden: E0
Geïmplementeerd: app/api/cortex/intake/status/route.ts, risico/route.ts, diagnose/route.ts
Opmerking: URL structuur gewijzigd naar ?patientId=xxx&intakeId=xxx ipv [intakeId] path param
8.4 Epic 2 — IntakeStatusBlock ✅
Doel: Werkend IntakeStatusBlock component.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E2.S1 | Block component bouwen | Gebruikt shared components, alle states | ✅ | 5 |
| E2.S2 | Navigatie naar secties | Klik op sectie opent EPD tab | ✅ | 2 |
Afhankelijkheden: E0, E1.S1
Geïmplementeerd: components/cortex/blocks/intake-status-block.tsx
Features: CompletionRing (SVG), verplichte/optionele secties, "Naar intake" footer actie
8.5 Epic 3 — RisicoBlock ✅
Doel: Werkend RisicoBlock component.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E3.S1 | Block component bouwen | Gebruikt shared components, color-coded badges | ✅ | 3 |
| E3.S2 | Footer acties | "Bekijk in dossier" werkt | ✅ | 1 |
Afhankelijkheden: E0, E1.S2
Geïmplementeerd: components/cortex/blocks/risico-block.tsx
Features: RiskSummaryCard (suïcide/zelfbeschadiging/agressie flags), severity badges, "Naar risicotaxaties" footer
8.6 Epic 4 — DiagnoseBlock ✅
Doel: Werkend DiagnoseBlock component.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E4.S1 | Block component bouwen | Hoofddiagnose + nevendiagnoses gescheiden | ✅ | 3 |
| E4.S2 | Footer acties | "Bekijk in dossier" werkt | ✅ | 1 |
Afhankelijkheden: E0, E1.S3
Geïmplementeerd: components/cortex/blocks/diagnose-block.tsx
Features: PrimaryDiagnosisCard, clinical status badges, ICD-10 codes, "Naar diagnoses" footer
8.7 Epic 5 — Navigatie Handler ✅
Doel: intake_navigeer intent werkt.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E5.S1 | Tab parser bouwen | Extraheert target tab uit input | ✅ | 2 |
| E5.S2 | Navigation handler | router.push() naar correcte URL, toast feedback | ✅ | 2 |
Afhankelijkheden: E0 Geïmplementeerd:
- Entity extraction in
lib/cortex/entity-extractor.ts(INTAKE_TAB_KEYWORDS, extractIntakeNavigeerEntities) navigationTargetfield toegevoegd aan ExtractedEntities typelib/cortex/action-parser.ts- intake intents toegevoegd aan schema en routingcomponents/cortex/command-center/command-center.tsx- navigation handler met router.push() en toast feedback Opmerking: Navigeert naar/epd/patients/{id}/intakes(intake lijst). Volledige tab-navigatie vereist intakeId selectie.
8.8 Epic 6 — Integratie ⚠️
Doel: Alles werkt samen in Cortex.
| Story ID | Beschrijving | Acceptatiecriteria | Status | SP |
|---|---|---|---|---|
| E6.S1 | Canvas-area updaten | Rendert nieuwe blocks op basis van intent | ✅ | 2 |
| E6.S2 | E2E testing | Alle 4 intents werken via voice/text input | ⏳ | 3 |
Afhankelijkheden: E2, E3, E4, E5 Geïmplementeerd:
components/cortex/command-center/canvas-area.tsx- imports en switch cases voor 3 blockscomponents/cortex/command-center/recent-strip.tsx- INTENT_CONFIG voor nieuwe intents TODO: E2E testing met echte voice/text input
9. Implementatie Volgorde
Week 1:
┌─────────────────────────────────────────────────────────────────┐
│ Dag 1 │
│ ├── E0.S1 Intent types │
│ ├── E0.S2 Reflex patterns │
│ ├── E0.S3 Block configs │
│ └── E1.S1 /status API route │
│ │
│ Dag 2 │
│ ├── E1.S2 /risks API route │
│ ├── E1.S3 /diagnoses API route │
│ ├── E2.S1 IntakeStatusBlock │
│ └── E2.S2 Status navigatie │
│ │
│ Dag 3 (half) │
│ ├── E3.S1 RisicoBlock │
│ ├── E3.S2 Risico footer │
│ ├── E4.S1 DiagnoseBlock │
│ └── E4.S2 Diagnose footer │
│ │
│ Dag 3 (half) + Buffer │
│ ├── E5.S1 Tab parser │
│ ├── E5.S2 Navigation handler │
│ ├── E6.S1 Canvas-area update │
│ └── E6.S2 E2E testing │
└─────────────────────────────────────────────────────────────────┘
10. Dependencies Check
10.1 Bestaande code (hergebruiken)
| Dependency | Pad | Status |
|---|---|---|
| BlockContainer | components/cortex/blocks/block-container.tsx |
✅ |
| BlockLoading, BlockError, BlockEmpty | components/cortex/shared/block-states.tsx |
✅ |
| BlockSection, BlockItem, BlockFooter | components/cortex/shared/ |
✅ |
| useBlockData, useIntakeContext | lib/cortex/hooks/ |
✅ |
| useCortexStore | stores/cortex-store.ts |
✅ |
| safeFetch, getErrorInfo | lib/cortex/error-handler.ts |
✅ |
| getRiskAssessments | lib/actions/intake-actions.ts |
✅ |
| getDiagnoses | lib/actions/intake-actions.ts |
✅ |
10.2 Nieuw te bouwen
| Item | Type | Epic |
|---|---|---|
| 4 intent types | TypeScript | E0 |
| ~12 reflex patterns | Config | E0 |
| 3 block configs | Config | E0 |
| 3 API routes | Next.js API | E1 |
| IntakeStatusBlock | React component | E2 |
| RisicoBlock | React component | E3 |
| DiagnoseBlock | React component | E4 |
| Navigation handler | TypeScript | E5 |
11. Risico's & Mitigatie
| Risico | Kans | Impact | Mitigatie |
|---|---|---|---|
| Intake context niet beschikbaar | Middel | Hoog | Fallback naar patient-selectie block |
| Meerdere intakes per patient | Middel | Middel | Gebruik meest recente of vraag clarificatie |
| Bestaande actions niet compatible | Laag | Hoog | Wrapper functies voor Cortex API |
| Pattern overlap met bestaande intents | Laag | Middel | Specifieke patterns, hogere weights |
12. Definition of Done
Per Story:
- Code geschreven volgens specs
- TypeScript compileert zonder errors
- ESLint geen errors
- Component werkt in browser
- Alle states getest (loading, error, empty, data)
Per Epic:
- E0-E4 stories DONE
- Integratie met andere epics getest
- Code reviewed
Project DONE:
- 6/7 epics volledig DONE (E0-E5)
- 1/7 epic partial (E6 - testing)
- Alle 4 intents werken (3 blocks + 1 navigatie)
pnpm buildsuccesvol- Demo scenario werkt (E2E testing)
- Commit:
b095b1efeat(cortex): add Intake Blocks MVP
13. Referenties
Project documenten:
docs/intent/intake-intent-proces/intake-process-intents.mddocs/intent/intake-intent-proces/gap-analyse-intake-cortex.mddocs/intent/intake-intent-proces/fo-to-cortex-shared-components.md
Bestaande code:
components/cortex/blocks/- Block voorbeeldenlib/cortex/reflex-classifier.ts- Pattern voorbeeldenlib/actions/intake-actions.ts- Data functies
Versiehistorie
| Versie | Datum | Auteur | Wijziging |
|---|---|---|---|
| v1.0 | 03-02-2026 | Colin Lit | Initiële versie |
| v1.1 | 03-02-2026 | Colin Lit | Status update: E0-E4 done, E5-E6 partial |
| v1.2 | 03-02-2026 | Colin Lit | E5.S2 done: navigation handler in command-center.tsx |