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-b63b8eaf45596a97 .chartlet-f{opacity:.18}#chartlet-b63b8eaf45596a97-hs-0{left:26.14%;top:6.8%;width:21.785%;height:5%}#chartlet-b63b8eaf45596a97-hs-1{left:11.747%;top:27.378%;width:19.785%;height:5%}#chartlet-b63b8eaf45596a97-hs-2{left:42.532%;top:27.378%;width:19.785%;height:5%}#chartlet-b63b8eaf45596a97-hs-3{left:27.151%;top:68.396%;width:19.763%;height:5%}#chartlet-b63b8eaf45596a97-hs-4{left:66.817%;top:48.513%;width:21.086%;height:5%}#chartlet-b63b8eaf45596a97-hs-5{left:23.359%;top:91.2%;width:18.746%;height:6%}#chartlet-b63b8eaf45596a97-hs-6{left:45.606%;top:91.5%;width:25.849%;height:5.4%}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-0:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-0{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-0:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-0 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-0:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-0 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-1:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-1{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-1:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-1 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-1:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-1 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-2:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-2{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-2:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-2 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-2:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-2 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-3:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-3{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-3:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-3 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-3:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-3 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-4:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-4{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-4:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-4 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-4:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-4 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-5:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-5{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-5:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-5 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-5:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-5 .chartlet-seq-box{stroke-width:3}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-6:checked) #chartlet-b63b8eaf45596a97 .chartlet-f-6{opacity:1}.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-6:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-6 .chartlet-flow-node,.chartlet-wrapper:has(#chartlet-b63b8eaf45596a97-focus-6:checked) #chartlet-b63b8eaf45596a97 .chartlet-n-6 .chartlet-seq-box{stroke-width:3}</style><details class="chartlet-focus"><summary>Focus</summary><fieldset><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" checked> Show all</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-0"> Ingress (ingress-prod)</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-1"> Booking API (api-1)</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-2"> Booking API (api-2)</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-3"> Worker (worker-1)</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-4"> Job queue (jobs-prod)</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-5"> Bookings (db-prod)</label><label><input type="radio" name="chartlet-b63b8eaf45596a97-focus" class="chartlet-focus-node" id="chartlet-b63b8eaf45596a97-focus-6"> Certificates (files-prod)</label></fieldset></details><figure class="chartlet-figure" data-viz="chart"><figcaption>Course booking in production</figcaption><div class="chartlet-stage"><svg xmlns="http://www.w3.org/2000/svg" width="800" height="1000" viewBox="0 0 800 1000" id="chartlet-b63b8eaf45596a97" role="img" aria-labelledby="chartlet-b63b8eaf45596a97-title chartlet-b63b8eaf45596a97-description" class="chartlet-root"><title id="chartlet-b63b8eaf45596a97-title">Course booking in production</title><desc id="chartlet-b63b8eaf45596a97-description">Architecture diagram with 7 components and 9 connections in 5 boundaries. It shows the environment Production: 7 instances of 6 components of the model; only the connections listed for the instances are drawn. Cloud region: Job queue (jobs-prod), Bookings (db-prod), Certificates (files-prod), Container cluster. Container cluster (in Cloud region): Ingress (ingress-prod), Node A, Node B, Node pool: workers. Node A (in Container cluster): Booking API (api-1). Node B (in Container cluster): Booking API (api-2). Node pool: workers (in Container cluster): Worker (worker-1). Nothing leads into Ingress (ingress-prod). Nothing leads out of Bookings (db-prod) and Certificates (files-prod). Ingress (ingress-prod) (service): connects to Booking API (api-1) (routes, via HTTP) and Booking API (api-2) (routes, via HTTP). Booking API (api-1) (artifact): connects to Bookings (db-prod) (reads, writes, via SQL/TLS) and Job queue (jobs-prod) (queues jobs). Booking API (api-2) (artifact): connects to Bookings (db-prod) (reads, writes, via SQL/TLS) and Job queue (jobs-prod) (queues jobs). Job queue (jobs-prod) (queue): connects to Worker (worker-1) (delivers). Worker (worker-1) (artifact): connects to Certificates (files-prod) (stores certificates) and Bookings (db-prod) (updates, via SQL/TLS). Bookings (db-prod) (database): no outgoing connection. Certificates (files-prod) (storage): 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-b63b8eaf45596a97 .chartlet-title{font-size:22px;font-weight:650;fill:var(--chartlet-text)}#chartlet-b63b8eaf45596a97 .chartlet-label,#chartlet-b63b8eaf45596a97 .chartlet-tick,#chartlet-b63b8eaf45596a97 .chartlet-value,#chartlet-b63b8eaf45596a97 .chartlet-value-inverse,#chartlet-b63b8eaf45596a97 .chartlet-axis-title{font-size:12px;fill:var(--chartlet-muted)}#chartlet-b63b8eaf45596a97 .chartlet-value,#chartlet-b63b8eaf45596a97 .chartlet-value-inverse{font-weight:600}#chartlet-b63b8eaf45596a97 .chartlet-value{fill:var(--chartlet-text)}#chartlet-b63b8eaf45596a97 .chartlet-value-inverse{fill:var(--chartlet-background)}#chartlet-b63b8eaf45596a97 .chartlet-axis-title{font-weight:600}#chartlet-b63b8eaf45596a97 .chartlet-grid{stroke:var(--chartlet-grid);stroke-width:1}#chartlet-b63b8eaf45596a97 .chartlet-zero{stroke:var(--chartlet-zero);stroke-width:1.5}#chartlet-b63b8eaf45596a97 .chartlet-bar,#chartlet-b63b8eaf45596a97 .chartlet-point{fill:var(--chartlet-accent)}#chartlet-b63b8eaf45596a97 .chartlet-line{fill:none;stroke:var(--chartlet-accent);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}#chartlet-b63b8eaf45596a97 .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-b63b8eaf45596a97 .chartlet-role-blue{fill:var(--chartlet-role-blue-fill);stroke:var(--chartlet-role-blue)}#chartlet-b63b8eaf45596a97 .chartlet-role-green{fill:var(--chartlet-role-green-fill);stroke:var(--chartlet-role-green)}#chartlet-b63b8eaf45596a97 .chartlet-role-amber{fill:var(--chartlet-role-amber-fill);stroke:var(--chartlet-role-amber)}#chartlet-b63b8eaf45596a97 .chartlet-role-teal{fill:var(--chartlet-role-teal-fill);stroke:var(--chartlet-role-teal)}#chartlet-b63b8eaf45596a97 .chartlet-role-violet{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet)}#chartlet-b63b8eaf45596a97 .chartlet-role-gray{fill:var(--chartlet-role-gray-fill);stroke:var(--chartlet-role-gray)}#chartlet-b63b8eaf45596a97 .chartlet-role-red{fill:var(--chartlet-role-red-fill);stroke:var(--chartlet-role-red)}#chartlet-b63b8eaf45596a97 .chartlet-diagram-rim{fill:none;stroke:var(--chartlet-role-teal);stroke-width:1.5}#chartlet-b63b8eaf45596a97 .chartlet-diagram-shadow{fill:var(--chartlet-shadow);stroke:none;rx:7px}#chartlet-b63b8eaf45596a97 .chartlet-diagram-chip{fill:var(--chartlet-background);stroke:var(--chartlet-grid);stroke-width:1;rx:4px}#chartlet-b63b8eaf45596a97 .chartlet-diagram-chip-text{font-size:12px;fill:var(--chartlet-text)}#chartlet-b63b8eaf45596a97 .chartlet-diagram-badge{fill:var(--chartlet-accent);stroke:var(--chartlet-background);stroke-width:2}#chartlet-b63b8eaf45596a97 .chartlet-diagram-badge-text{font-size:10px;font-weight:700;fill:var(--chartlet-background)}#chartlet-b63b8eaf45596a97 .chartlet-flow-node{stroke-width:1.5;stroke-linejoin:round;rx:7px}#chartlet-b63b8eaf45596a97 .chartlet-flow-start{stroke-width:2}#chartlet-b63b8eaf45596a97 .chartlet-flow-end{stroke-width:3}#chartlet-b63b8eaf45596a97 .chartlet-flow-external{stroke-dasharray:5 3}#chartlet-b63b8eaf45596a97 .chartlet-flow-inner{stroke:var(--chartlet-role-blue);stroke-width:1}#chartlet-b63b8eaf45596a97 .chartlet-flow-label{font-size:13px;font-weight:600;fill:var(--chartlet-text)}#chartlet-b63b8eaf45596a97 .chartlet-flow-sublabel{font-size:11px;fill:var(--chartlet-muted)}#chartlet-b63b8eaf45596a97 .chartlet-flow-edge{fill:none;stroke:var(--chartlet-zero);stroke-width:1.4;stroke-linejoin:round}#chartlet-b63b8eaf45596a97 .chartlet-flow-dashed{stroke-dasharray:5 4}#chartlet-b63b8eaf45596a97 .chartlet-flow-dotted{stroke-dasharray:1 4;stroke-linecap:round}#chartlet-b63b8eaf45596a97 .chartlet-flow-main{stroke:var(--chartlet-accent);stroke-width:2.2}#chartlet-b63b8eaf45596a97 .chartlet-flow-head{fill:var(--chartlet-zero);stroke:var(--chartlet-zero);stroke-width:1;stroke-linejoin:round}#chartlet-b63b8eaf45596a97 .chartlet-flow-main-head{fill:var(--chartlet-accent);stroke:var(--chartlet-accent)}#chartlet-b63b8eaf45596a97 .chartlet-flow-lane{fill:var(--chartlet-lane);stroke:var(--chartlet-grid);stroke-width:1}#chartlet-b63b8eaf45596a97 .chartlet-flow-lane-alt{fill:var(--chartlet-background)}#chartlet-b63b8eaf45596a97 .chartlet-flow-lane-head{fill:var(--chartlet-lane-head);stroke:none}#chartlet-b63b8eaf45596a97 .chartlet-flow-lane-label{font-size:11px;font-weight:650;fill:var(--chartlet-muted);letter-spacing:.04em}#chartlet-b63b8eaf45596a97 .chartlet-flow-group{fill:var(--chartlet-accent);fill-opacity:.04;stroke:var(--chartlet-zero);stroke-width:1;stroke-dasharray:4 3;rx:10px}#chartlet-b63b8eaf45596a97 .chartlet-flow-group-label{font-size:11px;font-weight:600;fill:var(--chartlet-muted)}#chartlet-b63b8eaf45596a97 .chartlet-arch-head{fill:var(--chartlet-role-violet-fill);stroke:var(--chartlet-role-violet);stroke-width:1.5}#chartlet-b63b8eaf45596a97 .chartlet-arch-dot{fill:var(--chartlet-role-blue);stroke:none}</style><rect x="57.977" y="12" width="657.25" height="972" class="chartlet-flow-group"/><text x="65.977" y="25" text-anchor="start" class="chartlet-flow-group-label">Cloud region</text><rect x="69.977" y="40" width="452.56" height="717.961" class="chartlet-flow-group"/><text x="77.977" y="53" text-anchor="start" class="chartlet-flow-group-label">Container cluster</text><rect x="205.207" y="655.961" width="182.1" height="90" class="chartlet-flow-group"/><text x="213.207" y="668.961" text-anchor="start" class="chartlet-flow-group-label">Node pool: workers</text><rect x="328.257" y="245.784" width="182.28" height="90" class="chartlet-flow-group"/><text x="336.257" y="258.784" text-anchor="start" class="chartlet-flow-group-label">Node B</text><rect x="81.977" y="245.784" width="182.28" height="90" class="chartlet-flow-group"/><text x="89.977" y="258.784" text-anchor="start" class="chartlet-flow-group-label">Node A</text><g class="chartlet-f chartlet-f-0 chartlet-f-1"><polyline points="284.258,118 284.258,201.456 173.118,201.456 173.118,265.784" class="chartlet-flow-edge"><title>Ingress (ingress-prod) → Booking API (api-1): routes [HTTP]</title></polyline><polyline points="169.618,265.784 173.118,273.784 176.618,265.784 169.618,265.784" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-0 chartlet-f-2"><polyline points="308.258,118 308.258,201.456 419.398,201.456 419.398,265.784" class="chartlet-flow-edge"><title>Ingress (ingress-prod) → Booking API (api-2): routes [HTTP]</title></polyline><polyline points="415.898,265.784 419.398,273.784 422.898,265.784 415.898,265.784" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-1 chartlet-f-5"><polyline points="161.118,323.784 161.118,423.931 173.118,423.931 173.118,597.724 143.207,597.724 143.207,850.799 237.861,850.799 237.861,904" class="chartlet-flow-edge"><title>Booking API (api-1) → Bookings (db-prod): reads, writes [SQL/TLS]</title></polyline><polyline points="234.361,904 237.861,912 241.361,904 234.361,904" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-2 chartlet-f-5"><polyline points="431.398,323.784 431.398,423.931 742.023,423.931 742.023,611.633 449.308,611.633 449.308,864.708 285.861,864.708 285.861,904" class="chartlet-flow-edge"><title>Booking API (api-2) → Bookings (db-prod): reads, writes [SQL/TLS]</title></polyline><polyline points="282.361,904 285.861,912 289.361,904 282.361,904" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-1 chartlet-f-4"><polyline points="185.118,323.784 185.118,451.749 606.883,451.749 606.883,477.132" class="chartlet-flow-edge"><title>Booking API (api-1) → Job queue (jobs-prod): queues jobs</title></polyline><polyline points="603.383,477.132 606.883,485.132 610.383,477.132 603.383,477.132" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-2 chartlet-f-4"><polyline points="407.398,323.784 407.398,437.84 630.883,437.84 630.883,477.132" class="chartlet-flow-edge"><title>Booking API (api-2) → Job queue (jobs-prod): queues jobs</title></polyline><polyline points="627.383,477.132 630.883,485.132 634.383,477.132 627.383,477.132" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-4"><polyline points="618.883,535.132 618.883,597.724 296.257,597.724 296.257,675.961" class="chartlet-flow-edge"><title>Job queue (jobs-prod) → Worker (worker-1): delivers</title></polyline><polyline points="292.757,675.961 296.257,683.961 299.757,675.961 292.757,675.961" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-6"><polyline points="308.257,733.961 308.257,878.618 468.241,878.618 468.241,907" class="chartlet-flow-edge"><title>Worker (worker-1) → Certificates (files-prod): stores certificates</title></polyline><polyline points="464.741,907 468.241,915 471.741,907 464.741,907" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-f-3 chartlet-f-5"><polyline points="284.257,733.961 284.257,850.799 261.861,850.799 261.861,904" class="chartlet-flow-edge"><title>Worker (worker-1) → Bookings (db-prod): updates [SQL/TLS]</title></polyline><polyline points="258.361,904 261.861,912 265.361,904 258.361,904" class="chartlet-flow-head"/></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1 chartlet-f-2"></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-4 chartlet-f-5"></g><g class="chartlet-f chartlet-n-2 chartlet-f-0 chartlet-f-2 chartlet-f-4 chartlet-f-5"></g><g class="chartlet-f chartlet-n-3 chartlet-f-3 chartlet-f-4 chartlet-f-5 chartlet-f-6"></g><g class="chartlet-f chartlet-n-4 chartlet-f-1 chartlet-f-2 chartlet-f-3 chartlet-f-4"></g><g class="chartlet-f chartlet-n-5 chartlet-f-1 chartlet-f-2 chartlet-f-3 chartlet-f-5"></g><g class="chartlet-f chartlet-n-6 chartlet-f-3 chartlet-f-6"></g><g class="chartlet-f chartlet-f-0 chartlet-f-1"><rect x="224.658" y="123" width="55.6" height="36" class="chartlet-diagram-chip"/><text x="275.258" y="137" text-anchor="end" class="chartlet-diagram-chip-text">routes</text><text x="275.258" y="152" text-anchor="end" class="chartlet-diagram-chip-text">[HTTP]</text></g><g class="chartlet-f chartlet-f-0 chartlet-f-2"><rect x="312.258" y="123" width="55.6" height="36" class="chartlet-diagram-chip"/><text x="317.258" y="137" text-anchor="start" class="chartlet-diagram-chip-text">routes</text><text x="317.258" y="152" text-anchor="start" class="chartlet-diagram-chip-text">[HTTP]</text></g><g class="chartlet-f chartlet-f-1 chartlet-f-5"><rect x="64.797" y="338.784" width="92.32" height="36" class="chartlet-diagram-chip"/><text x="152.118" y="352.784" text-anchor="end" class="chartlet-diagram-chip-text">reads, writes</text><text x="152.118" y="367.784" text-anchor="end" class="chartlet-diagram-chip-text">[SQL/TLS]</text></g><g class="chartlet-f chartlet-f-2 chartlet-f-5"><rect x="435.398" y="338.784" width="92.32" height="36" class="chartlet-diagram-chip"/><text x="440.398" y="352.784" text-anchor="start" class="chartlet-diagram-chip-text">reads, writes</text><text x="440.398" y="367.784" text-anchor="start" class="chartlet-diagram-chip-text">[SQL/TLS]</text></g><g class="chartlet-f chartlet-f-1 chartlet-f-4"><rect x="189.118" y="338.784" width="77.92" height="21" class="chartlet-diagram-chip"/><text x="194.118" y="352.784" text-anchor="start" class="chartlet-diagram-chip-text">queues jobs</text></g><g class="chartlet-f chartlet-f-2 chartlet-f-4"><rect x="325.478" y="338.784" width="77.92" height="21" class="chartlet-diagram-chip"/><text x="398.398" y="352.784" text-anchor="end" class="chartlet-diagram-chip-text">queues jobs</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-4"><rect x="622.883" y="540.132" width="57.52" height="21" class="chartlet-diagram-chip"/><text x="627.883" y="554.132" text-anchor="start" class="chartlet-diagram-chip-text">delivers</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-6"><rect x="312.257" y="760.961" width="128.56" height="21" class="chartlet-diagram-chip"/><text x="317.257" y="774.961" text-anchor="start" class="chartlet-diagram-chip-text">stores certificates</text></g><g class="chartlet-f chartlet-f-3 chartlet-f-5"><rect x="201.858" y="760.961" width="78.4" height="36" class="chartlet-diagram-chip"/><text x="275.257" y="774.961" text-anchor="end" class="chartlet-diagram-chip-text">updates</text><text x="275.257" y="789.961" text-anchor="end" class="chartlet-diagram-chip-text">[SQL/TLS]</text></g><g class="chartlet-f chartlet-n-0 chartlet-f-0 chartlet-f-1 chartlet-f-2"><rect x="209.118" y="70.5" width="174.28" height="50" class="chartlet-diagram-shadow"/><rect x="209.118" y="68" width="174.28" height="50" class="chartlet-flow-node chartlet-role-blue"><title>Ingress (ingress-prod) – load balancer</title></rect><text x="296.258" y="90.5" text-anchor="middle" class="chartlet-flow-label">Ingress (ingress-prod)</text><text x="296.258" y="104.5" text-anchor="middle" class="chartlet-flow-sublabel">load balancer</text></g><g class="chartlet-f chartlet-n-1 chartlet-f-0 chartlet-f-1 chartlet-f-4 chartlet-f-5"><polyline points="93.977,276.284 240.258,276.284 252.258,288.284 252.258,326.284 93.977,326.284 93.977,276.284" class="chartlet-diagram-shadow"/><polyline points="93.977,273.784 240.258,273.784 252.258,285.784 252.258,323.784 93.977,323.784 93.977,273.784" class="chartlet-flow-node chartlet-role-blue"><title>Booking API (api-1) – image: web app and API</title></polyline><line x1="240.258" y1="273.784" x2="240.258" y2="285.784" class="chartlet-flow-inner"/><line x1="240.258" y1="285.784" x2="252.258" y2="285.784" class="chartlet-flow-inner"/><text x="173.118" y="296.284" text-anchor="middle" class="chartlet-flow-label">Booking API (api-1)</text><text x="173.118" y="310.284" text-anchor="middle" class="chartlet-flow-sublabel">image: web app and API</text></g><g class="chartlet-f chartlet-n-2 chartlet-f-0 chartlet-f-2 chartlet-f-4 chartlet-f-5"><polyline points="340.257,276.284 486.538,276.284 498.538,288.284 498.538,326.284 340.257,326.284 340.257,276.284" class="chartlet-diagram-shadow"/><polyline points="340.257,273.784 486.538,273.784 498.538,285.784 498.538,323.784 340.257,323.784 340.257,273.784" class="chartlet-flow-node chartlet-role-blue"><title>Booking API (api-2) – image: web app and API</title></polyline><line x1="486.538" y1="273.784" x2="486.538" y2="285.784" class="chartlet-flow-inner"/><line x1="486.538" y1="285.784" x2="498.538" y2="285.784" class="chartlet-flow-inner"/><text x="419.398" y="296.284" text-anchor="middle" class="chartlet-flow-label">Booking API (api-2)</text><text x="419.398" y="310.284" text-anchor="middle" class="chartlet-flow-sublabel">image: web app and API</text></g><g class="chartlet-f chartlet-n-3 chartlet-f-3 chartlet-f-4 chartlet-f-5 chartlet-f-6"><polyline points="217.207,686.461 363.308,686.461 375.308,698.461 375.308,736.461 217.207,736.461 217.207,686.461" class="chartlet-diagram-shadow"/><polyline points="217.207,683.961 363.308,683.961 375.308,695.961 375.308,733.961 217.207,733.961 217.207,683.961" class="chartlet-flow-node chartlet-role-blue"><title>Worker (worker-1) – image: background jobs</title></polyline><line x1="363.308" y1="683.961" x2="363.308" y2="695.961" class="chartlet-flow-inner"/><line x1="363.308" y1="695.961" x2="375.308" y2="695.961" class="chartlet-flow-inner"/><text x="296.257" y="706.461" text-anchor="middle" class="chartlet-flow-label">Worker (worker-1)</text><text x="296.257" y="720.461" text-anchor="middle" class="chartlet-flow-sublabel">image: background jobs</text></g><g class="chartlet-f chartlet-n-4 chartlet-f-1 chartlet-f-2 chartlet-f-3 chartlet-f-4"><rect x="538.538" y="483.632" width="168.69" height="50" class="chartlet-diagram-shadow"/><rect x="538.538" y="481.132" width="168.69" height="50" class="chartlet-flow-node chartlet-role-violet"/><rect x="534.538" y="487.632" width="168.69" height="50" class="chartlet-diagram-shadow"/><rect x="534.538" y="485.132" width="168.69" height="50" class="chartlet-flow-node chartlet-role-violet"><title>Job queue (jobs-prod) – managed queue</title></rect><text x="618.883" y="507.632" text-anchor="middle" class="chartlet-flow-label">Job queue (jobs-prod)</text><text x="618.883" y="521.632" text-anchor="middle" class="chartlet-flow-sublabel">managed queue</text></g><g class="chartlet-f chartlet-n-5 chartlet-f-1 chartlet-f-2 chartlet-f-3 chartlet-f-5"><polyline points="186.876,919.5 186.876,969.5 189.431,970.794 196.922,972 208.838,973.036 224.368,973.83 242.453,974.33 261.861,974.5 281.268,974.33 299.353,973.83 314.883,973.036 326.8,972 334.291,970.794 336.846,969.5 336.846,919.5 334.291,918.206 326.8,917 314.883,915.964 299.353,915.17 281.268,914.67 261.861,914.5 242.453,914.67 224.368,915.17 208.838,915.964 196.922,917 189.431,918.206 186.876,919.5 186.876,919.5" class="chartlet-diagram-shadow"/><polyline points="186.876,917 186.876,967 189.431,968.294 196.922,969.5 208.838,970.536 224.368,971.33 242.453,971.83 261.861,972 281.268,971.83 299.353,971.33 314.883,970.536 326.8,969.5 334.291,968.294 336.846,967 336.846,917 334.291,915.706 326.8,914.5 314.883,913.464 299.353,912.67 281.268,912.17 261.861,912 242.453,912.17 224.368,912.67 208.838,913.464 196.922,914.5 189.431,915.706 186.876,917 186.876,917" class="chartlet-flow-node chartlet-role-teal"><title>Bookings (db-prod) – managed database</title></polyline><polyline points="186.876,917 189.431,918.294 196.922,919.5 208.838,920.536 224.368,921.33 242.453,921.83 261.861,922 281.268,921.83 299.353,921.33 314.883,920.536 326.8,919.5 334.291,918.294 336.846,917" class="chartlet-diagram-rim"/><text x="261.861" y="942.5" text-anchor="middle" class="chartlet-flow-label">Bookings (db-prod)</text><text x="261.861" y="956.5" text-anchor="middle" class="chartlet-flow-sublabel">managed database</text></g><g class="chartlet-f chartlet-n-6 chartlet-f-3 chartlet-f-6"><polyline points="364.846,917.5 571.636,917.5 563.636,971.5 372.846,971.5 364.846,917.5" class="chartlet-diagram-shadow"/><polyline points="364.846,915 571.636,915 563.636,969 372.846,969 364.846,915" class="chartlet-flow-node chartlet-role-teal"><title>Certificates (files-prod) – object storage</title></polyline><text x="468.241" y="939.5" text-anchor="middle" class="chartlet-flow-label">Certificates (files-prod)</text><text x="468.241" y="953.5" text-anchor="middle" class="chartlet-flow-sublabel">object storage</text></g></svg><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-0" for="chartlet-b63b8eaf45596a97-focus-0"></label><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-1" for="chartlet-b63b8eaf45596a97-focus-1"></label><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-2" for="chartlet-b63b8eaf45596a97-focus-2"></label><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-3" for="chartlet-b63b8eaf45596a97-focus-3"></label><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-4" for="chartlet-b63b8eaf45596a97-focus-4"></label><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-5" for="chartlet-b63b8eaf45596a97-focus-5"></label><label class="chartlet-hotspot" id="chartlet-b63b8eaf45596a97-hs-6" for="chartlet-b63b8eaf45596a97-focus-6"></label></div><details class="chartlet-data" data-viz-text><summary>Show chart data</summary><table><caption>Data for Course booking in production</caption><thead><tr><th scope="col">Instance</th><th scope="col">Kind</th><th scope="col">Boundary</th><th scope="col">Connects to</th></tr></thead><tbody><tr><th scope="row">Ingress (ingress-prod)</th><td>service</td><td>Cloud region › Container cluster</td><td>Booking API (api-1) (routes, via HTTP), Booking API (api-2) (routes, via HTTP)</td></tr><tr><th scope="row">Booking API (api-1)</th><td>artifact</td><td>Cloud region › Container cluster › Node A</td><td>Bookings (db-prod) (reads, writes, via SQL/TLS), Job queue (jobs-prod) (queues jobs)</td></tr><tr><th scope="row">Booking API (api-2)</th><td>artifact</td><td>Cloud region › Container cluster › Node B</td><td>Bookings (db-prod) (reads, writes, via SQL/TLS), Job queue (jobs-prod) (queues jobs)</td></tr><tr><th scope="row">Job queue (jobs-prod)</th><td>queue</td><td>Cloud region</td><td>Worker (worker-1) (delivers)</td></tr><tr><th scope="row">Worker (worker-1)</th><td>artifact</td><td>Cloud region › Container cluster › Node pool: workers</td><td>Certificates (files-prod) (stores certificates), Bookings (db-prod) (updates, via SQL/TLS)</td></tr><tr><th scope="row">Bookings (db-prod)</th><td>database</td><td>Cloud region</td><td></td></tr><tr><th scope="row">Certificates (files-prod)</th><td>storage</td><td>Cloud region</td><td></td></tr></tbody></table></details></figure></div>