@elevasis/core 0.24.1 → 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 +239 -86
- package/dist/index.js +474 -1346
- package/dist/knowledge/index.d.ts +57 -39
- package/dist/knowledge/index.js +1 -1
- package/dist/organization-model/index.d.ts +239 -86
- package/dist/organization-model/index.js +474 -1346
- package/dist/test-utils/index.d.ts +24 -31
- package/dist/test-utils/index.js +76 -1238
- package/package.json +1 -1
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +108 -96
- 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/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +10 -10
- package/src/knowledge/__tests__/queries.test.ts +960 -546
- package/src/knowledge/format.ts +322 -100
- package/src/knowledge/index.ts +18 -5
- package/src/knowledge/queries.ts +1004 -240
- 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__/deprecate-helpers.test.ts +71 -0
- 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 +88 -49
- package/src/organization-model/__tests__/scaffolders.test.ts +93 -0
- 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 +120 -141
- package/src/organization-model/icons.ts +1 -0
- package/src/organization-model/index.ts +107 -126
- 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 +251 -228
- package/src/organization-model/resolve.ts +4 -5
- package/src/organization-model/scaffolders/helpers.ts +84 -0
- package/src/organization-model/scaffolders/index.ts +19 -0
- package/src/organization-model/scaffolders/scaffoldKnowledgeNode.ts +48 -0
- package/src/organization-model/scaffolders/scaffoldOntologyRecord.ts +38 -0
- package/src/organization-model/scaffolders/scaffoldResource.ts +59 -0
- package/src/organization-model/scaffolders/scaffoldSystem.ts +110 -0
- package/src/organization-model/scaffolders/types.ts +81 -0
- package/src/organization-model/schema.ts +610 -704
- package/src/organization-model/types.ts +167 -161
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/registry/__tests__/validation.test.ts +23 -0
- package/src/platform/registry/validation.ts +13 -2
- package/src/reference/_generated/contracts.md +108 -96
- package/src/reference/glossary.md +71 -69
- 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
|
@@ -1,252 +1,214 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migration helpers
|
|
3
|
-
*
|
|
4
|
-
* External signatures are
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* Compatibility registry entries read:
|
|
9
|
-
* 'schema:pipeline' — one pipeline per owning system
|
|
10
|
-
* 'schema:stage' — stage within a pipeline; parentContentId = pipeline local id
|
|
11
|
-
* 'schema:template' — prospecting build template
|
|
12
|
-
* 'schema:template-step' — step within a template; parentContentId = template local id
|
|
13
|
-
* 'schema:status-flow' — status set for a project/milestone/task scope
|
|
14
|
-
* 'schema:status' — single status within a flow; parentContentId = status-flow local id
|
|
15
|
-
*/
|
|
16
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Migration helpers
|
|
3
|
+
*
|
|
4
|
+
* External signatures are intentionally stable. Internally these helpers now
|
|
5
|
+
* read first-class ontology catalog records.
|
|
6
|
+
*/
|
|
7
|
+
|
|
17
8
|
import type { OrganizationModel } from './types'
|
|
18
9
|
import type { z } from 'zod'
|
|
10
|
+
import type { LeadGenStageCatalogEntry } from './catalogs/lead-gen'
|
|
19
11
|
import type { SalesPipelineSchema, SalesStageSchema } from './domains/sales'
|
|
20
|
-
import type { ProspectingBuildTemplateSchema, ProspectingLifecycleStageSchema } from './domains/prospecting'
|
|
21
|
-
import type { ProjectsDomainStateSchema } from './domains/projects'
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
type
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
.sort((a, b) => a.order - b.order)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
id:
|
|
160
|
-
label:
|
|
161
|
-
|
|
162
|
-
...(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const results: ProjectStatus[] = []
|
|
224
|
-
|
|
225
|
-
for (const { system } of listAllSystems(model)) {
|
|
226
|
-
const content = system.content ?? {}
|
|
227
|
-
|
|
228
|
-
// Find the status-flow node for this appliesTo scope.
|
|
229
|
-
for (const [flowLocalId, flowNode] of Object.entries(content)) {
|
|
230
|
-
if (flowNode.kind !== 'schema' || flowNode.type !== 'status-flow') continue
|
|
231
|
-
const fd = (flowNode.data ?? {}) as Record<string, unknown>
|
|
232
|
-
if (fd.appliesTo !== appliesTo) continue
|
|
233
|
-
|
|
234
|
-
// Collect child status nodes.
|
|
235
|
-
for (const [statusLocalId, statusNode] of Object.entries(content)) {
|
|
236
|
-
if (statusNode.kind !== 'schema' || statusNode.type !== 'status') continue
|
|
237
|
-
if (statusNode.parentContentId !== flowLocalId) continue
|
|
238
|
-
|
|
239
|
-
const sd = (statusNode.data ?? {}) as Record<string, unknown>
|
|
240
|
-
results.push({
|
|
241
|
-
id: statusLocalId,
|
|
242
|
-
label: statusNode.label ?? statusLocalId,
|
|
243
|
-
order: typeof sd.order === 'number' ? sd.order : 0,
|
|
244
|
-
...(typeof sd.color === 'string' ? { color: sd.color } : {}),
|
|
245
|
-
...(statusNode.description ? { description: statusNode.description } : {})
|
|
246
|
-
} satisfies ProjectStatus)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return results.sort((a, b) => a.order - b.order)
|
|
252
|
-
}
|
|
12
|
+
import type { ProspectingBuildTemplateSchema, ProspectingLifecycleStageSchema } from './domains/prospecting'
|
|
13
|
+
import type { ProjectsDomainStateSchema } from './domains/projects'
|
|
14
|
+
import { compileOrganizationOntology, parseOntologyId, type OntologyCatalogType, type OntologyId } from './ontology'
|
|
15
|
+
|
|
16
|
+
type Pipeline = z.infer<typeof SalesPipelineSchema>
|
|
17
|
+
type Stage = z.infer<typeof SalesStageSchema>
|
|
18
|
+
type BuildTemplate = z.infer<typeof ProspectingBuildTemplateSchema>
|
|
19
|
+
type ProspectingStage = z.infer<typeof ProspectingLifecycleStageSchema>
|
|
20
|
+
type ProjectStatus = z.infer<typeof ProjectsDomainStateSchema>
|
|
21
|
+
|
|
22
|
+
type CatalogRecord = OntologyCatalogType & { origin?: { systemPath?: string } }
|
|
23
|
+
type CatalogEntry = Record<string, unknown>
|
|
24
|
+
|
|
25
|
+
function catalogRecords(model: OrganizationModel): CatalogRecord[] {
|
|
26
|
+
return Object.values(compileOrganizationOntology(model).ontology.catalogTypes) as CatalogRecord[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function localId(id: string): string {
|
|
30
|
+
return parseOntologyId(id).localId
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function systemScope(id: string, fallback?: string): string {
|
|
34
|
+
return parseOntologyId(id).scope || fallback || ''
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function entriesOf(catalog: CatalogRecord): Array<[string, CatalogEntry]> {
|
|
38
|
+
return Object.entries(catalog.entries ?? {}).map(([id, value]) => [
|
|
39
|
+
id,
|
|
40
|
+
value && typeof value === 'object' && !Array.isArray(value) ? (value as CatalogEntry) : {}
|
|
41
|
+
])
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function stringValue(value: unknown): string | undefined {
|
|
45
|
+
return typeof value === 'string' ? value : undefined
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function stringArray(value: unknown): string[] {
|
|
49
|
+
return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function numberValue(value: unknown, fallback = 0): number {
|
|
53
|
+
return typeof value === 'number' ? value : fallback
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function stageFromEntry(entryId: string, entry: CatalogEntry): Stage {
|
|
57
|
+
return {
|
|
58
|
+
id: entryId,
|
|
59
|
+
label: stringValue(entry.label) ?? entryId,
|
|
60
|
+
order: numberValue(entry.order),
|
|
61
|
+
semanticClass: (stringValue(entry.semanticClass) as Stage['semanticClass']) ?? 'open',
|
|
62
|
+
surfaceIds: stringArray(entry.surfaceIds),
|
|
63
|
+
resourceIds: stringArray(entry.resourceIds),
|
|
64
|
+
color: stringValue(entry.color)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function appliesToLocalId(catalog: CatalogRecord): string | undefined {
|
|
69
|
+
const appliesTo = catalog.appliesTo
|
|
70
|
+
if (appliesTo === undefined) return undefined
|
|
71
|
+
return parseOntologyId(appliesTo).localId
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function appliesToEntityKind(catalog: CatalogRecord): 'company' | 'contact' | 'project' | 'milestone' | 'task' | undefined {
|
|
75
|
+
const id = appliesToLocalId(catalog)
|
|
76
|
+
if (id === 'company' || id === 'contact' || id === 'project' || id === 'milestone' || id === 'task') return id
|
|
77
|
+
if (id === 'deal') return undefined
|
|
78
|
+
return undefined
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function getAllPipelines(model: OrganizationModel): Array<{ systemPath: string; pipeline: Pipeline }> {
|
|
82
|
+
return catalogRecords(model)
|
|
83
|
+
.filter((catalog) => catalog.kind === 'pipeline')
|
|
84
|
+
.map((catalog) => {
|
|
85
|
+
const pipeline: Pipeline = {
|
|
86
|
+
id: localId(catalog.id),
|
|
87
|
+
label: catalog.label ?? localId(catalog.id),
|
|
88
|
+
...(catalog.description ? { description: catalog.description } : {}),
|
|
89
|
+
entityId: appliesToLocalId(catalog) ?? '',
|
|
90
|
+
stages: entriesOf(catalog)
|
|
91
|
+
.map(([entryId, entry]) => stageFromEntry(entryId, entry))
|
|
92
|
+
.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return { systemPath: catalog.ownerSystemId ?? systemScope(catalog.id), pipeline }
|
|
96
|
+
})
|
|
97
|
+
.sort((a, b) => a.systemPath.localeCompare(b.systemPath) || a.pipeline.id.localeCompare(b.pipeline.id))
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function getStagesInPipeline(model: OrganizationModel, systemPath: string, pipelineLocalId: string): Stage[] {
|
|
101
|
+
const catalog = catalogRecords(model).find(
|
|
102
|
+
(record) =>
|
|
103
|
+
record.kind === 'pipeline' &&
|
|
104
|
+
(record.ownerSystemId ?? systemScope(record.id)) === systemPath &&
|
|
105
|
+
localId(record.id) === pipelineLocalId
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if (catalog === undefined) return []
|
|
109
|
+
|
|
110
|
+
return entriesOf(catalog)
|
|
111
|
+
.map(([entryId, entry]) => stageFromEntry(entryId, entry))
|
|
112
|
+
.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function getAllBuildTemplates(model: OrganizationModel): BuildTemplate[] {
|
|
116
|
+
const catalogs = catalogRecords(model)
|
|
117
|
+
const stepCatalogs = new Map<OntologyId, CatalogRecord>(
|
|
118
|
+
catalogs.filter((catalog) => catalog.kind === 'template-step').map((catalog) => [catalog.id as OntologyId, catalog])
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return catalogs
|
|
122
|
+
.filter((catalog) => catalog.kind === 'template')
|
|
123
|
+
.flatMap((catalog) =>
|
|
124
|
+
entriesOf(catalog).map(([templateId, templateEntry]) => {
|
|
125
|
+
const stepCatalogId = stringValue(templateEntry.stepCatalog) as OntologyId | undefined
|
|
126
|
+
const stepCatalog = stepCatalogId !== undefined ? stepCatalogs.get(stepCatalogId) : undefined
|
|
127
|
+
const steps = stepCatalog === undefined ? [] : entriesOf(stepCatalog)
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
id: templateId,
|
|
131
|
+
label: stringValue(templateEntry.label) ?? templateId,
|
|
132
|
+
...(stringValue(templateEntry.description) ? { description: stringValue(templateEntry.description) } : {}),
|
|
133
|
+
...(stringValue(templateEntry.color) ? { color: stringValue(templateEntry.color) } : {}),
|
|
134
|
+
steps: steps.map(([stepId, step]) => ({
|
|
135
|
+
id: stepId,
|
|
136
|
+
label: stringValue(step.label) ?? stepId,
|
|
137
|
+
...(stringValue(step.description) ? { description: stringValue(step.description) } : {}),
|
|
138
|
+
...step
|
|
139
|
+
})) as BuildTemplate['steps']
|
|
140
|
+
} satisfies BuildTemplate
|
|
141
|
+
})
|
|
142
|
+
)
|
|
143
|
+
.sort((a, b) => a.id.localeCompare(b.id))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function getAllProspectingStages(model: OrganizationModel, kind: 'company' | 'contact'): ProspectingStage[] {
|
|
147
|
+
return catalogRecords(model)
|
|
148
|
+
.filter((catalog) => catalog.kind === 'stage' && appliesToEntityKind(catalog) === kind)
|
|
149
|
+
.flatMap((catalog) =>
|
|
150
|
+
entriesOf(catalog).map(([entryId, entry]) => ({
|
|
151
|
+
id: entryId,
|
|
152
|
+
label: stringValue(entry.label) ?? entryId,
|
|
153
|
+
order: numberValue(entry.order),
|
|
154
|
+
...(stringValue(entry.color) ? { color: stringValue(entry.color) } : {}),
|
|
155
|
+
...(stringValue(entry.description) ? { description: stringValue(entry.description) } : {})
|
|
156
|
+
}))
|
|
157
|
+
)
|
|
158
|
+
.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function getLeadGenStageCatalog(model: OrganizationModel): Record<string, LeadGenStageCatalogEntry> {
|
|
162
|
+
const results: Record<string, LeadGenStageCatalogEntry> = {}
|
|
163
|
+
|
|
164
|
+
for (const catalog of catalogRecords(model).filter(
|
|
165
|
+
(record) => record.kind === 'stage' && (record.ownerSystemId ?? systemScope(record.id)) === 'sales.lead-gen'
|
|
166
|
+
)) {
|
|
167
|
+
const catalogEntity = appliesToEntityKind(catalog)
|
|
168
|
+
if (catalogEntity !== 'company' && catalogEntity !== 'contact') continue
|
|
169
|
+
|
|
170
|
+
for (const [entryId, entry] of entriesOf(catalog)) {
|
|
171
|
+
const entity =
|
|
172
|
+
entry.entity === 'contact' ? 'contact' : entry.entity === 'company' ? 'company' : catalogEntity
|
|
173
|
+
const additionalEntities = stringArray(entry.additionalEntities).filter(
|
|
174
|
+
(item): item is 'company' | 'contact' => item === 'company' || item === 'contact'
|
|
175
|
+
)
|
|
176
|
+
const recordEntity =
|
|
177
|
+
entry.recordEntity === 'company' || entry.recordEntity === 'contact' ? entry.recordEntity : undefined
|
|
178
|
+
const recordStageKey = stringValue(entry.recordStageKey)
|
|
179
|
+
|
|
180
|
+
results[entryId] = {
|
|
181
|
+
key: entryId,
|
|
182
|
+
label: stringValue(entry.label) ?? entryId,
|
|
183
|
+
description: stringValue(entry.description) ?? '',
|
|
184
|
+
order: numberValue(entry.order),
|
|
185
|
+
entity,
|
|
186
|
+
...(additionalEntities.length > 0 ? { additionalEntities } : {}),
|
|
187
|
+
...(recordEntity ? { recordEntity } : {}),
|
|
188
|
+
...(recordStageKey ? { recordStageKey } : {})
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return Object.fromEntries(
|
|
194
|
+
Object.entries(results).sort(([, a], [, b]) => a.order - b.order || a.key.localeCompare(b.key))
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function getAllProjectStatuses(
|
|
199
|
+
model: OrganizationModel,
|
|
200
|
+
appliesTo: 'project' | 'milestone' | 'task'
|
|
201
|
+
): ProjectStatus[] {
|
|
202
|
+
return catalogRecords(model)
|
|
203
|
+
.filter((catalog) => catalog.kind === 'status-flow' && appliesToEntityKind(catalog) === appliesTo)
|
|
204
|
+
.flatMap((catalog) =>
|
|
205
|
+
entriesOf(catalog).map(([entryId, entry]) => ({
|
|
206
|
+
id: entryId,
|
|
207
|
+
label: stringValue(entry.label) ?? entryId,
|
|
208
|
+
order: numberValue(entry.order),
|
|
209
|
+
...(stringValue(entry.color) ? { color: stringValue(entry.color) } : {}),
|
|
210
|
+
...(stringValue(entry.description) ? { description: stringValue(entry.description) } : {})
|
|
211
|
+
}))
|
|
212
|
+
)
|
|
213
|
+
.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id))
|
|
214
|
+
}
|
|
@@ -292,7 +292,6 @@ type SystemLike = {
|
|
|
292
292
|
title?: string
|
|
293
293
|
description?: string
|
|
294
294
|
ontology?: OntologyScope
|
|
295
|
-
content?: Record<string, ContentLike>
|
|
296
295
|
systems?: Record<string, SystemLike>
|
|
297
296
|
subsystems?: Record<string, SystemLike>
|
|
298
297
|
}
|
|
@@ -319,15 +318,6 @@ type ActionLike = {
|
|
|
319
318
|
lifecycle?: string
|
|
320
319
|
}
|
|
321
320
|
|
|
322
|
-
type ContentLike = {
|
|
323
|
-
kind: string
|
|
324
|
-
type: string
|
|
325
|
-
label?: string
|
|
326
|
-
description?: string
|
|
327
|
-
parentContentId?: string
|
|
328
|
-
data?: Record<string, unknown>
|
|
329
|
-
}
|
|
330
|
-
|
|
331
321
|
type SourceContext = {
|
|
332
322
|
source: string
|
|
333
323
|
path: Array<string | number>
|
|
@@ -568,55 +558,6 @@ function addLegacyActionProjections(
|
|
|
568
558
|
}
|
|
569
559
|
}
|
|
570
560
|
|
|
571
|
-
function addSystemContentProjections(
|
|
572
|
-
index: ResolvedOntologyIndex,
|
|
573
|
-
diagnostics: OntologyDiagnostic[],
|
|
574
|
-
sourcesById: Map<string, SourceContext>,
|
|
575
|
-
systemPath: string,
|
|
576
|
-
system: SystemLike,
|
|
577
|
-
schemaPath: Array<string | number>
|
|
578
|
-
): void {
|
|
579
|
-
const content = system.content ?? {}
|
|
580
|
-
for (const [localId, node] of Object.entries(content)) {
|
|
581
|
-
if (node.kind !== 'schema') continue
|
|
582
|
-
|
|
583
|
-
const entries = Object.fromEntries(
|
|
584
|
-
Object.entries(content)
|
|
585
|
-
.filter(([, candidate]) => candidate.parentContentId === localId)
|
|
586
|
-
.map(([entryId, candidate]) => [
|
|
587
|
-
entryId,
|
|
588
|
-
{
|
|
589
|
-
label: candidate.label ?? entryId,
|
|
590
|
-
type: candidate.type,
|
|
591
|
-
...(candidate.description !== undefined ? { description: candidate.description } : {}),
|
|
592
|
-
...(candidate.data !== undefined ? candidate.data : {})
|
|
593
|
-
}
|
|
594
|
-
])
|
|
595
|
-
)
|
|
596
|
-
|
|
597
|
-
const catalogType: OntologyCatalogType = {
|
|
598
|
-
id: formatOntologyId({ scope: systemPath, kind: 'catalog', localId }),
|
|
599
|
-
label: node.label ?? localId,
|
|
600
|
-
description: node.description,
|
|
601
|
-
ownerSystemId: systemPath,
|
|
602
|
-
kind: node.type,
|
|
603
|
-
...(typeof node.data?.['entityId'] === 'string'
|
|
604
|
-
? { appliesTo: formatOntologyId({ scope: systemPath, kind: 'object', localId: node.data['entityId'] }) }
|
|
605
|
-
: {}),
|
|
606
|
-
...(Object.keys(entries).length > 0 ? { entries } : {}),
|
|
607
|
-
...(node.data !== undefined ? { data: node.data } : {})
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
addRecord(index, diagnostics, sourcesById, 'catalogTypes', catalogType, {
|
|
611
|
-
source: 'legacy.system.content',
|
|
612
|
-
path: [...schemaPath, 'content', localId],
|
|
613
|
-
kind: 'projected',
|
|
614
|
-
systemPath,
|
|
615
|
-
legacyId: `${systemPath}:${localId}`
|
|
616
|
-
})
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
561
|
function addSystemScopes(
|
|
621
562
|
index: ResolvedOntologyIndex,
|
|
622
563
|
diagnostics: OntologyDiagnostic[],
|
|
@@ -632,7 +573,6 @@ function addSystemScopes(
|
|
|
632
573
|
...currentPath,
|
|
633
574
|
'ontology'
|
|
634
575
|
])
|
|
635
|
-
addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, currentPath)
|
|
636
576
|
addSystemScopes(index, diagnostics, sourcesById, childSystemsOf(system), systemPath, [
|
|
637
577
|
...currentPath,
|
|
638
578
|
system.systems !== undefined ? 'systems' : 'subsystems'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Organization Graph
|
|
3
|
-
description: Organization OS graph layer documentation for the organization graph derived from Organization Model Systems, resources, actions, entities,
|
|
3
|
+
description: Organization OS graph layer documentation for the organization graph derived from Organization Model Systems, resources, actions, entities, ontology catalogs, and typed links.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Overview
|
|
@@ -38,7 +38,6 @@ Node kinds:
|
|
|
38
38
|
- `goal`
|
|
39
39
|
- `surface`
|
|
40
40
|
- `navigation-group`
|
|
41
|
-
- `content-node`
|
|
42
41
|
|
|
43
42
|
Edge kinds:
|
|
44
43
|
|
|
@@ -58,7 +57,7 @@ Edge kinds:
|
|
|
58
57
|
|
|
59
58
|
System nodes come from the id-keyed `OrganizationModel.systems` map. Their graph IDs use `system:<id>`, such as `system:sales.crm`.
|
|
60
59
|
|
|
61
|
-
Resource, action, entity, policy, navigation, and
|
|
60
|
+
Resource, action, entity, policy, navigation, and ontology catalog edges are derived from canonical OM maps:
|
|
62
61
|
|
|
63
62
|
```ts
|
|
64
63
|
// ResourceEntry.systemPath => system -> resource contains
|
|
@@ -67,7 +66,7 @@ Resource, action, entity, policy, navigation, and content edges are derived from
|
|
|
67
66
|
// Action.affects[] => action -> entity affects
|
|
68
67
|
// Entity.links[] => entity -> entity links
|
|
69
68
|
// ResourceEntry.emits[] => resource -> event emits
|
|
70
|
-
// System.
|
|
69
|
+
// System.ontology.catalogTypes => ontology catalog nodes and relationships
|
|
71
70
|
// AgentResource.invocations[] => agent resource -> invocation target uses/references
|
|
72
71
|
```
|
|
73
72
|
|
|
@@ -84,7 +83,7 @@ interface BuildOrganizationGraphInput {
|
|
|
84
83
|
|
|
85
84
|
1. Reads Organization Model Systems and derives `system:*` nodes.
|
|
86
85
|
2. Reads OM resources, including workflow, agent, integration, and script resources, as `resource` nodes.
|
|
87
|
-
3. Emits derived graph links from System, Resource, Action, Entity, Policy, Agent invocation, Knowledge, navigation, and
|
|
86
|
+
3. Emits derived graph links from System, Resource, Action, Entity, Policy, Agent invocation, Knowledge, navigation, and ontology catalog contracts.
|
|
88
87
|
4. Bridges Command View runtime topology into resource nodes and relationship edges.
|
|
89
88
|
5. Returns a renderer-agnostic DTO.
|
|
90
89
|
|
|
@@ -179,7 +179,7 @@ The model keeps business semantics in named domains:
|
|
|
179
179
|
- `policies` -- operational governance rules over systems, actions, resources, and roles
|
|
180
180
|
- `knowledge` -- playbooks, strategies, references, and graph-governing links
|
|
181
181
|
|
|
182
|
-
System-local operational catalogs
|
|
182
|
+
System-local operational catalogs live under `System.ontology.catalogTypes`, including pipeline, stage, template, template-step, status-flow, and status records. System-local settings live in `System.config`. The legacy compound and status domains should not be used for new authoring.
|
|
183
183
|
|
|
184
184
|
## Authoring and Resolution
|
|
185
185
|
|