Diagram conventions
Every architecture diagram in these docs colours each box by the tier it lives in. Five tiers, the same everywhere — memorise them once and you can read any diagram at a glance: colour tells you what kind of thing a box is before you read its label.
The colours are deterministic hex, not theme-derived. Diagrams render client-side and re-theme with the light/dark toggle, but a box’s tier colour stays constant across themes so a screenshot in one theme still reads correctly in the other.
The five tiers
Section titled “The five tiers”| Tier | Class | fill / stroke |
What lives here |
|---|---|---|---|
| frontend | frontend |
#6366f1 / #4338ca (indigo) |
soundverse-saas-2.0 (the Next.js SPA + BFF) and the standalone, demo-only UI2.0 studio |
| gateway | gateway |
#0ea5e9 / #0369a1 (sky) |
The trust boundary and request pipeline: core-gateway-consumer, core-identity, and core-mcp (the agent-side boundary + second billing pipeline) |
| data plane | data |
#8b5cf6 / #6d28d9 (violet) |
The data owners: core-database (the single Postgres door), core-storage (blob owner), and core-billing |
| worker | worker |
#10b981 / #047857 (emerald) |
Task-claiming tool services — every core-tool-* worker, including the agent worker (core-tool-agent) |
| external | external |
#f59e0b fill, #b45309 stroke (amber) |
Third parties: Logto (OIDC), the LLM / audio model providers (Anthropic, Kimi, and the song/media model APIs), and Azure Blob |
The copy-paste block
Section titled “The copy-paste block”Paste this at the bottom of any Mermaid diagram, then tag each node with :::<class>.
It is the canonical legend — do not invent new colours or reorder the tiers.
classDef frontend fill:#6366f1,color:#fff,stroke:#4338caclassDef gateway fill:#0ea5e9,color:#fff,stroke:#0369a1classDef data fill:#8b5cf6,color:#fff,stroke:#6d28d9classDef worker fill:#10b981,color:#fff,stroke:#047857classDef external fill:#f59e0b,color:#111,stroke:#b45309Amber (external) uses dark label text (color:#111) because the fill is light; the other
four use white (color:#fff). Keeping these fixed is what makes the fleet’s diagrams read
as one system.
How to apply it
Section titled “How to apply it”-
Draw the diagram with plain node ids and labels — no styling yet.
-
Tag each node with its tier using Mermaid’s inline class syntax
id:::className(or a trailingclass id classNameline). A node with no tag falls back to the theme default, which is the right choice only for the neutral backing stores above. -
Append the classDef block verbatim from the section above. Order the five lines the same way every time so diffs stay clean.
Worked example
Section titled “Worked example”A minimal flowchart that exercises all five tiers plus one neutral store:
flowchart LR
UI["saas-2.0<br/>SPA + BFF"]:::frontend
GW["core-gateway-consumer"]:::gateway
ID["core-identity"]:::gateway
DB["core-database"]:::data
W["core-tool-sansaarm"]:::worker
LLM["Logto / model providers"]:::external
PG[("Postgres")]
UI -->|"/api/* BFF"| GW
GW -->|validate| ID
ID -->|JWKS| LLM
GW -->|"single door"| DB
DB --- PG
GW -. "enqueue task" .-> W
W -->|"model call"| LLM
classDef frontend fill:#6366f1,color:#fff,stroke:#4338ca
classDef gateway fill:#0ea5e9,color:#fff,stroke:#0369a1
classDef data fill:#8b5cf6,color:#fff,stroke:#6d28d9
classDef worker fill:#10b981,color:#fff,stroke:#047857
classDef external fill:#f59e0b,color:#111,stroke:#b45309
The trust boundary reads visually: everything sky (gateway) is the authorise → price →
reserve → queue pipeline, violet (data) is the one Postgres door behind it, emerald
(worker) is the fleet doing the heavy lifting off the request path, and amber (external)
is anything the fleet doesn’t own.
Conventions to keep diagrams consistent
Section titled “Conventions to keep diagrams consistent”- Direction: prefer
flowchart LRfor topology (frontend on the left, external on the right, so the trust boundary runs vertically down the middle) andsequenceDiagramwithautonumberfor request lifecycles. - Edges tell you the plane: a solid arrow is a synchronous call; a dotted arrow
(
-. label .->) is an async enqueue onto the task queue. The gateway-to-worker hop is always dotted — the worker claims the task later, it isn’t called inline. - Theme-neutral, always. Don’t hardcode a background or rely on default node fills for
meaning — the toggle flips them. Meaning lives in the tier
classDef, which is fixed. - One tier per box. If a box feels like two tiers (for example
core-mcpis both a boundary and a billing engine), pick the tier that matches its role in that diagram and say the rest in prose.
Related
Section titled “Related”- Adding a Mermaid diagram — how the fences render and re-theme
- Authoring conventions — asides, badges, and the secret-safety rule
- System overview — the hero diagram this legend was built for
- The 60-second mental model — the same tiers, one flowchart