Voegt docs/datamodel/diagrammen/ toe: één self-contained HTML per deelmodel (instroom, aanmelding, behandelplan, diagnose, intake-behandeladvies, rapportage, screening, wachtlijst), elk met een Mermaid erDiagram, blueprint-vormgeving en sleep/scroll pan-zoom (mermaid.js + svg-pan-zoom via CDN, geen serverside build nodig). Per diagram alleen sleutel-/FK-attributen en de kernrelaties uit de §2/§3 entiteiten-/cardinaliteitensecties van het bijbehorende deelmodel, niet elk veld — bedoeld als navigeerbaar overzicht naast de tabelvorm, niet als vervanging ervan. Scope-keuzes: - model-intake.md en datamodel-discovery.md zijn overgeslagen: eerstgenoemde is volledig vervangen door model-intake-behandeladvies.md, laatstgenoemde is een prosedocument zonder entiteitenstructuur. - model-aanmelding.md toont alleen de nog geldige PERSOON/CLIENT-kern; AANMELDING/VERWIJZING/ZORGEPISODE zijn vervangen door model-instroom.md en daar al gediagrammeerd. - model-screening.md krijgt een expliciete waarschuwing in titel en bronregel: het losse screeningsbesluit is achterhaald door besluit B21 (screeningsbesluit = acceptatiebesluit, nu care_acceptance_decision in model-instroom.md). - model-behandelplan.md, model-rapportage.md en model-wachtlijst.md tonen een statusnotitie (in herziening resp. deels herzien resp. voorlopig onderzoeksmodel) conform hun documentstatus. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
296 lines
8.2 KiB
HTML
296 lines
8.2 KiB
HTML
<!doctype html>
|
||
<html lang="nl">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Intake en behandeladvies — entiteit-relatiediagram</title>
|
||
<style>
|
||
:root {
|
||
--bg: #F5FAF9;
|
||
--surface: #FFFFFF;
|
||
--surface-2: #EAF3F1;
|
||
--border: #CFE1DE;
|
||
--text: #12211F;
|
||
--text-muted: #4C6B66;
|
||
--accent: #0F766E;
|
||
--font-sans: -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||
--font-mono: ui-monospace, "SFMono-Regular", "Cascadia Code", "Roboto Mono", Consolas, monospace;
|
||
}
|
||
|
||
@media (prefers-color-scheme: dark) {
|
||
:root {
|
||
--bg: #0A1615;
|
||
--surface: #10201E;
|
||
--surface-2: #15302C;
|
||
--border: #1F3A36;
|
||
--text: #E6F5F2;
|
||
--text-muted: #8FB6B0;
|
||
--accent: #34D6C4;
|
||
}
|
||
}
|
||
|
||
* { box-sizing: border-box; }
|
||
|
||
html, body {
|
||
margin: 0;
|
||
height: 100%;
|
||
overscroll-behavior: none;
|
||
}
|
||
|
||
body {
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
font-family: var(--font-sans);
|
||
}
|
||
|
||
.app {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100vh;
|
||
}
|
||
|
||
/* Toolbar */
|
||
.toolbar {
|
||
flex: 0 0 auto;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 16px;
|
||
padding: 10px 16px;
|
||
background: var(--surface);
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
.title-group {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 10px;
|
||
min-width: 0;
|
||
}
|
||
|
||
.title-group h1 {
|
||
font-size: 0.95rem;
|
||
margin: 0;
|
||
font-weight: 700;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.title-group .source {
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
color: var(--text-muted);
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.controls {
|
||
display: flex;
|
||
gap: 6px;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.controls button {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 6px;
|
||
border: 1px solid var(--border);
|
||
background: var(--surface-2);
|
||
color: var(--text);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
padding: 0;
|
||
}
|
||
|
||
.controls button:hover { border-color: var(--accent); color: var(--accent); }
|
||
.controls button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||
|
||
@media (prefers-reduced-motion: no-preference) {
|
||
.controls button { transition: border-color 120ms, color 120ms; }
|
||
}
|
||
|
||
/* Diagram canvas */
|
||
.canvas-wrap {
|
||
flex: 1 1 auto;
|
||
position: relative;
|
||
overflow: hidden;
|
||
background:
|
||
repeating-linear-gradient(0deg, rgba(87,216,198,0.07) 0 1px, transparent 1px 28px),
|
||
repeating-linear-gradient(90deg, rgba(87,216,198,0.07) 0 1px, transparent 1px 28px),
|
||
#08211D;
|
||
}
|
||
|
||
.canvas-wrap .hint {
|
||
position: absolute;
|
||
left: 16px;
|
||
bottom: 14px;
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
color: #6FBFB2;
|
||
z-index: 2;
|
||
pointer-events: none;
|
||
}
|
||
|
||
#diagram {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
#diagram svg {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
|
||
.loading {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #6FBFB2;
|
||
font-family: var(--font-mono);
|
||
font-size: 13px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="app">
|
||
<div class="toolbar">
|
||
<div class="title-group">
|
||
<h1>Intake en behandeladvies — entiteit-relatiediagram</h1>
|
||
<span class="source">model-intake-behandeladvies.md §1–§2 · 7 entiteiten · 7 relaties</span>
|
||
</div>
|
||
<div class="controls">
|
||
<button id="zoom-out" title="Uitzoomen" aria-label="Uitzoomen">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><line x1="3" y1="8" x2="13" y2="8" stroke="currentColor" stroke-width="2"/></svg>
|
||
</button>
|
||
<button id="zoom-in" title="Inzoomen" aria-label="Inzoomen">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><line x1="8" y1="3" x2="8" y2="13" stroke="currentColor" stroke-width="2"/><line x1="3" y1="8" x2="13" y2="8" stroke="currentColor" stroke-width="2"/></svg>
|
||
</button>
|
||
<button id="zoom-fit" title="Passend maken" aria-label="Passend maken">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||
<path d="M2 6V2h4M14 6V2h-4M2 10v4h4M14 10v4h-4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</button>
|
||
<button id="zoom-reset" title="Reset (100%)" aria-label="Reset naar 100%">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||
<path d="M8 2a6 6 0 1 1-4.24 1.76" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
|
||
<path d="M2 2v3h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="canvas-wrap">
|
||
<div class="loading" id="loading">Diagram wordt geladen…</div>
|
||
<div id="diagram" class="mermaid">
|
||
erDiagram
|
||
clinical_care_episode {
|
||
uuid id PK
|
||
}
|
||
care_program {
|
||
uuid id PK
|
||
}
|
||
clinical_intake_assessment {
|
||
uuid id PK
|
||
uuid clinical_care_episode_id FK
|
||
string initiation_reason
|
||
string status
|
||
timestamp planned_at
|
||
}
|
||
intake_contact {
|
||
uuid id PK
|
||
uuid clinical_intake_assessment_id FK
|
||
timestamp occurred_at
|
||
string contact_type
|
||
int planned_duration_minutes
|
||
}
|
||
child_safety_check {
|
||
uuid id PK
|
||
uuid clinical_intake_assessment_id FK
|
||
boolean responsible_for_minors
|
||
boolean safety_concern
|
||
boolean action_taken
|
||
}
|
||
intake_mdt_review {
|
||
uuid id PK
|
||
timestamp occurred_at
|
||
text participants
|
||
}
|
||
treatment_advice {
|
||
uuid id PK
|
||
uuid clinical_intake_assessment_id FK
|
||
uuid mdt_review_id FK
|
||
uuid replaces_advice_id FK
|
||
uuid recommended_care_program FK
|
||
string outcome
|
||
timestamp decided_at
|
||
}
|
||
|
||
clinical_care_episode ||--o{ clinical_intake_assessment : "clinical_care_episode_id"
|
||
clinical_intake_assessment ||--o{ intake_contact : "clinical_intake_assessment_id"
|
||
clinical_intake_assessment ||--o| child_safety_check : "clinical_intake_assessment_id"
|
||
clinical_intake_assessment ||--o{ treatment_advice : "clinical_intake_assessment_id"
|
||
treatment_advice |o--o| treatment_advice : "vervangt (self)"
|
||
intake_mdt_review |o--o| treatment_advice : "mdt_review_id"
|
||
care_program |o--o{ treatment_advice : "recommended_care_program"
|
||
</div>
|
||
<div class="hint">sleep om te pannen · scroll om te zoomen</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
|
||
<script>
|
||
mermaid.initialize({
|
||
startOnLoad: false,
|
||
theme: "base",
|
||
themeVariables: {
|
||
background: "#08211D",
|
||
primaryColor: "#0E2E29",
|
||
primaryBorderColor: "#57D8C6",
|
||
primaryTextColor: "#EAFBF7",
|
||
lineColor: "#57D8C6",
|
||
textColor: "#EAFBF7",
|
||
tertiaryColor: "#123B35",
|
||
attributeBackgroundColorOdd: "#0E2E29",
|
||
attributeBackgroundColorEven: "#123B35",
|
||
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
||
fontSize: "13px"
|
||
}
|
||
});
|
||
|
||
(async () => {
|
||
await mermaid.run({ querySelector: "#diagram" });
|
||
document.getElementById("loading").remove();
|
||
|
||
const svgEl = document.querySelector("#diagram svg");
|
||
svgEl.removeAttribute("style");
|
||
|
||
const panZoom = svgPanZoom(svgEl, {
|
||
panEnabled: true,
|
||
zoomEnabled: true,
|
||
controlIconsEnabled: false,
|
||
fit: true,
|
||
center: true,
|
||
minZoom: 0.15,
|
||
maxZoom: 8,
|
||
zoomScaleSensitivity: 0.35
|
||
});
|
||
|
||
document.getElementById("zoom-in").addEventListener("click", () => panZoom.zoomIn());
|
||
document.getElementById("zoom-out").addEventListener("click", () => panZoom.zoomOut());
|
||
document.getElementById("zoom-fit").addEventListener("click", () => { panZoom.fit(); panZoom.center(); });
|
||
document.getElementById("zoom-reset").addEventListener("click", () => { panZoom.reset(); });
|
||
|
||
window.addEventListener("resize", () => { panZoom.resize(); panZoom.fit(); panZoom.center(); });
|
||
})();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|