arc42 and ArchiMate layouts in the folder guide; arc42 examples cover all sections; 1.3
references/folders.md gains arc42 (sections as numbered folders and cards, black boxes, quality tree) and ArchiMate (layers, type in tag and sublabel, element mapping). Gotchas: ref in every kind needs extension 0.11.0; tags are not drawn on the box.
This commit is contained in:
1 parent
d9777fb90e
commit
900e0986e6
20 files changed
+554
-89
No files matched your search
@@ -15,7 +15,7 @@ license: MIT
|
||||
compatibility: Requires Node.js 18+, bash and go-task (task). No network access; Archify is bundled under scripts/vendor.
|
||||
metadata:
|
||||
author: root-at-skic
|
||||
version: "1.2"
|
||||
version: "1.3"
|
||||
origin-repository: https://gitea.lego-cloud.eu/vscode-extensions-skills/archify-vscode-ext.git
|
||||
targets: Archify Diagram Viewer (root-at-skic.archify-vscode-ext)
|
||||
---
|
||||
@@ -175,7 +175,8 @@ Diagrams next to `main.archify` are listed first, ungrouped; deeper ones by fold
|
||||
- **Boxes need clear gaps.** Components closer than 8px fail; labels wider than the box fail (`6.5px` per character plus 13). The grid in `references/authoring.md` keeps a standard layout clear.
|
||||
- **Links are relative to the model root**, never to the file, and must end in `.archify` and exist. `..` is refused.
|
||||
- **A second `main.archify` deeper down** is reported, not nested. One model per tree.
|
||||
- **Diagram kinds other than architecture** take `ref` too (workflow and dataflow `nodes`, sequence `participants`, lifecycle `states`), but the registry `type` must fit that kind: lifecycle states use their own type enum, and sequence participants have no `tag`.
|
||||
- **Diagram kinds other than architecture** take `ref` too (workflow and dataflow `nodes`, sequence `participants`, lifecycle `states`), but the registry `type` must fit that kind: lifecycle states use their own type enum, and sequence participants have no `tag`. The extension resolves these since 0.11.0; older versions showed such a diagram with schema errors.
|
||||
- **Tags are not drawn on the box.** Archify shows `tag` only in the focus panel and search. When a type must be visible (an ArchiMate element type, a C4 level), put it in `sublabel` too.
|
||||
- **Decisions are files, ids are words.** One `*.archify-decision` per decision (`decision:` block with id, title, status, date, elements, diagrams, supersedes; prose in context, decision, consequences). Diagrams point at them with `decisions: [<id>]` on the diagram, a node or an edge; the resolver strips the key. An unquoted numeric id (`0001`) is refused because YAML reads it as 1. When an agent changes the shape of a model (a new store, a new queue, a new boundary), it writes a decision and links the elements it touched.
|
||||
- **The graph answers structure questions.** Before guessing from file contents, run `task model:graph` with a query: `uses:<id>` for neighbours, `from:<a> to:<b>` for the route, `decision:<id>` for what a decision touches, `unused` for registry elements no diagram draws. Walks follow the diagrams' connections only; decision and registry nodes follow the elements they link to. The extension's Graph page (the **Model | Graph | Source** switch on `main.archify`) shows the same graph with the same queries.
|
||||
- **The extension checks keys the skill does not.** Since extension 0.9.2 every Archify page has a **Source** view (Diagram | Graph | Source, View | Source on registries and decisions) that checks the YAML against the bundled JSON schemas without a YAML extension: an unknown key in a registry element (`lable:`) or a diagram is an error there. `task model:validate` does not check registry keys yet and passes such a file, so read registry edits back for typos. When a user says "the Source view shows an error", the message names the key and path (`Unknown key "lable" in elements.api.`).
|
||||
@@ -186,5 +187,5 @@ Diagrams next to `main.archify` are listed first, ungrouped; deeper ones by fold
|
||||
|
||||
- Read `references/authoring.md` when writing or repairing a diagram: kinds, fields, grid, labels, boundaries, brands, validator codes and fixes.
|
||||
- Read `references/formats.md` when writing `main.archify`, a registry, a `ref` or a link, or when unsure what the tasks strip before Archify runs.
|
||||
- Read `references/folders.md` when laying out a model folder or explaining how the extension finds the root and groups diagrams.
|
||||
- Read `references/folders.md` when laying out a model folder or explaining how the extension finds the root and groups diagrams; it has the C4, arc42 and ArchiMate layouts.
|
||||
- `examples/` holds nine complete models that validate with 0 problems; copy their shape, or copy one with `model:scaffold --example`. Three C4 (`c4-*`: context, containers, components). Three arc42 (`arc42-*`: the overview is section 3 business context with goals, constraints, quality, risks and glossary as `cards`; `0300-context`, `0500-building-blocks`, `0600-runtime` sequence diagrams, `0700-deployment`; decisions are section 9). Three ArchiMate (`archimate-*`: the overview is a layered view in three region boundaries; `0100-business`, `0200-application`, `0300-technology`; one registry file per layer; each element's ArchiMate type as its `tag` and `sublabel`, since Archify shows tags only in the focus panel).
|
||||
@@ -28,3 +28,12 @@ connections:
|
||||
- { from: tickets, to: psp, label: REST webhook, variant: security }
|
||||
- { from: tickets, to: mail, label: SMTP TLS }
|
||||
- { from: tickets, to: pos, label: REST VPN }
|
||||
cards:
|
||||
- dot: cyan
|
||||
title: 3 Domain interfaces
|
||||
items:
|
||||
- "Moviegoer: in shows, seats, payment start; out seat map, QR tickets"
|
||||
- "Usher: in scanned QR codes; out valid or invalid, seat"
|
||||
- "Payment provider: out checkout session; in paid or failed webhook"
|
||||
- "E-mail service: out ticket e-mails with QR and receipt"
|
||||
- "Box-office POS: in counter sales; out seat availability"
|
||||
@@ -58,7 +58,9 @@ cards:
|
||||
- dot: amber
|
||||
title: 8 Crosscutting concepts
|
||||
items:
|
||||
- "Persistence: PostgreSQL is the truth; Redis only for holds"
|
||||
- "Security: OIDC for staff apps; card data never stored"
|
||||
- "Errors: idempotency keys; failed webhooks are retried"
|
||||
- "Times in UTC; shown in cinema local time"
|
||||
- "Every write carries an idempotency key"
|
||||
- "QR payload signed with an Ed25519 key"
|
||||
- "Structured logs with order id as trace key"
|
||||
@@ -5,7 +5,10 @@ meta:
|
||||
output: production.html
|
||||
components:
|
||||
- ref: customer
|
||||
pos: [40, 160]
|
||||
pos: [40, 260]
|
||||
size: [130, 60]
|
||||
- ref: mobile
|
||||
pos: [40, 60]
|
||||
size: [130, 60]
|
||||
- id: ingress
|
||||
type: security
|
||||
@@ -44,6 +47,9 @@ boundaries:
|
||||
- kind: security-group
|
||||
label: Managed data zone
|
||||
wraps: [seatlock, db]
|
||||
- kind: region
|
||||
label: Customer phones
|
||||
wraps: [mobile]
|
||||
- kind: region
|
||||
label: Cinema site
|
||||
wraps: [pos, scanner]
|
||||
@@ -56,3 +62,13 @@ connections:
|
||||
- { from: ticketing, to: db, label: TLS }
|
||||
- { from: possync, to: pos, label: VPN, variant: security }
|
||||
- { from: scanner, to: ingress, label: HTTPS }
|
||||
- { from: mobile, to: ingress, label: HTTPS }
|
||||
cards:
|
||||
- dot: slate
|
||||
title: 7 Mapping
|
||||
items:
|
||||
- "Web Shop, Booking API, Ticket Service, POS Sync -> EU k8s cluster"
|
||||
- "Seat Locks -> managed Redis; Tickets DB -> managed PostgreSQL"
|
||||
- "Mobile App -> customer phones"
|
||||
- "Scanner App -> door phones at the cinema site"
|
||||
- "Box-office POS -> cinema site, VPN to POS Sync"
|
||||
@@ -0,0 +1,75 @@
|
||||
schema_version: 1
|
||||
diagram_type: architecture
|
||||
meta:
|
||||
title: Quality tree
|
||||
output: quality-tree.html
|
||||
components:
|
||||
- id: quality
|
||||
type: cloud
|
||||
label: Quality
|
||||
pos: [40, 260]
|
||||
size: [130, 60]
|
||||
- id: reliability
|
||||
type: backend
|
||||
label: Reliability
|
||||
pos: [250, 60]
|
||||
size: [130, 60]
|
||||
- id: performance
|
||||
type: backend
|
||||
label: Performance
|
||||
pos: [250, 210]
|
||||
size: [130, 60]
|
||||
- id: availability
|
||||
type: backend
|
||||
label: Availability
|
||||
pos: [250, 360]
|
||||
size: [130, 60]
|
||||
- id: security
|
||||
type: security
|
||||
label: Security
|
||||
pos: [250, 460]
|
||||
size: [130, 60]
|
||||
- id: s-nodouble
|
||||
type: external
|
||||
label: No double sale
|
||||
pos: [460, 10]
|
||||
size: [150, 60]
|
||||
- id: s-payfail
|
||||
type: external
|
||||
label: Failed pay frees seats
|
||||
pos: [460, 110]
|
||||
size: [170, 60]
|
||||
- id: s-peak
|
||||
type: external
|
||||
label: Checkout < 2 s at peak
|
||||
pos: [460, 210]
|
||||
size: [170, 60]
|
||||
- id: s-offline
|
||||
type: external
|
||||
label: Offline door scans
|
||||
pos: [460, 360]
|
||||
size: [170, 60]
|
||||
- id: s-forged
|
||||
type: external
|
||||
label: Forged QR rejected
|
||||
pos: [460, 460]
|
||||
size: [170, 60]
|
||||
connections:
|
||||
- { from: quality, to: reliability }
|
||||
- { from: quality, to: performance }
|
||||
- { from: quality, to: availability }
|
||||
- { from: quality, to: security }
|
||||
- { from: reliability, to: s-nodouble }
|
||||
- { from: reliability, to: s-payfail }
|
||||
- { from: performance, to: s-peak }
|
||||
- { from: availability, to: s-offline }
|
||||
- { from: security, to: s-forged }
|
||||
cards:
|
||||
- dot: emerald
|
||||
title: 10 Quality scenarios
|
||||
items:
|
||||
- "500 holds on one show in 1 min: no seat sold twice"
|
||||
- "Payment fails or is abandoned: seats free again within 8 min"
|
||||
- "Friday 19:00 peak, 300 checkouts/min: p95 under 2 s"
|
||||
- "Wi-Fi down at the door: scans go on, check-ins sync later"
|
||||
- "Edited or forged QR code scanned: rejected at once"
|
||||
@@ -3,13 +3,14 @@ model:
|
||||
id: cinema-tickets
|
||||
name: Cinema Tickets
|
||||
description: >
|
||||
An arc42 example: online and mobile seat booking for a small
|
||||
cinema chain. This overview is section 3 (business context) with
|
||||
cards for sections 1, 2, 10, 11 and 12. 0300-context holds the
|
||||
technical context (3), 0500-building-blocks the building block
|
||||
view (5), 0600-runtime the runtime view (6), 0700-deployment the
|
||||
deployment view (7), decisions/ the architecture decisions (9).
|
||||
Crosscutting concepts (8) are a card on the level-1 diagram.
|
||||
An arc42 example: seat booking for the fictional Lantern Cinemas.
|
||||
1 Requirements, quality goals, stakeholders; 2 Constraints;
|
||||
4 Solution strategy; 11 Risks; 12 Glossary: cards on this overview.
|
||||
3 Context: this overview (business) and 0300-context (technical).
|
||||
5 Building blocks: 0500-building-blocks, black boxes in registry/.
|
||||
6 Runtime: 0600-runtime. 7 Deployment: 0700-deployment.
|
||||
8 Crosscutting concepts: card on 0500-building-blocks/level-1.
|
||||
9 Decisions: decisions/. 10 Quality: 1000-quality.
|
||||
diagram_type: architecture
|
||||
meta:
|
||||
title: Cinema Tickets - business context
|
||||
@@ -40,12 +41,26 @@ connections:
|
||||
- { from: tickets, to: mail, label: tickets }
|
||||
- { from: tickets, to: pos, label: seat sales }
|
||||
cards:
|
||||
- dot: orange
|
||||
title: 1.1 Requirements
|
||||
items:
|
||||
- "Browse shows and pick seats on a seat map"
|
||||
- "Hold seats, pay online, get QR tickets by e-mail"
|
||||
- "Ushers check tickets in at the door"
|
||||
- "Box-office POS sells from the same seats"
|
||||
- dot: cyan
|
||||
title: 1 Quality goals
|
||||
title: 1.2 Quality goals
|
||||
items:
|
||||
- "No seat is ever sold twice"
|
||||
- "Checkout under 2 s at Friday peak"
|
||||
- "Door check-in works offline"
|
||||
- dot: amber
|
||||
title: 1.3 Stakeholders
|
||||
items:
|
||||
- "Moviegoer: quick booking, tickets on the phone"
|
||||
- "Usher: fast scans even without Wi-Fi"
|
||||
- "Box-office staff: one seat map with online sales"
|
||||
- "Lantern Cinemas management: fewer refunds, low cost"
|
||||
- dot: slate
|
||||
title: 2 Constraints
|
||||
items:
|
||||
@@ -53,16 +68,20 @@ cards:
|
||||
- "Card data only at the provider"
|
||||
- "Team of four; hosted in the EU"
|
||||
- dot: emerald
|
||||
title: 10 Quality scenarios
|
||||
title: 4 Solution strategy
|
||||
items:
|
||||
- "500 holds on one show in 1 min: no double sale"
|
||||
- "Wi-Fi down at the door: scans go on, sync later"
|
||||
- "Payment fails: seats free again within 8 min"
|
||||
- "Node.js, PostgreSQL, Redis on managed EU k8s: fits a team of four"
|
||||
- "Three services by job: booking, tickets, POS sync"
|
||||
- "No double sale: Booking API sole seat owner (booking-owns-seat-inventory)"
|
||||
- "Checkout speed: Redis holds with TTL (seat-holds-with-ttl)"
|
||||
- "Offline check-in: signed QR codes (signed-qr-codes)"
|
||||
- dot: rose
|
||||
title: 11 Risks
|
||||
title: 11 Risks and technical debt
|
||||
items:
|
||||
- "POS vendor API is slow and undocumented"
|
||||
- "Forwarded QR e-mails: first scan wins"
|
||||
- "Risk: POS vendor API is slow and undocumented"
|
||||
- "Risk: forwarded QR e-mails, first scan wins"
|
||||
- "Debt: POS Sync adapter has no automated tests"
|
||||
- "Debt: QR key rotation needs an app release"
|
||||
- dot: violet
|
||||
title: 12 Glossary
|
||||
items:
|
||||
|
||||
@@ -6,52 +6,67 @@ elements:
|
||||
sublabel: React
|
||||
brand: react
|
||||
description: >
|
||||
Programme, seat map and checkout in the browser.
|
||||
Responsibility: programme, seat map and checkout in the browser.
|
||||
Interfaces: provides the web UI; requires Booking API (JSON)
|
||||
and the provider's hosted checkout page.
|
||||
mobile:
|
||||
type: frontend
|
||||
label: Mobile App
|
||||
sublabel: iOS and Android
|
||||
description: >
|
||||
The same booking flow as the web shop, plus a ticket wallet.
|
||||
Responsibility: the web shop's booking flow plus a ticket wallet.
|
||||
Interfaces: provides the iOS/Android UI; requires Booking API
|
||||
(JSON).
|
||||
scanner:
|
||||
type: frontend
|
||||
label: Scanner App
|
||||
sublabel: door phones
|
||||
description: >
|
||||
Reads QR codes at the door; checks signatures offline.
|
||||
Responsibility: reads QR codes at the door, checks signatures
|
||||
offline. Interfaces: provides the usher UI; requires Ticket
|
||||
Service (POST /checkins), queued while offline.
|
||||
booking:
|
||||
type: backend
|
||||
label: Booking API
|
||||
sublabel: Node.js
|
||||
brand: node-js
|
||||
description: >
|
||||
Shows, seat maps, seat holds and orders; the only writer of
|
||||
the seat inventory.
|
||||
Responsibility: shows, seat maps, holds and orders; the only
|
||||
writer of the seat inventory. Interfaces: provides REST JSON to
|
||||
the apps and the payment webhook; requires Seat Locks, Tickets
|
||||
DB, payment provider, Ticket Service.
|
||||
diagram: 0500-building-blocks/booking.archify
|
||||
ticketing:
|
||||
type: backend
|
||||
label: Ticket Service
|
||||
sublabel: QR, check-in
|
||||
description: >
|
||||
Issues signed QR tickets, sends them by e-mail and records
|
||||
check-ins at the door.
|
||||
Responsibility: issues signed QR tickets, mails them and records
|
||||
check-ins. Interfaces: provides issue and POST /checkins;
|
||||
requires Tickets DB and the e-mail service (SMTP).
|
||||
possync:
|
||||
type: backend
|
||||
label: POS Sync
|
||||
sublabel: adapter
|
||||
description: >
|
||||
Exchanges seat sales with the box-office POS in both directions.
|
||||
Responsibility: exchanges seat sales with the box-office POS.
|
||||
Interfaces: provides a REST adapter to the POS over VPN;
|
||||
requires Tickets DB (SQL).
|
||||
seatlock:
|
||||
type: database
|
||||
label: Seat Locks
|
||||
sublabel: Redis
|
||||
brand: redis
|
||||
description: >
|
||||
Short-lived seat holds with a TTL while the customer pays.
|
||||
Responsibility: short-lived seat holds with a TTL while the
|
||||
customer pays. Interfaces: provides Redis SET NX/GET/DEL to the
|
||||
Booking API; requires nothing.
|
||||
db:
|
||||
type: database
|
||||
label: Tickets DB
|
||||
sublabel: PostgreSQL
|
||||
brand: postgresql
|
||||
description: >
|
||||
Shows, seats, orders and tickets; the source of truth.
|
||||
Responsibility: shows, seats, orders and tickets; the source of
|
||||
truth. Interfaces: provides SQL to Booking API, Ticket Service
|
||||
and POS Sync; requires nothing.
|
||||
@@ -33,3 +33,13 @@ connections:
|
||||
- { from: heat-pump, to: telemetry-platform, label: MQTT 8883, variant: emphasis, decisions: [mqtt-with-mutual-tls] }
|
||||
- { from: telemetry-platform, to: push-service, label: HTTP/2 }
|
||||
- { from: telemetry-platform, to: service-desk, label: webhook }
|
||||
cards:
|
||||
- dot: cyan
|
||||
title: 3 Domain interfaces
|
||||
items:
|
||||
- "Heat pump: in telemetry and fault codes; out none"
|
||||
- "Homeowner: in app requests; out status, history, alerts"
|
||||
- "Ops engineer: in queries; out fleet dashboards"
|
||||
- "Installer: in device serial; out device certificate"
|
||||
- "Push service: out alert notifications"
|
||||
- "Service desk: out tickets for faults needing a visit"
|
||||
@@ -73,5 +73,8 @@ cards:
|
||||
title: 8 Crosscutting concepts
|
||||
items:
|
||||
- Device identity, one X.509 certificate per device
|
||||
- Security, OIDC login for people, mTLS for devices
|
||||
- Persistence, PostgreSQL dialect for all stores
|
||||
- Idempotent writes, keyed by device id and timestamp
|
||||
- Error handling, invalid readings to dead letters
|
||||
- Observability, metrics and traces on every service
|
||||
@@ -29,6 +29,12 @@ components:
|
||||
- ref: device-registry
|
||||
pos: [760, 260]
|
||||
size: [130, 60]
|
||||
- ref: ops-dashboard
|
||||
pos: [1030, 160]
|
||||
size: [130, 60]
|
||||
- ref: customer-app
|
||||
pos: [490, 440]
|
||||
size: [130, 60]
|
||||
boundaries:
|
||||
- kind: region
|
||||
label: Kubernetes cluster, eu-central
|
||||
@@ -36,9 +42,26 @@ boundaries:
|
||||
- kind: security-group
|
||||
label: Managed DB zone
|
||||
wraps: [tsdb, device-registry]
|
||||
- kind: region
|
||||
label: Ops network, managed Grafana
|
||||
wraps: [ops-dashboard]
|
||||
- kind: region
|
||||
label: Homeowner phones
|
||||
wraps: [customer-app]
|
||||
connections:
|
||||
- { from: heat-pump, to: mqtt-broker, label: "8883", variant: emphasis }
|
||||
- { from: mqtt-broker, to: ingest, label: in-cluster }
|
||||
- { from: ingest, to: tsdb, label: "5432", variant: emphasis }
|
||||
- { from: ingest, to: rules, label: gRPC }
|
||||
- { from: device-api, to: device-registry, label: "5432" }
|
||||
- { from: tsdb, to: ops-dashboard, label: read-only }
|
||||
- { from: customer-app, to: device-api, label: HTTPS }
|
||||
cards:
|
||||
- dot: slate
|
||||
title: 7 Mapping
|
||||
items:
|
||||
- "mqtt-broker, ingest, rules -> Kubernetes cluster, eu-central"
|
||||
- "provisioning, device-api -> Kubernetes cluster, eu-central"
|
||||
- "tsdb, device-registry -> managed DB zone, eu-central"
|
||||
- "ops-dashboard -> ops network, managed Grafana"
|
||||
- "customer-app -> homeowner phones, app stores"
|
||||
@@ -0,0 +1,75 @@
|
||||
schema_version: 1
|
||||
diagram_type: architecture
|
||||
meta:
|
||||
title: Quality tree
|
||||
output: quality-tree.html
|
||||
components:
|
||||
- id: quality
|
||||
type: cloud
|
||||
label: Quality
|
||||
pos: [40, 240]
|
||||
size: [130, 100]
|
||||
- id: reliability
|
||||
type: backend
|
||||
label: Reliability
|
||||
pos: [250, 60]
|
||||
size: [130, 60]
|
||||
- id: performance
|
||||
type: backend
|
||||
label: Performance
|
||||
pos: [250, 210]
|
||||
size: [130, 60]
|
||||
- id: security
|
||||
type: security
|
||||
label: Security
|
||||
pos: [250, 360]
|
||||
size: [130, 60]
|
||||
- id: operability
|
||||
type: backend
|
||||
label: Operability
|
||||
pos: [250, 460]
|
||||
size: [130, 60]
|
||||
- id: q-no-loss
|
||||
type: frontend
|
||||
label: Broker restart, no loss
|
||||
pos: [460, 60]
|
||||
size: [180, 60]
|
||||
- id: q-alert-60s
|
||||
type: frontend
|
||||
label: Fault alert in 60 s
|
||||
pos: [460, 160]
|
||||
size: [180, 60]
|
||||
- id: q-peak-load
|
||||
type: frontend
|
||||
label: 4,000 readings/s
|
||||
pos: [460, 260]
|
||||
size: [180, 60]
|
||||
- id: q-revoke
|
||||
type: frontend
|
||||
label: Revoke cert in 15 min
|
||||
pos: [460, 360]
|
||||
size: [180, 60]
|
||||
- id: q-new-device
|
||||
type: frontend
|
||||
label: New device in 10 min
|
||||
pos: [460, 460]
|
||||
size: [180, 60]
|
||||
connections:
|
||||
- { from: quality, to: reliability }
|
||||
- { from: quality, to: performance }
|
||||
- { from: quality, to: security }
|
||||
- { from: quality, to: operability }
|
||||
- { from: reliability, to: q-no-loss }
|
||||
- { from: performance, to: q-alert-60s }
|
||||
- { from: performance, to: q-peak-load }
|
||||
- { from: security, to: q-revoke }
|
||||
- { from: operability, to: q-new-device }
|
||||
cards:
|
||||
- dot: emerald
|
||||
title: 10 Quality scenarios
|
||||
items:
|
||||
- "Broker restarts under load: devices reconnect, no accepted reading lost"
|
||||
- "Heat pump sends a fault code: homeowner gets a push within 60 s"
|
||||
- "Fleet peaks at 4,000 readings/s: p95 ingest lag stays under 5 s"
|
||||
- "A device certificate is stolen: ops revoke it, broker refuses it within 15 min"
|
||||
- "Installer registers a new heat pump: data visible in the app within 10 min"
|
||||
@@ -5,11 +5,14 @@ model:
|
||||
description: >
|
||||
An arc42 example: a fictional heat pump maker collects device telemetry
|
||||
over MQTT, stores it, raises alerts and shows it to operations and customers.
|
||||
main.archify holds section 3 business context with cards for sections
|
||||
1 goals, 2 constraints, 10 quality, 11 risks and 12 glossary;
|
||||
0300-context the technical context; 0500-building-blocks section 5;
|
||||
0600-runtime section 6; 0700-deployment section 7; decisions/ section 9;
|
||||
the crosscutting concepts of section 8 are a card on level-1.
|
||||
Where the 12 arc42 sections live:
|
||||
1 introduction and goals, 2 constraints, 4 solution strategy,
|
||||
11 risks and 12 glossary are cards on this overview;
|
||||
3 business context is this overview, technical context in 0300-context;
|
||||
5 building blocks in 0500-building-blocks (black boxes in the registry);
|
||||
6 runtime in 0600-runtime; 7 deployment in 0700-deployment;
|
||||
8 crosscutting concepts a card on 0500-building-blocks/level-1;
|
||||
9 decisions in decisions/; 10 quality tree in 1000-quality.
|
||||
diagram_type: architecture
|
||||
meta:
|
||||
title: Business context
|
||||
@@ -44,29 +47,47 @@ connections:
|
||||
- { from: telemetry-platform, to: push-service, label: alerts }
|
||||
- { from: telemetry-platform, to: service-desk, label: tickets }
|
||||
cards:
|
||||
- dot: orange
|
||||
title: 1.1 Requirements
|
||||
items:
|
||||
- Collect telemetry from every heat pump every 30 s
|
||||
- Alert homeowner and ops on fault codes
|
||||
- Show live and historic data in app and dashboard
|
||||
- Register and provision new devices on site
|
||||
- dot: cyan
|
||||
title: 1 Quality goals
|
||||
title: 1.2 Quality goals
|
||||
items:
|
||||
- Reliability, no telemetry lost once accepted
|
||||
- Timeliness, alert within 60 s of a fault
|
||||
- Security, every device authenticated
|
||||
- dot: emerald
|
||||
title: 1.3 Stakeholders
|
||||
items:
|
||||
- "Homeowner: sees status, gets alerts quickly"
|
||||
- "Ops engineer: fleet view, few false alarms"
|
||||
- "Installer: register a device in minutes"
|
||||
- "Firmware partner: stable MQTT contract"
|
||||
- dot: slate
|
||||
title: 2 Constraints
|
||||
items:
|
||||
- Devices speak MQTT only; firmware by a partner
|
||||
- Data stays in one EU region
|
||||
- Team of six; PostgreSQL skills in house
|
||||
- dot: emerald
|
||||
title: 10 Quality scenarios
|
||||
- dot: amber
|
||||
title: 4 Solution strategy
|
||||
items:
|
||||
- A fault code reaches the homeowner within 60 s
|
||||
- Broker restart, devices reconnect, no data lost
|
||||
- A stolen certificate is revoked within 15 min
|
||||
- MQTT with mutual TLS for devices (security, ADR 0001)
|
||||
- TimescaleDB for telemetry, SQL everywhere (ADR 0002)
|
||||
- Ingest acks only after commit (reliability)
|
||||
- Rules engine on the ingest stream (timeliness)
|
||||
- Split by flow, ingest vs read vs provisioning
|
||||
- dot: rose
|
||||
title: 11 Risks
|
||||
title: 11 Risks and technical debt
|
||||
items:
|
||||
- R1 fleet growth beyond one TSDB node
|
||||
- R2 partner firmware delays certificate rotation
|
||||
- "Risk: fleet growth beyond one TSDB node"
|
||||
- "Risk: partner firmware delays cert rotation"
|
||||
- "Debt: payload v1 decoder kept for old firmware"
|
||||
- "Debt: rules configured in code, no UI"
|
||||
- dot: violet
|
||||
title: 12 Glossary
|
||||
items:
|
||||
|
||||
@@ -5,14 +5,18 @@ elements:
|
||||
label: MQTT broker
|
||||
sublabel: mutual TLS
|
||||
description: >
|
||||
Terminates device connections; one topic per device.
|
||||
Responsibility: terminates device connections, one topic per device.
|
||||
Interfaces: provides MQTT 8883 with mTLS; requires certs and
|
||||
revocation checks from Provisioning.
|
||||
ingest:
|
||||
type: backend
|
||||
label: Ingest
|
||||
sublabel: Go
|
||||
brand: go
|
||||
description: >
|
||||
Decodes, validates and stores telemetry; forwards it to the rules.
|
||||
Responsibility: decodes, validates and stores telemetry.
|
||||
Interfaces: requires MQTT subscription, TSDB, device registry;
|
||||
provides the reading stream to the rules engine.
|
||||
diagram: 0500-building-blocks/ingest.archify
|
||||
tsdb:
|
||||
type: database
|
||||
@@ -20,42 +24,52 @@ elements:
|
||||
sublabel: TimescaleDB
|
||||
brand: postgresql
|
||||
description: >
|
||||
Raw telemetry for 90 days and hourly rollups for 10 years.
|
||||
Responsibility: raw telemetry 90 days, hourly rollups 10 years.
|
||||
Interfaces: provides SQL on 5432 to Device API and dashboard;
|
||||
requires batched writes from Ingest.
|
||||
rules:
|
||||
type: backend
|
||||
label: Rules engine
|
||||
sublabel: alerting
|
||||
description: >
|
||||
Evaluates thresholds and fault codes; raises alerts.
|
||||
Responsibility: evaluates thresholds and fault codes, raises alerts.
|
||||
Interfaces: requires the reading stream from Ingest;
|
||||
provides alerts to the push service and service desk.
|
||||
provisioning:
|
||||
type: security
|
||||
label: Provisioning
|
||||
sublabel: device certs
|
||||
description: >
|
||||
Registers devices and issues their client certificates.
|
||||
Responsibility: registers devices and issues client certificates.
|
||||
Interfaces: provides a REST register call for installers and
|
||||
revocation checks for the broker; requires the device registry.
|
||||
device-registry:
|
||||
type: database
|
||||
label: Device registry
|
||||
sublabel: PostgreSQL
|
||||
brand: postgresql
|
||||
description: >
|
||||
Devices, owners, firmware versions and certificate state.
|
||||
Responsibility: devices, owners, firmware and certificate state.
|
||||
Interfaces: provides SQL on 5432 to Ingest, Provisioning, Device API.
|
||||
device-api:
|
||||
type: backend
|
||||
label: Device API
|
||||
sublabel: REST
|
||||
description: >
|
||||
Serves telemetry and device data to the customer app.
|
||||
Responsibility: serves telemetry and device data to the customer app.
|
||||
Interfaces: provides REST over HTTPS; requires TSDB and device registry.
|
||||
ops-dashboard:
|
||||
type: frontend
|
||||
label: Ops dashboard
|
||||
sublabel: Grafana
|
||||
brand: grafana
|
||||
description: >
|
||||
Fleet view for the operations team, read only on the TSDB.
|
||||
Responsibility: fleet view for the operations team.
|
||||
Interfaces: provides web UI over HTTPS; requires read-only SQL on TSDB.
|
||||
customer-app:
|
||||
type: frontend
|
||||
label: Customer app
|
||||
sublabel: mobile
|
||||
description: >
|
||||
Shows the homeowner their heat pump and its alerts.
|
||||
Responsibility: shows the homeowner their heat pump and alerts.
|
||||
Interfaces: provides the mobile UI; requires Device API and push.
|
||||
@@ -24,3 +24,11 @@ connections:
|
||||
- { from: wiki-admin, to: wiki, label: kubectl }
|
||||
- { from: wiki, to: idp, label: OIDC, variant: security }
|
||||
- { from: wiki, to: object-store, label: S3 API }
|
||||
cards:
|
||||
- dot: cyan
|
||||
title: 3 Domain interfaces
|
||||
items:
|
||||
- "Engineer: in edits, queries, files; out pages, results"
|
||||
- "Wiki admin: in deploys, restore commands; out status, logs"
|
||||
- "Identity provider: out sign-in code, groups; in token requests"
|
||||
- "Object storage: out attachments, backups; in signed URL reads"
|
||||
@@ -42,6 +42,9 @@ cards:
|
||||
- dot: amber
|
||||
title: 8 Crosscutting concepts
|
||||
items:
|
||||
- Access - every request checked against space groups
|
||||
- Logs - JSON to stdout, collected by the cluster
|
||||
- Config - environment variables, secrets from the vault
|
||||
- "Security: OIDC session, every request checked against space groups"
|
||||
- "Persistence: PostgreSQL is the only source of truth"
|
||||
- "Errors: API returns problem JSON; the web app shows a retry"
|
||||
- "Logging: JSON to stdout, collected by the cluster"
|
||||
- "Backups: nightly dump to object storage, 30 days"
|
||||
- "Config: environment variables, secrets from the vault"
|
||||
@@ -36,8 +36,11 @@ boundaries:
|
||||
label: Company cluster
|
||||
wraps: [ingress, web, api, db, backup-job]
|
||||
- kind: security-group
|
||||
label: Namespace team-wiki
|
||||
wraps: [web, api, db, backup-job]
|
||||
label: App node pool
|
||||
wraps: [web, api]
|
||||
- kind: security-group
|
||||
label: Data node
|
||||
wraps: [db, backup-job]
|
||||
connections:
|
||||
- { from: engineer, to: ingress, label: HTTPS, variant: emphasis }
|
||||
- { from: ingress, to: web, label: static }
|
||||
@@ -46,3 +49,12 @@ connections:
|
||||
- { from: api, to: idp, label: OIDC, variant: security, labelAt: [525, 234] }
|
||||
- { from: backup-job, to: db, label: dump }
|
||||
- { from: backup-job, to: object-store, label: S3 }
|
||||
cards:
|
||||
- dot: slate
|
||||
title: 7 Mapping
|
||||
items:
|
||||
- "Web App -> app node pool, nginx pod, namespace team-wiki"
|
||||
- "Wiki API -> app node pool, 2 pods behind the ingress"
|
||||
- "Database -> data node, PostgreSQL stateful set with volume"
|
||||
- "Backup job -> data node, Kubernetes CronJob"
|
||||
- "Attachments, backups -> company object storage buckets"
|
||||
@@ -0,0 +1,77 @@
|
||||
schema_version: 1
|
||||
diagram_type: architecture
|
||||
meta:
|
||||
title: Quality tree
|
||||
output: quality-tree.html
|
||||
legend:
|
||||
mode: hidden
|
||||
components:
|
||||
- id: quality
|
||||
type: cloud
|
||||
label: Quality
|
||||
pos: [40, 200]
|
||||
size: [130, 120]
|
||||
- id: usability
|
||||
type: frontend
|
||||
label: Usability
|
||||
pos: [250, 60]
|
||||
size: [130, 60]
|
||||
- id: security
|
||||
type: security
|
||||
label: Security
|
||||
pos: [250, 160]
|
||||
size: [130, 60]
|
||||
- id: reliability
|
||||
type: backend
|
||||
label: Reliability
|
||||
pos: [250, 310]
|
||||
size: [130, 60]
|
||||
- id: maintainability
|
||||
type: backend
|
||||
label: Maintainability
|
||||
pos: [250, 460]
|
||||
size: [130, 60]
|
||||
- id: q-search
|
||||
type: external
|
||||
label: Search under 1 s
|
||||
pos: [460, 60]
|
||||
size: [170, 60]
|
||||
- id: q-leaver
|
||||
type: external
|
||||
label: Leaver out in 5 min
|
||||
pos: [460, 160]
|
||||
size: [170, 60]
|
||||
- id: q-restore
|
||||
type: external
|
||||
label: Restore in 30 min
|
||||
pos: [460, 260]
|
||||
size: [170, 60]
|
||||
- id: q-pod
|
||||
type: external
|
||||
label: Pod back in 1 min
|
||||
pos: [460, 360]
|
||||
size: [170, 60]
|
||||
- id: q-upgrade
|
||||
type: external
|
||||
label: Upgrade in 1 hour
|
||||
pos: [460, 460]
|
||||
size: [170, 60]
|
||||
connections:
|
||||
- { from: quality, to: usability }
|
||||
- { from: quality, to: security }
|
||||
- { from: quality, to: reliability }
|
||||
- { from: quality, to: maintainability }
|
||||
- { from: usability, to: q-search }
|
||||
- { from: security, to: q-leaver }
|
||||
- { from: reliability, to: q-restore }
|
||||
- { from: reliability, to: q-pod }
|
||||
- { from: maintainability, to: q-upgrade }
|
||||
cards:
|
||||
- dot: emerald
|
||||
title: 10 Quality scenarios
|
||||
items:
|
||||
- "Search: an engineer searches 5000 pages; results in under 1 s"
|
||||
- "Leaver: HR disables an account; wiki access ends within 5 minutes"
|
||||
- "Restore: the database is lost; the admin restores last night in 30 minutes"
|
||||
- "Crash: an API pod dies; the cluster restarts it, no data lost, back in 1 minute"
|
||||
- "Upgrade: a new wiki version ships; one admin rolls it out in 1 hour"
|
||||
@@ -3,12 +3,14 @@ model:
|
||||
id: team-wiki
|
||||
name: Team Wiki
|
||||
description: >
|
||||
An arc42 example: a small self-hosted wiki for an engineering
|
||||
team. Sections 1 goals, 2 constraints, 3 business context,
|
||||
10 quality, 11 risks and 12 glossary are on this overview;
|
||||
0300-context holds 3 technical context, 0500-building-blocks
|
||||
5 building blocks, 0600-runtime 6 runtime, 0700-deployment
|
||||
7 deployment and decisions 9 architecture decisions.
|
||||
An arc42 example: a small self-hosted wiki for an engineering team.
|
||||
1 Requirements, quality goals, stakeholders; 2 Constraints;
|
||||
4 Solution strategy; 11 Risks; 12 Glossary: cards on this overview.
|
||||
3 Context: this overview (business) and 0300-context (technical).
|
||||
5 Building blocks: 0500-building-blocks, black boxes in registry/.
|
||||
6 Runtime: 0600-runtime. 7 Deployment: 0700-deployment.
|
||||
8 Crosscutting concepts: card on 0500-building-blocks/level-1.
|
||||
9 Decisions: decisions/. 10 Quality: 1000-quality.
|
||||
diagram_type: architecture
|
||||
meta:
|
||||
title: Team Wiki - business context
|
||||
@@ -36,31 +38,48 @@ connections:
|
||||
- { from: wiki, to: idp, label: sign-in, variant: security }
|
||||
- { from: wiki, to: object-store, label: files }
|
||||
cards:
|
||||
- dot: cyan
|
||||
title: 1 Quality goals
|
||||
- dot: orange
|
||||
title: 1.1 Requirements
|
||||
items:
|
||||
- Findability - any page found in two searches
|
||||
- Security - only current staff can read
|
||||
- Operability - one person runs it in an hour a week
|
||||
- "Create, edit and version pages in team spaces"
|
||||
- "Full-text search over every page a user may read"
|
||||
- "Attach files to pages"
|
||||
- "Admin restores the wiki from a nightly backup"
|
||||
- dot: cyan
|
||||
title: 1.2 Quality goals
|
||||
items:
|
||||
- "Findability: any page found in two searches"
|
||||
- "Security: only current staff can read"
|
||||
- "Operability: one person runs it in an hour a week"
|
||||
- dot: amber
|
||||
title: 1.3 Stakeholders
|
||||
items:
|
||||
- "Engineer: fast search, simple editor"
|
||||
- "Wiki admin: little routine work, easy restore"
|
||||
- "Security officer: no access after leaving"
|
||||
- "Team lead: one place for team knowledge"
|
||||
- dot: slate
|
||||
title: 2 Constraints
|
||||
items:
|
||||
- Runs on the company Kubernetes cluster
|
||||
- Sign-in only via the company identity provider
|
||||
- "Runs on the company Kubernetes cluster"
|
||||
- "Sign-in only via the company identity provider"
|
||||
- dot: emerald
|
||||
title: 10 Quality scenarios
|
||||
title: 4 Solution strategy
|
||||
items:
|
||||
- A search over 5000 pages answers in under 1 s
|
||||
- A leaver loses access within 5 minutes
|
||||
- The admin restores last night's state in 30 minutes
|
||||
- "React, Node.js API, PostgreSQL: one stack the team knows"
|
||||
- "Three blocks plus a backup job: operability"
|
||||
- "Findability: PostgreSQL full-text search (postgres-full-text-search)"
|
||||
- "Security: OIDC at the company IdP only (sso-only-via-company-idp)"
|
||||
- "Operability: files and backups in company object storage"
|
||||
- dot: rose
|
||||
title: 11 Risks
|
||||
title: 11 Risks and technical debt
|
||||
items:
|
||||
- Identity provider outage blocks all sign-ins
|
||||
- Backups untested until a restore drill is run
|
||||
- "Risk: identity provider outage blocks all sign-ins"
|
||||
- "Risk: backups untested until a restore drill is run"
|
||||
- "Debt: attachments are not virus-scanned yet"
|
||||
- dot: violet
|
||||
title: 12 Glossary
|
||||
items:
|
||||
- Space - pages of one team, mapped to a group
|
||||
- Revision - one saved version of a page
|
||||
- Attachment - a file stored beside a page
|
||||
- "Space: pages of one team, mapped to a group"
|
||||
- "Revision: one saved version of a page"
|
||||
- "Attachment: a file stored beside a page"
|
||||
@@ -6,15 +6,17 @@ elements:
|
||||
sublabel: React
|
||||
brand: react
|
||||
description: >
|
||||
Page editor, viewer and search box in the browser; talks
|
||||
only to the API.
|
||||
Responsibility: page editor, viewer and search box in the
|
||||
browser. Interfaces: provides the UI over HTTPS; requires
|
||||
the Wiki API (JSON).
|
||||
api:
|
||||
type: backend
|
||||
label: Wiki API
|
||||
sublabel: REST
|
||||
description: >
|
||||
Pages, search, attachments and access checks; the only
|
||||
writer of the database.
|
||||
Responsibility: pages, search, attachments and access checks;
|
||||
the only writer of the database. Interfaces: provides REST
|
||||
JSON; requires the IdP (OIDC), the database (SQL), object storage (S3).
|
||||
diagram: 0500-building-blocks/wiki-api.archify
|
||||
db:
|
||||
type: database
|
||||
@@ -22,12 +24,14 @@ elements:
|
||||
sublabel: PostgreSQL
|
||||
brand: postgresql
|
||||
description: >
|
||||
Pages, revisions, users and the full-text index; the
|
||||
source of truth.
|
||||
Responsibility: pages, revisions, users and the full-text
|
||||
index; the source of truth. Interfaces: provides SQL to the
|
||||
API and dumps to the backup job.
|
||||
backup-job:
|
||||
type: backend
|
||||
label: Backup job
|
||||
sublabel: nightly
|
||||
description: >
|
||||
Dumps the database at 02:00 and writes it to the backup
|
||||
bucket; keeps 30 days.
|
||||
Responsibility: dumps the database at 02:00, keeps 30 days.
|
||||
Interfaces: requires the database (pg_dump) and the backup
|
||||
bucket (S3); provides none.
|
||||
@@ -77,6 +77,65 @@ The numbered folders are only for sorting; nothing depends on the names. A team
|
||||
|
||||
Component types that fit C4: people are `external`; the system itself and other systems are `cloud` (own) or `external` (others); containers are `frontend`, `backend`, `database`, `messagebus`, `security`; components inside a container use the same set, wrapped in a `region` boundary named after the container.
|
||||
|
||||
## arc42
|
||||
|
||||
[arc42](https://arc42.org) is a documentation template with twelve sections; four of them are views (diagrams), the rest are text. In a model, the views are folders numbered like their section, the decisions are section 9, and the text sections are `cards` (title plus short items) on the diagram they belong to. Card titles carry the section number so a reader finds each section.
|
||||
|
||||
```
|
||||
cinema-tickets/
|
||||
main.archify section 3 business context (the system and its neighbours);
|
||||
cards 1.1 Requirements, 1.2 Quality goals, 1.3 Stakeholders,
|
||||
2 Constraints, 4 Solution strategy, 11 Risks and technical debt,
|
||||
12 Glossary
|
||||
registry/
|
||||
people.archify-registry users and operators
|
||||
systems.archify-registry neighbouring systems
|
||||
building-blocks.archify-registry each block's description in black-box form:
|
||||
"Responsibility: ... Interfaces: ..." (section 5)
|
||||
0300-context/
|
||||
technical-context.archify channels and protocols; card 3 Domain interfaces
|
||||
0500-building-blocks/
|
||||
level-1.archify the system's white box; card 8 Crosscutting concepts
|
||||
booking.archify level 2 of one block, linked from its registry entry
|
||||
0600-runtime/
|
||||
book-seats.archify key scenarios as sequence diagrams
|
||||
0700-deployment/
|
||||
production.archify building blocks inside boundaries for nodes and zones;
|
||||
card 7 Mapping (block -> node)
|
||||
1000-quality/
|
||||
quality-tree.archify Quality -> characteristics -> scenarios;
|
||||
card 10 Quality scenarios (stimulus and response)
|
||||
decisions/ section 9, one *.archify-decision per decision
|
||||
```
|
||||
|
||||
Say where each section lives in `model.description`. Cards hold short lines, not prose: an arc42 document with long text belongs next to the model, not in it. `examples/arc42-cinema-tickets/`, `arc42-iot-telemetry/` and `arc42-team-wiki/` (the smallest) are complete.
|
||||
|
||||
## ArchiMate
|
||||
|
||||
[ArchiMate](https://www.opengroup.org/archimate-forum) models an enterprise in layers. Archify has no ArchiMate notation, so each element is an Archify component type with its ArchiMate type written out: in `tag` (searchable, shown in the focus panel) and in `sublabel` (shown on the box; Archify draws tags only in the focus panel).
|
||||
|
||||
```
|
||||
insurance-claims/
|
||||
main.archify layered view: Business, Application, Technology as three
|
||||
region boundaries, top to bottom, three elements each in the
|
||||
same columns, serves/realizes arrows between layers
|
||||
registry/
|
||||
business.archify-registry actors, roles, processes, services, events
|
||||
application.archify-registry components, services, interfaces, data objects
|
||||
technology.archify-registry nodes, system software, technology services, networks
|
||||
0100-business/
|
||||
business-layer.archify actors, roles and services
|
||||
handle-claim.archify the business process as a workflow (lanes per role)
|
||||
0200-application/
|
||||
application-structure.archify components, services, interfaces, data objects
|
||||
application-cooperation.archify how the components talk
|
||||
0300-technology/
|
||||
infrastructure.archify nodes and networks inside boundaries
|
||||
decisions/
|
||||
```
|
||||
|
||||
A mapping that reads well: actors and roles `external`; processes `backend`; business and application services `cloud` or `frontend`; application components `backend` or `frontend`; data objects `database`; nodes `backend`, `cloud` or `database`; networks `messagebus` or `security`. Name relationships in connection labels: serves, realizes, uses, accesses, assigned to, triggers. Keep type names short enough for the box (`App Component`, `Tech Service`). `examples/archimate-insurance-claims/`, `archimate-hr-onboarding/` and `archimate-logistics-tracking/` are complete.
|
||||
|
||||
## How the extension knows it is in a model
|
||||
|
||||
The nearest folder above a file that contains `main.archify` is the root. Under that root, at any depth: `*.archify` are member diagrams, `*.archify-registry` make up the registry, subfolders are groups. `node_modules` and `.git` are skipped.
|
||||
|
||||
Reference in new issue
Block a user