<div class="chartlet-wrapper chartlet-responsive chartlet-bp-640"><style>.chartlet-wrapper.chartlet-responsive{display:block;width:100%;container-type:inline-size}.chartlet-variant-mobile{display:none}@container (max-width:639px){.chartlet-bp-640 .chartlet-variant-desktop{display:none}.chartlet-bp-640 .chartlet-variant-mobile{display:block}}</style><style>.chartlet-stage{position:relative;display:inline-block;max-width:100%;vertical-align:top}.chartlet-stage>svg{display:block}.chartlet-hotspot{position:absolute;border-radius:8px;cursor:pointer}.chartlet-focus{margin:0 0 12px 0;font-size:13px}.chartlet-focus summary{cursor:pointer;min-height:24px}.chartlet-focus fieldset{border:none;padding:0;margin:4px 0 0 0}.chartlet-focus label{display:inline-flex;align-items:center;min-height:44px;margin-right:14px;cursor:pointer;white-space:nowrap}.chartlet-focus input{margin-right:4px}.chartlet-focus input:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.chartlet-wrapper:has(.chartlet-focus-node:checked) #chartlet-993d7890224c2061 .chartlet-f{opacity:.18}#chartlet-993d7890224c2061-hs-0{left:39%;top:1.091%;width:11.333%;height:5.091%}#chartlet-993d7890224c2061-hs-1{left:40.333%;top:12%;width:8.667%;height:4.364%}#chartlet-993d7890224c2061-hs-2{left:39.667%;top:26.182%;width:10%;height:6.545%}#chartlet-993d7890224c2061-hs-3{left:40.333%;top:40.727%;width:8.667%;height:5.091%}#chartlet-993d7890224c2061-hs-4{left:29.333%;top:53.818%;width:8.667%;height:6.545%}#chartlet-993d7890224c2061-hs-5{left:40.333%;top:54.545%;width:8.667%;height:5.091%}#chartlet-993d7890224c2061-hs-6{left:37.667%;top:77.818%;width:14%;height:5.818%}#chartlet-993d7890224c2061-hs-7{left:54%;top:77.818%;width:8.667%;height:5.818%}#chartlet-993d7890224c2061-hs-8{left:36%;top:93.455%;width:10%;height:5.091%}#chartlet-993d7890224c2061-hs-9{left:51.333%;top:11.636%;width:10.667%;height:5.091%}#chartlet-993d7890224c2061-hs-10{left:64%;top:94.182%;width:8.667%;height:3.636%}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-0:checked) #chartlet-993d7890224c2061 .chartlet-f-0{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-0:checked) #chartlet-993d7890224c2061 .chartlet-n-0 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-0:checked) #chartlet-993d7890224c2061 .chartlet-n-0 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-1:checked) #chartlet-993d7890224c2061 .chartlet-f-1{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-1:checked) #chartlet-993d7890224c2061 .chartlet-n-1 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-1:checked) #chartlet-993d7890224c2061 .chartlet-n-1 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-2:checked) #chartlet-993d7890224c2061 .chartlet-f-2{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-2:checked) #chartlet-993d7890224c2061 .chartlet-n-2 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-2:checked) #chartlet-993d7890224c2061 .chartlet-n-2 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-3:checked) #chartlet-993d7890224c2061 .chartlet-f-3{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-3:checked) #chartlet-993d7890224c2061 .chartlet-n-3 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-3:checked) #chartlet-993d7890224c2061 .chartlet-n-3 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-4:checked) #chartlet-993d7890224c2061 .chartlet-f-4{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-4:checked) #chartlet-993d7890224c2061 .chartlet-n-4 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-4:checked) #chartlet-993d7890224c2061 .chartlet-n-4 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-5:checked) #chartlet-993d7890224c2061 .chartlet-f-5{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-5:checked) #chartlet-993d7890224c2061 .chartlet-n-5 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-5:checked) #chartlet-993d7890224c2061 .chartlet-n-5 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-6:checked) #chartlet-993d7890224c2061 .chartlet-f-6{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-6:checked) #chartlet-993d7890224c2061 .chartlet-n-6 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-6:checked) #chartlet-993d7890224c2061 .chartlet-n-6 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-7:checked) #chartlet-993d7890224c2061 .chartlet-f-7{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-7:checked) #chartlet-993d7890224c2061 .chartlet-n-7 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-7:checked) #chartlet-993d7890224c2061 .chartlet-n-7 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-8:checked) #chartlet-993d7890224c2061 .chartlet-f-8{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-8:checked) #chartlet-993d7890224c2061 .chartlet-n-8 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-8:checked) #chartlet-993d7890224c2061 .chartlet-n-8 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-9:checked) #chartlet-993d7890224c2061 .chartlet-f-9{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-9:checked) #chartlet-993d7890224c2061 .chartlet-n-9 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-9:checked) #chartlet-993d7890224c2061 .chartlet-n-9 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-10:checked) #chartlet-993d7890224c2061 .chartlet-f-10{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-10:checked) #chartlet-993d7890224c2061 .chartlet-n-10 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-10:checked) #chartlet-993d7890224c2061 .chartlet-n-10 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(.chartlet-focus-node:checked) #chartlet-993d7890224c2061-m .chartlet-f{opacity:.18}#chartlet-993d7890224c2061-m-hs-0{left:34.188%;top:1.356%;width:18.803%;height:6.102%}#chartlet-993d7890224c2061-m-hs-1{left:34.188%;top:13.559%;width:18.803%;height:4.068%}#chartlet-993d7890224c2061-m-hs-2{left:30.769%;top:27.797%;width:25.641%;height:6.102%}#chartlet-993d7890224c2061-m-hs-3{left:33.333%;top:41.695%;width:20.513%;height:4.746%}#chartlet-993d7890224c2061-m-hs-4{left:7.692%;top:54.237%;width:22.222%;height:6.102%}#chartlet-993d7890224c2061-m-hs-5{left:33.333%;top:54.915%;width:20.513%;height:4.746%}#chartlet-993d7890224c2061-m-hs-6{left:32.479%;top:77.288%;width:22.222%;height:6.78%}#chartlet-993d7890224c2061-m-hs-7{left:58.12%;top:77.966%;width:18.803%;height:5.424%}#chartlet-993d7890224c2061-m-hs-8{left:27.35%;top:93.559%;width:22.222%;height:4.746%}#chartlet-993d7890224c2061-m-hs-9{left:56.41%;top:12.542%;width:22.222%;height:6.102%}#chartlet-993d7890224c2061-m-hs-10{left:75.214%;top:94.237%;width:22.222%;height:3.39%}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-0:checked) #chartlet-993d7890224c2061-m .chartlet-f-0{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-0:checked) #chartlet-993d7890224c2061-m .chartlet-n-0 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-0:checked) #chartlet-993d7890224c2061-m .chartlet-n-0 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-1:checked) #chartlet-993d7890224c2061-m .chartlet-f-1{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-1:checked) #chartlet-993d7890224c2061-m .chartlet-n-1 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-1:checked) #chartlet-993d7890224c2061-m .chartlet-n-1 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-2:checked) #chartlet-993d7890224c2061-m .chartlet-f-2{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-2:checked) #chartlet-993d7890224c2061-m .chartlet-n-2 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-2:checked) #chartlet-993d7890224c2061-m .chartlet-n-2 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-3:checked) #chartlet-993d7890224c2061-m .chartlet-f-3{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-3:checked) #chartlet-993d7890224c2061-m .chartlet-n-3 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-3:checked) #chartlet-993d7890224c2061-m .chartlet-n-3 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-4:checked) #chartlet-993d7890224c2061-m .chartlet-f-4{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-4:checked) #chartlet-993d7890224c2061-m .chartlet-n-4 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-4:checked) #chartlet-993d7890224c2061-m .chartlet-n-4 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-5:checked) #chartlet-993d7890224c2061-m .chartlet-f-5{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-5:checked) #chartlet-993d7890224c2061-m .chartlet-n-5 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-5:checked) #chartlet-993d7890224c2061-m .chartlet-n-5 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-6:checked) #chartlet-993d7890224c2061-m .chartlet-f-6{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-6:checked) #chartlet-993d7890224c2061-m .chartlet-n-6 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-6:checked) #chartlet-993d7890224c2061-m .chartlet-n-6 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-7:checked) #chartlet-993d7890224c2061-m .chartlet-f-7{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-7:checked) #chartlet-993d7890224c2061-m .chartlet-n-7 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-7:checked) #chartlet-993d7890224c2061-m .chartlet-n-7 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-8:checked) #chartlet-993d7890224c2061-m .chartlet-f-8{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-8:checked) #chartlet-993d7890224c2061-m .chartlet-n-8 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-8:checked) #chartlet-993d7890224c2061-m .chartlet-n-8 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-9:checked) #chartlet-993d7890224c2061-m .chartlet-f-9{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-9:checked) #chartlet-993d7890224c2061-m .chartlet-n-9 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-9:checked) #chartlet-993d7890224c2061-m .chartlet-n-9 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-10:checked) #chartlet-993d7890224c2061-m .chartlet-f-10{opacity:1}.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-10:checked) #chartlet-993d7890224c2061-m .chartlet-n-10 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-993d7890224c2061-focus-10:checked) #chartlet-993d7890224c2061-m .chartlet-n-10 .chartlet-seq-box{stroke-width:3}</style><details class="chartlet-focus"><summary>Focus</summary><fieldset><label><input type="radio" name="chartlet-993d7890224c2061-focus" checked> Show all</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-0"> Teacher, parent</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-1"> Browser</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-2"> Reverse proxy</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-3"> Web / BFF</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-4"> Sign-in</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-5"> Domain API</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-6"> Domain data</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-7"> Audit log</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-8"> Backup</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-9"> School records</label><label><input type="radio" name="chartlet-993d7890224c2061-focus" class="chartlet-focus-node" id="chartlet-993d7890224c2061-focus-10"> SIEM / SOC</label></fieldset></details><figure class="chartlet-figure" data-viz="chart"><figcaption>Multi-tenant line-of-business application</figcaption><div class="chartlet-variant-desktop"><div class="chartlet-stage"><svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1100" viewBox="0 0 1200 1100" id="chartlet-993d7890224c2061" role="img" aria-labelledby="chartlet-993d7890224c2061-title chartlet-993d7890224c2061-description" class="chartlet-root"><title id="chartlet-993d7890224c2061-title">Multi-tenant line-of-business application</title><desc id="chartlet-993d7890224c2061-description">Architecture diagram with 11 components and 10 connections in 3 boundaries. Data center: Reverse proxy, Application network. Application network (in Data center): Web / BFF, Sign-in, Domain API, Data zone. Data zone (in Application network): Domain data, Audit log. Main path: Teacher, parent → Browser → Reverse proxy → Web / BFF → Domain API → Domain data. Most connected: Domain API (5 connections). Nothing leads into Teacher, parent and School records. Teacher, parent (person): connects to Browser (uses). Browser (frontend): connects to Reverse proxy (calls, via HTTPS). School records (external system): connects to Domain API (master data, via REST/JSON). Reverse proxy (security): connects to Web / BFF (forwards). Web / BFF (service): connects to Sign-in (signs in, via OIDC) and Domain API (queries, via user context). Sign-in (security): no outgoing connection. Domain API (service): connects to Domain data (reads, writes, via SQL/TLS), Audit log (logs) and SIEM / SOC (events, via Syslog). Domain data (database): connects to Backup (backs up). Audit log (database): no outgoing connection. Backup (storage): no outgoing connection. SIEM / SOC (external system): no outgoing connection.</desc><style>.chartlet-root{--chartlet-text:#172033;--chartlet-muted:#344054;--chartlet-grid:#d9dee8;--chartlet-zero:#667085;--chartlet-accent:#2563eb;--chartlet-background:#fff;--chartlet-color-1:#2563eb;--chartlet-color-2:#c2410c;--chartlet-color-3:#475569;--chartlet-color-4:#111827;max-width:100%;height:auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:var(--chartlet-text)}#chartlet-993d7890224c2061 .chartlet-title{font-size:22px;font-weight:650;fill:var(--chartlet-text)}#chartlet-993d7890224c2061 .chartlet-label,#chartlet-993d7890224c2061 .chartlet-tick,#chartlet-993d7890224c2061 .chartlet-value,#chartlet-993d7890224c2061 .chartlet-value-inverse,#chartlet-993d7890224c2061 .chartlet-axis-title{font-size:12px;fill:var(--chartlet-muted)}#chartlet-993d7890224c2061 .chartlet-value,#chartlet-993d7890224c2061 .chartlet-value-inverse{font-weight:600}#chartlet-993d7890224c2061 .chartlet-value{fill:var(--chartlet-text)}#chartlet-993d7890224c2061 .chartlet-value-inverse{fill:var(--chartlet-background)}#chartlet-993d7890224c2061 .chartlet-axis-title{font-weight:600}#chartlet-993d7890224c2061 .chartlet-grid{stroke:var(--chartlet-grid);stroke-width:1}#chartlet-993d7890224c2061 .chartlet-zero{stroke:var(--chartlet-zero);stroke-width:1.5}#chartlet-993d7890224c2061 .chartlet-bar,#chartlet-993d7890224c2061 .chartlet-point{fill:var(--chartlet-accent)}#chartlet-993d7890224c2061 .chartlet-line{fill:none;stroke:var(--chartlet-accent);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}#chartlet-993d7890224c2061 .chartlet-background{fill:var(--chartlet-background)}.chartlet-root{--chartlet-node:#eef3fd;--chartlet-lane:#f7f9fc;--chartlet-lane-head:#eef1f6;--chartlet-shadow:rgba(16,24,40,.09);--chartlet-role-blue:#2563eb;--chartlet-role-blue-fill:#eef3fd;--chartlet-role-green:#15803d;--chartlet-role-green-fill:#ecfdf3;--chartlet-role-amber:#b45309;--chartlet-role-amber-fill:#fff7e8;--chartlet-role-teal:#0f766e;--chartlet-role-teal-fill:#e9faf7;--chartlet-role-violet:#6d28d9;--chartlet-role-violet-fill:#f3efff;--chartlet-role-gray:#667085;--chartlet-role-gray-fill:#f7f8fa;--chartlet-role-red:#b42318;--chartlet-role-red-fill:#fef3f2}.chartlet-root.chartlet-theme-dark{--chartlet-node:#1a2436;--chartlet-lane:#121925;--chartlet-lane-head:#18212f;--chartlet-shadow:rgba(0,0,0,.45);--chartlet-role-blue:#7ea6ff;--chartlet-role-blue-fill:#1a2436;--chartlet-role-green:#4ade80;--chartlet-role-green-fill:#132a1d;--chartlet-role-amber:#fbbf24;--chartlet-role-amber-fill:#2b2210;--chartlet-role-teal:#2dd4bf;--chartlet-role-teal-fill:#0f2a27;--chartlet-role-violet:#b69cff;--chartlet-role-violet-fill:#231c38;--chartlet-role-gray:#9aa7bd;--chartlet-role-gray-fill:#161d29;--chartlet-role-red:#f97066;--chartlet-role-red-fill:#2d1616}#chartlet-993d7890224c2061 .chartlet-role-blue{fill:var(--chartlet-role-blue-fill);stroke:var(--chartlet-role-blue)}#chartlet-993d7890224c2061 .chartlet-role-green{fill:var(--chartlet-role-green-fill);stroke:var(--chartlet-role-green)}#chartlet-993d7890224c2061 .chartlet-role-amber{fill:var(--chartlet-role-amber-fill);stroke:var(--chartlet-role-amber)}#chartlet-993d7890224c2061 .chartlet-role-teal{fill:var(--chartlet-role-teal-fill);stroke:var(--chartlet-role-teal)}#chartlet-993d7890224c2061 .chartlet-role-violet{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet)}#chartlet-993d7890224c2061 .chartlet-role-gray{fill:var(--chartlet-role-gray-fill);stroke:var(--chartlet-role-gray)}#chartlet-993d7890224c2061 .chartlet-role-red{fill:var(--chartlet-role-red-fill);stroke:var(--chartlet-role-red)}#chartlet-993d7890224c2061 .chartlet-diagram-rim{fill:none;stroke:var(--chartlet-role-teal);stroke-width:1.5}#chartlet-993d7890224c2061 .chartlet-diagram-shadow{fill:var(--chartlet-shadow);stroke:none;rx:7px}#chartlet-993d7890224c2061 .chartlet-diagram-chip{fill:var(--chartlet-background);stroke:var(--chartlet-grid);stroke-width:1;rx:4px}#chartlet-993d7890224c2061 .chartlet-diagram-chip-text{font-size:12px;fill:var(--chartlet-text)}#chartlet-993d7890224c2061 .chartlet-diagram-badge{fill:var(--chartlet-accent);stroke:var(--chartlet-background);stroke-width:2}#chartlet-993d7890224c2061 .chartlet-diagram-badge-text{font-size:10px;font-weight:700;fill:var(--chartlet-background)}#chartlet-993d7890224c2061 .chartlet-flow-node{stroke-width:1.5;stroke-linejoin:round;rx:7px}#chartlet-993d7890224c2061 .chartlet-flow-start{stroke-width:2}#chartlet-993d7890224c2061 .chartlet-flow-end{stroke-width:3}#chartlet-993d7890224c2061 .chartlet-flow-external{stroke-dasharray:5 3}#chartlet-993d7890224c2061 .chartlet-flow-inner{stroke:var(--chartlet-role-blue);stroke-width:1}#chartlet-993d7890224c2061 .chartlet-flow-label{font-size:13px;font-weight:600;fill:var(--chartlet-text)}#chartlet-993d7890224c2061 .chartlet-flow-sublabel{font-size:11px;fill:var(--chartlet-muted)}#chartlet-993d7890224c2061 .chartlet-flow-edge{fill:none;stroke:var(--chartlet-zero);stroke-width:1.4;stroke-linejoin:round}#chartlet-993d7890224c2061 .chartlet-flow-dashed{stroke-dasharray:5 4}#chartlet-993d7890224c2061 .chartlet-flow-dotted{stroke-dasharray:1 4;stroke-linecap:round}#chartlet-993d7890224c2061 .chartlet-flow-main{stroke:var(--chartlet-accent);stroke-width:2.2}#chartlet-993d7890224c2061 .chartlet-flow-head{fill:var(--chartlet-zero);stroke:var(--chartlet-zero);stroke-width:1;stroke-linejoin:round}#chartlet-993d7890224c2061 .chartlet-flow-main-head{fill:var(--chartlet-accent);stroke:var(--chartlet-accent)}#chartlet-993d7890224c2061 .chartlet-flow-lane{fill:var(--chartlet-lane);stroke:var(--chartlet-grid);stroke-width:1}#chartlet-993d7890224c2061 .chartlet-flow-lane-alt{fill:var(--chartlet-background)}#chartlet-993d7890224c2061 .chartlet-flow-lane-head{fill:var(--chartlet-lane-head);stroke:none}#chartlet-993d7890224c2061 .chartlet-flow-lane-label{font-size:11px;font-weight:650;fill:var(--chartlet-muted);letter-spacing:.04em}#chartlet-993d7890224c2061 .chartlet-flow-group{fill:var(--chartlet-accent);fill-opacity:.04;stroke:var(--chartlet-zero);stroke-width:1;stroke-dasharray:4 3;rx:10px}#chartlet-993d7890224c2061 .chartlet-flow-group-label{font-size:11px;font-weight:600;fill:var(--chartlet-muted)}#chartlet-993d7890224c2061 .chartlet-arch-head{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet);stroke-width:1.5}#chartlet-993d7890224c2061 .chartlet-arch-dot{fill:var(--chartlet-role-blue);stroke:none}</style><rect x="328" y="260" width="460" height="696" class="chartlet-flow-group"/><text x="336" y="273" text-anchor="start" class="chartlet-flow-group-label">Data center</text><rect x="340" y="420" width="436" height="524" class="chartlet-flow-group"/><text x="348" y="433" text-anchor="start" class="chartlet-flow-group-label">Application network</text><rect x="440" y="828" width="324" height="104" class="chartlet-flow-group"/><text x="448" y="841" text-anchor="start" class="chartlet-flow-group-label">Data zone</text><g class="chartlet-f chartlet-f-0 chartlet-f-1"><polyline points="536,68 536,124" class="chartlet-flow-edge chartlet-flow-main"><title>Teacher, parent → Browser: uses</title></polyline><polyline points="532.5,124 536,132 539.5,124 532.5,124" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-1 chartlet-f-2"><polyline points="536,180 536,280" class="chartlet-flow-edge chartlet-flow-main"><title>Browser → Reverse proxy: calls [HTTPS]</title></polyline><polyline points="532.5,280 536,288 539.5,280 532.5,280" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-2 chartlet-f-3"><polyline points="536,360 536,440" class="chartlet-flow-edge chartlet-flow-main"><title>Reverse proxy → Web / BFF: forwards</title></polyline><polyline points="532.5,440 536,448 539.5,440 532.5,440" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-4"><polyline points="512,504 512,564 404,564 404,584" class="chartlet-flow-edge"><title>Web / BFF → Sign-in: signs in [OIDC]</title></polyline><polyline points="400.5,584 404,592 407.5,584 400.5,584" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-5"><polyline points="536,504 536,592" class="chartlet-flow-edge chartlet-flow-main"><title>Web / BFF → Domain API: queries [user context]</title></polyline><polyline points="532.5,592 536,600 539.5,592 532.5,592" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-6"><polyline points="536,656 536,848" class="chartlet-flow-edge chartlet-flow-main"><title>Domain API → Domain data: reads, writes [SQL/TLS]</title></polyline><polyline points="532.5,848 536,856 539.5,848 532.5,848" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-7"><polyline points="558,656 558,799 700,799 700,848" class="chartlet-flow-edge"><title>Domain API → Audit log: logs</title></polyline><polyline points="696.5,848 700,856 703.5,848 696.5,848" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-9"><polyline points="680,184 680,564 560,564 560,592" class="chartlet-flow-edge"><title>School records → Domain API: master data [REST/JSON]</title></polyline><polyline points="556.5,592 560,600 563.5,592 556.5,592" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-10"><polyline points="580,656 580,787 864,787 864,1001 820,1001 820,1028" class="chartlet-flow-edge chartlet-flow-dashed"><title>Domain API → SIEM / SOC: events [Syslog]</title></polyline><polyline points="816.5,1028 820,1036 823.5,1028 816.5,1028" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-6 chartlet-f-8"><polyline points="536,920 536,1001 492,1001 492,1020" class="chartlet-flow-edge chartlet-flow-dashed"><title>Domain data → Backup: backs up</title></polyline><polyline points="488.5,1020 492,1028 495.5,1020 488.5,1020" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1"></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-2"></g><g class="chartlet-f chartlet-n-2 chartlet-f-1 chartlet-f-2 chartlet-f-3"></g><g class="chartlet-f chartlet-n-3 chartlet-f-2 chartlet-f-3 chartlet-f-4 chartlet-f-5"></g><g class="chartlet-f chartlet-n-4 chartlet-f-3 chartlet-f-4"></g><g class="chartlet-f chartlet-n-5 chartlet-f-3 chartlet-f-5 chartlet-f-6 chartlet-f-7 chartlet-f-9 chartlet-f-10"></g><g class="chartlet-f chartlet-n-6 chartlet-f-5 chartlet-f-6 chartlet-f-8"></g><g class="chartlet-f chartlet-n-7 chartlet-f-5 chartlet-f-7"></g><g class="chartlet-f chartlet-n-8 chartlet-f-6 chartlet-f-8"></g><g class="chartlet-f chartlet-n-9 chartlet-f-5 chartlet-f-9"></g><g class="chartlet-f chartlet-n-10 chartlet-f-5 chartlet-f-10"></g><g class="chartlet-f chartlet-f-0 chartlet-f-1"><rect x="540" y="73" width="36.88" height="21" class="chartlet-diagram-chip"/><text x="545" y="87" text-anchor="start" class="chartlet-diagram-chip-text">uses</text></g><g class="chartlet-f chartlet-f-1 chartlet-f-2"><rect x="540" y="185" width="63.64" height="36" class="chartlet-diagram-chip"/><text x="545" y="199" text-anchor="start" class="chartlet-diagram-chip-text">calls</text><text x="545" y="214" text-anchor="start" class="chartlet-diagram-chip-text">[HTTPS]</text></g><g class="chartlet-f chartlet-f-2 chartlet-f-3"><rect x="540" y="365" width="67.84" height="21" class="chartlet-diagram-chip"/><text x="545" y="379" text-anchor="start" class="chartlet-diagram-chip-text">forwards</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-4"><rect x="453.36" y="509" width="54.64" height="36" class="chartlet-diagram-chip"/><text x="503" y="523" text-anchor="end" class="chartlet-diagram-chip-text">signs in</text><text x="503" y="538" text-anchor="end" class="chartlet-diagram-chip-text">[OIDC]</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-5"><rect x="540" y="509" width="101.2" height="36" class="chartlet-diagram-chip"/><text x="545" y="523" text-anchor="start" class="chartlet-diagram-chip-text">queries</text><text x="545" y="538" text-anchor="start" class="chartlet-diagram-chip-text">[user context]</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-6"><rect x="439.68" y="667" width="92.32" height="36" class="chartlet-diagram-chip"/><text x="527" y="681" text-anchor="end" class="chartlet-diagram-chip-text">reads, writes</text><text x="527" y="696" text-anchor="end" class="chartlet-diagram-chip-text">[SQL/TLS]</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-7"><rect x="612.12" y="803" width="33.76" height="21" class="chartlet-diagram-chip"/><text x="629" y="817" text-anchor="middle" class="chartlet-diagram-chip-text">logs</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-9"><rect x="684" y="189" width="94.48" height="36" class="chartlet-diagram-chip"/><text x="689" y="203" text-anchor="start" class="chartlet-diagram-chip-text">master data</text><text x="689" y="218" text-anchor="start" class="chartlet-diagram-chip-text">[REST/JSON]</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-10"><rect x="584" y="661" width="61.96" height="36" class="chartlet-diagram-chip"/><text x="589" y="675" text-anchor="start" class="chartlet-diagram-chip-text">events</text><text x="589" y="690" text-anchor="start" class="chartlet-diagram-chip-text">[Syslog]</text></g><g class="chartlet-f chartlet-f-6 chartlet-f-8"><rect x="540" y="959" width="60.88" height="21" class="chartlet-diagram-chip"/><text x="545" y="973" text-anchor="start" class="chartlet-diagram-chip-text">backs up</text></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1"><rect x="468" y="14.5" width="136" height="56" class="chartlet-diagram-shadow"/><rect x="468" y="12" width="136" height="56" class="chartlet-flow-node chartlet-role-violet"><title>Teacher, parent</title></rect><circle cx="536" cy="23" r="6" class="chartlet-arch-head"/><text x="536" y="52.5" text-anchor="middle" class="chartlet-flow-label">Teacher, parent</text></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-2"><rect x="484" y="134.5" width="104" height="48" class="chartlet-diagram-shadow"/><rect x="484" y="132" width="104" height="48" class="chartlet-flow-node chartlet-role-blue"><title>Browser</title></rect><line x1="484" y1="144" x2="588" y2="144" class="chartlet-flow-inner"/><circle cx="492" cy="138" r="1.8" class="chartlet-arch-dot"/><circle cx="498" cy="138" r="1.8" class="chartlet-arch-dot"/><circle cx="504" cy="138" r="1.8" class="chartlet-arch-dot"/><text x="536" y="166.5" text-anchor="middle" class="chartlet-flow-label">Browser</text></g><g class="chartlet-f chartlet-n-2 chartlet-f-1 chartlet-f-2 chartlet-f-3"><polyline points="476,290.5 596,290.5 596,333.7 536,362.5 476,333.7 476,290.5" class="chartlet-diagram-shadow"/><polyline points="476,288 596,288 596,331.2 536,360 476,331.2 476,288" class="chartlet-flow-node chartlet-role-red"><title>Reverse proxy – TLS 1.3, WAF</title></polyline><text x="536" y="315.5" text-anchor="middle" class="chartlet-flow-label">Reverse proxy</text><text x="536" y="329.5" text-anchor="middle" class="chartlet-flow-sublabel">TLS 1.3, WAF</text></g><g class="chartlet-f chartlet-n-3 chartlet-f-2 chartlet-f-3 chartlet-f-4 chartlet-f-5"><rect x="484" y="450.5" width="104" height="56" class="chartlet-diagram-shadow"/><rect x="484" y="448" width="104" height="56" class="chartlet-flow-node chartlet-role-blue"><title>Web / BFF – SvelteKit</title></rect><text x="536" y="473.5" text-anchor="middle" class="chartlet-flow-label">Web / BFF</text><text x="536" y="487.5" text-anchor="middle" class="chartlet-flow-sublabel">SvelteKit</text></g><g class="chartlet-f chartlet-n-4 chartlet-f-3 chartlet-f-4"><polyline points="352,594.5 456,594.5 456,637.7 404,666.5 352,637.7 352,594.5" class="chartlet-diagram-shadow"/><polyline points="352,592 456,592 456,635.2 404,664 352,635.2 352,592" class="chartlet-flow-node chartlet-role-red"><title>Sign-in – Keycloak, OIDC</title></polyline><text x="404" y="619.5" text-anchor="middle" class="chartlet-flow-label">Sign-in</text><text x="404" y="633.5" text-anchor="middle" class="chartlet-flow-sublabel">Keycloak, OIDC</text></g><g class="chartlet-f chartlet-n-5 chartlet-f-3 chartlet-f-5 chartlet-f-6 chartlet-f-7 chartlet-f-9 chartlet-f-10"><rect x="484" y="602.5" width="104" height="56" class="chartlet-diagram-shadow"/><rect x="484" y="600" width="104" height="56" class="chartlet-flow-node chartlet-role-blue"><title>Domain API – Rust</title></rect><text x="536" y="625.5" text-anchor="middle" class="chartlet-flow-label">Domain API</text><text x="536" y="639.5" text-anchor="middle" class="chartlet-flow-sublabel">Rust</text></g><g class="chartlet-f chartlet-n-6 chartlet-f-5 chartlet-f-6 chartlet-f-8"><polyline points="452,863.5 452,917.5 454.862,918.794 463.254,920 476.603,921.036 494,921.83 514.259,922.33 536,922.5 557.741,922.33 578,921.83 595.397,921.036 608.746,920 617.138,918.794 620,917.5 620,863.5 617.138,862.206 608.746,861 595.397,859.964 578,859.17 557.741,858.67 536,858.5 514.259,858.67 494,859.17 476.603,859.964 463.254,861 454.862,862.206 452,863.5 452,863.5" class="chartlet-diagram-shadow"/><polyline points="452,861 452,915 454.862,916.294 463.254,917.5 476.603,918.536 494,919.33 514.259,919.83 536,920 557.741,919.83 578,919.33 595.397,918.536 608.746,917.5 617.138,916.294 620,915 620,861 617.138,859.706 608.746,858.5 595.397,857.464 578,856.67 557.741,856.17 536,856 514.259,856.17 494,856.67 476.603,857.464 463.254,858.5 454.862,859.706 452,861 452,861" class="chartlet-flow-node chartlet-role-teal"><title>Domain data – Postgres, RLS per tenant</title></polyline><polyline points="452,861 454.862,862.294 463.254,863.5 476.603,864.536 494,865.33 514.259,865.83 536,866 557.741,865.83 578,865.33 595.397,864.536 608.746,863.5 617.138,862.294 620,861" class="chartlet-diagram-rim"/><text x="536" y="888.5" text-anchor="middle" class="chartlet-flow-label">Domain data</text><text x="536" y="902.5" text-anchor="middle" class="chartlet-flow-sublabel">Postgres, RLS per tenant</text></g><g class="chartlet-f chartlet-n-7 chartlet-f-5 chartlet-f-7"><polyline points="648,863.5 648,917.5 649.772,918.794 654.967,920 663.23,921.036 674,921.83 686.541,922.33 700,922.5 713.459,922.33 726,921.83 736.77,921.036 745.033,920 750.228,918.794 752,917.5 752,863.5 750.228,862.206 745.033,861 736.77,859.964 726,859.17 713.459,858.67 700,858.5 686.541,858.67 674,859.17 663.23,859.964 654.967,861 649.772,862.206 648,863.5 648,863.5" class="chartlet-diagram-shadow"/><polyline points="648,861 648,915 649.772,916.294 654.967,917.5 663.23,918.536 674,919.33 686.541,919.83 700,920 713.459,919.83 726,919.33 736.77,918.536 745.033,917.5 750.228,916.294 752,915 752,861 750.228,859.706 745.033,858.5 736.77,857.464 726,856.67 713.459,856.17 700,856 686.541,856.17 674,856.67 663.23,857.464 654.967,858.5 649.772,859.706 648,861 648,861" class="chartlet-flow-node chartlet-role-teal"><title>Audit log – append only</title></polyline><polyline points="648,861 649.772,862.294 654.967,863.5 663.23,864.536 674,865.33 686.541,865.83 700,866 713.459,865.83 726,865.33 736.77,864.536 745.033,863.5 750.228,862.294 752,861" class="chartlet-diagram-rim"/><text x="700" y="888.5" text-anchor="middle" class="chartlet-flow-label">Audit log</text><text x="700" y="902.5" text-anchor="middle" class="chartlet-flow-sublabel">append only</text></g><g class="chartlet-f chartlet-n-8 chartlet-f-6 chartlet-f-8"><polyline points="432,1030.5 552,1030.5 544,1086.5 440,1086.5 432,1030.5" class="chartlet-diagram-shadow"/><polyline points="432,1028 552,1028 544,1084 440,1084 432,1028" class="chartlet-flow-node chartlet-role-teal"><title>Backup – second site</title></polyline><text x="492" y="1053.5" text-anchor="middle" class="chartlet-flow-label">Backup</text><text x="492" y="1067.5" text-anchor="middle" class="chartlet-flow-sublabel">second site</text></g><g class="chartlet-f chartlet-n-9 chartlet-f-5 chartlet-f-9"><rect x="616" y="130.5" width="128" height="56" class="chartlet-diagram-shadow"/><rect x="616" y="128" width="128" height="56" class="chartlet-flow-node chartlet-flow-external chartlet-role-gray"><title>School records – legacy system</title></rect><text x="680" y="153.5" text-anchor="middle" class="chartlet-flow-label">School records</text><text x="680" y="167.5" text-anchor="middle" class="chartlet-flow-sublabel">legacy system</text></g><g class="chartlet-f chartlet-n-10 chartlet-f-5 chartlet-f-10"><rect x="768" y="1038.5" width="104" height="40" class="chartlet-diagram-shadow"/><rect x="768" y="1036" width="104" height="40" class="chartlet-flow-node chartlet-flow-external chartlet-role-gray"><title>SIEM / SOC</title></rect><text x="820" y="1060.5" text-anchor="middle" class="chartlet-flow-label">SIEM / SOC</text></g></svg><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-0" for="chartlet-993d7890224c2061-focus-0"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-1" for="chartlet-993d7890224c2061-focus-1"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-2" for="chartlet-993d7890224c2061-focus-2"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-3" for="chartlet-993d7890224c2061-focus-3"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-4" for="chartlet-993d7890224c2061-focus-4"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-5" for="chartlet-993d7890224c2061-focus-5"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-6" for="chartlet-993d7890224c2061-focus-6"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-7" for="chartlet-993d7890224c2061-focus-7"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-8" for="chartlet-993d7890224c2061-focus-8"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-9" for="chartlet-993d7890224c2061-focus-9"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-hs-10" for="chartlet-993d7890224c2061-focus-10"></label></div></div><div class="chartlet-variant-mobile"><div class="chartlet-stage"><svg xmlns="http://www.w3.org/2000/svg" width="468" height="1180" viewBox="0 0 468 1180" id="chartlet-993d7890224c2061-m" role="img" aria-labelledby="chartlet-993d7890224c2061-m-title chartlet-993d7890224c2061-m-description" class="chartlet-root"><title id="chartlet-993d7890224c2061-m-title">Multi-tenant line-of-business application</title><desc id="chartlet-993d7890224c2061-m-description">Architecture diagram with 11 components and 10 connections in 3 boundaries. Data center: Reverse proxy, Application network. Application network (in Data center): Web / BFF, Sign-in, Domain API, Data zone. Data zone (in Application network): Domain data, Audit log. Main path: Teacher, parent → Browser → Reverse proxy → Web / BFF → Domain API → Domain data. Most connected: Domain API (5 connections). Nothing leads into Teacher, parent and School records. Teacher, parent (person): connects to Browser (uses). Browser (frontend): connects to Reverse proxy (calls, via HTTPS). School records (external system): connects to Domain API (master data, via REST/JSON). Reverse proxy (security): connects to Web / BFF (forwards). Web / BFF (service): connects to Sign-in (signs in, via OIDC) and Domain API (queries, via user context). Sign-in (security): no outgoing connection. Domain API (service): connects to Domain data (reads, writes, via SQL/TLS), Audit log (logs) and SIEM / SOC (events, via Syslog). Domain data (database): connects to Backup (backs up). Audit log (database): no outgoing connection. Backup (storage): no outgoing connection. SIEM / SOC (external system): no outgoing connection.</desc><style>.chartlet-root{--chartlet-text:#172033;--chartlet-muted:#344054;--chartlet-grid:#d9dee8;--chartlet-zero:#667085;--chartlet-accent:#2563eb;--chartlet-background:#fff;--chartlet-color-1:#2563eb;--chartlet-color-2:#c2410c;--chartlet-color-3:#475569;--chartlet-color-4:#111827;max-width:100%;height:auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:var(--chartlet-text)}#chartlet-993d7890224c2061-m .chartlet-title{font-size:22px;font-weight:650;fill:var(--chartlet-text)}#chartlet-993d7890224c2061-m .chartlet-label,#chartlet-993d7890224c2061-m .chartlet-tick,#chartlet-993d7890224c2061-m .chartlet-value,#chartlet-993d7890224c2061-m .chartlet-value-inverse,#chartlet-993d7890224c2061-m .chartlet-axis-title{font-size:12px;fill:var(--chartlet-muted)}#chartlet-993d7890224c2061-m .chartlet-value,#chartlet-993d7890224c2061-m .chartlet-value-inverse{font-weight:600}#chartlet-993d7890224c2061-m .chartlet-value{fill:var(--chartlet-text)}#chartlet-993d7890224c2061-m .chartlet-value-inverse{fill:var(--chartlet-background)}#chartlet-993d7890224c2061-m .chartlet-axis-title{font-weight:600}#chartlet-993d7890224c2061-m .chartlet-grid{stroke:var(--chartlet-grid);stroke-width:1}#chartlet-993d7890224c2061-m .chartlet-zero{stroke:var(--chartlet-zero);stroke-width:1.5}#chartlet-993d7890224c2061-m .chartlet-bar,#chartlet-993d7890224c2061-m .chartlet-point{fill:var(--chartlet-accent)}#chartlet-993d7890224c2061-m .chartlet-line{fill:none;stroke:var(--chartlet-accent);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}#chartlet-993d7890224c2061-m .chartlet-background{fill:var(--chartlet-background)}#chartlet-993d7890224c2061-m .chartlet-title-small{font-size:18px}.chartlet-root{--chartlet-node:#eef3fd;--chartlet-lane:#f7f9fc;--chartlet-lane-head:#eef1f6;--chartlet-shadow:rgba(16,24,40,.09);--chartlet-role-blue:#2563eb;--chartlet-role-blue-fill:#eef3fd;--chartlet-role-green:#15803d;--chartlet-role-green-fill:#ecfdf3;--chartlet-role-amber:#b45309;--chartlet-role-amber-fill:#fff7e8;--chartlet-role-teal:#0f766e;--chartlet-role-teal-fill:#e9faf7;--chartlet-role-violet:#6d28d9;--chartlet-role-violet-fill:#f3efff;--chartlet-role-gray:#667085;--chartlet-role-gray-fill:#f7f8fa;--chartlet-role-red:#b42318;--chartlet-role-red-fill:#fef3f2}.chartlet-root.chartlet-theme-dark{--chartlet-node:#1a2436;--chartlet-lane:#121925;--chartlet-lane-head:#18212f;--chartlet-shadow:rgba(0,0,0,.45);--chartlet-role-blue:#7ea6ff;--chartlet-role-blue-fill:#1a2436;--chartlet-role-green:#4ade80;--chartlet-role-green-fill:#132a1d;--chartlet-role-amber:#fbbf24;--chartlet-role-amber-fill:#2b2210;--chartlet-role-teal:#2dd4bf;--chartlet-role-teal-fill:#0f2a27;--chartlet-role-violet:#b69cff;--chartlet-role-violet-fill:#231c38;--chartlet-role-gray:#9aa7bd;--chartlet-role-gray-fill:#161d29;--chartlet-role-red:#f97066;--chartlet-role-red-fill:#2d1616}#chartlet-993d7890224c2061-m .chartlet-role-blue{fill:var(--chartlet-role-blue-fill);stroke:var(--chartlet-role-blue)}#chartlet-993d7890224c2061-m .chartlet-role-green{fill:var(--chartlet-role-green-fill);stroke:var(--chartlet-role-green)}#chartlet-993d7890224c2061-m .chartlet-role-amber{fill:var(--chartlet-role-amber-fill);stroke:var(--chartlet-role-amber)}#chartlet-993d7890224c2061-m .chartlet-role-teal{fill:var(--chartlet-role-teal-fill);stroke:var(--chartlet-role-teal)}#chartlet-993d7890224c2061-m .chartlet-role-violet{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet)}#chartlet-993d7890224c2061-m .chartlet-role-gray{fill:var(--chartlet-role-gray-fill);stroke:var(--chartlet-role-gray)}#chartlet-993d7890224c2061-m .chartlet-role-red{fill:var(--chartlet-role-red-fill);stroke:var(--chartlet-role-red)}#chartlet-993d7890224c2061-m .chartlet-diagram-rim{fill:none;stroke:var(--chartlet-role-teal);stroke-width:1.5}#chartlet-993d7890224c2061-m .chartlet-diagram-shadow{fill:var(--chartlet-shadow);stroke:none;rx:7px}#chartlet-993d7890224c2061-m .chartlet-diagram-chip{fill:var(--chartlet-background);stroke:var(--chartlet-grid);stroke-width:1;rx:4px}#chartlet-993d7890224c2061-m .chartlet-diagram-chip-text{font-size:12px;fill:var(--chartlet-text)}#chartlet-993d7890224c2061-m .chartlet-diagram-badge{fill:var(--chartlet-accent);stroke:var(--chartlet-background);stroke-width:2}#chartlet-993d7890224c2061-m .chartlet-diagram-badge-text{font-size:10px;font-weight:700;fill:var(--chartlet-background)}#chartlet-993d7890224c2061-m .chartlet-flow-node{stroke-width:1.5;stroke-linejoin:round;rx:7px}#chartlet-993d7890224c2061-m .chartlet-flow-start{stroke-width:2}#chartlet-993d7890224c2061-m .chartlet-flow-end{stroke-width:3}#chartlet-993d7890224c2061-m .chartlet-flow-external{stroke-dasharray:5 3}#chartlet-993d7890224c2061-m .chartlet-flow-inner{stroke:var(--chartlet-role-blue);stroke-width:1}#chartlet-993d7890224c2061-m .chartlet-flow-label{font-size:13px;font-weight:600;fill:var(--chartlet-text)}#chartlet-993d7890224c2061-m .chartlet-flow-sublabel{font-size:11px;fill:var(--chartlet-muted)}#chartlet-993d7890224c2061-m .chartlet-flow-edge{fill:none;stroke:var(--chartlet-zero);stroke-width:1.4;stroke-linejoin:round}#chartlet-993d7890224c2061-m .chartlet-flow-dashed{stroke-dasharray:5 4}#chartlet-993d7890224c2061-m .chartlet-flow-dotted{stroke-dasharray:1 4;stroke-linecap:round}#chartlet-993d7890224c2061-m .chartlet-flow-main{stroke:var(--chartlet-accent);stroke-width:2.2}#chartlet-993d7890224c2061-m .chartlet-flow-head{fill:var(--chartlet-zero);stroke:var(--chartlet-zero);stroke-width:1;stroke-linejoin:round}#chartlet-993d7890224c2061-m .chartlet-flow-main-head{fill:var(--chartlet-accent);stroke:var(--chartlet-accent)}#chartlet-993d7890224c2061-m .chartlet-flow-lane{fill:var(--chartlet-lane);stroke:var(--chartlet-grid);stroke-width:1}#chartlet-993d7890224c2061-m .chartlet-flow-lane-alt{fill:var(--chartlet-background)}#chartlet-993d7890224c2061-m .chartlet-flow-lane-head{fill:var(--chartlet-lane-head);stroke:none}#chartlet-993d7890224c2061-m .chartlet-flow-lane-label{font-size:11px;font-weight:650;fill:var(--chartlet-muted);letter-spacing:.04em}#chartlet-993d7890224c2061-m .chartlet-flow-group{fill:var(--chartlet-accent);fill-opacity:.04;stroke:var(--chartlet-zero);stroke-width:1;stroke-dasharray:4 3;rx:10px}#chartlet-993d7890224c2061-m .chartlet-flow-group-label{font-size:11px;font-weight:600;fill:var(--chartlet-muted)}#chartlet-993d7890224c2061-m .chartlet-arch-head{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet);stroke-width:1.5}#chartlet-993d7890224c2061-m .chartlet-arch-dot{fill:var(--chartlet-role-blue);stroke:none}</style><rect x="12" y="300" width="384" height="728" class="chartlet-flow-group"/><text x="20" y="313" text-anchor="start" class="chartlet-flow-group-label">Data center</text><rect x="24" y="464" width="360" height="552" class="chartlet-flow-group"/><text x="32" y="477" text-anchor="start" class="chartlet-flow-group-label">Application network</text><rect x="140" y="884" width="232" height="120" class="chartlet-flow-group"/><text x="148" y="897" text-anchor="start" class="chartlet-flow-group-label">Data zone</text><g class="chartlet-f chartlet-f-0 chartlet-f-1"><polyline points="204,88 204,152" class="chartlet-flow-edge chartlet-flow-main"><title>Teacher, parent → Browser: uses</title></polyline><polyline points="200.5,152 204,160 207.5,152 200.5,152" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-1 chartlet-f-2"><polyline points="204,208 204,320" class="chartlet-flow-edge chartlet-flow-main"><title>Browser → Reverse proxy: calls [HTTPS]</title></polyline><polyline points="200.5,320 204,328 207.5,320 200.5,320" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-2 chartlet-f-3"><polyline points="204,400 204,484" class="chartlet-flow-edge chartlet-flow-main"><title>Reverse proxy → Web / BFF: forwards</title></polyline><polyline points="200.5,484 204,492 207.5,484 200.5,484" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-4"><polyline points="180,548 180,611 88,611 88,632" class="chartlet-flow-edge"><title>Web / BFF → Sign-in: signs in [OIDC]</title></polyline><polyline points="84.5,632 88,640 91.5,632 84.5,632" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-5"><polyline points="204,548 204,640" class="chartlet-flow-edge chartlet-flow-main"><title>Web / BFF → Domain API: queries [user context]</title></polyline><polyline points="200.5,640 204,648 207.5,640 200.5,640" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-6"><polyline points="204,704 204,904" class="chartlet-flow-edge chartlet-flow-main"><title>Domain API → Domain data: reads, writes [SQL/TLS]</title></polyline><polyline points="200.5,904 204,912 207.5,904 200.5,904" class="chartlet-flow-head chartlet-flow-main-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-7"><polyline points="224,704 224,853.75 316,853.75 316,912" class="chartlet-flow-edge"><title>Domain API → Audit log: logs</title></polyline><polyline points="312.5,912 316,920 319.5,912 312.5,912" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-9"><polyline points="316,220 316,611 228,611 228,640" class="chartlet-flow-edge"><title>School records → Domain API: master data [REST/JSON]</title></polyline><polyline points="224.5,640 228,648 231.5,640 224.5,640" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-5 chartlet-f-10"><polyline points="244,704 244,841.15 428,841.15 428,1077.05 404,1077.05 404,1104" class="chartlet-flow-edge chartlet-flow-dashed"><title>Domain API → SIEM / SOC: events [Syslog]</title></polyline><polyline points="400.5,1104 404,1112 407.5,1104 400.5,1104" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-6 chartlet-f-8"><polyline points="204,992 204,1077.05 180,1077.05 180,1096" class="chartlet-flow-edge chartlet-flow-dashed"><title>Domain data → Backup: backs up</title></polyline><polyline points="176.5,1096 180,1104 183.5,1096 176.5,1096" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1"></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-2"></g><g class="chartlet-f chartlet-n-2 chartlet-f-1 chartlet-f-2 chartlet-f-3"></g><g class="chartlet-f chartlet-n-3 chartlet-f-2 chartlet-f-3 chartlet-f-4 chartlet-f-5"></g><g class="chartlet-f chartlet-n-4 chartlet-f-3 chartlet-f-4"></g><g class="chartlet-f chartlet-n-5 chartlet-f-3 chartlet-f-5 chartlet-f-6 chartlet-f-7 chartlet-f-9 chartlet-f-10"></g><g class="chartlet-f chartlet-n-6 chartlet-f-5 chartlet-f-6 chartlet-f-8"></g><g class="chartlet-f chartlet-n-7 chartlet-f-5 chartlet-f-7"></g><g class="chartlet-f chartlet-n-8 chartlet-f-6 chartlet-f-8"></g><g class="chartlet-f chartlet-n-9 chartlet-f-5 chartlet-f-9"></g><g class="chartlet-f chartlet-n-10 chartlet-f-5 chartlet-f-10"></g><g class="chartlet-f chartlet-f-0 chartlet-f-1"><rect x="208" y="93" width="36.88" height="21" class="chartlet-diagram-chip"/><text x="213" y="107" text-anchor="start" class="chartlet-diagram-chip-text">uses</text></g><g class="chartlet-f chartlet-f-1 chartlet-f-2"><rect x="208" y="223" width="63.64" height="36" class="chartlet-diagram-chip"/><text x="213" y="237" text-anchor="start" class="chartlet-diagram-chip-text">calls</text><text x="213" y="252" text-anchor="start" class="chartlet-diagram-chip-text">[HTTPS]</text></g><g class="chartlet-f chartlet-f-2 chartlet-f-3"><rect x="208" y="405" width="67.84" height="21" class="chartlet-diagram-chip"/><text x="213" y="419" text-anchor="start" class="chartlet-diagram-chip-text">forwards</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-4"><rect x="121.36" y="553" width="54.64" height="36" class="chartlet-diagram-chip"/><text x="171" y="567" text-anchor="end" class="chartlet-diagram-chip-text">signs in</text><text x="171" y="582" text-anchor="end" class="chartlet-diagram-chip-text">[OIDC]</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-5"><rect x="208" y="553" width="101.2" height="36" class="chartlet-diagram-chip"/><text x="213" y="567" text-anchor="start" class="chartlet-diagram-chip-text">queries</text><text x="213" y="582" text-anchor="start" class="chartlet-diagram-chip-text">[user context]</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-6"><rect x="107.68" y="715" width="92.32" height="36" class="chartlet-diagram-chip"/><text x="195" y="729" text-anchor="end" class="chartlet-diagram-chip-text">reads, writes</text><text x="195" y="744" text-anchor="end" class="chartlet-diagram-chip-text">[SQL/TLS]</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-7"><rect x="253.12" y="857.75" width="33.76" height="21" class="chartlet-diagram-chip"/><text x="270" y="871.75" text-anchor="middle" class="chartlet-diagram-chip-text">logs</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-9"><rect x="320" y="225" width="94.48" height="36" class="chartlet-diagram-chip"/><text x="325" y="239" text-anchor="start" class="chartlet-diagram-chip-text">master data</text><text x="325" y="254" text-anchor="start" class="chartlet-diagram-chip-text">[REST/JSON]</text></g><g class="chartlet-f chartlet-f-5 chartlet-f-10"><rect x="248" y="709" width="61.96" height="36" class="chartlet-diagram-chip"/><text x="253" y="723" text-anchor="start" class="chartlet-diagram-chip-text">events</text><text x="253" y="738" text-anchor="start" class="chartlet-diagram-chip-text">[Syslog]</text></g><g class="chartlet-f chartlet-f-6 chartlet-f-8"><rect x="208" y="1031" width="60.88" height="21" class="chartlet-diagram-chip"/><text x="213" y="1045" text-anchor="start" class="chartlet-diagram-chip-text">backs up</text></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1"><rect x="160" y="18.5" width="88" height="72" class="chartlet-diagram-shadow"/><rect x="160" y="16" width="88" height="72" class="chartlet-flow-node chartlet-role-violet"><title>Teacher, parent</title></rect><circle cx="204" cy="27" r="6" class="chartlet-arch-head"/><text x="204" y="56.5" text-anchor="middle" class="chartlet-flow-label">Teacher,</text><text x="204" y="72.5" text-anchor="middle" class="chartlet-flow-label">parent</text></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-2"><rect x="160" y="162.5" width="88" height="48" class="chartlet-diagram-shadow"/><rect x="160" y="160" width="88" height="48" class="chartlet-flow-node chartlet-role-blue"><title>Browser</title></rect><line x1="160" y1="172" x2="248" y2="172" class="chartlet-flow-inner"/><circle cx="168" cy="166" r="1.8" class="chartlet-arch-dot"/><circle cx="174" cy="166" r="1.8" class="chartlet-arch-dot"/><circle cx="180" cy="166" r="1.8" class="chartlet-arch-dot"/><text x="204" y="194.5" text-anchor="middle" class="chartlet-flow-label">Browser</text></g><g class="chartlet-f chartlet-n-2 chartlet-f-1 chartlet-f-2 chartlet-f-3"><polyline points="144,330.5 264,330.5 264,373.7 204,402.5 144,373.7 144,330.5" class="chartlet-diagram-shadow"/><polyline points="144,328 264,328 264,371.2 204,400 144,371.2 144,328" class="chartlet-flow-node chartlet-role-red"><title>Reverse proxy – TLS 1.3, WAF</title></polyline><text x="204" y="355.5" text-anchor="middle" class="chartlet-flow-label">Reverse proxy</text><text x="204" y="369.5" text-anchor="middle" class="chartlet-flow-sublabel">TLS 1.3, WAF</text></g><g class="chartlet-f chartlet-n-3 chartlet-f-2 chartlet-f-3 chartlet-f-4 chartlet-f-5"><rect x="156" y="494.5" width="96" height="56" class="chartlet-diagram-shadow"/><rect x="156" y="492" width="96" height="56" class="chartlet-flow-node chartlet-role-blue"><title>Web / BFF – SvelteKit</title></rect><text x="204" y="517.5" text-anchor="middle" class="chartlet-flow-label">Web / BFF</text><text x="204" y="531.5" text-anchor="middle" class="chartlet-flow-sublabel">SvelteKit</text></g><g class="chartlet-f chartlet-n-4 chartlet-f-3 chartlet-f-4"><polyline points="36,642.5 140,642.5 140,685.7 88,714.5 36,685.7 36,642.5" class="chartlet-diagram-shadow"/><polyline points="36,640 140,640 140,683.2 88,712 36,683.2 36,640" class="chartlet-flow-node chartlet-role-red"><title>Sign-in – Keycloak, OIDC</title></polyline><text x="88" y="667.5" text-anchor="middle" class="chartlet-flow-label">Sign-in</text><text x="88" y="681.5" text-anchor="middle" class="chartlet-flow-sublabel">Keycloak, OIDC</text></g><g class="chartlet-f chartlet-n-5 chartlet-f-3 chartlet-f-5 chartlet-f-6 chartlet-f-7 chartlet-f-9 chartlet-f-10"><rect x="156" y="650.5" width="96" height="56" class="chartlet-diagram-shadow"/><rect x="156" y="648" width="96" height="56" class="chartlet-flow-node chartlet-role-blue"><title>Domain API – Rust</title></rect><text x="204" y="673.5" text-anchor="middle" class="chartlet-flow-label">Domain API</text><text x="204" y="687.5" text-anchor="middle" class="chartlet-flow-sublabel">Rust</text></g><g class="chartlet-f chartlet-n-6 chartlet-f-5 chartlet-f-6 chartlet-f-8"><polyline points="152,919.5 152,989.5 153.772,990.794 158.967,992 167.23,993.036 178,993.83 190.541,994.33 204,994.5 217.459,994.33 230,993.83 240.77,993.036 249.033,992 254.228,990.794 256,989.5 256,919.5 254.228,918.206 249.033,917 240.77,915.964 230,915.17 217.459,914.67 204,914.5 190.541,914.67 178,915.17 167.23,915.964 158.967,917 153.772,918.206 152,919.5 152,919.5" class="chartlet-diagram-shadow"/><polyline points="152,917 152,987 153.772,988.294 158.967,989.5 167.23,990.536 178,991.33 190.541,991.83 204,992 217.459,991.83 230,991.33 240.77,990.536 249.033,989.5 254.228,988.294 256,987 256,917 254.228,915.706 249.033,914.5 240.77,913.464 230,912.67 217.459,912.17 204,912 190.541,912.17 178,912.67 167.23,913.464 158.967,914.5 153.772,915.706 152,917 152,917" class="chartlet-flow-node chartlet-role-teal"><title>Domain data – Postgres, RLS per tenant</title></polyline><polyline points="152,917 153.772,918.294 158.967,919.5 167.23,920.536 178,921.33 190.541,921.83 204,922 217.459,921.83 230,921.33 240.77,920.536 249.033,919.5 254.228,918.294 256,917" class="chartlet-diagram-rim"/><text x="204" y="945.5" text-anchor="middle" class="chartlet-flow-label">Domain data</text><text x="204" y="959.5" text-anchor="middle" class="chartlet-flow-sublabel">Postgres, RLS</text><text x="204" y="973.5" text-anchor="middle" class="chartlet-flow-sublabel">per tenant</text></g><g class="chartlet-f chartlet-n-7 chartlet-f-5 chartlet-f-7"><polyline points="272,927.5 272,981.5 273.499,982.794 277.895,984 284.887,985.036 294,985.83 304.612,986.33 316,986.5 327.388,986.33 338,985.83 347.113,985.036 354.105,984 358.501,982.794 360,981.5 360,927.5 358.501,926.206 354.105,925 347.113,923.964 338,923.17 327.388,922.67 316,922.5 304.612,922.67 294,923.17 284.887,923.964 277.895,925 273.499,926.206 272,927.5 272,927.5" class="chartlet-diagram-shadow"/><polyline points="272,925 272,979 273.499,980.294 277.895,981.5 284.887,982.536 294,983.33 304.612,983.83 316,984 327.388,983.83 338,983.33 347.113,982.536 354.105,981.5 358.501,980.294 360,979 360,925 358.501,923.706 354.105,922.5 347.113,921.464 338,920.67 327.388,920.17 316,920 304.612,920.17 294,920.67 284.887,921.464 277.895,922.5 273.499,923.706 272,925 272,925" class="chartlet-flow-node chartlet-role-teal"><title>Audit log – append only</title></polyline><polyline points="272,925 273.499,926.294 277.895,927.5 284.887,928.536 294,929.33 304.612,929.83 316,930 327.388,929.83 338,929.33 347.113,928.536 354.105,927.5 358.501,926.294 360,925" class="chartlet-diagram-rim"/><text x="316" y="952.5" text-anchor="middle" class="chartlet-flow-label">Audit log</text><text x="316" y="966.5" text-anchor="middle" class="chartlet-flow-sublabel">append only</text></g><g class="chartlet-f chartlet-n-8 chartlet-f-6 chartlet-f-8"><polyline points="128,1106.5 232,1106.5 224,1162.5 136,1162.5 128,1106.5" class="chartlet-diagram-shadow"/><polyline points="128,1104 232,1104 224,1160 136,1160 128,1104" class="chartlet-flow-node chartlet-role-teal"><title>Backup – second site</title></polyline><text x="180" y="1129.5" text-anchor="middle" class="chartlet-flow-label">Backup</text><text x="180" y="1143.5" text-anchor="middle" class="chartlet-flow-sublabel">second site</text></g><g class="chartlet-f chartlet-n-9 chartlet-f-5 chartlet-f-9"><rect x="264" y="150.5" width="104" height="72" class="chartlet-diagram-shadow"/><rect x="264" y="148" width="104" height="72" class="chartlet-flow-node chartlet-flow-external chartlet-role-gray"><title>School records – legacy system</title></rect><text x="316" y="173.5" text-anchor="middle" class="chartlet-flow-label">School</text><text x="316" y="189.5" text-anchor="middle" class="chartlet-flow-label">records</text><text x="316" y="203.5" text-anchor="middle" class="chartlet-flow-sublabel">legacy system</text></g><g class="chartlet-f chartlet-n-10 chartlet-f-5 chartlet-f-10"><rect x="352" y="1114.5" width="104" height="40" class="chartlet-diagram-shadow"/><rect x="352" y="1112" width="104" height="40" class="chartlet-flow-node chartlet-flow-external chartlet-role-gray"><title>SIEM / SOC</title></rect><text x="404" y="1136.5" text-anchor="middle" class="chartlet-flow-label">SIEM / SOC</text></g></svg><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-0" for="chartlet-993d7890224c2061-focus-0"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-1" for="chartlet-993d7890224c2061-focus-1"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-2" for="chartlet-993d7890224c2061-focus-2"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-3" for="chartlet-993d7890224c2061-focus-3"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-4" for="chartlet-993d7890224c2061-focus-4"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-5" for="chartlet-993d7890224c2061-focus-5"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-6" for="chartlet-993d7890224c2061-focus-6"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-7" for="chartlet-993d7890224c2061-focus-7"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-8" for="chartlet-993d7890224c2061-focus-8"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-9" for="chartlet-993d7890224c2061-focus-9"></label><label class="chartlet-hotspot" id="chartlet-993d7890224c2061-m-hs-10" for="chartlet-993d7890224c2061-focus-10"></label></div></div><p class="chartlet-source">Source: Illustrative reference architecture</p><details class="chartlet-data" data-viz-text><summary>Show chart data</summary><table><caption>Data for Multi-tenant line-of-business application</caption><thead><tr><th scope="col">Component</th><th scope="col">Kind</th><th scope="col">Boundary</th><th scope="col">Connects to</th></tr></thead><tbody><tr><th scope="row">Teacher, parent</th><td>person</td><td></td><td>Browser (uses)</td></tr><tr><th scope="row">Browser</th><td>frontend</td><td></td><td>Reverse proxy (calls, via HTTPS)</td></tr><tr><th scope="row">School records</th><td>external system</td><td></td><td>Domain API (master data, via REST/JSON)</td></tr><tr><th scope="row">Reverse proxy</th><td>security</td><td>Data center</td><td>Web / BFF (forwards)</td></tr><tr><th scope="row">Web / BFF</th><td>service</td><td>Data center › Application network</td><td>Sign-in (signs in, via OIDC), Domain API (queries, via user context)</td></tr><tr><th scope="row">Sign-in</th><td>security</td><td>Data center › Application network</td><td></td></tr><tr><th scope="row">Domain API</th><td>service</td><td>Data center › Application network</td><td>Domain data (reads, writes, via SQL/TLS), Audit log (logs), SIEM / SOC (events, via Syslog)</td></tr><tr><th scope="row">Domain data</th><td>database</td><td>Data center › Application network › Data zone</td><td>Backup (backs up)</td></tr><tr><th scope="row">Audit log</th><td>database</td><td>Data center › Application network › Data zone</td><td></td></tr><tr><th scope="row">Backup</th><td>storage</td><td></td><td></td></tr><tr><th scope="row">SIEM / SOC</th><td>external system</td><td></td><td></td></tr></tbody></table></details></figure></div>