feat(diagnose+agenda): Diagnose module met ICD-10 en agenda uitbreidingen

Diagnose Module:
- Diagnose overzicht pagina met alle patiënt diagnoses
- Diagnosis manager met ICD-10 combobox zoekfunctie
- Diagnose kaarten met hoofddiagnose markering
- Modal voor nieuwe/bewerkte diagnoses
- ICD-10 GGZ codes dataset (lib/data/)
- Zod schemas voor diagnose validatie
- TypeScript types voor ICD-10 (lib/types/icd10.ts)
- Complete documentatie (PRD, FO, TO, Bouwplan)

Agenda Uitbreidingen:
- Patient context card in afspraak modal
- Rapportage composer direct in afspraak modal
- Rapportage bewerken vanuit gekoppelde rapportages
- Verbeterde focus styling voor inputs

Behandelplan:
- Flat componenten structuur (behandeldoel-card, form, planning)
- Context header component
- Uitgebreide types (lib/types/behandelplan.ts)
- Actions voor behandelplan beheer

UI Componenten:
- Command component (shadcn/ui) voor combobox
- Popover component (shadcn/ui)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
colinislit
2025-12-12 13:29:59 +01:00
parent 593bef4dcf
commit 265d3a971f
36 changed files with 6663 additions and 236 deletions

View File

@@ -0,0 +1,768 @@
# Mission Control — Bouwplan Diagnose Module
**Projectnaam:** Diagnose Module - Mini EPD
**Versie:** v1.1
**Datum:** 11-12-2024
**Auteur:** Colin Lit
---
## 1. Doel en context
**Doel:** De bestaande diagnose-functionaliteit uitbreiden naar een volwaardige module met doorzoekbare ICD-10 classificatie, verbeterde UX en hoofd-/nevendiagnose ondersteuning.
**Toelichting:**
De huidige implementatie (`diagnosis-manager.tsx`) is een basic formulier met handmatige code-invoer. Dit bouwplan beschrijft de upgrade naar:
- Doorzoekbare **ICD-10 codelijst** (~50 GGZ-codes, client-side filtering)
- **Modal-based invoer** (in plaats van inline formulier)
- **Diagnose cards** met visuele status badges
- Hoofd-/nevendiagnose markering
- DSM-5 referentieveld (vrije tekst)
**Referentiedocumenten:**
- PRD: `docs/specs/diagnose/prd-diagnose-module-v1.md` (v1.1)
- FO: `docs/specs/diagnose/fo-diagnose-module-v1.md` (v1.1)
- TO: `docs/specs/diagnose/to-diagnose-module-v1.md` (v1.0)
---
## 2. Uitgangspunten
### 2.1 Technische Stack
- **Frontend:** Next.js 14 App Router + Tailwind CSS + shadcn/ui
- **Database:** Supabase PostgreSQL (bestaande `conditions` tabel)
- **UI Components:** shadcn/ui Dialog, Command (cmdk), Badge, Card
- **Form Handling:** react-hook-form + zod
- **Icons:** Lucide React
### 2.2 Projectkaders
- **Scope:** Prototype voor demo
- **Data:** Statische ICD-10 JSON (~50 codes), geen API call
- **Licentie:** ICD-10 = publiek domein (WHO). DSM-5 vereist licentie.
- **AI:** Optioneel / post-MVP
### 2.3 Programmeer Uitgangspunten
**Code Quality Principles:**
- **DRY:** Herbruikbare ICD-10 zoekcomponent, diagnose types
- **KISS:** Client-side filtering (geen server call voor 50 codes)
- **SOC:** Modal logica gescheiden van lijst weergave
- **YAGNI:** Geen AI-suggesties in v1, geen patiënt-breed overzicht
**Development Practices:**
- Bestaande `conditions` tabel gebruiken (geen schema wijzigingen)
- Server actions in bestaande `actions.ts` uitbreiden
- shadcn/ui Command component voor autocomplete
---
## 3. Epics & Stories Overzicht
| Epic ID | Titel | Doel | Status | Stories | Opmerkingen |
|---------|-------|------|--------|---------|-------------|
| E0 | Data & Types | ICD-10 codelijst en TypeScript types | ✅ Gereed | 3 | JSON + types + schema |
| E1 | UI Componenten | Nieuwe componenten voor diagnose UI | ⏳ To Do | 4 | Modal, Combobox, Card |
| E2 | Integratie | Bestaande code refactoren | ⏳ To Do | 3 | Actions + Manager refactor |
| E3 | Polish & Test | Afronding en testen | ⏳ To Do | 2 | States + handmatige tests |
**Belangrijk:** Voer niet in 1x het volledige plan uit. Bouw per epic en per story.
**Belangrijk:** Installatie van `cmdk` dependency moet eerst aan Colin worden gemeld.
---
## 4. Epics & Stories (Uitwerking)
### Epic 0 — Data & Types
**Epic Doel:** Statische ICD-10 codelijst en TypeScript types voor de module.
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
|----------|--------------|---------------------|--------|------------------|--------------|
| E0.S1 | ICD-10 JSON codelijst maken | `lib/data/icd10-ggz-codes.json` met ~50 GGZ-codes, categorieën, keywords | ✅ | — | 3 |
| E0.S2 | TypeScript types voor ICD-10 | `lib/types/icd10.ts` met interfaces en helper functies | ✅ | E0.S1 | 1 |
| E0.S3 | Zod validatieschema | `lib/schemas/diagnosis.ts` voor form validatie met Nederlandse foutmeldingen | ✅ | E0.S2 | 1 |
**Technical Notes:**
- ICD-10 codes: F32.x (depressie), F40.x-F41.x (angst), F43.x (trauma), F60.x (persoonlijkheid), etc.
- Keywords toevoegen voor betere zoekresultaten
- Code format: `/^F\d{2}(\.\d{1,2})?$/`
---
#### E0.S1 — ICD-10 JSON Codelijst
**Doel:** Statische JSON met ~50 GGZ-relevante ICD-10 codes voor client-side filtering.
**Locatie:** `lib/data/icd10-ggz-codes.json`
**Data structuur:**
```json
{
"version": "ICD-10-GM 2024",
"source": "WHO (publiek domein)",
"categories": [
{
"name": "Depressieve stoornissen",
"codes": [
{ "code": "F32.0", "display": "Lichte depressieve episode", "keywords": ["depressie", "licht"] }
]
}
],
"frequentCodes": ["F32.1", "F41.1", "F43.1", "F41.0", "F60.3"]
}
```
**Categorie indeling (~55 codes):**
| Categorie | Codes | Aantal |
|-----------|-------|--------|
| Depressieve stoornissen | F32.x, F33.x | 7 |
| Angststoornissen | F40.x, F41.x | 8 |
| Trauma/stress | F43.x | 4 |
| OCD | F42.x | 3 |
| Bipolaire stoornissen | F31.x | 4 |
| Persoonlijkheidsstoornissen | F60.x | 7 |
| ADHD | F90.x | 2 |
| Autisme | F84.x | 2 |
| Eetstoornissen | F50.x | 3 |
| Schizofrenie/psychose | F20.x, F23.x | 3 |
| Middelengebruik | F10.x-F19.x | 6 |
| Somatoforme/dissociatief | F44.x, F45.x | 4 |
| Slaapstoornissen | F51.x | 2 |
**Acceptatiecriteria:**
- [ ] JSON is valid en parsed zonder errors
- [ ] Alle codes hebben `code`, `display` en `keywords` velden
- [ ] Keywords zijn in het Nederlands
- [ ] `frequentCodes` bevat top 5 meest gebruikte GGZ-codes
---
#### E0.S2 — TypeScript Types
**Doel:** Type-safe interfaces voor ICD-10 data en diagnose operaties.
**Locatie:** `lib/types/icd10.ts`
**Te implementeren types:**
```typescript
// Data types
interface ICD10Code {
code: string;
display: string;
keywords: string[];
}
interface ICD10Category {
name: string;
codes: ICD10Code[];
}
interface ICD10CodeList {
version: string;
source: string;
categories: ICD10Category[];
frequentCodes: string[];
}
// Diagnose types (FHIR compatible)
type DiagnosisSeverity = 'licht' | 'matig' | 'ernstig';
type DiagnosisClinicalStatus = 'active' | 'remission' | 'resolved' | ...;
type DiagnosisType = 'primary' | 'secondary';
// Helper type
type FlatICD10Code = ICD10Code & { category: string };
```
**Helper functies:**
```typescript
flattenICD10Codes(codeList): FlatICD10Code[]
searchICD10Codes(codes, query, maxResults): FlatICD10Code[]
getFrequentCodes(codes, frequentIds): FlatICD10Code[]
```
**Acceptatiecriteria:**
- [ ] Alle types exporteren correct
- [ ] Helper functies zijn type-safe
- [ ] `searchICD10Codes` zoekt op code, display en keywords
- [ ] `pnpm build` slaagt zonder type errors
---
#### E0.S3 — Zod Validatieschema
**Doel:** Form validatie met Nederlandse foutmeldingen.
**Locatie:** `lib/schemas/diagnosis.ts`
**Schema velden:**
| Veld | Type | Verplicht | Validatie |
|------|------|-----------|-----------|
| `code` | string | Ja | Regex: `/^F\d{2}(\.\d{1,2})?$/` |
| `description` | string | Ja | Min 1, max 200 tekens |
| `severity` | enum | Ja | licht / matig / ernstig |
| `diagnosisType` | enum | Ja | primary / secondary |
| `status` | enum | Ja | active / remission / resolved / entered-in-error |
| `dsm5Reference` | string | Nee | Max 100 tekens |
| `notes` | string | Nee | Max 500 tekens |
**Exports:**
```typescript
// Constants
export const DIAGNOSIS_SEVERITIES = ['licht', 'matig', 'ernstig'] as const;
export const DIAGNOSIS_TYPES = ['primary', 'secondary'] as const;
export const DIAGNOSIS_STATUSES = ['active', 'remission', 'resolved', 'entered-in-error'] as const;
// Schemas
export const diagnosisSchema = z.object({...});
export const diagnosisPayloadSchema = diagnosisSchema.extend({ patientId, intakeId });
export const diagnosisUpdateSchema = diagnosisSchema.partial().extend({ id });
// Types
export type DiagnosisFormData = z.infer<typeof diagnosisSchema>;
export type DiagnosisPayload = z.infer<typeof diagnosisPayloadSchema>;
// Defaults
export const diagnosisDefaults: DiagnosisFormData = {...};
```
**Acceptatiecriteria:**
- [ ] Alle foutmeldingen zijn in het Nederlands
- [ ] `diagnosisDefaults` heeft correcte default waarden
- [ ] Schema's zijn compatibel met react-hook-form
- [ ] `pnpm build` slaagt zonder type errors
---
### Epic 1 — UI Componenten
**Epic Doel:** Nieuwe React componenten voor de diagnose-UI.
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
|----------|--------------|---------------------|--------|------------------|--------------|
| E1.S1 | ICD-10 Combobox component | Autocomplete zoeken in ICD-10 codes, debounce, max 8 resultaten | ⏳ | E0.S1, E0.S2 | 3 |
| E1.S2 | Diagnose Modal component | Dialog met form, validatie, opslaan/bewerken | ⏳ | E0.S3, E1.S1 | 5 |
| E1.S3 | Diagnose Card component | Weergave per diagnose met badges, expand/collapse, acties | ⏳ | — | 2 |
| E1.S4 | cmdk dependency installeren | `pnpm add cmdk` uitvoeren (Colin) | ⏳ | — | 1 |
**Technical Notes:**
- **E1.S4:** Colin moet `pnpm add cmdk` goedkeuren/uitvoeren
- Gebruik shadcn/ui patterns voor consistentie
- Command component voor autocomplete (cmdk based)
---
#### E1.S1 — ICD-10 Combobox Component
**Doel:** Autocomplete zoekcomponent voor ICD-10 codes met keyboard navigatie.
**Locatie:** `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/icd10-combobox.tsx`
**Props interface:**
```typescript
interface ICD10ComboboxProps {
value: string; // Geselecteerde code (bijv. "F32.1")
onSelect: (code: FlatICD10Code) => void; // Callback bij selectie
placeholder?: string; // Default: "Zoek op code of beschrijving..."
disabled?: boolean;
}
```
**Functionaliteit:**
| Feature | Beschrijving |
|---------|--------------|
| Zoeken | Filter op code (F32), display (depressie) en keywords |
| Debounce | 200ms delay voor filtering |
| Max resultaten | 8 items in dropdown |
| Snelkeuze | Bij leeg veld: toon top 5 veelgebruikte codes |
| Keyboard | Arrow keys navigatie, Enter selecteert, Escape sluit |
| Display | Code vetgedrukt, beschrijving normaal |
**UI States:**
| State | Weergave |
|-------|----------|
| Leeg veld | Placeholder + snelkeuze dropdown |
| Typing | Zoekresultaten dropdown |
| Geen resultaten | "Geen codes gevonden voor '{query}'" |
| Geselecteerd | Geselecteerde code + beschrijving in input |
**Acceptatiecriteria:**
- [ ] Zoeken werkt op code, display en keywords
- [ ] Debounce voorkomt te veel renders
- [ ] Max 8 resultaten worden getoond
- [ ] Snelkeuze toont top 5 bij leeg veld
- [ ] Keyboard navigatie werkt correct
- [ ] Focus management correct (blur sluit dropdown)
---
#### E1.S2 — Diagnose Modal Component
**Doel:** Modal dialog voor toevoegen en bewerken van diagnoses.
**Locatie:** `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-modal.tsx`
**Props interface:**
```typescript
interface DiagnosisModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
patientId: string;
intakeId: string;
diagnosis?: Condition; // undefined = nieuw, Condition = bewerk
onSuccess: () => void; // Callback na succesvol opslaan
}
```
**Form velden:**
| Veld | Component | Verplicht | Notes |
|------|-----------|-----------|-------|
| ICD-10 Code | ICD10Combobox | Ja | Autocomplete |
| Ernst | Select | Ja | licht / matig / ernstig |
| Diagnose type | RadioGroup | Ja | Hoofd / Neven |
| Status | Select | Ja | Actief / In remissie / Opgelost |
| DSM-5 referentie | Input | Nee | Vrije tekst |
| Onderbouwing | Textarea | Nee | Max 500 tekens |
**Gedrag:**
| Scenario | Actie |
|----------|-------|
| Nieuw | Lege form met defaults |
| Bewerk | Form voorgevuld met bestaande data |
| Submit | Validatie → Server action → onSuccess → Close |
| Validatiefout | Inline errors onder velden |
| Server error | Toast met foutmelding |
**UI Layout:**
```
┌─────────────────────────────────────────────────────────────┐
│ Nieuwe diagnose / Diagnose bewerken [✕] │
├─────────────────────────────────────────────────────────────┤
│ │
│ ICD-10 Code * │
│ [Combobox: Zoek op code of beschrijving...] │
│ │
│ Ernst * Diagnose type * │
│ [Select: Matig ▼] ○ Hoofddiagnose │
│ ● Nevendiagnose │
│ │
│ Status * │
│ [Select: Actief ▼] │
│ │
│ DSM-5 referentie (optioneel) │
│ [Input: bijv. Major Depressive Disorder] │
│ │
│ Onderbouwing (optioneel) │
│ [Textarea: Klinische redenering...] │
│ │
│ [Annuleren] [Opslaan] │
└─────────────────────────────────────────────────────────────┘
```
**Acceptatiecriteria:**
- [ ] Modal opent/sluit correct
- [ ] Form validatie werkt met Nederlandse foutmeldingen
- [ ] ICD-10 combobox integreert correct
- [ ] Bewerk modus vult form voor met bestaande data
- [ ] Opslaan roept juiste server action aan
- [ ] Loading state tijdens opslaan
- [ ] Modal sluit na succesvolle actie
---
#### E1.S3 — Diagnose Card Component
**Doel:** Visuele weergave van een diagnose met acties.
**Locatie:** `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-card.tsx`
**Props interface:**
```typescript
interface DiagnosisCardProps {
diagnosis: Condition;
isPrimary?: boolean;
onEdit: () => void;
onDelete: () => void;
isDeleting?: boolean;
}
```
**UI Layout:**
```
┌─────────────────────────────────────────────────────────────┐
│ F32.1 — Matige depressieve episode HOOFD [⋮] │
├─────────────────────────────────────────────────────────────┤
│ Ernst: Matig │ Status: Actief │ 15 nov 2024 │
├─────────────────────────────────────────────────────────────┤
│ ▼ Onderbouwing │
│ Patiënt voldoet aan 6 van de 9 criteria... │
└─────────────────────────────────────────────────────────────┘
```
**Elementen:**
| Element | Beschrijving |
|---------|--------------|
| Code + beschrijving | Vetgedrukt, altijd zichtbaar |
| HOOFD badge | Groen, alleen bij isPrimary |
| Status badge | Kleur per status (groen/blauw/grijs/rood) |
| Ernst | Tekst weergave |
| Datum | Format: d MMM yyyy (NL locale) |
| Onderbouwing | Ingeklapt, expand via chevron |
| Context menu | Bewerk, Verwijder |
**Status badge kleuren:**
| Status | Kleur | Tekst |
|--------|-------|-------|
| active | Groen | Actief |
| remission | Blauw | In remissie |
| resolved | Grijs | Opgelost |
| entered-in-error | Rood | Foutief |
**Acceptatiecriteria:**
- [ ] Card toont alle diagnose informatie
- [ ] HOOFD badge alleen zichtbaar bij isPrimary
- [ ] Status badge heeft correcte kleur
- [ ] Onderbouwing is expand/collapse
- [ ] Context menu met Bewerk/Verwijder
- [ ] Loading state bij verwijderen
---
#### E1.S4 — cmdk Dependency Installeren
**Doel:** Command menu library installeren voor autocomplete functionaliteit.
**Commando:**
```bash
pnpm add cmdk
```
**Alternatief (indien cmdk niet gewenst):**
Custom autocomplete bouwen met:
- `@radix-ui/react-popover` (reeds aanwezig)
- `@radix-ui/react-scroll-area`
- Custom filtering logic
**Acceptatiecriteria:**
- [ ] `pnpm add cmdk` uitgevoerd door Colin
- [ ] Package toegevoegd aan `package.json`
- [ ] `pnpm install` succesvol
- [ ] `pnpm build` slaagt
---
### Epic 2 — Integratie
**Epic Doel:** Bestaande code refactoren en nieuwe componenten integreren.
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
|----------|--------------|---------------------|--------|------------------|--------------|
| E2.S1 | Server actions uitbreiden | `updateDiagnosis` functie, code_system naar ICD-10 | ⏳ | E0.S3 | 2 |
| E2.S2 | DiagnosisManager refactoren | Vervang inline form door modal, gebruik DiagnosisCard | ⏳ | E1.S2, E1.S3 | 3 |
| E2.S3 | Page.tsx aanpassen | Pagina tekst updaten, imports aanpassen | ⏳ | E2.S2 | 1 |
---
#### E2.S1 — Server Actions Uitbreiden
**Doel:** Bestaande server actions aanpassen en uitbreiden voor nieuwe functionaliteit.
**Locatie:** `app/epd/patients/[id]/intakes/[intakeId]/actions.ts`
**Wijzigingen in `createDiagnosis`:**
```typescript
// Huidige implementatie
code_system: undefined // of 'DSM-5'
// Nieuwe implementatie
code_system: 'ICD-10',
category: payload.diagnosisType === 'primary' ? 'primary-diagnosis' : 'encounter-diagnosis',
```
**Nieuwe functie `updateDiagnosis`:**
```typescript
export async function updateDiagnosis(
diagnosisId: string,
payload: DiagnosisUpdatePayload
): Promise<{ success: boolean; error?: string }> {
const supabase = await createClient();
const { error } = await supabase
.from('conditions')
.update({
code_code: payload.code,
code_display: payload.description,
clinical_status: payload.status,
severity_display: payload.severity,
note: payload.notes,
category: payload.diagnosisType === 'primary' ? 'primary-diagnosis' : 'encounter-diagnosis',
updated_at: new Date().toISOString(),
})
.eq('id', diagnosisId);
if (error) {
return { success: false, error: 'Diagnose bijwerken mislukt' };
}
revalidatePath(`/epd/patients/[id]/intakes/[intakeId]/diagnosis`);
return { success: true };
}
```
**Acceptatiecriteria:**
- [ ] `createDiagnosis` zet code_system op 'ICD-10'
- [ ] `createDiagnosis` zet category correct (primary/encounter)
- [ ] `updateDiagnosis` functie werkt correct
- [ ] Path revalidatie na create/update/delete
- [ ] Foutafhandeling met Nederlandse meldingen
---
#### E2.S2 — DiagnosisManager Refactoren
**Doel:** Bestaande component vervangen door nieuwe UI met modal en cards.
**Locatie:** `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-manager.tsx`
**Huidige structuur (te vervangen):**
```
- Inline diagnose lijst
- Inline toevoeg formulier
- Verwijder buttons
```
**Nieuwe structuur:**
```
- DiagnosisCard lijst (met sorteer: hoofd eerst)
- [+ Nieuwe diagnose] button → opent DiagnosisModal
- DiagnosisModal (create/edit)
- Verwijder bevestiging dialog
```
**State management:**
```typescript
const [modalOpen, setModalOpen] = useState(false);
const [editingDiagnosis, setEditingDiagnosis] = useState<Condition | undefined>();
const [deletingId, setDeletingId] = useState<string | null>(null);
```
**Gedrag:**
| Actie | Effect |
|-------|--------|
| [+ Nieuwe diagnose] | `setModalOpen(true)`, `setEditingDiagnosis(undefined)` |
| Card: Bewerk | `setModalOpen(true)`, `setEditingDiagnosis(diagnosis)` |
| Card: Verwijder | Confirm dialog → `deleteDiagnosis()` |
| Modal: Opslaan | `create/updateDiagnosis()` → close modal |
**Acceptatiecriteria:**
- [ ] Inline form verwijderd
- [ ] DiagnosisCard voor elke diagnose
- [ ] Hoofddiagnoses worden eerst getoond
- [ ] Modal opent voor nieuw/bewerk
- [ ] Verwijderen met bevestiging
- [ ] Loading states correct
---
#### E2.S3 — Page.tsx Aanpassen
**Doel:** Server component aanpassen voor nieuwe module.
**Locatie:** `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/page.tsx`
**Wijzigingen:**
```typescript
// Huidige tekst
<p className="text-sm text-slate-600">
Registreer DSM-5 diagnoses gekoppeld aan deze intake.
</p>
// Nieuwe tekst
<p className="text-sm text-slate-600">
Registreer diagnoses met ICD-10 classificatie gekoppeld aan deze intake.
</p>
```
**Acceptatiecriteria:**
- [ ] Tekst verwijst naar ICD-10 i.p.v. DSM-5
- [ ] Imports zijn correct
- [ ] Pagina laadt zonder errors
---
### Epic 3 — Polish & Test
**Epic Doel:** Afronding met correcte feedback en handmatige tests.
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | Story Points |
|----------|--------------|---------------------|--------|------------------|--------------|
| E3.S1 | Empty states en feedback | Toast bij acties, lege staat tekst, loading indicators | ⏳ | E2.S2 | 1 |
| E3.S2 | Handmatige tests uitvoeren | Alle test scenario's doorlopen en documenteren | ⏳ | E3.S1 | 1 |
---
#### E3.S1 — Empty States en Feedback
**Doel:** Consistente feedback en lege staten voor goede UX.
**Empty states:**
| Context | Tekst | Actie |
|---------|-------|-------|
| Geen diagnoses | "Nog geen diagnoses geregistreerd." | [+ Nieuwe diagnose] button prominent |
| Geen zoekresultaten | "Geen codes gevonden voor '{query}'" | — |
**Toast feedback:**
| Actie | Type | Tekst |
|-------|------|-------|
| Diagnose opgeslagen | Success | "Diagnose opgeslagen" |
| Diagnose bijgewerkt | Success | "Diagnose bijgewerkt" |
| Diagnose verwijderd | Success | "Diagnose verwijderd" |
| Opslaan mislukt | Error | "Opslaan mislukt: {error}" |
**Loading indicators:**
| Context | Indicator |
|---------|-----------|
| Modal opslaan | Button disabled + spinner |
| Verwijderen | Card disabled + spinner |
**Acceptatiecriteria:**
- [ ] Lege staat toont correcte tekst en button
- [ ] Toast feedback bij alle acties
- [ ] Loading indicators zichtbaar
- [ ] Geen UI jumps tijdens laden
---
#### E3.S2 — Handmatige Tests
**Doel:** Alle functionaliteit testen en documenteren.
**Test scenario's:**
| # | Scenario | Stappen | Verwacht resultaat | Status |
|---|----------|---------|-------------------|--------|
| 1 | Zoek op beschrijving | Type "depressie" in combobox | Toont F32.x codes | ⏳ |
| 2 | Zoek op code | Type "F41" in combobox | Toont angststoornissen | ⏳ |
| 3 | Selecteer code | Klik op F32.1 in dropdown | Vult code + beschrijving | ⏳ |
| 4 | Validatie | Opslaan zonder code | Toont foutmelding | ⏳ |
| 5 | Nieuwe diagnose | Vul form in → Opslaan | Card verschijnt in lijst | ⏳ |
| 6 | Bewerk diagnose | Klik Bewerk → wijzig → Opslaan | Card toont nieuwe data | ⏳ |
| 7 | Verwijder diagnose | Klik Verwijder → Bevestig | Card verdwijnt | ⏳ |
| 8 | Snelkeuze | Focus op lege combobox | Toont top 5 codes | ⏳ |
| 9 | Hoofddiagnose | Selecteer "Hoofddiagnose" | HOOFD badge zichtbaar | ⏳ |
| 10 | Build | `pnpm build` | Geen errors | ⏳ |
**Acceptatiecriteria:**
- [ ] Alle scenario's doorlopen
- [ ] Eventuele bugs gedocumenteerd
- [ ] `pnpm build` slaagt
- [ ] `pnpm lint` geen errors
---
## 5. Kwaliteit & Testplan
### Test Types
| Test Type | Scope | Tools | Verantwoordelijke |
|-----------|-------|-------|-------------------|
| Type Check | Alle nieuwe files | `pnpm build` | Developer |
| Lint | Alle nieuwe files | `pnpm lint` | Developer |
| Manual Tests | Diagnose flows | Handmatig | Developer |
### Manual Test Checklist (voor demo)
- [ ] ICD-10 zoeken werkt op code en beschrijving
- [ ] Nieuwe diagnose toevoegen via modal
- [ ] Bestaande diagnose bewerken
- [ ] Diagnose verwijderen met bevestiging
- [ ] Hoofddiagnose markeren (visuele badge)
- [ ] Ernst en status selecteren
- [ ] Onderbouwing toevoegen en bekijken
- [ ] Lege staat correct weergegeven
- [ ] Toast feedback bij opslaan/verwijderen
- [ ] Build slaagt zonder errors
---
## 6. Bestandsstructuur (Na Implementatie)
```
app/epd/patients/[id]/intakes/[intakeId]/diagnosis/
├── page.tsx # Server component (aangepast)
└── components/
├── diagnosis-manager.tsx # Refactored: lijst + modal trigger
├── diagnosis-card.tsx # Nieuw: diagnose weergave
├── diagnosis-modal.tsx # Nieuw: invoer/bewerk modal
└── icd10-combobox.tsx # Nieuw: autocomplete zoeken
lib/data/
└── icd10-ggz-codes.json # Nieuw: statische codelijst (55 codes)
lib/types/
└── icd10.ts # Nieuw: ICD-10 TypeScript types
lib/schemas/
└── diagnosis.ts # Nieuw: Zod validatieschema
```
---
## 7. Risico's & Mitigatie
| Risico | Kans | Impact | Mitigatie | Owner |
|--------|------|--------|-----------|-------|
| cmdk dependency te groot | Laag | Laag | ~10KB gzipped, acceptabel | Developer |
| ICD-10 codes incompleet voor demo | Laag | Middel | Start met 55, uitbreiden op verzoek | Developer |
| Bestaande diagnoses breken | Laag | Hoog | Backward compatible, DSM-5 data blijft | Developer |
| Modal UX niet intuïtief | Middel | Middel | Volg shadcn/ui patterns | Developer |
---
## 8. Dependency Check
### Benodigde nieuwe dependency
```bash
pnpm add cmdk
```
### Bestaande dependencies (geen actie)
- `@radix-ui/react-dialog` — Dialog voor modal
- `@radix-ui/react-select` — Dropdowns
- `react-hook-form` — Form handling
- `@hookform/resolvers` — Zod integration
- `zod` — Validatie
- `lucide-react` — Icons
- `date-fns` — Datum formatting
---
## 9. Referenties
**Mission Control Documents:**
- PRD: `docs/specs/diagnose/prd-diagnose-module-v1.md`
- FO: `docs/specs/diagnose/fo-diagnose-module-v1.md`
- TO: `docs/specs/diagnose/to-diagnose-module-v1.md`
**Bestaande Implementatie:**
- `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/` — Huidige pagina
- `app/epd/patients/[id]/intakes/[intakeId]/actions.ts` — Server actions
- `lib/supabase/database.types.ts` — Database types (conditions)
**Externe Bronnen:**
- [WHO ICD-10 (publiek domein)](https://www.who.int/standards/classifications/classification-of-diseases)
- [shadcn/ui Command](https://ui.shadcn.com/docs/components/command)
- [cmdk documentation](https://cmdk.paco.me/)
---
## 10. Glossary
| Term | Betekenis |
|------|-----------|
| ICD-10 | International Classification of Diseases, 10e revisie (WHO) |
| DSM-5 | Diagnostic and Statistical Manual of Mental Disorders (APA) |
| GGZ | Geestelijke gezondheidszorg |
| cmdk | Command menu library voor React (autocomplete) |
| FHIR | Fast Healthcare Interoperability Resources (standaard) |
---
**Versiehistorie:**
| Versie | Datum | Auteur | Wijziging |
|--------|-------|--------|-----------|
| v1.0 | 11-12-2024 | Colin Lit | Initiële versie |
| v1.1 | 11-12-2024 | Colin Lit | Uitgebreide story beschrijvingen, E0 gereed |

View File

@@ -0,0 +1,397 @@
# 🧩 Functioneel Ontwerp (FO) Diagnose Module
**Projectnaam:** Diagnose Module - Mini EPD
**Versie:** v1.1
**Datum:** 11-12-2024
**Auteur:** Colin Lit
---
## 1. Doel en relatie met het PRD
🎯 **Doel van dit document:**
Het Functioneel Ontwerp beschrijft **hoe** de diagnosemodule in de praktijk werkt voor GGZ-professionals. Dit document vertaalt de requirements uit het PRD naar concrete schermen, acties en interacties.
📘 **Toelichting aan de lezer:**
Dit FO beschrijft de diagnose-functionaliteit voor het prototype met **ICD-10 classificatie** (publiek domein) als basis en optionele DSM-5 referentie. De focus ligt op een eenvoudige, werkende flow voor demo-doeleinden.
**Relatie met PRD:**
Dit FO implementeert de requirements uit `prd-diagnose-module-v1.md` (v1.1), specifiek:
- ICD-10 classificatie browser (PRD 3.1)
- Diagnose registratie met DSM-5 referentieveld (PRD 3.2)
- AI-ondersteuning (PRD 3.3) — optioneel voor prototype
> **Licentie-opmerking:** DSM-5 vereist licentie. Dit prototype gebruikt ICD-10 (publiek domein).
---
## 2. Overzicht van de belangrijkste onderdelen
1. **Diagnose Tab** (binnen Intake) — Hoofdlocatie voor diagnose-registratie
2. **ICD-10 Code Zoeken** — Autocomplete met GGZ-subset (~50 codes)
3. **Diagnose Invoer Modal** — Formulier voor nieuwe/bewerken diagnose
4. **Diagnose Detail Card** — Weergave per geregistreerde diagnose
5. *(Optioneel)* **AI Diagnose Assistent** — Suggesties op basis van intake
---
## 3. Userstories (Prototype)
| ID | Rol | Doel / Actie | Verwachte waarde | Prioriteit |
|----|------|---------------|------------------|-------------|
| US-01 | Psycholoog | ICD-10 code zoeken op beschrijving | Snel juiste code vinden | Hoog |
| US-02 | Psycholoog | ICD-10 code zoeken op code (F32) | Direct navigeren bij bekende code | Hoog |
| US-03 | Psycholoog | Hoofddiagnose markeren | Duidelijke prioritering | Hoog |
| US-04 | Psycholoog | Nevendiagnose(s) toevoegen | Comorbiditeit vastleggen | Hoog |
| US-05 | Psycholoog | Ernst classificeren | Behandelniveau bepalen | Hoog |
| US-06 | Psycholoog | DSM-5 referentie toevoegen | Eigen notatie mogelijk | Middel |
| US-07 | Psycholoog | Onderbouwing vastleggen | Klinische redenering documenteren | Middel |
| US-08 | Psycholoog | Diagnose bewerken/verwijderen | Correcties doorvoeren | Hoog |
| US-09 | Systeem | Diagnoses tonen in overdracht | Relevante info voor collega's | Hoog |
---
## 4. Functionele werking per onderdeel
### 4.1 Diagnose Tab (binnen Intake)
**Locatie:** `/epd/patients/[id]/intakes/[intakeId]/diagnosis`
**Schermopbouw:**
```
┌─────────────────────────────────────────────────────────────┐
│ Diagnoses │
│ Registreer DSM-5 diagnoses gekoppeld aan deze intake. │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─ Hoofddiagnose ────────────────────────────────────────┐ │
│ │ F32.1 — Depressieve stoornis, matig [Bewerk] │ │
│ │ Ernst: Matig | Status: Actief | 15 nov 2024 │ │
│ │ "Voldoet aan 6/9 criteria, significant functioneel..." │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Nevendiagnose ────────────────────────────────────────┐ │
│ │ F41.1 — Gegeneraliseerde angststoornis [Bewerk] │ │
│ │ Ernst: Licht | Status: Actief | 15 nov 2024 │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ [+ Nieuwe diagnose] [AI Analyseer intake] │
│ │
└─────────────────────────────────────────────────────────────┘
```
**Functionaliteit:**
**Diagnoselijst:**
- Toont alle diagnoses gekoppeld aan deze intake
- Hoofddiagnose bovenaan met visuele markering (badge/border)
- Per diagnose: code, beschrijving, ernst, status, datum
- Optionele notitie ingeklapt, uitklappen via chevron
- Acties per kaart: Bewerk, Verwijder
**Lege staat:**
- Tekst: "Nog geen diagnoses geregistreerd."
- Prominente [+ Nieuwe diagnose] knop
**Acties:**
- [+ Nieuwe diagnose] → Opent diagnose-invoer modal
- [AI Analyseer intake] → Start AI-analyse, toont suggesties
---
### 4.2 Diagnose Invoer Modal
**Trigger:** Klik op [+ Nieuwe diagnose] of [Bewerk]
**Schermopbouw:**
```
┌─────────────────────────────────────────────────────────────┐
│ Nieuwe diagnose [✕] │
├─────────────────────────────────────────────────────────────┤
│ │
│ ICD-10 Code * │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 🔍 Zoek op code of beschrijving... │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Veelgebruikt ─────────────────────────────────────────┐ │
│ │ F32.1 Matige depressieve episode │ │
│ │ F41.1 Gegeneraliseerde angststoornis │ │
│ │ F43.1 Posttraumatische stressstoornis │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ Ernst * Diagnose type │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ Matig ▼ │ │ ○ Hoofddiagnose │ │
│ └──────────────────────┘ │ ● Nevendiagnose │ │
│ └──────────────────────┘ │
│ │
│ Status │
│ ┌──────────────────────┐ │
│ │ Actief ▼ │ │
│ └──────────────────────┘ │
│ │
│ DSM-5 referentie (optioneel) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Major Depressive Disorder, moderate │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Onderbouwing / Notities │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Patiënt presenteert met sombere stemming, verminderde │ │
│ │ interesse en slaapproblemen sinds 3 maanden... │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ [Annuleren] [Opslaan] │
└─────────────────────────────────────────────────────────────┘
```
**Velden:**
| Veld | Type | Verplicht | Opties/Validatie |
|------|------|-----------|------------------|
| ICD-10 Code | Autocomplete | Ja | Zoeken in ~50 GGZ codes |
| Ernst | Dropdown | Ja | Licht, Matig, Ernstig |
| Diagnose type | Radio | Ja | Hoofddiagnose, Nevendiagnose |
| Status | Dropdown | Ja | Actief, In remissie, Opgelost |
| DSM-5 referentie | Text input | Nee | Vrije tekst voor DSM-5 equivalent |
| Onderbouwing | Textarea | Nee | Max 500 tekens |
**Gedrag:**
- Bij invoer in zoekveld: live filtering van ICD-10 codelijst
- Selectie code: vult automatisch beschrijving in
- Bij wijzigen bestaande: velden voorgevuld
- Validatie: minimaal code + ernst verplicht
- Maximaal 1 hoofddiagnose per intake (toggle andere om bij selectie)
---
### 4.3 ICD-10 Code Zoeken (Inline Autocomplete)
**Trigger:** Focus op code-zoekveld in modal
**Gedrag:**
Voor het prototype gebruiken we een eenvoudige inline autocomplete in plaats van een aparte browser/drawer.
```
┌─────────────────────────────────────────────────────────────┐
│ ICD-10 Code * │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ depre │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ F32.0 Lichte depressieve episode │ │
│ │ F32.1 Matige depressieve episode ← │ │
│ │ F32.2 Ernstige depressieve episode zonder psychose │ │
│ │ F32.3 Ernstige depressieve episode met psychose │ │
│ │ F33.0 Recidiverende depressie, lichte episode │ │
│ │ F33.1 Recidiverende depressie, matige episode │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
**Functionaliteit:**
**Zoeken:**
- Zoekt op code (F32, F41.1) en beschrijving (depressie, angst)
- Client-side filtering van ~50 GGZ codes
- Debounce 200ms
- Max 8 resultaten in dropdown
**Snelkeuze (bij leeg veld):**
- Toon top 5 veelgebruikte GGZ-diagnoses
- Depressie (F32.1), Angst (F41.1), PTSS (F43.1), etc.
**Selectie:**
- Klik of Enter: selecteert code, vult beschrijving in
- Escape: sluit dropdown
---
### 4.4 AI Diagnose Assistent (Optioneel - Post-MVP)
> **Prototype scope:** AI-suggesties zijn optioneel voor de eerste versie. Focus eerst op de handmatige invoer-flow. Onderstaande specificatie is voor een latere iteratie.
**Trigger:** Klik op [AI Analyseer intake]
**Schermopbouw (indien geïmplementeerd):**
```
┌─────────────────────────────────────────────────────────────┐
│ AI Diagnose Suggesties [✕] │
├─────────────────────────────────────────────────────────────┤
│ ⚠️ Dit zijn suggesties ter ondersteuning. De clinicus │
│ neemt altijd de eindbeslissing. │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─ Suggestie 1 ──────────────────────────────────────────┐ │
│ │ F32.1 — Matige depressieve episode │ │
│ │ │ │
│ │ Onderbouwing: │ │
│ │ • "Patiënt meldt al 3 maanden somber te zijn" │ │
│ │ • "Verminderde interesse in dagelijkse activiteiten" │ │
│ │ │ │
│ │ [Overnemen] │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Suggestie 2 ──────────────────────────────────────────┐ │
│ │ F41.1 — Gegeneraliseerde angststoornis │ │
│ │ ... │ │
│ │ [Overnemen] │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
**Vereenvoudigde flow voor prototype:**
- Input: intake-notities + anamnese
- Output: 2-3 ICD-10 suggesties met onderbouwing
- Actie: [Overnemen] opent modal met voorgevulde code
---
### 4.5 Diagnose Overzicht (Post-MVP)
> **Prototype scope:** Patiënt-breed diagnose-overzicht is post-MVP. Voor het prototype zijn diagnoses alleen zichtbaar binnen de intake waar ze zijn geregistreerd.
**Toekomstige locatie:** `/epd/patients/[id]/diagnoses`
Voor nu volstaat de diagnose-tab binnen de intake.
---
### 4.6 Diagnose Detail Card
**Component voor weergave in lijsten:**
```
┌─────────────────────────────────────────────────────────────┐
│ F32.1 — Depressieve stoornis, matig HOOFD [⋮] │
├─────────────────────────────────────────────────────────────┤
│ Ernst: Matig Status: Actief 15 nov 2024 │
├─────────────────────────────────────────────────────────────┤
│ ▼ Onderbouwing │
│ Patiënt voldoet aan 6 van de 9 DSM-5 criteria voor een │
│ depressieve episode. Significant functioneel verlies op │
│ werk en in sociale relaties. │
└─────────────────────────────────────────────────────────────┘
```
**Elementen:**
- Code + beschrijving (altijd zichtbaar)
- Type badge: HOOFD (groen) of geen (nevendiagnose)
- Status badge: kleurcodering per status
- Ernst, status, datum regel
- Onderbouwing: standaard ingeklapt, uitklappen via chevron
- Context menu [⋮]: Bewerk, Status wijzigen, Verwijderen
**Status kleuren:**
| Status | Badge kleur |
|--------|-------------|
| Actief | Groen |
| In remissie | Blauw |
| Opgelost | Grijs |
| Ingevoerd-in-fout | Rood/doorgestreept |
---
## 5. UI-overzicht (visuele structuur)
### Diagnose Tab Layout (Prototype)
```
┌─────────────────────────────────────────────────────────────────────┐
│ [← Terug naar intake] Jan de Vries │
├─────────────────────────────────────────────────────────────────────┤
│ Contacts │ Kindcheck │ Risico │ Anamnese │ Onderzoek │ DIAGNOSE │ Advies │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Diagnoses │
│ Registreer diagnoses gekoppeld aan deze intake. │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ [Diagnose Card - Hoofddiagnose] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ [Diagnose Card - Nevendiagnose] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ [+ Nieuwe diagnose] │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
> **Prototype:** De [AI Analyseer intake] knop is optioneel en kan in een latere iteratie worden toegevoegd.
---
## 6. Interacties met AI (Optioneel - Post-MVP)
> **Prototype scope:** AI-functionaliteit is optioneel voor de eerste versie. Onderstaande tabel beschrijft de beoogde functionaliteit voor een latere iteratie.
| Locatie | AI-actie | Trigger | Output |
|---------|----------|---------|--------|
| Diagnose Tab | Analyseer intake | Klik [AI Analyseer] | 2-3 ICD-10 suggesties met onderbouwing |
**Vereenvoudigde flow:**
1. Gebruiker klikt [AI Analyseer intake]
2. Systeem analyseert intake-notities + anamnese
3. Toont 2-3 ICD-10 suggesties met citaten
4. Gebruiker klikt [Overnemen] → opent modal met voorgevulde code
---
## 7. Gebruikersrollen en rechten (Prototype)
| Rol | Toegang | Acties |
|-----|---------|--------|
| Demo-user | Alle patiënten | Volledig CRUD |
> **Prototype:** Geen rollen-onderscheid. Alle gebruikers hebben volledige toegang tot demo-data.
---
## 8. States en Feedback
### Lege staten
| Context | Weergave |
|---------|----------|
| Geen diagnoses | "Nog geen diagnoses geregistreerd." + [+ Nieuwe diagnose] |
| Geen zoekresultaten | "Geen codes gevonden voor '{query}'" |
### Succes feedback
| Actie | Feedback |
|-------|----------|
| Diagnose opgeslagen | Toast: "Diagnose opgeslagen" |
| Diagnose verwijderd | Toast: "Diagnose verwijderd" |
### Error feedback
| Fout | Weergave |
|------|----------|
| Opslaan mislukt | Inline error |
| Validatiefout | Inline onder veld |
---
## 9. Bijlagen & Referenties
### Gerelateerde documenten
- PRD Diagnose Module v1.1 (`docs/specs/diagnose/prd-diagnose-module-v1.md`)
- FO Screening & Intake (`docs/specs/screening-intake/fo-screening-intake-v1_0.md`)
- UX Stylesheet (`docs/specs/ux-stylesheet.md`)
### Bestaande implementatie
- `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/` — Huidige diagnose-tab
- `app/epd/patients/[id]/intakes/[intakeId]/actions.ts` — Server actions
- `lib/supabase/database.types.ts` — conditions tabel
### Component referenties
- shadcn/ui: Dialog, Command (voor autocomplete), Badge, Card
- Lucide icons: Search, Plus, ChevronDown
### Externe bronnen
- [WHO-FIC Nederland - ICD-10/DSM-5 mapping](https://www.whofic.nl/dsm-5icd-10)
- [ICD-10-GM codelijst](https://www.dimdi.de/dynamic/de/klassifikationen/icd/icd-10-gm/) (publiek domein)
---
*Document laatst bijgewerkt: 11-12-2024*

View File

@@ -0,0 +1,291 @@
# 📄 Product Requirements Document (PRD) Diagnose Module
**Projectnaam:** Diagnose Module - Mini EPD
**Versie:** v1.1
**Datum:** 11-12-2024
**Auteur:** Colin Lit
---
## 1. Doelstelling
🎯 **Doel:** Een diagnosemodule bouwen voor het prototype die psychologen in staat stelt diagnoses gestructureerd vast te leggen met ICD-10 codes (publiek domein) en DSM-5 referenties.
📘 **Toelichting:**
De huidige diagnose-functionaliteit is minimaal: een simpel formulier met handmatige code-invoer. Deze MVP breidt dit uit naar een werkende module met:
- Doorzoekbare **ICD-10 classificatie** (publiek domein, geen licentie nodig)
- DSM-5 equivalent als referentieveld (vrije tekst)
- Meervoudige diagnoses per intake (hoofd- en nevendiagnoses)
- Status tracking (actief, in remissie, opgelost)
- AI-ondersteuning voor diagnose-suggesties
**Type:** Prototype voor demo en validatie.
> **Licentie-opmerking:** DSM-5 classificaties vallen onder licentie van Boom uitgevers. Voor productie is een licentie vereist. Dit prototype gebruikt ICD-10 (WHO, publiek domein) als primaire classificatie.
---
## 2. Doelgroep
🎯 **Primaire doelgroep:**
- **Psychologen / Regiebehandelaren:** Stellen diagnoses en hebben behoefte aan efficiënte classificatie met onderbouwing.
- **Psychiaters:** Valideren diagnoses, voegen specialistische classificaties toe.
📘 **Secundaire doelgroep:**
- **Product Owners & Managers:** Demo van AI-potentieel in diagnostisch proces.
- **Developers:** Referentie-implementatie voor medische classificatiesystemen.
**Persona's:**
> - **Marieke (GZ-psycholoog):** Wil snel DSM-5 codes kunnen vinden zonder handboek. Wil zien welke diagnoses passen bij de intake-bevindingen.
> - **Peter (Psychiater):** Wil comorbiditeit vastleggen met hoofd/nevendiagnose structuur. Heeft behoefte aan differentiaaldiagnostiek.
---
## 3. Kernfunctionaliteiten (MVP-scope)
### 3.1 ICD-10 Classificatie Browser
1. **Doorzoekbare codelijst:** Zoeken op code (F32.1) of beschrijving ("depressieve episode").
2. **Categorie navigatie:** Hiërarchische structuur (Hoofdgroep → Subgroep → Specifieke diagnose).
3. **Snelkeuze:** Veelvoorkomende GGZ-diagnoses (top 30).
### 3.2 Diagnose Registratie
4. **ICD-10 code:** Primaire classificatie (verplicht).
5. **DSM-5 referentie:** Optioneel vrije-tekst veld voor DSM-5 equivalent.
6. **Meervoudige diagnoses:** Hoofd- en nevendiagnoses (primair/secundair markering).
7. **Ernst classificatie:** Licht / Matig / Ernstig.
8. **Status tracking:** Actief / In remissie / Opgelost / Ingevoerd-in-fout.
9. **Notities veld:** Onderbouwing en klinische redenering.
### 3.3 AI-ondersteuning
10. **Diagnose-suggesties:** Op basis van intake-notities en anamnese (ICD-10 codes).
11. **Differentiaal-helper:** Toon vergelijkbare diagnoses met onderscheidende kenmerken.
### 3.4 Integratie
12. **Behandelplan-koppeling:** Diagnoses beschikbaar als input voor behandelplan.
13. **Overdracht-integratie:** Actieve diagnoses in overdrachtsamenvatting.
### *(Stretch / Post-prototype)*
- Volledige DSM-5 integratie (na licentie-afsluiting)
- Diagnose-overzicht patiënt-breed
- Versiebeheer diagnoses
---
## 4. Gebruikersflows (MVP-flows)
### Flow 1: Diagnose toevoegen via zoeken
```
1. Psycholoog opent Diagnose tab binnen intake
2. Klikt [+ Nieuwe diagnose]
3. Zoekt op "depressie" of "F32"
4. Selecteert "F32.1 - Depressieve stoornis, matig"
5. Vult ernst in (dropdown: matig)
6. Markeert als hoofddiagnose (toggle)
7. Voegt optionele notitie toe
8. Klikt [Opslaan]
```
### Flow 2: AI-suggestie gebruiken
```
1. Psycholoog opent Diagnose tab
2. Klikt [AI Analyseer intake]
3. Systeem analyseert intake-notities + anamnese
4. Toont 2-4 diagnose-suggesties met confidence score
5. Per suggestie: onderbouwing uit intake-tekst (citaten)
6. Psycholoog selecteert relevante suggestie(s)
7. Past aan indien nodig → [Opslaan]
```
### Flow 3: Differentiaaldiagnose bekijken
```
1. Bij geselecteerde diagnose (bijv. F41.1 GAD)
2. Klikt [Differentiaal bekijken]
3. Toont gerelateerde diagnoses:
- F41.0 Paniekstoornis
- F43.1 PTSS
- F32.1 Depressie met angstkenmerken
4. Per alternatief: kernverschillen uitgelicht
5. Psycholoog bevestigt of past diagnose aan
```
### Flow 4: Diagnose-overzicht raadplegen
```
1. Psycholoog opent Patiënt dossier
2. Navigeert naar Diagnoses sectie (L2 menu)
3. Ziet overzicht alle diagnoses (actief + historisch)
4. Filter op status: Actief / In remissie / Alle
5. Klik op diagnose → details + gekoppelde intake
```
---
## 5. Niet in Scope (Prototype)
| Feature | Reden |
|---------|-------|
| Volledige DSM-5 classificatie | Licentie vereist (Boom uitgevers) |
| DSM-5 criteria/checklists | Licentiegebonden content |
| Multi-disciplinaire validatie workflow | Complexiteit, geen meerwaarde voor demo |
| Automatische DBC/ZPM-koppeling | Vereist externe integraties |
| Medicatie-diagnose interacties | Buiten scope |
| ICD-11 ondersteuning | Nog niet gangbaar in NL GGZ |
---
## 6. Succescriteria
| Criterium | Meetbaar doel |
|-----------|---------------|
| Code-zoekfunctie | < 3 klikken van zoeken naar selectie |
| AI-suggesties | Relevante suggestie in top-3 bij 80% van intakes |
| Differentiaal | Toon minimaal 2 relevante alternatieven |
| Demo-flow | Volledige diagnose-registratie in < 60 seconden |
| Data-integriteit | Diagnoses correct gekoppeld aan intake + patiënt |
| Overdracht | Actieve diagnoses automatisch in AI-samenvatting |
---
## 7. Risico's & Mitigatie
| Risico | Impact | Mitigatie |
|--------|--------|-----------|
| AI-suggesties onjuist/onvolledig | Hoog | Duidelijke disclaimer, suggesties als hulpmiddel niet als diagnose |
| ICD-10 minder bekend bij GGZ | Laag | Codes zijn identiek aan DSM-5, alleen beschrijvingen verschillen |
| Complexe classificatie UI | Middel | Focus op top 30 GGZ-diagnoses, rest via zoeken |
| Performance bij grote codelijst | Laag | Client-side filtering + debounce |
---
## 8. Roadmap / Vervolg (Post-Prototype)
### Fase 2: DSM-5 Licentie
- Licentie afsluiten met Boom uitgevers
- DSM-5 beschrijvingen en criteria toevoegen
- Volledige DSM-5/ICD-10 mapping
### Fase 3: Verdieping
- Diagnose-overzicht patiënt-breed (over intakes)
- Versiebeheer diagnoses (audittrail)
- Comorbiditeit-visualisatie
### Fase 4: Compliance
- DBC/ZPM declaratie-integratie
- NEN 7510 logging
- Multi-disciplinaire validatie workflow (MDO)
---
## 9. Bijlagen & Referenties
### Bestaande documentatie
- FO Screening & Intake v1.0 (`docs/specs/screening-intake/fo-screening-intake-v1_0.md`)
- TO Mini EPD v1.2 (`docs/specs/to-mini-ecd-v1_2.md`)
- UX Stylesheet (`docs/specs/ux-stylesheet.md`)
- PRD AI Prefill Behandelplan (`docs/specs/ai-integratie/prd-ai-prefill-behandelplan-v1.md`)
### Bestaande implementatie
- `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/` - Huidige diagnose-tab
- `lib/supabase/database.types.ts` - `conditions` tabel definitie
- `app/epd/patients/[id]/intakes/[intakeId]/actions.ts` - CRUD operaties
### Externe referenties
- [WHO-FIC Nederland - ICD-10/DSM-5 mapping](https://www.whofic.nl/dsm-5icd-10)
- [Zorgprestatiemodel - DSM-5 codelijst](https://www.zorgprestatiemodel.nl/aan-de-slag/downloads/)
- [ICD-10-GM codelijst](https://www.dimdi.de/dynamic/de/klassifikationen/icd/icd-10-gm/) (publiek domein)
- FHIR Condition Resource (R4)
---
## 10. Technische Uitgangspunten
### Database (bestaande `conditions` tabel)
```typescript
// Huidige velden (FHIR-inspired)
- code_code: string // ICD-10 code (bijv. "F32.1")
- code_display: string // ICD-10 beschrijving
- code_system: string // 'ICD-10' (primair voor prototype)
- clinical_status: enum // active | remission | resolved
- verification_status: enum // provisional | confirmed | entered-in-error
- severity_code: string
- severity_display: string
- onset_datetime: timestamp
- recorded_date: timestamp
- note: text
- patient_id: uuid
- encounter_id: uuid // Gekoppelde intake
```
### Nieuwe velden (Prototype)
```typescript
- is_primary: boolean // Hoofd- vs nevendiagnose
- dsm5_reference: text // Optioneel: DSM-5 equivalent (vrije tekst)
```
### Statische data (JSON)
```typescript
// lib/data/icd10-ggz-codes.json
// Top ~50 GGZ-relevante ICD-10 codes met Nederlandse beschrijvingen
[
{ "code": "F32.0", "display": "Lichte depressieve episode", "category": "Depressie" },
{ "code": "F32.1", "display": "Matige depressieve episode", "category": "Depressie" },
...
]
```
### API Endpoints
```
GET /api/diagnose/codes?q={search} // Zoek ICD-10 codes (client-side fallback)
POST /api/diagnose/suggest // AI suggesties (optioneel)
```
---
## 11. ICD-10 GGZ Code Subset (Prototype)
Focus op meest voorkomende GGZ-diagnoses (~50 codes). De ICD-10 codes zijn identiek aan DSM-5, alleen de beschrijvingen komen uit de WHO-classificatie (publiek domein).
| Categorie | ICD-10 Codes | Voorbeelden |
|-----------|--------------|-------------|
| **Depressieve stoornissen** | F32.x, F33.x | Depressieve episode (licht/matig/ernstig) |
| **Angststoornissen** | F40.x, F41.x | Sociale fobie, GAD, Paniekstoornis |
| **Trauma/stress** | F43.x | PTSS, Aanpassingsstoornis |
| **OCD** | F42.x | Obsessief-compulsieve stoornis |
| **Persoonlijkheid** | F60.x | Borderline, Antisociaal, Vermijdend |
| **Bipolair** | F31.x | Bipolaire stoornis |
| **ADHD** | F90.x | Aandachtstekortstoornis |
| **Autisme** | F84.x | Autismespectrumstoornis |
| **Eetstoornissen** | F50.x | Anorexia, Boulimia |
> **Opmerking:** Voor productie kunnen de volledige DSM-5 beschrijvingen worden toegevoegd na licentie-afsluiting.
---
## 12. AI Prompt Strategie (Optioneel)
### Diagnose-suggestie prompt
```
Je bent een klinisch ondersteuningssysteem voor GGZ-professionals.
CONTEXT:
- Intake notities: {intakeContent}
- Anamnese: {anamneseContent}
OPDRACHT:
Analyseer de informatie en geef maximaal 3 diagnose-suggesties met ICD-10 codes.
Per suggestie:
1. ICD-10 code en beschrijving
2. Onderbouwing met citaten uit de intake
3. Ernst-indicatie (licht/matig/ernstig)
BELANGRIJK:
- Dit zijn SUGGESTIES ter ondersteuning, geen diagnoses
- De clinicus neemt altijd de eindbeslissing
- Gebruik alleen ICD-10 codes uit de GGZ-subset (F-codes)
```
> **Prototype scope:** AI-suggesties zijn optioneel voor de eerste versie. Focus eerst op de handmatige invoer-flow.
---
*Document laatst bijgewerkt: 11-12-2024*

View File

@@ -0,0 +1,467 @@
# ⚙️ Technisch Ontwerp (TO) Diagnose Module
**Projectnaam:** Diagnose Module - Mini EPD
**Versie:** v1.0
**Datum:** 11-12-2024
**Auteur:** Colin Lit
---
## 1. Doel en relatie met PRD en FO
🎯 **Doel van dit document:**
Het Technisch Ontwerp beschrijft **hoe** de diagnosemodule technisch wordt geïmplementeerd. Dit document vertaalt het FO naar concrete code-structuren, database-wijzigingen en componenten.
📘 **Toelichting:**
De diagnosemodule bouwt voort op de bestaande `conditions` tabel (FHIR-inspired) en breidt de huidige basic UI uit met een doorzoekbare ICD-10 codelijst en verbeterde UX.
**Relatie met documenten:**
- PRD: `docs/specs/diagnose/prd-diagnose-module-v1.md` (v1.1)
- FO: `docs/specs/diagnose/fo-diagnose-module-v1.md` (v1.1)
---
## 2. Technische Architectuur Overzicht
```
┌─────────────────────────────────────────────────────────────────┐
│ Frontend (Next.js) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ DiagnosisTab │───▶│ DiagnosisModal │───▶│ ICD10Search │ │
│ │ (page.tsx) │ │ (Dialog) │ │ (Combobox) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Server Actions (actions.ts) │ │
│ │ • createDiagnosis() • updateDiagnosis() • deleteDiagnosis() │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
└──────────────────────────────┼──────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Supabase (PostgreSQL) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ patients │◀──▶│ conditions │◀──▶│ intakes │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Statische Data (JSON) │
│ │
│ lib/data/icd10-ggz-codes.json (~50 codes, client-side) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## 3. Dependency Analyse
### Bestaande dependencies (reeds aanwezig)
| Dependency | Versie | Gebruik |
|------------|--------|---------|
| `@radix-ui/react-dialog` | ^1.1.15 | Modal voor diagnose invoer |
| `@radix-ui/react-select` | ^2.2.6 | Dropdowns (ernst, status) |
| `lucide-react` | ^0.553.0 | Icons (Search, Plus, Trash) |
| `date-fns` | ^4.1.0 | Datum formatting |
| `zod` | ^4.1.12 | Input validatie |
| `react-hook-form` | ^7.66.1 | Form handling |
| `@hookform/resolvers` | ^5.2.2 | Zod resolver |
### Nieuwe dependency (toe te voegen)
| Dependency | Versie | Gebruik | Alternatief |
|------------|--------|---------|-------------|
| `cmdk` | ^1.0.0 | Autocomplete/Combobox voor ICD-10 zoeken | Custom met Radix Popover |
**Aanbeveling:** Voeg `cmdk` toe voor de autocomplete functionaliteit. Dit is de standaard voor shadcn/ui Command component.
```bash
pnpm add cmdk
```
**Alternatief:** Bouw custom autocomplete met bestaande `@radix-ui/react-popover` + input. Minder features maar geen extra dependency.
---
## 4. Database Schema
### Bestaande `conditions` tabel (geen wijzigingen nodig)
De huidige `conditions` tabel is al FHIR-compliant en bevat alle benodigde velden:
```sql
-- Bestaande tabel (lib/supabase/database.types.ts:291-369)
conditions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
patient_id UUID NOT NULL REFERENCES patients(id),
encounter_id UUID REFERENCES intakes(id), -- Gekoppelde intake
-- ICD-10/DSM-5 classificatie
code_code TEXT NOT NULL, -- "F32.1"
code_display TEXT NOT NULL, -- "Matige depressieve episode"
code_system TEXT DEFAULT 'ICD-10', -- "ICD-10" of "DSM-5"
-- Status (FHIR enums)
clinical_status condition_clinical_status DEFAULT 'active',
-- active | recurrence | relapse | inactive | remission | resolved
verification_status condition_verification_status DEFAULT 'confirmed',
-- unconfirmed | provisional | differential | confirmed | refuted | entered-in-error
-- Ernst
severity_code TEXT, -- "mild" | "moderate" | "severe"
severity_display TEXT, -- "Licht" | "Matig" | "Ernstig"
-- Timing
onset_datetime TIMESTAMPTZ,
recorded_date DATE DEFAULT CURRENT_DATE,
-- Extra
note TEXT, -- Onderbouwing
category TEXT DEFAULT 'encounter-diagnosis',
-- Metadata
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
```
### Optionele schema-uitbreiding (later)
Voor de toekomst kunnen deze velden worden toegevoegd via migratie:
```sql
-- Optioneel: nieuwe velden voor uitgebreide functionaliteit
ALTER TABLE conditions ADD COLUMN IF NOT EXISTS is_primary BOOLEAN DEFAULT false;
ALTER TABLE conditions ADD COLUMN IF NOT EXISTS dsm5_reference TEXT;
```
**Besluit:** Voor het prototype gebruiken we de bestaande velden. `is_primary` kan worden afgeleid uit volgorde of in `note` worden vastgelegd.
---
## 5. Statische ICD-10 Data
### Bestandslocatie
```
lib/data/icd10-ggz-codes.json
```
### Data structuur
```typescript
// lib/types/icd10.ts
export interface ICD10Code {
code: string; // "F32.1"
display: string; // "Matige depressieve episode"
category: string; // "Depressie"
keywords?: string[]; // ["depressief", "somber", "neerslachtig"]
}
export interface ICD10Category {
name: string;
codes: ICD10Code[];
}
```
### Voorbeeld data (~50 codes)
```json
{
"version": "ICD-10-GM 2024",
"source": "WHO (publiek domein)",
"categories": [
{
"name": "Depressieve stoornissen",
"codes": [
{ "code": "F32.0", "display": "Lichte depressieve episode", "keywords": ["depressie", "licht"] },
{ "code": "F32.1", "display": "Matige depressieve episode", "keywords": ["depressie", "matig"] },
{ "code": "F32.2", "display": "Ernstige depressieve episode zonder psychotische kenmerken", "keywords": ["depressie", "ernstig"] },
{ "code": "F32.3", "display": "Ernstige depressieve episode met psychotische kenmerken", "keywords": ["depressie", "psychose"] },
{ "code": "F33.0", "display": "Recidiverende depressieve stoornis, huidige episode licht", "keywords": ["recidiverend"] },
{ "code": "F33.1", "display": "Recidiverende depressieve stoornis, huidige episode matig", "keywords": ["recidiverend"] },
{ "code": "F33.2", "display": "Recidiverende depressieve stoornis, huidige episode ernstig", "keywords": ["recidiverend"] }
]
},
{
"name": "Angststoornissen",
"codes": [
{ "code": "F40.0", "display": "Agorafobie", "keywords": ["angst", "plein", "open ruimte"] },
{ "code": "F40.1", "display": "Sociale fobie", "keywords": ["sociaal", "angst", "vermijding"] },
{ "code": "F40.2", "display": "Specifieke fobie", "keywords": ["fobie", "specifiek"] },
{ "code": "F41.0", "display": "Paniekstoornis", "keywords": ["paniek", "aanval"] },
{ "code": "F41.1", "display": "Gegeneraliseerde angststoornis", "keywords": ["gad", "piekeren", "angst"] },
{ "code": "F41.2", "display": "Gemengde angststoornis en depressieve stoornis", "keywords": ["gemengd"] }
]
},
{
"name": "Trauma- en stressorgerelateerde stoornissen",
"codes": [
{ "code": "F43.0", "display": "Acute stressreactie", "keywords": ["stress", "acuut"] },
{ "code": "F43.1", "display": "Posttraumatische stressstoornis", "keywords": ["ptss", "trauma"] },
{ "code": "F43.2", "display": "Aanpassingsstoornis", "keywords": ["aanpassing", "stress"] }
]
}
]
}
```
---
## 6. Component Structuur
### Bestandsstructuur
```
app/epd/patients/[id]/intakes/[intakeId]/diagnosis/
├── page.tsx # Server component (bestaand)
└── components/
├── diagnosis-manager.tsx # Refactor: lijst + modal trigger
├── diagnosis-card.tsx # Nieuwe: diagnose weergave card
├── diagnosis-modal.tsx # Nieuwe: invoer/bewerk modal
└── icd10-combobox.tsx # Nieuwe: autocomplete zoeken
lib/data/
└── icd10-ggz-codes.json # Statische codelijst
lib/types/
└── icd10.ts # TypeScript types
```
### Component specificaties
#### 1. `DiagnosisModal` (nieuw)
```typescript
// components/diagnosis-modal.tsx
interface DiagnosisModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
patientId: string;
intakeId: string;
diagnosis?: Condition; // undefined = nieuw, anders = bewerk
}
// Features:
// - Dialog wrapper (Radix)
// - Form met react-hook-form + zod
// - ICD10Combobox voor code selectie
// - Dropdowns voor ernst/status
// - Textarea voor onderbouwing
```
#### 2. `ICD10Combobox` (nieuw)
```typescript
// components/icd10-combobox.tsx
interface ICD10ComboboxProps {
value: string;
onSelect: (code: ICD10Code) => void;
placeholder?: string;
}
// Features:
// - cmdk Command component
// - Client-side filtering op code + display + keywords
// - Debounce 200ms
// - Max 8 resultaten
// - Snelkeuze bij leeg veld (top 5)
```
#### 3. `DiagnosisCard` (nieuw)
```typescript
// components/diagnosis-card.tsx
interface DiagnosisCardProps {
diagnosis: Condition;
isPrimary?: boolean;
onEdit: () => void;
onDelete: () => void;
}
// Features:
// - Code + beschrijving
// - Ernst + status badges
// - Datum
// - Expand/collapse voor onderbouwing
// - Context menu (bewerk, verwijder)
```
---
## 7. Server Actions Refactor
### Huidige actions (aanpassen)
```typescript
// app/epd/patients/[id]/intakes/[intakeId]/actions.ts
// Bestaand - werkt, kleine aanpassing code_system
export async function createDiagnosis(payload: DiagnosisPayload) {
const supabase = await getSupabase();
const { error } = await supabase.from('conditions').insert({
patient_id: payload.patientId,
encounter_id: payload.intakeId,
code_code: payload.code,
code_display: payload.description,
code_system: 'ICD-10', // Wijzig van 'DSM-5' naar 'ICD-10'
clinical_status: payload.status || 'active',
severity_display: payload.severity || null,
note: payload.notes,
recorded_date: new Date().toISOString(),
});
// ...
}
// Nieuw - update functie
export async function updateDiagnosis(
diagnosisId: string,
payload: Partial<DiagnosisPayload>
) {
const supabase = await getSupabase();
const { error } = await supabase
.from('conditions')
.update({
code_code: payload.code,
code_display: payload.description,
clinical_status: payload.status,
severity_display: payload.severity,
note: payload.notes,
updated_at: new Date().toISOString(),
})
.eq('id', diagnosisId);
// ...
}
```
### Uitgebreide payload type
```typescript
export interface DiagnosisPayload {
patientId: string;
intakeId: string;
code: string;
description: string;
severity?: 'licht' | 'matig' | 'ernstig';
status?: 'active' | 'remission' | 'resolved' | 'entered-in-error';
notes?: string;
dsm5Reference?: string; // Optioneel vrije tekst veld
}
```
---
## 8. Zod Validatie Schema
```typescript
// lib/schemas/diagnosis.ts
import { z } from 'zod';
export const diagnosisSchema = z.object({
code: z.string()
.min(1, 'ICD-10 code is verplicht')
.regex(/^F\d{2}(\.\d{1,2})?$/, 'Ongeldige ICD-10 code'),
description: z.string()
.min(1, 'Beschrijving is verplicht')
.max(200, 'Beschrijving mag maximaal 200 tekens zijn'),
severity: z.enum(['licht', 'matig', 'ernstig']),
status: z.enum(['active', 'remission', 'resolved', 'entered-in-error'])
.default('active'),
notes: z.string()
.max(500, 'Onderbouwing mag maximaal 500 tekens zijn')
.optional(),
dsm5Reference: z.string()
.max(100, 'DSM-5 referentie mag maximaal 100 tekens zijn')
.optional(),
});
export type DiagnosisFormData = z.infer<typeof diagnosisSchema>;
```
---
## 9. Implementatie Stappenplan
### Fase 1: Data & Types (1-2 uur)
1. Creëer `lib/data/icd10-ggz-codes.json` met ~50 codes
2. Creëer `lib/types/icd10.ts` met TypeScript types
3. Creëer `lib/schemas/diagnosis.ts` met Zod schema
### Fase 2: Componenten (3-4 uur)
4. Installeer `cmdk` dependency
5. Creëer `ICD10Combobox` component
6. Creëer `DiagnosisModal` component
7. Creëer `DiagnosisCard` component
### Fase 3: Integratie (2 uur)
8. Refactor `diagnosis-manager.tsx` naar nieuwe componenten
9. Update server actions (ICD-10, update functie)
10. Test flows: toevoegen, bewerken, verwijderen
### Fase 4: Polish (1 uur)
11. Lege staten en error handling
12. Loading states
13. Toast feedback
---
## 10. Testen
### Handmatige test scenario's
| # | Scenario | Verwacht resultaat |
|---|----------|-------------------|
| 1 | Zoek "depressie" | Toont F32.x codes |
| 2 | Zoek "F41" | Toont angststoornissen |
| 3 | Selecteer code | Vult beschrijving automatisch |
| 4 | Opslaan zonder code | Validatiefout |
| 5 | Bewerk bestaande | Modal met voorgevulde waarden |
| 6 | Verwijder diagnose | Bevestiging + toast |
| 7 | Leeg veld | Toont top 5 snelkeuze |
### Build verificatie
```bash
pnpm build # Moet slagen zonder type errors
```
---
## 11. Risico's & Mitigatie
| Risico | Impact | Mitigatie |
|--------|--------|-----------|
| cmdk bundle size | Laag | ~10KB gzipped, acceptabel |
| ICD-10 codes incompleet | Laag | Start met 50, uitbreiden op aanvraag |
| Performance filtering | Laag | 50 codes is instant client-side |
| Bestaande data breekt | Middel | Backward compatible, DSM-5 data blijft werken |
---
## 12. Bijlagen & Referenties
### Projectdocumenten
- PRD: `docs/specs/diagnose/prd-diagnose-module-v1.md`
- FO: `docs/specs/diagnose/fo-diagnose-module-v1.md`
### Bestaande code
- `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/` — Huidige implementatie
- `app/epd/patients/[id]/intakes/[intakeId]/actions.ts` — Server actions
- `lib/supabase/database.types.ts` — Database types
### Externe referenties
- [cmdk documentation](https://cmdk.paco.me/)
- [shadcn/ui Command](https://ui.shadcn.com/docs/components/command)
- [ICD-10-GM 2024](https://www.dimdi.de/dynamic/de/klassifikationen/icd/icd-10-gm/)
---
*Document laatst bijgewerkt: 11-12-2024*

View File

@@ -0,0 +1,195 @@
# Diagnose Module - Implementatieplan
## Overzicht
Implementatie van een verbeterde diagnosemodule voor het Mini-EPD prototype met:
- ICD-10 classificatie (publiek domein, geen licentie nodig)
- Autocomplete zoekfunctionaliteit
- Consistente UX/UI volgens bestaande EPD patterns
## Documentatie Status ✅
- [x] PRD v1.1 - `docs/specs/diagnose/prd-diagnose-module-v1.md`
- [x] FO v1.1 - `docs/specs/diagnose/fo-diagnose-module-v1.md`
- [x] TO v1.0 - `docs/specs/diagnose/to-diagnose-module-v1.md`
- [x] UX/UI Specificaties (zie hieronder)
---
## UX/UI Design Beslissingen
### Kleurenschema (conform ux-stylesheet.md)
| Element | Kleur | Hex |
|---------|-------|-----|
| Primary action (knoppen) | Teal | `#0D9488` (teal-600) |
| Borders | Slate | `#E2E8F0` (slate-200) |
| Text primary | Slate | `#0F172A` (slate-900) |
| Text secondary | Slate | `#64748B` (slate-500) |
| Error | Red | `#DC2626` |
| Success toast | Green | `#16A34A` |
### Badge Kleuren (Ernst/Status)
| Type | Achtergrond | Tekst |
|------|-------------|-------|
| Ernst: Licht | `#E5E7EB` | `#374151` |
| Ernst: Matig | `#FEF3C7` | `#92400E` |
| Ernst: Ernstig | `#FEE2E2` | `#991B1B` |
| Status: Actief | `#ECFDF5` | `#16A34A` |
| Status: In remissie | `#EFF6FF` | `#3B82F6` |
| Status: Opgelost | `#F1F5F9` | `#64748B` |
| HOOFD badge | `#0D9488` | `#FFFFFF` |
### Component Patterns (hergebruik bestaande)
- **Card layout**: Zoals `anamnese-manager.tsx` en `risk-manager.tsx`
- **Modal/Dialog**: Zoals `appointment-modal.tsx`
- **Form styling**: Bestaande input/select classes
- **Empty state**: Zoals `intake-list.tsx`
---
## Implementatie Stappenplan
### Epic 1: Data & Types (~1 uur)
**Story 1.1: ICD-10 Codelijst JSON**
```
lib/data/icd10-ggz-codes.json
```
- ~50 meest voorkomende GGZ codes
- Categorieën: Depressie, Angst, Trauma, OCD, Persoonlijkheid, etc.
- Velden: code, display, category, keywords
**Story 1.2: TypeScript Types**
```
lib/types/icd10.ts
```
- ICD10Code interface
- ICD10Category interface
**Story 1.3: Zod Validatie Schema**
```
lib/schemas/diagnosis.ts
```
- diagnosisSchema met code, severity, status validatie
---
### Epic 2: UI Componenten (~3-4 uur)
**Story 2.1: Installeer cmdk**
```bash
pnpm add cmdk
```
**Story 2.2: ICD10Combobox Component**
```
app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/icd10-combobox.tsx
```
- Autocomplete met cmdk
- Client-side filtering
- Snelkeuze bij leeg veld
- Keyboard navigatie
**Story 2.3: DiagnosisCard Component**
```
app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-card.tsx
```
- Code + beschrijving header
- Ernst/Status/Datum badges
- HOOFD badge voor hoofddiagnose
- Expandable onderbouwing
- Bewerk/Verwijder acties
**Story 2.4: DiagnosisModal Component**
```
app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-modal.tsx
```
- Dialog wrapper
- ICD10Combobox integratie
- Ernst dropdown (Licht/Matig/Ernstig)
- Status dropdown (Actief/In remissie/Opgelost)
- Type radio (Hoofd/Nevendiagnose)
- DSM-5 referentie tekstveld (optioneel)
- Onderbouwing textarea
- Validatie met zod
---
### Epic 3: Integratie (~2 uur)
**Story 3.1: Refactor DiagnosisManager**
```
app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-manager.tsx
```
- Vervang inline form door modal trigger
- Integreer DiagnosisCard voor lijst
- Lege staat met dashed border
- + Nieuwe diagnose knop
**Story 3.2: Update Server Actions**
```
app/epd/patients/[id]/intakes/[intakeId]/actions.ts
```
- Wijzig code_system naar 'ICD-10'
- Voeg updateDiagnosis() functie toe
- Uitbreid DiagnosisPayload type
**Story 3.3: Toast Integratie**
- Succes toast bij opslaan
- Succes toast bij verwijderen
- Error handling
---
### Epic 4: Polish (~1 uur)
**Story 4.1: Empty State**
- Dashed border container
- Icon + tekst
- Prominente CTA knop
**Story 4.2: Loading States**
- Button spinner bij opslaan
- Disabled state tijdens transitie
**Story 4.3: Validatie Feedback**
- Inline errors onder velden
- Focus op eerste error veld
---
## Kritieke Bestanden
### Te wijzigen
- `app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/diagnosis-manager.tsx`
- `app/epd/patients/[id]/intakes/[intakeId]/actions.ts`
### Nieuw aan te maken
- `lib/data/icd10-ggz-codes.json`
- `lib/types/icd10.ts`
- `lib/schemas/diagnosis.ts`
- `app/epd/.../diagnosis/components/icd10-combobox.tsx`
- `app/epd/.../diagnosis/components/diagnosis-card.tsx`
- `app/epd/.../diagnosis/components/diagnosis-modal.tsx`
### Dependencies
- `cmdk` (toe te voegen)
---
## Acceptatiecriteria
1. **Zoekfunctie**: Zoeken op "depressie" toont F32.x codes binnen 200ms
2. **Code selectie**: Selecteren vult beschrijving automatisch in
3. **Validatie**: Opslaan zonder code toont inline error
4. **CRUD**: Toevoegen, bewerken, verwijderen werkt correct
5. **Badges**: Ernst en status tonen correcte kleuren
6. **Hoofddiagnose**: Maximaal 1 per intake, duidelijk gemarkeerd
7. **Build**: `pnpm build` slaagt zonder errors
---
## Geschatte Doorlooptijd
- Epic 1: 1 uur
- Epic 2: 3-4 uur
- Epic 3: 2 uur
- Epic 4: 1 uur
- **Totaal: ~7-8 uur**