docs: architectuurdocs, styleguides en release notes intake/behandelplan
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1734
docs/architecture/enterprise-componenten-uitbreiding.md
Normal file
1734
docs/architecture/enterprise-componenten-uitbreiding.md
Normal file
File diff suppressed because it is too large
Load Diff
1619
docs/architecture/enterprise-epd-architectuur.md
Normal file
1619
docs/architecture/enterprise-epd-architectuur.md
Normal file
File diff suppressed because it is too large
Load Diff
1073
docs/architecture/intent-system-architecture.md
Normal file
1073
docs/architecture/intent-system-architecture.md
Normal file
File diff suppressed because it is too large
Load Diff
1101
docs/architecture/intent-system-architectuur-nl.md
Normal file
1101
docs/architecture/intent-system-architectuur-nl.md
Normal file
File diff suppressed because it is too large
Load Diff
287
docs/architecture/overzicht-po-pm.html
Normal file
287
docs/architecture/overzicht-po-pm.html
Normal file
@@ -0,0 +1,287 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Mini-EPD — Architectuur & Datacomponenten (PO/PM)</title>
|
||||
<style>
|
||||
:root{
|
||||
--bg:#0f172a; --panel:#ffffff; --ink:#1e293b; --muted:#64748b;
|
||||
--line:#e2e8f0; --brand:#4f46e5; --brand-soft:#eef2ff;
|
||||
--teal:#0d9488; --teal-soft:#ecfdf5; --amber:#d97706; --amber-soft:#fffbeb;
|
||||
--rose:#e11d48; --rose-soft:#fff1f2; --sky:#0284c7; --sky-soft:#f0f9ff;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
|
||||
background:linear-gradient(160deg,#0f172a 0%,#1e1b4b 100%);color:var(--ink);line-height:1.5;padding:32px 16px;}
|
||||
.wrap{max-width:1080px;margin:0 auto;}
|
||||
header{text-align:center;color:#fff;margin-bottom:32px;}
|
||||
header h1{font-size:30px;margin:0 0 8px;letter-spacing:-.5px;}
|
||||
header p{color:#c7d2fe;margin:0;font-size:15px;}
|
||||
.badge{display:inline-block;background:rgba(255,255,255,.12);color:#e0e7ff;
|
||||
padding:4px 12px;border-radius:999px;font-size:12px;margin-top:12px;}
|
||||
.card{background:var(--panel);border-radius:18px;padding:26px 28px;margin-bottom:22px;
|
||||
box-shadow:0 10px 40px rgba(0,0,0,.18);}
|
||||
.card h2{font-size:13px;text-transform:uppercase;letter-spacing:1.5px;color:var(--brand);
|
||||
margin:0 0 4px;font-weight:700;}
|
||||
.card h2 .num{background:var(--brand);color:#fff;border-radius:8px;padding:2px 9px;margin-right:8px;font-size:13px;}
|
||||
.card .lead{color:var(--muted);font-size:14px;margin:0 0 20px;}
|
||||
|
||||
/* layers stack */
|
||||
.stack{display:flex;flex-direction:column;gap:10px;}
|
||||
.layer{border-radius:14px;padding:16px 20px;border:1px solid var(--line);}
|
||||
.layer .tag{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;opacity:.7;}
|
||||
.layer .title{font-size:16px;font-weight:700;margin:2px 0 6px;}
|
||||
.layer .desc{font-size:13px;color:var(--muted);}
|
||||
.l1{background:var(--sky-soft);border-color:#bae6fd;}
|
||||
.l2{background:var(--brand-soft);border-color:#c7d2fe;}
|
||||
.l3{background:var(--teal-soft);border-color:#a7f3d0;}
|
||||
.chev{text-align:center;color:#94a3b8;font-size:18px;line-height:1;}
|
||||
|
||||
/* modules grid */
|
||||
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;}
|
||||
.mod{border:1px solid var(--line);border-radius:14px;padding:16px;}
|
||||
.mod .ic{font-size:22px;}
|
||||
.mod .nm{font-weight:700;margin:8px 0 4px;font-size:15px;}
|
||||
.mod .tx{font-size:13px;color:var(--muted);}
|
||||
|
||||
/* cortex flow */
|
||||
.flow{display:flex;flex-direction:column;gap:8px;}
|
||||
.step{display:flex;align-items:center;gap:14px;border:1px solid var(--line);border-radius:12px;padding:12px 16px;}
|
||||
.step .badgeN{flex:0 0 34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;
|
||||
font-weight:800;color:#fff;font-size:14px;}
|
||||
.step .body{flex:1;}
|
||||
.step .t{font-weight:700;font-size:14px;}
|
||||
.step .d{font-size:12.5px;color:var(--muted);}
|
||||
.n1{background:var(--sky);} .n2{background:var(--brand);} .n3{background:var(--teal);} .nA{background:#475569;}
|
||||
|
||||
.intents{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px;}
|
||||
.intent{background:var(--brand-soft);color:var(--brand);border-radius:999px;padding:5px 13px;font-size:12.5px;font-weight:600;}
|
||||
|
||||
/* services */
|
||||
.svc{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;}
|
||||
.svcbox{border:1px solid var(--line);border-radius:14px;padding:16px;}
|
||||
.svcbox .h{font-weight:700;font-size:15px;display:flex;align-items:center;gap:8px;}
|
||||
.svcbox .role{font-size:12px;color:var(--muted);margin:6px 0;}
|
||||
.svcbox .why{font-size:12.5px;background:#f8fafc;border-radius:8px;padding:8px 10px;color:var(--ink);}
|
||||
|
||||
/* data model diagram */
|
||||
.dm{display:flex;flex-direction:column;align-items:center;gap:0;}
|
||||
.entity{border-radius:12px;padding:12px 18px;text-align:center;border:2px solid;min-width:150px;}
|
||||
.entity .e-nm{font-weight:800;font-size:14px;}
|
||||
.entity .e-tx{font-size:11.5px;color:var(--muted);}
|
||||
.epatient{background:var(--brand-soft);border-color:var(--brand);}
|
||||
.erow{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-top:12px;}
|
||||
.echild{background:#f8fafc;border-color:var(--line);}
|
||||
.echild .e-nm{font-size:13px;}
|
||||
.pipe{width:2px;height:18px;background:#cbd5e1;}
|
||||
|
||||
/* journey */
|
||||
.journey{display:flex;flex-wrap:wrap;align-items:stretch;gap:0;}
|
||||
.jstep{flex:1;min-width:120px;background:#f8fafc;border:1px solid var(--line);padding:12px;text-align:center;position:relative;}
|
||||
.jstep:first-child{border-radius:12px 0 0 12px;}
|
||||
.jstep:last-child{border-radius:0 12px 12px 0;}
|
||||
.jstep .jt{font-weight:700;font-size:13px;}
|
||||
.jstep .jd{font-size:11px;color:var(--muted);margin-top:3px;}
|
||||
.jstep .arrow{position:absolute;right:-9px;top:50%;transform:translateY(-50%);color:#cbd5e1;font-size:18px;z-index:2;}
|
||||
|
||||
/* tables */
|
||||
table{width:100%;border-collapse:collapse;font-size:13px;}
|
||||
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);vertical-align:top;}
|
||||
th{font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);}
|
||||
td:first-child{font-weight:600;white-space:nowrap;}
|
||||
|
||||
/* rules / warnings */
|
||||
.rules{display:grid;gap:10px;}
|
||||
.rule{display:flex;gap:12px;border:1px solid var(--line);border-radius:12px;padding:12px 14px;}
|
||||
.rule .ic{font-size:18px;}
|
||||
.rule .rt{font-weight:700;font-size:13.5px;}
|
||||
.rule .rd{font-size:12.5px;color:var(--muted);}
|
||||
.warns{display:grid;gap:10px;}
|
||||
.warn{display:flex;gap:12px;background:var(--amber-soft);border:1px solid #fde68a;border-radius:12px;padding:12px 14px;}
|
||||
.warn .rt{font-weight:700;font-size:13.5px;color:#92400e;}
|
||||
.warn .rd{font-size:12.5px;color:#78350f;}
|
||||
footer{text-align:center;color:#94a3b8;font-size:12px;margin-top:8px;}
|
||||
.tags{margin-top:14px;}
|
||||
.pill{display:inline-block;font-size:11px;padding:3px 9px;border-radius:6px;margin:2px;font-weight:600;}
|
||||
.pill-type{background:var(--sky-soft);color:var(--sky);}
|
||||
.pill-cat{background:var(--teal-soft);color:var(--teal);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
|
||||
<header>
|
||||
<h1>Mini-EPD — Architectuur & Datacomponenten</h1>
|
||||
<p>Eén begrijpelijk overzicht voor Product Owners & Project Managers</p>
|
||||
<span class="badge">GGZ Elektronisch Patiëntdossier · Prototype</span>
|
||||
</header>
|
||||
|
||||
<!-- IN ÉÉN ALINEA -->
|
||||
<div class="card">
|
||||
<h2><span class="num">1</span>In het kort</h2>
|
||||
<p style="font-size:15px;margin:0;">Het Mini-EPD is een <strong>elektronisch patiëntdossier voor de GGZ</strong>. Een zorgverlener meldt patiënten aan, doet intake, maakt behandelplannen, schrijft dagrapportages en draagt diensten over. Het hart is de <strong>Cortex AI Command Center</strong>: een natuurlijke-taal-interface (typen of inspreken) waarmee je acties uitvoert in gewone zinnen — <em>"maak een notitie voor Jan: medicatie ingenomen"</em> of <em>"plan een afspraak morgen om 14:00"</em>.</p>
|
||||
</div>
|
||||
|
||||
<!-- DRIE LAGEN -->
|
||||
<div class="card">
|
||||
<h2><span class="num">2</span>De drie lagen van het systeem</h2>
|
||||
<p class="lead">Van wat de gebruiker ziet tot waar de gegevens staan.</p>
|
||||
<div class="stack">
|
||||
<div class="layer l1">
|
||||
<div class="tag">Laag 1 · Schermen</div>
|
||||
<div class="title">Wat de gebruiker ziet</div>
|
||||
<div class="desc">Dashboard · Patiëntdossier · Intake · Behandelplan · Verpleegrapportage · Agenda · Cortex AI Command Center</div>
|
||||
</div>
|
||||
<div class="chev">▼</div>
|
||||
<div class="layer l2">
|
||||
<div class="tag">Laag 2 · Logica</div>
|
||||
<div class="title">De verwerking (API's)</div>
|
||||
<div class="desc">Rapportage · Overdracht · Behandelplan · Intake · Cortex (intentherkenning + chat) · Spraak-naar-tekst</div>
|
||||
</div>
|
||||
<div class="chev">▼</div>
|
||||
<div class="layer l3">
|
||||
<div class="tag">Laag 3 · Gegevens</div>
|
||||
<div class="title">Database & externe diensten</div>
|
||||
<div class="desc">Supabase database · Claude AI (Anthropic) · Deepgram (spraak)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODULES -->
|
||||
<div class="card">
|
||||
<h2><span class="num">3</span>De modules (wat de gebruiker ziet)</h2>
|
||||
<p class="lead">De schermen waarmee de zorgverlener werkt.</p>
|
||||
<div class="grid">
|
||||
<div class="mod"><div class="ic">🏠</div><div class="nm">Dashboard</div><div class="tx">Startscherm met het Cortex AI Command Center. Hier begint elke actie.</div></div>
|
||||
<div class="mod"><div class="ic">📋</div><div class="nm">Patiëntdossier</div><div class="tx">Basisgegevens (incl. BSN), diagnoses, observaties en intakes per patiënt.</div></div>
|
||||
<div class="mod"><div class="ic">📝</div><div class="nm">Intake</div><div class="tx">Stapsgewijs: contactpersonen, risicotaxatie, anamnese, onderzoek, diagnose, advies.</div></div>
|
||||
<div class="mod"><div class="ic">🎯</div><div class="nm">Behandelplan</div><div class="tx">Doelen en interventies per leefgebied vastleggen en beheren.</div></div>
|
||||
<div class="mod"><div class="ic">🔄</div><div class="nm">Verpleegrapportage</div><div class="tx">Dagnotities in tijdlijn + overdracht met AI-samenvatting voor de volgende dienst.</div></div>
|
||||
<div class="mod"><div class="ic">📅</div><div class="nm">Agenda</div><div class="tx">Kalender met afspraken; inplannen, verzetten of annuleren.</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CORTEX -->
|
||||
<div class="card">
|
||||
<h2><span class="num">4</span>Het hart: Cortex AI Command Center</h2>
|
||||
<p class="lead">De gebruiker typt of spreekt een opdracht. Het systeem begrijpt de bedoeling en handelt — in drie slimme lagen die snelheid én begrip combineren.</p>
|
||||
<div class="flow">
|
||||
<div class="step"><div class="badgeN nA">🗣</div><div class="body"><div class="t">Gebruiker zegt of typt iets</div><div class="d">"Maak een notitie voor Jan: medicatie ingenomen"</div></div></div>
|
||||
<div class="chev">▼</div>
|
||||
<div class="step"><div class="badgeN n1">1</div><div class="body"><div class="t">Reflex (lokaal) — snel & gratis</div><div class="d">Herkent veelvoorkomende opdrachten direct via patronen (<20ms). Twijfel of complex? → door naar laag 2.</div></div></div>
|
||||
<div class="chev">▼</div>
|
||||
<div class="step"><div class="badgeN n2">2</div><div class="body"><div class="t">Orchestrator (AI) — voor lastige gevallen</div><div class="d">Claude lost op: meerdere opdrachten tegelijk, "hem/haar", "morgen", onduidelijke zinnen.</div></div></div>
|
||||
<div class="chev">▼</div>
|
||||
<div class="step"><div class="badgeN nA">✓</div><div class="body"><div class="t">Actie uitgevoerd</div><div class="d">Notitie opgeslagen · afspraak gemaakt · patiënt gevonden …</div></div></div>
|
||||
<div class="chev">▼</div>
|
||||
<div class="step"><div class="badgeN n3">3</div><div class="body"><div class="t">Nudge — proactieve suggestie achteraf</div><div class="d">"Wil je hier ook een observatie bij maken?" — verhoogt de zorgkwaliteit op het juiste moment.</div></div></div>
|
||||
</div>
|
||||
<p class="lead" style="margin:18px 0 6px;"><strong>Waarom drie lagen?</strong> De goedkope lokale laag vangt het gros af zonder AI-kosten of vertraging. Alleen echt lastige zinnen gaan naar de betaalde AI.</p>
|
||||
<p class="lead" style="margin:14px 0 4px;"><strong>Wat Cortex begrijpt (de "intents"):</strong></p>
|
||||
<div class="intents">
|
||||
<span class="intent">Dagnotitie maken</span>
|
||||
<span class="intent">Patiënt zoeken</span>
|
||||
<span class="intent">Overdracht bekijken</span>
|
||||
<span class="intent">Agenda opvragen</span>
|
||||
<span class="intent">Afspraak inplannen</span>
|
||||
<span class="intent">Afspraak annuleren</span>
|
||||
<span class="intent">Afspraak verzetten</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EXTERNE DIENSTEN -->
|
||||
<div class="card">
|
||||
<h2><span class="num">5</span>De externe diensten (afhankelijkheden)</h2>
|
||||
<p class="lead">Waar het product op leunt buiten de eigen code.</p>
|
||||
<div class="svc">
|
||||
<div class="svcbox">
|
||||
<div class="h">🗄️ Supabase</div>
|
||||
<div class="role">Database + inloggen (authenticatie)</div>
|
||||
<div class="why">De plek waar alle patiëntgegevens veilig staan.</div>
|
||||
</div>
|
||||
<div class="svcbox">
|
||||
<div class="h">🤖 Claude (Anthropic)</div>
|
||||
<div class="role">Intentherkenning · chat · overdrachtssamenvatting · behandelplan</div>
|
||||
<div class="why">De "intelligentie" achter Cortex en de samenvattingen. <strong>Betaalde API → gebruik = kosten.</strong></div>
|
||||
</div>
|
||||
<div class="svcbox">
|
||||
<div class="h">🎙️ Deepgram</div>
|
||||
<div class="role">Spraak omzetten naar tekst</div>
|
||||
<div class="why">Maakt het inspreken van notities mogelijk. <strong>Betaalde API → gebruik = kosten.</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- DATAMODEL -->
|
||||
<div class="card">
|
||||
<h2><span class="num">6</span>De gegevens (datacomponenten)</h2>
|
||||
<p class="lead">Het datamodel is <strong>FHIR-geïnspireerd</strong> — de internationale standaard voor zorggegevens, pragmatisch vereenvoudigd. Alles draait om de patiënt.</p>
|
||||
|
||||
<div class="dm">
|
||||
<div class="entity epatient">
|
||||
<div class="e-nm">PATIËNT</div>
|
||||
<div class="e-tx">naam · BSN · geboortedatum · status</div>
|
||||
</div>
|
||||
<div class="pipe"></div>
|
||||
<div class="erow">
|
||||
<div class="entity echild"><div class="e-nm">Screening</div><div class="e-tx">aanmelding & besluit</div></div>
|
||||
<div class="entity echild"><div class="e-nm">Intake</div><div class="e-tx">+ risico, anamnese, onderzoek</div></div>
|
||||
<div class="entity echild"><div class="e-nm">Diagnose</div><div class="e-tx">DSM-5 / ICD-10</div></div>
|
||||
<div class="entity echild"><div class="e-nm">Observatie</div><div class="e-tx">metingen & scores</div></div>
|
||||
<div class="entity echild"><div class="e-nm">Behandelplan</div><div class="e-tx">doelen & interventies</div></div>
|
||||
</div>
|
||||
<div class="pipe"></div>
|
||||
<div class="entity echild" style="min-width:200px;"><div class="e-nm">Contactmoment → Rapportage</div><div class="e-tx">sessies & dagnotities</div></div>
|
||||
</div>
|
||||
|
||||
<div class="tags">
|
||||
<p class="lead" style="margin:18px 0 6px;"><strong>Soorten rapportage (type):</strong></p>
|
||||
<span class="pill pill-type">voortgang</span><span class="pill pill-type">observatie</span><span class="pill pill-type">incident</span><span class="pill pill-type">medicatie</span><span class="pill pill-type">contact</span><span class="pill pill-type">crisis</span><span class="pill pill-type">verpleegkundig</span><span class="pill pill-type">behandeladvies</span>
|
||||
<p class="lead" style="margin:14px 0 6px;"><strong>Categorieën (verpleegkundig):</strong></p>
|
||||
<span class="pill pill-cat">medicatie</span><span class="pill pill-cat">ADL</span><span class="pill pill-cat">gedrag</span><span class="pill pill-cat">incident</span><span class="pill pill-cat">observatie</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PATIENTREIS -->
|
||||
<div class="card">
|
||||
<h2><span class="num">7</span>De patiëntreis door de data</h2>
|
||||
<p class="lead">Hoe een patiënt door het systeem stroomt.</p>
|
||||
<div class="journey">
|
||||
<div class="jstep"><div class="jt">Aangemeld</div><div class="jd">status: planned</div><span class="arrow">›</span></div>
|
||||
<div class="jstep"><div class="jt">Screening</div><div class="jd">geschikt?</div><span class="arrow">›</span></div>
|
||||
<div class="jstep"><div class="jt">Intake</div><div class="jd">anamnese, risico</div><span class="arrow">›</span></div>
|
||||
<div class="jstep"><div class="jt">In zorg</div><div class="jd">plan + rapportages</div><span class="arrow">›</span></div>
|
||||
<div class="jstep"><div class="jt">Overdracht</div><div class="jd">samenvatting collega</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- REGELS -->
|
||||
<div class="card">
|
||||
<h2><span class="num">8</span>Belangrijke regels in de data</h2>
|
||||
<p class="lead">Goed om te weten als PO/PM.</p>
|
||||
<div class="rules">
|
||||
<div class="rule"><div class="ic">♻️</div><div><div class="rt">Soft delete</div><div class="rd">Verwijderen markeert alleen; data blijft staan. Niets gaat echt verloren — belangrijk voor zorgdossiers en herstel.</div></div></div>
|
||||
<div class="rule"><div class="ic">🌙</div><div><div class="rt">Shift-logica</div><div class="rd">Notities vóór 07:00 horen bij de dienst van de vórige dag. Zorgt dat nachtdiensten correct in de overdracht vallen.</div></div></div>
|
||||
<div class="rule"><div class="ic">✅</div><div><div class="rt">Overdrachtsfilter</div><div class="rd">Alleen notities met "meenemen in overdracht" verschijnen in de samenvatting. De zorgverlener bepaalt wat relevant is.</div></div></div>
|
||||
<div class="rule"><div class="ic">🔒</div><div><div class="rt">Row Level Security (RLS)</div><div class="rd">De database dwingt af wie welke gegevens mag zien — fundament voor privacy/AVG. In deze fase nog ruim ingesteld.</div></div></div>
|
||||
<div class="rule"><div class="ic">🧠</div><div><div class="rt">AI-herkomst</div><div class="rd">Bij AI-gegenereerde inhoud worden zekerheid en redenering bewaard — transparant en controleerbaar.</div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- AANDACHTSPUNTEN -->
|
||||
<div class="card">
|
||||
<h2><span class="num">9</span>Aandachtspunten & status (eerlijk beeld)</h2>
|
||||
<div class="warns">
|
||||
<div class="warn"><div class="ic">⚠️</div><div><div class="rt">Prototype-status</div><div class="rd">Geen productiesysteem. Beveiligingsregels (RLS) zijn nog ruim; verfijning per team/organisatie is nog niet gebouwd.</div></div></div>
|
||||
<div class="warn"><div class="ic">⚠️</div><div><div class="rt">Twee-sporen datamodel</div><div class="rd">Naast het nieuwe FHIR-model bestaat nog een ouder model. Het nieuwe is leidend; het oude is nog niet opgeruimd — technische schuld om te bewaken.</div></div></div>
|
||||
<div class="warn"><div class="ic">⚠️</div><div><div class="rt">Externe AI-kosten</div><div class="rd">Schaalbaarheid van Cortex hangt samen met de gebruikskosten van Claude en Deepgram.</div></div></div>
|
||||
<div class="warn"><div class="ic">⚠️</div><div><div class="rt">Nog geen echte interoperabiliteit</div><div class="rd">Het model is FHIR-geïnspireerd; volledige FHIR-uitwisseling met externe systemen is nog niet geïmplementeerd.</div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>Bron: codebase mini-epd-prototype · modules in <code>app/</code> · logica in <code>app/api/</code> · Cortex in <code>lib/cortex/</code> · datamodel in <code>supabase/migrations/</code></footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
170
docs/architecture/overzicht-po-pm.md
Normal file
170
docs/architecture/overzicht-po-pm.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# Mini-EPD — Architectuur & Datacomponenten (PO/PM-overzicht)
|
||||
|
||||
> Doel van dit document: één begrijpelijk overzicht van **wat het systeem doet**, **uit welke bouwblokken het bestaat** en **welke gegevens het beheert** — zonder dat je code hoeft te lezen. Bedoeld voor product owners en project managers.
|
||||
|
||||
---
|
||||
|
||||
## 1. In één alinea
|
||||
|
||||
Het Mini-EPD is een **elektronisch patiëntdossier voor de GGZ**. Een zorgverlener kan patiënten aanmelden, intake doen, behandelplannen maken, dagelijkse rapportages schrijven en diensten overdragen aan een collega. Het bijzondere is de **Cortex AI Command Center**: een natuurlijke-taal-interface (typen of inspreken) waarmee de zorgverlener acties uitvoert in gewone zinnen, zoals *"maak een notitie voor Jan: medicatie ingenomen"* of *"plan een afspraak morgen om 14:00"*.
|
||||
|
||||
---
|
||||
|
||||
## 2. De drie lagen van het systeem
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ 1. WAT DE GEBRUIKER ZIET (de modules / schermen) │
|
||||
│ Dashboard · Patiëntdossier · Intake · Behandelplan · │
|
||||
│ Verpleegrapportage · Agenda · Cortex AI Command Center │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ 2. DE LOGICA (de API's / verwerking) │
|
||||
│ Rapportage · Overdracht · Behandelplan · Intake · │
|
||||
│ Cortex (intentherkenning + chat) · Spraak-naar-tekst │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ 3. DE GEGEVENS (de database + externe diensten) │
|
||||
│ Supabase database · Claude AI · Deepgram (spraak) │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. De modules (wat de gebruiker ziet)
|
||||
|
||||
| Module | Wat de zorgverlener ermee doet |
|
||||
|---|---|
|
||||
| **Dashboard** | Startscherm met het Cortex AI Command Center. Hier begint elke actie. |
|
||||
| **Patiëntdossier** | Volledig dossier per patiënt: basisgegevens (incl. BSN), diagnoses, observaties, intakes. |
|
||||
| **Intake** | Stapsgewijze intakeprocedure voor een nieuwe patiënt: contactpersonen, risicotaxatie, anamnese, onderzoek, diagnose, behandeladvies. |
|
||||
| **Behandelplan** | Behandeldoelen en interventies per leefgebied vastleggen en beheren. |
|
||||
| **Verpleegrapportage** | Dagelijkse notities in een tijdlijn (nacht/ochtend/middag/avond) + **overdracht** met AI-samenvatting voor de collega van de volgende dienst. |
|
||||
| **Agenda** | Kalender met alle afspraken; afspraken inplannen, verzetten of annuleren. |
|
||||
|
||||
---
|
||||
|
||||
## 4. Het hart: Cortex AI Command Center
|
||||
|
||||
De zorgverlener typt of spreekt een opdracht in. Het systeem begrijpt de bedoeling ("intent") en voert de juiste actie uit. Dit gebeurt in **drie slimme lagen** die samen snelheid én begrip combineren:
|
||||
|
||||
```
|
||||
Gebruiker zegt/typt iets
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐ Snel & gratis. Herkent veelvoorkomende
|
||||
│ 1. REFLEX (lokaal) │ opdrachten direct via patronen (<20ms).
|
||||
└─────────┬───────────┘ Twijfel of complex? → door naar laag 2.
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐ AI (Claude) lost lastige gevallen op:
|
||||
│ 2. ORCHESTRATOR (AI)│ meerdere opdrachten tegelijk, "hem/haar",
|
||||
└─────────┬───────────┘ "morgen", onduidelijke zinnen.
|
||||
│
|
||||
▼
|
||||
Actie wordt uitgevoerd (notitie opgeslagen, afspraak gemaakt...)
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐ Proactieve suggestie achteraf, bijv.
|
||||
│ 3. NUDGE │ "Wil je hier ook een observatie bij maken?"
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
**Waarom drie lagen?** De Reflex-laag handelt het gros af zonder AI-kosten en zonder vertraging. Alleen echt lastige zinnen gaan naar de (betaalde, iets tragere) AI. De Nudge-laag verhoogt de zorgkwaliteit door op het juiste moment iets te suggereren.
|
||||
|
||||
**Wat begrijpt Cortex (de "intents"):**
|
||||
- Dagnotitie maken · Patiënt zoeken · Overdracht bekijken
|
||||
- Agenda opvragen · Afspraak inplannen / annuleren / verzetten
|
||||
|
||||
**Chat & artifacts:** Het scherm is gesplitst — links een **chatpaneel** (gesprek met de assistent), rechts een **werkblok** ("artifact") dat past bij de opdracht: een notitieformulier, een overdrachtssamenvatting, een zoekresultaat, enzovoort.
|
||||
|
||||
---
|
||||
|
||||
## 5. De externe diensten (afhankelijkheden)
|
||||
|
||||
| Dienst | Waarvoor | Belang voor het product |
|
||||
|---|---|---|
|
||||
| **Supabase** | Database + inloggen (authenticatie) | De plek waar alle patiëntgegevens veilig staan. |
|
||||
| **Claude (Anthropic)** | AI: intentherkenning, chat, overdrachtssamenvatting, behandelplan genereren | De "intelligentie" achter Cortex en de samenvattingen. |
|
||||
| **Deepgram** | Spraak omzetten naar tekst | Maakt inspreken van notities mogelijk. |
|
||||
|
||||
> **Aandachtspunt PO/PM:** Claude en Deepgram zijn betaalde externe API's. Gebruik = kosten. Cortex is bewust zo ontworpen dat de goedkope lokale laag het meeste afvangt.
|
||||
|
||||
---
|
||||
|
||||
## 6. De gegevens (datacomponenten)
|
||||
|
||||
Het datamodel is **FHIR-geïnspireerd**. FHIR is de internationale standaard voor gestructureerde zorggegevens. "Geïnspireerd" betekent: we volgen de standaard waar het helpt voor uitwisselbaarheid met andere systemen (denk ICD-10/DSM-5 diagnosecodes, BIG/AGB-nummers), maar pragmatisch vereenvoudigd waar dat sneller bouwt.
|
||||
|
||||
### De kerngegevens en hoe ze samenhangen
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ PATIËNT │ (naam, BSN, geboortedatum, status)
|
||||
└──────┬───────┘
|
||||
┌──────────────┬───────┼───────────┬──────────────┐
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│SCREENING │ │ INTAKE │ │ DIAGNOSE │ │OBSERVATIE│ │BEHANDEL- │
|
||||
│(aanmeld) │ │(+ risico,│ │(condition)│ │(meting) │ │ PLAN │
|
||||
│ │ │ anamnese,│ │ │ │ │ │(doelen, │
|
||||
│ │ │ onderzoek)│ │ │ │ │ │interventies)│
|
||||
└──────────┘ └────┬─────┘ └──────────┘ └──────────┘ └──────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ CONTACTMOMENT │ (encounter: intake-gesprek, sessie)
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ RAPPORTAGE │ (dagnotities: voortgang, observatie,
|
||||
│ (reports) │ incident, medicatie, verpleegkundig...)
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
### Wat elk gegevenstype bevat
|
||||
|
||||
| Gegevenstype | Wat het is |
|
||||
|---|---|
|
||||
| **Patiënt** | De persoon in zorg: naam, BSN, geboortedatum, en een **status** (aangemeld → in zorg → afgerond / afgemeld). |
|
||||
| **Behandelaar** | De zorgprofessional, met BIG- en AGB-nummer; gekoppeld aan het inlogaccount. |
|
||||
| **Organisatie** | De GGZ-instelling. |
|
||||
| **Screening** | Het aanmeldproces: hulpvraag, activiteitenlog, documenten (verwijsbrieven), en het besluit (geschikt / niet geschikt). |
|
||||
| **Intake** | De intakesessie met onderliggende onderdelen: **anamnese**, **onderzoeken** en **risicotaxaties** (bv. suïcide-/agressierisico met niveau laag→zeer hoog). |
|
||||
| **Diagnose** (condition) | DSM-5/ICD-10 diagnoses met status. |
|
||||
| **Observatie** | Metingen en inschattingen (vitale waarden, ROM-scores, klachten). |
|
||||
| **Behandelplan** | Doelen en interventies, gekoppeld aan diagnoses. |
|
||||
| **Contactmoment** (encounter) | Een afspraak of sessie tussen patiënt en behandelaar (voedt ook de agenda). |
|
||||
| **Rapportage** (reports) | Eén centrale tabel voor álle dagnotities, met een **type** (voortgang, observatie, incident, medicatie, contact, crisis, verpleegkundig, ...) en een **categorie** (medicatie, ADL, gedrag, incident, observatie). |
|
||||
|
||||
### De patiëntreis door de data
|
||||
|
||||
```
|
||||
Aangemeld → Screening → Intake → In zorg → Overdracht
|
||||
(status: (besluit: (anamnese, (diagnoses, (samenvatting
|
||||
planned) geschikt?) risico, behandelplan, voor volgende
|
||||
onderzoek) dagrapportages) dienst)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Belangrijke regels in de data (voor PO/PM goed om te weten)
|
||||
|
||||
| Regel | Wat het betekent | Waarom relevant |
|
||||
|---|---|---|
|
||||
| **Soft delete** | Verwijderen markeert alleen ("deleted_at"), de data blijft staan. | Niets gaat echt verloren — belangrijk voor zorgdossiers en herstel. |
|
||||
| **Shift-logica** | Notities vóór 07:00 horen bij de dienst van de vórige dag. | Zorgt dat nachtdiensten correct in de overdracht vallen. |
|
||||
| **Overdrachtsfilter** | Alleen notities met "meenemen in overdracht" verschijnen in de samenvatting. | De zorgverlener bepaalt wat relevant is voor de collega. |
|
||||
| **Row Level Security (RLS)** | De database dwingt af wie welke gegevens mag zien. | Privacy/AVG-fundament. *Let op: in deze prototypefase nog ruim ingesteld — verfijning per team/organisatie staat nog open.* |
|
||||
| **AI-herkomst** | Bij AI-gegenereerde inhoud wordt zekerheid en redenering bewaard. | Transparantie/controleerbaarheid van AI-output. |
|
||||
|
||||
---
|
||||
|
||||
## 8. Aandachtspunten & status (eerlijk beeld)
|
||||
|
||||
- **Prototype-status:** Dit is een prototype, geen productiesysteem. De beveiligingsregels (RLS) zijn nog ruim; verfijning per team/organisatie is nog niet gebouwd.
|
||||
- **Twee-sporen datamodel:** Er bestaat nog een oudere ("clients/treatment_plans") naast de nieuwe FHIR-structuur ("patients/care_plans"). Het nieuwe spoor is leidend; het oude is nog niet volledig opgeruimd. Dit is technische schuld om in de gaten te houden.
|
||||
- **Externe AI-kosten:** Schaalbaarheid van Cortex/AI hangt samen met gebruikskosten van Claude en Deepgram.
|
||||
- **Geen echte interoperabiliteit (nog):** Het model is FHIR-*geïnspireerd*; volledige FHIR-uitwisseling met externe systemen is nog niet geïmplementeerd.
|
||||
|
||||
---
|
||||
|
||||
*Bronnen: codebase mini-epd-prototype (modules in `app/`, logica in `app/api/`, Cortex in `lib/cortex/`, datamodel in `supabase/migrations/`).*
|
||||
1175
docs/architecture/platform-connectiviteit-selfhosted.md
Normal file
1175
docs/architecture/platform-connectiviteit-selfhosted.md
Normal file
File diff suppressed because it is too large
Load Diff
494
docs/architecture/tech-stack-onderzoek.md
Normal file
494
docs/architecture/tech-stack-onderzoek.md
Normal file
@@ -0,0 +1,494 @@
|
||||
# Tech Stack Onderzoek — Versies, Alternatieven & Samenhang
|
||||
|
||||
> **Type**: Onderzoeksrapport
|
||||
> **Datum**: 2026-02-14
|
||||
> **Doel**: Valideer alle technologiekeuzes uit de architectuur op versies, community health, alternatieven en onderlinge compatibiliteit
|
||||
> **Conclusie**: 5 wijzigingen aanbevolen, 3 aandachtspunten, rest is solide
|
||||
|
||||
---
|
||||
|
||||
## Samenvatting: Wijzigingen ten opzichte van de architectuur
|
||||
|
||||
### Wijzigingen (doorvoeren)
|
||||
|
||||
| # | Was | Wordt | Waarom |
|
||||
|---|-----|-------|--------|
|
||||
| W1 | Next.js 14 + React 18 | **Next.js 16.1 LTS + React 19** | Next.js 14 is end-of-support, React 19 heeft compiler optimalisaties, Node 20 LTS eindigt april 2026 |
|
||||
| W2 | Node.js 20 | **Node.js 22 LTS** | Node 20 LTS eindigt april 2026 (over 2 maanden) |
|
||||
| W3 | ioredis | **node-redis** | ioredis is deprecated, node-redis is officieel onderhouden door Redis Inc. |
|
||||
| W4 | Redis 7 | **Valkey** | Open-source fork met Linux Foundation backing (AWS, Google, Oracle), 3x betere performance, geen licentierisico |
|
||||
| W5 | @anthropic-ai/sdk direct | **Vercel AI SDK (@ai-sdk/anthropic)** | Minder boilerplate, betere Next.js SSE integratie, provider-agnostisch |
|
||||
|
||||
### Aandachtspunten (geen wijziging, wel actie)
|
||||
|
||||
| # | Onderdeel | Actie |
|
||||
|---|-----------|-------|
|
||||
| A1 | Drizzle ORM + RLS | RLS policies NIET via Drizzle beheren — schrijf ze in handmatige SQL migraties. Drizzle verwijdert stiekem bestaande policies |
|
||||
| A2 | Auth.js v5 + Keycloak | Token refresh race conditions bij concurrent sessions. Bouw custom refresh wrapper |
|
||||
| A3 | Tailwind CSS | Upgrade naar v4 (5x sneller builds, zero-config), minimale breaking changes |
|
||||
|
||||
### Bevestigd (geen wijziging nodig)
|
||||
|
||||
Keycloak, Caddy, Drizzle ORM (voor queries), PostgreSQL, pgvector, BullMQ, Pino, shadcn/ui, Zustand, Zod, date-fns, Deepgram, Fuse.js, Lucide React, React Hook Form, Hetzner, Docker Compose
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Framework Stack
|
||||
|
||||
### Next.js — upgrade naar 16.1 LTS
|
||||
|
||||
| Eigenschap | Huidig (14) | Aanbevolen (16.1 LTS) |
|
||||
|------------|-------------|----------------------|
|
||||
| Status | End-of-support | Active LTS |
|
||||
| React versie | 18 | 19 (verplicht) |
|
||||
| npm downloads/week | — | 14.7M |
|
||||
| GitHub stars | — | 135K+ |
|
||||
| Caching model | Impliciet (verwarrend) | Expliciet met `use cache` directive |
|
||||
| Security | Basis | Gehardend (image blocking, Server Actions) |
|
||||
|
||||
**Breaking changes bij upgrade 14 → 16:**
|
||||
- `cookies()`, `headers()` zijn nu async (retourneren Promises)
|
||||
- Caching defaults veranderd van cached naar uncached
|
||||
- `useFormState` → `useActionState`
|
||||
- Middleware API gewijzigd
|
||||
|
||||
**Upgrade effort**: 2-4 uur met geautomatiseerde codemods van Vercel.
|
||||
|
||||
**Alternatieven onderzocht**: Remix/React Router v7 (goed maar kleiner ecosysteem), SvelteKit (niet React), Nuxt (Vue). Next.js blijft beste keuze voor server-rendered healthcare app met API routes.
|
||||
|
||||
### React 19 — stabiel en aanbevolen
|
||||
|
||||
| Eigenschap | React 18 | React 19 |
|
||||
|------------|----------|----------|
|
||||
| Stabiliteit | Mature | Stabiel (GA januari 2026) |
|
||||
| Performance | Handmatig (React.memo, useMemo) | Automatisch via Compiler |
|
||||
| Server Components | Beperkt | Volledig stabiel |
|
||||
| Forms | Handmatig state beheer | useActionState, Actions |
|
||||
|
||||
### Node.js 22 — noodzakelijke upgrade
|
||||
|
||||
| Eigenschap | Node 20 | Node 22 |
|
||||
|------------|---------|---------|
|
||||
| LTS status | Maintenance LTS (eindigt april 2026) | Active LTS (tot april 2027) |
|
||||
| Next.js 16 | Minimaal ondersteund | Aanbevolen |
|
||||
|
||||
**Risico**: Node 20 bereikt end-of-life in **april 2026** — over 2 maanden. Upgrade is urgent.
|
||||
|
||||
### TypeScript 5.9 — geen actie nodig
|
||||
|
||||
Huidige 5.x is volledig compatibel met Next.js 16 + React 19. TypeScript 6.0 beta is aangekondigd (februari 2026), 7.0 wordt herschreven in Go. Geen haast.
|
||||
|
||||
---
|
||||
|
||||
## 2. Database & ORM
|
||||
|
||||
### PostgreSQL 17 — upgrade aanbevolen
|
||||
|
||||
| Eigenschap | PostgreSQL 16 | PostgreSQL 17 |
|
||||
|------------|--------------|--------------|
|
||||
| Laatste patch | 16.12 (feb 2026) | 17.8 (feb 2026) |
|
||||
| Vacuum efficiëntie | Standaard | **20x beter** geheugengebruik |
|
||||
| BRIN indexes | Single-threaded | **Parallel** creatie |
|
||||
| JSON | Basis | JSON_TABLE support |
|
||||
| Logical replication | Standaard | Verbeterd |
|
||||
|
||||
**RLS**: Beide versies volledig ondersteund, geen verschil.
|
||||
**Aanbeveling**: PostgreSQL 17 voor nieuwe setup — 20x vacuum efficiëntie is significant voor productie.
|
||||
|
||||
### Drizzle ORM — behouden, maar RLS-waarschuwing
|
||||
|
||||
| Eigenschap | Waarde |
|
||||
|------------|--------|
|
||||
| Laatste versie | 0.45.1 |
|
||||
| npm downloads/week | ~4.7M |
|
||||
| GitHub stars | 32.8K |
|
||||
| Bundle size | ~7.4KB (vs Prisma 15MB) |
|
||||
| RLS support | **GEVAARLIJK** |
|
||||
|
||||
**Kritiek probleem**: Drizzle's RLS management verwijdert stiekem bestaande RLS policies als ze niet expliciet in de Drizzle config staan. `drizzle-kit push` past policies niet correct toe.
|
||||
|
||||
**Oplossing**: Gebruik Drizzle alleen voor queries en schema. Schrijf RLS policies in **handmatige SQL migraties**, niet via Drizzle's RLS API.
|
||||
|
||||
**Vergelijking**:
|
||||
|
||||
| Criterium | Drizzle | Prisma | Kysely |
|
||||
|-----------|---------|--------|--------|
|
||||
| Bundle size | 7.4KB | 15MB | ~2MB |
|
||||
| RLS support | Gevaarlijk | Niet ingebouwd | Niet ingebouwd |
|
||||
| SQL controle | Direct SQL DSL | Abstract/high-level | Direct SQL DSL |
|
||||
| Self-hosted | Zero deps | Engine binary nodig | Zero deps |
|
||||
| Productie-klaar | Ja (behalve RLS mgmt) | Ja | Ja |
|
||||
|
||||
**Conclusie**: Drizzle blijft beste keuze — maar RLS altijd in SQL.
|
||||
|
||||
### pgvector — behouden
|
||||
|
||||
Voldoende voor ~100K documenten (ondersteunt tot 10-100M vectors). Geen extra infra nodig.
|
||||
|
||||
**Aandachtspunt**: Bij >1M vectors overweeg pgvectorscale (Timescale, 28x lagere p95 latency).
|
||||
|
||||
### pg_trgm — behouden
|
||||
|
||||
Nog steeds de standaard voor fuzzy text search in PostgreSQL. Geen betere alternatieven.
|
||||
|
||||
---
|
||||
|
||||
## 3. Auth & Security
|
||||
|
||||
### Keycloak 26.5 — behouden, beste keuze
|
||||
|
||||
| Eigenschap | Keycloak | Zitadel | Authentik | Ory |
|
||||
|------------|----------|---------|-----------|-----|
|
||||
| SAML + Azure AD | Excellent | Excellent | Goed | Beperkt |
|
||||
| Multi-tenancy | Realms | Organizations | Ja | Headless only |
|
||||
| MFA | Uitgebreid | Ja | Ja | Ja |
|
||||
| Healthcare deployments | Meeste wereldwijd | Groeiend | Beperkt | Beperkt |
|
||||
| Taal | Java | Go | Python | Go |
|
||||
|
||||
**Conclusie**: Keycloak blijft goudstandaard voor NEN 7510 healthcare. Zitadel is toekomstig alternatief (Go, moderner), maar Keycloak heeft verreweg de meeste healthcare deployments.
|
||||
|
||||
### Auth.js v5 + Keycloak — behouden, met aandacht
|
||||
|
||||
Auth.js v5 is stabiel (GA), maar de **Keycloak provider heeft bekende problemen**:
|
||||
|
||||
1. **Refresh token race conditions** bij concurrent `useSession()` calls
|
||||
2. **Session timeout redirects** naar `/api/auth/error` na idle time
|
||||
3. **Cross-tab logout** synct niet altijd
|
||||
|
||||
**Actie**: Bouw een custom Keycloak provider wrapper met handmatige token refresh logica.
|
||||
|
||||
### AES-256-GCM (node:crypto) — behouden
|
||||
|
||||
Nog steeds de industriestandaard. Onderdeel van TLS 1.3, FIPS 140-3, onderschreven door NSA/NIST/OWASP. Geen betere alternatieven.
|
||||
|
||||
### Caddy 2.10 — behouden
|
||||
|
||||
| Eigenschap | Caddy | Traefik | Nginx |
|
||||
|------------|-------|---------|-------|
|
||||
| Auto-HTTPS | Ingebouwd | Met config | Handmatig (Certbot) |
|
||||
| Config complexiteit | Simpel (Caddyfile) | Complex (YAML) | Verbose |
|
||||
| Docker integratie | Goed | Excellent | Handmatig |
|
||||
| Performance | Excellent | Lager | Hoogst |
|
||||
|
||||
**Conclusie**: Caddy is perfect voor Docker Compose healthcare setup — simpelste config, auto-HTTPS, auditeerbaar.
|
||||
|
||||
---
|
||||
|
||||
## 4. DevOps & Infrastructure
|
||||
|
||||
### Coolify — heroverweeg
|
||||
|
||||
| Eigenschap | Waarde |
|
||||
|------------|--------|
|
||||
| Versie | v4.0.0-beta.462 |
|
||||
| GitHub stars | 50.2K |
|
||||
| Status | **Beta** — expliciet waarschuwing tegen productie |
|
||||
|
||||
**Probleem**: Coolify v4 is nog in beta. Voor een healthcare systeem is dat een risico.
|
||||
|
||||
**Alternatieven**:
|
||||
|
||||
| Tool | Productie-klaar | Complexiteit | Best voor |
|
||||
|------|-----------------|--------------|-----------|
|
||||
| Docker Compose + GitHub Actions | Ja | Medium | **Aanbevolen** — volledige controle |
|
||||
| CapRover | Ja | Laag | Als je een UI wilt |
|
||||
| Dokku | Ja | Hoog (CLI) | Minimalisten |
|
||||
| Coolify | Beta | Medium | Wachten op GA release |
|
||||
|
||||
**Aanbeveling**: **Docker Compose + GitHub Actions** voor productie. Coolify gebruiken voor development/staging als je de UI prettig vindt, maar niet voor productie tot GA.
|
||||
|
||||
### Hetzner — behouden
|
||||
|
||||
Nog steeds beste prijs/prestatie in EU. Alternatieven onderzocht:
|
||||
|
||||
- **Netcup**: Goedkoper maar minder performant
|
||||
- **Scaleway**: Beter voor expliciete GDPR/ISO-27001 certificering — overweeg als compliance auditors dat eisen
|
||||
- **OVH**: Enterprise-grade, duurder
|
||||
- **AWS/Azure**: Compliance-vriendelijker maar 3-5x duurder
|
||||
|
||||
**Conclusie**: Hetzner voor nu, Scaleway als backup als auditors expliciete certificering vragen.
|
||||
|
||||
### Valkey i.p.v. Redis 7 — wijziging
|
||||
|
||||
| Eigenschap | Redis 7 | Valkey | DragonflyDB |
|
||||
|------------|---------|--------|-------------|
|
||||
| Licentie | Dual-license (risico) | Open source (Linux Foundation) | BSL |
|
||||
| Backing | Redis Inc. | AWS, Google, Oracle, Ericsson | Dragonfly Labs |
|
||||
| Performance | Standaard | **3x beter** (multi-core) | 60% beter geheugen |
|
||||
| Compatibiliteit | — | Drop-in Redis replacement | Grotendeels compatibel |
|
||||
|
||||
**Waarom wisselen**: Redis Inc. heeft licentiewijzigingen doorgevoerd. Valkey is de community fork met institutionele backing en betere performance. 100% Redis-compatible.
|
||||
|
||||
### node-redis i.p.v. ioredis — wijziging
|
||||
|
||||
| Eigenschap | ioredis | node-redis |
|
||||
|------------|---------|------------|
|
||||
| npm downloads/week | 9.97M | 6.27M |
|
||||
| Status | **Deprecated** | Actief onderhouden door Redis Inc. |
|
||||
| Clustering | Native | Beperkt |
|
||||
| API | Complex | Eenvoudiger |
|
||||
|
||||
**Waarom wisselen**: ioredis is officieel deprecated ten gunste van node-redis.
|
||||
|
||||
**Let op**: BullMQ gebruikt ioredis intern. Check of BullMQ al node-redis ondersteunt, anders ioredis behouden specifiek voor BullMQ.
|
||||
|
||||
### BullMQ 5.69 — behouden
|
||||
|
||||
| Eigenschap | BullMQ | pg-boss | Quirrel |
|
||||
|------------|--------|---------|---------|
|
||||
| Versie | 5.69.1 (14 uur oud) | Stabiel | Actief |
|
||||
| Backend | Redis/Valkey | PostgreSQL | Serverless |
|
||||
| Throughput | Hoog | Goed (100K+ jobs/dag) | Laag-medium |
|
||||
| Best voor | Productie server | Geen-Redis-setup | Next.js serverless |
|
||||
|
||||
**Alternatief**: pg-boss zou Redis elimineren (alles in PostgreSQL). Maar we hebben Redis/Valkey toch al nodig voor caching (C37). BullMQ is de betere keuze.
|
||||
|
||||
### Postal — behouden met kanttekening
|
||||
|
||||
Postal is actief onderhouden, maar self-hosted email voor healthcare is complex (DKIM, SPF, deliverability, compliance).
|
||||
|
||||
**Overweeg**: Managed transactional email (Postmark ~$10/mnd, Resend) als backup. Compliance is makkelijker met managed providers.
|
||||
|
||||
### Pino 10.3 — behouden
|
||||
|
||||
| Eigenschap | Pino | Winston | Bunyan |
|
||||
|------------|------|---------|--------|
|
||||
| npm downloads/week | 17.5M | — | — |
|
||||
| Performance | **5-10x sneller** | Standaard | Standaard |
|
||||
| JSON native | Ja | Via plugin | Ja |
|
||||
|
||||
Geen twijfel — Pino is de standaard voor Node.js structured logging.
|
||||
|
||||
### OpenTelemetry Node.js SDK 2.x — behouden
|
||||
|
||||
Productie-klaar sinds 2025. Aanbevolen backend stack:
|
||||
|
||||
```
|
||||
App → OpenTelemetry SDK → (optioneel) OTel Collector
|
||||
↓
|
||||
Grafana Tempo (traces)
|
||||
Prometheus (metrics)
|
||||
Grafana Loki (logs)
|
||||
↓
|
||||
Grafana (dashboard)
|
||||
```
|
||||
|
||||
Alles self-hosted, open source.
|
||||
|
||||
### Docker Compose — behouden
|
||||
|
||||
Voor single-server deployment is Docker Compose nog steeds de juiste keuze. Docker Swarm is stagnant (geen actieve ontwikkeling sinds 2019). K3s is overkill voor één server.
|
||||
|
||||
---
|
||||
|
||||
## 5. Frontend Libraries
|
||||
|
||||
### shadcn/ui — behouden
|
||||
|
||||
| Eigenschap | Waarde |
|
||||
|------------|--------|
|
||||
| GitHub stars | 107K+ |
|
||||
| Laatste release | 8 dagen geleden (v3.8.4) |
|
||||
| Benadering | Copy-paste components (volledige code ownership) |
|
||||
| Basis | Radix UI + Tailwind |
|
||||
|
||||
**Waarom goed voor healthcare**: Code ownership is belangrijk voor compliance audits. Volledig toegankelijk (WCAG via Radix UI).
|
||||
|
||||
### Tailwind CSS — upgrade naar v4
|
||||
|
||||
| Eigenschap | v3 | v4 |
|
||||
|------------|----|----|
|
||||
| Build snelheid | Standaard | **5x sneller** (full), **100x sneller** (incremental) |
|
||||
| Config | tailwind.config.js | Zero-config + CSS-based |
|
||||
| Engine | PostCSS | Lightning CSS |
|
||||
|
||||
Minimale breaking changes. Upgrade is laag risico, hoge winst.
|
||||
|
||||
### Zustand 5.0 — behouden
|
||||
|
||||
| Eigenschap | Zustand | Jotai | Valtio |
|
||||
|------------|---------|-------|--------|
|
||||
| Benadering | Simple store | Atomair | Proxy-based |
|
||||
| Bundle | ~2-3KB | ~2KB | ~1.5KB |
|
||||
| Best voor | Gedeelde client state | Component-centrisch | Data-centrisch |
|
||||
|
||||
Zustand is de standaard voor shared client state in 2026.
|
||||
|
||||
### Zod 4.3 — behouden
|
||||
|
||||
44M+ downloads/week, mature ecosysteem. **Valibot** (1.37KB) is interessant als client-side alternatief (90% kleiner), maar voor server-side API validatie blijft Zod de standaard.
|
||||
|
||||
### date-fns 4.1 — behouden
|
||||
|
||||
35M+ downloads/week. Nederlandse locale ondersteuning. Temporal API is nog Stage 3 — niet beschikbaar in alle browsers. date-fns blijft nodig.
|
||||
|
||||
### Fuse.js 7.1 — behouden
|
||||
|
||||
Voldoende voor fuzzy search op patiëntnamen. **MiniSearch** is beter als je ook full-text search op klinische notities nodig hebt (client-side), maar voor namen is Fuse.js prima.
|
||||
|
||||
### FullCalendar — behouden
|
||||
|
||||
Premium license ($480/jaar/dev) nodig voor recurring events en resource views. **React Big Calendar** (gratis, MIT) als budget krap is. **Schedule-X** als modern open-source alternatief.
|
||||
|
||||
### Lucide React 0.564 — behouden
|
||||
|
||||
Actief onderhouden (release gisteren), 9.9K+ projecten, tree-shakeable. Geen reden om te wisselen.
|
||||
|
||||
### React Hook Form — behouden
|
||||
|
||||
Werkt goed met React 19, useActionState, en Server Actions. **Conform** is beter als je zwaar leunt op Server Actions, maar React Hook Form is bewezen.
|
||||
|
||||
---
|
||||
|
||||
## 6. AI & Spraak
|
||||
|
||||
### Vercel AI SDK i.p.v. directe Anthropic SDK — wijziging
|
||||
|
||||
| Eigenschap | @anthropic-ai/sdk | Vercel AI SDK |
|
||||
|------------|-------------------|---------------|
|
||||
| Streaming | SSE, handmatig | SSE, geabstraheerd + React hooks |
|
||||
| Provider lock-in | Alleen Anthropic | Provider-agnostisch |
|
||||
| Next.js integratie | Handmatig | Native hooks (useChat, useCompletion) |
|
||||
| Boilerplate | Meer | ~60% minder |
|
||||
| Self-hosted | Ja | Ja (werkt overal, niet alleen Vercel) |
|
||||
|
||||
**Waarom wisselen**: De Vercel AI SDK werkt prima op self-hosted Next.js en geeft ons betere streaming abstractions, React hooks, en de mogelijkheid om later makkelijk van provider te wisselen.
|
||||
|
||||
### Deepgram — behouden
|
||||
|
||||
| Eigenschap | Deepgram | Whisper | Azure Speech |
|
||||
|------------|----------|---------|-------------|
|
||||
| Nederlandse accuratesse | Goed | 36% meer fouten | Goed |
|
||||
| Streaming latency | <300ms | 500ms+ | ~300ms |
|
||||
| Prijs/1000 min | $4.30 | $6.00 | Variabel |
|
||||
|
||||
Deepgram is de beste keuze voor Nederlandse klinische spraak met streaming.
|
||||
|
||||
### pgvector voor RAG — behouden
|
||||
|
||||
Voldoende voor 100K documenten. Geen extra infra nodig.
|
||||
|
||||
### Embeddings — nieuw: MedRoBERTa.nl
|
||||
|
||||
**Belangrijke vinding**: Er bestaat een **MedRoBERTa.nl** model, specifiek getraind op Nederlandse Elektronische Patiëntendossiers.
|
||||
|
||||
| Model | Taal | Domein | Best voor |
|
||||
|-------|------|--------|-----------|
|
||||
| MedRoBERTa.nl | Nederlands | Medisch (EHR) | Klinische notities embeddings |
|
||||
| OpenAI text-embedding-3-large | Multi | Algemeen | Backup, managed service |
|
||||
|
||||
**Anthropic biedt geen eigen embeddings**. Partner is Voyage AI.
|
||||
|
||||
**Aanbeveling**: MedRoBERTa.nl als primary embedding model voor de RAG pipeline. OpenAI als fallback.
|
||||
|
||||
---
|
||||
|
||||
## 7. Compatibiliteitsmatrix — Werkt alles samen?
|
||||
|
||||
```
|
||||
Node.js 22 LTS ─────────────────────────────────────────────────
|
||||
│
|
||||
├── Next.js 16.1 LTS ──── React 19 ──── TypeScript 5.9
|
||||
│ ├── App Router (stabiel, productie-klaar)
|
||||
│ ├── Server Components (React 19 native)
|
||||
│ └── Server Actions (useActionState)
|
||||
│
|
||||
├── Drizzle ORM 0.45 ──── PostgreSQL 17 (Docker)
|
||||
│ ├── pgvector 0.7+ (RAG embeddings)
|
||||
│ ├── pg_trgm (fuzzy search)
|
||||
│ └── RLS via handmatige SQL migraties (NIET Drizzle)
|
||||
│
|
||||
├── Keycloak 26.5 ──── Auth.js v5 (met custom Keycloak wrapper)
|
||||
│ ├── SAML/OIDC
|
||||
│ ├── Azure AD federatie
|
||||
│ └── MFA (TOTP, WebAuthn)
|
||||
│
|
||||
├── Valkey 8+ (Redis-compatible) ──── node-redis
|
||||
│ ├── BullMQ 5.69 (job queue) [gebruikt intern ioredis]
|
||||
│ └── Caching (C37)
|
||||
│
|
||||
├── Vercel AI SDK ──── @ai-sdk/anthropic
|
||||
│ ├── Streaming SSE
|
||||
│ └── React hooks (useChat)
|
||||
│
|
||||
├── Deepgram API ──── Web Audio API (browser)
|
||||
│
|
||||
├── MedRoBERTa.nl ──── pgvector (embeddings → vector search)
|
||||
│
|
||||
├── Tailwind CSS 4.x ──── shadcn/ui 3.8+
|
||||
│ └── Lucide React 0.564
|
||||
│
|
||||
├── Zustand 5.0 (client state)
|
||||
├── Zod 4.3 (validatie)
|
||||
├── date-fns 4.1 (NL locale)
|
||||
├── Fuse.js 7.1 (fuzzy search client)
|
||||
└── React Hook Form (forms)
|
||||
|
||||
Infrastructure:
|
||||
├── Hetzner VPS (Amsterdam, €15-25/mnd)
|
||||
├── Docker Compose + GitHub Actions
|
||||
├── Caddy 2.10 (reverse proxy, auto-HTTPS)
|
||||
├── Pino 10.3 → Grafana Loki
|
||||
├── OpenTelemetry 2.x → Grafana Tempo
|
||||
└── Postal (email) of managed alternatief
|
||||
```
|
||||
|
||||
**Bekende incompatibiliteiten**: Geen. Alle componenten zijn getest samen of hebben bewezen compatibiliteit.
|
||||
|
||||
**Enige aandachtspunt**: BullMQ gebruikt intern ioredis. Als we node-redis kiezen voor onze eigen code, draaien er twee Redis clients. Dit is geen probleem (BullMQ beheert zijn eigen connections), maar het is goed om te weten.
|
||||
|
||||
---
|
||||
|
||||
## 8. Community Health Scorecard
|
||||
|
||||
| Technologie | npm/week | GitHub stars | Laatste release | Onderhoud | Score |
|
||||
|-------------|----------|-------------|-----------------|-----------|-------|
|
||||
| Next.js 16 | 14.7M | 135K | Actief | Vercel (bedrijf) | ⭐⭐⭐⭐⭐ |
|
||||
| React 19 | 20M+ | 207K | Jan 2026 | Meta (bedrijf) | ⭐⭐⭐⭐⭐ |
|
||||
| TypeScript | — | — | Actief | Microsoft | ⭐⭐⭐⭐⭐ |
|
||||
| Drizzle ORM | 4.7M | 32.8K | Recent | Community + bedrijf | ⭐⭐⭐⭐ |
|
||||
| PostgreSQL 17 | — | — | Feb 2026 | PostgreSQL Global Dev Group | ⭐⭐⭐⭐⭐ |
|
||||
| Keycloak 26.5 | — | — | Feb 2026 | Red Hat | ⭐⭐⭐⭐⭐ |
|
||||
| Auth.js v5 | — | — | Actief | Community | ⭐⭐⭐ |
|
||||
| BullMQ 5.69 | — | — | 14 uur geleden | Taskforce.sh | ⭐⭐⭐⭐ |
|
||||
| Valkey | — | — | Actief | Linux Foundation | ⭐⭐⭐⭐⭐ |
|
||||
| Caddy 2.10 | — | — | Actief | Community + bedrijf | ⭐⭐⭐⭐ |
|
||||
| Pino 10.3 | 17.5M | — | 3 dagen geleden | Community | ⭐⭐⭐⭐⭐ |
|
||||
| shadcn/ui | — | 107K | 8 dagen geleden | Community | ⭐⭐⭐⭐⭐ |
|
||||
| Tailwind 4.1 | — | — | Actief | Tailwind Labs | ⭐⭐⭐⭐⭐ |
|
||||
| Zustand 5.0 | — | — | 14 dagen geleden | pmndrs collective | ⭐⭐⭐⭐ |
|
||||
| Zod 4.3 | 44M | 41.3K | Actief | Community | ⭐⭐⭐⭐⭐ |
|
||||
| Deepgram | — | — | Actief | Deepgram (bedrijf) | ⭐⭐⭐⭐ |
|
||||
| Fuse.js 7.1 | — | — | ~10 mnd geleden | Community | ⭐⭐⭐ |
|
||||
| Postal | — | — | Actief | Krystal + community | ⭐⭐⭐ |
|
||||
| Coolify | — | 50.2K | Jan 2026 | Community | ⭐⭐⭐ (beta) |
|
||||
|
||||
---
|
||||
|
||||
## 9. Beslissingenlog (aanvullingen)
|
||||
|
||||
| # | Beslissing | Alternatieven | Rationale |
|
||||
|---|-----------|---------------|-----------|
|
||||
| D26 | Next.js 16 LTS + React 19 (upgrade van 14+18) | Blijven op 14 | Node 20 EOL april 2026, security hardening, React Compiler |
|
||||
| D27 | Node.js 22 LTS | Blijven op 20 | Node 20 EOL in 2 maanden |
|
||||
| D28 | Valkey i.p.v. Redis 7 | Redis 7, DragonflyDB | Open source, Linux Foundation, 3x performance, drop-in replacement |
|
||||
| D29 | node-redis i.p.v. ioredis | ioredis behouden | ioredis deprecated, node-redis officieel onderhouden |
|
||||
| D30 | Vercel AI SDK i.p.v. directe Anthropic SDK | @anthropic-ai/sdk | Minder boilerplate, provider-agnostisch, betere Next.js integratie |
|
||||
| D31 | MedRoBERTa.nl voor embeddings | OpenAI text-embedding-3, Voyage AI | Specifiek getraind op Nederlandse EHR data |
|
||||
| D32 | PostgreSQL 17 i.p.v. 16 | PostgreSQL 16 | 20x vacuum efficiëntie, parallel BRIN indexes |
|
||||
| D33 | Tailwind CSS v4 i.p.v. v3 | v3 behouden | 5x sneller builds, zero-config, minimale breaking changes |
|
||||
| D34 | Docker Compose + GH Actions (geen Coolify voor prod) | Coolify, CapRover | Coolify is beta, Docker Compose is bewezen voor single-server |
|
||||
| D35 | RLS policies in handmatige SQL (niet via Drizzle) | Drizzle RLS API | Drizzle verwijdert stiekem bestaande policies — te gevaarlijk |
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Bronnen
|
||||
|
||||
Alle feiten in dit document zijn gebaseerd op web research uitgevoerd op 2026-02-14. Belangrijkste bronnen per categorie:
|
||||
|
||||
**Frameworks**: Next.js releases/blog, React.dev versions, Node.js release schedule, TypeScript releases
|
||||
**Database**: PostgreSQL release notes, Drizzle ORM docs/GitHub issues, pgvector GitHub, npmjs.com
|
||||
**Auth**: Keycloak releases, Auth.js migration guide, NEN 7510 compliance guides
|
||||
**DevOps**: Coolify GitHub, Hetzner/Scaleway/Netcup vergelijkingen, Docker docs
|
||||
**Frontend**: npm trends, GitHub repositories, shadcn-ui/Tailwind/Zustand/Zod release pages
|
||||
**AI**: Anthropic SDK npm, Vercel AI SDK docs, Deepgram benchmarks, MedRoBERTa.nl research papers
|
||||
1461
docs/architecture/technische-invulling-componenten.md
Normal file
1461
docs/architecture/technische-invulling-componenten.md
Normal file
File diff suppressed because it is too large
Load Diff
864
docs/architecture/usecases-technische-componenten.md
Normal file
864
docs/architecture/usecases-technische-componenten.md
Normal file
@@ -0,0 +1,864 @@
|
||||
# Use Cases × Technische Componenten — Validatiematrix
|
||||
|
||||
> **Type**: Architectuur Validatiedocument
|
||||
> **Versie**: 1.0
|
||||
> **Datum**: 2026-02-14
|
||||
> **Doel**: Valideer of de enterprise architectuur alle use cases ondersteunt. Identificeer gaten.
|
||||
> **Relatie**: Valideert `enterprise-epd-architectuur.md` en `intent-system-architectuur-nl.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. Use Case Catalogus
|
||||
|
||||
Alle use cases uit de huidige codebase, uitgebreid met enterprise-scenario's die nog ontbreken.
|
||||
|
||||
### 1.1 Bestaande use cases (geïmplementeerd in prototype)
|
||||
|
||||
| ID | Use Case | Categorie | Intent | Status |
|
||||
|----|----------|-----------|--------|--------|
|
||||
| UC-01 | Dagnotitie aanmaken via spraak/tekst | Rapportage | `dagnotitie` | ✅ Volledig |
|
||||
| UC-02 | Rapportage tijdlijn bekijken (per shift) | Rapportage | — (UI) | ✅ Volledig |
|
||||
| UC-03 | Notitie markeren voor overdracht | Rapportage | — (UI) | ✅ Volledig |
|
||||
| UC-04 | Overdracht overzicht bekijken | Overdracht | `overdracht` | ✅ Volledig |
|
||||
| UC-05 | AI-samenvatting genereren voor overdracht | Overdracht | `overdracht` | ✅ Volledig |
|
||||
| UC-06 | Bronverwijzing volgen vanuit AI-samenvatting | Overdracht | — (UI) | ✅ Volledig |
|
||||
| UC-07 | Patiënt zoeken op naam/BSN | Zoeken | `zoeken` | ✅ Volledig |
|
||||
| UC-08 | Patiëntdossier openen | Navigatie | — (UI) | ✅ Volledig |
|
||||
| UC-09 | Agenda bekijken (vandaag/week) | Agenda | `agenda_query` | ✅ Volledig |
|
||||
| UC-10 | Afspraak aanmaken | Agenda | `create_appointment` | ✅ Volledig |
|
||||
| UC-11 | Afspraak annuleren | Agenda | `cancel_appointment` | ✅ Volledig |
|
||||
| UC-12 | Afspraak verzetten | Agenda | `reschedule_appointment` | ✅ Volledig |
|
||||
| UC-13 | Intake status bekijken | Intake | `intake_status` | ⚠️ MVP |
|
||||
| UC-14 | Risicotaxatie bekijken | Intake | `risico_query` | ⚠️ MVP |
|
||||
| UC-15 | Diagnoses bekijken | Intake | `diagnose_query` | ⚠️ MVP |
|
||||
| UC-16 | Navigeren naar intake-sectie | Intake | `intake_navigeer` | ⚠️ MVP |
|
||||
| UC-17 | Spraak-naar-tekst voor invoer | Invoer | — (Deepgram) | ✅ Volledig |
|
||||
| UC-18 | Samengestelde opdracht (multi-intent) | Classificatie | Meerdere | ✅ Volledig |
|
||||
| UC-19 | Context-afhankelijke verwijzingen ("hem", "haar") | Classificatie | — (Orchestrator) | ✅ Volledig |
|
||||
| UC-20 | Nudge na actie (vervolgactie suggestie) | Protocol | — (Nudge) | ⚠️ Code bestaat, niet aangeroepen |
|
||||
|
||||
### 1.2 Ontbrekende enterprise use cases
|
||||
|
||||
| ID | Use Case | Categorie | Waarom nodig |
|
||||
|----|----------|-----------|-------------|
|
||||
| UC-21 | Behandelplan opstellen en bijwerken | Behandeling | Kernfunctie GGZ-EPD |
|
||||
| UC-22 | Medicatieoverzicht bekijken/bijwerken | Medicatie | Wettelijk verplicht, hoog-risico |
|
||||
| UC-23 | Incident/MIC-melding registreren | Veiligheid | Wkkgz verplichting |
|
||||
| UC-24 | Wvggz-dwangmaatregel registreren | Juridisch | Wvggz verplichting |
|
||||
| UC-25 | Toestemming registreren/intrekken | Juridisch | AVG + Wvggz |
|
||||
| UC-26 | Audit log doorzoeken (compliance officer) | Audit | NEN 7513 verplichting |
|
||||
| UC-27 | Patiëntdata exporteren (FHIR Bundle) | Interoperabiliteit | Dataportabiliteit (AVG) |
|
||||
| UC-28 | Gebruikersbeheer (admin) | Beheer | Multi-tenancy |
|
||||
| UC-29 | Protocolregel toevoegen/valideren | Knowledge | Protocol Engine beheer |
|
||||
| UC-30 | Dashboard: team-overzicht per afdeling | Overzicht | Management informatie |
|
||||
| UC-31 | Rapportage verwijderen (soft delete) + versioning | Rapportage | Wkkgz dossierplicht |
|
||||
| UC-32 | Groepstherapie sessie rapporteren (meerdere patiënten) | Rapportage | GGZ-specifiek |
|
||||
| UC-33 | Noodtoegang ("break the glass") | Beveiliging | NEN 7510, noodsituaties |
|
||||
|
||||
---
|
||||
|
||||
## 2. Technische Componenten Register
|
||||
|
||||
Alle componenten die de architectuur beschrijft, met hun verantwoordelijkheid en status.
|
||||
|
||||
### 2.1 Component overzicht
|
||||
|
||||
```
|
||||
LAAG 1: INTERFACE
|
||||
├── C01 Traditionele EPD UI (Next.js pages + forms)
|
||||
├── C02 Intent Command Center (⌘K overlay)
|
||||
├── C03 Spraak Input (Deepgram integratie)
|
||||
└── C04 Block/Artifact systeem (canvas + forms)
|
||||
|
||||
LAAG 2: INTENT SYSTEEM
|
||||
├── C05 Intent Registry (declaratieve definities)
|
||||
├── C06 Reflex Classifier (lokale regex matching)
|
||||
├── C07 Orchestrator (LLM classificatie)
|
||||
├── C08 Entity Extractor + Date Parser
|
||||
├── C09 Action System (intent → UI artifact mapping)
|
||||
└── C10 Protocol Engine / Nudge
|
||||
|
||||
LAAG 3: KNOWLEDGE LAYER
|
||||
├── C11 Protocol Rules Store (gevalideerde regels)
|
||||
├── C12 RAG Pipeline (protocol indexering + vector search)
|
||||
├── C13 Regelvalidatie UI (admin)
|
||||
└── C14 Kennisbron Connectors (wet/protocol/kwaliteitsdoc importers)
|
||||
|
||||
LAAG 4: DOMEIN / BUSINESS LOGIC
|
||||
├── C15 Rapportage Service (CRUD, versioning, soft delete)
|
||||
├── C16 Overdracht Service (samenvatting generatie)
|
||||
├── C17 Agenda Service (CRUD, conflictdetectie)
|
||||
├── C18 Behandelplan Service
|
||||
├── C19 Medicatie Service
|
||||
├── C20 Intake Service
|
||||
├── C21 Patiënt Service (CRUD, zoeken, toewijzing)
|
||||
└── C22 Toestemming Service (Wvggz, AVG)
|
||||
|
||||
LAAG 5: ENTERPRISE FUNDAMENT
|
||||
├── C23 Auth + SSO (Supabase Auth, SAML)
|
||||
├── C24 Multi-tenancy (RLS, tenant context)
|
||||
├── C25 RBAC + ABAC Engine (policy evaluatie)
|
||||
├── C26 Audit Trail (NEN 7513 immutable log)
|
||||
├── C27 Field Encryption (AES-256-GCM)
|
||||
├── C28 FHIR Export Service
|
||||
├── C29 CDS Hooks Service
|
||||
├── C30 Observability (Pino, OpenTelemetry)
|
||||
├── C31 Circuit Breaker / Resilience
|
||||
├── C32 Health Check Service
|
||||
└── C33 PII Filter (sanitisatie voor AI prompts)
|
||||
|
||||
LAAG 6: PLATFORM SERVICES (zie enterprise-componenten-uitbreiding.md)
|
||||
├── C34 Notificatie Service (in-app + email + escalatie)
|
||||
├── C35 Workflow Engine (state machine voor klinische workflows)
|
||||
├── C36 Full-Text Search Service (klinische notities doorzoeken)
|
||||
├── C37 Caching Layer (AI responses, API responses, sessiedata)
|
||||
├── C38 Scheduled Jobs Service (BullMQ repeatable jobs)
|
||||
└── C39 Webhook System (outbound event webhooks)
|
||||
|
||||
LAAG 7: EXTERNE INTEGRATIES (zie enterprise-componenten-uitbreiding.md)
|
||||
├── C40 ZPM Facturatie Service (Zorgprestatiemodel)
|
||||
├── C41 Vecozo Connector (voorbereiding)
|
||||
└── C42 Zorgdomein Connector (voorbereiding)
|
||||
|
||||
LAAG 8: ANALYTICS (zie enterprise-componenten-uitbreiding.md)
|
||||
└── C43 BI Module (materialized views, data-export)
|
||||
```
|
||||
|
||||
### 2.2 Component status
|
||||
|
||||
| Component | Prototype status | Enterprise gereed? | Werk nodig |
|
||||
|-----------|-----------------|-------------------|------------|
|
||||
| C01 EPD UI | Gedeeltelijk (rapportage, overdracht, agenda) | Nee | Uitbreiden: behandelplan, medicatie, admin |
|
||||
| C02 Command Center | Volledig | Ja (refactor) | Store splitsen, Registry migratie |
|
||||
| C03 Spraak Input | Volledig | Ja | Minimale wijzigingen |
|
||||
| C04 Block/Artifact | Volledig | Ja | Uitbreiden met nieuwe block types |
|
||||
| C05 Intent Registry | 40% (patronen verspreid over code) | Nee | **Kernwijziging**: centraliseren in config/DB |
|
||||
| C06 Reflex Classifier | 85% werkend | Gedeeltelijk | Patronen naar Registry verplaatsen |
|
||||
| C07 Orchestrator | 85% werkend | Gedeeltelijk | Prompt extractie, unified pipeline |
|
||||
| C08 Entity Extractor | 60% werkend | Gedeeltelijk | Pattern tables externaliseren |
|
||||
| C09 Action System | 70% werkend | Gedeeltelijk | Meer artifact types |
|
||||
| C10 Protocol Engine | 30% (code niet aangeroepen) | Nee | **Nieuw bouwen** op basis van Knowledge Layer |
|
||||
| C11 Protocol Rules Store | 0% | Nee | **Volledig nieuw** |
|
||||
| C12 RAG Pipeline | 0% | Nee | **Volledig nieuw** |
|
||||
| C13 Regelvalidatie UI | 0% | Nee | **Volledig nieuw** |
|
||||
| C14 Kennisbron Connectors | 0% | Nee | **Volledig nieuw** |
|
||||
| C15 Rapportage Service | 80% (CRUD werkt) | Nee | Versioning, multi-tenant |
|
||||
| C16 Overdracht Service | 90% werkend | Gedeeltelijk | Multi-tenant, audit integratie |
|
||||
| C17 Agenda Service | 80% werkend | Gedeeltelijk | Conflictdetectie, multi-tenant |
|
||||
| C18 Behandelplan Service | 0% | Nee | **Volledig nieuw** |
|
||||
| C19 Medicatie Service | 0% | Nee | **Volledig nieuw** |
|
||||
| C20 Intake Service | 40% (MVP blocks) | Nee | Uitbreiden, multi-tenant |
|
||||
| C21 Patiënt Service | 70% | Nee | Toewijzing, multi-tenant |
|
||||
| C22 Toestemming Service | 0% | Nee | **Volledig nieuw** |
|
||||
| C23 Auth + SSO | 60% (Supabase Auth) | Nee | SSO/SAML, MFA, session management |
|
||||
| C24 Multi-tenancy | 0% | Nee | **Volledig nieuw** |
|
||||
| C25 RBAC + ABAC | 10% (basis RLS) | Nee | **Grotendeels nieuw** |
|
||||
| C26 Audit Trail | 0% | Nee | **Volledig nieuw** |
|
||||
| C27 Field Encryption | 0% | Nee | **Volledig nieuw** |
|
||||
| C28 FHIR Export | 10% (Patient endpoint) | Nee | Uitbreiden naar alle resources |
|
||||
| C29 CDS Hooks | 0% | Nee | **Volledig nieuw** |
|
||||
| C30 Observability | 10% (console.log) | Nee | **Grotendeels nieuw** |
|
||||
| C31 Circuit Breaker | 20% (classifyWithTimeout) | Nee | Generaliseren |
|
||||
| C32 Health Check | 0% | Nee | **Volledig nieuw** |
|
||||
| C33 PII Filter | 40% (logger.ts sanitisatie) | Nee | Uitbreiden voor AI prompts |
|
||||
|
||||
---
|
||||
|
||||
## 3. Validatiematrix — Use Case × Component
|
||||
|
||||
Elke cel toont welke componenten een use case nodig heeft. **Rode cellen** zijn gaten.
|
||||
|
||||
### 3.1 Rapportage use cases
|
||||
|
||||
#### UC-01: Dagnotitie aanmaken via spraak/tekst
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Zorgverlener spreekt/typt → "Notitie Jan medicatie onrustige nacht"
|
||||
|
||||
┌─────────────┐
|
||||
│ C03 Spraak │ (optioneel) Audio → tekst
|
||||
│ of C02 ⌘K │ Tekst invoer
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C05 Registry │────►│ C06 Reflex │ Pattern match: "notitie" → dagnotitie
|
||||
└──────────────┘ └──────┬───────┘
|
||||
│ confidence 0.9
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C08 Entity │ "Jan" → patient fuzzy match
|
||||
│ Extractor │ "medicatie" → category
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C09 Action │ Open dagnotitie-block met prefill
|
||||
│ System │ { patient: Jan, category: medicatie }
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C04 Block │ Formulier met vooringevulde data
|
||||
│ (UI) │ Gebruiker bevestigt + voegt content toe
|
||||
└──────┬───────┘
|
||||
│ [gebruiker klikt "Opslaan"]
|
||||
▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C25 RBAC │────►│ C15 Rapportage│ Insert report
|
||||
│ check │ │ Service │ shift_date berekend
|
||||
└──────────────┘ └──────┬───────┘
|
||||
│
|
||||
┌─────────────────────┤
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C26 Audit │ │ C10 Protocol │ Evalueer nudges
|
||||
│ Trail │ │ Engine │ → "Check vitale functies?"
|
||||
└──────────────┘ └──────────────┘
|
||||
|
||||
COMPONENTEN NODIG: C02/C03, C05, C06, C08, C09, C04, C25, C15, C26, C10
|
||||
GATEN:
|
||||
🔴 C05 Intent Registry bestaat niet als centraal component
|
||||
🔴 C25 RBAC check ontbreekt volledig
|
||||
🔴 C26 Audit trail ontbreekt volledig
|
||||
🔴 C10 Protocol Engine is niet aangesloten (code bestaat, niet aangeroepen)
|
||||
🟡 C15 Rapportage Service mist versioning en multi-tenant
|
||||
```
|
||||
|
||||
#### UC-05: AI-samenvatting genereren voor overdracht
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Zorgverlener → "Overdracht" of klikt in UI
|
||||
|
||||
┌─────────────┐
|
||||
│ C02 ⌘K │ of C01 UI → navigatie naar overdracht pagina
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C06 Reflex │────►│ C09 Action │ Open overdracht-block
|
||||
└──────────────┘ └──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C16 Overdracht│ Haal patiëntenlijst op
|
||||
│ Service │ Filter op afdeling/dienst
|
||||
└──────┬───────┘
|
||||
│ [voor elke actieve patiënt]
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C33 PII │ Minimaliseer patiëntdata voor AI
|
||||
│ Filter │
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C07 Claude │ Genereer samenvatting
|
||||
│ API │ Aandachtspunten + actiepunten
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌──────┴───────┐
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C26 Audit │ │ C04 Block │ Render samenvatting
|
||||
│ Trail │ │ (UI) │ met bronverwijzingen
|
||||
└──────────────┘ └──────────────┘
|
||||
|
||||
COMPONENTEN NODIG: C01/C02, C06, C09, C16, C33, C07 (Claude), C26, C04
|
||||
GATEN:
|
||||
🔴 C26 Audit trail ontbreekt — wie heeft welke samenvatting gegenereerd?
|
||||
🔴 C33 PII filter is onvolledig — welke data gaat naar Claude?
|
||||
🟡 C16 Overdracht Service mist tenant-filtering
|
||||
🟡 Geen caching — elke keer opnieuw genereren is duur
|
||||
```
|
||||
|
||||
#### UC-31: Rapportage verwijderen + versioning
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Zorgverlener wil rapport wijzigen of verwijderen
|
||||
|
||||
┌─────────────┐
|
||||
│ C01 UI │ Klik op "bewerken" of "verwijderen" in tijdlijn
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C25 RBAC │ Mag deze gebruiker dit rapport wijzigen?
|
||||
│ + ABAC │ Check: auteur OF hoofdbehandelaar OF admin
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C15 Rapportage│ WIJZIGEN: nieuwe versie aanmaken
|
||||
│ Service │ → version++, previous_version_id link
|
||||
│ │ VERWIJDEREN: soft delete (deleted_at)
|
||||
│ │ → NOOIT hard delete (Wkkgz)
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C26 Audit │ Log: wie, wat, wanneer, waarom
|
||||
│ Trail │ + data_before / data_after snapshot
|
||||
└──────────────┘
|
||||
|
||||
COMPONENTEN NODIG: C01, C25, C15, C26
|
||||
GATEN:
|
||||
🔴 C15 Rapportage Service heeft GEEN versioning (alleen soft delete)
|
||||
🔴 C25 Eigenaarschap-check ontbreekt
|
||||
🔴 C26 Audit trail ontbreekt — geen bewijs van wijzigingen
|
||||
```
|
||||
|
||||
### 3.2 Enterprise use cases (nieuw)
|
||||
|
||||
#### UC-23: Incident/MIC-melding registreren
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Zorgverlener → "Incident melding: patiënt gevallen op kamer 3"
|
||||
|
||||
┌─────────────┐
|
||||
│ C02 ⌘K │ "incident melding patiënt gevallen"
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C06 Reflex │ Pattern: "incident" / "melding" / "MIC" / "gevallen"
|
||||
│ │ → intent: NEW "incident_melding" (ONTBREEKT)
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C08 Entity │ Extraheer: patiënt, locatie, type incident
|
||||
│ Extractor │ "gevallen" → incident_type: "val"
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C09 Action │ Open incident-formulier (ONTBREEKT)
|
||||
│ │ Velden: patiënt, datum/tijd, locatie, beschrijving,
|
||||
│ │ ernst, getuigen, maatregelen genomen
|
||||
└──────┬───────┘
|
||||
│ [gebruiker bevestigt]
|
||||
▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C15 Rapportage│ │ C26 Audit │
|
||||
│ report_type:│ │ Trail │
|
||||
│ 'incident' │ └──────────────┘
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C10 Protocol │ Nudges:
|
||||
│ Engine │ → "Valpreventie protocol activeren?"
|
||||
│ │ → "Informeer hoofdbehandelaar"
|
||||
│ │ → "Plan follow-up observatie"
|
||||
└──────────────┘
|
||||
|
||||
COMPONENTEN NODIG: C02, C06, C08, C09, C04, C15, C26, C10
|
||||
NIEUWE COMPONENTEN NODIG:
|
||||
🔴 Intent 'incident_melding' toevoegen aan Registry
|
||||
🔴 Incident-formulier block (UI component)
|
||||
🔴 Protocol rules voor incidentopvolging
|
||||
🟡 Ernst-classificatie schema
|
||||
🟡 Notificatie naar hoofdbehandelaar (C-NEW: Notificatie Service)
|
||||
```
|
||||
|
||||
#### UC-24: Wvggz-dwangmaatregel registreren
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Arts → Registreer dwangmaatregel (bijv. separatie, gedwongen medicatie)
|
||||
|
||||
┌─────────────┐
|
||||
│ C01 UI │ Via traditionele formulier (te complex voor intent)
|
||||
│ │ OF C02 ⌘K → "dwangmaatregel registreren [patient]"
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C25 RBAC │ Check: alleen arts/psychiater mag dwangmaatregel registreren
|
||||
│ + ABAC │ Check: patiënt heeft Wvggz legal_status
|
||||
│ │ Check: toestemming/machtiging is actief (C22)
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ NEW: C34 │ Dwangmaatregel formulier
|
||||
│ Wvggz Service │ Velden: type maatregel, start/eind, reden,
|
||||
│ │ alternatieven overwogen, proportionaliteit
|
||||
│ │ Juridische grondslag (zorgmachtiging nr.)
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ C22 Toestem- │ │ C26 Audit │ EXTRA LOGGING:
|
||||
│ ming Service│ │ Trail │ Wvggz-maatregel = P1 audit event
|
||||
│ Verify OK │ │ │ purpose: 'wvggz_dwangmaatregel'
|
||||
└──────────────┘ └──────────────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C10 Protocol │ Nudges:
|
||||
│ Engine │ → "Plan evaluatie dwangmaatregel (binnen 24u)"
|
||||
│ │ → "Informeer geneesheer-directeur"
|
||||
│ │ → "Registreer in Wvggz-register"
|
||||
└──────────────┘
|
||||
|
||||
NIEUWE COMPONENTEN NODIG:
|
||||
🔴 C34 Wvggz Service (registratie, evaluatie, rapportage)
|
||||
🔴 C22 Toestemming Service (verificatie juridische grondslag)
|
||||
🔴 Wvggz-specifieke ABAC policies
|
||||
🔴 Protocol rules voor Wvggz-termijnen
|
||||
🔴 Notificatie naar geneesheer-directeur
|
||||
```
|
||||
|
||||
#### UC-26: Audit log doorzoeken
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Compliance officer → "Wie heeft dossier patiënt X bekeken afgelopen maand?"
|
||||
|
||||
┌─────────────┐
|
||||
│ C01 UI │ Admin → Audit log pagina
|
||||
│ (admin) │ Zoekfilters: patiënt, gebruiker, periode, actie
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C25 RBAC │ Check: rol = 'audit' of 'admin'
|
||||
│ │ Audit officers hebben read-only toegang tot ALLE logs
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C26 Audit │ Query: forensische zoekopdracht
|
||||
│ Trail │ Filters: entity_type, entity_id, user_id, date range
|
||||
│ │ Resultaat: gesorteerd op timestamp
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C26 Audit │ META: het doorzoeken van de audit log
|
||||
│ Trail │ wordt ZELF ook gelogd (wie zoekt wat op)
|
||||
└──────────────┘
|
||||
|
||||
COMPONENTEN NODIG: C01, C25, C26
|
||||
GATEN:
|
||||
🔴 C26 Audit log UI (admin pagina) ontbreekt volledig
|
||||
🔴 Export functie (CSV/PDF voor externe auditor)
|
||||
🟡 Anomalie-detectie dashboard
|
||||
```
|
||||
|
||||
#### UC-33: Noodtoegang ("break the glass")
|
||||
|
||||
```
|
||||
FLOW:
|
||||
Arts in noodsituatie → toegang nodig tot patiënt die niet is toegewezen
|
||||
|
||||
┌─────────────┐
|
||||
│ C01 UI │ Patiëntdossier → "Geen toegang" melding
|
||||
│ │ → Knop: "Noodtoegang aanvragen"
|
||||
└──────┬──────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C25 RBAC │ Normale check FAALT (niet toegewezen)
|
||||
│ + ABAC │ → Noodtoegang flow activeren
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────────────────────────────┐
|
||||
│ NEW: Break-the-Glass Dialog │
|
||||
│ "U bent niet toegewezen aan deze │
|
||||
│ patiënt. Noodtoegang vereist een │
|
||||
│ reden." │
|
||||
│ │
|
||||
│ Reden: [dropdown] │
|
||||
│ - Medisch noodgeval │
|
||||
│ - Dienstdoend arts (geen toewijzing) │
|
||||
│ - Vervanging collega │
|
||||
│ Toelichting: [vrij tekstveld] │
|
||||
│ │
|
||||
│ [Annuleren] [Noodtoegang activeren] │
|
||||
└──────┬───────────────────────────────┘
|
||||
│ [gebruiker bevestigt]
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C26 Audit │ P1 AUDIT EVENT:
|
||||
│ Trail │ action: 'emergency_access'
|
||||
│ │ purpose: reden uit formulier
|
||||
│ │ → Automatische notificatie naar privacy officer
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ C21 Patiënt │ Tijdelijke toegang (bijv. 4 uur)
|
||||
│ Service │ Auto-expire na timeout
|
||||
└──────────────┘
|
||||
|
||||
NIEUWE COMPONENTEN NODIG:
|
||||
🔴 Break-the-glass UI component
|
||||
🔴 Tijdelijke toegang mechanisme in C25
|
||||
🔴 Automatische notificatie service
|
||||
🔴 Auto-expire logica
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Gap Analyse — Samenvatting
|
||||
|
||||
### 4.1 Kritieke gaten (blokkeren enterprise deployment)
|
||||
|
||||
| # | Gap | Impact | Benodigde componenten | Inspanning |
|
||||
|---|-----|--------|----------------------|------------|
|
||||
| G1 | **Geen audit trail** | NEN 7513 niet-compliant, geen bewijs bij audit | C26 volledig bouwen | 2-3 weken |
|
||||
| G2 | **Geen multi-tenancy** | Kan niet bij meerdere instellingen draaien | C24 volledig bouwen | 2-3 weken |
|
||||
| G3 | **Geen RBAC/ABAC** | Iedereen ziet alles, geen rolgebaseerde toegang | C25 volledig bouwen | 2-3 weken |
|
||||
| G4 | **Intent Registry ontbreekt** | Patronen verspreid over 3-4 bestanden | C05 centraliseren | 2-3 dagen |
|
||||
| G5 | **Protocol Engine niet actief** | Nudges bestaan maar worden nooit getoond | C10 aansluiten + C11 rules store | 1-2 weken |
|
||||
| G6 | **Geen versioning op rapportages** | Wijzigingsgeschiedenis niet traceerbaar | C15 uitbreiden | 3-5 dagen |
|
||||
| G7 | **Geen field encryptie** | BSN en diagnoses onversleuteld in DB | C27 bouwen | 1 week |
|
||||
|
||||
### 4.2 Functionele gaten (ontbrekende GGZ-modules)
|
||||
|
||||
| # | Gap | Impact | Inspanning |
|
||||
|---|-----|--------|------------|
|
||||
| G8 | **Behandelplan module** | Kernfunctie GGZ ontbreekt volledig | C18: 3-4 weken |
|
||||
| G9 | **Medicatie module** | Wettelijk verplicht, hoog-risico domein | C19: 3-4 weken |
|
||||
| G10 | **Wvggz registratie** | Kan geen verplichte zorg registreren | C34 + C22: 2-3 weken |
|
||||
| G11 | **Incident/MIC module** | Wkkgz niet-compliant | Uitbreiding C15 + intent: 1-2 weken |
|
||||
| G12 | **Knowledge Layer** | Geen protocol-gestuurde nudges | C11-C14: 4-6 weken |
|
||||
|
||||
### 4.3 Technische gaten
|
||||
|
||||
| # | Gap | Impact | Inspanning |
|
||||
|---|-----|--------|------------|
|
||||
| G13 | **Geen SSO/SAML** | Enterprise instellingen vereisen SSO | C23 uitbreiden: 1 week |
|
||||
| G14 | **Geen structured logging** | Console.log in productie = blind vliegen | C30: 1 week |
|
||||
| G15 | **Geen health checks** | Geen alerting bij uitval | C32: 2-3 dagen |
|
||||
| G16 | **Circuit breaker incompleet** | Alleen voor classify, niet generiek | C31 generaliseren: 3-5 dagen |
|
||||
| G17 | **PII filter incompleet** | Patiëntdata lekt naar AI prompts | C33 uitbreiden: 3-5 dagen |
|
||||
| G18 | **Geen FHIR Bundle export** | Alleen Patient endpoint, rest ontbreekt | C28 uitbreiden: 1-2 weken |
|
||||
| G19 | **Geen notificatie service** | Geen alerts bij incidenten, Wvggz-termijnen | Nieuw component: 1-2 weken |
|
||||
| G20 | **Geen caching** | AI samenvattingen elke keer opnieuw genereren | Cache layer toevoegen: 3-5 dagen |
|
||||
|
||||
---
|
||||
|
||||
## 5. Use Case × Component Kruistabel
|
||||
|
||||
Welk component is nodig voor welke use case? `●` = nodig, `○` = optioneel, `-` = niet relevant.
|
||||
|
||||
```
|
||||
UC UC UC UC UC UC UC UC UC UC UC UC UC
|
||||
Component 01 05 07 10 11 21 23 24 26 27 31 32 33
|
||||
dag ovdr zoek afsp ann beh inc wvgz aud fhir ver grp nood
|
||||
─────────────────────────────────────────────────────────────────────────────
|
||||
C01 EPD UI ○ ● ○ ○ ○ ● ● ● ● ● ● ● ●
|
||||
C02 Command Center ● ● ● ● ● ○ ● ○ - - - ○ -
|
||||
C03 Spraak ○ - - - - - ○ - - - - ○ -
|
||||
C04 Block/Artifact ● ● ● ● ● - ● - - - - - -
|
||||
C05 Intent Registry ● ● ● ● ● - ● - - - - - -
|
||||
C06 Reflex ● ● ● ● ● - ● - - - - - -
|
||||
C07 Orchestrator ○ ○ ○ ○ ○ - ○ - - - - - -
|
||||
C08 Entity Extract ● - ● ● ● - ● - - - - - -
|
||||
C09 Action System ● ● ● ● ● - ● - - - - - -
|
||||
C10 Protocol Engine ● ● - - - ● ● ● - - - - -
|
||||
C15 Rapportage Svc ● ● - - - - ● - - - ● ● -
|
||||
C16 Overdracht Svc - ● - - - - - - - - - - -
|
||||
C17 Agenda Svc - - - ● ● - - - - - - - -
|
||||
C18 Behandelplan - - - - - ● - - - ○ - - -
|
||||
C21 Patiënt Svc ● ● ● ● - ● ● ● - ● - - ●
|
||||
C22 Toestemming - - - - - - - ● - - - - -
|
||||
C24 Multi-tenancy ● ● ● ● ● ● ● ● ● ● ● ● ●
|
||||
C25 RBAC/ABAC ● ● ● ● ● ● ● ● ● ● ● ● ●
|
||||
C26 Audit Trail ● ● ● ● ● ● ● ● ● ● ● ● ●
|
||||
C27 Field Encrypt - - ○ - - - - ● - ● - - -
|
||||
C28 FHIR Export - - - - - - - - - ● - - -
|
||||
C30 Observability ● ● ● ● ● ● ● ● ● ● ● ● ●
|
||||
C31 Circuit Breaker ○ ● - - - - - - - - - - -
|
||||
C33 PII Filter ○ ● - - - - - - - - - - -
|
||||
C34 Wvggz Svc - - - - - - - ● - - - - -
|
||||
```
|
||||
|
||||
**Leeswijzer**: C24 (Multi-tenancy), C25 (RBAC), C26 (Audit) en C30 (Observability) zijn nodig voor **elke** use case. Dit zijn de vier horizontale lagen die als eerste gebouwd moeten worden.
|
||||
|
||||
---
|
||||
|
||||
## 6. Bouwvolgorde — Prioritering op basis van gaps
|
||||
|
||||
### Fase 0: Horizontale lagen (weken 1-4)
|
||||
|
||||
Bouw de vier componenten die **elke** use case nodig heeft:
|
||||
|
||||
```
|
||||
Week 1-2: C24 Multi-tenancy (RLS, tenant context middleware)
|
||||
C26 Audit Trail (immutable log, NEN 7513)
|
||||
|
||||
Week 3-4: C25 RBAC + ABAC Engine (rollen, policies, evaluatie)
|
||||
C30 Observability (Pino structured logging)
|
||||
```
|
||||
|
||||
**Waarom eerst**: Zonder deze vier werkt geen enkele enterprise use case. Retrofit is exponentieel duurder.
|
||||
|
||||
### Fase 1: Intent systeem solide maken (weken 5-6)
|
||||
|
||||
```
|
||||
Week 5: C05 Intent Registry (centraliseer patronen uit reflex-classifier)
|
||||
C06 Reflex refactor (lees uit Registry)
|
||||
C07 Orchestrator refactor (unified pipeline met Classify)
|
||||
|
||||
Week 6: C10 Protocol Engine activeren (nudge.ts aansluiten)
|
||||
C15 Rapportage versioning + soft delete (G6)
|
||||
C33 PII Filter uitbreiden
|
||||
```
|
||||
|
||||
**Na deze fase**: UC-01 t/m UC-20 werken enterprise-grade.
|
||||
|
||||
### Fase 2: Ontbrekende GGZ-modules (weken 7-12)
|
||||
|
||||
```
|
||||
Week 7-8: C18 Behandelplan Service (UC-21)
|
||||
C19 Medicatie Service (UC-22)
|
||||
|
||||
Week 9-10: C22 Toestemming Service (UC-25)
|
||||
C34 Wvggz Service (UC-24)
|
||||
UC-23 Incident/MIC formulier
|
||||
|
||||
Week 11-12: C27 Field Encryption (BSN, diagnoses)
|
||||
C23 Auth uitbreiden (SSO/SAML, MFA)
|
||||
UC-33 Break-the-glass noodtoegang
|
||||
```
|
||||
|
||||
### Fase 3: Knowledge Layer + interoperabiliteit (weken 13-18)
|
||||
|
||||
```
|
||||
Week 13-14: C11 Protocol Rules Store (database)
|
||||
C13 Regelvalidatie UI (admin)
|
||||
|
||||
Week 15-16: C12 RAG Pipeline (pgvector, protocol indexering)
|
||||
C14 Kennisbron Connectors (eerste protocollen inladen)
|
||||
|
||||
Week 17-18: C28 FHIR Export (alle resources)
|
||||
C29 CDS Hooks Service
|
||||
C32 Health Check + C31 Circuit Breaker generaliseren
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Technische Specificaties per Component
|
||||
|
||||
### 7.1 C24 Multi-tenancy — Specificatie
|
||||
|
||||
**Verantwoordelijkheid**: Isoleer data per instelling/tenant.
|
||||
|
||||
**Database wijzigingen**:
|
||||
- `tenant_id UUID NOT NULL` kolom op ELKE tabel met patiëntdata
|
||||
- RLS policy per tabel: `USING (tenant_id = get_current_tenant())`
|
||||
- Helper function: `get_current_tenant()` leest uit `app.current_tenant_id` setting
|
||||
|
||||
**Middleware**:
|
||||
```typescript
|
||||
// Elke request:
|
||||
// 1. Haal user op uit Supabase Auth
|
||||
// 2. Lees tenant_id uit user metadata
|
||||
// 3. Zet als header voor Server Components
|
||||
// 4. Zet als PostgreSQL setting voor RLS
|
||||
```
|
||||
|
||||
**Bestanden**:
|
||||
- `lib/auth/tenant-context.ts` — Helper om tenant te zetten/lezen
|
||||
- `middleware.ts` — Injecteer tenant in elke request
|
||||
- Migratie: `add_tenant_id_to_all_tables.sql`
|
||||
- Migratie: `create_rls_policies.sql`
|
||||
|
||||
**Test**: Maak twee tenants, voeg patiënt toe aan tenant A, verifieer dat tenant B de patiënt NIET kan zien.
|
||||
|
||||
---
|
||||
|
||||
### 7.2 C26 Audit Trail — Specificatie
|
||||
|
||||
**Verantwoordelijkheid**: Onwijzigbare log van alle toegang en wijzigingen aan patiëntdata.
|
||||
|
||||
**Database**:
|
||||
- Tabel `audit_logs` (zie enterprise-epd-architectuur.md §5.2)
|
||||
- Partitionering per maand
|
||||
- Triggers die UPDATE/DELETE blokkeren
|
||||
- Hash chain voor integriteitsverificatie
|
||||
|
||||
**API**:
|
||||
```typescript
|
||||
// lib/audit/logger.ts
|
||||
logAuditEvent({ entityType, entityId, action, purpose, cortexIntent?, metadata? })
|
||||
|
||||
// Automatisch:
|
||||
// - user_id, user_role, user_name uit auth context
|
||||
// - tenant_id uit tenant context
|
||||
// - timestamp server-side
|
||||
// - data_hash berekend
|
||||
// - previous_hash opgehaald
|
||||
```
|
||||
|
||||
**Integratiepunten**: Elke API route roept `logAuditEvent()` aan na succesvolle actie. Dit is een **hard requirement** — geen route zonder audit log.
|
||||
|
||||
**Bestanden**:
|
||||
- `lib/audit/logger.ts` — Core logging functie
|
||||
- `lib/audit/hash.ts` — Hash chain berekening
|
||||
- `app/api/audit/route.ts` — Query endpoint (admin only)
|
||||
- Migratie: `create_audit_logs.sql`
|
||||
|
||||
---
|
||||
|
||||
### 7.3 C25 RBAC + ABAC — Specificatie
|
||||
|
||||
**Verantwoordelijkheid**: Bepaal of een gebruiker een actie mag uitvoeren op een resource.
|
||||
|
||||
**Twee lagen**:
|
||||
1. **RBAC** (snel): Rol → vaste permissions set
|
||||
2. **ABAC** (verfijnd): Context-afhankelijke policies (toewijzing, toestemming, tijdvenster)
|
||||
|
||||
**API**:
|
||||
```typescript
|
||||
// lib/access-control/evaluator.ts
|
||||
const { allowed, reason } = await evaluateAccess({
|
||||
userId, action, resource, resourceId, tenantId
|
||||
});
|
||||
|
||||
if (!allowed) {
|
||||
return Response.json({ error: 'Geen toegang', reason }, { status: 403 });
|
||||
}
|
||||
```
|
||||
|
||||
**Bestanden**:
|
||||
- `lib/access-control/roles.ts` — Rol definities en basis permissions
|
||||
- `lib/access-control/policies.ts` — ABAC policy definities
|
||||
- `lib/access-control/evaluator.ts` — Policy evaluatie engine
|
||||
- Migratie: `create_access_policies.sql`
|
||||
|
||||
---
|
||||
|
||||
### 7.4 C05 Intent Registry — Specificatie
|
||||
|
||||
**Verantwoordelijkheid**: Single source of truth voor alle intent definities.
|
||||
|
||||
**Structuur per intent**:
|
||||
```typescript
|
||||
interface IntentDefinition {
|
||||
id: CortexIntent; // 'dagnotitie', 'zoeken', etc.
|
||||
label: { nl: string; en: string }; // Mensleesbare labels
|
||||
description: string; // Voor LLM context
|
||||
priority: 'P1' | 'P2' | 'P3';
|
||||
|
||||
// Reflex patterns
|
||||
reflexPatterns: Array<{
|
||||
pattern: RegExp;
|
||||
weight: number;
|
||||
extractHints?: string[]; // Welke entities te extracten
|
||||
}>;
|
||||
|
||||
// Orchestrator hints
|
||||
aiExamples: Array<{
|
||||
input: string;
|
||||
expectedIntent: CortexIntent;
|
||||
expectedEntities: Record<string, string>;
|
||||
}>;
|
||||
|
||||
// Entity configuratie
|
||||
entities: {
|
||||
required: string[]; // Welke entities verplicht
|
||||
optional: string[];
|
||||
};
|
||||
|
||||
// Action mapping
|
||||
artifactType: string; // Welk block/formulier openen
|
||||
requiresConfirmation: boolean; // Destructieve actie?
|
||||
|
||||
// Access control
|
||||
allowedRoles?: string[]; // Welke rollen mogen dit intent gebruiken
|
||||
featureFlag?: string; // Feature flag voor geleidelijke uitrol
|
||||
enabled: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
**Opslag**: TypeScript config file (fase 1), migreerbaar naar database (fase 3).
|
||||
|
||||
**Bestanden**:
|
||||
- `lib/cortex/registry/intent-registry.ts` — Registry class
|
||||
- `lib/cortex/registry/definitions/dagnotitie.ts` — Per intent een definitie
|
||||
- `lib/cortex/registry/definitions/zoeken.ts`
|
||||
- `lib/cortex/registry/definitions/index.ts` — Barrel export
|
||||
- `lib/cortex/registry/types.ts` — IntentDefinition interface
|
||||
|
||||
---
|
||||
|
||||
### 7.5 C10 Protocol Engine — Specificatie
|
||||
|
||||
**Verantwoordelijkheid**: Evalueer klinische regels na afgeronde acties. Stel vervolgacties voor.
|
||||
|
||||
**Pure function**: `(completedAction, patientContext, rules) → suggestions[]`
|
||||
|
||||
**Regel evaluatie**:
|
||||
```typescript
|
||||
// lib/cortex/protocol-engine/evaluator.ts
|
||||
|
||||
async function evaluateRules(
|
||||
completedAction: CompletedAction,
|
||||
patientContext: PatientContext,
|
||||
rules: ProtocolRule[]
|
||||
): Promise<NudgeSuggestion[]> {
|
||||
|
||||
const applicableRules = rules.filter(rule =>
|
||||
rule.status === 'actief' &&
|
||||
rule.trigger.afterIntent?.includes(completedAction.intent)
|
||||
);
|
||||
|
||||
const suggestions: NudgeSuggestion[] = [];
|
||||
|
||||
for (const rule of applicableRules) {
|
||||
const conditionMet = await evaluateCondition(rule.condition, patientContext);
|
||||
if (conditionMet) {
|
||||
suggestions.push({
|
||||
ruleId: rule.id,
|
||||
message: rule.suggestion.message,
|
||||
priority: rule.suggestion.priority,
|
||||
evidence: rule.suggestion.evidence,
|
||||
suggestedIntent: rule.suggestion.suggestedIntent,
|
||||
source: rule.source,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions.sort((a, b) =>
|
||||
a.priority.localeCompare(b.priority) // P1 eerst
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**Bestanden**:
|
||||
- `lib/cortex/protocol-engine/evaluator.ts` — Rule evaluatie
|
||||
- `lib/cortex/protocol-engine/conditions.ts` — Conditie evaluatie (static + query)
|
||||
- `lib/cortex/protocol-engine/rules/` — Gevalideerde regels per domein
|
||||
- `app/api/cortex/nudge/route.ts` — API endpoint
|
||||
|
||||
---
|
||||
|
||||
## 8. Validatie Conclusie
|
||||
|
||||
### De architectuur ondersteunt alle use cases MITS:
|
||||
|
||||
1. **De vier horizontale lagen eerst gebouwd worden** (G1-G3 + G14): multi-tenancy, audit, RBAC, logging
|
||||
2. **Het intent systeem gecentraliseerd wordt** (G4): Intent Registry als single source of truth
|
||||
3. **De Protocol Engine aangesloten wordt** (G5): nudge.ts → protocol-engine met rules store
|
||||
4. **Ontbrekende GGZ-modules gebouwd worden** (G8-G12): behandelplan, medicatie, Wvggz, incidenten
|
||||
|
||||
### Wat de architectuur GOED doet:
|
||||
|
||||
- Dual interface (traditioneel + intent) ondersteunt alle use cases via twee paden
|
||||
- De pipeline (Registry → Classify → Resolve → Action → Protocol) is generiek genoeg voor nieuwe intents
|
||||
- Multi-tenancy via RLS is pragmatisch en past bij Supabase
|
||||
- Audit trail als horizontale laag dekt alle use cases zonder per-module implementatie
|
||||
|
||||
### Wat nog aandacht nodig heeft:
|
||||
|
||||
- ~~**Notificatie service** (niet in architectuur): incidenten, Wvggz-termijnen, break-the-glass alerts~~ → **Opgelost: C34** (zie `enterprise-componenten-uitbreiding.md`)
|
||||
- **Groepstherapie** (UC-32): één rapportage voor meerdere patiënten — huidige datamodel is 1:1
|
||||
- ~~**Caching strategie**: AI-samenvattingen zijn duur, caching ontbreekt in architectuur~~ → **Opgelost: C37** (zie `enterprise-componenten-uitbreiding.md`)
|
||||
- **Offline support**: niet besproken, maar relevant voor mobiele zorgverleners
|
||||
|
||||
### Uitbreiding: 10 nieuwe componenten (C34–C43)
|
||||
|
||||
Na de initiële gap analyse zijn 10 aanvullende enterprise componenten geïdentificeerd en gespecificeerd. Deze zijn gedocumenteerd in **`enterprise-componenten-uitbreiding.md`** en omvatten:
|
||||
|
||||
| Component | Laag | Status |
|
||||
|-----------|------|--------|
|
||||
| C34 Notificatie Service | Platform Services | Interface gedefinieerd |
|
||||
| C35 Workflow Engine (State Machine) | Platform Services | Interface + voorbeeldworkflows |
|
||||
| C36 Full-Text Search | Platform Services | Interface + PostgreSQL tsvector schema |
|
||||
| C37 Caching Layer | Platform Services | Interface + TTL strategie |
|
||||
| C38 Scheduled Jobs | Platform Services | Interface + job definities |
|
||||
| C39 Webhook System | Platform Services | Interface + security (HMAC) |
|
||||
| C40 ZPM Facturatie | Externe Integraties | Interface + database schema |
|
||||
| C41 Vecozo Connector | Externe Integraties | Interface + mock (voorbereiding) |
|
||||
| C42 Zorgdomein Connector | Externe Integraties | Interface + mock (voorbereiding) |
|
||||
| C43 BI Module | Analytics | Materialized views gedefinieerd |
|
||||
|
||||
De gap items G19 (notificatie) en G20 (caching) uit §4.3 zijn hiermee opgelost. Zie het uitbreidingsdocument voor volledige interface definities, database schemas en integratiepunten.
|
||||
129
docs/releasenotes/RELEASE_INTAKE_BEHANDELPLAN.md
Normal file
129
docs/releasenotes/RELEASE_INTAKE_BEHANDELPLAN.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Release Notes – Intake & Behandelplan
|
||||
**Datum:** 9 maart 2026 | **Doelgroep:** Behandelaars
|
||||
|
||||
---
|
||||
|
||||
## Wat is er nieuw?
|
||||
|
||||
Deze release levert een volledige intake-werkruimte en een AI-ondersteund behandelplan. Samen vormen ze één doorgaande lijn: van eerste screening tot actief behandelplan met SMART-doelen.
|
||||
|
||||
---
|
||||
|
||||
## Cliëntenoverzicht
|
||||
|
||||
Het overzicht van alle cliënten is uitgebreid met filters en statusinformatie, zodat je snel ziet waar een cliënt in het traject staat.
|
||||
|
||||
**Nieuw:**
|
||||
- **Statusbadges** per cliënt: *Actief*, *Screening* of *Afgemeld* — direct zichtbaar in de lijst
|
||||
- **Filteren** op status én geslacht via de filterbalk
|
||||
- **Zoeken** op naam of BSN
|
||||
- Kolom "Laatst gewijzigd" toont datum en tijdstip van de meest recente aanpassing
|
||||
|
||||
---
|
||||
|
||||
## Patiëntdashboard
|
||||
|
||||
Per cliënt is er nu een overzichtspagina die als startpunt dient voor het hele zorgtraject.
|
||||
|
||||
**Nieuw:**
|
||||
- Drie snelkoppelingen: *Basisgegevens*, *Screening*, *Intake*
|
||||
- Sectie **Recente Intakes** met titel, afdeling, datum en status (*bezig* / *afgerond*)
|
||||
- Sectie **Agenda Afspraken** met aankomende en recente afspraken inclusief type en tijdstip
|
||||
- Preview van het **actieve behandelplan** en een "Volgende stappen"-blok
|
||||
|
||||
---
|
||||
|
||||
## Intake
|
||||
|
||||
De intakewerkruimte bestaat uit negen tabs die het volledige diagnostisch traject dekken. Je werkt ze niet verplicht op volgorde af — je kunt altijd naar elke tab navigeren.
|
||||
|
||||
### Tabs
|
||||
|
||||
| Tab | Wat je hier doet |
|
||||
|---|---|
|
||||
| **Algemeen** | Titel, afdeling, status en startdatum van de intake; notitieveld |
|
||||
| **Contactmomenten** | Registreer gesprekken (datum, tijd, type, locatie, notities) |
|
||||
| **Kindcheck** | Vastleggen of er kinderen betrokken zijn, zorgen en ondernomen acties |
|
||||
| **Risicotaxatie** | Risico's per type met ernst (laag / middel / hoog) en vervolgacties |
|
||||
| **Anamnese** | Psychiatrische, sociale en familiegeschiedenis |
|
||||
| **Onderzoeken** | Psychodiagnostisch onderzoek met type, datum en uitkomst |
|
||||
| **ROM** | Outcome-meting met scores per instrument |
|
||||
| **Diagnose** | ICD-10 diagnoses met hoofd- en nevendiagnose, ernst en datum |
|
||||
| **Behandeladvies** | Advies, aanbevolen behandeling, gekoppelde psycholoog en programma |
|
||||
|
||||
### Diagnoses registreren
|
||||
|
||||
- Zoek en koppel een **ICD-10 code** via de zoekbalk (combobox)
|
||||
- Markeer één diagnose als **hoofddiagnose**; overige worden als nevendiagnose geregistreerd
|
||||
- Registreer de **ernst**: mild, matig of ernstig
|
||||
- Meerdere diagnoses per intake zijn mogelijk; de hoofddiagnose staat altijd bovenaan
|
||||
|
||||
---
|
||||
|
||||
## Behandelplan
|
||||
|
||||
Het behandelplan is het hart van de behandeling. Je kunt een plan **handmatig opbouwen** of laten **genereren door AI** op basis van de intake.
|
||||
|
||||
### AI-gegenereerd plan
|
||||
|
||||
Via de knop **"Genereer met AI"** maakt het systeem een volledig conceptplan aan. De AI (Claude) gebruikt hiervoor:
|
||||
|
||||
- De intakenotities en het behandeladvies
|
||||
- De gestelde **ICD-10 diagnose** en ernst
|
||||
- De **leefgebiedenscores** (zie hieronder)
|
||||
- Eventuele extra instructies die je zelf meegeeft (max. 500 tekens)
|
||||
|
||||
Het gegenereerde plan bevat:
|
||||
- **SMART-behandeldoelen** met bijbehorende interventies
|
||||
- Een **behandelstructuur** (duur, frequentie, sessievorm)
|
||||
- **Evaluatiemomenten** (tussentijds en eindevaluatie)
|
||||
- Een **veiligheidsplan** — automatisch meegenomen bij een ernstige diagnose
|
||||
|
||||
Het plan wordt aangemaakt als concept; je kunt het volledig aanpassen vóór publicatie.
|
||||
|
||||
### Leefgebieden
|
||||
|
||||
Bij het opstellen van een behandelplan scoor je zeven leefgebieden op een schaal van 0–10 en geef je per domein een prioriteit mee:
|
||||
|
||||
- Dagelijkse Levensvaardigheden
|
||||
- Gezondheid
|
||||
- Werk & Activiteiten
|
||||
- Huisvesting
|
||||
- Sociale Relaties
|
||||
- Maatschappelijke Participatie
|
||||
- Veiligheid
|
||||
|
||||
Deze scores kleuren het behandelplan: de AI koppelt doelen automatisch aan de domeinen met de hoogste prioriteit.
|
||||
|
||||
### Behandeldoelen
|
||||
|
||||
Per doel leg je vast:
|
||||
- Titel en omschrijving
|
||||
- Gekoppeld leefgebied en prioriteit
|
||||
- Voortgang (0–100 %) en status: *Niet gestart* / *Bezig* / *Gehaald*
|
||||
- Eindweek
|
||||
- Bijbehorende **interventies** (inline, per doel)
|
||||
|
||||
### Versiebeheer
|
||||
|
||||
- Elk behandelplan krijgt een versienummer (v1, v2, …)
|
||||
- Je kunt een nieuw concept aanmaken terwijl het vorige plan actief blijft
|
||||
- Statussen: *Concept*, *Actief*, *On hold*, *Afgerond*, *Ingetrokken*
|
||||
- Alle versies blijven raadpleegbaar via de versieselectie in het zijpaneel
|
||||
|
||||
### Planning & Evaluatie
|
||||
|
||||
In het uitklapbare blok "Planning & Evaluatie" vind je:
|
||||
- **Behandelstructuur**: duur van het traject, sessiefrequentie, aantal sessies en vorm (individueel / groep / online)
|
||||
- **Sessieplanning**: per sessie een nummer, focus en datum
|
||||
- **Evaluatiemomenten**: week en type (tussentijds / eind / crisis), met status *gepland* of *afgerond*
|
||||
- **Veiligheidsplan**: waarschuwingssignalen, copingstrategieën, noodcontacten en afgesproken restricties
|
||||
|
||||
---
|
||||
|
||||
## Bekende beperkingen
|
||||
|
||||
- **Behandeldoelen** starten leeg bij een nieuw handmatig plan; sjablonen zijn nog niet beschikbaar.
|
||||
- **Sortering en dubbele-codevalidatie** bij diagnoses volgt in een volgende release.
|
||||
- Het **notitieveld** in de Algemeen-tab ondersteunt nog geen opmaak (geen vetgedrukte tekst, lijsten, e.d.).
|
||||
- AI-generatie vereist dat er minimaal een intake met notities aanwezig is; zonder intake-context is het resultaat beperkt.
|
||||
BIN
docs/releasenotes/Release_Intake_Behandelplan.docx
Normal file
BIN
docs/releasenotes/Release_Intake_Behandelplan.docx
Normal file
Binary file not shown.
433
docs/styleguide-ux.md
Normal file
433
docs/styleguide-ux.md
Normal file
@@ -0,0 +1,433 @@
|
||||
# Mini-EPD Style Guide & UX
|
||||
|
||||
> Geëxtraheerd uit de mini-epd-prototype codebase. Gebruik dit document om dezelfde look & feel in een ander project toe te passen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Tech Stack & Tooling
|
||||
|
||||
| Categorie | Keuze | Versie |
|
||||
|---|---|---|
|
||||
| Framework | Next.js (App Router) | 14.2 |
|
||||
| Taal | TypeScript | 5.x |
|
||||
| Styling | Tailwind CSS | 3.4 |
|
||||
| Component variants | `class-variance-authority` (CVA) | 0.7 |
|
||||
| Class merging | `tailwind-merge` | 3.4 |
|
||||
| Animaties | `tailwindcss-animate` + Framer Motion | 1.0 / 12.x |
|
||||
| UI primitives | Radix UI | diverse |
|
||||
| Iconen | Lucide React | 0.553 |
|
||||
| State management | Zustand | 5.x |
|
||||
| Formulieren | React Hook Form + Zod | 7.x / 4.x |
|
||||
| Rich text | TipTap | 3.x |
|
||||
|
||||
### Utility helper
|
||||
|
||||
```ts
|
||||
// lib/utils.ts
|
||||
import { clsx, type ClassValue } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Kleurensysteem
|
||||
|
||||
### 2.1 Basiskleuren
|
||||
|
||||
| Token | Hex | Gebruik |
|
||||
|---|---|---|
|
||||
| `app-background` | `#F8FAFC` | Pagina-achtergrond (slate-50) |
|
||||
| `surface` | `#FFFFFF` | Cards, panels |
|
||||
| `surface-sub` | `#F1F5F9` | Secundaire achtergrond (slate-100) |
|
||||
| `text-primary` | `#0F172A` | Primaire tekst (slate-900) |
|
||||
| `text-secondary` | `#475569` | Secundaire/meta-tekst (slate-600) |
|
||||
| `border` | `#E2E8F0` | Standaard borders (slate-200) |
|
||||
|
||||
### 2.2 Brand (Teal-first)
|
||||
|
||||
De primaire brandkleur is **teal**. Alle interactieve elementen, focus-states en links gebruiken deze kleur.
|
||||
|
||||
| Token | Hex | Ratio | Gebruik |
|
||||
|---|---|---|---|
|
||||
| `brand-50` | `#F0FDFA` | — | Subtiele achtergrond |
|
||||
| `brand-100` | `#CCFBF1` | — | Info-subtiel |
|
||||
| `brand-200` | `#99F6E4` | — | Lichte tint |
|
||||
| `brand-400` | `#2DD4BF` | — | Decoratief |
|
||||
| `brand-500` | `#14B8A6` | — | Accent |
|
||||
| `brand-600` | `#0D9488` | 3:1 | UI-componenten (non-text) |
|
||||
| **`brand-700`** | **`#0F766E`** | **5.47:1** | **Primaire tekst & CTA (WCAG AA) ✓** |
|
||||
| `brand-800` | `#115E59` | — | Hover state |
|
||||
| `brand-900` | `#134E4A` | — | Donkerste tint |
|
||||
|
||||
```css
|
||||
/* CSS custom properties */
|
||||
--color-brand: #0F766E;
|
||||
--color-brand-hover: #115E59;
|
||||
--color-brand-active: #0D9488;
|
||||
--color-brand-subtle: #F0FDFA;
|
||||
```
|
||||
|
||||
### 2.3 AI Features (Amber)
|
||||
|
||||
AI-gerelateerde acties worden visueel onderscheiden door een **amber** kleurenpalet.
|
||||
|
||||
| Token | Hex | Gebruik |
|
||||
|---|---|---|
|
||||
| `ai-50` | `#FFFBEB` | Subtiele AI-achtergrond |
|
||||
| `ai-500` | `#F59E0B` | Primaire AI-kleur |
|
||||
| `ai-600` | `#D97706` | AI-tekst (WCAG AA large) |
|
||||
| `ai-700` | `#B45309` | AI hover |
|
||||
|
||||
### 2.4 Module-accenten
|
||||
|
||||
Verschillende modules hebben een eigen kleurig accent:
|
||||
|
||||
| Module | Achtergrond | Accent | Border |
|
||||
|---|---|---|---|
|
||||
| Afspraken | `#E8F8EF` | `#16A34A` (groen) | `#CDECDC` |
|
||||
| Medicatie | `#FEF6DC` | `#F59E0B` (amber) | `#F6E7B6` |
|
||||
| Lab | `#FFEBDC` | `#F97316` (oranje) | `#FFD2B8` |
|
||||
|
||||
### 2.5 Status & Feedback
|
||||
|
||||
| Status | Kleur | Subtiel |
|
||||
|---|---|---|
|
||||
| Success | `#16A34A` | `#ECFDF5` |
|
||||
| Warning | `#EAB308` | `#FEFCE8` |
|
||||
| Error | `#DC2626` | `#FEF2F2` |
|
||||
| Info | `#0F766E` (teal) | `#CCFBF1` |
|
||||
|
||||
### 2.6 Severity Badges (DSM-light)
|
||||
|
||||
| Ernst | Achtergrond | Tekst |
|
||||
|---|---|---|
|
||||
| Low | `#E5E7EB` | `#374151` |
|
||||
| Medium | `#FEF3C7` | `#92400E` |
|
||||
| High | `#FEE2E2` | `#991B1B` |
|
||||
|
||||
### 2.7 Dark Mode
|
||||
|
||||
Dark mode is optioneel geïmplementeerd (MVP = licht thema):
|
||||
|
||||
```css
|
||||
.dark {
|
||||
--color-bg: #0a0a0a;
|
||||
--color-surface: #1a1a1a;
|
||||
--color-text: #ededed;
|
||||
--color-text-secondary: #a1a1a1;
|
||||
--color-border: #333333;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Typografie
|
||||
|
||||
### 3.1 Font Families
|
||||
|
||||
Drie fonts worden lokaal geladen via `next/font/local`:
|
||||
|
||||
| Variabele | Font | Gewichten | Gebruik |
|
||||
|---|---|---|---|
|
||||
| `--font-serif` | **Lora** | 400, 400i, 600 | Long-form content, manifesto teksten |
|
||||
| `--font-sans` | **Roboto** | 400, 500, 600 (+italic) | UI, navigatie, metadata, body |
|
||||
| `--font-mono` | **Source Code Pro** | 400, 600 | Code, technische details, nummers |
|
||||
|
||||
**Body default:** `var(--font-sans), system-ui, -apple-system, sans-serif`
|
||||
|
||||
### 3.2 Typografische Schaal
|
||||
|
||||
| Token | Waarde | Toepassing |
|
||||
|---|---|---|
|
||||
| `--text-hero` | `clamp(2.5rem, 6vw, 4rem)` | Hero quotes |
|
||||
| `--text-h1` | `clamp(2rem, 5vw, 3rem)` | Sectie-koppen |
|
||||
| `--text-h2` | `clamp(1.5rem, 4vw, 2.5rem)` | Subsecties |
|
||||
| `--text-body` | `1.25rem` | Content, lopende tekst |
|
||||
| `--text-small` | `0.875rem` | Metadata, labels |
|
||||
|
||||
### 3.3 Line Heights
|
||||
|
||||
| Token | Waarde | Gebruik |
|
||||
|---|---|---|
|
||||
| `--line-height-tight` | `1.2` | Headings |
|
||||
| `--line-height-relaxed` | `1.8` | Body/content |
|
||||
|
||||
---
|
||||
|
||||
## 4. Shadows & Border Radius
|
||||
|
||||
### Shadows
|
||||
|
||||
| Token | Waarde |
|
||||
|---|---|
|
||||
| `shadow-sm` | `0 1px 2px rgba(15,23,42,0.06)` |
|
||||
| `shadow-md` | `0 2px 6px rgba(15,23,42,0.08)` |
|
||||
| `shadow-lg` | `0 8px 20px rgba(15,23,42,0.10)` |
|
||||
|
||||
> Alle shadows zijn gebaseerd op **slate-900** alpha — geen hard zwart.
|
||||
|
||||
### Border Radius
|
||||
|
||||
| Token | Waarde |
|
||||
|---|---|
|
||||
| `--radius` | `0.625rem` (10px) |
|
||||
| `rounded-lg` | `var(--radius)` |
|
||||
| `rounded-md` | `calc(var(--radius) - 2px)` ≈ 8px |
|
||||
| `rounded-sm` | `calc(var(--radius) - 4px)` ≈ 6px |
|
||||
|
||||
---
|
||||
|
||||
## 5. Formulieren
|
||||
|
||||
| State | Property | Waarde |
|
||||
|---|---|---|
|
||||
| Default | bg | `#FFFFFF` |
|
||||
| Default | border | `#CBD5E1` |
|
||||
| Default | tekst | `#0F172A` |
|
||||
| Placeholder | kleur | `#94A3B8` |
|
||||
| Hover | border | `#94A3B8` |
|
||||
| Focus | ring/border | `#0F766E` (teal-700) |
|
||||
| Disabled | bg | `#F1F5F9` |
|
||||
| Disabled | tekst | `#94A3B8` |
|
||||
| Invalid | border | `#DC2626` |
|
||||
| Invalid | tekst | `#B91C1C` |
|
||||
|
||||
**Input component patroon:**
|
||||
```tsx
|
||||
<input className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1
|
||||
text-base shadow-sm transition-colors placeholder:text-muted-foreground
|
||||
focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring
|
||||
disabled:cursor-not-allowed disabled:opacity-50 md:text-sm" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Component Patronen
|
||||
|
||||
### 6.1 Component Architectuur
|
||||
|
||||
- Alle componenten gebruiken **`React.forwardRef`** voor ref-forwarding
|
||||
- Varianten via **`class-variance-authority`** (CVA)
|
||||
- Styling via Tailwind classes + `cn()` utility
|
||||
- Radix UI als headless primitives (Dialog, Tabs, Select, Popover, etc.)
|
||||
- **Default = server component**; `"use client"` alleen wanneer interactiviteit vereist is
|
||||
|
||||
### 6.2 Button
|
||||
|
||||
| Variant | Stijl |
|
||||
|---|---|
|
||||
| `default` | `bg-primary text-primary-foreground hover:bg-primary/90` |
|
||||
| `destructive` | `bg-destructive text-destructive-foreground hover:bg-destructive/90` |
|
||||
| `outline` | `border border-input bg-background hover:bg-accent` |
|
||||
| `secondary` | `bg-secondary text-secondary-foreground hover:bg-secondary/80` |
|
||||
| `ghost` | `hover:bg-accent hover:text-accent-foreground` |
|
||||
| `link` | `text-primary underline-offset-4 hover:underline` |
|
||||
|
||||
| Size | Afmetingen |
|
||||
|---|---|
|
||||
| `default` | `h-10 px-4 py-2` |
|
||||
| `sm` | `h-9 px-3` |
|
||||
| `lg` | `h-11 px-8` |
|
||||
| `icon` | `h-10 w-10` |
|
||||
|
||||
### 6.3 AI Button
|
||||
|
||||
Speciaal component voor AI-acties. Visueel onderscheiden door **amber gradient**.
|
||||
|
||||
| Variant | Stijl |
|
||||
|---|---|
|
||||
| `default` | Amber gradient (`from-amber-600 to-amber-700`) + witte tekst |
|
||||
| `outline` | `border-2 border-amber-500`, tekst `amber-700` |
|
||||
| `ghost` | Transparant, tekst `amber-700`, hover `amber-50` |
|
||||
|
||||
Features:
|
||||
- Sparkle-icoon (✨) als visuele AI-indicator
|
||||
- Loading state met `Loader2` spinner
|
||||
- Drie maten: `sm`, `md`, `lg`
|
||||
|
||||
### 6.4 Card
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ CardHeader (p-6) │
|
||||
│ CardTitle (semibold) │
|
||||
│ CardDescription (muted) │
|
||||
│ CardContent (p-6 pt-0) │
|
||||
│ CardFooter (p-6 pt-0) │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
- `rounded-xl`, `border`, `bg-card`, `shadow`
|
||||
|
||||
### 6.5 Badge
|
||||
|
||||
Varianten: `default`, `secondary`, `destructive`, `outline`
|
||||
Base: `rounded-md`, `px-2.5 py-0.5`, `text-xs font-semibold`
|
||||
|
||||
### 6.6 Tabs
|
||||
|
||||
- `TabsList`: `rounded-lg bg-muted p-1`
|
||||
- `TabsTrigger`: `rounded-md px-3 py-1 text-sm font-medium`
|
||||
- Active state: `bg-background text-foreground shadow`
|
||||
|
||||
### 6.7 Toast
|
||||
|
||||
- Positie: top op mobile, bottom-right op desktop
|
||||
- Swipe-to-dismiss ondersteuning
|
||||
- Slide-in animatie (top op mobile, bottom op desktop)
|
||||
- Varianten: `default` en `destructive`
|
||||
|
||||
---
|
||||
|
||||
## 7. Layout & Navigatie
|
||||
|
||||
### 7.1 App Shell
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────┐
|
||||
│ ┌──────────┐ ┌─────────────────────┐ │
|
||||
│ │ │ │ │ │
|
||||
│ │ Sidebar │ │ Main Content │ │
|
||||
│ │ (fixed) │ │ (scrollable) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┘ └─────────────────────┘ │
|
||||
└──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **Container**: `min-h-screen bg-slate-50 flex`
|
||||
- **Sidebar**: fixed, `w-78` open / `w-28` collapsed
|
||||
- **Main content**: flex-grow, scrollable
|
||||
|
||||
### 7.2 Sidebar UX
|
||||
|
||||
| Eigenschap | Waarde |
|
||||
|---|---|
|
||||
| Desktop breedte (open) | `w-78` (312px) |
|
||||
| Desktop breedte (collapsed) | `w-28` (112px) |
|
||||
| Achtergrond | `bg-white` |
|
||||
| Border | `border-r border-slate-200` |
|
||||
| Transition | `duration-300 ease-in-out` |
|
||||
| Mobile | Full overlay met `bg-black/40 backdrop-blur-sm` |
|
||||
|
||||
**Active nav item**: `bg-teal-50 text-teal-700` + icoon `text-teal-600`
|
||||
**Inactive nav item**: `text-slate-600 hover:bg-slate-50 hover:text-slate-900`
|
||||
|
||||
**Collapsed state**: tooltips verschijnen links met een pijl-indicator (`bg-slate-800 text-white`)
|
||||
|
||||
**Profiel sectie**: avatar cirkel, naam, rol, online-indicator (`bg-green-500` dot)
|
||||
**Logout**: `text-red-600 hover:bg-red-50`
|
||||
|
||||
---
|
||||
|
||||
## 8. Animaties
|
||||
|
||||
### 8.1 Float Animatie
|
||||
|
||||
Subtiele zweef-animatie voor badges of decoratieve elementen:
|
||||
|
||||
```css
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
||||
25% { transform: translateY(-5px) rotate(0.5deg); }
|
||||
50% { transform: translateY(-3px) rotate(-0.5deg); }
|
||||
75% { transform: translateY(-7px) rotate(0.3deg); }
|
||||
}
|
||||
.animate-float { animation: float 5s ease-in-out infinite; }
|
||||
```
|
||||
|
||||
### 8.2 Artifact Slide-in
|
||||
|
||||
Panel slide-in van rechts:
|
||||
|
||||
```css
|
||||
@keyframes artifact-enter {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
}
|
||||
.artifact-enter { animation: artifact-enter 200ms ease-out; }
|
||||
```
|
||||
|
||||
### 8.3 Transition Defaults
|
||||
|
||||
- Navigatie / sidebar: `transition-all duration-300 ease-in-out`
|
||||
- Buttons / interactie: `transition-colors` of `transition-all duration-200`
|
||||
- Toasts: slide-in + fade via `tailwindcss-animate`
|
||||
|
||||
### 8.4 Reduced Motion
|
||||
|
||||
Volledige `prefers-reduced-motion` ondersteuning:
|
||||
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.02ms !important;
|
||||
transition-duration: 0.03ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Toegankelijkheid (A11y)
|
||||
|
||||
| Aspect | Implementatie |
|
||||
|---|---|
|
||||
| Focus indicator | `outline: 2px solid var(--color-brand)`, `outline-offset: 2px` |
|
||||
| Focus ring (components) | `ring-2 ring-ring ring-offset-2` |
|
||||
| Skip to main | Verborgen link, zichtbaar bij focus |
|
||||
| Kleurcontrast | Brand teal-700 = 5.47:1 op wit (WCAG AA ✓) |
|
||||
| ARIA labels | Alle interactieve elementen (toggle buttons, sidebar) |
|
||||
| Reduced motion | Alle animaties gerespecteerd |
|
||||
| Iconen | `aria-hidden="true"` op decoratieve iconen |
|
||||
| Taal | `<html lang="nl">` |
|
||||
|
||||
---
|
||||
|
||||
## 10. AI UX Conventies
|
||||
|
||||
AI-functies worden visueel onderscheiden van standaard UI:
|
||||
|
||||
| Element | Conventie |
|
||||
|---|---|
|
||||
| Kleur | Amber-palet (geel/goud), nooit teal |
|
||||
| Button | `AIButton` component met Sparkle-icoon (✨) |
|
||||
| Highlight | `.ai-source-highlight` — lichtgeel (`#fef08a`) met `border-radius: 2px` |
|
||||
| Loading | `Loader2` spinner (animatie: `animate-spin`) |
|
||||
| Feedback | Confidence indicators bij AI-gegenereerde content |
|
||||
|
||||
---
|
||||
|
||||
## 11. Quick-Start Checklist
|
||||
|
||||
Om deze stijl in een nieuw project over te nemen:
|
||||
|
||||
1. **Installeer dependencies:**
|
||||
```bash
|
||||
pnpm add class-variance-authority clsx tailwind-merge tailwindcss-animate
|
||||
pnpm add lucide-react framer-motion
|
||||
pnpm add @radix-ui/react-dialog @radix-ui/react-tabs @radix-ui/react-select
|
||||
# + overige Radix primitives naar behoefte
|
||||
```
|
||||
|
||||
2. **Kopieer fonts** (Lora, Roboto, Source Code Pro) naar `public/fonts/` en configureer in `layout.tsx`
|
||||
|
||||
3. **Kopieer CSS custom properties** uit `globals.css` (sectie `:root`)
|
||||
|
||||
4. **Kopieer Tailwind config** — met name `colors`, `boxShadow`, `borderRadius` extensies
|
||||
|
||||
5. **Kopieer `cn()` utility** naar `lib/utils.ts`
|
||||
|
||||
6. **Kopieer UI components** uit `components/ui/` (shadcn-patroon met CVA)
|
||||
|
||||
7. **Zet `antialiased`** op de `<body>` tag
|
||||
|
||||
8. **Zet `lang="nl"`** op de `<html>` tag
|
||||
|
||||
---
|
||||
|
||||
*Gegenereerd op basis van de mini-epd-prototype codebase (maart 2026).*
|
||||
1514
docs/swift/cortex-architectuur-analyse.md
Normal file
1514
docs/swift/cortex-architectuur-analyse.md
Normal file
File diff suppressed because it is too large
Load Diff
89
docs/visuele-styleguide.md
Normal file
89
docs/visuele-styleguide.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Visuele Style Guide & UX Identity
|
||||
|
||||
Dit document beschrijft de visuele identiteit en de gebruikerservaring (UX) van het Mini-EPD. De focus ligt op de 'look & feel' en de ontwerpkeuzes, zonder technische code.
|
||||
|
||||
---
|
||||
|
||||
## 1. De Visuele Persoonlijkheid
|
||||
|
||||
Het ontwerp van het EPD is gestoeld op drie kernwaarden:
|
||||
1. **Betrouwbaarheid**: Een rustig, professioneel fundament (Slate & Teal).
|
||||
2. **Menselijkheid**: Gebruik van klassieke typografie (Serif) voor verslagen.
|
||||
3. **Innovatie**: Een warme, magische uitstraling voor AI-functies (Amber & Goud).
|
||||
|
||||
---
|
||||
|
||||
## 2. Kleurgebruik & Betekenis
|
||||
|
||||
Het kleurenpalet is functioneel ingezet om de gebruiker te gidsen door de complexe medische data.
|
||||
|
||||
### 2.1 De Basis (Rust & Ruimte)
|
||||
De interface ademt rust door het gebruik van een zeer lichte, bijna witte achtergrond (**Lichtgrijs/Slate**). Dit zorgt ervoor dat de content (patiëntdata) de meeste aandacht krijgt. Borders zijn subtiel en zacht, waardoor er geen harde lijnen in het zicht staan.
|
||||
|
||||
### 2.2 Actie & Focus (Teal / Groenblauw)
|
||||
**Teal** is de primaire accentkleur. Het wordt gebruikt voor alles wat "standaard" en "veilig" is:
|
||||
* Navigatie en menu's.
|
||||
* Primaire knoppen voor dagelijkse handelingen.
|
||||
* Focus-ringen (om aan te geven waar de gebruiker is).
|
||||
* Bevestigingen en succesmeldingen.
|
||||
* *Gevoel: Professioneel, medisch, kalm.*
|
||||
|
||||
### 2.3 AI & Intelligentie (Amber / Goud)
|
||||
**Amber** is gereserveerd voor alle functies waarbij de computer met de gebruiker meedenkt (AI):
|
||||
* Knoppen die samenvattingen genereren.
|
||||
* Highlights bij automatisch herkende tekst.
|
||||
* AI-assistent iconen (gecombineerd met een sterretje/sparkle ✨).
|
||||
* *Gevoel: Magisch, waardevol, onderscheidend.*
|
||||
|
||||
### 2.4 Module Kleuren
|
||||
Om snel te kunnen schakelen tussen dossiers, hebben specifieke onderdelen hun eigen kleuraccent:
|
||||
* **Afspraken**: Groen (Fris, vooruitgang).
|
||||
* **Medicatie**: Geel/Amber (Waarschuwing, actie).
|
||||
* **Labuitslagen**: Oranje (Energie, resultaat).
|
||||
|
||||
---
|
||||
|
||||
## 3. Typografie (De Stem van de App)
|
||||
|
||||
De app gebruikt drie verschillende lettertypes om context te geven aan de tekst.
|
||||
|
||||
* **De Stem van de Arts (Serif)**: Voor medische verslagen en verhalen wordt een klassiek lettertype met schreef gebruikt. Dit leest prettiger bij lange teksten en geeft een gevoel van autoriteit en menselijkheid, zoals in een gedrukt medisch dossier.
|
||||
* **De Stem van de App (Sans-Serif)**: Voor alle menu's, knoppen en navigatie wordt een modern, strak lettertype zonder schreef gebruikt. Dit zorgt voor optimale leesbaarheid en een efficiënte uitstraling.
|
||||
* **De Stem van de Data (Monospace)**: Voor getallen, uitslagen en technische details worden letters gebruikt die allemaal even breed zijn (zoals bij een typemachine). Dit zorgt ervoor dat kolommen met cijfers altijd strak onder elkaar staan.
|
||||
|
||||
---
|
||||
|
||||
## 4. Knoppen & Interactie
|
||||
|
||||
### 4.1 Standaard Knoppen
|
||||
Standaard knoppen hebben zachte, afgeronde hoeken en een rustige uitstraling.
|
||||
* **Primaire actie**: Een volle Teal kleur.
|
||||
* **Secundaire actie**: Een witte achtergrond met een dunne rand.
|
||||
* **Subtiele actie**: Geen achtergrond, alleen tekst die oplicht bij aanraking.
|
||||
|
||||
### 4.2 De 'Magische' AI-Knop
|
||||
De knoppen voor AI-functies vallen direct op. Ze gebruiken geen egale kleur, maar een verloop (**gradient**) van goud naar donker-amber. Dit geeft de suggestie van diepte en "energie". Vaak vergezeld door een klein sparkle-icoontje.
|
||||
|
||||
---
|
||||
|
||||
## 5. Layout & UX Patronen
|
||||
|
||||
### 5.1 De 'Geleende' Sidebar
|
||||
De navigatie bevindt zich aan de linkerkant.
|
||||
* **Open**: Toont iconen en tekst voor volledige duidelijkheid.
|
||||
* **Ingeklapt**: Toont alleen iconen om werkruimte te maximaliseren. Voor de duidelijkheid verschijnen er 'zwevende' labels (tooltips) als je over de iconen beweegt.
|
||||
* **Contrast**: De sidebar is vaak iets donkerder of heeft een duidelijke verticale lijn om de scheiding tussen "besturing" en "inhoud" aan te geven.
|
||||
|
||||
### 5.2 Kaarten (Cards)
|
||||
Informatie wordt gepresenteerd op witte "kaarten" die licht boven de achtergrond lijken te zweven door een zachte schaduw. Dit voorkomt dat de interface rommelig wordt en maakt duidelijk welke informatie bij elkaar hoort.
|
||||
|
||||
### 5.3 Feedback & Animaties
|
||||
De interface voelt "levend" aan:
|
||||
* Elementen glijden soepel in beeld (slide-in).
|
||||
* Belangrijke meldingen zweven lichtjes (floating effect) om subtiel de aandacht te trekken zonder te storen.
|
||||
* Knoppen reageren direct door een kleine kleurverandering als je eroverheen beweegt.
|
||||
|
||||
---
|
||||
|
||||
## 6. Samenvatting van de Vibe
|
||||
De app ziet eruit als een modern, high-end dashboard. Het combineert de zakelijkheid van een bank-app (veiligheid) met de slimheid van een moderne AI-tool (amber accenten) en de warmte van een magazine (serif typografie).
|
||||
Reference in New Issue
Block a user