finos / finos/architecture-as-code

Add First-Class Views to CALM

Open
#2,344 7 comments 0 reactions 0 assignees View on GitHub
calm needs-input
Dominant language
TypeScript
Stars
399
Forks
138
Avg merge
2d 6h
Merged PRs (30d)
38

Description

## Target Schema:

New file(s): `view.json` (view definition schema) and potentially a top-level `views` property on `core.json`

### Description of Change:
[]()
Add a first-class **View** concept to the CALM schema — named, reusable definitions that describe which parts of an architecture to show, for whom, and why.

**Background:** Architecture models serve many audiences. A security architect, an operations engineer, a new joiner, and a business stakeholder all look at the same system but care about different things. Tools like Structurizr and the C4 model solve this with explicit view definitions: named configurations that filter, scope, and describe a particular perspective of the architecture.

CALM today has powerful filtering at the tooling level — widgets support `focus-nodes`, `focus-flows`, `focus-relationships`, `focus-interfaces`, `focus-controls`, and `node-types` options; calm-studio provides C4 zoom levels; docify templates embed these as Handlebars parameters. But none of these are captured in the architecture itself. They exist only as:

- Inline widget option strings in docify templates (e.g., `focus-flows="payment-flow"`)
- Runtime UI state in calm-studio's C4 mode
- Implicit knowledge in people's heads ("to understand the payment flow, look at nodes X, Y, Z")

This means views are **ephemeral, not shareable, and not portable**. A team cannot commit a set of named views alongside their architecture and have every tool — IDE plugin, documentation generator, web UI, AI assistant — consistently render the same perspective. An open question is whether views should be explicitly authored and versioned, or whether standard rules could derive common views (logical, deployment, security) automatically from the architecture's structure.

### Use Cases:

1. **Deployment view** — Define a view that shows how services map to infrastructure (containers, clusters, networks) and overlay deployment decorator data (status, timestamps). Platform engineers see the physical topology without logical noise.
2. **Logical view** — Define a view of the logical architecture — systems, services, actors, and their interactions — stripped of infrastructure and deployment detail. Solution architects and developers work with this daily.
3. **Security view** — Highlight security-relevant nodes, their controls, and encrypted connections, overlaid with security audit decorators. Share with auditors without them needing to understand the full architecture.
4. **Onboarding** — Create a "Getting Started" view that shows only the core services a new team member needs to understand on day one.
5. **Domain focus** — In a large architecture with 50+ nodes, define views per domain (e.g., "Payments", "User Management", "Infrastructure") so teams can navigate their area without visual noise.
6. **Cross-tool consistency** — The same view definition renders identically in VS Code preview, calm-hub-ui, docify output, and calm-studio. Today each tool reinvents this independently.
7. **Review and governance** — Architecture review boards can define standard views (e.g., "Deployment", "Logical", "External Dependencies") that every team must maintain, enabling consistent review across the organisation.

### Current Limitations:

1. **No schema-level view concept** — There is no way to define a named, reusable view in a CALM document. Views exist only as ad-hoc widget parameters or runtime UI state.
2. **Views are tool-specific** — A focus configuration in a docify template does not transfer to calm-studio or the VS Code plugin. Each tool has its own mechanism.
3. **Views are not portable** — Because views live in templates or UI state, they cannot be shared or reused across tools.
4. **No audience/purpose metadata** — Even where filtering exists, there is no way to say *who* a view is for or *why* it exists. The intent is lost.

### Proposed Schema Changes:

```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://calm.finos.org/draft/XXXX-XX/meta/view.json",
"title": "CALM View Definition",
"defs": {
"view": {
"type": "object",
"properties": {
"unique-id": {
"type": "string",
"description": "Unique identifier for this view."
},
"name": {
"type": "string",
"description": "Human-readable name for the view."
},
"description": {
"type": "string",
"description": "What this view shows and why."
},
"audience": {
"type": "string",
"description": "Who this view is intended for (e.g., 'Security team', 'New joiners', 'Architecture review board')."
},
"filter": {
"type": "object",
"description": "Criteria for what to include in this view.",
"properties": {
"nodes": {
"type": "array",
"items": { "type": "string" },
"description": "Node unique-ids to include."
},
"relationships": {
"type": "array",
"items": { "type": "string" },
"description": "Relationship unique-ids to include."
},
"flows": {
"type": "array",
"items": { "type": "string" },
"description": "Flow unique-ids to include."
},
"node-types": {
"type": "array",
"items": { "type": "string" },
"description": "Include only nodes of these types."
},
"controls": {
"type": "array",
"items": { "type": "string" },
"description": "Control keys to focus on."
},
"decorators": {
"type": "array",
"items": { "type": "string" },
"description": "Decorator unique-ids to include in this view."
}
},
"additionalProperties": false
}
},
"required": ["unique-id", "name", "description", "filter"],
"additionalProperties": false
}
}
}
```

Usage in architecture document:

```json
{
"$schema": "https://calm.finos.org/draft/XXXX-XX/meta/calm.json",
"nodes": [ "..." ],
"relationships": [ "..." ],
"views": [
{
"unique-id": "deployment-view",
"name": "Deployment View",
"description": "Shows how services are deployed across infrastructure, overlaid with deployment status from decorators.",
"audience": "Platform engineers and SREs",
"filter": {
"node-types": ["service", "database", "network"],
"relationships": ["deployed-in-k8s-prod", "deployed-in-k8s-staging"],
"decorators": ["prod-deployment-dec-001", "staging-deployment-dec-002"]
}
},
{
"unique-id": "logical-view",
"name": "Logical Architecture",
"description": "Shows the logical system decomposition — services, their interactions, and key data flows — without infrastructure concerns.",
"audience": "Solution architects and development leads",
"filter": {
"node-types": ["system", "service", "database", "actor"],
"flows": ["payment-flow", "user-registration-flow"]
}
},
{
"unique-id": "security-overview",
"name": "Security Overview",
"description": "Shows all nodes with security controls and encrypted connections, overlaid with security audit decorators.",
"audience": "Security architects and auditors",
"filter": {
"controls": ["encryption-in-transit", "authentication"],
"node-types": ["service", "database"],
"decorators": ["api-security-context"]
}
},
{
"unique-id": "day-one-onboarding",
"name": "Getting Started",
"description": "Core services a new team member needs to understand.",
"audience": "New joiners",
"filter": {
"nodes": ["api-gateway", "user-service", "order-service", "primary-db"]
}
}
]
}
```

### Backward Compatibility:

- **No breaking changes.** `views` is a new optional top-level property.
- Existing CALM documents remain valid — views are entirely opt-in.
- No migration required for existing documents.
- Tooling that does not understand views simply ignores the property.

### Validation Strategy:

- Views reference nodes, relationships, flows, controls by unique-id — validation should warn if a referenced id does not exist in the architecture.
- Schema itself validates against JSON Schema 2020-12.
- Example documents with views that validate against the new schema.

### Implementation Impact:

- **Widget framework (calm-widgets)**: Already supports all the filter options (`focus-nodes`, `focus-flows`, etc.). Views would provide a schema-backed way to drive these existing capabilities — minimal new code, mostly mapping view filter properties to existing widget options.
- **VS Code extension**: Could list available views in the Tree View, letting users switch between perspectives with a click.
- **calm-hub-ui**: Could offer a view selector dropdown alongside the existing search and type filter.
- **calm-studio**: Could expose views alongside its existing C4 mode.
- **Docify**: Templates could reference a view by name instead of inlining focus parameters.
- **CLI**: `calm docify --view security-overview` could render documentation scoped to a named view.

### Open Questions:

1. **Standard views vs custom views** — Should CALM define standard rules that automatically derive common views (e.g., a "Logical View" is always nodes of type system/service/database/actor with connects/interacts relationships; a "Deployment View" is always deployed-in relationships plus deployment decorators)? Or should all views be explicitly authored by the user? A middle ground could be standard view *templates* that tooling generates by convention, which users can then customise.
2. **Do views need to be versioned?** — Should views be committed and tracked alongside the architecture, or are they lightweight enough to be ephemeral configurations that tooling generates on the fly? If standard derivation rules exist, explicit versioning may be less important since the view can be recalculated from the architecture at any time.
3. **Where do views live?** — Inline in the architecture document (as proposed above), in a separate sidecar file (like decorators), or both?

### Version Strategy:

- This is a significant addition — likely warrants inclusion in a future draft version.
- The `filter` property structure intentionally mirrors the existing widget focus options to minimise the impedance mismatch between schema and tooling.

### Implementation Checklist:

- [ ] Schema changes drafted and validated
- [ ] Example documents created that validate against the new schema
- [ ] Tests written to verify schema behavior
- [ ] Documentation updated to reflect changes
- [ ] Migration guide created (if applicable)
- [ ] Related schemas updated (if applicable)

### Additional Context:

**Relationship to existing concepts:**

| Concept | Purpose | How Views differ |
|---|---|---|
| **Flows** | Named sequences of transitions across relationships | A flow is a runtime path; a view may *include* a flow but also include standalone nodes, controls, etc. |
| **Decorators** | Cross-cutting supplementary data (deployment, security) | Decorators carry the data; views selectively surface it for a particular audience |
| **Controls** | Governance and compliance requirements | Controls define *rules*; views may filter by controls but are about *visibility* |
| **Widget focus options** | Tooling-level render-time filtering | Views formalise these as a schema concept — named, described, audience-tagged, and versionable |
| **C4 zoom levels** | Hierarchical abstraction (context/container/component) | C4 levels filter by *node type hierarchy*; views filter by *intent* — they are complementary |

**Why not just use docify templates?**
Templates are a rendering mechanism. They answer "how to display". Views answer "what to display and for whom". A single view can be rendered by multiple templates (a Mermaid diagram, a table, a prose summary). Separating the concern keeps both concepts clean.

**How do views relate to decorators?**
Decorators carry rich supplementary data — deployment status, security posture, cost attribution — but today there is no way to selectively surface that data for a particular audience. Views solve this by letting you specify which decorators to include. A Deployment View pulls in deployment decorators so platform engineers see rollout status overlaid on the topology. A Logical View omits them entirely. The decorator data already exists; views control when and where it appears.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.