- 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>
729 lines
19 KiB
Markdown
729 lines
19 KiB
Markdown
# Implementatieplan — Nieuwe Intents Toevoegen
|
|
|
|
**Versie:** v1.0
|
|
**Datum:** 4 februari 2026
|
|
**Doelgroep:** Product owners, IT consultants, data scientists
|
|
|
|
---
|
|
|
|
## 1. Overzicht
|
|
|
|
Dit document beschrijft het stappenplan voor het toevoegen van een nieuwe intent aan Cortex. Een intent doorloopt **8 aanraakpunten** in de codebase — elk punt moet correct geconfigureerd zijn.
|
|
|
|
### Tijdsindicatie per Intent Type
|
|
|
|
| Type | Complexiteit | Bestanden |
|
|
|------|--------------|-----------|
|
|
| **Query Block** (data tonen) | Laag | 6-7 bestanden |
|
|
| **Action Block** (data invoeren) | Middel | 7-8 bestanden |
|
|
| **Navigatie Intent** (geen block) | Laag | 4-5 bestanden |
|
|
|
|
---
|
|
|
|
## 2. Beslisboom: Welk Type Intent?
|
|
|
|
```
|
|
┌─────────────────────────┐
|
|
│ Wat moet de intent doen?│
|
|
└───────────┬─────────────┘
|
|
│
|
|
┌───────────────────────┼───────────────────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
│ Data TONEN │ │ Data INVOEREN │ │ NAVIGEREN │
|
|
│ (read-only) │ │ (formulier) │ │ (route) │
|
|
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
Query Block Action Block Navigation Intent
|
|
|
|
Voorbeelden: Voorbeelden: Voorbeelden:
|
|
- risico_query - dagnotitie - intake_navigeer
|
|
- diagnose_query - create_appointment
|
|
- intake_status
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Stappenplan
|
|
|
|
### Stap 1: Types Definiëren
|
|
|
|
**Bestand:** `lib/cortex/types.ts`
|
|
|
|
**Wat te doen:**
|
|
|
|
1. Voeg intent toe aan `CortexIntent` type:
|
|
```typescript
|
|
export type CortexIntent =
|
|
| 'dagnotitie'
|
|
| 'zoeken'
|
|
// ... bestaande intents
|
|
| 'nieuwe_intent' // ← NIEUW
|
|
| 'unknown';
|
|
```
|
|
|
|
2. Voeg block config toe aan `BLOCK_CONFIGS` (alleen als er een block is):
|
|
```typescript
|
|
export const BLOCK_CONFIGS: Record<BlockType, BlockConfig> = {
|
|
// ... bestaande configs
|
|
nieuwe_intent: {
|
|
type: 'nieuwe_intent',
|
|
title: 'Nieuwe Intent Titel',
|
|
size: 'md', // 'sm' | 'md' | 'lg' | 'full'
|
|
icon: 'IconName', // Lucide icon naam
|
|
},
|
|
};
|
|
```
|
|
|
|
3. Voeg eventuele nieuwe entities toe aan `ExtractedEntities`:
|
|
```typescript
|
|
export interface ExtractedEntities {
|
|
// ... bestaande entities
|
|
nieuwVeld?: string;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Stap 2: Patterns Toevoegen (Reflex Arc)
|
|
|
|
**Bestand:** `lib/cortex/reflex-classifier.ts`
|
|
|
|
**Wat te doen:**
|
|
|
|
Voeg patterns toe aan `INTENT_PATTERNS`:
|
|
|
|
```typescript
|
|
const INTENT_PATTERNS: Record<...> = {
|
|
// ... bestaande patterns
|
|
|
|
nieuwe_intent: [
|
|
// Exacte commando's (weight 1.0)
|
|
{ pattern: /^trigger woord/i, weight: 1.0 },
|
|
{ pattern: /^alternatief commando/i, weight: 1.0 },
|
|
|
|
// Sterke matches (weight 0.9)
|
|
{ pattern: /^toon\s+(de\s+)?nieuwe/i, weight: 0.9 },
|
|
|
|
// Partiele matches (weight 0.7-0.8)
|
|
{ pattern: /^nieuwe\b/i, weight: 0.7 },
|
|
],
|
|
};
|
|
```
|
|
|
|
**Pattern weight richtlijnen:**
|
|
|
|
| Weight | Wanneer | Voorbeeld |
|
|
|--------|---------|-----------|
|
|
| `1.0` | Exacte, unieke trigger | `"risicotaxatie"` |
|
|
| `0.9-0.95` | Sterke indicator | `"toon risico's"` |
|
|
| `0.8-0.85` | Goede match | `"bekijk risico"` |
|
|
| `0.7` | Partiele match | `"risico"` (kan ook andere dingen zijn) |
|
|
| `< 0.7` | Vermijd | Leidt tot escalatie naar AI |
|
|
|
|
---
|
|
|
|
### Stap 3: AI Chat Integratie
|
|
|
|
**Bestand:** `app/api/cortex/chat/route.ts`
|
|
|
|
**Wat te doen:**
|
|
|
|
1. Voeg intent toe aan de system prompt (in `buildSystemPrompt()` functie):
|
|
|
|
```typescript
|
|
// In de intents lijst:
|
|
- **nieuwe_intent** — Korte beschrijving wat het doet
|
|
- Triggers: "trigger 1", "trigger 2", "trigger 3"
|
|
- Entities: veldNaam (type)
|
|
- Actie: Beschrijf wat er gebeurt
|
|
```
|
|
|
|
2. Voeg een voorbeeld toe:
|
|
|
|
```typescript
|
|
### Voorbeeld N: Nieuwe Intent
|
|
|
|
**User:**
|
|
"trigger zin"
|
|
|
|
**AI Response:**
|
|
"Korte bevestiging van wat je gaat doen.
|
|
|
|
\`\`\`json
|
|
{
|
|
"type": "action",
|
|
"intent": "nieuwe_intent",
|
|
"entities": {
|
|
"veldNaam": "waarde"
|
|
},
|
|
"confidence": 0.95,
|
|
"artifact": {
|
|
"type": "nieuwe_intent",
|
|
"prefill": {
|
|
"veldNaam": "waarde"
|
|
}
|
|
}
|
|
}
|
|
\`\`\`"
|
|
```
|
|
|
|
**Let op:** De AI leert van voorbeelden. Zorg dat:
|
|
- Het JSON format exact klopt
|
|
- De confidence realistisch is (0.85-0.98)
|
|
- De entities overeenkomen met wat je in types.ts hebt gedefinieerd
|
|
|
|
---
|
|
|
|
### Stap 4: Validatie Schema
|
|
|
|
**Bestand:** `lib/cortex/action-parser.ts`
|
|
|
|
**Wat te doen:**
|
|
|
|
1. Voeg intent toe aan `ActionSchema`:
|
|
|
|
```typescript
|
|
const ActionSchema = z.object({
|
|
type: z.literal('action'),
|
|
intent: z.enum([
|
|
'dagnotitie',
|
|
'zoeken',
|
|
// ... bestaande intents
|
|
'nieuwe_intent', // ← NIEUW
|
|
'unknown',
|
|
]),
|
|
// ... rest van schema
|
|
});
|
|
```
|
|
|
|
2. Voeg artifact type toe (als er een block is):
|
|
|
|
```typescript
|
|
artifact: z.object({
|
|
type: z.enum([
|
|
'dagnotitie',
|
|
'zoeken',
|
|
// ... bestaande types
|
|
'nieuwe_intent', // ← NIEUW
|
|
'fallback',
|
|
]),
|
|
prefill: z.record(z.string(), z.any()),
|
|
}).optional(),
|
|
```
|
|
|
|
---
|
|
|
|
### Stap 5: Routing Configureren
|
|
|
|
**Bestand:** `lib/cortex/action-parser.ts`
|
|
|
|
**Wat te doen:**
|
|
|
|
Voeg case toe aan `routeIntentToArtifact()`:
|
|
|
|
```typescript
|
|
export function routeIntentToArtifact(
|
|
intent: CortexIntent,
|
|
entities: Record<string, any>,
|
|
confidence: number
|
|
): { type: BlockType; prefill: Record<string, any>; title: string } | null {
|
|
|
|
// ... bestaande cases
|
|
|
|
case 'nieuwe_intent':
|
|
// Optioneel: check of vereiste entities aanwezig zijn
|
|
if (!entities.vereistVeld) {
|
|
return null; // Triggert clarification vraag
|
|
}
|
|
return {
|
|
type: 'nieuwe_intent',
|
|
title: 'Nieuwe Intent Titel',
|
|
prefill: {
|
|
veldNaam: entities.veldNaam,
|
|
// ... andere prefill data
|
|
},
|
|
};
|
|
}
|
|
```
|
|
|
|
**Voor navigatie intents:**
|
|
```typescript
|
|
case 'nieuwe_navigeer':
|
|
// Return null → wordt afgehandeld in CommandCenter
|
|
return null;
|
|
```
|
|
|
|
---
|
|
|
|
### Stap 6: API Route (Indien Nodig)
|
|
|
|
**Bestand:** `app/api/cortex/[domain]/route.ts`
|
|
|
|
**Wanneer nodig:** Als de block data moet ophalen van de server.
|
|
|
|
**Wat te doen:**
|
|
|
|
```typescript
|
|
// app/api/cortex/nieuwe/route.ts
|
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { z } from 'zod';
|
|
import { createClient } from '@/lib/auth/server';
|
|
|
|
const QuerySchema = z.object({
|
|
patientId: z.string().uuid(),
|
|
optionalParam: z.string().optional(), // Let op: NIET .nullable()
|
|
});
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const supabase = await createClient();
|
|
const { data: { user } } = await supabase.auth.getUser();
|
|
|
|
if (!user) {
|
|
return NextResponse.json({ error: 'Niet ingelogd' }, { status: 401 });
|
|
}
|
|
|
|
const searchParams = request.nextUrl.searchParams;
|
|
|
|
// BELANGRIJK: Convert null naar undefined voor Zod
|
|
const params = QuerySchema.safeParse({
|
|
patientId: searchParams.get('patientId'),
|
|
optionalParam: searchParams.get('optionalParam') || undefined, // ← NIET null!
|
|
});
|
|
|
|
if (!params.success) {
|
|
return NextResponse.json({ error: 'Ongeldige parameters' }, { status: 400 });
|
|
}
|
|
|
|
// Data ophalen
|
|
const { data, error } = await supabase
|
|
.from('tabel_naam')
|
|
.select('*')
|
|
.eq('patient_id', params.data.patientId);
|
|
|
|
if (error) {
|
|
return NextResponse.json({ error: error.message }, { status: 500 });
|
|
}
|
|
|
|
return NextResponse.json({ data });
|
|
}
|
|
```
|
|
|
|
**Let op (Lesson Learned):**
|
|
- `searchParams.get()` retourneert `null`, niet `undefined`
|
|
- Zod's `.optional()` verwacht `undefined`
|
|
- Gebruik altijd `|| undefined` bij optionele params
|
|
|
|
---
|
|
|
|
### Stap 7: Block Component
|
|
|
|
**Bestand:** `components/cortex/blocks/nieuwe-intent-block.tsx`
|
|
|
|
**Wat te doen:**
|
|
|
|
```typescript
|
|
'use client';
|
|
|
|
/**
|
|
* Nieuwe Intent Block
|
|
*
|
|
* Block voor [beschrijving].
|
|
* Intent: nieuwe_intent
|
|
*/
|
|
|
|
import { useCortexStore, type BlockPrefillData } from '@/stores/cortex-store';
|
|
import { BlockContainer } from './block-container';
|
|
import { BlockLoading, BlockError, BlockEmpty } from '../shared/block-states';
|
|
import { useBlockData } from '@/lib/cortex/hooks/use-block-data';
|
|
import { BLOCK_CONFIGS } from '@/lib/cortex/types';
|
|
import { IconName } from 'lucide-react';
|
|
|
|
interface NieuweIntentBlockProps {
|
|
prefill?: BlockPrefillData;
|
|
}
|
|
|
|
interface NieuweIntentData {
|
|
items: Array<{
|
|
id: string;
|
|
// ... velden
|
|
}>;
|
|
}
|
|
|
|
export function NieuweIntentBlock({ prefill }: NieuweIntentBlockProps) {
|
|
const config = BLOCK_CONFIGS['nieuwe_intent'];
|
|
const { activePatient } = useCortexStore();
|
|
|
|
const patientId = prefill?.patientId || activePatient?.id;
|
|
|
|
// Data ophalen
|
|
const { data, isLoading, error, refetch } = useBlockData<NieuweIntentData>({
|
|
endpoint: '/api/cortex/nieuwe',
|
|
params: { patientId: patientId || '' },
|
|
enabled: Boolean(patientId),
|
|
});
|
|
|
|
// State: Geen context
|
|
if (!patientId) {
|
|
return (
|
|
<BlockContainer title={config.title} size={config.size}>
|
|
<BlockEmpty
|
|
icon={IconName}
|
|
message="Selecteer eerst een patiënt"
|
|
/>
|
|
</BlockContainer>
|
|
);
|
|
}
|
|
|
|
// State: Loading
|
|
if (isLoading) {
|
|
return (
|
|
<BlockContainer title={config.title} size={config.size}>
|
|
<BlockLoading message="Data laden..." />
|
|
</BlockContainer>
|
|
);
|
|
}
|
|
|
|
// State: Error
|
|
if (error) {
|
|
return (
|
|
<BlockContainer title={config.title} size={config.size}>
|
|
<BlockError message={error} onRetry={refetch} />
|
|
</BlockContainer>
|
|
);
|
|
}
|
|
|
|
// State: Data
|
|
return (
|
|
<BlockContainer title={config.title} size={config.size}>
|
|
<div className="space-y-4">
|
|
{/* Render je data hier */}
|
|
{data?.items.map((item) => (
|
|
<div key={item.id}>
|
|
{/* Item content */}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</BlockContainer>
|
|
);
|
|
}
|
|
```
|
|
|
|
**Shared components beschikbaar:**
|
|
- `BlockContainer` — Wrapper met header en close button
|
|
- `BlockLoading` — Spinner met message
|
|
- `BlockError` — Foutmelding met retry button
|
|
- `BlockEmpty` — Lege state met icon en actie
|
|
- `BlockSection` — Sectie met header
|
|
- `BlockItem` — Lijst-item met badge
|
|
- `BlockFooter` — Footer met acties
|
|
|
|
---
|
|
|
|
### Stap 8: Artifact Container Updaten
|
|
|
|
**Bestand:** `components/cortex/artifacts/artifact-container.tsx`
|
|
|
|
**Wat te doen (3 plekken):**
|
|
|
|
1. **Import toevoegen:**
|
|
```typescript
|
|
import { NieuweIntentBlock } from '../blocks/nieuwe-intent-block';
|
|
```
|
|
|
|
2. **Render case toevoegen:**
|
|
```typescript
|
|
function renderArtifactBlock(artifact: Artifact) {
|
|
switch (artifact.type) {
|
|
// ... bestaande cases
|
|
|
|
case 'nieuwe_intent':
|
|
return <NieuweIntentBlock key={artifact.id} prefill={artifact.prefill} />;
|
|
}
|
|
}
|
|
```
|
|
|
|
3. **Titel toevoegen:**
|
|
```typescript
|
|
function getArtifactTitle(type: string): string {
|
|
switch (type) {
|
|
// ... bestaande cases
|
|
|
|
case 'nieuwe_intent':
|
|
return 'Nieuwe Intent Titel';
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Stap 9 (Optioneel): Navigatie Handler
|
|
|
|
**Alleen voor navigatie intents (zonder block)**
|
|
|
|
**Bestand:** `components/cortex/command-center/command-center.tsx`
|
|
|
|
**Wat te doen:**
|
|
|
|
In de `useEffect` die `pendingAction` afhandelt:
|
|
|
|
```typescript
|
|
useEffect(() => {
|
|
if (!pendingAction) return;
|
|
|
|
// ... bestaande handlers
|
|
|
|
if (pendingAction.intent === 'nieuwe_navigeer') {
|
|
const target = pendingAction.entities.navigationTarget;
|
|
|
|
// Navigeer naar juiste pagina
|
|
router.push(`/epd/patients/${patientId}/path/${target}`);
|
|
|
|
// Feedback tonen
|
|
toast({
|
|
title: 'Navigeren...',
|
|
description: `Naar ${target}`,
|
|
});
|
|
|
|
// Cleanup
|
|
setPendingAction(null);
|
|
return;
|
|
}
|
|
}, [pendingAction]);
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Checklist
|
|
|
|
Gebruik deze checklist bij het toevoegen van een nieuwe intent:
|
|
|
|
### Voorbereiding
|
|
- [ ] Intent type bepaald (Query/Action/Navigation)
|
|
- [ ] Intent naam gekozen (lowercase, underscore)
|
|
- [ ] Entities gedefinieerd
|
|
- [ ] Trigger woorden verzameld
|
|
|
|
### Types & Patterns
|
|
- [ ] `lib/cortex/types.ts` — CortexIntent type
|
|
- [ ] `lib/cortex/types.ts` — BLOCK_CONFIGS (als block nodig)
|
|
- [ ] `lib/cortex/types.ts` — ExtractedEntities (als nieuwe entities)
|
|
- [ ] `lib/cortex/reflex-classifier.ts` — INTENT_PATTERNS
|
|
|
|
### AI Integratie
|
|
- [ ] `app/api/cortex/chat/route.ts` — Intent in system prompt
|
|
- [ ] `app/api/cortex/chat/route.ts` — Voorbeeld met JSON
|
|
|
|
### Validatie & Routing
|
|
- [ ] `lib/cortex/action-parser.ts` — ActionSchema intent enum
|
|
- [ ] `lib/cortex/action-parser.ts` — ActionSchema artifact type (als block)
|
|
- [ ] `lib/cortex/action-parser.ts` — routeIntentToArtifact() case
|
|
|
|
### API (indien nodig)
|
|
- [ ] `app/api/cortex/[domain]/route.ts` — Nieuwe route
|
|
- [ ] Query params: `|| undefined` voor optionele params!
|
|
|
|
### UI Component
|
|
- [ ] `components/cortex/blocks/[intent]-block.tsx` — Block component
|
|
- [ ] `components/cortex/artifacts/artifact-container.tsx` — Import
|
|
- [ ] `components/cortex/artifacts/artifact-container.tsx` — Render case
|
|
- [ ] `components/cortex/artifacts/artifact-container.tsx` — Titel
|
|
|
|
### Navigatie (indien van toepassing)
|
|
- [ ] `components/cortex/command-center/command-center.tsx` — Handler
|
|
|
|
### Testen
|
|
- [ ] Lokale classificatie testen (Reflex Arc)
|
|
- [ ] AI classificatie testen (Chat)
|
|
- [ ] Block rendering testen
|
|
- [ ] Error states testen
|
|
- [ ] Voice input testen
|
|
|
|
---
|
|
|
|
## 5. Veelgemaakte Fouten
|
|
|
|
### Fout 1: Zod + null vs undefined
|
|
|
|
**Probleem:**
|
|
```typescript
|
|
// Dit faalt!
|
|
const param = searchParams.get('optionalParam'); // Returns null
|
|
```
|
|
|
|
**Oplossing:**
|
|
```typescript
|
|
const param = searchParams.get('optionalParam') || undefined;
|
|
```
|
|
|
|
### Fout 2: Intent niet in AI prompt
|
|
|
|
**Symptoom:** Chat AI vraagt "Wil je het dossier opzoeken?" ipv de juiste actie.
|
|
|
|
**Oorzaak:** Intent ontbreekt in system prompt.
|
|
|
|
**Oplossing:** Voeg intent + voorbeeld toe aan `buildSystemPrompt()`.
|
|
|
|
### Fout 3: Block wordt niet gerenderd
|
|
|
|
**Symptoom:** Console log toont "Opening artifact: intent" maar niets verschijnt.
|
|
|
|
**Oorzaak:** Drie plekken in artifact-container.tsx niet bijgewerkt.
|
|
|
|
**Oplossing:** Check import, render case, én titel.
|
|
|
|
### Fout 4: Escalatie bij elke invoer
|
|
|
|
**Symptoom:** Alles gaat naar AI, zelfs simpele commando's.
|
|
|
|
**Oorzaak:** Pattern weight te laag (< 0.7).
|
|
|
|
**Oplossing:** Verhoog weights of voeg sterkere patterns toe.
|
|
|
|
---
|
|
|
|
## 6. Diagram: Bestandenflow
|
|
|
|
```
|
|
┌────────────────────────────────────────────────────────────────────────┐
|
|
│ BESTANDEN PER STAP │
|
|
├────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ lib/cortex/ │
|
|
│ ├── types.ts ────────────────────────┬─── Stap 1: Types │
|
|
│ ├── reflex-classifier.ts ────────────┼─── Stap 2: Patterns │
|
|
│ └── action-parser.ts ────────────────┼─── Stap 4-5: Validatie+Route │
|
|
│ │ │
|
|
│ app/api/cortex/ │ │
|
|
│ ├── chat/route.ts ───────────────────┼─── Stap 3: AI Prompt │
|
|
│ └── [domain]/route.ts ───────────────┼─── Stap 6: API (optioneel) │
|
|
│ │ │
|
|
│ components/cortex/ │ │
|
|
│ ├── blocks/[intent]-block.tsx ───────┼─── Stap 7: Block Component │
|
|
│ ├── artifacts/artifact-container.tsx ┼─── Stap 8: Rendering │
|
|
│ └── command-center/command-center.tsx┴─── Stap 9: Navigatie │
|
|
│ │
|
|
└────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Voorbeeld: Nieuwe Intent "kindcheck_query"
|
|
|
|
Stel we willen een intent toevoegen voor "Toon kindcheck status".
|
|
|
|
### Stap 1: types.ts
|
|
```typescript
|
|
// CortexIntent
|
|
| 'kindcheck_query'
|
|
|
|
// BLOCK_CONFIGS
|
|
kindcheck_query: {
|
|
type: 'kindcheck_query',
|
|
title: 'Kindcheck',
|
|
size: 'md',
|
|
icon: 'Baby',
|
|
},
|
|
```
|
|
|
|
### Stap 2: reflex-classifier.ts
|
|
```typescript
|
|
kindcheck_query: [
|
|
{ pattern: /^kindcheck/i, weight: 1.0 },
|
|
{ pattern: /^(toon|bekijk)\s+(de\s+)?kindcheck/i, weight: 0.95 },
|
|
{ pattern: /^zijn\s+er\s+kinderen/i, weight: 0.9 },
|
|
{ pattern: /^kinderen\s+in\s+beeld/i, weight: 0.85 },
|
|
],
|
|
```
|
|
|
|
### Stap 3: chat/route.ts
|
|
```typescript
|
|
// In prompt:
|
|
- **kindcheck_query** — Kindcheck status opvragen
|
|
- Triggers: "kindcheck", "zijn er kinderen?", "kinderen in beeld?"
|
|
- Entities: geen
|
|
- Actie: Toont kindcheck status block
|
|
|
|
// Voorbeeld:
|
|
### Voorbeeld 13: Kindcheck
|
|
|
|
**User:**
|
|
"kindcheck"
|
|
|
|
**AI Response:**
|
|
"Ik toon de kindcheck status.
|
|
|
|
\`\`\`json
|
|
{
|
|
"type": "action",
|
|
"intent": "kindcheck_query",
|
|
"entities": {},
|
|
"confidence": 0.98,
|
|
"artifact": {
|
|
"type": "kindcheck_query",
|
|
"prefill": {}
|
|
}
|
|
}
|
|
\`\`\`"
|
|
```
|
|
|
|
### Stap 4-5: action-parser.ts
|
|
```typescript
|
|
// ActionSchema intent enum
|
|
'kindcheck_query',
|
|
|
|
// ActionSchema artifact type
|
|
'kindcheck_query',
|
|
|
|
// routeIntentToArtifact
|
|
case 'kindcheck_query':
|
|
return {
|
|
type: 'kindcheck_query',
|
|
title: 'Kindcheck',
|
|
prefill: entities,
|
|
};
|
|
```
|
|
|
|
### Stap 6: API route
|
|
```typescript
|
|
// app/api/cortex/intake/kindcheck/route.ts
|
|
// ... (vergelijkbaar met risico/route.ts)
|
|
```
|
|
|
|
### Stap 7: Block component
|
|
```typescript
|
|
// components/cortex/blocks/kindcheck-block.tsx
|
|
// ... (vergelijkbaar met risico-block.tsx)
|
|
```
|
|
|
|
### Stap 8: artifact-container.tsx
|
|
```typescript
|
|
import { KindcheckBlock } from '../blocks/kindcheck-block';
|
|
|
|
// render case
|
|
case 'kindcheck_query':
|
|
return <KindcheckBlock key={artifact.id} prefill={artifact.prefill} />;
|
|
|
|
// titel
|
|
case 'kindcheck_query':
|
|
return 'Kindcheck';
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Gerelateerde Documentatie
|
|
|
|
| Document | Locatie |
|
|
|----------|---------|
|
|
| Intent Overzicht | `docs/architectuur/intent-overzicht.md` |
|
|
| Block Template Pattern | `docs/intent/intake-intent-proces/block-template-pattern.md` |
|
|
| Session Log (Lessons Learned) | `docs/intent/intake-intent-proces/session-log-2026-02-03.md` |
|
|
| Architectuur Overzicht | `docs/architectuur/architectuur-overzicht.md` |
|
|
|
|
---
|
|
|
|
*Bij vragen of problemen, raadpleeg de session logs voor bekende issues en oplossingen.*
|