chartlet 0.21.0

Compile structured data into deterministic, accessible static charts
Documentation
1
<div class="chartlet-wrapper"><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-79335aff9fa623ac .chartlet-f{opacity:.18}#chartlet-79335aff9fa623ac-hs-0{left:1.714%;top:39.004%;width:7.429%;height:11.947%}#chartlet-79335aff9fa623ac-hs-1{left:16.386%;top:39.668%;width:9.468%;height:10.619%}#chartlet-79335aff9fa623ac-hs-2{left:36.569%;top:39.004%;width:7.49%;height:11.947%}#chartlet-79335aff9fa623ac-hs-3{left:57.134%;top:29.646%;width:7.429%;height:11.062%}#chartlet-79335aff9fa623ac-hs-4{left:56.755%;top:47.08%;width:8.186%;height:15.044%}#chartlet-79335aff9fa623ac-hs-5{left:76.427%;top:48.009%;width:8.289%;height:7.965%}#chartlet-79335aff9fa623ac-hs-6{left:76.857%;top:28.54%;width:7.429%;height:13.274%}#chartlet-79335aff9fa623ac-hs-7{left:88.298%;top:61.726%;width:9.988%;height:7.965%}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-0:checked) #chartlet-79335aff9fa623ac .chartlet-f-0{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-0:checked) #chartlet-79335aff9fa623ac .chartlet-n-0 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-0:checked) #chartlet-79335aff9fa623ac .chartlet-n-0 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-1:checked) #chartlet-79335aff9fa623ac .chartlet-f-1{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-1:checked) #chartlet-79335aff9fa623ac .chartlet-n-1 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-1:checked) #chartlet-79335aff9fa623ac .chartlet-n-1 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-2:checked) #chartlet-79335aff9fa623ac .chartlet-f-2{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-2:checked) #chartlet-79335aff9fa623ac .chartlet-n-2 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-2:checked) #chartlet-79335aff9fa623ac .chartlet-n-2 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-3:checked) #chartlet-79335aff9fa623ac .chartlet-f-3{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-3:checked) #chartlet-79335aff9fa623ac .chartlet-n-3 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-3:checked) #chartlet-79335aff9fa623ac .chartlet-n-3 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-4:checked) #chartlet-79335aff9fa623ac .chartlet-f-4{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-4:checked) #chartlet-79335aff9fa623ac .chartlet-n-4 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-4:checked) #chartlet-79335aff9fa623ac .chartlet-n-4 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-5:checked) #chartlet-79335aff9fa623ac .chartlet-f-5{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-5:checked) #chartlet-79335aff9fa623ac .chartlet-n-5 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-5:checked) #chartlet-79335aff9fa623ac .chartlet-n-5 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-6:checked) #chartlet-79335aff9fa623ac .chartlet-f-6{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-6:checked) #chartlet-79335aff9fa623ac .chartlet-n-6 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-6:checked) #chartlet-79335aff9fa623ac .chartlet-n-6 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-7:checked) #chartlet-79335aff9fa623ac .chartlet-f-7{opacity:1}.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-7:checked) #chartlet-79335aff9fa623ac .chartlet-n-7 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-79335aff9fa623ac-focus-7:checked) #chartlet-79335aff9fa623ac .chartlet-n-7 .chartlet-seq-box{stroke-width:3}</style><details class="chartlet-focus"><summary>Focus</summary><fieldset><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" checked> Show all</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-0"> Customer</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-1"> Customer portal</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-2"> API gateway</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-3"> Monolith</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-4"> Billing service</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-5"> Invoice events</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-6"> Accounts</label><label><input type="radio" name="chartlet-79335aff9fa623ac-focus" class="chartlet-focus-node" id="chartlet-79335aff9fa623ac-focus-7"> Payment provider</label></fieldset></details><figure class="chartlet-figure" data-viz="chart"><figcaption>Billing moves from the monolith to its own service</figcaption><div class="chartlet-stage"><svg xmlns="http://www.w3.org/2000/svg" width="1400" height="452" viewBox="0 0 1400 452" id="chartlet-79335aff9fa623ac" role="img" aria-labelledby="chartlet-79335aff9fa623ac-title chartlet-79335aff9fa623ac-description" class="chartlet-root"><title id="chartlet-79335aff9fa623ac-title">Billing moves from the monolith to its own service</title><desc id="chartlet-79335aff9fa623ac-description">Architecture diagram with 8 components and 8 connections in 1 boundary. Platform: API gateway, Monolith, Billing service, Invoice events, Accounts. Most connected: Billing service (4 connections). Nothing leads into Customer. Nothing leads out of Invoice events, Accounts and Payment provider. Bottleneck: API gateway; without it the diagram falls apart. Customer (person): connects to Customer portal (pays). Customer portal (frontend): connects to API gateway (calls, via HTTPS). API gateway (security): connects to Monolith (routes today) and Billing service (routes after). Monolith (service): connects to Accounts (via SQL). Billing service (service): connects to Accounts (via SQL), Invoice events (publishes) and Payment provider (charges, via HTTPS). Accounts (database): no outgoing connection. Invoice events (queue): no outgoing connection. Payment provider (external system): no outgoing connection. Roles: critical: API gateway, Accounts, Billing service → Payment provider; planned: Billing service, Invoice events, API gateway → Billing service, Billing service → Accounts, Billing service → Invoice events; deprecated: Monolith, API gateway → Monolith, Monolith → Accounts.</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-79335aff9fa623ac .chartlet-title{font-size:22px;font-weight:650;fill:var(--chartlet-text)}#chartlet-79335aff9fa623ac .chartlet-label,#chartlet-79335aff9fa623ac .chartlet-tick,#chartlet-79335aff9fa623ac .chartlet-value,#chartlet-79335aff9fa623ac .chartlet-value-inverse,#chartlet-79335aff9fa623ac .chartlet-axis-title{font-size:12px;fill:var(--chartlet-muted)}#chartlet-79335aff9fa623ac .chartlet-value,#chartlet-79335aff9fa623ac .chartlet-value-inverse{font-weight:600}#chartlet-79335aff9fa623ac .chartlet-value{fill:var(--chartlet-text)}#chartlet-79335aff9fa623ac .chartlet-value-inverse{fill:var(--chartlet-background)}#chartlet-79335aff9fa623ac .chartlet-axis-title{font-weight:600}#chartlet-79335aff9fa623ac .chartlet-grid{stroke:var(--chartlet-grid);stroke-width:1}#chartlet-79335aff9fa623ac .chartlet-zero{stroke:var(--chartlet-zero);stroke-width:1.5}#chartlet-79335aff9fa623ac .chartlet-bar,#chartlet-79335aff9fa623ac .chartlet-point{fill:var(--chartlet-accent)}#chartlet-79335aff9fa623ac .chartlet-line{fill:none;stroke:var(--chartlet-accent);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}#chartlet-79335aff9fa623ac .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-79335aff9fa623ac .chartlet-role-blue{fill:var(--chartlet-role-blue-fill);stroke:var(--chartlet-role-blue)}#chartlet-79335aff9fa623ac .chartlet-role-green{fill:var(--chartlet-role-green-fill);stroke:var(--chartlet-role-green)}#chartlet-79335aff9fa623ac .chartlet-role-amber{fill:var(--chartlet-role-amber-fill);stroke:var(--chartlet-role-amber)}#chartlet-79335aff9fa623ac .chartlet-role-teal{fill:var(--chartlet-role-teal-fill);stroke:var(--chartlet-role-teal)}#chartlet-79335aff9fa623ac .chartlet-role-violet{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet)}#chartlet-79335aff9fa623ac .chartlet-role-gray{fill:var(--chartlet-role-gray-fill);stroke:var(--chartlet-role-gray)}#chartlet-79335aff9fa623ac .chartlet-role-red{fill:var(--chartlet-role-red-fill);stroke:var(--chartlet-role-red)}#chartlet-79335aff9fa623ac .chartlet-diagram-rim{fill:none;stroke:var(--chartlet-role-teal);stroke-width:1.5}#chartlet-79335aff9fa623ac .chartlet-diagram-shadow{fill:var(--chartlet-shadow);stroke:none;rx:7px}#chartlet-79335aff9fa623ac .chartlet-diagram-chip{fill:var(--chartlet-background);stroke:var(--chartlet-grid);stroke-width:1;rx:4px}#chartlet-79335aff9fa623ac .chartlet-diagram-chip-text{font-size:12px;fill:var(--chartlet-text)}#chartlet-79335aff9fa623ac .chartlet-diagram-badge{fill:var(--chartlet-accent);stroke:var(--chartlet-background);stroke-width:2}#chartlet-79335aff9fa623ac .chartlet-diagram-badge-text{font-size:10px;font-weight:700;fill:var(--chartlet-background)}#chartlet-79335aff9fa623ac .chartlet-flow-node{stroke-width:1.5;stroke-linejoin:round;rx:7px}#chartlet-79335aff9fa623ac .chartlet-flow-start{stroke-width:2}#chartlet-79335aff9fa623ac .chartlet-flow-end{stroke-width:3}#chartlet-79335aff9fa623ac .chartlet-flow-external{stroke-dasharray:5 3}#chartlet-79335aff9fa623ac .chartlet-flow-inner{stroke:var(--chartlet-role-blue);stroke-width:1}#chartlet-79335aff9fa623ac .chartlet-flow-label{font-size:13px;font-weight:600;fill:var(--chartlet-text)}#chartlet-79335aff9fa623ac .chartlet-flow-sublabel{font-size:11px;fill:var(--chartlet-muted)}#chartlet-79335aff9fa623ac .chartlet-flow-edge{fill:none;stroke:var(--chartlet-zero);stroke-width:1.4;stroke-linejoin:round}#chartlet-79335aff9fa623ac .chartlet-flow-dashed{stroke-dasharray:5 4}#chartlet-79335aff9fa623ac .chartlet-flow-dotted{stroke-dasharray:1 4;stroke-linecap:round}#chartlet-79335aff9fa623ac .chartlet-flow-main{stroke:var(--chartlet-accent);stroke-width:2.2}#chartlet-79335aff9fa623ac .chartlet-flow-head{fill:var(--chartlet-zero);stroke:var(--chartlet-zero);stroke-width:1;stroke-linejoin:round}#chartlet-79335aff9fa623ac .chartlet-flow-main-head{fill:var(--chartlet-accent);stroke:var(--chartlet-accent)}#chartlet-79335aff9fa623ac .chartlet-flow-lane{fill:var(--chartlet-lane);stroke:var(--chartlet-grid);stroke-width:1}#chartlet-79335aff9fa623ac .chartlet-flow-lane-alt{fill:var(--chartlet-background)}#chartlet-79335aff9fa623ac .chartlet-flow-lane-head{fill:var(--chartlet-lane-head);stroke:none}#chartlet-79335aff9fa623ac .chartlet-flow-lane-label{font-size:11px;font-weight:650;fill:var(--chartlet-muted);letter-spacing:.04em}#chartlet-79335aff9fa623ac .chartlet-flow-group{fill:var(--chartlet-accent);fill-opacity:.04;stroke:var(--chartlet-zero);stroke-width:1;stroke-dasharray:4 3;rx:10px}#chartlet-79335aff9fa623ac .chartlet-flow-group-label{font-size:11px;font-weight:600;fill:var(--chartlet-muted)}#chartlet-79335aff9fa623ac .chartlet-arch-head{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet);stroke-width:1.5}#chartlet-79335aff9fa623ac .chartlet-arch-dot{fill:var(--chartlet-role-blue);stroke:none}#chartlet-79335aff9fa623ac .chartlet-flow-role-critical .chartlet-flow-node{stroke:var(--chartlet-role-red);stroke-width:3}#chartlet-79335aff9fa623ac .chartlet-flow-role-planned .chartlet-flow-node{stroke:var(--chartlet-role-violet);stroke-dasharray:6 3}#chartlet-79335aff9fa623ac .chartlet-flow-role-deprecated .chartlet-flow-node{stroke:var(--chartlet-role-gray);stroke-dasharray:1.5 3}#chartlet-79335aff9fa623ac .chartlet-flow-role-critical .chartlet-flow-edge{stroke:var(--chartlet-role-red);stroke-width:2.6}#chartlet-79335aff9fa623ac .chartlet-flow-role-planned .chartlet-flow-edge{stroke:var(--chartlet-role-violet);stroke-dasharray:6 4}#chartlet-79335aff9fa623ac .chartlet-flow-role-deprecated .chartlet-flow-edge{stroke:var(--chartlet-role-gray);stroke-dasharray:1 4;stroke-linecap:round}#chartlet-79335aff9fa623ac .chartlet-flow-role-critical .chartlet-flow-head,#chartlet-79335aff9fa623ac .chartlet-flow-role-critical .chartlet-diagram-badge{fill:var(--chartlet-role-red);stroke:var(--chartlet-role-red)}#chartlet-79335aff9fa623ac .chartlet-flow-role-planned .chartlet-flow-head,#chartlet-79335aff9fa623ac .chartlet-flow-role-planned .chartlet-diagram-badge{fill:var(--chartlet-role-violet);stroke:var(--chartlet-role-violet)}#chartlet-79335aff9fa623ac .chartlet-flow-role-deprecated .chartlet-flow-head,#chartlet-79335aff9fa623ac .chartlet-flow-role-deprecated .chartlet-diagram-badge{fill:var(--chartlet-role-gray);stroke:var(--chartlet-role-gray)}#chartlet-79335aff9fa623ac .chartlet-legend{font-size:12px;fill:var(--chartlet-muted)}</style><rect x="499.97" y="101" width="698.047" height="191.8" class="chartlet-flow-group"/><text x="507.97" y="114" text-anchor="start" class="chartlet-flow-group-label">Platform</text><g class="chartlet-f chartlet-f-0 chartlet-f-1"><polyline points="128,203.3 221.411,203.3" class="chartlet-flow-edge"><title>Customer → Customer portal: pays</title></polyline><polyline points="221.411,206.8 229.411,203.3 221.411,199.8 221.411,206.8" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-1 chartlet-f-2"><polyline points="361.961,203.3 503.97,203.3" class="chartlet-flow-edge"><title>Customer portal → API gateway: calls [HTTPS]</title></polyline><polyline points="503.97,206.8 511.97,203.3 503.97,199.8 503.97,206.8" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-2 chartlet-f-3 chartlet-flow-role-deprecated"><polyline points="616.83,191.3 764.482,191.3 764.482,159 791.879,159" class="chartlet-flow-edge"><title>API gateway → Monolith: routes today</title></polyline><polyline points="791.879,162.5 799.879,159 791.879,155.5 791.879,162.5" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-2 chartlet-f-4 chartlet-flow-role-planned"><polyline points="616.83,215.3 764.482,215.3 764.482,246.8 786.574,246.8" class="chartlet-flow-edge"><title>API gateway → Billing service: routes after</title></polyline><polyline points="786.574,250.3 794.574,246.8 786.574,243.3 786.574,250.3" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-6 chartlet-flow-role-deprecated"><polyline points="903.879,159 1027.346,159 1027.346,147 1067.996,147" class="chartlet-flow-edge"><title>Monolith → Accounts: [SQL]</title></polyline><polyline points="1067.996,150.5 1075.996,147 1067.996,143.5 1067.996,150.5" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-4 chartlet-f-6 chartlet-flow-role-planned"><polyline points="909.184,226.4 1027.346,226.4 1027.346,171 1067.996,171" class="chartlet-flow-edge"><title>Billing service → Accounts: [SQL]</title></polyline><polyline points="1067.996,174.5 1075.996,171 1067.996,167.5 1067.996,174.5" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-4 chartlet-f-5 chartlet-flow-role-planned"><polyline points="909.184,246.8 1039.884,246.8 1039.884,235 1061.976,235" class="chartlet-flow-edge"><title>Billing service → Invoice events: publishes</title></polyline><polyline points="1061.976,238.5 1069.976,235 1061.976,231.5 1061.976,238.5" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-4 chartlet-f-7 chartlet-flow-role-critical"><polyline points="909.184,267.2 1027.346,267.2 1027.346,297 1228.17,297" class="chartlet-flow-edge"><title>Billing service → Payment provider: charges [HTTPS]</title></polyline><polyline points="1228.17,300.5 1236.17,297 1228.17,293.5 1228.17,300.5" 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 chartlet-f-4"></g><g class="chartlet-f chartlet-n-3 chartlet-f-2 chartlet-f-3 chartlet-f-6"></g><g class="chartlet-f chartlet-n-4 chartlet-f-2 chartlet-f-4 chartlet-f-5 chartlet-f-6 chartlet-f-7"></g><g class="chartlet-f chartlet-n-5 chartlet-f-4 chartlet-f-5"></g><g class="chartlet-f chartlet-n-6 chartlet-f-3 chartlet-f-4 chartlet-f-6"></g><g class="chartlet-f chartlet-n-7 chartlet-f-4 chartlet-f-7"></g><g class="chartlet-f chartlet-f-0 chartlet-f-1"><rect x="132" y="178.3" width="36.88" height="21" class="chartlet-diagram-chip"/><text x="137" y="192.3" text-anchor="start" class="chartlet-diagram-chip-text">pays</text></g><g class="chartlet-f chartlet-f-1 chartlet-f-2"><rect x="365.961" y="163.3" width="63.64" height="36" class="chartlet-diagram-chip"/><text x="370.961" y="177.3" text-anchor="start" class="chartlet-diagram-chip-text">calls</text><text x="370.961" y="192.3" text-anchor="start" class="chartlet-diagram-chip-text">[HTTPS]</text></g><g class="chartlet-f chartlet-f-2 chartlet-f-3"><rect x="620.83" y="166.3" width="87.76" height="21" class="chartlet-diagram-chip"/><text x="625.83" y="180.3" text-anchor="start" class="chartlet-diagram-chip-text">routes today</text></g><g class="chartlet-f chartlet-f-2 chartlet-f-4"><rect x="620.83" y="219.3" width="87.76" height="21" class="chartlet-diagram-chip"/><text x="625.83" y="233.3" text-anchor="start" class="chartlet-diagram-chip-text">routes after</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-6"><rect x="907.879" y="134" width="47.56" height="21" class="chartlet-diagram-chip"/><text x="912.879" y="148" text-anchor="start" class="chartlet-diagram-chip-text">[SQL]</text></g><g class="chartlet-f chartlet-f-4 chartlet-f-6"><rect x="913.184" y="201.4" width="47.56" height="21" class="chartlet-diagram-chip"/><text x="918.184" y="215.4" text-anchor="start" class="chartlet-diagram-chip-text">[SQL]</text></g><g class="chartlet-f chartlet-f-4 chartlet-f-5"><rect x="963.744" y="201.4" width="64.24" height="21" class="chartlet-diagram-chip"/><text x="968.744" y="215.4" text-anchor="start" class="chartlet-diagram-chip-text">publishes</text></g><g class="chartlet-f chartlet-f-4 chartlet-f-7"><rect x="913.184" y="271.2" width="63.64" height="36" class="chartlet-diagram-chip"/><text x="918.184" y="285.2" text-anchor="start" class="chartlet-diagram-chip-text">charges</text><text x="918.184" y="300.2" text-anchor="start" class="chartlet-diagram-chip-text">[HTTPS]</text></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1"><rect x="24" y="178.8" width="104" height="54" class="chartlet-diagram-shadow"/><rect x="24" y="176.3" width="104" height="54" class="chartlet-flow-node chartlet-role-violet"><title>Customer</title></rect><circle cx="76" cy="187.3" r="6" class="chartlet-arch-head"/><text x="76" y="215.8" text-anchor="middle" class="chartlet-flow-label">Customer</text></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-2"><rect x="229.411" y="181.8" width="132.55" height="48" class="chartlet-diagram-shadow"/><rect x="229.411" y="179.3" width="132.55" height="48" class="chartlet-flow-node chartlet-role-blue"><title>Customer portal</title></rect><line x1="229.411" y1="191.3" x2="361.961" y2="191.3" class="chartlet-flow-inner"/><circle cx="237.411" cy="185.3" r="1.8" class="chartlet-arch-dot"/><circle cx="243.411" cy="185.3" r="1.8" class="chartlet-arch-dot"/><circle cx="249.411" cy="185.3" r="1.8" class="chartlet-arch-dot"/><text x="295.686" y="213.8" text-anchor="middle" class="chartlet-flow-label">Customer portal</text></g><g class="chartlet-f chartlet-n-2 chartlet-f-1 chartlet-f-2 chartlet-f-3 chartlet-f-4 chartlet-flow-role-critical"><polyline points="511.97,178.8 616.83,178.8 616.83,211.2 564.4,232.8 511.97,211.2 511.97,178.8" class="chartlet-diagram-shadow"/><polyline points="511.97,176.3 616.83,176.3 616.83,208.7 564.4,230.3 511.97,208.7 511.97,176.3" class="chartlet-flow-node chartlet-role-red"><title>API gateway</title></polyline><text x="564.4" y="201.8" text-anchor="middle" class="chartlet-flow-label">API gateway</text><circle cx="511.97" cy="176.3" r="8" class="chartlet-diagram-badge"/><text x="511.97" y="179.8" text-anchor="middle" class="chartlet-diagram-badge-text">!</text></g><g class="chartlet-f chartlet-n-3 chartlet-f-2 chartlet-f-3 chartlet-f-6 chartlet-flow-role-deprecated"><rect x="799.879" y="136.5" width="104" height="50" class="chartlet-diagram-shadow"/><rect x="799.879" y="134" width="104" height="50" class="chartlet-flow-node chartlet-role-blue"><title>Monolith – billing module</title></rect><text x="851.879" y="156.5" text-anchor="middle" class="chartlet-flow-label">Monolith</text><text x="851.879" y="170.5" text-anchor="middle" class="chartlet-flow-sublabel">billing module</text><circle cx="799.879" cy="134" r="8" class="chartlet-diagram-badge"/><text x="799.879" y="137.5" text-anchor="middle" class="chartlet-diagram-badge-text">−</text></g><g class="chartlet-f chartlet-n-4 chartlet-f-2 chartlet-f-4 chartlet-f-5 chartlet-f-6 chartlet-f-7 chartlet-flow-role-planned"><rect x="794.574" y="215.3" width="114.61" height="68" class="chartlet-diagram-shadow"/><rect x="794.574" y="212.8" width="114.61" height="68" class="chartlet-flow-node chartlet-role-blue"><title>Billing service</title></rect><text x="851.879" y="251.3" text-anchor="middle" class="chartlet-flow-label">Billing service</text><circle cx="794.574" cy="212.8" r="8" class="chartlet-diagram-badge"/><text x="794.574" y="216.3" text-anchor="middle" class="chartlet-diagram-badge-text">+</text></g><g class="chartlet-f chartlet-n-5 chartlet-f-4 chartlet-f-5 chartlet-flow-role-planned"><rect x="1073.976" y="215.5" width="116.04" height="36" class="chartlet-diagram-shadow"/><rect x="1073.976" y="213" width="116.04" height="36" class="chartlet-flow-node chartlet-role-violet"/><rect x="1069.976" y="219.5" width="116.04" height="36" class="chartlet-diagram-shadow"/><rect x="1069.976" y="217" width="116.04" height="36" class="chartlet-flow-node chartlet-role-violet"><title>Invoice events</title></rect><text x="1127.996" y="239.5" text-anchor="middle" class="chartlet-flow-label">Invoice events</text><circle cx="1069.976" cy="217" r="8" class="chartlet-diagram-badge"/><text x="1069.976" y="220.5" text-anchor="middle" class="chartlet-diagram-badge-text">+</text></g><g class="chartlet-f chartlet-n-6 chartlet-f-3 chartlet-f-4 chartlet-f-6 chartlet-flow-role-critical"><polyline points="1075.996,136.5 1075.996,186.5 1077.768,187.794 1082.963,189 1091.227,190.036 1101.996,190.83 1114.538,191.33 1127.996,191.5 1141.455,191.33 1153.996,190.83 1164.766,190.036 1173.03,189 1178.225,187.794 1179.996,186.5 1179.996,136.5 1178.225,135.206 1173.03,134 1164.766,132.964 1153.996,132.17 1141.455,131.67 1127.996,131.5 1114.538,131.67 1101.996,132.17 1091.227,132.964 1082.963,134 1077.768,135.206 1075.996,136.5 1075.996,136.5" class="chartlet-diagram-shadow"/><polyline points="1075.996,134 1075.996,184 1077.768,185.294 1082.963,186.5 1091.227,187.536 1101.996,188.33 1114.538,188.83 1127.996,189 1141.455,188.83 1153.996,188.33 1164.766,187.536 1173.03,186.5 1178.225,185.294 1179.996,184 1179.996,134 1178.225,132.706 1173.03,131.5 1164.766,130.464 1153.996,129.67 1141.455,129.17 1127.996,129 1114.538,129.17 1101.996,129.67 1091.227,130.464 1082.963,131.5 1077.768,132.706 1075.996,134 1075.996,134" class="chartlet-flow-node chartlet-role-teal"><title>Accounts – Postgres</title></polyline><polyline points="1075.996,134 1077.768,135.294 1082.963,136.5 1091.227,137.536 1101.996,138.33 1114.538,138.83 1127.996,139 1141.455,138.83 1153.996,138.33 1164.766,137.536 1173.03,136.5 1178.225,135.294 1179.996,134" class="chartlet-diagram-rim"/><text x="1127.996" y="159.5" text-anchor="middle" class="chartlet-flow-label">Accounts</text><text x="1127.996" y="173.5" text-anchor="middle" class="chartlet-flow-sublabel">Postgres</text><circle cx="1075.996" cy="129" r="8" class="chartlet-diagram-badge"/><text x="1075.996" y="132.5" text-anchor="middle" class="chartlet-diagram-badge-text">!</text></g><g class="chartlet-f chartlet-n-7 chartlet-f-4 chartlet-f-7"><rect x="1236.17" y="281.5" width="139.83" height="36" class="chartlet-diagram-shadow"/><rect x="1236.17" y="279" width="139.83" height="36" class="chartlet-flow-node chartlet-flow-external chartlet-role-gray"><title>Payment provider</title></rect><text x="1306.085" y="301.5" text-anchor="middle" class="chartlet-flow-label">Payment provider</text></g><g class="chartlet-flow-role-critical"><circle cx="32" cy="434" r="8" class="chartlet-diagram-badge"/><text x="32" y="437.5" text-anchor="middle" class="chartlet-diagram-badge-text">!</text><line x1="46" y1="434" x2="68" y2="434" class="chartlet-flow-edge"/></g><text x="74" y="438" text-anchor="start" class="chartlet-legend">Critical</text><g class="chartlet-flow-role-planned"><circle cx="147.72" cy="434" r="8" class="chartlet-diagram-badge"/><text x="147.72" y="437.5" text-anchor="middle" class="chartlet-diagram-badge-text">+</text><line x1="161.72" y1="434" x2="183.72" y2="434" class="chartlet-flow-edge"/></g><text x="189.72" y="438" text-anchor="start" class="chartlet-legend">Planned</text><g class="chartlet-flow-role-deprecated"><circle cx="262.96" cy="434" r="8" class="chartlet-diagram-badge"/><text x="262.96" y="437.5" text-anchor="middle" class="chartlet-diagram-badge-text">−</text><line x1="276.96" y1="434" x2="298.96" y2="434" class="chartlet-flow-edge"/></g><text x="304.96" y="438" text-anchor="start" class="chartlet-legend">Deprecated</text></svg><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-0" for="chartlet-79335aff9fa623ac-focus-0"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-1" for="chartlet-79335aff9fa623ac-focus-1"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-2" for="chartlet-79335aff9fa623ac-focus-2"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-3" for="chartlet-79335aff9fa623ac-focus-3"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-4" for="chartlet-79335aff9fa623ac-focus-4"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-5" for="chartlet-79335aff9fa623ac-focus-5"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-6" for="chartlet-79335aff9fa623ac-focus-6"></label><label class="chartlet-hotspot" id="chartlet-79335aff9fa623ac-hs-7" for="chartlet-79335aff9fa623ac-focus-7"></label></div><p class="chartlet-source">Source: Architecture review, migration plan</p><details class="chartlet-data" data-viz-text><summary>Show chart data</summary><table><caption>Data for Billing moves from the monolith to its own service</caption><thead><tr><th scope="col">Component</th><th scope="col">Kind</th><th scope="col">Boundary</th><th scope="col">Role</th><th scope="col">Connects to</th></tr></thead><tbody><tr><th scope="row">Customer</th><td>person</td><td></td><td></td><td>Customer portal (pays)</td></tr><tr><th scope="row">Customer portal</th><td>frontend</td><td></td><td></td><td>API gateway (calls, via HTTPS)</td></tr><tr><th scope="row">API gateway</th><td>security</td><td>Platform</td><td>critical</td><td>Monolith (routes today, deprecated), Billing service (routes after, planned)</td></tr><tr><th scope="row">Monolith</th><td>service</td><td>Platform</td><td>deprecated</td><td>Accounts (via SQL, deprecated)</td></tr><tr><th scope="row">Billing service</th><td>service</td><td>Platform</td><td>planned</td><td>Accounts (via SQL, planned), Invoice events (publishes, planned), Payment provider (charges, via HTTPS, critical)</td></tr><tr><th scope="row">Accounts</th><td>database</td><td>Platform</td><td>critical</td><td></td></tr><tr><th scope="row">Invoice events</th><td>queue</td><td>Platform</td><td>planned</td><td></td></tr><tr><th scope="row">Payment provider</th><td>external system</td><td></td><td></td><td></td></tr></tbody></table></details></figure></div>