@archinsight/cli 3.0.0-snapshot.5 → 3.0.0-snapshot.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/build/index.js +1040 -100
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -57,7 +57,7 @@ var require_archy = __commonJS({
|
|
|
57
57
|
|
|
58
58
|
// src/index.ts
|
|
59
59
|
var import_archy = __toESM(require_archy(), 1);
|
|
60
|
-
import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
60
|
+
import { mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
61
61
|
import path from "node:path";
|
|
62
62
|
import { instance } from "@viz-js/viz";
|
|
63
63
|
|
|
@@ -34184,6 +34184,7 @@ function linkProject(request) {
|
|
|
34184
34184
|
sourceIdentity: edge.sourceName,
|
|
34185
34185
|
fromId: edge.source,
|
|
34186
34186
|
toId: target.id,
|
|
34187
|
+
projectedAttributes: materialized.edge.attributes,
|
|
34187
34188
|
...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
|
|
34188
34189
|
});
|
|
34189
34190
|
pendingProjections.push({
|
|
@@ -34191,6 +34192,7 @@ function linkProject(request) {
|
|
|
34191
34192
|
fromId: edge.source,
|
|
34192
34193
|
toId: target.id,
|
|
34193
34194
|
attributes: edgeAttributes,
|
|
34195
|
+
projectedAttributes: materialized.edge.attributes,
|
|
34194
34196
|
...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
|
|
34195
34197
|
});
|
|
34196
34198
|
}
|
|
@@ -34220,7 +34222,7 @@ function linkProject(request) {
|
|
|
34220
34222
|
});
|
|
34221
34223
|
}
|
|
34222
34224
|
for (const projection of pendingProjections) {
|
|
34223
|
-
addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations);
|
|
34225
|
+
addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations, projection.projectedAttributes);
|
|
34224
34226
|
}
|
|
34225
34227
|
const slotDomainTypes = typeSystem.slotDomainTypes();
|
|
34226
34228
|
for (const element of elements) {
|
|
@@ -35248,7 +35250,14 @@ function resolveAttributes(owner, ownerType, attributes2, referenceAttributePosi
|
|
|
35248
35250
|
});
|
|
35249
35251
|
continue;
|
|
35250
35252
|
}
|
|
35251
|
-
result[name] = [...result[name] ?? [], {
|
|
35253
|
+
result[name] = [...result[name] ?? [], {
|
|
35254
|
+
id: resolved.id,
|
|
35255
|
+
element: resolved,
|
|
35256
|
+
line: value.line,
|
|
35257
|
+
column: value.column,
|
|
35258
|
+
...value.endLine === void 0 ? {} : { endLine: value.endLine },
|
|
35259
|
+
...value.endColumn === void 0 ? {} : { endColumn: value.endColumn }
|
|
35260
|
+
}];
|
|
35252
35261
|
}
|
|
35253
35262
|
}
|
|
35254
35263
|
return result;
|
|
@@ -35284,7 +35293,7 @@ function flattenAttributes(scalarAttributes, attributes2) {
|
|
|
35284
35293
|
...Object.fromEntries(Object.entries(attributes2).map(([name, values]) => [name, values.map((value) => value.id)]))
|
|
35285
35294
|
};
|
|
35286
35295
|
}
|
|
35287
|
-
function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes2, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], visitedProjectionElements = /* @__PURE__ */ new Set()) {
|
|
35296
|
+
function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes2, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, visitedProjectionElements = /* @__PURE__ */ new Set()) {
|
|
35288
35297
|
for (const values of Object.values(attributes2)) {
|
|
35289
35298
|
for (const value of values) {
|
|
35290
35299
|
if (value.element === void 0) {
|
|
@@ -35301,8 +35310,24 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
|
|
|
35301
35310
|
if (isDirectSlotReferenceSelfProjection(value.element, fromId, toId)) {
|
|
35302
35311
|
continue;
|
|
35303
35312
|
}
|
|
35304
|
-
|
|
35305
|
-
|
|
35313
|
+
const rules = typeSystem.projectionRules(value.element.type);
|
|
35314
|
+
if (fromId === toId && rules.some(projectionRuleUsesTo)) {
|
|
35315
|
+
const position3 = value.line === void 0 || value.column === void 0 ? value.element : {
|
|
35316
|
+
line: value.line,
|
|
35317
|
+
column: value.column,
|
|
35318
|
+
...value.endLine === void 0 ? {} : { endLine: value.endLine },
|
|
35319
|
+
...value.endColumn === void 0 ? {} : { endColumn: value.endColumn }
|
|
35320
|
+
};
|
|
35321
|
+
diagnostics.push({
|
|
35322
|
+
code: "PROJECTION_TARGET_REQUIRED",
|
|
35323
|
+
message: `Projection for '${value.element.type}' uses '$to' and must be attached to a relationship, not to element '${fromId}'`,
|
|
35324
|
+
sourceName: sourceIdentity,
|
|
35325
|
+
...diagnosticPosition2(position3)
|
|
35326
|
+
});
|
|
35327
|
+
continue;
|
|
35328
|
+
}
|
|
35329
|
+
for (const rule3 of rules) {
|
|
35330
|
+
addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2, projectedAttributes);
|
|
35306
35331
|
}
|
|
35307
35332
|
addProjectedEdges(
|
|
35308
35333
|
linkedEdges,
|
|
@@ -35317,12 +35342,13 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
|
|
|
35317
35342
|
diagnostics,
|
|
35318
35343
|
projectionScope,
|
|
35319
35344
|
annotations2,
|
|
35345
|
+
void 0,
|
|
35320
35346
|
visitedProjectionElements
|
|
35321
35347
|
);
|
|
35322
35348
|
}
|
|
35323
35349
|
}
|
|
35324
35350
|
}
|
|
35325
|
-
function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, values, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = []) {
|
|
35351
|
+
function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, values, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes) {
|
|
35326
35352
|
addProjectedEdges(
|
|
35327
35353
|
linkedEdges,
|
|
35328
35354
|
sourceIdentity,
|
|
@@ -35335,7 +35361,8 @@ function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, v
|
|
|
35335
35361
|
typeSystem,
|
|
35336
35362
|
diagnostics,
|
|
35337
35363
|
projectionScope,
|
|
35338
|
-
annotations2
|
|
35364
|
+
annotations2,
|
|
35365
|
+
projectedAttributes
|
|
35339
35366
|
);
|
|
35340
35367
|
}
|
|
35341
35368
|
function addEdgeScopes(scopesByCarrierId, attributes2, scope) {
|
|
@@ -35352,15 +35379,16 @@ function addEdgeScopes(scopesByCarrierId, attributes2, scope) {
|
|
|
35352
35379
|
function isDirectSlotReferenceSelfProjection(element, fromId, toId) {
|
|
35353
35380
|
return fromId === toId && element.parent === fromId && element.scalarAttributes.parentType !== void 0 && element.scalarAttributes.attributeName !== void 0;
|
|
35354
35381
|
}
|
|
35355
|
-
function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = []) {
|
|
35382
|
+
function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes) {
|
|
35356
35383
|
const sources = projectionTerm(rule3.source, fromId, toId, projectionElement, elementsById, resolvedElementAttributes, diagnostics);
|
|
35357
35384
|
const targets = projectionTerm(rule3.target, fromId, toId, projectionElement, elementsById, resolvedElementAttributes, diagnostics);
|
|
35385
|
+
const carriedAttributes = rule3.source.kind === "from" ? projectedAttributes : void 0;
|
|
35358
35386
|
for (const source of sources) {
|
|
35359
35387
|
for (const target of targets) {
|
|
35360
35388
|
if (!projectionRuleUsesOwner(rule3)) {
|
|
35361
35389
|
const key = `${projectionElement.id}\0${source}\0${rule3.operator}\0${target}`;
|
|
35362
35390
|
if (ownerIndependentProjectionKeys.has(key)) {
|
|
35363
|
-
|
|
35391
|
+
mergeProjectedEdge(linkedEdges, source, rule3.operator, target, annotations2, carriedAttributes);
|
|
35364
35392
|
continue;
|
|
35365
35393
|
}
|
|
35366
35394
|
ownerIndependentProjectionKeys.add(key);
|
|
@@ -35375,6 +35403,7 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
|
|
|
35375
35403
|
if (edge !== void 0) {
|
|
35376
35404
|
linkedEdges[existingIndex] = {
|
|
35377
35405
|
...edge,
|
|
35406
|
+
attributes: mergeAttributeValues(carriedAttributes, edge.attributes),
|
|
35378
35407
|
annotations: uniqueAnnotations([...edge.annotations ?? [], ...annotations2])
|
|
35379
35408
|
};
|
|
35380
35409
|
}
|
|
@@ -35388,7 +35417,7 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
|
|
|
35388
35417
|
operator: rule3.operator,
|
|
35389
35418
|
type,
|
|
35390
35419
|
sourceIdentity,
|
|
35391
|
-
attributes: {},
|
|
35420
|
+
attributes: carriedAttributes ?? {},
|
|
35392
35421
|
...listAttributesProperty(typeSystem, type),
|
|
35393
35422
|
projected: true,
|
|
35394
35423
|
...projectionScope === void 0 ? {} : { projectionScope },
|
|
@@ -35397,8 +35426,8 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
|
|
|
35397
35426
|
}
|
|
35398
35427
|
}
|
|
35399
35428
|
}
|
|
35400
|
-
function
|
|
35401
|
-
if (annotations2.length === 0) {
|
|
35429
|
+
function mergeProjectedEdge(linkedEdges, source, operator, target, annotations2, attributes2) {
|
|
35430
|
+
if (annotations2.length === 0 && (attributes2 === void 0 || Object.keys(attributes2).length === 0)) {
|
|
35402
35431
|
return;
|
|
35403
35432
|
}
|
|
35404
35433
|
const index = linkedEdges.findIndex((edge2) => edge2.projected === true && edge2.source === source && edge2.operator === operator && edge2.target === target);
|
|
@@ -35411,9 +35440,19 @@ function mergeProjectedEdgeAnnotations(linkedEdges, source, operator, target, an
|
|
|
35411
35440
|
}
|
|
35412
35441
|
linkedEdges[index] = {
|
|
35413
35442
|
...edge,
|
|
35443
|
+
attributes: mergeAttributeValues(attributes2, edge.attributes),
|
|
35414
35444
|
annotations: uniqueAnnotations([...edge.annotations ?? [], ...annotations2])
|
|
35415
35445
|
};
|
|
35416
35446
|
}
|
|
35447
|
+
function mergeAttributeValues(base, override) {
|
|
35448
|
+
if (base === void 0 || Object.keys(base).length === 0) {
|
|
35449
|
+
return override;
|
|
35450
|
+
}
|
|
35451
|
+
if (Object.keys(override).length === 0) {
|
|
35452
|
+
return base;
|
|
35453
|
+
}
|
|
35454
|
+
return { ...base, ...override };
|
|
35455
|
+
}
|
|
35417
35456
|
function uniqueAnnotations(annotations2) {
|
|
35418
35457
|
const seen = /* @__PURE__ */ new Set();
|
|
35419
35458
|
const result = [];
|
|
@@ -35438,6 +35477,12 @@ function referenceAttributesProperty(attributes2) {
|
|
|
35438
35477
|
function projectionRuleUsesOwner(rule3) {
|
|
35439
35478
|
return projectionTermUsesOwner(rule3.source) || projectionTermUsesOwner(rule3.target);
|
|
35440
35479
|
}
|
|
35480
|
+
function projectionRuleUsesTo(rule3) {
|
|
35481
|
+
return projectionTermUsesTo(rule3.source) || projectionTermUsesTo(rule3.target);
|
|
35482
|
+
}
|
|
35483
|
+
function projectionTermUsesTo(term) {
|
|
35484
|
+
return term.kind === "to";
|
|
35485
|
+
}
|
|
35441
35486
|
function projectionTermUsesOwner(term) {
|
|
35442
35487
|
return term.kind === "from" || term.kind === "to" || term.kind === "slot";
|
|
35443
35488
|
}
|
|
@@ -36029,7 +36074,8 @@ function applyDeploymentUsesCarrier(carrier, parent, context) {
|
|
|
36029
36074
|
context.typeSystem,
|
|
36030
36075
|
context.diagnostics,
|
|
36031
36076
|
projectionScope,
|
|
36032
|
-
annotations2
|
|
36077
|
+
annotations2,
|
|
36078
|
+
scope.projectedAttributes
|
|
36033
36079
|
);
|
|
36034
36080
|
}
|
|
36035
36081
|
}
|
|
@@ -37802,7 +37848,7 @@ var QueryParser = class {
|
|
|
37802
37848
|
};
|
|
37803
37849
|
|
|
37804
37850
|
// src/version.ts
|
|
37805
|
-
var version = "3.0.0-snapshot.
|
|
37851
|
+
var version = "3.0.0-snapshot.7";
|
|
37806
37852
|
|
|
37807
37853
|
// src/index.ts
|
|
37808
37854
|
var hiddenStructureTypes = /* @__PURE__ */ new Set(["List", "Nothing", "Text", "text"]);
|
|
@@ -37995,11 +38041,24 @@ async function runSkillInit(args, skillPackage) {
|
|
|
37995
38041
|
const projectRoot = path.resolve(projectPath(args));
|
|
37996
38042
|
const usesDefaultOutput = args.output === void 0;
|
|
37997
38043
|
const outputRoot = path.resolve(projectRoot, args.output ?? skillPackage.defaultOutput);
|
|
38044
|
+
if (args.force && await exists(outputRoot)) {
|
|
38045
|
+
assertSafeSkillOutputRoot(projectRoot, outputRoot);
|
|
38046
|
+
await rm(outputRoot, { recursive: true, force: true });
|
|
38047
|
+
}
|
|
37998
38048
|
for (const file of skillPackage.files) {
|
|
37999
38049
|
await writeGeneratedFile(path.join(outputRoot, file.path), file.content, args.force);
|
|
38000
38050
|
}
|
|
38001
38051
|
process.stdout.write(skillPackageSuccess(projectRoot, outputRoot, skillPackage, usesDefaultOutput));
|
|
38002
38052
|
}
|
|
38053
|
+
function assertSafeSkillOutputRoot(projectRoot, outputRoot) {
|
|
38054
|
+
if (outputRoot === path.parse(outputRoot).root || outputRoot === process.cwd() || outputRoot === projectRoot) {
|
|
38055
|
+
throw new CliError(`Refusing to delete unsafe skill output directory '${outputRoot}'. Choose a dedicated --out directory.`);
|
|
38056
|
+
}
|
|
38057
|
+
const projectRelativeToOutput = path.relative(outputRoot, projectRoot);
|
|
38058
|
+
if (projectRelativeToOutput !== "" && !projectRelativeToOutput.startsWith("..") && !path.isAbsolute(projectRelativeToOutput)) {
|
|
38059
|
+
throw new CliError(`Refusing to delete skill output directory '${outputRoot}' because it contains the project root.`);
|
|
38060
|
+
}
|
|
38061
|
+
}
|
|
38003
38062
|
async function loadProject(input) {
|
|
38004
38063
|
const root = path.resolve(input);
|
|
38005
38064
|
const sources = await readSources(root);
|
|
@@ -38452,7 +38511,7 @@ Options:
|
|
|
38452
38511
|
-o, --out <file> Write output to file instead of stdout; for skill init, write the guide directory.
|
|
38453
38512
|
-t, --theme <theme> Render theme, default: light.
|
|
38454
38513
|
--target <target> Skill target: generic, codex, or claude.
|
|
38455
|
-
--force
|
|
38514
|
+
--force Delete and recreate the generated skill directory.
|
|
38456
38515
|
-V, --version Print version.
|
|
38457
38516
|
-h, --help Show help.
|
|
38458
38517
|
|
|
@@ -38539,6 +38598,10 @@ function sharedSkillFiles() {
|
|
|
38539
38598
|
path: "references/c4-deployment.md",
|
|
38540
38599
|
content: genericC4DeploymentReference()
|
|
38541
38600
|
},
|
|
38601
|
+
{
|
|
38602
|
+
path: "references/scaling.md",
|
|
38603
|
+
content: genericScalingReference()
|
|
38604
|
+
},
|
|
38542
38605
|
{
|
|
38543
38606
|
path: "references/project-structure.md",
|
|
38544
38607
|
content: genericProjectStructureReference()
|
|
@@ -38555,6 +38618,10 @@ function sharedSkillFiles() {
|
|
|
38555
38618
|
path: "references/queries.md",
|
|
38556
38619
|
content: genericQueriesReference()
|
|
38557
38620
|
},
|
|
38621
|
+
{
|
|
38622
|
+
path: "references/query-recipes.md",
|
|
38623
|
+
content: genericQueryRecipesReference()
|
|
38624
|
+
},
|
|
38558
38625
|
{
|
|
38559
38626
|
path: "examples/layered-architecture.ai",
|
|
38560
38627
|
content: genericLayeredArchitectureExample()
|
|
@@ -38583,6 +38650,26 @@ function sharedSkillFiles() {
|
|
|
38583
38650
|
path: "examples/c2-containers.aiq",
|
|
38584
38651
|
content: genericC2QueryExample()
|
|
38585
38652
|
},
|
|
38653
|
+
{
|
|
38654
|
+
path: "examples/builtin-views/no-filter.aiq",
|
|
38655
|
+
content: noFilterQuery
|
|
38656
|
+
},
|
|
38657
|
+
{
|
|
38658
|
+
path: "examples/builtin-views/c1.aiq",
|
|
38659
|
+
content: c1Query
|
|
38660
|
+
},
|
|
38661
|
+
{
|
|
38662
|
+
path: "examples/builtin-views/c2.aiq",
|
|
38663
|
+
content: c2Query
|
|
38664
|
+
},
|
|
38665
|
+
{
|
|
38666
|
+
path: "examples/builtin-views/c3.aiq",
|
|
38667
|
+
content: c3Query
|
|
38668
|
+
},
|
|
38669
|
+
{
|
|
38670
|
+
path: "examples/builtin-views/c4.aiq",
|
|
38671
|
+
content: c4Query
|
|
38672
|
+
},
|
|
38586
38673
|
...coreSkillFiles()
|
|
38587
38674
|
];
|
|
38588
38675
|
}
|
|
@@ -38645,8 +38732,18 @@ If \`archinsight\` is not available, ask the user to install or expose
|
|
|
38645
38732
|
2. Preserve indentation and the project's existing naming style.
|
|
38646
38733
|
3. Model architecture from the outside inward: context, external actors/systems,
|
|
38647
38734
|
systems, containers/services, components, and deployment details.
|
|
38648
|
-
4.
|
|
38649
|
-
|
|
38735
|
+
4. Do not ask about deployment depth until the task touches infrastructure,
|
|
38736
|
+
runtime placement, regions, brokers, gateways, storage, or deployment.
|
|
38737
|
+
5. At that point, decide per system whether pragmatic mixed C2 or clean
|
|
38738
|
+
C4/deployment is appropriate. If modeling clean C4: attach placement/storage
|
|
38739
|
+
to elements, attach path infrastructure that needs \`$to\` to wires, and make
|
|
38740
|
+
pub/sub dependencies consumer-owned.
|
|
38741
|
+
6. If a diagram becomes noisy, adjust scope/query before changing a correct
|
|
38742
|
+
graph model.
|
|
38743
|
+
7. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
|
|
38744
|
+
8. Keep definition/framework files separate from model files that declare
|
|
38745
|
+
\`context <id>\`.
|
|
38746
|
+
9. Validate every Insight change with \`archinsight link . --format text\`.
|
|
38650
38747
|
|
|
38651
38748
|
## References
|
|
38652
38749
|
|
|
@@ -38664,12 +38761,16 @@ If \`archinsight\` is not available, ask the user to install or expose
|
|
|
38664
38761
|
- Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
|
|
38665
38762
|
models, infrastructure inventories, environment-scoped infrastructure, or
|
|
38666
38763
|
projection rules.
|
|
38764
|
+
- Read \`references/scaling.md\` when splitting a repository into reusable
|
|
38765
|
+
framework, environment, profile, system, or deployment-view files.
|
|
38667
38766
|
- Read \`references/project-structure.md\` before searching for declarations,
|
|
38668
38767
|
planning imports, or making broad edits.
|
|
38669
38768
|
- Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
|
|
38670
38769
|
attributes, presentations, or projections.
|
|
38671
38770
|
- Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
|
|
38672
38771
|
files.
|
|
38772
|
+
- Read \`references/query-recipes.md\` when a built-in view hides an expected
|
|
38773
|
+
element/edge or needs customization.
|
|
38673
38774
|
- Read \`references/validation.md\` before running checks, structure inspection,
|
|
38674
38775
|
or rendering.
|
|
38675
38776
|
- Use \`examples/layered-architecture.ai\` as a compact valid model.
|
|
@@ -38706,12 +38807,16 @@ Treat this \`SKILL.md\` as the entrypoint. Load reference files only when needed
|
|
|
38706
38807
|
- Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
|
|
38707
38808
|
models, infrastructure inventories, environment-scoped infrastructure, or
|
|
38708
38809
|
projection rules.
|
|
38810
|
+
- Read \`references/scaling.md\` before splitting a repository into reusable
|
|
38811
|
+
framework, environment, profile, system, or deployment-view files.
|
|
38709
38812
|
- Read \`references/project-structure.md\` before searching for declarations,
|
|
38710
38813
|
planning imports, or making broad edits.
|
|
38711
38814
|
- Read \`references/core.md\` and \`.core/*.ai\` before assuming available
|
|
38712
38815
|
constructors, attributes, presentations, or projections.
|
|
38713
38816
|
- Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
|
|
38714
38817
|
files.
|
|
38818
|
+
- Read \`references/query-recipes.md\` before customizing a built-in view or
|
|
38819
|
+
explaining why an expected element/edge is hidden.
|
|
38715
38820
|
- Read \`references/validation.md\` before running checks, structure inspection,
|
|
38716
38821
|
or rendering commands.
|
|
38717
38822
|
|
|
@@ -38738,11 +38843,21 @@ If \`archinsight\` is not available, ask the user to install or expose
|
|
|
38738
38843
|
2. Preserve indentation and the project's existing naming style.
|
|
38739
38844
|
3. Model architecture from the outside inward: context, external actors/systems,
|
|
38740
38845
|
systems, containers/services, components, and deployment details.
|
|
38741
|
-
4.
|
|
38742
|
-
|
|
38846
|
+
4. Do not ask about deployment depth until the task touches infrastructure,
|
|
38847
|
+
runtime placement, regions, brokers, gateways, storage, or deployment.
|
|
38848
|
+
5. At that point, decide per system whether pragmatic mixed C2 or clean
|
|
38849
|
+
C4/deployment is appropriate. If modeling clean C4: attach placement/storage
|
|
38850
|
+
to elements, attach path infrastructure that needs \`$to\` to wires, and make
|
|
38851
|
+
pub/sub dependencies consumer-owned.
|
|
38852
|
+
6. If a diagram becomes noisy, adjust scope/query before changing a correct
|
|
38853
|
+
graph model.
|
|
38854
|
+
7. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
|
|
38855
|
+
8. Keep definition/framework files separate from model files that declare
|
|
38856
|
+
\`context <id>\`.
|
|
38857
|
+
9. Use \`archinsight structure . --format text\` before broad edits when the
|
|
38743
38858
|
project shape is unclear.
|
|
38744
|
-
|
|
38745
|
-
|
|
38859
|
+
10. Validate every Insight change with \`archinsight link . --format text\`.
|
|
38860
|
+
11. If validation fails, fix the first real syntax/type/linking error before
|
|
38746
38861
|
adding more model content.
|
|
38747
38862
|
|
|
38748
38863
|
## References
|
|
@@ -38761,12 +38876,16 @@ If \`archinsight\` is not available, ask the user to install or expose
|
|
|
38761
38876
|
- Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
|
|
38762
38877
|
models, infrastructure inventories, environment-scoped infrastructure, or
|
|
38763
38878
|
projection rules.
|
|
38879
|
+
- Read \`references/scaling.md\` when splitting a repository into reusable
|
|
38880
|
+
framework, environment, profile, system, or deployment-view files.
|
|
38764
38881
|
- Read \`references/project-structure.md\` before searching for declarations,
|
|
38765
38882
|
planning imports, or making broad edits.
|
|
38766
38883
|
- Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
|
|
38767
38884
|
attributes, presentations, or projections.
|
|
38768
38885
|
- Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
|
|
38769
38886
|
files.
|
|
38887
|
+
- Read \`references/query-recipes.md\` when a built-in view hides an expected
|
|
38888
|
+
element/edge or needs customization.
|
|
38770
38889
|
- Read \`references/validation.md\` before running checks, structure inspection,
|
|
38771
38890
|
or rendering.
|
|
38772
38891
|
- Use \`examples/layered-architecture.ai\` as a compact valid model.
|
|
@@ -38804,12 +38923,16 @@ they are needed:
|
|
|
38804
38923
|
- Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
|
|
38805
38924
|
models, infrastructure inventories, environment-scoped infrastructure, or
|
|
38806
38925
|
projection rules.
|
|
38926
|
+
- Read \`references/scaling.md\` before splitting a repository into reusable
|
|
38927
|
+
framework, environment, profile, system, or deployment-view files.
|
|
38807
38928
|
- Read \`references/project-structure.md\` before searching for declarations,
|
|
38808
38929
|
planning imports, or making broad edits.
|
|
38809
38930
|
- Read \`references/core.md\` and \`.core/*.ai\` before assuming available
|
|
38810
38931
|
constructors, attributes, presentations, or projections.
|
|
38811
38932
|
- Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
|
|
38812
38933
|
files.
|
|
38934
|
+
- Read \`references/query-recipes.md\` before customizing a built-in view or
|
|
38935
|
+
explaining why an expected element/edge is hidden.
|
|
38813
38936
|
- Read \`references/validation.md\` before asking the user to run validation,
|
|
38814
38937
|
structure inspection, or rendering commands.
|
|
38815
38938
|
|
|
@@ -38836,12 +38959,22 @@ install or expose \`@archinsight/cli\` before changing \`.ai\` files.
|
|
|
38836
38959
|
2. Preserve indentation and the project's existing naming style.
|
|
38837
38960
|
3. Model architecture from the outside inward: context, external actors/systems,
|
|
38838
38961
|
systems, containers/services, components, and deployment details.
|
|
38839
|
-
4.
|
|
38840
|
-
|
|
38962
|
+
4. Do not ask about deployment depth until the task touches infrastructure,
|
|
38963
|
+
runtime placement, regions, brokers, gateways, storage, or deployment.
|
|
38964
|
+
5. At that point, decide per system whether pragmatic mixed C2 or clean
|
|
38965
|
+
C4/deployment is appropriate. If modeling clean C4: attach placement/storage
|
|
38966
|
+
to elements, attach path infrastructure that needs \`$to\` to wires, and make
|
|
38967
|
+
pub/sub dependencies consumer-owned.
|
|
38968
|
+
6. If a diagram becomes noisy, adjust scope/query before changing a correct
|
|
38969
|
+
graph model.
|
|
38970
|
+
7. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
|
|
38971
|
+
8. Keep definition/framework files separate from model files that declare
|
|
38972
|
+
\`context <id>\`.
|
|
38973
|
+
9. Use \`archinsight structure . --format text\` to inspect the current model
|
|
38841
38974
|
before broad edits when the CLI is available.
|
|
38842
|
-
|
|
38975
|
+
10. Validate every Insight change with \`archinsight link . --format text\` when
|
|
38843
38976
|
shell access is available; otherwise ask the user to run validation.
|
|
38844
|
-
|
|
38977
|
+
11. If validation fails, fix the first real syntax/type/linking error before
|
|
38845
38978
|
adding more model content.
|
|
38846
38979
|
|
|
38847
38980
|
## Communication
|
|
@@ -38879,12 +39012,16 @@ sections of Insight unless the existing layering is already understood.
|
|
|
38879
39012
|
- Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
|
|
38880
39013
|
models, infrastructure inventories, environment-scoped infrastructure, or
|
|
38881
39014
|
projection rules.
|
|
39015
|
+
- Read \`references/scaling.md\` when splitting a repository into reusable
|
|
39016
|
+
framework, environment, profile, system, or deployment-view files.
|
|
38882
39017
|
- Read \`references/project-structure.md\` before searching for declarations,
|
|
38883
39018
|
planning imports, or making broad edits.
|
|
38884
39019
|
- Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
|
|
38885
39020
|
attributes, presentations, or projections.
|
|
38886
39021
|
- Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
|
|
38887
39022
|
files.
|
|
39023
|
+
- Read \`references/query-recipes.md\` when a built-in view hides an expected
|
|
39024
|
+
element/edge or needs customization.
|
|
38888
39025
|
- Read \`references/validation.md\` before running checks, structure inspection,
|
|
38889
39026
|
or rendering.
|
|
38890
39027
|
- Use \`examples/layered-architecture.ai\` as a compact valid model.
|
|
@@ -38906,6 +39043,40 @@ function genericModelingReference() {
|
|
|
38906
39043
|
Insight syntax is small; most mistakes are modeling mistakes. Decide the view
|
|
38907
39044
|
question before changing files.
|
|
38908
39045
|
|
|
39046
|
+
## Separate Definitions From Model Sources
|
|
39047
|
+
|
|
39048
|
+
Keep language/framework definitions separate from graph model files.
|
|
39049
|
+
|
|
39050
|
+
- Definition/framework files contain \`define type\`, \`define operator\`,
|
|
39051
|
+
\`define presentation\`, \`extend type\`, \`extend enum of\`, and
|
|
39052
|
+
\`extend presentation\`.
|
|
39053
|
+
- Model files declare \`context <id>\` and create graph objects with
|
|
39054
|
+
constructors such as \`system\`, \`service\`, \`component\`, \`environment\`,
|
|
39055
|
+
or \`deploymentProfile\`.
|
|
39056
|
+
|
|
39057
|
+
Do not mix definition declarations and \`context\` declarations in one source
|
|
39058
|
+
file. Put shared vocabulary in a framework file, then put concrete contexts,
|
|
39059
|
+
systems, environments, profiles, and links in model files. This keeps schema
|
|
39060
|
+
changes reviewable and avoids source-level syntax failures.
|
|
39061
|
+
|
|
39062
|
+
## Model Source Granularity
|
|
39063
|
+
|
|
39064
|
+
Default to one primary owned system per model source file: the system you are
|
|
39065
|
+
about to detail with containers, services, components, and deployment
|
|
39066
|
+
relationships. This keeps the selected source file useful as a C2/C3/C4 view
|
|
39067
|
+
scope and avoids accidental mega-files.
|
|
39068
|
+
|
|
39069
|
+
Do not create one file per external actor or external system. Shared external
|
|
39070
|
+
dependencies are usually better modeled once in a reusable external context, or
|
|
39071
|
+
in a few external contexts grouped by meaning such as \`external_platforms\`,
|
|
39072
|
+
\`partners\`, or \`regulators\`. Import those shared declarations from system
|
|
39073
|
+
files that need them.
|
|
39074
|
+
|
|
39075
|
+
If a user asks for deeper splitting, use \`extend <object>\` files for the
|
|
39076
|
+
detail being extracted. For example, keep the main service file readable and put
|
|
39077
|
+
large per-service component sets in a small utility subdirectory for that
|
|
39078
|
+
context.
|
|
39079
|
+
|
|
38909
39080
|
## Projections Are Bottom-Up
|
|
38910
39081
|
|
|
38911
39082
|
Built-in C1/C2/C3/C4 views are selected from the linked model. They are not
|
|
@@ -38969,23 +39140,50 @@ type hierarchy:
|
|
|
38969
39140
|
If a nested declaration fails type checking, fix the type/ownership model rather
|
|
38970
39141
|
than forcing a link or inventing a wrapper element.
|
|
38971
39142
|
|
|
38972
|
-
##
|
|
39143
|
+
## Choose Infrastructure Depth Per System
|
|
39144
|
+
|
|
39145
|
+
Do not force every project into C4/deployment on the first pass. Most modeling
|
|
39146
|
+
work can proceed through C1-C3 without asking about deployment depth. When the
|
|
39147
|
+
task first touches infrastructure, runtime placement, regions, compute, brokers,
|
|
39148
|
+
gateways, storage, or deployment, ask the user or infer from the repository
|
|
39149
|
+
whether the affected system needs a pragmatic mixed C2 view or a clean
|
|
39150
|
+
C4/deployment model.
|
|
39151
|
+
|
|
39152
|
+
Pragmatic mixed C2 is fast: model databases, brokers, gateways, or secret stores
|
|
39153
|
+
next to services when the user wants a quick single-environment diagram. The
|
|
39154
|
+
cost is that C2 now mixes logical containers with infrastructure, and C4 is
|
|
39155
|
+
effectively absent for that system.
|
|
38973
39156
|
|
|
38974
|
-
|
|
38975
|
-
|
|
38976
|
-
|
|
38977
|
-
|
|
39157
|
+
Clean C4 keeps C2 logical and moves physical realization into deployment
|
|
39158
|
+
profiles, environments, inventory slots, and projection rules. This is more work
|
|
39159
|
+
up front, but it supports many-to-many deployment: one logical service can run
|
|
39160
|
+
in several environments whose infrastructure differs by region, provider, or
|
|
39161
|
+
organizational boundary.
|
|
38978
39162
|
|
|
38979
|
-
|
|
39163
|
+
This choice is per-system, not global. A critical system can use clean C4 while
|
|
39164
|
+
peripheral systems stay pragmatic in C2. Starting cheap is acceptable, but know
|
|
39165
|
+
that upgrading mixed C2 infrastructure into clean C4 is a migration, not just an
|
|
39166
|
+
extra attribute.
|
|
38980
39167
|
|
|
38981
39168
|
## Eventing
|
|
38982
39169
|
|
|
38983
39170
|
Use \`~>\` for asynchronous relationships. Model one async wire per meaningful
|
|
38984
39171
|
topic or event flow between real producer and consumer elements.
|
|
38985
39172
|
|
|
39173
|
+
For pub/sub, make the dependency consumer-owned:
|
|
39174
|
+
|
|
39175
|
+
- The producer/source declares the event topic as part of its contract, but does
|
|
39176
|
+
not maintain a manual list of subscribers.
|
|
39177
|
+
- The consumer declares \`~> producer\` with \`via = <topic>\`, because the
|
|
39178
|
+
consumer depends on the producer's event contract.
|
|
39179
|
+
- To answer "who depends on this event?", query the graph for incoming async
|
|
39180
|
+
dependencies instead of editing a subscriber list on the producer.
|
|
39181
|
+
|
|
38986
39182
|
Do not invent a broker node just to make the diagram look familiar. If the
|
|
38987
|
-
broker is deployment infrastructure, model it
|
|
38988
|
-
|
|
39183
|
+
chosen style is clean C4 and the broker is deployment infrastructure, model it
|
|
39184
|
+
in deployment/C4. If the chosen style is pragmatic mixed C2, a broker-like node
|
|
39185
|
+
can be acceptable, but document that the view mixes levels. If the producer or
|
|
39186
|
+
consumer is not known, leave a gap and report it instead of fabricating an
|
|
38989
39187
|
element.
|
|
38990
39188
|
|
|
38991
39189
|
## No Fabricated Elements
|
|
@@ -39069,6 +39267,11 @@ Definition files are different from model files. They declare vocabulary:
|
|
|
39069
39267
|
\`extend enum of\`, and \`extend presentation\`. Model files usually start with
|
|
39070
39268
|
\`context <id>\` and then create graph object instances with constructors.
|
|
39071
39269
|
|
|
39270
|
+
Do not mix these source forms in one file. A framework/definitions file should
|
|
39271
|
+
contain only vocabulary/schema declarations. A model file should declare a
|
|
39272
|
+
\`context <id>\` and graph object instances. If both are needed, create two
|
|
39273
|
+
files and validate the whole project.
|
|
39274
|
+
|
|
39072
39275
|
## Type Definitions and Extensions
|
|
39073
39276
|
|
|
39074
39277
|
Use \`define type\` to create a new graph/value type. Use \`extend type\` to add
|
|
@@ -39126,10 +39329,10 @@ links:
|
|
|
39126
39329
|
technology = HTTPS, JSON
|
|
39127
39330
|
call = POST /checkout
|
|
39128
39331
|
description = Places an order
|
|
39129
|
-
~>
|
|
39332
|
+
~> order_events
|
|
39130
39333
|
technology = Kafka
|
|
39131
39334
|
via = orders.created
|
|
39132
|
-
description =
|
|
39335
|
+
description = Consumes order events
|
|
39133
39336
|
\`\`\`
|
|
39134
39337
|
|
|
39135
39338
|
\`call\` is singular and belongs to synchronous \`->\` links. \`via\` belongs to
|
|
@@ -39179,22 +39382,79 @@ Use \`extend type\` / \`extend presentation\` when patching existing vocabulary.
|
|
|
39179
39382
|
Repeating \`define presentation X\` for an existing presentation is a diagnostic
|
|
39180
39383
|
in current Archinsight.
|
|
39181
39384
|
|
|
39385
|
+
## Comments and Notes
|
|
39386
|
+
|
|
39387
|
+
Use \`#\` for ordinary comments when you want to leave guidance for humans or
|
|
39388
|
+
agents without changing the model:
|
|
39389
|
+
|
|
39390
|
+
\`\`\`insight
|
|
39391
|
+
# This file owns the checkout bounded context.
|
|
39392
|
+
context checkout
|
|
39393
|
+
|
|
39394
|
+
system checkout_platform
|
|
39395
|
+
# Keep logical services here; deployment inventory belongs in C4 files.
|
|
39396
|
+
name = Checkout Platform
|
|
39397
|
+
\`\`\`
|
|
39398
|
+
|
|
39399
|
+
A \`#\` after an element or relationship line is an inline note. Notes are
|
|
39400
|
+
stored in the linked graph and can be rendered as note nodes near the element or
|
|
39401
|
+
edge:
|
|
39402
|
+
|
|
39403
|
+
\`\`\`insight
|
|
39404
|
+
context checkout
|
|
39405
|
+
|
|
39406
|
+
system checkout_platform
|
|
39407
|
+
name = Checkout Platform
|
|
39408
|
+
|
|
39409
|
+
container api # Public API owned by the checkout team
|
|
39410
|
+
name = Checkout API
|
|
39411
|
+
links:
|
|
39412
|
+
-> payment_gateway # PCI-sensitive request path
|
|
39413
|
+
technology = HTTPS
|
|
39414
|
+
call = POST /payments
|
|
39415
|
+
|
|
39416
|
+
external system payment_gateway
|
|
39417
|
+
name = Payment gateway
|
|
39418
|
+
\`\`\`
|
|
39419
|
+
|
|
39420
|
+
Use comments for authoring hints that should stay invisible in diagrams. Use
|
|
39421
|
+
notes for architecture remarks that should travel with the model and help
|
|
39422
|
+
readers understand a specific element or relationship.
|
|
39423
|
+
|
|
39182
39424
|
## Annotations
|
|
39183
39425
|
|
|
39184
|
-
Annotations decorate the next declaration or
|
|
39426
|
+
Annotations decorate the next declaration or relationship. Put each annotation
|
|
39427
|
+
on its own line immediately before the target:
|
|
39185
39428
|
|
|
39186
39429
|
\`\`\`insight
|
|
39187
|
-
|
|
39188
|
-
external system warehouse
|
|
39189
|
-
name = Warehouse
|
|
39430
|
+
context fulfillment
|
|
39190
39431
|
|
|
39191
|
-
|
|
39192
|
-
|
|
39193
|
-
|
|
39432
|
+
system fulfillment_platform
|
|
39433
|
+
name = Fulfillment Platform
|
|
39434
|
+
|
|
39435
|
+
@planned
|
|
39436
|
+
container fulfillment_adapter
|
|
39437
|
+
name = Fulfillment adapter
|
|
39438
|
+
links:
|
|
39439
|
+
@deprecated(replace after ERP migration)
|
|
39440
|
+
~> legacy_erp # scheduled for removal
|
|
39441
|
+
|
|
39442
|
+
external system legacy_erp
|
|
39443
|
+
name = Legacy ERP
|
|
39194
39444
|
\`\`\`
|
|
39195
39445
|
|
|
39196
|
-
|
|
39197
|
-
|
|
39446
|
+
Available annotations:
|
|
39447
|
+
|
|
39448
|
+
- \`@planned\` marks an element or relationship as planned or not fully
|
|
39449
|
+
implemented yet. The default Graphviz renderer highlights it in green.
|
|
39450
|
+
- \`@deprecated\` marks an element or relationship as legacy or scheduled for
|
|
39451
|
+
removal. Add optional text in parentheses when the replacement or reason is
|
|
39452
|
+
useful. The default Graphviz renderer highlights it in red.
|
|
39453
|
+
|
|
39454
|
+
Annotations can be stacked and are preserved on projected relationships, so a
|
|
39455
|
+
C4 projection can still show that the original logical relationship was planned
|
|
39456
|
+
or deprecated. Annotations cannot decorate assignments; use a comment above the
|
|
39457
|
+
assignment when you only need a local authoring hint.
|
|
39198
39458
|
|
|
39199
39459
|
## Presentation Syntax
|
|
39200
39460
|
|
|
@@ -39515,11 +39775,13 @@ at context level. Prefer capability language over endpoint trivia.
|
|
|
39515
39775
|
Use \`~>\` for meaningful asynchronous context flows:
|
|
39516
39776
|
|
|
39517
39777
|
\`\`\`insight
|
|
39518
|
-
|
|
39519
|
-
|
|
39520
|
-
|
|
39521
|
-
|
|
39522
|
-
|
|
39778
|
+
external system analytics_platform
|
|
39779
|
+
name = Analytics Platform
|
|
39780
|
+
links:
|
|
39781
|
+
~> storefront
|
|
39782
|
+
technology = Kafka
|
|
39783
|
+
via = order.completed
|
|
39784
|
+
description = Consumes completed order events from Storefront
|
|
39523
39785
|
\`\`\`
|
|
39524
39786
|
|
|
39525
39787
|
## What Not To Put In C1
|
|
@@ -39568,6 +39830,22 @@ the selected source file, so a C2 file should usually contain the selected
|
|
|
39568
39830
|
\`system <id>\` declaration or an \`extend system <id>\` block with its
|
|
39569
39831
|
containers/services.
|
|
39570
39832
|
|
|
39833
|
+
## C2 Purity vs Pragmatic Infrastructure
|
|
39834
|
+
|
|
39835
|
+
The clean C2 answer is logical: deployable containers/services and how they
|
|
39836
|
+
collaborate. In that mode, databases, brokers, gateways, vaults, compute, and
|
|
39837
|
+
regions belong to C4/deployment.
|
|
39838
|
+
|
|
39839
|
+
Archinsight does not force that choice. For a quick or single-environment model,
|
|
39840
|
+
it is acceptable to put simple infrastructure-like runtime nodes into C2 when
|
|
39841
|
+
the user wants speed over strict layer separation. Be explicit about the
|
|
39842
|
+
tradeoff: the C2 view becomes mixed, C4 is not really modeled for that system,
|
|
39843
|
+
and many-to-many deployment across different environments will not be available
|
|
39844
|
+
until the model is migrated to clean C4.
|
|
39845
|
+
|
|
39846
|
+
Choose this per system. Do not make the whole repository clean or mixed just
|
|
39847
|
+
because one system needs that style.
|
|
39848
|
+
|
|
39571
39849
|
## C2 Workflow
|
|
39572
39850
|
|
|
39573
39851
|
1. Run \`archinsight structure . --format text\` to find the exact system id,
|
|
@@ -39691,21 +39969,33 @@ Import the real declaration when it is shared.
|
|
|
39691
39969
|
|
|
39692
39970
|
## Async and Eventing Pattern
|
|
39693
39971
|
|
|
39694
|
-
Use \`~>\` for meaningful asynchronous
|
|
39972
|
+
Use \`~>\` for meaningful asynchronous dependencies. For pub/sub, declare the
|
|
39973
|
+
wire on the consumer, pointing at the producer/source whose topic contract it
|
|
39974
|
+
depends on:
|
|
39695
39975
|
|
|
39696
39976
|
\`\`\`insight
|
|
39697
|
-
|
|
39698
|
-
name =
|
|
39977
|
+
external system analytics_platform
|
|
39978
|
+
name = Analytics Platform
|
|
39979
|
+
technology = Kafka consumer
|
|
39699
39980
|
links:
|
|
39700
|
-
~>
|
|
39981
|
+
~> checkout_api
|
|
39701
39982
|
technology = Kafka
|
|
39702
39983
|
via = checkout.completed
|
|
39703
|
-
description =
|
|
39984
|
+
description = Consumes completed checkout events
|
|
39985
|
+
|
|
39986
|
+
service checkout_api
|
|
39987
|
+
name = Checkout API
|
|
39988
|
+
description = Publishes checkout.completed as an event contract
|
|
39704
39989
|
\`\`\`
|
|
39705
39990
|
|
|
39706
|
-
Do not
|
|
39707
|
-
|
|
39708
|
-
|
|
39991
|
+
Do not list consumers under the producer just to answer "who listens to this
|
|
39992
|
+
topic?" That answer belongs in a query over incoming async dependencies.
|
|
39993
|
+
|
|
39994
|
+
Do not add a broker node just to make an event diagram look familiar. In clean
|
|
39995
|
+
C2, a broker is usually deployment/C4 infrastructure unless the project defines
|
|
39996
|
+
it as a runtime system or service in the selected view. In pragmatic mixed C2,
|
|
39997
|
+
adding a broker can be acceptable for a quick view, but it means the diagram is
|
|
39998
|
+
no longer strictly logical C2.
|
|
39709
39999
|
|
|
39710
40000
|
## C2 Link Details
|
|
39711
40001
|
|
|
@@ -39726,8 +40016,9 @@ details at C2 only when they clarify the architecture; otherwise use a plain
|
|
|
39726
40016
|
## What Not To Put In C2
|
|
39727
40017
|
|
|
39728
40018
|
- Components, classes, handlers, repositories, or UI widgets.
|
|
39729
|
-
- Deployment nodes, pods, regions, network gateways, or secret stores
|
|
39730
|
-
|
|
40019
|
+
- Deployment nodes, pods, regions, network gateways, or secret stores in clean
|
|
40020
|
+
C2. Include them only when the user intentionally wants pragmatic mixed C2 or
|
|
40021
|
+
the project models them as C2 runtime systems.
|
|
39731
40022
|
- Database tables and internal schemas.
|
|
39732
40023
|
- One-off scripts or build-time tools unless they are real runtime units.
|
|
39733
40024
|
- Duplicate links already represented at a lower C3 level unless the C2 view is
|
|
@@ -39736,7 +40027,8 @@ details at C2 only when they clarify the architecture; otherwise use a plain
|
|
|
39736
40027
|
## Common C2 Mistakes
|
|
39737
40028
|
|
|
39738
40029
|
- Adding C2 nodes directly under \`context\` instead of under a \`system\`.
|
|
39739
|
-
- Modeling infrastructure that
|
|
40030
|
+
- Modeling infrastructure in C2 without deciding that the system is using the
|
|
40031
|
+
pragmatic mixed-C2 style.
|
|
39740
40032
|
- Mixing C2 container/service links with C3 component links in the same source
|
|
39741
40033
|
file without a clear view goal.
|
|
39742
40034
|
- Forgetting \`--source <c2-file.ai>\` when rendering C2.
|
|
@@ -39909,10 +40201,6 @@ extend service inventory_api
|
|
|
39909
40201
|
links:
|
|
39910
40202
|
-> inventory_policy
|
|
39911
40203
|
-> reservation_repository
|
|
39912
|
-
~> inventory_events
|
|
39913
|
-
technology = Kafka
|
|
39914
|
-
via = inventory.reserved
|
|
39915
|
-
description = Publishes successful reservation events
|
|
39916
40204
|
|
|
39917
40205
|
component inventory_policy
|
|
39918
40206
|
name = Inventory policy
|
|
@@ -39924,15 +40212,21 @@ extend service inventory_api
|
|
|
39924
40212
|
technology = SQL
|
|
39925
40213
|
responsibility = Stores reservation state and idempotency keys
|
|
39926
40214
|
|
|
39927
|
-
component
|
|
39928
|
-
name =
|
|
39929
|
-
technology = Kafka
|
|
39930
|
-
responsibility =
|
|
40215
|
+
component stock_projection
|
|
40216
|
+
name = Stock projection
|
|
40217
|
+
technology = Kafka consumer
|
|
40218
|
+
responsibility = Maintains a stock read model from reservation events
|
|
40219
|
+
links:
|
|
40220
|
+
~> reservation_service
|
|
40221
|
+
technology = Kafka
|
|
40222
|
+
via = inventory.reserved
|
|
40223
|
+
description = Consumes successful reservation events
|
|
39931
40224
|
\`\`\`
|
|
39932
40225
|
|
|
39933
40226
|
Use \`->\` for synchronous calls and \`~>\` for asynchronous flows. Use singular
|
|
39934
40227
|
\`call\` for the synchronous operation and \`via\` for the asynchronous topic,
|
|
39935
|
-
queue, or channel.
|
|
40228
|
+
queue, or channel. For pub/sub, put the async link on the consumer and point it
|
|
40229
|
+
at the producer/source whose event contract it consumes.
|
|
39936
40230
|
|
|
39937
40231
|
## Imported Boundary Pattern
|
|
39938
40232
|
|
|
@@ -40011,9 +40305,9 @@ Use async details for events:
|
|
|
40011
40305
|
|
|
40012
40306
|
\`\`\`insight
|
|
40013
40307
|
links:
|
|
40014
|
-
~>
|
|
40308
|
+
~> reservation_service
|
|
40015
40309
|
via = inventory.reserved
|
|
40016
|
-
description =
|
|
40310
|
+
description = Consumes reservation completion events
|
|
40017
40311
|
\`\`\`
|
|
40018
40312
|
|
|
40019
40313
|
Do not add a broker as a component unless the broker is actually part of the
|
|
@@ -40056,10 +40350,13 @@ projection rules.
|
|
|
40056
40350
|
## Contents
|
|
40057
40351
|
|
|
40058
40352
|
- What C4 Answers
|
|
40353
|
+
- Before You Use C4
|
|
40059
40354
|
- Mental Model
|
|
40060
40355
|
- C4 Workflow
|
|
40356
|
+
- C4 Decision Checklist
|
|
40061
40357
|
- Environment Inventory
|
|
40062
40358
|
- Why Infrastructure Is Per Environment
|
|
40359
|
+
- Graph Model vs Diagram Scope
|
|
40063
40360
|
- Attaching Deployment To C1-C3 Elements
|
|
40064
40361
|
- usesProfile, environmentsFrom, runsOn, and uses
|
|
40065
40362
|
- Deployment Archetypes
|
|
@@ -40081,6 +40378,31 @@ C4 is not just another decomposition level. C1-C3 mostly describe logical
|
|
|
40081
40378
|
architecture. C4 maps logical elements and links onto environment-local
|
|
40082
40379
|
infrastructure inventory.
|
|
40083
40380
|
|
|
40381
|
+
## Before You Use C4
|
|
40382
|
+
|
|
40383
|
+
C4/deployment is optional. Do not push the user into environments, projection
|
|
40384
|
+
rules, and infrastructure inventory when they only need a quick logical/runtime
|
|
40385
|
+
view.
|
|
40386
|
+
|
|
40387
|
+
If the work has reached infrastructure, runtime placement, regions, compute, or
|
|
40388
|
+
deployment, ask or infer the intended style for the current system:
|
|
40389
|
+
|
|
40390
|
+
- Pragmatic mixed C2: put simple infrastructure-like runtime nodes such as a
|
|
40391
|
+
database, broker, gateway, or vault near the services in C2. This is fast and
|
|
40392
|
+
easier for simple or single-environment systems, but it mixes abstraction
|
|
40393
|
+
levels and does not produce a real C4 model.
|
|
40394
|
+
- Clean C4: keep C2 logical and describe physical realization through
|
|
40395
|
+
\`Environment\` slots, deployment profiles, inventory, \`runsOn\`, \`uses\`,
|
|
40396
|
+
and projection rules. This takes more design work, but supports region/env
|
|
40397
|
+
differences, many-to-many deployment, and organization-specific runtime
|
|
40398
|
+
complexity.
|
|
40399
|
+
|
|
40400
|
+
The choice is per-system. Model a critical system with clean C4 and keep a
|
|
40401
|
+
peripheral system pragmatic in C2 if that matches the user's needs. If a system
|
|
40402
|
+
starts as mixed C2 and later needs multi-env deployment, expect a migration:
|
|
40403
|
+
infrastructure nodes must move into environment inventory and links must gain
|
|
40404
|
+
deployment/projection semantics.
|
|
40405
|
+
|
|
40084
40406
|
## Mental Model
|
|
40085
40407
|
|
|
40086
40408
|
There are three layers:
|
|
@@ -40148,6 +40470,23 @@ environment prod
|
|
|
40148
40470
|
8. Validate with \`archinsight link . --format text\`.
|
|
40149
40471
|
9. Render with \`archinsight render . -c <context-id> -s <c4-file.ai> -v c4 -f svg -o c4.svg\`.
|
|
40150
40472
|
|
|
40473
|
+
## C4 Decision Checklist
|
|
40474
|
+
|
|
40475
|
+
Use this before adding a \`deployment:\` block:
|
|
40476
|
+
|
|
40477
|
+
- Placement/grouping? Put \`runsOn compute\` on the deployed element.
|
|
40478
|
+
- Stateful or sidecar-like dependency? Put \`uses storage\`, \`uses observability\`,
|
|
40479
|
+
or similar element-level infrastructure on the deployed element.
|
|
40480
|
+
- Traffic path to a target? Put \`uses network\`, \`uses publicGateway\`, or any
|
|
40481
|
+
infrastructure whose projection mentions \`$to\` on the relationship under
|
|
40482
|
+
\`links:\`, not on the container/service.
|
|
40483
|
+
- Pub/sub path? Make the async wire consumer-owned: the consumer declares
|
|
40484
|
+
\`~> producer\` with \`via = <topic>\`, then attach \`uses broker\` to that wire
|
|
40485
|
+
when modeling clean C4 broker infrastructure.
|
|
40486
|
+
- Picture too noisy? Keep the graph model correct and change source scope or
|
|
40487
|
+
write a custom query. Fan-in to a shared node is normal graph reality, not a
|
|
40488
|
+
modeling error by itself.
|
|
40489
|
+
|
|
40151
40490
|
## Environment Inventory
|
|
40152
40491
|
|
|
40153
40492
|
Define infrastructure vocabulary in a definition file:
|
|
@@ -40220,6 +40559,12 @@ environment prod
|
|
|
40220
40559
|
specific \`prod\` environment. Another environment can fill the same slots with
|
|
40221
40560
|
different concrete infrastructure.
|
|
40222
40561
|
|
|
40562
|
+
Object ids are still unique within a context, even when the instances live in
|
|
40563
|
+
different environment slots. When the exact id is not important, use anonymous
|
|
40564
|
+
\`_\` instances inside each environment. When you need stable ids, make them
|
|
40565
|
+
environment-specific, such as \`envoy_prod\` and \`envoy_staging\`, instead of
|
|
40566
|
+
reusing \`envoy_public\` in several environments.
|
|
40567
|
+
|
|
40223
40568
|
## Why Infrastructure Is Per Environment
|
|
40224
40569
|
|
|
40225
40570
|
Infrastructure must be per environment because deployment is many-to-many:
|
|
@@ -40236,6 +40581,14 @@ If infrastructure were modeled as global nodes, the model could not say:
|
|
|
40236
40581
|
"Checkout API runs on EKS in production, Cloud Run in staging, and uses a
|
|
40237
40582
|
different database in each environment" without duplicating logical services.
|
|
40238
40583
|
|
|
40584
|
+
## Graph Model vs Diagram Scope
|
|
40585
|
+
|
|
40586
|
+
The linked model is a graph; a diagram is only one scoped query over that graph.
|
|
40587
|
+
Fan-in to one broker, gateway, load balancer, or producer is often the correct
|
|
40588
|
+
physical model. If the picture explodes, do not rewrite the model just to make
|
|
40589
|
+
the image tidy. Narrow the selected source file, add a custom \`.aiq\` query,
|
|
40590
|
+
group differently, or aggregate the view.
|
|
40591
|
+
|
|
40239
40592
|
## Attaching Deployment To C1-C3 Elements
|
|
40240
40593
|
|
|
40241
40594
|
\`deployment\` is available on systems, containers/services, components, and
|
|
@@ -40250,7 +40603,27 @@ Prefer C2 containers/services for most deployment mapping:
|
|
|
40250
40603
|
Use C1 deployment only when the whole system is deployed as one unit. Use C3
|
|
40251
40604
|
deployment when a component is independently deployed or has a distinct physical
|
|
40252
40605
|
path. Use wire deployment when a specific logical relationship travels through
|
|
40253
|
-
infrastructure such as a public gateway,
|
|
40606
|
+
infrastructure such as a public gateway, network connection, broker, or egress
|
|
40607
|
+
path.
|
|
40608
|
+
|
|
40609
|
+
## Element-Level vs Wire-Level Infrastructure
|
|
40610
|
+
|
|
40611
|
+
Attach infrastructure to an element when the projection only needs the deployed
|
|
40612
|
+
element itself:
|
|
40613
|
+
|
|
40614
|
+
- \`runsOn compute\`: placement/grouping.
|
|
40615
|
+
- \`uses storage\`: the element depends on stateful infrastructure.
|
|
40616
|
+
- \`uses observability\`: monitoring sidecars or collectors around the element.
|
|
40617
|
+
|
|
40618
|
+
Attach infrastructure to a wire when the projection needs a real target:
|
|
40619
|
+
|
|
40620
|
+
- \`uses publicGateway\`: expands a caller-to-service path through ingress.
|
|
40621
|
+
- \`uses network\`: keeps a direct source-to-target network path on C4.
|
|
40622
|
+
- \`uses broker\`: both producer and consumer physically connect to the broker.
|
|
40623
|
+
|
|
40624
|
+
Rule of thumb: if the infrastructure type's \`project:\` block mentions \`$to\`,
|
|
40625
|
+
use it on a relationship under \`links:\`. Using it on an element is invalid
|
|
40626
|
+
because an element deployment has no separate target endpoint.
|
|
40254
40627
|
|
|
40255
40628
|
## usesProfile, environmentsFrom, runsOn, and uses
|
|
40256
40629
|
|
|
@@ -40367,7 +40740,6 @@ deploymentProfile global_service
|
|
|
40367
40740
|
global_edge
|
|
40368
40741
|
|
|
40369
40742
|
runsOn compute
|
|
40370
|
-
uses publicGateway
|
|
40371
40743
|
|
|
40372
40744
|
deploymentProfile regional_service
|
|
40373
40745
|
environments:
|
|
@@ -40384,6 +40756,11 @@ container web_app
|
|
|
40384
40756
|
name = Web app
|
|
40385
40757
|
deployment:
|
|
40386
40758
|
usesProfile global_service
|
|
40759
|
+
links:
|
|
40760
|
+
-> checkout_api
|
|
40761
|
+
deployment:
|
|
40762
|
+
environmentsFrom global_service
|
|
40763
|
+
uses publicGateway
|
|
40387
40764
|
|
|
40388
40765
|
service checkout_api
|
|
40389
40766
|
name = Checkout API
|
|
@@ -40392,18 +40769,19 @@ service checkout_api
|
|
|
40392
40769
|
uses storage
|
|
40393
40770
|
\`\`\`
|
|
40394
40771
|
|
|
40395
|
-
The profile supplies the common environment scope, placement, and
|
|
40772
|
+
The profile supplies the common environment scope, placement, and element-level
|
|
40396
40773
|
infrastructure. Additional local \`uses\` entries extend the profile for that
|
|
40397
40774
|
specific element. In the example, \`checkout_api\` inherits regional compute and
|
|
40398
40775
|
observability from \`regional_service\`, then adds its own \`uses storage\`
|
|
40399
|
-
because this service owns persistent state.
|
|
40776
|
+
because this service owns persistent state. The \`web_app -> checkout_api\` wire uses
|
|
40777
|
+
\`environmentsFrom global_service\` to reuse the environment list while attaching
|
|
40778
|
+
the path-only \`publicGateway\` projection to the relationship.
|
|
40400
40779
|
|
|
40401
|
-
Use separate profiles when the
|
|
40402
|
-
\`
|
|
40403
|
-
|
|
40404
|
-
|
|
40405
|
-
|
|
40406
|
-
service-to-service path.
|
|
40780
|
+
Use separate profiles when the element-level defaults differ. For example,
|
|
40781
|
+
\`regional_service\` can include \`runsOn compute\` and \`uses observability\`,
|
|
40782
|
+
while \`regional_stateful_service\` can also include \`uses storage\`. Keep
|
|
40783
|
+
path-only infrastructure such as \`publicGateway\`, \`network\`, or \`broker\`
|
|
40784
|
+
on the wire deployment where the source and target are known.
|
|
40407
40785
|
|
|
40408
40786
|
When an element should reuse only the environments from an archetype, use
|
|
40409
40787
|
\`environmentsFrom <profile>\` instead of \`usesProfile <profile>\` and then add
|
|
@@ -40467,6 +40845,10 @@ queries commonly select projected deployment edges; a plain logical wire without
|
|
|
40467
40845
|
deployment projection may be correct in C2/C3 but absent from the deployment
|
|
40468
40846
|
layer.
|
|
40469
40847
|
|
|
40848
|
+
If validation reports \`PROJECTION_TARGET_REQUIRED\`, you attached a projection
|
|
40849
|
+
that uses \`$to\` to an element. Move that \`uses ...\` entry to the relevant
|
|
40850
|
+
wire and reuse the element's environment scope with \`environmentsFrom\`.
|
|
40851
|
+
|
|
40470
40852
|
Projection terms:
|
|
40471
40853
|
|
|
40472
40854
|
- \`$from\` is the logical source of the deployment use.
|
|
@@ -40551,7 +40933,6 @@ deploymentProfile public_regional_service
|
|
|
40551
40933
|
|
|
40552
40934
|
runsOn compute
|
|
40553
40935
|
uses observability
|
|
40554
|
-
uses publicGateway
|
|
40555
40936
|
|
|
40556
40937
|
service checkout_api
|
|
40557
40938
|
name = Checkout API
|
|
@@ -40604,7 +40985,8 @@ logical service projects into both environments without duplicating
|
|
|
40604
40985
|
- Logical components invented only to represent physical routing.
|
|
40605
40986
|
- C3 internals unless they are independently deployed.
|
|
40606
40987
|
- Cloud resources with no relationship to a deployment question.
|
|
40607
|
-
- A broker/gateway/load balancer in C2 just because it appears in deployment
|
|
40988
|
+
- A broker/gateway/load balancer in C2 just because it appears in deployment,
|
|
40989
|
+
unless the system intentionally uses the pragmatic mixed-C2 style.
|
|
40608
40990
|
|
|
40609
40991
|
## Common C4 Mistakes
|
|
40610
40992
|
|
|
@@ -40612,7 +40994,13 @@ logical service projects into both environments without duplicating
|
|
|
40612
40994
|
slots for them.
|
|
40613
40995
|
- Creating \`infrastructureComponent\` nodes at context level when they should
|
|
40614
40996
|
live in an \`environment\` inventory slot.
|
|
40997
|
+
- Reusing the same concrete infrastructure id in several environments. Use
|
|
40998
|
+
anonymous \`_\` instances or environment-specific ids.
|
|
40615
40999
|
- Using \`usesProfile\` on a wire when only \`environmentsFrom\` is intended.
|
|
41000
|
+
- Attaching \`uses publicGateway\`, \`uses network\`, or another \`$to\`-based
|
|
41001
|
+
path projection to a container/service. Move it to the specific wire.
|
|
41002
|
+
- Modeling pub/sub as a producer-owned subscriber list. Consumers should declare
|
|
41003
|
+
\`~> producer\` with \`via = <topic>\`; use queries to list consumers.
|
|
40616
41004
|
- Forgetting \`--source <c4-file.ai>\` when rendering C4.
|
|
40617
41005
|
- Expecting \`runsOn\` to draw traffic; use \`project:\` rules and \`uses\` for
|
|
40618
41006
|
traffic/path projections.
|
|
@@ -40630,6 +41018,272 @@ Use \`examples/c4-deployment-framework.ai\` and \`examples/c4-deployment.ai\` as
|
|
|
40630
41018
|
a compact valid C4 model when syntax is unclear.
|
|
40631
41019
|
`;
|
|
40632
41020
|
}
|
|
41021
|
+
function genericScalingReference() {
|
|
41022
|
+
return `# Scaling an Archinsight Repository
|
|
41023
|
+
|
|
41024
|
+
Use this reference when a project grows beyond one or two files and you need to
|
|
41025
|
+
reuse definitions, environments, deployment profiles, or systems without
|
|
41026
|
+
duplicating them.
|
|
41027
|
+
|
|
41028
|
+
## Repository Shape
|
|
41029
|
+
|
|
41030
|
+
Prefer one shared framework per repository:
|
|
41031
|
+
|
|
41032
|
+
- one definitions/framework area for \`extend type Environment\`, custom
|
|
41033
|
+
infrastructure types, presentation tweaks, projection-capable infrastructure,
|
|
41034
|
+
and reusable deployment profiles;
|
|
41035
|
+
- source files grouped by context directories when the repository is large;
|
|
41036
|
+
- model files that usually focus on one primary owned system being detailed;
|
|
41037
|
+
- one or more inventory files for concrete \`environment <id>\` instances and
|
|
41038
|
+
their env-local infrastructure;
|
|
41039
|
+
- shared external contexts for external actors and systems reused by many
|
|
41040
|
+
systems;
|
|
41041
|
+
- focused deployment-view files that attach deployment profiles and per-view
|
|
41042
|
+
traffic paths.
|
|
41043
|
+
|
|
41044
|
+
Do not copy the same \`extend type Environment\`, infra type definitions, or
|
|
41045
|
+
\`deploymentProfile\` blocks into every system file. Define the vocabulary and
|
|
41046
|
+
reusable archetypes once, import or reference them where needed, and validate the
|
|
41047
|
+
whole project.
|
|
41048
|
+
|
|
41049
|
+
## Framework Once, Use Everywhere
|
|
41050
|
+
|
|
41051
|
+
A typical deployment framework file contains only shared vocabulary: type
|
|
41052
|
+
definitions, type extensions, projection rules, and presentation overrides. Do
|
|
41053
|
+
not mix \`define type\` / \`extend type\` declarations and \`context\`
|
|
41054
|
+
declarations in the same source file.
|
|
41055
|
+
|
|
41056
|
+
\`\`\`insight
|
|
41057
|
+
define type PublicGateway of InfrastructureComponent
|
|
41058
|
+
constructor publicGateway
|
|
41059
|
+
required InfrastructureComponent cdn
|
|
41060
|
+
required InfrastructureComponent loadBalancer
|
|
41061
|
+
|
|
41062
|
+
project:
|
|
41063
|
+
$from -> cdn
|
|
41064
|
+
cdn -> loadBalancer
|
|
41065
|
+
loadBalancer -> $this
|
|
41066
|
+
$this -> $to
|
|
41067
|
+
|
|
41068
|
+
extend type Environment
|
|
41069
|
+
Compute compute
|
|
41070
|
+
Storage storage
|
|
41071
|
+
Broker broker
|
|
41072
|
+
PublicGateway publicGateway
|
|
41073
|
+
NetworkConnection network
|
|
41074
|
+
\`\`\`
|
|
41075
|
+
|
|
41076
|
+
Concrete inventory/profile files then declare contexts, environments, and
|
|
41077
|
+
profiles:
|
|
41078
|
+
|
|
41079
|
+
\`\`\`insight
|
|
41080
|
+
context infra
|
|
41081
|
+
name = Shared Infrastructure
|
|
41082
|
+
|
|
41083
|
+
environment prod_eu
|
|
41084
|
+
name = Production EU
|
|
41085
|
+
compute:
|
|
41086
|
+
compute ecs
|
|
41087
|
+
name = ECS
|
|
41088
|
+
technology = AWS ECS
|
|
41089
|
+
broker:
|
|
41090
|
+
broker kafka
|
|
41091
|
+
name = Kafka
|
|
41092
|
+
technology = MSK
|
|
41093
|
+
address = kafka.prod.eu.internal
|
|
41094
|
+
|
|
41095
|
+
deploymentProfile regional_service
|
|
41096
|
+
environments:
|
|
41097
|
+
prod_eu
|
|
41098
|
+
|
|
41099
|
+
runsOn compute
|
|
41100
|
+
\`\`\`
|
|
41101
|
+
|
|
41102
|
+
System files should reuse these definitions instead of recreating \`compute\`,
|
|
41103
|
+
\`broker\`, or profile declarations locally.
|
|
41104
|
+
|
|
41105
|
+
## System Files and External Contexts
|
|
41106
|
+
|
|
41107
|
+
The default model file is centered on one owned system:
|
|
41108
|
+
|
|
41109
|
+
\`\`\`text
|
|
41110
|
+
commerce/
|
|
41111
|
+
checkout.ai
|
|
41112
|
+
catalog.ai
|
|
41113
|
+
fulfillment.ai
|
|
41114
|
+
external/
|
|
41115
|
+
platforms.ai
|
|
41116
|
+
regulators.ai
|
|
41117
|
+
\`\`\`
|
|
41118
|
+
|
|
41119
|
+
\`commerce/checkout.ai\` would declare \`context commerce\`, the
|
|
41120
|
+
\`system checkout\` focal object, and the containers/services/components needed
|
|
41121
|
+
to explain checkout. \`commerce/catalog.ai\` would do the same for catalog.
|
|
41122
|
+
|
|
41123
|
+
Shared external actors and systems should not be copied into every system file.
|
|
41124
|
+
Put them in one external context, or a few semantically grouped external
|
|
41125
|
+
contexts:
|
|
41126
|
+
|
|
41127
|
+
\`\`\`insight
|
|
41128
|
+
context external_platforms
|
|
41129
|
+
|
|
41130
|
+
external system stripe
|
|
41131
|
+
name = Stripe
|
|
41132
|
+
|
|
41133
|
+
external system sendgrid
|
|
41134
|
+
name = SendGrid
|
|
41135
|
+
\`\`\`
|
|
41136
|
+
|
|
41137
|
+
Then import them where needed:
|
|
41138
|
+
|
|
41139
|
+
\`\`\`insight
|
|
41140
|
+
context commerce
|
|
41141
|
+
|
|
41142
|
+
import stripe from context external_platforms
|
|
41143
|
+
|
|
41144
|
+
system checkout
|
|
41145
|
+
links:
|
|
41146
|
+
-> stripe from external_platforms
|
|
41147
|
+
\`\`\`
|
|
41148
|
+
|
|
41149
|
+
Avoid making a separate file for every external actor or vendor unless the
|
|
41150
|
+
external dependency itself has substantial reusable structure. A small number of
|
|
41151
|
+
well-named external contexts gives all repository systems one shared vocabulary
|
|
41152
|
+
for outside dependencies.
|
|
41153
|
+
|
|
41154
|
+
When a system file becomes too large, split details by extending the focal
|
|
41155
|
+
object in utility subdirectories:
|
|
41156
|
+
|
|
41157
|
+
\`\`\`text
|
|
41158
|
+
commerce/
|
|
41159
|
+
checkout.ai
|
|
41160
|
+
checkout-components/
|
|
41161
|
+
pricing.ai
|
|
41162
|
+
payment.ai
|
|
41163
|
+
inventory.ai
|
|
41164
|
+
\`\`\`
|
|
41165
|
+
|
|
41166
|
+
Those files should repeat the same \`context commerce\`, explicitly import the
|
|
41167
|
+
object being extended when it lives in another source file, and use
|
|
41168
|
+
\`extend service checkout_api\`, \`extend container web_app\`, or another object
|
|
41169
|
+
extension to add focused details.
|
|
41170
|
+
|
|
41171
|
+
## Same-Context Cross-File Imports
|
|
41172
|
+
|
|
41173
|
+
Insight resolves unqualified ids in this order: declarations in the same source
|
|
41174
|
+
file, explicit imports in the same source file, then it reports an error if the
|
|
41175
|
+
same id exists only in another source file of the same context.
|
|
41176
|
+
|
|
41177
|
+
That means splitting one context across files still requires imports:
|
|
41178
|
+
|
|
41179
|
+
\`\`\`insight
|
|
41180
|
+
context services
|
|
41181
|
+
|
|
41182
|
+
deploymentProfile eu_service
|
|
41183
|
+
\`\`\`
|
|
41184
|
+
|
|
41185
|
+
\`\`\`insight
|
|
41186
|
+
context services
|
|
41187
|
+
|
|
41188
|
+
import eu_service from context services
|
|
41189
|
+
|
|
41190
|
+
system checkout
|
|
41191
|
+
name = Checkout
|
|
41192
|
+
deployment:
|
|
41193
|
+
usesProfile eu_service
|
|
41194
|
+
\`\`\`
|
|
41195
|
+
|
|
41196
|
+
This is intentional. If a file is extracted, removed, or not included in the
|
|
41197
|
+
project, the linker should fail with an explicit identifier/import diagnostic
|
|
41198
|
+
instead of silently binding to whatever remains in the context.
|
|
41199
|
+
|
|
41200
|
+
## Inline from Context
|
|
41201
|
+
|
|
41202
|
+
When a relationship target is declared outside the current source file, prefer
|
|
41203
|
+
an explicit context qualifier on the link target:
|
|
41204
|
+
|
|
41205
|
+
\`\`\`insight
|
|
41206
|
+
context commerce
|
|
41207
|
+
|
|
41208
|
+
import payments from context external_systems
|
|
41209
|
+
|
|
41210
|
+
system checkout
|
|
41211
|
+
name = Checkout
|
|
41212
|
+
links:
|
|
41213
|
+
-> payments from external_systems
|
|
41214
|
+
technology = HTTPS
|
|
41215
|
+
call = POST /payments
|
|
41216
|
+
\`\`\`
|
|
41217
|
+
|
|
41218
|
+
The \`import <id> from context <context-id>\` line documents the dependency and
|
|
41219
|
+
makes the id available for attributes such as profiles and environment slots.
|
|
41220
|
+
The inline \`from <context-id>\` on a link target states which context owns the
|
|
41221
|
+
linked element. Use the same pattern for same-context cross-file links when the
|
|
41222
|
+
source has been split and ambiguity matters:
|
|
41223
|
+
|
|
41224
|
+
\`\`\`insight
|
|
41225
|
+
context services
|
|
41226
|
+
|
|
41227
|
+
import inventory_api from context services
|
|
41228
|
+
|
|
41229
|
+
system checkout_api
|
|
41230
|
+
links:
|
|
41231
|
+
-> inventory_api from services
|
|
41232
|
+
technology = HTTPS
|
|
41233
|
+
call = GET /inventory
|
|
41234
|
+
\`\`\`
|
|
41235
|
+
|
|
41236
|
+
This explicitness is useful during refactors: if the source file holding
|
|
41237
|
+
\`inventory_api\` disappears, validation points at the missing declaration
|
|
41238
|
+
instead of creating a hidden dependency on file layout.
|
|
41239
|
+
|
|
41240
|
+
## C4 Multi-File Pattern
|
|
41241
|
+
|
|
41242
|
+
For C4, keep these responsibilities separate:
|
|
41243
|
+
|
|
41244
|
+
- framework file: type extensions, infra constructors, presentation/projection
|
|
41245
|
+
definitions;
|
|
41246
|
+
- inventory/profile file: concrete environments and reusable deployment
|
|
41247
|
+
profiles;
|
|
41248
|
+
- deployment-view file: the relationships whose deployment path you want to
|
|
41249
|
+
render for one selected view.
|
|
41250
|
+
|
|
41251
|
+
When rendering C4 with \`-s <source.ai>\`, remember that source/tab scoping is
|
|
41252
|
+
part of the view. Put the view-driving logical relationships in the selected
|
|
41253
|
+
source file, or render from the source file that owns those relationships. Keep
|
|
41254
|
+
imported framework and inventory reusable, but validate the rendered C4 output
|
|
41255
|
+
after moving traffic relationships across files:
|
|
41256
|
+
|
|
41257
|
+
\`\`\`shell
|
|
41258
|
+
archinsight link . --format text
|
|
41259
|
+
archinsight render . -c deployment_shop -s c4-deployment.ai -v c4 -f svg -o deployment-c4.svg
|
|
41260
|
+
\`\`\`
|
|
41261
|
+
|
|
41262
|
+
If projected infrastructure edges disappear after a split, first check whether
|
|
41263
|
+
the selected \`-s\` file still contains the source logical relationship or an
|
|
41264
|
+
intended imported deployment-view relationship. Do not fix that by duplicating
|
|
41265
|
+
infrastructure nodes; fix the source selection or the file boundary.
|
|
41266
|
+
|
|
41267
|
+
## Practical Workflow
|
|
41268
|
+
|
|
41269
|
+
1. Run \`archinsight structure . --format text\`.
|
|
41270
|
+
2. Identify contexts, source files, and declaration ids before editing.
|
|
41271
|
+
3. Move shared vocabulary into one framework file.
|
|
41272
|
+
4. Group model files by context directory when the repository is large.
|
|
41273
|
+
5. Keep each ordinary system file focused on one owned system being detailed.
|
|
41274
|
+
6. Put external actors/systems in shared external contexts, not one file per
|
|
41275
|
+
external element.
|
|
41276
|
+
7. Move reusable environments and deployment profiles into inventory/profile
|
|
41277
|
+
files.
|
|
41278
|
+
8. Add explicit imports for every cross-file dependency, including same-context
|
|
41279
|
+
dependencies.
|
|
41280
|
+
9. Add inline \`from <context-id>\` on relationship targets that live outside
|
|
41281
|
+
the current source file.
|
|
41282
|
+
10. Validate with \`archinsight link . --format text\`.
|
|
41283
|
+
11. Render important C1/C2/C3/C4 views with explicit \`-c\`, \`-s\`, and \`-v\`
|
|
41284
|
+
options.
|
|
41285
|
+
`;
|
|
41286
|
+
}
|
|
40633
41287
|
function genericProjectStructureReference() {
|
|
40634
41288
|
return `# Project Structure Workflow
|
|
40635
41289
|
|
|
@@ -40637,6 +41291,37 @@ Use \`archinsight structure\` before broad edits, imports, or declaration lookup
|
|
|
40637
41291
|
Do not start with raw grep when you need to know what the linked project
|
|
40638
41292
|
contains.
|
|
40639
41293
|
|
|
41294
|
+
## Source File Classes
|
|
41295
|
+
|
|
41296
|
+
Keep source files in one role:
|
|
41297
|
+
|
|
41298
|
+
- definition/framework files: \`define type\`, \`define operator\`,
|
|
41299
|
+
\`define presentation\`, \`extend type\`, \`extend enum of\`, and
|
|
41300
|
+
\`extend presentation\`;
|
|
41301
|
+
- model files: \`context <id>\`, imports, graph object declarations,
|
|
41302
|
+
relationships, environments, and deployment profiles.
|
|
41303
|
+
|
|
41304
|
+
Do not mix definition/framework declarations with \`context <id>\` in one file.
|
|
41305
|
+
When a model needs custom vocabulary, add or edit a framework file first, then
|
|
41306
|
+
use the resulting constructors and attributes from model files.
|
|
41307
|
+
|
|
41308
|
+
## Directory and File Granularity
|
|
41309
|
+
|
|
41310
|
+
For larger repositories, group model files by context directory. Inside a
|
|
41311
|
+
context directory, default to one primary owned system per ordinary model file:
|
|
41312
|
+
the system that will be detailed by containers, services, components, links, and
|
|
41313
|
+
deployment information.
|
|
41314
|
+
|
|
41315
|
+
External actors and systems are different. Put reusable outside dependencies in
|
|
41316
|
+
one external context or a few semantically grouped external contexts. Do not
|
|
41317
|
+
create a separate file for every external actor or vendor unless that external
|
|
41318
|
+
dependency has real internal structure to model.
|
|
41319
|
+
|
|
41320
|
+
If a system needs further splitting, create a utility subdirectory for focused
|
|
41321
|
+
\`extend <object>\` files, such as per-service component files. Import the
|
|
41322
|
+
extended object explicitly when it is declared in another source file. Keep the
|
|
41323
|
+
main system file as the readable entry point.
|
|
41324
|
+
|
|
40640
41325
|
## Commands
|
|
40641
41326
|
|
|
40642
41327
|
Human-readable overview:
|
|
@@ -40684,6 +41369,33 @@ links:
|
|
|
40684
41369
|
-> payments from external_systems
|
|
40685
41370
|
\`\`\`
|
|
40686
41371
|
|
|
41372
|
+
Imports are also required when a declaration lives in another source file of the
|
|
41373
|
+
same context:
|
|
41374
|
+
|
|
41375
|
+
\`\`\`insight
|
|
41376
|
+
context services
|
|
41377
|
+
|
|
41378
|
+
import eu_service from context services
|
|
41379
|
+
|
|
41380
|
+
system checkout_api
|
|
41381
|
+
deployment:
|
|
41382
|
+
usesProfile eu_service
|
|
41383
|
+
\`\`\`
|
|
41384
|
+
|
|
41385
|
+
The explicit import is intentional. If the source file that declared
|
|
41386
|
+
\`eu_service\` is removed or excluded, validation should fail with a clear
|
|
41387
|
+
missing import/identifier diagnostic instead of depending on hidden file layout.
|
|
41388
|
+
|
|
41389
|
+
For links, \`from <context-id>\` on the target is an inline context qualifier:
|
|
41390
|
+
|
|
41391
|
+
\`\`\`insight
|
|
41392
|
+
links:
|
|
41393
|
+
-> inventory_api from services
|
|
41394
|
+
\`\`\`
|
|
41395
|
+
|
|
41396
|
+
Use it when the relationship target is owned by another context or another
|
|
41397
|
+
source file whose context ownership should remain visible at the call site.
|
|
41398
|
+
|
|
40687
41399
|
Do not guess context ids from filenames. Filenames, context ids, and element ids
|
|
40688
41400
|
can differ.
|
|
40689
41401
|
|
|
@@ -41141,6 +41853,16 @@ diagram needs stable layout.
|
|
|
41141
41853
|
|
|
41142
41854
|
## Built-In View Patterns
|
|
41143
41855
|
|
|
41856
|
+
Exact built-in query sources are bundled in:
|
|
41857
|
+
|
|
41858
|
+
\`\`\`text
|
|
41859
|
+
examples/builtin-views/no-filter.aiq
|
|
41860
|
+
examples/builtin-views/c1.aiq
|
|
41861
|
+
examples/builtin-views/c2.aiq
|
|
41862
|
+
examples/builtin-views/c3.aiq
|
|
41863
|
+
examples/builtin-views/c4.aiq
|
|
41864
|
+
\`\`\`
|
|
41865
|
+
|
|
41144
41866
|
C1 usually selects systems in the selected context and rolls lower-level links
|
|
41145
41867
|
up to system-level relationships.
|
|
41146
41868
|
|
|
@@ -41153,6 +41875,10 @@ and returns component relationships.
|
|
|
41153
41875
|
C4 usually selects deployment and container nodes from \`$tab\`, uses
|
|
41154
41876
|
\`OPTIONAL MATCH ROLLUP\`, and returns projected relationships.
|
|
41155
41877
|
|
|
41878
|
+
When a built-in view is close but hides the wrong thing, read
|
|
41879
|
+
\`references/query-recipes.md\`, copy the nearest built-in \`.aiq\`, and change
|
|
41880
|
+
the filter or grouping deliberately.
|
|
41881
|
+
|
|
41156
41882
|
## Authoring Rules
|
|
41157
41883
|
|
|
41158
41884
|
- Start from the view question: context, containers, components, or deployment.
|
|
@@ -41163,6 +41889,207 @@ C4 usually selects deployment and container nodes from \`$tab\`, uses
|
|
|
41163
41889
|
- Keep custom queries in \`.aiq\` files when they are reused.
|
|
41164
41890
|
`;
|
|
41165
41891
|
}
|
|
41892
|
+
function genericQueryRecipesReference() {
|
|
41893
|
+
return `# Query Recipes and Built-In View Customization
|
|
41894
|
+
|
|
41895
|
+
Use this reference when a built-in C1/C2/C3/C4 view is close but not quite right:
|
|
41896
|
+
an expected element is hidden, a relationship is missing, infrastructure is too
|
|
41897
|
+
noisy, or the diagram needs a different scope.
|
|
41898
|
+
|
|
41899
|
+
## Start From Built-In Queries
|
|
41900
|
+
|
|
41901
|
+
The generated skill includes exact built-in view queries:
|
|
41902
|
+
|
|
41903
|
+
\`\`\`text
|
|
41904
|
+
examples/builtin-views/no-filter.aiq
|
|
41905
|
+
examples/builtin-views/c1.aiq
|
|
41906
|
+
examples/builtin-views/c2.aiq
|
|
41907
|
+
examples/builtin-views/c3.aiq
|
|
41908
|
+
examples/builtin-views/c4.aiq
|
|
41909
|
+
\`\`\`
|
|
41910
|
+
|
|
41911
|
+
Before inventing a query from scratch, open the nearest built-in query, copy it
|
|
41912
|
+
to the project, and make the smallest change.
|
|
41913
|
+
|
|
41914
|
+
\`\`\`shell
|
|
41915
|
+
archinsight query . -c <context-id> -s <source.ai> -q queries/custom.aiq -f text
|
|
41916
|
+
archinsight render . -c <context-id> -s <source.ai> -q queries/custom.aiq -f svg -o custom.svg
|
|
41917
|
+
\`\`\`
|
|
41918
|
+
|
|
41919
|
+
Use \`references/queries.md\` for syntax details. Use this file for common
|
|
41920
|
+
customization patterns.
|
|
41921
|
+
|
|
41922
|
+
## When To Customize
|
|
41923
|
+
|
|
41924
|
+
Write or adjust a \`.aiq\` query when:
|
|
41925
|
+
|
|
41926
|
+
- the built-in view hides a node or edge that exists in \`archinsight link\`;
|
|
41927
|
+
- the source/tab scope is right but the view intentionally filters out a type;
|
|
41928
|
+
- C4 should include actors, vendors, or a special deployment path;
|
|
41929
|
+
- the diagram should show only one layer, one flow, or one relationship class;
|
|
41930
|
+
- grouping needs to change, such as grouping by parent instead of \`runsOn\`.
|
|
41931
|
+
|
|
41932
|
+
Do not compensate for a view filter by duplicating model elements. First inspect
|
|
41933
|
+
the built-in query and decide whether the model or the query owns the behavior.
|
|
41934
|
+
|
|
41935
|
+
## Graph Is Not The Picture
|
|
41936
|
+
|
|
41937
|
+
The linked model can have correct fan-in to one broker, gateway, load balancer,
|
|
41938
|
+
producer, or shared runtime node. A crowded diagram means the current view is too
|
|
41939
|
+
broad or not aggregated enough; it does not automatically mean the model is
|
|
41940
|
+
wrong.
|
|
41941
|
+
|
|
41942
|
+
When the graph is right but the picture is noisy:
|
|
41943
|
+
|
|
41944
|
+
- narrow \`-s <source.ai>\` to the file that owns the view;
|
|
41945
|
+
- copy the nearest \`examples/builtin-views/*.aiq\` query;
|
|
41946
|
+
- filter to the layer, flow, or relationship class the user asked for;
|
|
41947
|
+
- change \`GROUP BY\` to cluster by parent, runtime placement, or another useful
|
|
41948
|
+
attribute.
|
|
41949
|
+
|
|
41950
|
+
Do not duplicate infrastructure or invert dependencies only to make one render
|
|
41951
|
+
look cleaner.
|
|
41952
|
+
|
|
41953
|
+
## Diagnose A Missing Element
|
|
41954
|
+
|
|
41955
|
+
1. Validate the model:
|
|
41956
|
+
|
|
41957
|
+
\`\`\`shell
|
|
41958
|
+
archinsight link . --format text
|
|
41959
|
+
\`\`\`
|
|
41960
|
+
|
|
41961
|
+
2. Inspect declarations and source identities:
|
|
41962
|
+
|
|
41963
|
+
\`\`\`shell
|
|
41964
|
+
archinsight structure . --format text
|
|
41965
|
+
\`\`\`
|
|
41966
|
+
|
|
41967
|
+
3. Run the built-in query text explicitly:
|
|
41968
|
+
|
|
41969
|
+
\`\`\`shell
|
|
41970
|
+
archinsight query . -c <context-id> -s <source.ai> -q examples/builtin-views/c4.aiq -f text
|
|
41971
|
+
\`\`\`
|
|
41972
|
+
|
|
41973
|
+
4. Check the query filters:
|
|
41974
|
+
|
|
41975
|
+
- \`node.sourceIdentity = $tab\` means the node must be declared in the selected
|
|
41976
|
+
source file.
|
|
41977
|
+
- \`node IS DeploymentElement\` hides actors and ordinary logical elements.
|
|
41978
|
+
- \`{projected}\` means only derived deployment projection edges are selected.
|
|
41979
|
+
- \`{derived}\` means only rolled-up relationships are selected.
|
|
41980
|
+
- \`sourceIdentity: $tab\` on an edge means the relationship/projection must come
|
|
41981
|
+
from the selected source.
|
|
41982
|
+
|
|
41983
|
+
## Include External Actors In C4
|
|
41984
|
+
|
|
41985
|
+
The built-in C4 query focuses on deployment/container nodes. If a deployment
|
|
41986
|
+
diagram needs the external actor that starts the traffic path, copy
|
|
41987
|
+
\`examples/builtin-views/c4.aiq\` and widen the node and projected target filters:
|
|
41988
|
+
|
|
41989
|
+
\`\`\`cypher
|
|
41990
|
+
MATCH (node:Element)
|
|
41991
|
+
WHERE node.sourceIdentity = $tab
|
|
41992
|
+
AND (node IS DeploymentElement OR node IS ContainerElement OR node IS Actor)
|
|
41993
|
+
OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected, sourceIdentity: $tab}]->(projectedTarget:Element)
|
|
41994
|
+
WHERE projectedTarget IS DeploymentElement
|
|
41995
|
+
OR projectedTarget IS ContainerElement
|
|
41996
|
+
OR projectedTarget IS External
|
|
41997
|
+
OR projectedTarget IS Actor
|
|
41998
|
+
OPTIONAL MATCH (node)-[directDeploymentLink {sourceIdentity: $tab}]->(directDeploymentTarget:Element)
|
|
41999
|
+
WHERE node IS DeploymentElement
|
|
42000
|
+
AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
|
|
42001
|
+
GROUP BY node.runsOn
|
|
42002
|
+
RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
|
|
42003
|
+
\`\`\`
|
|
42004
|
+
|
|
42005
|
+
If the actor is declared in another source file, either render from that source
|
|
42006
|
+
or relax the \`node.sourceIdentity = $tab\` condition intentionally.
|
|
42007
|
+
|
|
42008
|
+
## Show Only Async Flows
|
|
42009
|
+
|
|
42010
|
+
Use edge attributes when the question is about relationship kind:
|
|
42011
|
+
|
|
42012
|
+
\`\`\`cypher
|
|
42013
|
+
MATCH (source:Element)-[link]->(target:Element)
|
|
42014
|
+
WHERE source.context = $context
|
|
42015
|
+
AND link.model = 'async'
|
|
42016
|
+
GROUP BY source.parent
|
|
42017
|
+
RETURN source, link, target
|
|
42018
|
+
\`\`\`
|
|
42019
|
+
|
|
42020
|
+
This is useful for event-stream, broker, queue, or notification diagrams. Add
|
|
42021
|
+
\`source.sourceIdentity = $tab\` when the query should stay scoped to one file.
|
|
42022
|
+
|
|
42023
|
+
## Hide Deployment Infrastructure
|
|
42024
|
+
|
|
42025
|
+
When a C4-oriented source file is too noisy and you only need logical containers
|
|
42026
|
+
or services, select logical container elements and direct logical relationships:
|
|
42027
|
+
|
|
42028
|
+
\`\`\`cypher
|
|
42029
|
+
MATCH (node:ContainerElement)
|
|
42030
|
+
WHERE node.sourceIdentity = $tab
|
|
42031
|
+
OPTIONAL MATCH (node)-[link]->(target:ContainerElement)
|
|
42032
|
+
GROUP BY node.parent
|
|
42033
|
+
RETURN node, link, target
|
|
42034
|
+
\`\`\`
|
|
42035
|
+
|
|
42036
|
+
This is intentionally closer to C2 than C4. Use it when deployment annotations
|
|
42037
|
+
exist in the file but the diagram question is still logical.
|
|
42038
|
+
|
|
42039
|
+
## Show Projected Edges Across Split Files
|
|
42040
|
+
|
|
42041
|
+
The built-in C4 query restricts projected edges to \`sourceIdentity: $tab\`. That
|
|
42042
|
+
is usually correct for a focused deployment-view source file, but it can hide
|
|
42043
|
+
projected edges when traffic relationships were split across files.
|
|
42044
|
+
|
|
42045
|
+
Copy \`examples/builtin-views/c4.aiq\` and relax only the projected edge selector:
|
|
42046
|
+
|
|
42047
|
+
\`\`\`cypher
|
|
42048
|
+
MATCH (node:Element)
|
|
42049
|
+
WHERE node.sourceIdentity = $tab
|
|
42050
|
+
AND (node IS DeploymentElement OR node IS ContainerElement)
|
|
42051
|
+
OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)
|
|
42052
|
+
WHERE projectedTarget IS DeploymentElement
|
|
42053
|
+
OR projectedTarget IS ContainerElement
|
|
42054
|
+
OR projectedTarget IS External
|
|
42055
|
+
OPTIONAL MATCH (node)-[directDeploymentLink {sourceIdentity: $tab}]->(directDeploymentTarget:Element)
|
|
42056
|
+
WHERE node IS DeploymentElement
|
|
42057
|
+
AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
|
|
42058
|
+
GROUP BY node.runsOn
|
|
42059
|
+
RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
|
|
42060
|
+
\`\`\`
|
|
42061
|
+
|
|
42062
|
+
Use this deliberately. Removing the source filter can bring in projections from
|
|
42063
|
+
other view files, so validate the result with \`archinsight query\` before
|
|
42064
|
+
rendering.
|
|
42065
|
+
|
|
42066
|
+
## Change Grouping
|
|
42067
|
+
|
|
42068
|
+
Grouping controls visual clusters. If C4 grouping by \`runsOn\` is not helpful,
|
|
42069
|
+
try grouping by parent:
|
|
42070
|
+
|
|
42071
|
+
\`\`\`cypher
|
|
42072
|
+
MATCH (node:Element)
|
|
42073
|
+
WHERE node.sourceIdentity = $tab
|
|
42074
|
+
AND (node IS DeploymentElement OR node IS ContainerElement)
|
|
42075
|
+
OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected, sourceIdentity: $tab}]->(projectedTarget:Element)
|
|
42076
|
+
WHERE projectedTarget IS DeploymentElement
|
|
42077
|
+
OR projectedTarget IS ContainerElement
|
|
42078
|
+
OR projectedTarget IS External
|
|
42079
|
+
GROUP BY node.parent
|
|
42080
|
+
RETURN node, projectedLink, projectedTarget
|
|
42081
|
+
\`\`\`
|
|
42082
|
+
|
|
42083
|
+
Use \`GROUP BY node.runsOn\` for deployment placement; use \`GROUP BY node.parent\`
|
|
42084
|
+
for logical ownership.
|
|
42085
|
+
|
|
42086
|
+
## Working Rule
|
|
42087
|
+
|
|
42088
|
+
If a diagram looks wrong but \`archinsight link\` is clean, inspect the selected
|
|
42089
|
+
source, built-in query, and returned aliases before changing the model. Many
|
|
42090
|
+
display issues are query scope issues, not schema or linker bugs.
|
|
42091
|
+
`;
|
|
42092
|
+
}
|
|
41166
42093
|
function genericLayeredArchitectureExample() {
|
|
41167
42094
|
return `context shop
|
|
41168
42095
|
name = Shop Platform
|
|
@@ -41346,6 +42273,11 @@ external system payment_provider
|
|
|
41346
42273
|
external system analytics_platform
|
|
41347
42274
|
name = Analytics Platform
|
|
41348
42275
|
technology = Kafka consumer
|
|
42276
|
+
links:
|
|
42277
|
+
~> checkout_api
|
|
42278
|
+
technology = Kafka
|
|
42279
|
+
via = checkout.completed
|
|
42280
|
+
description = Consumes completed checkout events
|
|
41349
42281
|
|
|
41350
42282
|
system storefront
|
|
41351
42283
|
name = Storefront
|
|
@@ -41376,12 +42308,6 @@ system storefront
|
|
|
41376
42308
|
name = Checkout API
|
|
41377
42309
|
technology = Kotlin, PostgreSQL
|
|
41378
42310
|
description = Prices carts, creates orders, and coordinates payment
|
|
41379
|
-
links:
|
|
41380
|
-
~> analytics_platform
|
|
41381
|
-
technology = Kafka
|
|
41382
|
-
via = checkout.completed
|
|
41383
|
-
description = Publishes completed checkout events
|
|
41384
|
-
|
|
41385
42311
|
component checkout_controller
|
|
41386
42312
|
name = Checkout controller
|
|
41387
42313
|
technology = REST controller
|
|
@@ -41398,10 +42324,6 @@ system storefront
|
|
|
41398
42324
|
call = authorize(paymentCommand)
|
|
41399
42325
|
description = Requests payment authorization
|
|
41400
42326
|
-> order_repository
|
|
41401
|
-
~> checkout_events
|
|
41402
|
-
technology = Kafka
|
|
41403
|
-
via = checkout.completed
|
|
41404
|
-
description = Publishes completed checkout events
|
|
41405
42327
|
|
|
41406
42328
|
component payment_gateway
|
|
41407
42329
|
name = Payment gateway
|
|
@@ -41418,10 +42340,15 @@ system storefront
|
|
|
41418
42340
|
technology = SQL
|
|
41419
42341
|
responsibility = Stores order state and checkout audit records
|
|
41420
42342
|
|
|
41421
|
-
component
|
|
41422
|
-
name = Checkout
|
|
41423
|
-
technology = Kafka
|
|
41424
|
-
responsibility =
|
|
42343
|
+
component checkout_projection
|
|
42344
|
+
name = Checkout projection
|
|
42345
|
+
technology = Kafka consumer
|
|
42346
|
+
responsibility = Maintains an internal checkout read model from events
|
|
42347
|
+
links:
|
|
42348
|
+
~> checkout_service
|
|
42349
|
+
technology = Kafka
|
|
42350
|
+
via = checkout.completed
|
|
42351
|
+
description = Consumes checkout completion events
|
|
41425
42352
|
`;
|
|
41426
42353
|
}
|
|
41427
42354
|
function genericC4DeploymentFrameworkExample() {
|
|
@@ -41490,7 +42417,6 @@ deploymentProfile public_regional_service
|
|
|
41490
42417
|
|
|
41491
42418
|
runsOn compute
|
|
41492
42419
|
uses observability
|
|
41493
|
-
uses publicGateway
|
|
41494
42420
|
|
|
41495
42421
|
environment prod
|
|
41496
42422
|
name = Production
|
|
@@ -41619,11 +42545,25 @@ system storefront
|
|
|
41619
42545
|
deployment:
|
|
41620
42546
|
usesProfile regional_service
|
|
41621
42547
|
uses storage
|
|
41622
|
-
uses broker
|
|
41623
42548
|
links:
|
|
41624
42549
|
-> payment_provider
|
|
41625
42550
|
technology = HTTPS
|
|
41626
42551
|
call = POST /payments/authorizations
|
|
42552
|
+
|
|
42553
|
+
service order_worker
|
|
42554
|
+
name = Order Worker
|
|
42555
|
+
technology = Kotlin
|
|
42556
|
+
description = Processes order events asynchronously
|
|
42557
|
+
deployment:
|
|
42558
|
+
usesProfile regional_service
|
|
42559
|
+
links:
|
|
42560
|
+
~> checkout_api
|
|
42561
|
+
technology = Kafka
|
|
42562
|
+
via = orders.events
|
|
42563
|
+
description = Consumes order events emitted by Checkout API
|
|
42564
|
+
deployment:
|
|
42565
|
+
environmentsFrom regional_service
|
|
42566
|
+
uses broker
|
|
41627
42567
|
`;
|
|
41628
42568
|
}
|
|
41629
42569
|
function genericC2QueryExample() {
|