Registry as Archify cards on the model page; cards under model diagrams from registry descriptions

- model page: registry elements are rendered as Archify info cards (type
  colour dot, label, id · type, description, used-in chips that open the
  diagram), replacing the table
- resolveRefs: a diagram without cards of its own gets one card per drawn
  shared element that has a description, so the registry text shows under
  every model diagram as it does on hand-written diagrams
- unit tests for generated cards, own cards winning and no cards without
  refs; docs and changelog
This commit is contained in:
2026-10-19 12:53:45 +03:00
parent 57914d435c
commit 38cdc7604f
6 changed files with 102 additions and 17 deletions
+18
View File
@@ -3,6 +3,8 @@ import fs from 'node:fs';
import path from 'node:path';
import { test } from 'node:test';
import {
cardsFromElements,
dotForType,
groupOf,
hasDiagramBody,
isMainFile,
@@ -81,6 +83,22 @@ test('resolve: refs become full components, links and usage are collected', () =
assert.deepEqual([...r.used].sort(), ['api', 'cache', 'customer', 'db', 'queue', 'web', 'worker']);
assert.equal(r.refs.get(2)?.id, 'api');
assert.ok(!('model' in r.diagram));
// Cards from the registry descriptions, in drawing order, one per element.
const cards = r.diagram.cards as { dot: string; title: string; items: string[] }[];
assert.equal(cards.length, 7);
assert.deepEqual(cards[0], { dot: 'slate', title: 'Customer', items: ['Buys products; signs in with email or a social account.'] });
assert.equal(cards.find((c) => c.title === 'API')?.dot, 'emerald');
});
test('resolve: own cards win, no cards without refs or descriptions', () => {
const registry = registryOfModel();
const own = resolveRefs({ components: [{ ref: 'api', pos: [0, 0] }], cards: [{ dot: 'rose', title: 'Mine', items: ['kept'] }] }, { registry, fileName: 'x.archify' });
assert.deepEqual(own.diagram.cards, [{ dot: 'rose', title: 'Mine', items: ['kept'] }]);
const inline = resolveRefs({ components: [{ id: 'a', type: 'backend', label: 'A', pos: [0, 0] }] }, { registry, fileName: 'x.archify' });
assert.ok(!('cards' in inline.diagram));
assert.equal(cardsFromElements([{ id: 'x', type: 'cloud', label: 'X', file: 'r', line: 0 }]).length, 0);
assert.equal(dotForType('messagebus'), 'orange');
assert.equal(dotForType(undefined), 'slate');
});
test('resolve: overrides, second id for the same element, inline elements and links', () => {