@sdd-method/sdd-cli 0.25.3 → 0.26.0

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.
@@ -1,22 +1,32 @@
1
- // Events discoverer — emits `events.csv` from avro contracts (kind=event).
1
+ // Events discoverer — emits `events.csv` from two canonical sources per
2
+ // ADR 0156 (multi-source ingestion):
2
3
  //
3
- // In the forward method, every avro `*.avsc` schema declares one event;
4
- // the canonical builder treats events as 1:1 with avro contracts and
5
- // reuses the contract's id as the event id.
4
+ // Forward-method canonical: `contracts/avro/*.avsc` files (existing path).
5
+ // The avsc id becomes the event id; publisher_service_id reads from
6
+ // `repo-config.events.produces[].schema` resolved against the avsc index.
7
+ // Reverse-method canonical: `docs/domains/<domain>/contracts/events/
8
+ // event-catalog.yaml` (new path, walked by event-catalog-walker.ts).
9
+ // One file per domain; each entry carries name, publisher_service_id,
10
+ // transport, schema_path, version, consumers[].
6
11
  //
7
- // publisher_service_id derivation: ONLY events.produces is authoritative.
8
- // `contracts.avro` is a build-time list (for code-gen / validation) and
9
- // MUST NOT be inferred as a publish declaration services that consume
10
- // avro schemas commonly list them under contracts.avro too. If no
11
- // service declares events.produces for a given schema, the event row
12
- // emits with empty publisher_service_id.
12
+ // Merge precedence when both sources declare an event (matched by id slug):
13
+ // - name, domain_id, publisher_service_id, transport YAML wins
14
+ // - schema_path, version YAML wins when set; avsc augments when null
15
+ // - Events declared only in avsc forward-only row (existing behaviour)
16
+ // - Events declared only in YAML reverse-only row (new)
13
17
  //
14
- // transport defaults to `nats` per ADR 0068 (Scaleway MnQ NATS for
15
- // platform messaging). The schema's enum doesn't include "nats" today;
16
- // the column is nullable string so any value is accepted.
18
+ // Transport: open string per ADR 0156 (no hardcoded default). When the
19
+ // source is avsc-only with no `repo-config.events` declaration, transport
20
+ // may be empty.
17
21
  import { sep } from "node:path";
18
- export function buildEvents(inputs) {
19
- // Build the publisher index from repo-config events.produces only.
22
+ import { mergeYamlAndAvsc, walkEventCatalogs, } from "./event-catalog-walker.js";
23
+ export async function buildEvents(inputs) {
24
+ // 1. Walk the reverse-method canonical source (event-catalog.yaml files).
25
+ const yamlResult = await walkEventCatalogs({
26
+ sddPath: inputs.sddPath,
27
+ findings: inputs.findings,
28
+ });
29
+ // 2. Build the forward-method publisher index from repo-config events.produces.
20
30
  // Earlier-encountered service wins on ties (deterministic per sorted
21
31
  // config order from the repositories builder).
22
32
  const publisherByContractId = new Map();
@@ -37,7 +47,8 @@ export function buildEvents(inputs) {
37
47
  }
38
48
  }
39
49
  }
40
- const rows = [];
50
+ // 3. Build avsc-derived event rows (forward path), indexed by id for merge.
51
+ const avscRows = new Map();
41
52
  for (const c of inputs.avroContracts) {
42
53
  const id = String(c["id"]);
43
54
  const specPath = String(c["spec_path"] ?? "");
@@ -45,25 +56,59 @@ export function buildEvents(inputs) {
45
56
  let domain = rawDomain;
46
57
  if (rawDomain.startsWith("_")) {
47
58
  // `_common`, `_shared`, etc. — cross-domain envelope schemas.
48
- // Emit empty domain_id (events.domain_id is nullable per schema 1.4.0).
49
59
  domain = "";
50
60
  }
51
61
  else if (rawDomain !== "" && !inputs.knownDomainIds.has(rawDomain)) {
52
62
  inputs.findings.add("orphan", `event ${id}: schema is at ${specPath} but no docs/domains/${rawDomain}/ exists — emitting with empty domain_id`);
53
63
  domain = "";
54
64
  }
55
- rows.push({
65
+ avscRows.set(id, {
56
66
  id,
57
67
  name: String(c["name"] ?? id),
58
68
  publisher_service_id: publisherByContractId.get(id) ?? "",
59
69
  domain_id: domain,
60
- transport: "nats",
70
+ transport: "",
61
71
  schema_path: specPath,
62
72
  version: String(c["version"] ?? ""),
63
73
  source_sdd_id: "",
64
74
  });
65
75
  }
66
- return { rows, publisherIndex: { publisherByContractId } };
76
+ // 4. Merge YAML + avsc. YAML rows win on overlapping fields.
77
+ const merged = new Map();
78
+ for (const [id, yaml] of yamlResult.byId) {
79
+ const avsc = avscRows.get(id);
80
+ const baseRow = mergeYamlAndAvsc(yaml, avsc);
81
+ // Resolve domain_id against known domains; empty if unknown.
82
+ let domainId = String(baseRow["domain_id"] ?? "");
83
+ if (domainId !== "" && !inputs.knownDomainIds.has(domainId)) {
84
+ inputs.findings.add("orphan", `event ${id}: event-catalog.yaml declares domain "${domainId}" but no docs/domains/${domainId}/ exists — emitting with empty domain_id`);
85
+ domainId = "";
86
+ }
87
+ // Resolve publisher against known services.
88
+ let publisher = String(baseRow["publisher_service_id"] ?? "");
89
+ if (publisher !== "" && !inputs.knownServiceIds.has(publisher)) {
90
+ inputs.findings.add("orphan", `event ${id}: publisher_service_id "${publisher}" does not resolve to a known service — emitting with empty publisher_service_id`);
91
+ publisher = "";
92
+ }
93
+ merged.set(id, {
94
+ ...baseRow,
95
+ domain_id: domainId,
96
+ publisher_service_id: publisher,
97
+ });
98
+ }
99
+ // Avsc-only events (no YAML row): keep the existing avsc-derived row as-is.
100
+ for (const [id, row] of avscRows) {
101
+ if (!merged.has(id)) {
102
+ merged.set(id, row);
103
+ }
104
+ }
105
+ // 5. Deterministic order: sort by id.
106
+ const rows = [...merged.values()].sort((a, b) => String(a["id"]).localeCompare(String(b["id"])));
107
+ return {
108
+ rows,
109
+ publisherIndex: { publisherByContractId },
110
+ yamlEvents: yamlResult.byId,
111
+ };
67
112
  }
68
113
  function inferDomainFromAvroPath(relPath) {
69
114
  // Layout: contracts/avro/<domain>/<file>.avsc
@@ -74,20 +119,17 @@ function inferDomainFromAvroPath(relPath) {
74
119
  }
75
120
  function resolveContractByPath(schema, kind, index) {
76
121
  const cleaned = schema.replace(/^\/+/, "");
77
- // Repo-config event paths are relative to contracts/<kind>/.
78
122
  const fullCandidate = `contracts/${kind}/${cleaned}`;
79
123
  if (index.has(fullCandidate))
80
124
  return index.get(fullCandidate);
81
125
  if (index.has(cleaned))
82
126
  return index.get(cleaned);
83
- // Suffix fallback (last two segments).
84
127
  for (const [path, id] of index) {
85
128
  const parts = path.split(sep);
86
129
  const last2 = parts.length >= 2 ? parts.slice(-2).join("/") : "";
87
130
  if (last2 === cleaned)
88
131
  return id;
89
132
  }
90
- // Basename fallback.
91
133
  const base = cleaned.split("/").slice(-1)[0] ?? cleaned;
92
134
  for (const [path, id] of index) {
93
135
  const parts = path.split(sep);
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/events.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,17 @@ export interface GlossaryXrefInputs {
5
5
  readonly findings: FindingsLog;
6
6
  /** From the glossary builder: `<domain>:<term>` (lower-case term) → glossary_items.id. */
7
7
  readonly idByDomainTerm: ReadonlyMap<string, string>;
8
+ /** Term name (case-insensitive) → set of (domain, id) for resolving raw term names. */
9
+ readonly idsByTermName?: ReadonlyMap<string, ReadonlyArray<{
10
+ domain: string;
11
+ id: string;
12
+ }>>;
8
13
  readonly knownGlossaryIds: ReadonlySet<string>;
14
+ readonly knownDomainIds: ReadonlySet<string>;
9
15
  }
10
- export declare function buildGlossaryXref(inputs: GlossaryXrefInputs): Promise<CatalogueRow[]>;
16
+ export interface GlossaryXrefResult {
17
+ readonly glossaryXref: CatalogueRow[];
18
+ readonly entityGlossary: CatalogueRow[];
19
+ }
20
+ export declare function buildGlossaryXref(inputs: GlossaryXrefInputs): Promise<GlossaryXrefResult>;
11
21
  //# sourceMappingURL=glossary-xref.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"glossary-xref.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/glossary-xref.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,0FAA0F;IAC1F,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChD;AASD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,EAAE,CAAC,CAqEzB"}
1
+ {"version":3,"file":"glossary-xref.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/glossary-xref.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,0FAA0F;IAC1F,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,uFAAuF;IACvF,QAAQ,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC5F,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,YAAY,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,YAAY,EAAE,CAAC;CACzC;AAWD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAgU7B"}
@@ -1,21 +1,42 @@
1
- // glossary_xref edge builderemits cross-domain glossary
1
+ // glossary_xref + entity_glossary edge buildersemit cross-domain glossary
2
2
  // relationships from `docs/platform/reference/glossary-alignment-manifest.yaml`.
3
3
  //
4
- // Expected manifest shape (canonical):
4
+ // Per ADR 0158 (Glossary Cross-Reference Multi-Source Ingestion, schema 2.12.0),
5
+ // the builder ingests from FIVE walkers:
5
6
  //
6
- // aliases:
7
- // - source: <source-domain>:<term>
8
- // target: <target-domain>:<term>
9
- // conflicts:
10
- // - source: <source-domain>:<term>
11
- // target: <target-domain>:<term>
7
+ // 1. Forward declared pair-form (existing).
8
+ // aliases: [{source, target}]
9
+ // conflicts: [{source, target}]
10
+ // Emits glossary_xref rows with relation ∈ {alias-of, conflicts-with}.
12
11
  //
13
- // Or the per-entry shape with `source_id`/`target_id` fields directly.
12
+ // 2. Reverse-method cross_domain_terms (new).
13
+ // cross_domain_terms:
14
+ // - term: <name>
15
+ // owner: <domain>
16
+ // referenced_by: [<domain>, ...]
17
+ // One row per (referencer, owner) pair with relation=references.
14
18
  //
15
- // Adopters whose alignment manifest is in a different shape (e.g.
16
- // data-dictionary alignment rather than cross-domain term aliasing)
17
- // will simply produce zero rows. This builder logs a `convention`
18
- // finding when a manifest exists but no expected blocks are present.
19
+ // 3. Reverse-method multi-domain conflicts (new).
20
+ // conflicts:
21
+ // - term: <name>
22
+ // domains: [{domain, meaning}, ...]
23
+ // resolution: <text>
24
+ // Pair-wise expansion across domains[] with relation=conflicts-with.
25
+ // Disambiguated from #1 by per-entry field inspection.
26
+ //
27
+ // 4. Forward-method supersedes (new).
28
+ // models[].entities[] with status: superseded + superseded_by
29
+ // One row per supersedes mapping after resolving both endpoints'
30
+ // glossary_term against glossary_items.csv. Orphan finding when an
31
+ // endpoint doesn't resolve.
32
+ //
33
+ // 5. Forward-method entity-mapping (new, writes to entity_glossary).
34
+ // models[].entities[] with status ∈ {aligned, matched_direct} and
35
+ // non-empty glossary_term.
36
+ // One row per (domain, entity_name, glossary_term) tuple after dedup.
37
+ // Same-domain multi-diagram entries collapse to one row; cross-domain
38
+ // entries (e.g. platform-wide conceptual + party-domain detailed)
39
+ // emit one row per domain — legitimate cross-level cataloguing.
19
40
  import { readFile } from "node:fs/promises";
20
41
  import { join } from "node:path";
21
42
  import { parse as parseYaml } from "yaml";
@@ -29,7 +50,7 @@ export async function buildGlossaryXref(inputs) {
29
50
  catch (err) {
30
51
  const code = err.code;
31
52
  if (code === "ENOENT")
32
- return [];
53
+ return { glossaryXref: [], entityGlossary: [] };
33
54
  throw err;
34
55
  }
35
56
  let raw;
@@ -38,43 +59,266 @@ export async function buildGlossaryXref(inputs) {
38
59
  }
39
60
  catch (err) {
40
61
  inputs.findings.add("convention", `${MANIFEST_REL_PATH}: failed to parse YAML — ${err.message}`);
41
- return [];
62
+ return { glossaryXref: [], entityGlossary: [] };
42
63
  }
43
64
  if (!raw || typeof raw !== "object")
44
- return [];
65
+ return { glossaryXref: [], entityGlossary: [] };
45
66
  const obj = raw;
46
- const aliases = collectPairs(obj["aliases"]);
47
- const conflicts = collectPairs(obj["conflicts_with"] ?? obj["conflicts"]);
48
- if (aliases.length === 0 && conflicts.length === 0) {
49
- inputs.findings.add("convention", `${MANIFEST_REL_PATH}: present but no aliases/conflicts blocks recognised — emitting 0 xref rows`);
50
- return [];
51
- }
52
- const rows = [];
53
- const seen = new Set();
54
- const emit = (rawSource, rawTarget, relation) => {
55
- const sourceId = resolveTerm(rawSource, inputs);
56
- const targetId = resolveTerm(rawTarget, inputs);
57
- if (sourceId === undefined) {
58
- inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: ${relation} source "${rawSource}" doesn't resolve to a known glossary item`);
59
- return;
60
- }
61
- if (targetId === undefined) {
62
- inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: ${relation} target "${rawTarget}" doesn't resolve to a known glossary item`);
63
- return;
64
- }
67
+ const xrefRows = [];
68
+ const xrefSeen = new Set();
69
+ const entityRows = [];
70
+ const entitySeen = new Map();
71
+ const emitXref = (sourceId, targetId, relation) => {
65
72
  if (sourceId === targetId)
66
- return; // self-reference is meaningless
73
+ return;
67
74
  const id = `${sourceId}__${relation}__${targetId}`;
68
- if (seen.has(id))
75
+ if (xrefSeen.has(id))
69
76
  return;
70
- seen.add(id);
71
- rows.push({ id, source_id: sourceId, target_id: targetId, relation });
77
+ xrefSeen.add(id);
78
+ xrefRows.push({ id, source_id: sourceId, target_id: targetId, relation });
72
79
  };
73
- for (const { source, target } of aliases)
74
- emit(source, target, "alias-of");
75
- for (const { source, target } of conflicts)
76
- emit(source, target, "conflicts-with");
77
- return rows;
80
+ // Walker 1 forward declared pair-form aliases.
81
+ const aliasesRaw = obj["aliases"];
82
+ for (const pair of collectPairs(aliasesRaw)) {
83
+ const sourceId = resolveTerm(pair.source, inputs);
84
+ const targetId = resolveTerm(pair.target, inputs);
85
+ if (sourceId === undefined) {
86
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: alias-of source "${pair.source}" doesn't resolve to a known glossary item`);
87
+ continue;
88
+ }
89
+ if (targetId === undefined) {
90
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: alias-of target "${pair.target}" doesn't resolve to a known glossary item`);
91
+ continue;
92
+ }
93
+ emitXref(sourceId, targetId, "alias-of");
94
+ }
95
+ // Walkers 1+3 — `conflicts` key: disambiguated per-entry.
96
+ // Pair-form {source, target} → forward (alias-style conflicts-with).
97
+ // Multi-domain {term, domains[]} → reverse-method walker.
98
+ const conflictsRaw = obj["conflicts_with"] ?? obj["conflicts"];
99
+ if (Array.isArray(conflictsRaw)) {
100
+ for (const item of conflictsRaw) {
101
+ if (!item || typeof item !== "object")
102
+ continue;
103
+ const o = item;
104
+ const hasPairFields = "source" in o || "source_id" in o || "target" in o || "target_id" in o;
105
+ const hasReverseFields = "term" in o && "domains" in o && Array.isArray(o["domains"]);
106
+ if (hasPairFields && hasReverseFields) {
107
+ inputs.findings.add("divergence", `${MANIFEST_REL_PATH}: glossary-xref conflicts entry has mixed forward/reverse fields — skipped`);
108
+ continue;
109
+ }
110
+ if (hasPairFields) {
111
+ const source = String(o["source"] ?? o["source_id"] ?? "").trim();
112
+ const target = String(o["target"] ?? o["target_id"] ?? "").trim();
113
+ if (source === "" || target === "")
114
+ continue;
115
+ const sourceId = resolveTerm(source, inputs);
116
+ const targetId = resolveTerm(target, inputs);
117
+ if (sourceId === undefined) {
118
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: conflicts-with source "${source}" doesn't resolve to a known glossary item`);
119
+ continue;
120
+ }
121
+ if (targetId === undefined) {
122
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: conflicts-with target "${target}" doesn't resolve to a known glossary item`);
123
+ continue;
124
+ }
125
+ emitXref(sourceId, targetId, "conflicts-with");
126
+ }
127
+ else if (hasReverseFields) {
128
+ const term = String(o["term"] ?? "").trim();
129
+ const domains = o["domains"].map((d) => {
130
+ if (!d || typeof d !== "object")
131
+ return null;
132
+ return String(d["domain"] ?? "").trim();
133
+ }).filter((d) => d !== null && d !== "");
134
+ // Resolve each domain to its term-specific glossary id.
135
+ const resolvedIds = [];
136
+ for (const domain of domains) {
137
+ const id = inputs.idByDomainTerm.get(`${domain}:${term.toLowerCase()}`);
138
+ if (id === undefined) {
139
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: conflicts entry "${term}" domain "${domain}" — no domain-local glossary item`);
140
+ continue;
141
+ }
142
+ resolvedIds.push({ domain, id });
143
+ }
144
+ // Pair-wise emit across domains[i] × domains[j] for i<j.
145
+ for (let i = 0; i < resolvedIds.length; i++) {
146
+ for (let j = i + 1; j < resolvedIds.length; j++) {
147
+ emitXref(resolvedIds[i].id, resolvedIds[j].id, "conflicts-with");
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ // Walker 2 — reverse-method cross_domain_terms.
154
+ const crossDomainTermsRaw = obj["cross_domain_terms"];
155
+ if (Array.isArray(crossDomainTermsRaw)) {
156
+ for (const item of crossDomainTermsRaw) {
157
+ if (!item || typeof item !== "object")
158
+ continue;
159
+ const o = item;
160
+ const term = String(o["term"] ?? "").trim();
161
+ const owner = String(o["owner"] ?? "").trim();
162
+ if (term === "" || owner === "")
163
+ continue;
164
+ const ownerTermId = inputs.idByDomainTerm.get(`${owner}:${term.toLowerCase()}`);
165
+ if (ownerTermId === undefined) {
166
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: cross_domain_terms entry "${term}" owner "${owner}" doesn't resolve to a glossary item`);
167
+ continue;
168
+ }
169
+ const referencedByRaw = o["referenced_by"];
170
+ if (!Array.isArray(referencedByRaw))
171
+ continue;
172
+ for (const refDomain of referencedByRaw) {
173
+ const domain = String(refDomain ?? "").trim();
174
+ if (domain === "")
175
+ continue;
176
+ const referencerId = inputs.idByDomainTerm.get(`${domain}:${term.toLowerCase()}`);
177
+ if (referencerId === undefined) {
178
+ // Domain doesn't have its own glossary entry for the term — note
179
+ // this and skip (no edge can resolve when source is unknown).
180
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: cross_domain_terms entry "${term}" referencer "${domain}" has no domain-local glossary item — edge skipped`);
181
+ continue;
182
+ }
183
+ emitXref(referencerId, ownerTermId, "references");
184
+ }
185
+ }
186
+ }
187
+ // Walkers 4 + 5 — models[].entities[] (forward-method supersedes + entity-mapping).
188
+ const modelsRaw = obj["models"];
189
+ if (Array.isArray(modelsRaw)) {
190
+ // First pass: index all entities by name for supersedes resolution.
191
+ const entityByName = new Map();
192
+ for (const m of modelsRaw) {
193
+ if (!m || typeof m !== "object")
194
+ continue;
195
+ const mObj = m;
196
+ const domain = String(mObj["domain"] ?? "").trim();
197
+ const entitiesRaw = mObj["entities"];
198
+ if (!Array.isArray(entitiesRaw))
199
+ continue;
200
+ for (const e of entitiesRaw) {
201
+ if (!e || typeof e !== "object")
202
+ continue;
203
+ const eObj = e;
204
+ const name = String(eObj["name"] ?? "").trim();
205
+ const glossaryTerm = String(eObj["glossary_term"] ?? "").trim();
206
+ if (name === "" || glossaryTerm === "")
207
+ continue;
208
+ // First-seen wins; cross-domain entries don't overwrite. Used only
209
+ // by supersedes walker for back-link resolution.
210
+ if (!entityByName.has(name)) {
211
+ entityByName.set(name, { domain, glossaryTerm });
212
+ }
213
+ }
214
+ }
215
+ // Second pass: emit entity_glossary + supersedes edges.
216
+ for (const m of modelsRaw) {
217
+ if (!m || typeof m !== "object")
218
+ continue;
219
+ const mObj = m;
220
+ const domain = String(mObj["domain"] ?? "").trim();
221
+ const entitiesRaw = mObj["entities"];
222
+ if (!Array.isArray(entitiesRaw))
223
+ continue;
224
+ for (const e of entitiesRaw) {
225
+ if (!e || typeof e !== "object")
226
+ continue;
227
+ const eObj = e;
228
+ const name = String(eObj["name"] ?? "").trim();
229
+ const status = String(eObj["status"] ?? "").trim();
230
+ const glossaryTerm = String(eObj["glossary_term"] ?? "").trim();
231
+ if (status === "superseded") {
232
+ const supersededBy = String(eObj["superseded_by"] ?? "").trim();
233
+ if (supersededBy === "") {
234
+ inputs.findings.add("coverage", `${MANIFEST_REL_PATH}: superseded marker on ${name} has no superseded_by field`);
235
+ continue;
236
+ }
237
+ if (glossaryTerm === "") {
238
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: supersedes edge can't emit — ${name} has no glossary_term`);
239
+ continue;
240
+ }
241
+ const sourceId = inputs.idByDomainTerm.get(`${domain}:${glossaryTerm.toLowerCase()}`)
242
+ ?? resolveTermByName(glossaryTerm, inputs);
243
+ const targetEntity = entityByName.get(supersededBy);
244
+ const targetId = targetEntity === undefined
245
+ ? undefined
246
+ : inputs.idByDomainTerm.get(`${targetEntity.domain}:${targetEntity.glossaryTerm.toLowerCase()}`)
247
+ ?? resolveTermByName(targetEntity.glossaryTerm, inputs);
248
+ if (sourceId === undefined) {
249
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: supersedes edge can't emit — source "${glossaryTerm}" doesn't resolve to a glossary item`);
250
+ continue;
251
+ }
252
+ if (targetId === undefined) {
253
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: supersedes edge can't emit — target "${supersededBy}" (→ glossary "${targetEntity?.glossaryTerm ?? "?"}") doesn't resolve to a glossary item`);
254
+ continue;
255
+ }
256
+ emitXref(sourceId, targetId, "supersedes");
257
+ continue;
258
+ }
259
+ if ((status === "aligned" || status === "matched_direct") && glossaryTerm !== "") {
260
+ // Entity-mapping walker writes to entity_glossary.csv.
261
+ if (domain === "" || !inputs.knownDomainIds.has(domain)) {
262
+ // Domain not in this SDD's domains.csv — likely "platform-wide"
263
+ // or another scope identifier. Skip with a coverage finding.
264
+ inputs.findings.add("coverage", `${MANIFEST_REL_PATH}: entity ${name} domain "${domain}" not in known domains — entity_glossary row skipped`);
265
+ continue;
266
+ }
267
+ const glossaryItemId = inputs.idByDomainTerm.get(`${domain}:${glossaryTerm.toLowerCase()}`)
268
+ ?? resolveTermByName(glossaryTerm, inputs);
269
+ if (glossaryItemId === undefined) {
270
+ inputs.findings.add("orphan", `${MANIFEST_REL_PATH}: entity ${name} glossary_term "${glossaryTerm}" doesn't resolve to a glossary item — entity_glossary row skipped`);
271
+ continue;
272
+ }
273
+ const entityNameSlug = slugify(name);
274
+ const id = `${domain}__${entityNameSlug}__${glossaryItemId}`;
275
+ const existing = entitySeen.get(id);
276
+ if (existing !== undefined) {
277
+ // Dedup: matched_direct wins over aligned; same status = no-op;
278
+ // conflicting statuses fire divergence finding.
279
+ const existingStatus = String(existing["status"]);
280
+ if (existingStatus === status)
281
+ continue;
282
+ const winner = status === "matched_direct" ? status : existingStatus;
283
+ if (existingStatus !== winner) {
284
+ entitySeen.set(id, {
285
+ ...existing,
286
+ status: winner,
287
+ });
288
+ }
289
+ inputs.findings.add("divergence", `${MANIFEST_REL_PATH}: entity ${name} in domain ${domain} has conflicting statuses across models (${existingStatus} vs ${status}) — keeping ${winner} (per ADR 0158)`);
290
+ continue;
291
+ }
292
+ const row = {
293
+ id,
294
+ domain_id: domain,
295
+ entity_name: name,
296
+ glossary_item_id: glossaryItemId,
297
+ status,
298
+ source_sdd_id: "",
299
+ };
300
+ entitySeen.set(id, row);
301
+ }
302
+ // status: missing or other → no edge emitted.
303
+ }
304
+ }
305
+ // Realise the deduplicated entity_glossary rows.
306
+ entityRows.push(...entitySeen.values());
307
+ }
308
+ // Surface a single convention finding when the manifest is present but
309
+ // zero walkers produced output. Older builders emitted this; preserved
310
+ // for adopters whose manifest sits in an entirely-unsupported shape.
311
+ if (xrefRows.length === 0 && entityRows.length === 0) {
312
+ const hasAnyKnownKey = "aliases" in obj
313
+ || "conflicts" in obj
314
+ || "conflicts_with" in obj
315
+ || "cross_domain_terms" in obj
316
+ || "models" in obj;
317
+ if (!hasAnyKnownKey) {
318
+ inputs.findings.add("convention", `${MANIFEST_REL_PATH}: present but no recognised top-level keys (aliases/conflicts/cross_domain_terms/models) — emitting 0 xref rows (per ADR 0158)`);
319
+ }
320
+ }
321
+ return { glossaryXref: xrefRows, entityGlossary: entityRows };
78
322
  }
79
323
  function collectPairs(raw) {
80
324
  if (!Array.isArray(raw))
@@ -104,4 +348,25 @@ function resolveTerm(raw, inputs) {
104
348
  }
105
349
  return undefined;
106
350
  }
351
+ function resolveTermByName(term, inputs) {
352
+ // Match term names case-insensitively against the (domain, term) index.
353
+ const needle = term.toLowerCase();
354
+ for (const [key, id] of inputs.idByDomainTerm) {
355
+ const colonIdx = key.indexOf(":");
356
+ if (colonIdx <= 0)
357
+ continue;
358
+ const keyTerm = key.slice(colonIdx + 1);
359
+ if (keyTerm === needle)
360
+ return id;
361
+ }
362
+ return undefined;
363
+ }
364
+ function slugify(s) {
365
+ return s
366
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
367
+ .toLowerCase()
368
+ .replace(/[^a-z0-9-]+/g, "-")
369
+ .replace(/-+/g, "-")
370
+ .replace(/^-|-$/g, "");
371
+ }
107
372
  //# sourceMappingURL=glossary-xref.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"glossary-xref.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/glossary-xref.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"glossary-xref.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/glossary-xref.ts"],"names":[],"mappings":"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"}