Architecture decisions: files, diagram references, views and panels
- *.archify-decision files: id (unique, words), title, status, date, elements, diagrams, supersedes, and prose; parsed, merged and link-checked in the model index; diagnostics on the file - diagrams point at decisions with decisions: [...] on the diagram, nodes and edges; stripped before Archify, unknown ids reported, completion, hover and go-to-definition for the ids and for elements/diagrams/ supersedes in decision files - Decisions panel on the main.archify page; Decisions rail panel under a diagram (hover lights up the node or connection); decisions on element cards and in the element dialog; decision view for the file, with a lost-model note outside a model - Archify | New Decision… command and template; editor schemas; the three New Model examples carry decisions; docs, changelog, 0.8.0
This commit is contained in:
1 parent
33ebdd6328
commit
ebf320a023
49 files changed
+1637
-55
No files matched your search
+37
-5
@@ -1,6 +1,8 @@
|
||||
import path from 'node:path';
|
||||
import * as vscode from 'vscode';
|
||||
import { DiagramSource, readDiagramSource } from '../sources/detect';
|
||||
import { ModelProblem, Registry, resolveRefs } from './format';
|
||||
import { DecisionAttachment, ModelProblem, Registry, resolveRefs } from './format';
|
||||
import { effectiveStatus } from './decisions';
|
||||
import { ModelService } from './service';
|
||||
|
||||
/**
|
||||
@@ -18,6 +20,16 @@ export interface PreparedDiagram {
|
||||
links: Map<string, string>;
|
||||
/** Node id → registry description. */
|
||||
descriptions: Map<string, string>;
|
||||
/** Decisions of this diagram for the Decisions rail panel: pointed at by the diagram, or naming it. */
|
||||
decisions: DiagramDecision[];
|
||||
}
|
||||
|
||||
export interface DiagramDecision {
|
||||
id: string;
|
||||
title?: string;
|
||||
status: string;
|
||||
file: string;
|
||||
attachedTo: DecisionAttachment[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,12 +40,32 @@ export interface PreparedDiagram {
|
||||
export async function prepareDiagram(models: ModelService, uri: vscode.Uri, text: string): Promise<PreparedDiagram | undefined> {
|
||||
const source = readDiagramSource(text, uri.path);
|
||||
if (!source) return undefined;
|
||||
const found = await models.registryFor(uri);
|
||||
const resolved = resolveRefs(source.diagram, { registry: found?.registry, fileName: uri.path });
|
||||
const index = await models.indexFor(uri);
|
||||
const found = index ? { root: index.root, registry: index.registry } : undefined;
|
||||
const resolved = resolveRefs(source.diagram, { registry: found?.registry, decisions: index ? new Set(index.decisions.decisions.keys()) : undefined, fileName: uri.path });
|
||||
// Only diagrams that use refs (or carry a model block) need the resolved form.
|
||||
const changed = resolved.refs.size > 0 || resolved.problems.length > 0 || 'model' in source.diagram || resolved.links.size > 0;
|
||||
const changed = resolved.refs.size > 0 || resolved.problems.length > 0 || 'model' in source.diagram || resolved.links.size > 0 || resolved.decisionRefs.length > 0;
|
||||
const prepared: DiagramSource = changed
|
||||
? { ...source, diagram: resolved.diagram, json: JSON.stringify(resolved.diagram, null, 2) }
|
||||
: source;
|
||||
return { source: prepared, root: found?.root, registry: found?.registry, problems: resolved.problems, links: resolved.links, descriptions: resolved.descriptions };
|
||||
// Decisions for the rail: the ones this diagram points at, plus the ones that name this diagram.
|
||||
const decisions: DiagramDecision[] = [];
|
||||
if (index) {
|
||||
const rel = path.relative(index.root.fsPath, uri.fsPath).split(path.sep).join('/');
|
||||
const byId = new Map<string, DiagramDecision>();
|
||||
const add = (id: string, attachedTo?: DecisionAttachment) => {
|
||||
const d = index.decisions.decisions.get(id);
|
||||
if (!d) return;
|
||||
let row = byId.get(id);
|
||||
if (!row) {
|
||||
row = { id, title: d.title, status: effectiveStatus(d, index.decisions.decisions).status, file: d.file, attachedTo: [] };
|
||||
byId.set(id, row);
|
||||
decisions.push(row);
|
||||
}
|
||||
if (attachedTo && !row.attachedTo.some((a) => JSON.stringify(a) === JSON.stringify(attachedTo))) row.attachedTo.push(attachedTo);
|
||||
};
|
||||
for (const ref of resolved.decisionRefs) add(ref.id, ref.attachedTo);
|
||||
for (const d of index.decisions.decisions.values()) if (d.diagrams.includes(rel)) add(d.id, { kind: 'diagram' });
|
||||
}
|
||||
return { source: prepared, root: found?.root, registry: found?.registry, problems: resolved.problems, links: resolved.links, descriptions: resolved.descriptions, decisions };
|
||||
}
|
||||
Reference in new issue
Block a user