SCAN concepts
SCAN (System & Component Architecture Notation) describes software systems as structured YAML (or JSON). Version key: scan: "0.1".
Principle: keep architectural type (role) separate from technology (stack) — e.g. type: service + technology: Spring Boot.
Document shape
scan: "0.1"
system:
id: order-platform
name: Order Platform
components: [ ... ]
channels: [ ... ]
external_systems: [ ... ]
agents: [ ... ]
repositories: [ ... ]
connections: [ ... ]
views:
- id: architecture-board
layout: { ... }
boundaries: [ ... ]
| Field | Required | Purpose |
|---|---|---|
scan | yes | Notation version "0.1" |
system | yes | System id + name |
views | yes (≥1) | Diagram layout + boundaries |
| Collections | no | Semantics for nodes and edges |
Where elements live
| Concept | Collection |
|---|---|
| Service / datastore / search | components |
| Event / stream topic | channels |
| Third-party system | external_systems |
| Agent | agents |
| Agent runtime | agent_runtimes |
| Repo as a canvas node | repositories |
| Typed edge | connections |
Inline repository: on a component is a path reference — not a separate box.
Ports
consumes:
- id: api-in
label: REST
protocol: OpenAPI
exposes:
- id: api-out
label: REST
protocol: OpenAPI
consumes = inbound surface. exposes = provided interface. With fromPort / toPort, rules expect expose → consume.
Semantics vs presentation
- Semantics — root collections (what exists, how it connects).
- Presentation —
views[].layoutboxes andviews[].boundaries(pixels only).
Every element that should appear on the board needs a layout entry — the viewer throws Missing layout for entity for one that's missing. The schema and validate command only catch the opposite mistake: a layout key with no matching element (unknown-layout-id).
Minimal example
scan: "0.1"
system:
id: checkout
name: Checkout
components:
- id: checkout-api
name: Checkout API
type: service
technology: NestJS
exposes:
- id: checkout-api-out
label: REST
protocol: OpenAPI
external_systems:
- id: payments
name: Payments Provider
exposes:
- id: payments-out
label: REST
connections:
- id: c1
from: payments
to: checkout-api
type: synchronous-request
label: REST
views:
- id: board
layout:
checkout-api: { x: 320, y: 120, w: 260, h: 190 }
payments: { x: 40, y: 120, w: 220, h: 150 }
Next: field-level SCAN reference.