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:
768
docs/specs/diagnose/bouwplan-diagnose-module-v1.md
Normal file
768
docs/specs/diagnose/bouwplan-diagnose-module-v1.md
Normal 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 |
|
||||
397
docs/specs/diagnose/fo-diagnose-module-v1.md
Normal file
397
docs/specs/diagnose/fo-diagnose-module-v1.md
Normal 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*
|
||||
291
docs/specs/diagnose/prd-diagnose-module-v1.md
Normal file
291
docs/specs/diagnose/prd-diagnose-module-v1.md
Normal 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*
|
||||
467
docs/specs/diagnose/to-diagnose-module-v1.md
Normal file
467
docs/specs/diagnose/to-diagnose-module-v1.md
Normal 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*
|
||||
195
docs/specs/diagnose/vectorized-brewing-stearns.md
Normal file
195
docs/specs/diagnose/vectorized-brewing-stearns.md
Normal 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**
|
||||
Reference in New Issue
Block a user