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 |