@elevasis/core 0.25.0 → 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.
- package/dist/index.d.ts +166 -85
- package/dist/index.js +146 -1346
- package/dist/knowledge/index.d.ts +27 -38
- package/dist/knowledge/index.js +1 -1
- package/dist/organization-model/index.d.ts +166 -85
- package/dist/organization-model/index.js +146 -1346
- package/dist/test-utils/index.d.ts +23 -31
- package/dist/test-utils/index.js +75 -1238
- package/package.json +1 -1
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +14 -2
- package/src/business/acquisition/api-schemas.test.ts +70 -77
- package/src/business/acquisition/api-schemas.ts +21 -42
- package/src/business/acquisition/derive-actions.test.ts +11 -21
- package/src/business/acquisition/derive-actions.ts +61 -14
- package/src/business/acquisition/ontology-validation.ts +4 -4
- package/src/business/acquisition/types.ts +7 -8
- package/src/knowledge/queries.ts +0 -1
- package/src/organization-model/__tests__/content-kinds-registry.test.ts +35 -210
- package/src/organization-model/__tests__/defaults.test.ts +4 -4
- package/src/organization-model/__tests__/domains/actions.test.ts +12 -36
- package/src/organization-model/__tests__/domains/offerings.test.ts +13 -6
- package/src/organization-model/__tests__/domains/resources.test.ts +497 -350
- package/src/organization-model/__tests__/domains/systems.test.ts +6 -7
- package/src/organization-model/__tests__/flatten-additive-merge.test.ts +68 -80
- package/src/organization-model/__tests__/foundation.test.ts +81 -14
- package/src/organization-model/__tests__/graph.test.ts +662 -694
- package/src/organization-model/__tests__/knowledge.test.ts +31 -17
- package/src/organization-model/__tests__/lookup-helpers.test.ts +128 -438
- package/src/organization-model/__tests__/migration-helpers.test.ts +362 -591
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +68 -103
- package/src/organization-model/__tests__/published-zero-leak.test.ts +17 -0
- package/src/organization-model/__tests__/recursive-system-schema.test.ts +159 -532
- package/src/organization-model/__tests__/resolve.test.ts +79 -42
- package/src/organization-model/__tests__/schema.test.ts +65 -56
- package/src/organization-model/catalogs/lead-gen.ts +0 -103
- package/src/organization-model/defaults.ts +17 -702
- package/src/organization-model/domains/actions.ts +116 -333
- package/src/organization-model/domains/knowledge.ts +15 -7
- package/src/organization-model/domains/projects.ts +4 -4
- package/src/organization-model/domains/prospecting.ts +405 -395
- package/src/organization-model/domains/resources.ts +206 -135
- package/src/organization-model/domains/sales.ts +5 -5
- package/src/organization-model/domains/systems.ts +8 -23
- package/src/organization-model/graph/build.ts +223 -294
- package/src/organization-model/graph/schema.ts +2 -3
- package/src/organization-model/graph/types.ts +12 -14
- package/src/organization-model/helpers.ts +130 -218
- package/src/organization-model/index.ts +104 -124
- package/src/organization-model/migration-helpers.ts +211 -249
- package/src/organization-model/ontology.ts +0 -60
- package/src/organization-model/organization-graph.mdx +4 -5
- package/src/organization-model/organization-model.mdx +1 -1
- package/src/organization-model/published.ts +236 -226
- package/src/organization-model/resolve.ts +4 -5
- package/src/organization-model/schema.ts +610 -704
- package/src/organization-model/types.ts +167 -161
- package/src/platform/registry/__tests__/validation.test.ts +23 -0
- package/src/platform/registry/validation.ts +13 -2
- package/src/reference/_generated/contracts.md +14 -2
- package/src/organization-model/content-kinds/config.ts +0 -36
- package/src/organization-model/content-kinds/index.ts +0 -78
- package/src/organization-model/content-kinds/pipeline.ts +0 -68
- package/src/organization-model/content-kinds/registry.ts +0 -44
- package/src/organization-model/content-kinds/status.ts +0 -71
- package/src/organization-model/content-kinds/template.ts +0 -83
- package/src/organization-model/content-kinds/types.ts +0 -117
|
@@ -2,36 +2,36 @@ import { BuildOrganizationGraphInputSchema, OrganizationGraphSchema } from './sc
|
|
|
2
2
|
import type { CommandViewData } from '../../platform/registry/command-view'
|
|
3
3
|
import type {
|
|
4
4
|
BuildOrganizationGraphInput,
|
|
5
|
-
OrganizationGraph,
|
|
6
|
-
OrganizationGraphEdge,
|
|
7
|
-
OrganizationGraphEdgeKind,
|
|
8
|
-
OrganizationGraphNode,
|
|
9
|
-
OrganizationGraphNodeKind
|
|
10
|
-
} from './types'
|
|
11
|
-
import type { ActionInvocation } from '../domains/actions'
|
|
12
|
-
import type { Entity } from '../domains/entities'
|
|
13
|
-
import type { ResourceEntry } from '../domains/resources'
|
|
14
|
-
import type { OmTopologyNodeRef } from '../domains/topology'
|
|
15
|
-
import type { EventDescriptor, OrganizationModelSidebarNode } from '../types'
|
|
5
|
+
OrganizationGraph,
|
|
6
|
+
OrganizationGraphEdge,
|
|
7
|
+
OrganizationGraphEdgeKind,
|
|
8
|
+
OrganizationGraphNode,
|
|
9
|
+
OrganizationGraphNodeKind
|
|
10
|
+
} from './types'
|
|
11
|
+
import type { ActionInvocation } from '../domains/actions'
|
|
12
|
+
import type { Entity } from '../domains/entities'
|
|
13
|
+
import type { ResourceEntry } from '../domains/resources'
|
|
14
|
+
import type { OmTopologyNodeRef } from '../domains/topology'
|
|
15
|
+
import type { EventDescriptor, OrganizationModelSidebarNode } from '../types'
|
|
16
16
|
import {
|
|
17
17
|
getAllPipelines,
|
|
18
18
|
getAllBuildTemplates,
|
|
19
|
+
getLeadGenStageCatalog,
|
|
19
20
|
getAllProjectStatuses,
|
|
20
21
|
getAllProspectingStages
|
|
21
22
|
} from '../migration-helpers'
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type
|
|
30
|
-
type
|
|
31
|
-
type
|
|
32
|
-
type
|
|
33
|
-
|
|
34
|
-
} from '../ontology'
|
|
23
|
+
import { listAllSystems } from '../helpers'
|
|
24
|
+
import {
|
|
25
|
+
compileOrganizationOntology,
|
|
26
|
+
listResolvedOntologyRecords,
|
|
27
|
+
ontologyGraphNodeId,
|
|
28
|
+
parseOntologyId,
|
|
29
|
+
type OntologyActionType,
|
|
30
|
+
type OntologyCatalogType,
|
|
31
|
+
type OntologyGroup,
|
|
32
|
+
type OntologyId,
|
|
33
|
+
type OntologyLinkType
|
|
34
|
+
} from '../ontology'
|
|
35
35
|
|
|
36
36
|
type EventEmissionDescriptor = NonNullable<Extract<ResourceEntry, { kind: 'workflow' }>['emits']>[number]
|
|
37
37
|
|
|
@@ -187,31 +187,31 @@ function invocationLabel(invocation: ActionInvocation): string {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
function eventNodeId(eventId: string): string {
|
|
191
|
-
return nodeId('event', eventId)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function ontologyLabel(id: OntologyId, label: string | undefined): string {
|
|
195
|
-
return label ?? parseOntologyId(id).localId
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function pushOntologyBindingEdges(
|
|
199
|
-
edges: OrganizationGraphEdge[],
|
|
200
|
-
edgeIds: Set<string>,
|
|
201
|
-
resourceNodeId: string,
|
|
202
|
-
kind: OrganizationGraphEdgeKind,
|
|
203
|
-
ids: OntologyId[] | undefined
|
|
204
|
-
): void {
|
|
205
|
-
ids?.forEach((ontologyId) => {
|
|
206
|
-
const targetId = ontologyGraphNodeId(ontologyId)
|
|
207
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
208
|
-
id: edgeId(kind, resourceNodeId, targetId),
|
|
209
|
-
kind,
|
|
210
|
-
sourceId: resourceNodeId,
|
|
211
|
-
targetId
|
|
212
|
-
})
|
|
213
|
-
})
|
|
214
|
-
}
|
|
190
|
+
function eventNodeId(eventId: string): string {
|
|
191
|
+
return nodeId('event', eventId)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function ontologyLabel(id: OntologyId, label: string | undefined): string {
|
|
195
|
+
return label ?? parseOntologyId(id).localId
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function pushOntologyBindingEdges(
|
|
199
|
+
edges: OrganizationGraphEdge[],
|
|
200
|
+
edgeIds: Set<string>,
|
|
201
|
+
resourceNodeId: string,
|
|
202
|
+
kind: OrganizationGraphEdgeKind,
|
|
203
|
+
ids: OntologyId[] | undefined
|
|
204
|
+
): void {
|
|
205
|
+
ids?.forEach((ontologyId) => {
|
|
206
|
+
const targetId = ontologyGraphNodeId(ontologyId)
|
|
207
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
208
|
+
id: edgeId(kind, resourceNodeId, targetId),
|
|
209
|
+
kind,
|
|
210
|
+
sourceId: resourceNodeId,
|
|
211
|
+
targetId
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
215
|
|
|
216
216
|
function buildResourceEventDescriptor(resourceId: string, emission: EventEmissionDescriptor): EventDescriptor {
|
|
217
217
|
return {
|
|
@@ -270,10 +270,10 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
270
270
|
const nodeIds = new Set<string>()
|
|
271
271
|
const edgeIds = new Set<string>()
|
|
272
272
|
const resourceNodesById = new Map<string, OrganizationGraphNode>()
|
|
273
|
-
const organizationModelResourceIds = new Set(Object.keys(organizationModel.resources))
|
|
274
|
-
const actionIdsByInvocation = new Map<string, string[]>()
|
|
275
|
-
const projectedEventNodeIdsByEventId = new Map<string, string>()
|
|
276
|
-
const ontologyCompilation = compileOrganizationOntology(organizationModel)
|
|
273
|
+
const organizationModelResourceIds = new Set(Object.keys(organizationModel.resources))
|
|
274
|
+
const actionIdsByInvocation = new Map<string, string[]>()
|
|
275
|
+
const projectedEventNodeIdsByEventId = new Map<string, string>()
|
|
276
|
+
const ontologyCompilation = compileOrganizationOntology(organizationModel)
|
|
277
277
|
|
|
278
278
|
const organizationNode: OrganizationGraphNode = {
|
|
279
279
|
id: nodeId('organization'),
|
|
@@ -287,42 +287,42 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
287
287
|
systemPathByRef.set(path, path)
|
|
288
288
|
systemPathByRef.set(system.id, path)
|
|
289
289
|
}
|
|
290
|
-
const validSystemRefs = new Set(systemPathByRef.keys())
|
|
291
|
-
const systemNodeId = (systemRef: string) => nodeId('system', systemPathByRef.get(systemRef) ?? systemRef)
|
|
292
|
-
|
|
293
|
-
function topologyNodeId(ref: OmTopologyNodeRef): string {
|
|
294
|
-
if (ref.kind === 'system') return systemNodeId(ref.id)
|
|
295
|
-
if (ref.kind === 'resource') return nodeId('resource', ref.id)
|
|
296
|
-
if (ref.kind === 'ontology') return ontologyGraphNodeId(ref.id)
|
|
297
|
-
if (ref.kind === 'policy') return nodeId('policy', ref.id)
|
|
298
|
-
if (ref.kind === 'role') return nodeId('role', ref.id)
|
|
299
|
-
return nodeId('resource', ref.id)
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
function ensureTopologyNode(ref: OmTopologyNodeRef): string {
|
|
303
|
-
const id = topologyNodeId(ref)
|
|
304
|
-
if (nodeIds.has(id)) return id
|
|
305
|
-
|
|
306
|
-
if (ref.kind === 'resource') {
|
|
307
|
-
ensureResourceNode(nodes, nodeIds, resourceNodesById, ref.id)
|
|
308
|
-
return id
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (ref.kind === 'trigger' || ref.kind === 'humanCheckpoint' || ref.kind === 'externalResource') {
|
|
312
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
313
|
-
id,
|
|
314
|
-
kind: 'resource',
|
|
315
|
-
label: ref.id,
|
|
316
|
-
sourceId: ref.id,
|
|
317
|
-
resourceType:
|
|
318
|
-
ref.kind === 'trigger' ? 'trigger' : ref.kind === 'humanCheckpoint' ? 'human_checkpoint' : 'external'
|
|
319
|
-
})
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
return id
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
for (const { path, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
290
|
+
const validSystemRefs = new Set(systemPathByRef.keys())
|
|
291
|
+
const systemNodeId = (systemRef: string) => nodeId('system', systemPathByRef.get(systemRef) ?? systemRef)
|
|
292
|
+
|
|
293
|
+
function topologyNodeId(ref: OmTopologyNodeRef): string {
|
|
294
|
+
if (ref.kind === 'system') return systemNodeId(ref.id)
|
|
295
|
+
if (ref.kind === 'resource') return nodeId('resource', ref.id)
|
|
296
|
+
if (ref.kind === 'ontology') return ontologyGraphNodeId(ref.id)
|
|
297
|
+
if (ref.kind === 'policy') return nodeId('policy', ref.id)
|
|
298
|
+
if (ref.kind === 'role') return nodeId('role', ref.id)
|
|
299
|
+
return nodeId('resource', ref.id)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function ensureTopologyNode(ref: OmTopologyNodeRef): string {
|
|
303
|
+
const id = topologyNodeId(ref)
|
|
304
|
+
if (nodeIds.has(id)) return id
|
|
305
|
+
|
|
306
|
+
if (ref.kind === 'resource') {
|
|
307
|
+
ensureResourceNode(nodes, nodeIds, resourceNodesById, ref.id)
|
|
308
|
+
return id
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (ref.kind === 'trigger' || ref.kind === 'humanCheckpoint' || ref.kind === 'externalResource') {
|
|
312
|
+
pushUniqueNode(nodes, nodeIds, {
|
|
313
|
+
id,
|
|
314
|
+
kind: 'resource',
|
|
315
|
+
label: ref.id,
|
|
316
|
+
sourceId: ref.id,
|
|
317
|
+
resourceType:
|
|
318
|
+
ref.kind === 'trigger' ? 'trigger' : ref.kind === 'humanCheckpoint' ? 'human_checkpoint' : 'external'
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return id
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
for (const { path, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
326
326
|
const id = nodeId('system', path)
|
|
327
327
|
pushUniqueNode(nodes, nodeIds, {
|
|
328
328
|
id,
|
|
@@ -348,85 +348,85 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
348
348
|
targetId: id
|
|
349
349
|
})
|
|
350
350
|
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
for (const { id: ontologyId, kind, record } of listResolvedOntologyRecords(ontologyCompilation.ontology).sort((a, b) =>
|
|
354
|
-
a.id.localeCompare(b.id)
|
|
355
|
-
)) {
|
|
356
|
-
const id = ontologyGraphNodeId(ontologyId)
|
|
357
|
-
const parsedId = parseOntologyId(ontologyId)
|
|
358
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
359
|
-
id,
|
|
360
|
-
kind: 'ontology',
|
|
361
|
-
label: ontologyLabel(ontologyId, record.label),
|
|
362
|
-
sourceId: ontologyId,
|
|
363
|
-
description: record.description,
|
|
364
|
-
ontologyKind: kind
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
const ownerSystemId = record.ownerSystemId ?? (parsedId.isGlobal ? undefined : parsedId.scope)
|
|
368
|
-
if (ownerSystemId !== undefined && validSystemRefs.has(ownerSystemId)) {
|
|
369
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
370
|
-
id: edgeId('contains', systemNodeId(ownerSystemId), id, `ontology-${kind}`),
|
|
371
|
-
kind: 'contains',
|
|
372
|
-
sourceId: systemNodeId(ownerSystemId),
|
|
373
|
-
targetId: id
|
|
374
|
-
})
|
|
375
|
-
} else {
|
|
376
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
377
|
-
id: edgeId('contains', organizationNode.id, id, `ontology-${kind}`),
|
|
378
|
-
kind: 'contains',
|
|
379
|
-
sourceId: organizationNode.id,
|
|
380
|
-
targetId: id
|
|
381
|
-
})
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
if (kind === 'link') {
|
|
385
|
-
const link = record as OntologyLinkType
|
|
386
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
387
|
-
id: edgeId('links', ontologyGraphNodeId(link.from), ontologyGraphNodeId(link.to), ontologyId),
|
|
388
|
-
kind: 'links',
|
|
389
|
-
sourceId: ontologyGraphNodeId(link.from),
|
|
390
|
-
targetId: ontologyGraphNodeId(link.to),
|
|
391
|
-
label: link.label ?? parsedId.localId
|
|
392
|
-
})
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (kind === 'action') {
|
|
396
|
-
const action = record as OntologyActionType
|
|
397
|
-
for (const targetOntologyId of action.actsOn ?? []) {
|
|
398
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
399
|
-
id: edgeId('affects', id, ontologyGraphNodeId(targetOntologyId), ontologyId),
|
|
400
|
-
kind: 'affects',
|
|
401
|
-
sourceId: id,
|
|
402
|
-
targetId: ontologyGraphNodeId(targetOntologyId)
|
|
403
|
-
})
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (kind === 'catalog') {
|
|
408
|
-
const catalog = record as OntologyCatalogType
|
|
409
|
-
if (catalog.appliesTo === undefined) continue
|
|
410
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
411
|
-
id: edgeId('applies_to', id, ontologyGraphNodeId(catalog.appliesTo), ontologyId),
|
|
412
|
-
kind: 'applies_to',
|
|
413
|
-
sourceId: id,
|
|
414
|
-
targetId: ontologyGraphNodeId(catalog.appliesTo)
|
|
415
|
-
})
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if (kind === 'group') {
|
|
419
|
-
const group = record as OntologyGroup
|
|
420
|
-
for (const memberOntologyId of group.members ?? []) {
|
|
421
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
422
|
-
id: edgeId('contains', id, ontologyGraphNodeId(memberOntologyId), ontologyId),
|
|
423
|
-
kind: 'contains',
|
|
424
|
-
sourceId: id,
|
|
425
|
-
targetId: ontologyGraphNodeId(memberOntologyId)
|
|
426
|
-
})
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
for (const { id: ontologyId, kind, record } of listResolvedOntologyRecords(ontologyCompilation.ontology).sort((a, b) =>
|
|
354
|
+
a.id.localeCompare(b.id)
|
|
355
|
+
)) {
|
|
356
|
+
const id = ontologyGraphNodeId(ontologyId)
|
|
357
|
+
const parsedId = parseOntologyId(ontologyId)
|
|
358
|
+
pushUniqueNode(nodes, nodeIds, {
|
|
359
|
+
id,
|
|
360
|
+
kind: 'ontology',
|
|
361
|
+
label: ontologyLabel(ontologyId, record.label),
|
|
362
|
+
sourceId: ontologyId,
|
|
363
|
+
description: record.description,
|
|
364
|
+
ontologyKind: kind
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
const ownerSystemId = record.ownerSystemId ?? (parsedId.isGlobal ? undefined : parsedId.scope)
|
|
368
|
+
if (ownerSystemId !== undefined && validSystemRefs.has(ownerSystemId)) {
|
|
369
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
370
|
+
id: edgeId('contains', systemNodeId(ownerSystemId), id, `ontology-${kind}`),
|
|
371
|
+
kind: 'contains',
|
|
372
|
+
sourceId: systemNodeId(ownerSystemId),
|
|
373
|
+
targetId: id
|
|
374
|
+
})
|
|
375
|
+
} else {
|
|
376
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
377
|
+
id: edgeId('contains', organizationNode.id, id, `ontology-${kind}`),
|
|
378
|
+
kind: 'contains',
|
|
379
|
+
sourceId: organizationNode.id,
|
|
380
|
+
targetId: id
|
|
381
|
+
})
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (kind === 'link') {
|
|
385
|
+
const link = record as OntologyLinkType
|
|
386
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
387
|
+
id: edgeId('links', ontologyGraphNodeId(link.from), ontologyGraphNodeId(link.to), ontologyId),
|
|
388
|
+
kind: 'links',
|
|
389
|
+
sourceId: ontologyGraphNodeId(link.from),
|
|
390
|
+
targetId: ontologyGraphNodeId(link.to),
|
|
391
|
+
label: link.label ?? parsedId.localId
|
|
392
|
+
})
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (kind === 'action') {
|
|
396
|
+
const action = record as OntologyActionType
|
|
397
|
+
for (const targetOntologyId of action.actsOn ?? []) {
|
|
398
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
399
|
+
id: edgeId('affects', id, ontologyGraphNodeId(targetOntologyId), ontologyId),
|
|
400
|
+
kind: 'affects',
|
|
401
|
+
sourceId: id,
|
|
402
|
+
targetId: ontologyGraphNodeId(targetOntologyId)
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (kind === 'catalog') {
|
|
408
|
+
const catalog = record as OntologyCatalogType
|
|
409
|
+
if (catalog.appliesTo === undefined) continue
|
|
410
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
411
|
+
id: edgeId('applies_to', id, ontologyGraphNodeId(catalog.appliesTo), ontologyId),
|
|
412
|
+
kind: 'applies_to',
|
|
413
|
+
sourceId: id,
|
|
414
|
+
targetId: ontologyGraphNodeId(catalog.appliesTo)
|
|
415
|
+
})
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (kind === 'group') {
|
|
419
|
+
const group = record as OntologyGroup
|
|
420
|
+
for (const memberOntologyId of group.members ?? []) {
|
|
421
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
422
|
+
id: edgeId('contains', id, ontologyGraphNodeId(memberOntologyId), ontologyId),
|
|
423
|
+
kind: 'contains',
|
|
424
|
+
sourceId: id,
|
|
425
|
+
targetId: ontologyGraphNodeId(memberOntologyId)
|
|
426
|
+
})
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
430
|
|
|
431
431
|
for (const role of Object.values(organizationModel.roles).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
432
432
|
const id = nodeId('role', role.id)
|
|
@@ -479,17 +479,17 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
479
479
|
kind: 'contains',
|
|
480
480
|
sourceId: organizationNode.id,
|
|
481
481
|
targetId: id
|
|
482
|
-
})
|
|
483
|
-
for (const link of node.links) {
|
|
484
|
-
const targetId =
|
|
485
|
-
link.target.kind === 'system'
|
|
486
|
-
? systemNodeId(link.target.id)
|
|
487
|
-
: link.target.kind === 'ontology'
|
|
488
|
-
? ontologyGraphNodeId(link.target.id)
|
|
489
|
-
: link.nodeId
|
|
490
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
491
|
-
id: edgeId('governs', id, targetId),
|
|
492
|
-
kind: 'governs',
|
|
482
|
+
})
|
|
483
|
+
for (const link of node.links) {
|
|
484
|
+
const targetId =
|
|
485
|
+
link.target.kind === 'system'
|
|
486
|
+
? systemNodeId(link.target.id)
|
|
487
|
+
: link.target.kind === 'ontology'
|
|
488
|
+
? ontologyGraphNodeId(link.target.id)
|
|
489
|
+
: link.nodeId
|
|
490
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
491
|
+
id: edgeId('governs', id, targetId),
|
|
492
|
+
kind: 'governs',
|
|
493
493
|
sourceId: id,
|
|
494
494
|
targetId
|
|
495
495
|
})
|
|
@@ -596,9 +596,8 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
596
596
|
if (entity.stateCatalogId !== undefined) {
|
|
597
597
|
const stateEvents: EventDescriptor[] = []
|
|
598
598
|
|
|
599
|
-
// Phase 4: model.statuses removed (D1).
|
|
600
|
-
//
|
|
601
|
-
// belongs in System.ontology catalogTypes.
|
|
599
|
+
// Phase 4: model.statuses removed (D1). Status-flow authoring belongs
|
|
600
|
+
// in System.ontology catalogTypes.
|
|
602
601
|
|
|
603
602
|
if (entity.stateCatalogId === 'crm.pipeline') {
|
|
604
603
|
// Phase 4: model.sales removed (D8). Read pipelines via migration helper.
|
|
@@ -622,7 +621,7 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
622
621
|
|
|
623
622
|
if (entity.stateCatalogId === 'lead-gen.company' || entity.stateCatalogId === 'lead-gen.contact') {
|
|
624
623
|
const leadGenEntity = entity.stateCatalogId === 'lead-gen.company' ? 'company' : 'contact'
|
|
625
|
-
for (const stage of Object.values(
|
|
624
|
+
for (const stage of Object.values(getLeadGenStageCatalog(organizationModel)).sort(
|
|
626
625
|
(a, b) => a.order - b.order || a.key.localeCompare(b.key)
|
|
627
626
|
)) {
|
|
628
627
|
if (stage.entity !== leadGenEntity && !(stage.additionalEntities ?? []).includes(leadGenEntity)) continue
|
|
@@ -673,22 +672,22 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
673
672
|
|
|
674
673
|
// Skip the contains edge if the systemPath doesn't resolve to a real system.
|
|
675
674
|
// In a fully-validated model this never fires; it guards partial-OM fixtures.
|
|
676
|
-
if (validSystemPaths.has(resource.systemPath)) {
|
|
677
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
678
|
-
id: edgeId('contains', systemNodeId(resource.systemPath), resourceNode.id, 'system-resource'),
|
|
679
|
-
kind: 'contains',
|
|
680
|
-
sourceId: systemNodeId(resource.systemPath),
|
|
681
|
-
targetId: resourceNode.id
|
|
682
|
-
})
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'actions', resource.ontology?.actions)
|
|
686
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'reads', resource.ontology?.reads)
|
|
687
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'writes', resource.ontology?.writes)
|
|
688
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'uses_catalog', resource.ontology?.usesCatalogs)
|
|
689
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'emits', resource.ontology?.emits)
|
|
690
|
-
|
|
691
|
-
if (resource.kind === 'workflow' || resource.kind === 'agent') {
|
|
675
|
+
if (validSystemPaths.has(resource.systemPath)) {
|
|
676
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
677
|
+
id: edgeId('contains', systemNodeId(resource.systemPath), resourceNode.id, 'system-resource'),
|
|
678
|
+
kind: 'contains',
|
|
679
|
+
sourceId: systemNodeId(resource.systemPath),
|
|
680
|
+
targetId: resourceNode.id
|
|
681
|
+
})
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'actions', resource.ontology?.actions)
|
|
685
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'reads', resource.ontology?.reads)
|
|
686
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'writes', resource.ontology?.writes)
|
|
687
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'uses_catalog', resource.ontology?.usesCatalogs)
|
|
688
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, 'emits', resource.ontology?.emits)
|
|
689
|
+
|
|
690
|
+
if (resource.kind === 'workflow' || resource.kind === 'agent') {
|
|
692
691
|
for (const emission of resource.emits ?? []) {
|
|
693
692
|
pushEventProjection(
|
|
694
693
|
nodes,
|
|
@@ -731,9 +730,9 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
731
730
|
}
|
|
732
731
|
}
|
|
733
732
|
|
|
734
|
-
for (const policy of Object.values(organizationModel.policies).sort(
|
|
735
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
736
|
-
)) {
|
|
733
|
+
for (const policy of Object.values(organizationModel.policies).sort(
|
|
734
|
+
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
735
|
+
)) {
|
|
737
736
|
const id = nodeId('policy', policy.id)
|
|
738
737
|
pushUniqueNode(nodes, nodeIds, {
|
|
739
738
|
id,
|
|
@@ -820,26 +819,26 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
820
819
|
targetId: nodeId('role', effect.roleId),
|
|
821
820
|
label: effect.kind
|
|
822
821
|
})
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
for (const [relationshipId, relationship] of Object.entries(organizationModel.topology.relationships).sort(([a], [b]) =>
|
|
828
|
-
a.localeCompare(b)
|
|
829
|
-
)) {
|
|
830
|
-
const sourceId = ensureTopologyNode(relationship.from)
|
|
831
|
-
const targetId = ensureTopologyNode(relationship.to)
|
|
832
|
-
|
|
833
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
834
|
-
id: edgeId(relationship.kind, sourceId, targetId, `topology-${relationshipId}`),
|
|
835
|
-
kind: relationship.kind,
|
|
836
|
-
sourceId,
|
|
837
|
-
targetId,
|
|
838
|
-
relationshipType: relationship.kind
|
|
839
|
-
})
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
for (const segment of Object.values(organizationModel.customers).sort(
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
for (const [relationshipId, relationship] of Object.entries(organizationModel.topology.relationships).sort(([a], [b]) =>
|
|
827
|
+
a.localeCompare(b)
|
|
828
|
+
)) {
|
|
829
|
+
const sourceId = ensureTopologyNode(relationship.from)
|
|
830
|
+
const targetId = ensureTopologyNode(relationship.to)
|
|
831
|
+
|
|
832
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
833
|
+
id: edgeId(relationship.kind, sourceId, targetId, `topology-${relationshipId}`),
|
|
834
|
+
kind: relationship.kind,
|
|
835
|
+
sourceId,
|
|
836
|
+
targetId,
|
|
837
|
+
relationshipType: relationship.kind
|
|
838
|
+
})
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
for (const segment of Object.values(organizationModel.customers).sort(
|
|
843
842
|
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
844
843
|
)) {
|
|
845
844
|
const id = nodeId('customer-segment', segment.id)
|
|
@@ -961,78 +960,8 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
961
960
|
targetId: id
|
|
962
961
|
})
|
|
963
962
|
}
|
|
964
|
-
|
|
965
|
-
//
|
|
966
|
-
// Compatibility bridge: content-node graph projection
|
|
967
|
-
// ---------------------------------------------------------------------------
|
|
968
|
-
// Keep bridge-era System.content addressable as read-only content-node:* graph
|
|
969
|
-
// IDs for old UI and knowledge consumers. New semantic graph consumers should
|
|
970
|
-
// prefer ontology-native graph nodes emitted from System.ontology.
|
|
971
|
-
//
|
|
972
|
-
// For every system in the model tree, emit a 'content-node' graph node for
|
|
973
|
-
// each entry in system.content[*]. Edges:
|
|
974
|
-
// - contains: system spine node → content-node
|
|
975
|
-
// - contains: parent content-node → child content-node (via parentContentId)
|
|
976
|
-
// - references: pipeline content-node → entity node (when data.entityId set)
|
|
977
|
-
// ---------------------------------------------------------------------------
|
|
978
|
-
for (const { path, system } of listAllSystems(organizationModel).sort((a, b) => a.path.localeCompare(b.path))) {
|
|
979
|
-
const contentMap = system.content ?? {}
|
|
980
|
-
const systemSpineId = nodeId('system', path)
|
|
981
|
-
|
|
982
|
-
for (const [localId, contentNode] of Object.entries(contentMap).sort(([a], [b]) => a.localeCompare(b))) {
|
|
983
|
-
const contentNodeGraphId = `content-node:${path}:${localId}`
|
|
984
|
-
|
|
985
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
986
|
-
id: contentNodeGraphId,
|
|
987
|
-
kind: 'content-node',
|
|
988
|
-
label: contentNode.label,
|
|
989
|
-
sourceId: `${path}:${localId}`,
|
|
990
|
-
description: contentNode.description
|
|
991
|
-
// Spread contentKind and contentType into attributes; the node schema
|
|
992
|
-
// does not have custom attribute slots, so we encode them in the label
|
|
993
|
-
// suffix for now. The actual kind/type are recoverable from sourceId +
|
|
994
|
-
// the registry lookup by consumers.
|
|
995
|
-
})
|
|
996
|
-
|
|
997
|
-
// contains: system spine → content-node
|
|
998
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
999
|
-
id: edgeId('contains', systemSpineId, contentNodeGraphId, 'system-content'),
|
|
1000
|
-
kind: 'contains',
|
|
1001
|
-
sourceId: systemSpineId,
|
|
1002
|
-
targetId: contentNodeGraphId
|
|
1003
|
-
})
|
|
1004
|
-
|
|
1005
|
-
// contains: parent content-node → child content-node (parentContentId chain)
|
|
1006
|
-
if (contentNode.parentContentId) {
|
|
1007
|
-
const parentContentNodeGraphId = `content-node:${path}:${contentNode.parentContentId}`
|
|
1008
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
1009
|
-
id: edgeId('contains', parentContentNodeGraphId, contentNodeGraphId, 'content-parent'),
|
|
1010
|
-
kind: 'contains',
|
|
1011
|
-
sourceId: parentContentNodeGraphId,
|
|
1012
|
-
targetId: contentNodeGraphId
|
|
1013
|
-
})
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
// references: pipeline -> entity (data.entityId ref-field annotation)
|
|
1017
|
-
// Bridge schema:pipeline payloadSchema carries `.meta({ ref: 'entity' })` on entityId.
|
|
1018
|
-
// Emit a 'references' edge from the pipeline content-node to the entity node.
|
|
1019
|
-
if (
|
|
1020
|
-
contentNode.kind === 'schema' &&
|
|
1021
|
-
contentNode.type === 'pipeline' &&
|
|
1022
|
-
contentNode.data &&
|
|
1023
|
-
typeof contentNode.data['entityId'] === 'string'
|
|
1024
|
-
) {
|
|
1025
|
-
const targetEntityId = nodeId('entity', contentNode.data['entityId'])
|
|
1026
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
1027
|
-
id: edgeId('references', contentNodeGraphId, targetEntityId, 'pipeline-entity'),
|
|
1028
|
-
kind: 'references',
|
|
1029
|
-
sourceId: contentNodeGraphId,
|
|
1030
|
-
targetId: targetEntityId,
|
|
1031
|
-
label: 'applies to entity'
|
|
1032
|
-
})
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
963
|
+
// System.content bridge projection removed; ontology catalog nodes now carry
|
|
964
|
+
// operational catalog identity in the graph.
|
|
1036
965
|
|
|
1037
966
|
// Phase 4: prospecting domain removed; read templates via migration helper.
|
|
1038
967
|
// Steps are typed as BuildTemplate['steps'] which carries ProspectingBuildTemplateStepSchema fields.
|
|
@@ -18,9 +18,8 @@ export const OrganizationGraphNodeKindSchema = z.enum([
|
|
|
18
18
|
'goal',
|
|
19
19
|
'surface',
|
|
20
20
|
'navigation-group',
|
|
21
|
-
//
|
|
22
|
-
'ontology'
|
|
23
|
-
'content-node'
|
|
21
|
+
// Ontology records are projected from compiled System.ontology scopes.
|
|
22
|
+
'ontology'
|
|
24
23
|
])
|
|
25
24
|
|
|
26
25
|
export const OrganizationGraphEdgeKindSchema = z.enum([
|
|
@@ -19,9 +19,7 @@ export type OrganizationGraphNodeKind =
|
|
|
19
19
|
| 'goal'
|
|
20
20
|
| 'surface'
|
|
21
21
|
| 'navigation-group'
|
|
22
|
-
|
|
23
|
-
| 'ontology'
|
|
24
|
-
| 'content-node'
|
|
22
|
+
| 'ontology'
|
|
25
23
|
|
|
26
24
|
export type OrganizationGraphEdgeKind =
|
|
27
25
|
| 'contains'
|
|
@@ -32,15 +30,15 @@ export type OrganizationGraphEdgeKind =
|
|
|
32
30
|
| 'links'
|
|
33
31
|
| 'affects'
|
|
34
32
|
| 'emits'
|
|
35
|
-
| 'originates_from'
|
|
36
|
-
| 'triggers'
|
|
37
|
-
| 'approval'
|
|
38
|
-
| 'applies_to'
|
|
39
|
-
| 'effects'
|
|
40
|
-
| 'actions'
|
|
41
|
-
| 'reads'
|
|
42
|
-
| 'writes'
|
|
43
|
-
| 'uses_catalog'
|
|
33
|
+
| 'originates_from'
|
|
34
|
+
| 'triggers'
|
|
35
|
+
| 'approval'
|
|
36
|
+
| 'applies_to'
|
|
37
|
+
| 'effects'
|
|
38
|
+
| 'actions'
|
|
39
|
+
| 'reads'
|
|
40
|
+
| 'writes'
|
|
41
|
+
| 'uses_catalog'
|
|
44
42
|
export type { Link } from './link'
|
|
45
43
|
|
|
46
44
|
export interface OrganizationGraphNode {
|
|
@@ -50,8 +48,8 @@ export interface OrganizationGraphNode {
|
|
|
50
48
|
sourceId?: string
|
|
51
49
|
description?: string
|
|
52
50
|
icon?: OrganizationModelIconToken
|
|
53
|
-
enabled?: boolean
|
|
54
|
-
ontologyKind?: string
|
|
51
|
+
enabled?: boolean
|
|
52
|
+
ontologyKind?: string
|
|
55
53
|
resourceType?: 'workflow' | 'agent' | 'trigger' | 'integration' | 'external' | 'human_checkpoint' | 'script'
|
|
56
54
|
}
|
|
57
55
|
|