Skip to content

Commit 3764208

Browse files
Merge pull request #2189 from jimthompson5802/pattern-concept-write-up
Pattern concept write up
2 parents 5fb3295 + 35d4e5c commit 3764208

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
id: patterns
3+
title: Patterns
4+
sidebar_position: 9
5+
---
6+
7+
# Patterns in CALM
8+
9+
**Patterns** in CALM define **reusable architecture templates** that can be used to **generate** new architecture scaffolds and **validate** that existing architectures conform to a required structure. This “generate + validate” dual use is a key mechanism for reuse and governance across teams.
10+
11+
12+
## What is a Pattern?
13+
14+
Patterns describe architecture blueprints. Instead of listing a fixed set of components, a pattern prescribes:
15+
* Which nodes (e.g., services, systems, databases) must exist.
16+
* Which relationships connect those nodes.
17+
* What constraints or choices are required for those nodes and relationships.
18+
* Which fields are structural (governed by the pattern) versus which are descriptive (left for implementation).
19+
20+
Because they’re expressed in JSON Schema, patterns use familiar constraints such as:
21+
* const to enforce fixed values that identify required elements,
22+
* `prefixItems` and `minItems`/`maxItems` to require specific arrays of elements, and
23+
* `oneOf` / `anyOf` to offer allowable alternatives (e.g., different database options).
24+
25+
This schema-based definition makes patterns self-validating, versionable, and compatible with existing tooling.
26+
27+
## Key Properties of Patterns
28+
29+
Patterns are primarily about **structural intent**—what must exist and how it must connect:
30+
31+
* **Structural identifiers (fixed)**: commonly constrained with `const` (e.g., node `unique-id`, `node-type`, relationship `unique-id`, sometimes `name`).
32+
* **User-authored fields (open but required)**: fields like `description` are typically left as `"type": "string"` (and may be required), so generated architectures include placeholders that users should replace.
33+
* **Required arrays of components**: `prefixItems` + `minItems`/`maxItems` are commonly used to require a specific set/count of nodes and relationships.
34+
* **Choices**: `anyOf`/`oneOf` can model “pick one of these components/topologies” patterns.
35+
36+
## Example pattern template
37+
38+
Below is a small **3-tier web application** pattern template (frontend → API → database) that enforces **exactly 3 nodes** and **exactly 2 relationships**, while leaving `description` user-fillable.
39+
40+
```json
41+
{
42+
"$schema": "https://calm.finos.org/release/1.2/meta/calm.json",
43+
"$id": "https://example.com/patterns/web-app-pattern.json",
44+
"title": "Web Application Pattern",
45+
"description": "A reusable 3-tier web application pattern (frontend, API service, database).",
46+
"type": "object",
47+
"properties": {
48+
"nodes": {
49+
"type": "array",
50+
"minItems": 3,
51+
"maxItems": 3,
52+
"prefixItems": [
53+
{
54+
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/node",
55+
"type": "object",
56+
"properties": {
57+
"unique-id": { "const": "web-frontend" },
58+
"node-type": { "const": "webclient" },
59+
"name": { "const": "Web Frontend" },
60+
"description": { "type": "string" }
61+
},
62+
"required": ["description"]
63+
},
64+
{
65+
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/node",
66+
"type": "object",
67+
"properties": {
68+
"unique-id": { "const": "api-service" },
69+
"node-type": { "const": "service" },
70+
"name": { "const": "API Service" },
71+
"description": { "type": "string" }
72+
},
73+
"required": ["description"]
74+
},
75+
{
76+
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/node",
77+
"type": "object",
78+
"properties": {
79+
"unique-id": { "const": "app-database" },
80+
"node-type": { "const": "database" },
81+
"name": { "const": "Application Database" },
82+
"description": { "type": "string" }
83+
},
84+
"required": ["description"]
85+
}
86+
]
87+
},
88+
"relationships": {
89+
"type": "array",
90+
"minItems": 2,
91+
"maxItems": 2,
92+
"prefixItems": [
93+
{
94+
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/relationship",
95+
"type": "object",
96+
"properties": {
97+
"unique-id": { "const": "frontend-to-api" },
98+
"description": { "type": "string" },
99+
"protocol": { "const": "HTTPS" },
100+
"relationship-type": {
101+
"const": {
102+
"connects": {
103+
"source": { "node": "web-frontend" },
104+
"destination": { "node": "api-service" }
105+
}
106+
}
107+
}
108+
},
109+
"required": ["description"]
110+
},
111+
{
112+
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/relationship",
113+
"type": "object",
114+
"properties": {
115+
"unique-id": { "const": "api-to-database" },
116+
"description": { "type": "string" },
117+
"protocol": { "const": "JDBC" },
118+
"relationship-type": {
119+
"const": {
120+
"connects": {
121+
"source": { "node": "api-service" },
122+
"destination": { "node": "app-database" }
123+
}
124+
}
125+
}
126+
},
127+
"required": ["description"]
128+
}
129+
]
130+
}
131+
},
132+
"required": ["nodes", "relationships"]
133+
}
134+
```
135+
136+
This template follows the same techniques shown in the CALM Patterns guidance: use `const` for structural identity and `prefixItems`/`minItems`/`maxItems` to require exact architecture shape, while keeping human-authored fields open but required.
137+
138+
## Using Patterns effectively
139+
140+
### Generate an architecture scaffold
141+
142+
```bash
143+
calm generate -p patterns/web-app-pattern.json -o architectures/generated-webapp.json
144+
```
145+
146+
This creates a concrete architecture that conforms to the pattern’s constraints.
147+
148+
### Validate an existing architecture against the pattern
149+
150+
```bash
151+
calm validate -p patterns/web-app-pattern.json -a architectures/existing-webapp.json
152+
```
153+
154+
This checks whether the target architecture has the required nodes/relationships and respects the pattern’s constraints.
155+
156+
### Watch for placeholders
157+
158+
User-fillable properties are emitted into the generated architecture using placeholder values based on their declared data type:
159+
160+
* String properties use a bracketed token format, e.g., [[ DESCRIPTION ]]
161+
* Integer properties use a sentinel numeric value, e.g., -1
162+
163+
These placeholders act as markers and must be replaced with appropriate architecture-specific values before use.

docs/sidebars.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const sidebars = {
3939
'core-concepts/timelines',
4040
'core-concepts/decorators',
4141
'core-concepts/metadata',
42+
'core-concepts/patterns',
4243
],
4344
},
4445
{

0 commit comments

Comments
 (0)