0.11.0: arc42 and ArchiMate examples; ref in every diagram kind

Six example models next to the three C4 ones: arc42 (Cinema Tickets, IoT
Telemetry, Team Wiki) by section, ArchiMate (Insurance Claims, HR
Onboarding, Logistics Tracking) by layer, each validated with 0 errors and
0 warnings. resolveRefs and the editor schemas now take ref: in workflow
and dataflow nodes, sequence participants and lifecycle states, as the
skill already did. Example tests check each framework's folders.
This commit is contained in:
root-at-skic committed 2026-11-08 22:54:23 +02:00
1 parent f4df6a0834
commit 0745de822a
85 files changed
+2945 -67

No files matched your search

+16 -8
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env node
// Adds the model keys to the editor schemas in schemas/ (the CLI keeps the
// strict originals): `model` on main.archify, `ref` and `diagram` on
// architecture components, and a schema for *.archify-registry files.
// strict originals): `model` on main.archify, `ref` and `diagram` on each
// kind's nodes, and a schema for *.archify-registry files.
// Run after sync-archify.mjs, or on its own after editing this file.
import fs from 'node:fs';
import path from 'node:path';
@@ -28,6 +28,7 @@ const DIAGRAM_LINK = { type: 'string', description: 'Diagram that explains this
const DECISIONS = { type: 'array', items: { type: 'string', minLength: 1 }, description: 'Ids of architecture decisions (*.archify-decision files of the model) this is about. Shown in the Decisions panel under the diagram.' };
const NODE_COLLECTIONS = ['components', 'nodes', 'participants', 'states'];
const EDGE_COLLECTIONS = ['connections', 'edges', 'flows', 'transitions', 'messages'];
const NODE_COLLECTION_OF = { architecture: 'components', workflow: 'nodes', dataflow: 'nodes', sequence: 'participants', lifecycle: 'states' };
for (const file of fs.readdirSync(schemas)) {
if (!/^(architecture|workflow|sequence|dataflow|lifecycle)\.schema\.json$/.test(file)) continue;
@@ -38,13 +39,20 @@ for (const file of fs.readdirSync(schemas)) {
const items = schema.properties[key]?.items;
if (items?.properties) items.properties.decisions = DECISIONS;
}
if (file === 'architecture.schema.json') {
const item = schema.properties.components.items;
item.properties.ref = { type: 'string', pattern: '^[a-zA-Z][a-zA-Z0-9_-]*$', description: 'A shared element from the model’s registry (*.archify-registry). Its type, label, sublabel, brand and sources come from there; the diagram adds pos/size and may override label, sublabel and tag.' };
// The list where each kind keeps its nodes takes `ref` (as the extension's resolver does).
const nodes = NODE_COLLECTION_OF[file.replace('.schema.json', '')];
const item = schema.properties[nodes]?.items;
if (item?.properties) {
item.properties.ref = { type: 'string', pattern: '^[a-zA-Z][a-zA-Z0-9_-]*$', description: 'A shared element from the model’s registry (*.archify-registry). Its type, label, sublabel, brand and sources come from there; the diagram adds its own placement and may override label, sublabel and tag.' };
item.properties.diagram = DIAGRAM_LINK;
// A ref brings type and label with it; an inline component must state them.
item.anyOf = [{ required: ['ref'] }, { required: ['id', 'type', 'label'] }];
delete item.required;
// A ref brings type and label with it; an inline node must state them. Re-runs keep the original list.
const required = item.required ?? item.anyOf?.[1]?.required;
if (required) {
// Placement (lane/col, stage/row) stays the diagram's own; only id, type and label may come from the ref.
const placement = required.filter((key) => !['id', 'type', 'label'].includes(key));
item.anyOf = [{ required: ['ref', ...placement] }, { required }];
delete item.required;
}
}
write(file, schema);
}