swift-cortex: technisch datamodel instroom/intake + ER-diagrammen #1

Merged
colin merged 19 commits from swift-cortex into main 2026-07-29 08:07:11 +02:00
3 changed files with 717 additions and 20 deletions
Showing only changes of commit 37beef14be - Show all commits

View File

@@ -60,7 +60,9 @@ Het datamodel ontwerpen we volledig op eigen termen, vanuit de feitzinnen. FHIR,
- **openEHR**: nemen we niet over; alleen de ontwerples "stabiele kern als schema, veranderlijke inhoud als data" — die al in het Triqura-architectuurdocument stond (ADR-03).
- **Aandachtspunt** (geen regel): drijf semantisch niet nodeloos af van wat de Nederlandse zorg onder een begrip verstaat — dat houdt een eventuele adapter later goedkoop.
## 5. Scope ronde 1: instroomflow
## 5. Scope ronde 1: instroom t/m behandelplan
**Scopeverbreding (sessie 17 juli 2026):** ronde 1 loopt van aanmelding t/m het opstellen van het behandelplan — dus inclusief wachtlijstbeheer (§5.3), diagnose stellen (§5.4) en behandelplan opstellen (§5.5). Agenda en rapportage & overdracht blijven latere rondes.
### 5.0 Besluiten basis (sessie 16 juli, Colin)
@@ -96,26 +98,101 @@ Het datamodel ontwerpen we volledig op eigen termen, vanuit de feitzinnen. FHIR,
6. **Wie de status mag zetten blijft open** — rollen/disciplines zijn nog niet gemodelleerd; komt terug in die ronde.
7. **Verwijsbrief blijft een nudge, geen harde schema-eis.** Ontbrekende verwijzing wordt een protocolregel (Nudge Engine), met severity die kan verschillen per financieringtype/regelgeving (bijv. `blokkade` bij Zvw-huisartsroute, `signaal` bij Wmo/Jeugdwet). Een beschikking telt ook als verwijzing: waardelijst `verwijsdocument_type` (verwijsbrief, beschikking, ...) i.p.v. één vast veld.
8. **Cliëntportaaltoegang als losse entiteit `CLIENTPORTAAL_ACCOUNT`**, 1-op-0..1 op CLIENT (niet elke cliënt heeft portaaltoegang; een persoon zonder cliëntrol kan sowieso geen portaalaccount hebben). Authenticatiedetails (e-mail, provider-koppeling, status uitgenodigd/actief/geblokkeerd) werken we pas uit in de auth/ADM-ronde — hier alleen de relatie vastgelegd zodat de entiteitenkaart klopt.
9. **ZORGEPISODE is een eigen entiteit** tussen aanmelding en de klinische records. De AANMELDING is de binnenkomst-*gebeurtenis* (verwijzer, hulpvraag, besluit); de ZORGEPISODE is de *periode van zorg* die bij uitkomst "intake" start. Aan de episode hangen: intakes (regulier én intern), diagnoses, behandelplannen en de behandelwachttijd. Bij de aanmelding blijven: screening en aanmeldwachttijd. Een afgewezen aanmelding heeft nooit een episode. Sluit straks aan op het ZPM-zorgtraject (declaratie-ronde). Open detail: ontstaat de episode al bij uitkomst "wachtlijst", of pas bij "intake"?
**Open idee, nog geen besluit:** mogelijk krijgt ook een verwijzer toegang tot de status van zijn verwijzingen (verwijzersportaal, analoog aan `CLIENTPORTAAL_ACCOUNT` maar dan op VERWIJZER). Nog niet uitgewerkt en niet in de entiteitenkaart opgenomen — apart onderwerp voor een volgende ronde als dit een echte behoefte blijkt.
Aanmelding → screening → intake. Dit is de eerste rebuild-module én de TIP-proefflow. Latere rondes: diagnose & behandeltraject, agenda, rapportage & overdracht.
### 5.2 Feitzinnen screening & intake (volgende ronde — nog te bespreken)
### 5.2 Feitzinnen screening & intake (herzien na sessie 17 juli)
1. *Voor de aanmelding van Jan de Vries is op 15 juli 2026 een screening gestart.*
2. *Screeningsactiviteit "telefonisch contact" is op 16 juli 2026 uitgevoerd door verpleegkundige K. Jansen.*
3. *Het screeningsbesluit voor de aanmelding van Jan de Vries luidt "geschikt voor afdeling Volwassenen".*
4. *Voor cliënt Jan de Vries is op 20 juli 2026 een intake gestart op afdeling Volwassenen.*
5. *De intake van Jan de Vries heeft status "bezig".*
6. *Het intakegesprek van 22 juli 2026 is gevoerd door psycholoog M. de Boer.*
7. *De kindcheck voor de intake van Jan de Vries is uitgevoerd met uitkomst "geen minderjarige kinderen".*
8. *Verslag X is op 22 juli 2026 geschreven door M. de Boer.* / *Verslag Y is gegenereerd door AI-model Z op basis van bronnen A en B, en bevestigd door M. de Boer.*
2. *Bij de screening is op 16 juli 2026 een activiteit van type "telefonisch contact" geregistreerd door verpleegkundige K. Jansen, met toelichting "huisarts gesproken over medicatiehistorie".*
3. *Het screeningsbesluit voor de aanmelding luidt "geschikt", met geadviseerde afdeling Volwassenen, genomen op 17 juli 2026.*
4. *Op basis van de aanmelding van Jan de Vries is op 20 juli 2026 een intake gestart op afdeling Volwassenen, met aanleiding "regulier".*
5. *De intake heeft status "bezig".*
6. *Contactmoment van type "intakegesprek" op 22 juli 2026 is gevoerd door psycholoog M. de Boer.*
7. *De kindcheck voor de intake is op 22 juli 2026 uitgevoerd: thuiswonende kinderen: nee.*
8. *De intake is op 30 juli 2026 afgerond met uitkomst "in zorg".*
9. *Verslag X is op 22 juli 2026 geschreven door M. de Boer.* / *Verslag Y is gegenereerd door AI-model Z op basis van bronnen A en B, en bevestigd door M. de Boer.*
Vragen voor die ronde:
- Is een screening verplicht vóór elke intake, of kan die worden overgeslagen (bijv. bij crisis)?
- Wat maakt een intake "afgerond" — en wie mag dat besluiten?
- Welke afdelingen bestaan er echt (screening bood er 5, intake accepteerde er 3)?
**Bevindingen prototype (verkenning 17 juli 2026):**
- Afdelingen: drie onderling inconsistente hardcoded lijsten screening biedt er 6 (incl. FACT, Verslaving), intake accepteert er 3 (andere labels: "Jeugd" vs "Jeugd (< 18 jaar)"), behandeladvies heeft een vierde lijst plus 4 "zorgprogramma's" (Algemeen GGZ, FACT, Verslaving, Trauma). FACT is op de ene plek afdeling, op de andere zorgprogramma.
- Screeningsactiviteiten zijn nu vrije tekst zonder typering; contactmomenten in de intake hebben wél een typed lijst (Intakegesprek, Aanvullend onderzoek, Telefonisch contact, Huisbezoek, Overig).
- Screeningsbesluit: `geschikt`/`niet_geschikt` + afdeling als vrije string.
- Kindcheck is geen enkele uitkomstwaarde maar drie ja/nee-vlaggen + tekst (thuiswonende kinderen?, zorgen over veiligheid?, actie ondernomen?).
- Intake afronden loopt via de behandeladvies-tab: checkbox + verplichte vervolgkeuze `in_zorg`/`doorverwijzing`/`extra_diagnostiek`, zet status `afgerond` + einddatum. Statussen: alleen `bezig`/`afgerond`.
**Besluiten (sessie 17 juli 2026, Colin):**
1. **Intake hangt aan de ZORGEPISODE** (aanvankelijk aan de aanmelding gemodelleerd; herzien met besluit §5.1 #9), niet direct aan de cliënt. Eén episode kan **meerdere intakes** hebben: naast de reguliere intake bestaan er interne intakes binnen een lopende episode (bijv. overgang naar een andere afdeling). De intake krijgt een **aanleiding** uit een waardelijst (regulier / intern / crisis — lijst te bevestigen).
2. **AFDELING en ZORGPROGRAMMA zijn twee aparte waardelijsten.** Afdeling = organisatorische eenheid (Volwassenen, Jeugd, Ouderen, Forensisch, ...), zorgprogramma = inhoudelijk aanbod (FACT, Verslaving, Trauma, ...). FACT is een programma, geen afdeling. Welke afdelingen echt bestaan is per instelling configureerbaar — waardelijst, geen hardcoded lijst.
3. **Screeningsactiviteiten krijgen een type uit een waardelijst + vrije toelichting** (telefonisch contact, dossieronderzoek, vragenlijst, overig — startlijst te bevestigen). Maakt nudges mogelijk ("nog geen contact geweest bij deze screening").
4. **Screening vóór intake is een nudge, geen harde eis** — zelfde patroon als de verwijsbrief. Interne intakes en crisis maken een harde volgorde-eis onhoudbaar; hooguit een protocolregel bij de eerste intake van een episode.
**Open vragen voor een volgende ronde:**
- Verhouding screeningsbesluit ↔ aanmelding-uitkomst: "geschikt" (screening) en uitkomst "intake" (aanmelding) overlappen — is het besluit hetzelfde feit als de uitkomst, of twee aparte feiten?
- Intake-uitkomstwaarden bevestigen: `in_zorg` / `doorverwijzing` / `extra_diagnostiek` (nu uit het prototype overgenomen).
- Kindcheck: gestructureerde velden zoals het prototype (drie ja/nee-vlaggen + tekst) aanhouden, of anders?
- Wie mag een intake afronden → rollenronde.
- Verslagen (feitzin 9, provenance) → rapportage-ronde; de provenance-spelregel (3.1 #2) ligt al vast.
### 5.3 Feitzinnen wachtlijstbeheer (startlijst — te corrigeren)
Wachtlijst bestaat niet in het prototype (geen tabel, geen scherm) — alleen als roadmap-idee (prioriteit `spoed`/`normaal`/`laag`, wachtdagen, Treeknorm-nudges). We ontwerpen dit vanaf nul. Aanmelding-uitkomst `wachtlijst` bestaat al (§5.1 besluit 5); de vraag is wat daarachter zit.
1. *De aanmelding van Jan de Vries is op 18 juli 2026 op de wachtlijst geplaatst voor afdeling Volwassenen.*
2. *De wachtlijstplaatsing heeft prioriteit "normaal".*
3. *De wachttijd van de plaatsing telt vanaf de aanmelddatum 14 juli 2026.*
4. *De wachtlijstplaatsing is op 20 augustus 2026 beëindigd met reden "intake gestart".*
5. *(nudge) Bij overschrijding van de Treeknorm voor aanmeldwachttijd volgt een signaal.*
**Besluit (sessie 17 juli 2026, Colin):** WACHTLIJSTPLAATSING wordt een **eigen entiteit** (afdeling, prioriteit, begin/eind, beëindigingsreden), inzetbaar op **twee momenten**: vóór de intake (aanmeldwachttijd) én na de intake wachtend op behandeling (behandelwachttijd) — sluit aan op de Treeknormen die beide kennen. Soort plaatsing als waardelijst (`aanmeld`/`behandel`). Met besluit §5.1 #9: de aanmeldwachttijd hangt aan de AANMELDING, de behandelwachttijd aan de ZORGEPISODE.
**Nog open:**
- Wachtlijst per afdeling, per zorgprogramma, of beide?
- Welke beëindigingsredenen: intake gestart / behandeling gestart / doorverwezen / cliënt trekt zich terug / ...?
### 5.4 Feitzinnen diagnose stellen (startlijst — te corrigeren)
Bevinding prototype: de module heet DSM-5 maar registreert feitelijk **ICD-10 F-codes** (`code_system: 'ICD-10'`, regex `F##.#`); "DSM-5" is een optioneel vrijetekstveld. Werkdiagnose-vs-definitief (FHIR `verification_status`) zit in de tabel maar de UI gebruikt het niet. Velden nu: ernst `licht`/`matig`/`ernstig`, type hoofd-/nevendiagnose, status `active`/`remission`/`resolved`/`inactive`. Diagnose hangt in het prototype aan de intake.
1. *Voor de zorgepisode van Jan de Vries is op 24 juli 2026 diagnose F32.1 "matige depressieve episode" geregistreerd door psycholoog M. de Boer, gesteld tijdens de intake van 22 juli.*
2. *Diagnose F32.1 is de hoofddiagnose.*
3. *Diagnose F32.1 heeft ernst "matig".*
4. *Diagnose F32.1 is een werkdiagnose.* / *Diagnose F32.1 is op 30 juli 2026 definitief vastgesteld.*
5. *Diagnose F32.1 heeft status "actief".*
6. *Diagnose F32.1 is op 1 december 2026 in remissie verklaard.*
**Besluiten (sessie 17 juli 2026, Colin):**
1. **DSM-5-TR is de primaire classificatie, met ICD-10-mapping** voor declaratie/uitwisseling. Behandelaren registreren in DSM-termen (bronregistratie), de ICD-10-code wordt afgeleid via een mappingtabel — geen dubbele handmatige invoer. (Het prototype deed het omgekeerd: ICD-10 als registratie, DSM als vrije tekst.)
2. **De diagnose hangt aan de ZORGEPISODE** (besluit §5.1 #9), niet aan de intake. De diagnose overleeft de intake en wordt tijdens de behandeling bijgesteld; de intake waarin hij gesteld is wordt als herkomst vastgelegd (optionele verwijzing), niet als eigenaar.
**Nog open:**
- Werkdiagnose vs. definitief: aparte status-as naast klinische status (actief/remissie/opgelost) — voorlopig zo gemodelleerd (verificatiestatus + klinische status), bevestigen.
- "Max één hoofddiagnose" (spelregel §3.1 #7): per wat — per episode, per moment in de tijd?
- Wie mag een diagnose (definitief) stellen → rollenronde (regiebehandelaar).
### 5.5 Feitzinnen behandelplan opstellen (startlijst — te corrigeren)
Bevinding prototype: module gestript (AI-generatie negeerde diagnose/ernst), maar het typemodel is bekend: behandelstructuur (duur, frequentie, vorm), SMART-doelen (1-6, met cliëntversie in B1-taal, leefgebied, prioriteit), interventies (1-5, gekoppeld aan doelen), sessieplanning, evaluatiemomenten, veiligheidsplan (bij ernstige diagnose), leefgebieden-scores (7 domeinen, 0-10). Statussen waren inconsistent per laag (TS: `concept/actief/in_evaluatie/afgerond/gearchiveerd`; DB: `draft/active/on-hold/revoked/completed`).
1. *Voor de zorgepisode van Jan de Vries is op 1 augustus 2026 een behandelplan opgesteld door M. de Boer.*
2. *Het behandelplan heeft status "concept".*
3. *Het behandelplan is gebaseerd op de intake van 20 juli 2026 en adresseert diagnose F32.1.*
4. *Het behandelplan bevat behandeldoel "weer drie nachten per week doorslapen" met prioriteit hoog en beoogde termijn 12 weken.*
5. *Behandeldoel X heeft een cliëntversie in B1-taal.*
6. *Aan behandeldoel X is interventie "CGT" gekoppeld.*
7. *Het behandelplan kent een evaluatiemoment in week 6.*
8. *Cliënt Jan de Vries heeft op 5 augustus 2026 ingestemd met het behandelplan.*
9. *Behandelplanversie 2 vervangt versie 1 per 15 september 2026.*
**Besluit (sessie 17 juli 2026, Colin):** deze ronde modelleert de **plan-kern**: doelen, interventies, evaluatiemomenten, status, versiebeheer en cliëntakkoord. Sessieplanning → agenda-ronde; leefgebieden en veiligheidsplan → aparte beslissing later.
**Nog open:**
- Statusmachine: welke statussen echt (prototype-lagen waren inconsistent), en is cliëntakkoord een status of een los feit (WGBO)?
- Versiebeheer: nieuw record per versie (zoals `care_plans.version` deed) of muteren met audit?
- ~~Waar hangt het plan aan~~ — besloten: aan de ZORGEPISODE (besluit §5.1 #9), consistent met de diagnose.
- Is een behandelplan verplicht vóór start behandeling — harde eis of nudge (ZPM kent `behandelplan_check` als regeltrigger)?
## 6. Vervolg

View File

@@ -263,13 +263,58 @@
<span class="eyebrow">ECD · datamodel discovery</span>
<h1>Entiteitenkaart — instroomflow</h1>
<p class="subtitle">
Afgeleid uit de feitzinnen in <code>datamodel-discovery.md</code> §5.1. Persoon, cliëntrol, aanmelding,
verwijzer en de bijbehorende waardelijsten. Status: concept, ter review — vóór dit naar SQL gaat, checkt
Colin de entiteiten, kardinaliteiten en waardelijst-waarden.
Afgeleid uit de feitzinnen in <code>datamodel-discovery.md</code> §5.15.5: van persoon en aanmelding
via screening, intake en wachtlijst tot diagnose en behandelplan, met de bijbehorende waardelijsten.
Status: concept, ter review — vóór dit naar SQL gaat, checkt Colin de entiteiten, kardinaliteiten en
waardelijst-waarden.
</p>
<section>
<h2>Diagram</h2>
<h2>Samenhang — de keten in één oogopslag</h2>
<p>
Aanmelding en zorgepisode zijn géén gelijke niveaus: de aanmelding is de binnenkomst en het
besluitproces (daar horen screening en aanmeldwachttijd bij), de zorgepisode is de periode van zorg
die pas ontstaat als het besluit "intake" is. Alles in de onderste doos hangt aan de episode.
De pijlen binnen de episode tonen de chronologie (intake → diagnose → behandelplan); in het
datamodel hangen alle drie rechtstreeks aan de episode, met de intake als optionele herkomst
van de diagnose.
</p>
<div class="panel diagram-panel">
<pre class="mermaid">
flowchart TB
CL["CLIËNT (rol op PERSOON)"] -->|"meldt zich aan — 1 op veel"| AANM
subgraph AANMBOX["AANMELDING — binnenkomst en besluitproces"]
direction TB
AANM["Aanmelding
verwijzer · wettelijk kader · hulpvraag"]
AANM --> SCR["Screening
activiteiten + besluit"]
AANM -.-> WLA["Wachtlijstplaatsing
soort: aanmeld"]
SCR --> UIT{"Uitkomst
bij status besloten"}
end
UIT -->|"afgewezen · doorverwezen"| EINDE["geen episode"]
UIT -->|"wachtlijst"| WLA
UIT ==>|"intake"| EPI
subgraph EPIBOX["ZORGEPISODE — periode van zorg, 0..1 per aanmelding"]
direction TB
EPI["Zorgepisode"]
EPI --> INT["Intake(s)
aanleiding: regulier · intern · crisis"]
EPI -.-> WLB["Wachtlijstplaatsing
soort: behandel"]
INT --> DIA["Diagnose(s)
DSM-5-TR · gesteld tijdens intake"]
DIA --> PLAN["Behandelplan
doelen · interventies · evaluaties"]
end
</pre>
</div>
</section>
<section>
<h2>Diagram 1 — persoon &amp; aanmelding (§5.1)</h2>
<p>Rechthoeken met een sleutel (<code>PK</code>) zijn entiteiten met een eigen identiteit; entiteiten met alleen een <code>code</code>-sleutel zijn waardelijsten (referentiedata, geen eigen levenscyclus).</p>
<div class="panel diagram-panel">
<pre class="mermaid">
@@ -277,6 +322,7 @@ erDiagram
PERSOON ||--o| CLIENT : "is cliënt sinds"
CLIENT ||--o{ AANMELDING : "meldt zich aan"
CLIENT ||--o| CLIENTPORTAAL_ACCOUNT : "heeft toegang via"
AANMELDING ||--o| ZORGEPISODE : "start bij uitkomst intake"
AANMELDING }o--|| WETTELIJK_KADER : "valt onder"
AANMELDING }o--|| AANMELDING_STATUS : "heeft"
AANMELDING }o--o| AANMELDING_UITKOMST : "heeft, bij besloten"
@@ -309,6 +355,12 @@ erDiagram
date datum
string hulpvraag
}
ZORGEPISODE {
uuid id PK
uuid aanmelding_id FK
date gestart_op
date beeindigd_op "optioneel"
}
VERWIJZER {
uuid id PK
string naam
@@ -348,12 +400,240 @@ erDiagram
</pre>
</div>
<p class="baseline-note">
Niet in het diagram, maar op elke entiteit hierboven van toepassing (spelregels §3.1): <code>id</code> (uuid),
Niet in het diagram, maar op elke entiteit van toepassing (spelregels §3.1): <code>id</code> (uuid),
<code>created_at</code>/<code>updated_at</code>, <code>deleted_at</code> (soft delete), en een append-only
audit-event per mutatie. Weggelaten voor leesbaarheid, niet omdat ze niet gelden.
</p>
</section>
<section>
<h2>Diagram 2 — screening &amp; intake (§5.2)</h2>
<p>
De screening hoort bij de aanmelding (besluitproces); intakes horen bij de zorgepisode. Eén episode
kan meerdere intakes hebben — naast de reguliere intake bestaan interne intakes binnen een lopende
episode; de <code>aanleiding</code> legt het verschil vast. Screening vóór intake is een nudge,
geen harde volgorde-eis in het schema.
</p>
<div class="panel diagram-panel">
<pre class="mermaid">
erDiagram
AANMELDING ||--o| SCREENING : "wordt gescreend in"
SCREENING ||--o{ SCREENING_ACTIVITEIT : "omvat"
SCREENING_ACTIVITEIT }o--|| SCREENING_ACTIVITEIT_TYPE : "is van type"
SCREENING }o--o| SCREENING_BESLUIT : "besluit, bij afronding"
SCREENING }o--o| AFDELING : "adviseert"
ZORGEPISODE ||--o{ INTAKE : "omvat"
INTAKE }o--|| INTAKE_AANLEIDING : "gestart vanwege"
INTAKE }o--|| INTAKE_STATUS : "heeft"
INTAKE }o--o| INTAKE_UITKOMST : "heeft, bij afgerond"
INTAKE }o--|| AFDELING : "op afdeling"
INTAKE ||--o{ CONTACTMOMENT : "omvat"
CONTACTMOMENT }o--|| CONTACTMOMENT_TYPE : "is van type"
INTAKE ||--o| KINDCHECK : "heeft"
SCREENING {
uuid id PK
uuid aanmelding_id FK
date gestart_op
date besluit_datum "optioneel"
}
SCREENING_ACTIVITEIT {
uuid id PK
uuid screening_id FK
date datum
string toelichting
uuid uitgevoerd_door "rollenronde"
}
INTAKE {
uuid id PK
uuid zorgepisode_id FK
date gestart_op
date afgerond_op "optioneel"
}
CONTACTMOMENT {
uuid id PK
uuid intake_id FK
date datum
uuid gevoerd_door "rollenronde"
}
KINDCHECK {
uuid id PK
uuid intake_id FK
date uitgevoerd_op
boolean thuiswonende_kinderen
boolean zorgen_veiligheid
boolean actie_ondernomen
string toelichting
}
SCREENING_ACTIVITEIT_TYPE {
string code PK
string label
}
SCREENING_BESLUIT {
string code PK
string label
}
AFDELING {
string code PK
string label
}
INTAKE_AANLEIDING {
string code PK
string label
}
INTAKE_STATUS {
string code PK
string label
}
INTAKE_UITKOMST {
string code PK
string label
}
CONTACTMOMENT_TYPE {
string code PK
string label
}
</pre>
</div>
<p class="baseline-note">
<b>ZORGPROGRAMMA</b> (FACT, Verslaving, Trauma, ...) is als waardelijst besloten maar heeft nog geen
relatie in dit diagram — de koppeling (aan behandeladvies of traject) volgt in de ronde
diagnose &amp; behandeltraject. <b>Verslagen</b> (feitzin 9, provenance) volgen in de rapportage-ronde.
</p>
</section>
<section>
<h2>Diagram 3 — wachtlijst, diagnose &amp; behandelplan (§5.35.5)</h2>
<p>
De aanmeldwachttijd hangt aan de AANMELDING (besluitproces); diagnoses, behandelplannen en de
behandelwachttijd hangen aan de ZORGEPISODE. De diagnose wordt in DSM-5-TR geregistreerd; de
ICD-10-code wordt via een mappingtabel afgeleid. Het behandelplan is hier de kern — sessieplanning,
leefgebieden en veiligheidsplan volgen in latere rondes.
</p>
<div class="panel diagram-panel">
<pre class="mermaid">
erDiagram
AANMELDING ||--o{ WACHTLIJSTPLAATSING : "aanmeldwachttijd"
ZORGEPISODE ||--o{ WACHTLIJSTPLAATSING : "behandelwachttijd"
WACHTLIJSTPLAATSING }o--|| WACHTLIJST_SOORT : "is van soort"
WACHTLIJSTPLAATSING }o--|| PRIORITEIT : "heeft"
WACHTLIJSTPLAATSING }o--|| AFDELING : "voor afdeling"
WACHTLIJSTPLAATSING }o--o| WACHTLIJST_EINDREDEN : "beëindigd met"
ZORGEPISODE ||--o{ DIAGNOSE : "heeft"
DIAGNOSE }o--|| ERNST : "heeft"
DIAGNOSE }o--|| DIAGNOSE_STATUS : "klinische status"
DIAGNOSE }o--|| VERIFICATIESTATUS : "werkdiagnose of definitief"
DIAGNOSE }o--o| INTAKE : "gesteld tijdens"
DIAGNOSE }o--|| DSM_ICD_MAPPING : "geclassificeerd als"
ZORGEPISODE ||--o{ BEHANDELPLAN : "heeft"
BEHANDELPLAN }o--|| PLAN_STATUS : "heeft"
BEHANDELPLAN }o--o{ DIAGNOSE : "adresseert"
BEHANDELPLAN }o--o| INTAKE : "gebaseerd op"
BEHANDELPLAN ||--o{ BEHANDELDOEL : "bevat"
BEHANDELDOEL }o--|| DOEL_STATUS : "heeft"
BEHANDELPLAN ||--o{ INTERVENTIE : "bevat"
INTERVENTIE }o--o{ BEHANDELDOEL : "werkt aan"
BEHANDELPLAN ||--o{ EVALUATIEMOMENT : "kent"
EVALUATIEMOMENT }o--|| EVALUATIE_TYPE : "is van type"
WACHTLIJSTPLAATSING {
uuid id PK
uuid aanmelding_id FK "bij soort aanmeld"
uuid zorgepisode_id FK "bij soort behandel"
date geplaatst_op
date telt_vanaf
date beeindigd_op "optioneel"
}
DIAGNOSE {
uuid id PK
uuid zorgepisode_id FK
string dsm_code
string omschrijving
boolean hoofddiagnose
date gesteld_op
uuid gesteld_door "rollenronde"
}
DSM_ICD_MAPPING {
string dsm_code PK
string icd10_code
string dsm_omschrijving
}
BEHANDELPLAN {
uuid id PK
uuid zorgepisode_id FK
int versie
date opgesteld_op
date client_akkoord_op "optioneel"
}
BEHANDELDOEL {
uuid id PK
uuid behandelplan_id FK
string titel
string clientversie_b1
string prioriteit
int termijn_weken
}
INTERVENTIE {
uuid id PK
uuid behandelplan_id FK
string naam
string rationale
}
EVALUATIEMOMENT {
uuid id PK
uuid behandelplan_id FK
int week
date gepland_op
date uitgevoerd_op "optioneel"
}
WACHTLIJST_SOORT {
string code PK
string label
}
PRIORITEIT {
string code PK
string label
}
WACHTLIJST_EINDREDEN {
string code PK
string label
}
ERNST {
string code PK
string label
}
DIAGNOSE_STATUS {
string code PK
string label
}
VERIFICATIESTATUS {
string code PK
string label
}
PLAN_STATUS {
string code PK
string label
}
DOEL_STATUS {
string code PK
string label
}
EVALUATIE_TYPE {
string code PK
string label
}
</pre>
</div>
<p class="baseline-note">
<b>Aannames ter bevestiging:</b> versiebeheer als nieuw record per versie (<code>versie</code>-veld) ·
cliëntakkoord als datum-feit, niet als status · "max één hoofddiagnose" als constraint — maar per wat
(episode / moment) is nog open. WACHTLIJSTPLAATSING heeft twee optionele FK's; welke gevuld is volgt
uit de soort (aanmeld → aanmelding, behandel → episode).
</p>
</section>
<section>
<h2>Waardelijsten</h2>
<p>De daadwerkelijke waarden per referentietabel, zodat je kunt controleren of de lijst klopt en compleet is.</p>
@@ -434,6 +714,253 @@ erDiagram
</p>
</div>
<div class="panel">
<h3>AFDELING</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">volwassenen</td></tr>
<tr><td class="code">jeugd</td></tr>
<tr><td class="code">ouderen</td></tr>
<tr><td class="code">forensisch</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Organisatorische eenheid; per instelling configureerbaar. Startlijst te bevestigen —
FACT en Verslaving zijn bewust géén afdeling (zie ZORGPROGRAMMA).
</p>
</div>
<div class="panel">
<h3>ZORGPROGRAMMA</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">algemeen_ggz</td></tr>
<tr><td class="code">fact</td></tr>
<tr><td class="code">verslaving</td></tr>
<tr><td class="code">trauma</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Inhoudelijk aanbod, los van afdeling. Koppeling volgt in de ronde diagnose &amp; behandeltraject.
</p>
</div>
<div class="panel">
<h3>SCREENING_ACTIVITEIT_TYPE</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">telefonisch_contact</td></tr>
<tr><td class="code">dossieronderzoek</td></tr>
<tr><td class="code">vragenlijst</td></tr>
<tr><td class="code">overig</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Type + vrije toelichting per activiteit. Startlijst te bevestigen.
</p>
</div>
<div class="panel">
<h3>SCREENING_BESLUIT</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">geschikt</td></tr>
<tr><td class="code">niet_geschikt</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Verhouding tot AANMELDING_UITKOMST is een open vraag (overlap "geschikt" ↔ "intake").
</p>
</div>
<div class="panel">
<h3>INTAKE_AANLEIDING</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">regulier</td></tr>
<tr><td class="code">intern</td></tr>
<tr><td class="code">crisis</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Regulier = vanuit aanmelding/screening; intern = tweede intake binnen lopende episode
(bijv. afdelingsovergang). Lijst te bevestigen.
</p>
</div>
<div class="panel">
<h3>INTAKE_STATUS</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">bezig</td></tr>
<tr><td class="code">afgerond</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Uit het prototype overgenomen; mogelijk komt er nog een status bij (bijv. gepland).
</p>
</div>
<div class="panel">
<h3>INTAKE_UITKOMST</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">in_zorg</td></tr>
<tr><td class="code">doorverwijzing</td></tr>
<tr><td class="code">extra_diagnostiek</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Alleen gezet bij status = <code>afgerond</code>. Waarden uit het prototype — te bevestigen.
</p>
</div>
<div class="panel">
<h3>CONTACTMOMENT_TYPE</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">intakegesprek</td></tr>
<tr><td class="code">aanvullend_onderzoek</td></tr>
<tr><td class="code">telefonisch_contact</td></tr>
<tr><td class="code">huisbezoek</td></tr>
<tr><td class="code">overig</td></tr>
</tbody>
</table>
</div>
<div class="panel">
<h3>WACHTLIJST_SOORT</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">aanmeld</td></tr>
<tr><td class="code">behandel</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Volgt de Treeknormen: aanmeldwachttijd (vóór intake) en behandelwachttijd (na intake).
</p>
</div>
<div class="panel">
<h3>PRIORITEIT</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">spoed</td></tr>
<tr><td class="code">normaal</td></tr>
<tr><td class="code">laag</td></tr>
</tbody>
</table>
</div>
<div class="panel">
<h3>WACHTLIJST_EINDREDEN</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">intake_gestart</td></tr>
<tr><td class="code">behandeling_gestart</td></tr>
<tr><td class="code">doorverwezen</td></tr>
<tr><td class="code">teruggetrokken</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Startlijst te bevestigen.
</p>
</div>
<div class="panel">
<h3>ERNST</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">licht</td></tr>
<tr><td class="code">matig</td></tr>
<tr><td class="code">ernstig</td></tr>
</tbody>
</table>
</div>
<div class="panel">
<h3>DIAGNOSE_STATUS</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">actief</td></tr>
<tr><td class="code">in_remissie</td></tr>
<tr><td class="code">opgelost</td></tr>
<tr><td class="code">inactief</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Klinische status — losse as naast VERIFICATIESTATUS.
</p>
</div>
<div class="panel">
<h3>VERIFICATIESTATUS</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">werkdiagnose</td></tr>
<tr><td class="code">definitief</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Aparte status-as — te bevestigen (zat in het prototype-model maar werd niet gebruikt).
</p>
</div>
<div class="panel">
<h3>PLAN_STATUS</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">concept</td></tr>
<tr><td class="code">actief</td></tr>
<tr><td class="code">afgerond</td></tr>
<tr><td class="code">vervallen</td></tr>
</tbody>
</table>
<p class="baseline-note" style="margin-top: 0.9rem; padding-top: 0.7rem;">
Voorstel — de statusmachine (incl. plaats van cliëntakkoord) is nog een open vraag.
</p>
</div>
<div class="panel">
<h3>DOEL_STATUS</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">niet_gestart</td></tr>
<tr><td class="code">bezig</td></tr>
<tr><td class="code">gehaald</td></tr>
<tr><td class="code">bijgesteld</td></tr>
</tbody>
</table>
</div>
<div class="panel">
<h3>EVALUATIE_TYPE</h3>
<table>
<thead><tr><th>Code</th></tr></thead>
<tbody>
<tr><td class="code">tussentijds</td></tr>
<tr><td class="code">eind</td></tr>
<tr><td class="code">crisis</td></tr>
</tbody>
</table>
</div>
</div>
</section>
@@ -466,12 +993,41 @@ erDiagram
<b>BSN is optioneel op PERSOON</b> — een medewerker is ook een persoon en heeft geen BSN in het systeem nodig. De verplichting hoort bij de rol (voor cliënten: Wabvpz).
<div class="why">Nudge ("cliënt zonder BSN") of rolgebonden eis — te bepalen in de rollenronde.</div>
</li>
<li>
<b>Screeningsbesluit ↔ aanmelding-uitkomst</b> — "geschikt" (screening) en uitkomst "intake" (aanmelding) overlappen mogelijk: één feit of twee?
<div class="why">Open vraag voor een volgende sessie.</div>
</li>
<li>
<b>Startlijsten te bevestigen</b> — AFDELING, ZORGPROGRAMMA, SCREENING_ACTIVITEIT_TYPE, INTAKE_AANLEIDING en INTAKE_UITKOMST zijn afgeleid uit het prototype en nog niet definitief.
</li>
<li>
<b>Kindcheck-structuur</b> — nu gemodelleerd als drie ja/nee-vlaggen + toelichting (zoals het prototype), niet als één uitkomstwaarde.
<div class="why">Bevestigen of dit de juiste registratievorm is (Meldcode-eisen meenemen).</div>
</li>
<li>
<b>Screening vóór intake is een nudge</b> — geen harde volgorde-eis in het schema; protocolregel bij de eerste intake van een episode.
</li>
<li>
<b>Behandelplan: statusmachine, versiebeheer-vorm en verplichting nog open</b> — cliëntakkoord als status of feit (WGBO), nieuw record per versie of muteren met audit, en behandelplan-verplicht-vóór-behandeling als nudge of harde eis.
</li>
<li>
<b>Wanneer ontstaat de ZORGEPISODE precies</b> — pas bij aanmelding-uitkomst "intake", of al bij "wachtlijst"?
<div class="why">Bepaalt waar de behandelwachttijd van een nog-niet-gestarte episode aan hangt.</div>
</li>
<li>
<b>DSM-ICD-mappingtabel heeft een bron nodig</b> — wie levert en onderhoudt de mapping (en de DSM-5-TR-lijst zelf, licentie APA)?
<div class="why">Uitzoeken vóór de schema-baseline; raakt ook de declaratie-ronde.</div>
</li>
<li>
<b>Wachtlijst per afdeling en/of zorgprogramma</b> — nu alleen afdeling gemodelleerd; en de beëindigingsredenen-startlijst is te bevestigen.
</li>
</ol>
</section>
<footer>
Bron: <code>docs/datamodel/datamodel-discovery.md</code> §5.1 · volgende stap (§6): dit diagram reviewen,
daarna statussen + eigenaarschap ECD/TIP vastleggen, vervolgens dezelfde cyclus voor screening &amp; intake (§5.2).
Bron: <code>docs/datamodel/datamodel-discovery.md</code> §5.15.5 · volgende stap (§6): statussen +
eigenaarschap ECD/TIP per entiteit vastleggen, daarna de latere rondes (agenda, rapportage &amp;
overdracht, rollen/disciplines) en pas dan de schema-baseline.
</footer>
</div>

View File

@@ -0,0 +1,64 @@
# Sessielog — 17 juli 2026
**Deelnemers:** Colin (PO) + Claude Code
**Onderwerp:** Datamodel-discovery ronde 1 — feitzinnen en entiteitenkaart van aanmelding t/m behandelplan
**Branch:** `swift-cortex`
---
## 1. Wat er ligt
- **`docs/datamodel/datamodel-discovery.md`** — feitzinnen, besluiten en open vragen per flow (§5.1 t/m §5.5), FCO-IM-werkwijze
- **`docs/datamodel/entiteitenkaart-instroom.html`** — samenhang-diagram + drie ER-diagrammen + waardelijsten, gepubliceerd als artifact ter review
De scope van ronde 1 is deze sessie verbreed: van alleen instroom naar **aanmelding t/m behandelplan** (incl. wachtlijstbeheer, diagnose, behandelplan-kern). Agenda en rapportage & overdracht blijven latere rondes.
## 2. Besluiten
| # | Besluit | Toelichting |
|---|---|---|
| 1 | **PERSOON en CLIENT gesplitst** | PERSOON draagt identiteit (naam, geboortedatum, BSN); CLIENT is een rol erop (cliëntnummer, sinds-datum). Zelfde persoon kan later ook contactpersoon, vertegenwoordiger of medewerker zijn. **BSN optioneel op PERSOON** — de verplichting hoort bij de rol (cliënt: Wabvpz), niet bij de persoon. |
| 2 | **ZORGEPISODE als eigen entiteit** | Aanmelding = binnenkomst-gebeurtenis (verwijzer, screening, besluit, aanmeldwachttijd); zorgepisode = periode van zorg die bij uitkomst "intake" start (intakes, diagnoses, behandelplan, behandelwachttijd). Sluit straks aan op het ZPM-zorgtraject. |
| 3 | **VERWIJZER + PRAKTIJK_INSTELLING als losse entiteiten** | AGB-verplichting hangt als attribuut aan de waardelijst `verwijzertype` (huisarts ja, gemeente nee). Geen AGB-validatie tegen Vecozo nu — declaratie-ronde. |
| 4 | **Aanmelding-status flexibel** | `nieuw → in screening → besloten`, vrij terug te bewegen. Uitkomst bij besloten: `intake` / `afgewezen` / `doorverwezen` / `wachtlijst`. |
| 5 | **Verwijsbrief is een nudge, geen harde eis** | Protocolregel met severity per financieringtype; beschikking telt ook als verwijzing (waardelijst `verwijsdocument_type`). Zelfde patroon voor screening-vóór-intake. |
| 6 | **Intake hangt aan de zorgepisode, meerdere per episode** | Interne intakes (bijv. afdelingsovergang) bestaan; `aanleiding`-waardelijst (regulier/intern/crisis). |
| 7 | **AFDELING en ZORGPROGRAMMA gescheiden waardelijsten** | FACT is een programma, geen afdeling. Lost de drie inconsistente hardcoded lijsten uit het prototype op. |
| 8 | **Screeningsactiviteiten getypeerd** | Type uit waardelijst + vrije toelichting (prototype had alleen vrije tekst). |
| 9 | **WACHTLIJSTPLAATSING als entiteit, twee momenten** | Aanmeldwachttijd (aan aanmelding) én behandelwachttijd (aan episode) — volgt de Treeknormen. Prioriteit, telt-vanaf, beëindigingsreden. |
| 10 | **DSM-5-TR primair, ICD-10 via mapping** | Behandelaren registreren DSM; ICD-10 afgeleid via mappingtabel. Prototype deed het omgekeerd (ICD-10 + DSM als vrije tekst). |
| 11 | **Diagnose aan de episode, intake als herkomst** | Diagnose overleeft de intake; twee status-assen (klinisch + verificatie werkdiagnose/definitief). |
| 12 | **Behandelplan: kern eerst** | Doelen (B1-cliëntversie), interventies, evaluatiemomenten, versies, cliëntakkoord. Sessieplanning → agenda-ronde; leefgebieden en veiligheidsplan → later. |
| 13 | **CLIENTPORTAAL_ACCOUNT als entiteit** (0..1 op CLIENT) | Alleen de relatie; auth-details in de auth/ADM-ronde. Verwijzersportaal genoteerd als idee, geen besluit. |
## 3. Bevindingen prototype (verkenningen)
- **Afdelingen:** drie onderling inconsistente hardcoded lijsten (screening 6, intake 3 met andere labels, behandeladvies 4 + 4 zorgprogramma's).
- **Diagnose-module:** heet DSM-5 maar registreert feitelijk ICD-10 F-codes; `verification_status` zit in de tabel maar de UI gebruikt het niet.
- **Kindcheck:** geen enkele uitkomstwaarde maar drie ja/nee-vlaggen + tekst — zo overgenomen in het model.
- **Wachtlijst:** bestaat nergens in code/DB, alleen als roadmap-idee — vanaf nul ontworpen.
- **Behandelplan:** gestript maar typemodel teruggehaald uit git-historie; statussen waren inconsistent tussen TS- en DB-laag.
- **Intake afronden:** liep via behandeladvies-tab met uitkomst `in_zorg`/`doorverwijzing`/`extra_diagnostiek` — als startlijst overgenomen.
## 4. Open vragen (belangrijkste)
1. Wanneer ontstaat de ZORGEPISODE precies — bij uitkomst "intake" of al bij "wachtlijst"?
2. Verhouding screeningsbesluit ↔ aanmelding-uitkomst: één feit of twee?
3. Behandelplan: statusmachine (cliëntakkoord als status of feit, WGBO), versiebeheer-vorm, verplicht-vóór-behandeling als nudge of eis.
4. "Max één hoofddiagnose" — per episode of per moment in de tijd?
5. DSM-ICD-mappingtabel: bron en onderhoud (APA-licentie) — vóór de schema-baseline.
6. Startlijsten bevestigen: afdelingen, zorgprogramma's, AGB-verplichting per verwijzertype, beëindigingsredenen wachtlijst, intake-uitkomsten.
7. Wie mag statussen zetten / diagnose stellen / intake afronden → rollen- en disciplinesronde.
## 5. Vervolgstappen
1. Entiteitenkaart reviewen (Colin) — met name kardinaliteiten en de aannames in de "Openstaand"-blokken.
2. Statussen + eigenaarschap ECD/TIP per entiteit vastleggen (§6 stap 3).
3. Latere rondes: agenda, rapportage & overdracht, rollen/disciplines, declaratie.
4. Pas daarna: verse schema-baseline (migrations) + `lib/dat/`.
## Referenties
- Discovery: `docs/datamodel/datamodel-discovery.md`
- Entiteitenkaart: `docs/datamodel/entiteitenkaart-instroom.html` (artifact: claude.ai/code/artifact/e2340972-f677-4f0d-af95-b40e8dcac241)
- Vorige sessie: `docs/sessions/2026-07-14-sessielog.md`