docs: add architecture and intake intent documentation
- Add architecture overview, implementation plan, and intent overview - Add intake intent process specs (gap analyse, bouwplan, testplan) - Add swift architecture specs and visualization prompts - Remove obsolete aispeedrun-manifesto template Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
511
docs/architectuur/intent-overzicht.md
Normal file
511
docs/architectuur/intent-overzicht.md
Normal file
@@ -0,0 +1,511 @@
|
||||
# Intent Overzicht — Cortex
|
||||
|
||||
**Versie:** v1.0
|
||||
**Datum:** 4 februari 2026
|
||||
**Doelgroep:** Product owners, IT consultants, data scientists
|
||||
|
||||
---
|
||||
|
||||
## 1. Wat is een Intent?
|
||||
|
||||
Een **intent** is de gedetecteerde bedoeling achter een gebruikerscommando. Wanneer een zorgmedewerker zegt "zoek jan", herkent Cortex de intent `zoeken` met de entity `patientName: "jan"`.
|
||||
|
||||
**Voorbeeld flow:**
|
||||
|
||||
```
|
||||
Gebruikersinvoer → Intent → Actie
|
||||
────────────────────────────────────────────────────────
|
||||
"notitie jan" → dagnotitie → Open notitie-formulier
|
||||
"wat zijn risico's" → risico_query → Toon risico-overzicht
|
||||
"agenda vandaag" → agenda_query → Toon afspraken
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Alle Intents in Kaart
|
||||
|
||||
### 2.1 Basis Intents (Productie)
|
||||
|
||||
| Intent | Trigger voorbeelden | Wat het doet | Block |
|
||||
|--------|---------------------|--------------|-------|
|
||||
| `dagnotitie` | "notitie jan", "medicatie gegeven" | Verpleegkundige notitie maken | DagnotitieBlock |
|
||||
| `zoeken` | "zoek marie", "wie is jan" | Patiënt opzoeken | ZoekenBlock |
|
||||
| `overdracht` | "overdracht", "einde dienst" | Shift-overdracht bekijken | OverdrachtBlock |
|
||||
|
||||
### 2.2 Agenda Intents (Productie)
|
||||
|
||||
| Intent | Trigger voorbeelden | Wat het doet | Block |
|
||||
|--------|---------------------|--------------|-------|
|
||||
| `agenda_query` | "agenda", "afspraken vandaag" | Afspraken bekijken | AgendaBlock |
|
||||
| `create_appointment` | "plan afspraak jan morgen" | Nieuwe afspraak maken | CreateAppointmentBlock |
|
||||
| `cancel_appointment` | "annuleer afspraak jan" | Afspraak annuleren | CancelAppointmentBlock |
|
||||
| `reschedule_appointment` | "verzet 14:00 naar 15:00" | Afspraak verzetten | RescheduleAppointmentBlock |
|
||||
|
||||
### 2.3 Intake Intents (MVP)
|
||||
|
||||
| Intent | Trigger voorbeelden | Wat het doet | Block |
|
||||
|--------|---------------------|--------------|-------|
|
||||
| `intake_status` | "wat moet ik nog doen?", "intake checklist" | Intake voortgang tonen | IntakeStatusBlock |
|
||||
| `risico_query` | "wat zijn de risico's?", "risicotaxatie" | Risico's weergeven | RisicoBlock |
|
||||
| `diagnose_query` | "welke diagnoses?", "toon diagnose" | Diagnoses weergeven | DiagnoseBlock |
|
||||
| `intake_navigeer` | "ga naar risico", "open anamnese" | Naar intake-sectie navigeren | *(geen block, directe navigatie)* |
|
||||
|
||||
### 2.4 Speciale Intents
|
||||
|
||||
| Intent | Wanneer | Wat het doet |
|
||||
|--------|---------|--------------|
|
||||
| `unknown` | Niet herkend | Toon fallback-keuzemenu |
|
||||
|
||||
---
|
||||
|
||||
## 3. Anatomie van een Intent
|
||||
|
||||
Elke intent heeft meerdere "aanraakpunten" in de codebase:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ INTENT LEVENSCYCLUS │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. TYPES lib/cortex/types.ts │
|
||||
│ └── Intent naam in CortexIntent type │
|
||||
│ └── Block config in BLOCK_CONFIGS │
|
||||
│ └── Entities in ExtractedEntities │
|
||||
│ │
|
||||
│ 2. HERKENNING lib/cortex/reflex-classifier.ts │
|
||||
│ └── Regex patterns voor lokale classificatie │
|
||||
│ │
|
||||
│ 3. AI PROMPT app/api/cortex/chat/route.ts │
|
||||
│ └── Intent beschrijving in system prompt │
|
||||
│ └── Voorbeelden met JSON output │
|
||||
│ │
|
||||
│ 4. VALIDATIE lib/cortex/action-parser.ts │
|
||||
│ └── Zod schema voor intent validatie │
|
||||
│ └── Artifact type mapping │
|
||||
│ │
|
||||
│ 5. ROUTING lib/cortex/action-parser.ts │
|
||||
│ └── routeIntentToArtifact() switch case │
|
||||
│ │
|
||||
│ 6. UI BLOCK components/cortex/blocks/[intent]-block.tsx │
|
||||
│ └── React component voor weergave │
|
||||
│ │
|
||||
│ 7. RENDERING components/cortex/artifacts/artifact- │
|
||||
│ container.tsx │
|
||||
│ └── Import statement │
|
||||
│ └── Switch case in renderArtifactBlock() │
|
||||
│ └── Titel in getArtifactTitle() │
|
||||
│ │
|
||||
│ 8. API (optioneel) app/api/cortex/[domain]/route.ts │
|
||||
│ └── Endpoint voor data ophalen │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Bestandsoverzicht per Intent
|
||||
|
||||
### 4.1 `dagnotitie`
|
||||
|
||||
| Aspect | Bestand | Regel/Sectie |
|
||||
|--------|---------|--------------|
|
||||
| Type definitie | `lib/cortex/types.ts` | `CortexIntent` type |
|
||||
| Block config | `lib/cortex/types.ts` | `BLOCK_CONFIGS.dagnotitie` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` | `INTENT_PATTERNS.dagnotitie` |
|
||||
| AI prompt | `app/api/cortex/chat/route.ts` | System prompt sectie |
|
||||
| Validatie | `lib/cortex/action-parser.ts` | `ActionSchema` |
|
||||
| Routing | `lib/cortex/action-parser.ts` | `routeIntentToArtifact()` case |
|
||||
| UI Block | `components/cortex/blocks/dagnotitie-block.tsx` | Hele bestand |
|
||||
| Rendering | `components/cortex/artifacts/artifact-container.tsx` | Import + switch |
|
||||
| API | `app/api/reports/route.ts` | POST voor opslaan |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
patientName?: string; // "jan"
|
||||
patientId?: string; // UUID
|
||||
category?: 'medicatie' | 'adl' | 'gedrag' | 'incident' | 'observatie';
|
||||
content?: string; // "medicatie gegeven"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 `zoeken`
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/zoeken-block.tsx` |
|
||||
| API | `app/api/cortex/patients/search/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
query?: string; // Zoekterm
|
||||
patientName?: string; // Directe naam
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.3 `overdracht`
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/overdracht-block.tsx` |
|
||||
| API | `app/api/overdracht/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
// Geen specifieke entities
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.4 `agenda_query`
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/agenda-block.tsx` |
|
||||
| API | `app/api/cortex/agenda/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
dateRange?: {
|
||||
start: Date;
|
||||
end: Date;
|
||||
label: 'vandaag' | 'morgen' | 'deze week' | 'volgende week' | 'custom';
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.5 `create_appointment`
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/agenda-block.tsx` (create mode) |
|
||||
| API | `app/api/cortex/agenda/create/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
patientName?: string;
|
||||
patientId?: string;
|
||||
datetime?: {
|
||||
date: Date;
|
||||
time: string; // "HH:mm"
|
||||
};
|
||||
appointmentType?: 'intake' | 'behandeling' | 'follow-up' | 'telefonisch' | 'huisbezoek' | 'online' | 'crisis' | 'overig';
|
||||
location?: 'praktijk' | 'online' | 'thuis';
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.6 `intake_status` (MVP)
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/intake-status-block.tsx` |
|
||||
| API | `app/api/cortex/intake/status/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
patientId?: string;
|
||||
intakeId?: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Trigger patterns:**
|
||||
- "wat moet ik nog doen?"
|
||||
- "is de intake compleet?"
|
||||
- "intake checklist"
|
||||
- "intake status"
|
||||
|
||||
---
|
||||
|
||||
### 4.7 `risico_query` (MVP)
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/risico-block.tsx` |
|
||||
| API | `app/api/cortex/intake/risico/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
patientId?: string;
|
||||
intakeId?: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Trigger patterns:**
|
||||
- "wat zijn de risico's?"
|
||||
- "risicotaxatie"
|
||||
- "toon risico's"
|
||||
|
||||
---
|
||||
|
||||
### 4.8 `diagnose_query` (MVP)
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Block config | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| UI Block | `components/cortex/blocks/diagnose-block.tsx` |
|
||||
| API | `app/api/cortex/intake/diagnose/route.ts` |
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
patientId?: string;
|
||||
intakeId?: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Trigger patterns:**
|
||||
- "welke diagnoses?"
|
||||
- "toon diagnose"
|
||||
- "wat is de diagnose?"
|
||||
|
||||
---
|
||||
|
||||
### 4.9 `intake_navigeer` (MVP)
|
||||
|
||||
| Aspect | Bestand |
|
||||
|--------|---------|
|
||||
| Type definitie | `lib/cortex/types.ts` |
|
||||
| Patterns | `lib/cortex/reflex-classifier.ts` |
|
||||
| Handler | `components/cortex/command-center/command-center.tsx` |
|
||||
|
||||
**Let op:** Deze intent heeft geen block — het navigeert direct naar een EPD-pagina.
|
||||
|
||||
**Entities:**
|
||||
```typescript
|
||||
{
|
||||
navigationTarget?: 'contacts' | 'kindcheck' | 'risk' | 'anamnese' |
|
||||
'examination' | 'rom' | 'diagnosis' | 'behandeladvies';
|
||||
}
|
||||
```
|
||||
|
||||
**Trigger patterns:**
|
||||
- "ga naar risico"
|
||||
- "open diagnose"
|
||||
- "naar anamnese"
|
||||
|
||||
---
|
||||
|
||||
## 5. Data Flow Diagram
|
||||
|
||||
### 5.1 Van Invoer naar Actie
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ GEBRUIKER │
|
||||
│ spreekt/ │
|
||||
│ typt │
|
||||
└──────┬───────┘
|
||||
│ "notitie jan medicatie"
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ LAAG 1: REFLEX ARC │
|
||||
│ lib/cortex/reflex-classifier.ts │
|
||||
│ │
|
||||
│ • Pattern matching: /^notitie\s+\w+/i │
|
||||
│ • Confidence: 0.95 │
|
||||
│ • Escalatie check: geen multi-intent, geen context nodig │
|
||||
│ │
|
||||
│ Output: { intent: "dagnotitie", confidence: 0.95 } │
|
||||
└──────────────────────────┬───────────────────────────────────┘
|
||||
│
|
||||
┌────────────────┴────────────────┐
|
||||
│ Confidence >= 0.7? │
|
||||
└────────────────┬────────────────┘
|
||||
│ Ja
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ ROUTING │
|
||||
│ lib/cortex/action-parser.ts → routeIntentToArtifact() │
|
||||
│ │
|
||||
│ Input: intent="dagnotitie", entities={patientName:"jan"} │
|
||||
│ Output: { type: "dagnotitie", prefill: {...}, title: "..." } │
|
||||
└──────────────────────────┬───────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ UI RENDERING │
|
||||
│ components/cortex/artifacts/artifact-container.tsx │
|
||||
│ │
|
||||
│ • Switch op artifact.type │
|
||||
│ • Rendert <DagnotitieBlock prefill={...} /> │
|
||||
└──────────────────────────┬───────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ BLOCK │
|
||||
│ components/cortex/blocks/dagnotitie-block.tsx │
|
||||
│ │
|
||||
│ • Toont formulier met prefilled data │
|
||||
│ • Gebruiker vult aan en klikt "Opslaan" │
|
||||
│ • POST naar /api/reports │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.2 Escalatie naar AI (Laag 2)
|
||||
|
||||
Wanneer escaleert de Reflex Arc naar de AI Orchestrator?
|
||||
|
||||
| Trigger | Voorbeeld | Reden |
|
||||
|---------|-----------|-------|
|
||||
| **Lage confidence** | "blah blah" | Geen pattern match |
|
||||
| **Ambiguïteit** | "jan" | Kan zoeken of notitie zijn |
|
||||
| **Multi-intent** | "zeg jan af en maak notitie" | Twee acties in één zin |
|
||||
| **Context nodig** | "maak notitie voor hem" | Wie is "hem"? |
|
||||
| **Relatieve tijd** | "morgen om 14:00" | Datum moet berekend worden |
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ LAAG 2: ORCHESTRATOR (bij escalatie) │
|
||||
│ app/api/cortex/chat/route.ts │
|
||||
│ │
|
||||
│ • Stuurt context + input naar Claude AI │
|
||||
│ • AI retourneert IntentChain met 1+ actions │
|
||||
│ • Kan clarification vragen ("Met welke patiënt?") │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Entity Extractie
|
||||
|
||||
### 6.1 Hoe worden entities geëxtraheerd?
|
||||
|
||||
**Lokaal (Reflex Arc):**
|
||||
- Eenvoudige regex voor bekende patronen
|
||||
- Voorbeeld: `/^notitie\s+(\w+)/` → extraheert patiëntnaam
|
||||
|
||||
**AI (Orchestrator):**
|
||||
- Claude analyseert volledige zin
|
||||
- Extraheert alle relevante entities
|
||||
- Kan context gebruiken (actieve patiënt, agenda)
|
||||
|
||||
### 6.2 Entity Types
|
||||
|
||||
| Entity | Type | Voorbeeld | Gebruikt door |
|
||||
|--------|------|-----------|---------------|
|
||||
| `patientName` | string | "jan de vries" | Alle intents |
|
||||
| `patientId` | UUID | "abc-123..." | Alle intents |
|
||||
| `category` | enum | "medicatie" | dagnotitie |
|
||||
| `content` | string | "medicatie gegeven" | dagnotitie |
|
||||
| `query` | string | "jan" | zoeken |
|
||||
| `dateRange` | object | { start, end, label } | agenda_query |
|
||||
| `datetime` | object | { date, time } | create_appointment |
|
||||
| `appointmentType` | enum | "intake" | create_appointment |
|
||||
| `location` | enum | "praktijk" | create_appointment |
|
||||
| `navigationTarget` | enum | "risk" | intake_navigeer |
|
||||
|
||||
---
|
||||
|
||||
## 7. Block Types
|
||||
|
||||
### 7.1 Block Categorieën
|
||||
|
||||
| Type | Doel | Voorbeeld |
|
||||
|------|------|-----------|
|
||||
| **Query Block** | Data tonen (read-only) | RisicoBlock, DiagnoseBlock |
|
||||
| **Action Block** | Data invoeren/wijzigen | DagnotitieBlock |
|
||||
| **Status Block** | Voortgang/checklist tonen | IntakeStatusBlock |
|
||||
| **Navigation Block** | Direct navigeren | *(intake_navigeer)* |
|
||||
|
||||
### 7.2 Block Structuur
|
||||
|
||||
Alle blocks volgen hetzelfde patroon:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ [Icon] Titel [Sluiten] │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Loading state → Error state → Data state │
|
||||
│ (spinner) (foutmelding) (content) │
|
||||
│ │
|
||||
│ ─────────────────────────────────────────────── │
|
||||
│ [Secundaire actie] [Primaire actie] │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Confidence & Escalatie
|
||||
|
||||
### 8.1 Drempelwaarden
|
||||
|
||||
| Waarde | Betekenis | Actie |
|
||||
|--------|-----------|-------|
|
||||
| `>= 0.9` | Zeer zeker | Direct uitvoeren |
|
||||
| `0.7 - 0.9` | Redelijk zeker | Uitvoeren met bevestiging |
|
||||
| `< 0.7` | Onzeker | Escaleer naar AI of vraag verduidelijking |
|
||||
|
||||
### 8.2 Escalatie Redenen
|
||||
|
||||
```typescript
|
||||
type EscalationReason =
|
||||
| 'low_confidence' // Confidence < 0.7
|
||||
| 'ambiguous' // Top-2 intents liggen dicht bij elkaar
|
||||
| 'multi_intent_detected' // Meerdere acties gedetecteerd
|
||||
| 'needs_context' // Voornaamwoorden zoals "hij", "haar"
|
||||
| 'relative_time'; // "morgen", "volgende week"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Gerelateerde Documentatie
|
||||
|
||||
| Document | Locatie | Inhoud |
|
||||
|----------|---------|--------|
|
||||
| Block Template Pattern | `docs/intent/intake-intent-proces/block-template-pattern.md` | Technisch patroon voor blocks |
|
||||
| Session Log | `docs/intent/intake-intent-proces/session-log-2026-02-03.md` | Bug fixes en lessons learned |
|
||||
| Implementatieplan | `docs/architectuur/implementatieplan-nieuwe-intents.md` | Stappenplan nieuwe intents |
|
||||
|
||||
---
|
||||
|
||||
## 10. Glossary
|
||||
|
||||
| Term | Betekenis |
|
||||
|------|-----------|
|
||||
| **Intent** | Gedetecteerde bedoeling achter een commando |
|
||||
| **Entity** | Geëxtraheerd gegeven uit de invoer (naam, datum, etc.) |
|
||||
| **Block** | UI component dat een intent visueel afhandelt |
|
||||
| **Artifact** | Container voor blocks in het werkgebied |
|
||||
| **Confidence** | Zekerheidsgraad van classificatie (0-1) |
|
||||
| **Escalatie** | Doorverwijzing naar AI voor complexe invoer |
|
||||
| **Prefill** | Vooringevulde data in een formulier |
|
||||
|
||||
---
|
||||
|
||||
*Voor het toevoegen van nieuwe intents, zie: `implementatieplan-nieuwe-intents.md`*
|
||||
Reference in New Issue
Block a user