@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
|
@@ -118,13 +118,12 @@ describe('SystemStatusSchema', () => {
|
|
|
118
118
|
})
|
|
119
119
|
})
|
|
120
120
|
|
|
121
|
-
describe('resolveOrganizationModel - systems domain integration', () => {
|
|
122
|
-
it('omitting systems keeps
|
|
123
|
-
const model = resolveOrganizationModel({})
|
|
124
|
-
|
|
125
|
-
expect(
|
|
126
|
-
|
|
127
|
-
})
|
|
121
|
+
describe('resolveOrganizationModel - systems domain integration', () => {
|
|
122
|
+
it('omitting systems keeps the generic systems domain empty', () => {
|
|
123
|
+
const model = resolveOrganizationModel({})
|
|
124
|
+
|
|
125
|
+
expect(model.systems).toEqual(DEFAULT_ORGANIZATION_MODEL_SYSTEMS)
|
|
126
|
+
})
|
|
128
127
|
|
|
129
128
|
it('accepts valid responsible role, knowledge, and goal references', () => {
|
|
130
129
|
expect(() =>
|
|
@@ -24,7 +24,7 @@ import type { DeepPartial, OrganizationModel } from '../types'
|
|
|
24
24
|
|
|
25
25
|
describe('flatten: deepMerge produces additive-by-id behavior across all 9 flattened domains', () => {
|
|
26
26
|
// Phase 4 (D1): 'statuses' top-level field removed from OrganizationModel.
|
|
27
|
-
// Status data moved into
|
|
27
|
+
// Status data moved into System.ontology.catalogTypes.
|
|
28
28
|
// The remaining 8 domains are all Record<string, Entry> after the flatten.
|
|
29
29
|
const FLATTENED_DOMAINS = [
|
|
30
30
|
'systems',
|
|
@@ -59,12 +59,9 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
59
59
|
}
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
-
expect(Object.keys(model.systems)).toHaveLength(baseSize + 1)
|
|
63
|
-
expect(model.systems['tenant.workspace']?.label).toBe('Tenant Workspace')
|
|
64
|
-
|
|
65
|
-
expect(model.systems['dashboard']).toBeDefined()
|
|
66
|
-
expect(model.systems['operations']).toBeDefined()
|
|
67
|
-
})
|
|
62
|
+
expect(Object.keys(model.systems)).toHaveLength(baseSize + 1)
|
|
63
|
+
expect(model.systems['tenant.workspace']?.label).toBe('Tenant Workspace')
|
|
64
|
+
})
|
|
68
65
|
|
|
69
66
|
it('merges a tenant role additively without clobbering default roles', () => {
|
|
70
67
|
const baseSize = Object.keys(DEFAULT_ORGANIZATION_MODEL.roles).length
|
|
@@ -83,11 +80,10 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
83
80
|
expect(model.roles['role.tenant-lead']?.title).toBe('Tenant Lead')
|
|
84
81
|
})
|
|
85
82
|
|
|
86
|
-
it('merges a tenant action additively while preserving the default action catalog', () => {
|
|
87
|
-
const baseSize = Object.keys(DEFAULT_ORGANIZATION_MODEL.actions).length
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const model = resolveOrganizationModel({
|
|
83
|
+
it('merges a tenant action additively while preserving the default action catalog', () => {
|
|
84
|
+
const baseSize = Object.keys(DEFAULT_ORGANIZATION_MODEL.actions).length
|
|
85
|
+
|
|
86
|
+
const model = resolveOrganizationModel({
|
|
91
87
|
actions: {
|
|
92
88
|
'tenant.custom-action': {
|
|
93
89
|
id: 'tenant.custom-action',
|
|
@@ -98,12 +94,10 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
98
94
|
}
|
|
99
95
|
}
|
|
100
96
|
})
|
|
101
|
-
|
|
102
|
-
expect(Object.keys(model.actions)).toHaveLength(baseSize + 1)
|
|
103
|
-
expect(model.actions['tenant.custom-action']?.label).toBe('Custom Action')
|
|
104
|
-
|
|
105
|
-
expect(model.actions['send_reply']).toBeDefined()
|
|
106
|
-
})
|
|
97
|
+
|
|
98
|
+
expect(Object.keys(model.actions)).toHaveLength(baseSize + 1)
|
|
99
|
+
expect(model.actions['tenant.custom-action']?.label).toBe('Custom Action')
|
|
100
|
+
})
|
|
107
101
|
|
|
108
102
|
it('overrides an existing system by id (last write wins on the same map key)', () => {
|
|
109
103
|
const model = resolveOrganizationModel({
|
|
@@ -119,29 +113,23 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
119
113
|
})
|
|
120
114
|
|
|
121
115
|
expect(model.systems['dashboard']?.label).toBe('Tenant Dashboard')
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
const merged = model.systems['dashboard']
|
|
142
|
-
expect(merged?.label).toBe('Renamed')
|
|
143
|
-
// Path from defaults survives because object merge is deep per-key.
|
|
144
|
-
expect(merged?.path).toBe(defaultDashboard!.path)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('adds a complete system entry when no generic default entry exists', () => {
|
|
119
|
+
const model = resolveOrganizationModel({
|
|
120
|
+
systems: {
|
|
121
|
+
dashboard: {
|
|
122
|
+
id: 'dashboard',
|
|
123
|
+
order: 10,
|
|
124
|
+
label: 'Renamed',
|
|
125
|
+
path: '/'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const merged = model.systems['dashboard']
|
|
131
|
+
expect(merged?.label).toBe('Renamed')
|
|
132
|
+
expect(merged?.path).toBe('/')
|
|
145
133
|
})
|
|
146
134
|
|
|
147
135
|
it('confirms no special-case mergeSystemsById helper exists in resolve.ts', async () => {
|
|
@@ -216,23 +204,18 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
216
204
|
})
|
|
217
205
|
})
|
|
218
206
|
|
|
219
|
-
it('override entry omitting order
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
id: 'dashboard',
|
|
226
|
-
label: 'Renamed Dashboard'
|
|
207
|
+
it('override entry omitting required order is rejected when no base entry exists', () => {
|
|
208
|
+
const override: DeepPartial<OrganizationModel> = {
|
|
209
|
+
systems: {
|
|
210
|
+
dashboard: {
|
|
211
|
+
id: 'dashboard',
|
|
212
|
+
label: 'Renamed Dashboard'
|
|
227
213
|
}
|
|
228
214
|
}
|
|
229
215
|
}
|
|
230
216
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
expect(resolved.systems['dashboard']!.order).toBe(baseOrder)
|
|
234
|
-
expect(resolved.systems['dashboard']!.label).toBe('Renamed Dashboard')
|
|
235
|
-
})
|
|
217
|
+
expect(() => resolveOrganizationModel(override)).toThrow()
|
|
218
|
+
})
|
|
236
219
|
|
|
237
220
|
it('throws when system map key does not match the entry id', () => {
|
|
238
221
|
const badOverride: DeepPartial<OrganizationModel> = {
|
|
@@ -255,13 +238,20 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
255
238
|
// deepMerge hits Array.isArray(existing) => returns override value directly.
|
|
256
239
|
const singleRef = [{ actionId: 'lead-gen.company.source', intent: 'exposes' as const }]
|
|
257
240
|
|
|
258
|
-
const override: DeepPartial<OrganizationModel> = {
|
|
259
|
-
|
|
260
|
-
'
|
|
261
|
-
id: '
|
|
262
|
-
order:
|
|
263
|
-
label: '
|
|
264
|
-
|
|
241
|
+
const override: DeepPartial<OrganizationModel> = {
|
|
242
|
+
actions: {
|
|
243
|
+
'lead-gen.company.source': {
|
|
244
|
+
id: 'lead-gen.company.source',
|
|
245
|
+
order: 10,
|
|
246
|
+
label: 'Source companies'
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
systems: {
|
|
250
|
+
'sales.lead-gen': {
|
|
251
|
+
id: 'sales.lead-gen',
|
|
252
|
+
order: 10,
|
|
253
|
+
label: 'Lead Gen',
|
|
254
|
+
actions: singleRef
|
|
265
255
|
}
|
|
266
256
|
}
|
|
267
257
|
}
|
|
@@ -280,23 +270,21 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
280
270
|
expect(withEmpty.systems).toEqual(withNone.systems)
|
|
281
271
|
})
|
|
282
272
|
|
|
283
|
-
it('field set to undefined in override is skipped and retains the base value', () => {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
label: 'Dashboard',
|
|
292
|
-
path: undefined
|
|
273
|
+
it('field set to undefined in override is skipped and retains the base value', () => {
|
|
274
|
+
const override: DeepPartial<OrganizationModel> = {
|
|
275
|
+
systems: {
|
|
276
|
+
dashboard: {
|
|
277
|
+
id: 'dashboard',
|
|
278
|
+
order: 10,
|
|
279
|
+
label: 'Dashboard',
|
|
280
|
+
path: undefined
|
|
293
281
|
}
|
|
294
282
|
}
|
|
295
283
|
}
|
|
296
284
|
|
|
297
|
-
const resolved = resolveOrganizationModel(override)
|
|
298
|
-
|
|
299
|
-
expect(resolved.systems['dashboard']!.path).
|
|
285
|
+
const resolved = resolveOrganizationModel(override)
|
|
286
|
+
|
|
287
|
+
expect(resolved.systems['dashboard']!.path).toBeUndefined()
|
|
300
288
|
})
|
|
301
289
|
|
|
302
290
|
it('simultaneous override of systems, roles, and actions merges each domain independently without cross-contamination', () => {
|
|
@@ -343,12 +331,12 @@ describe('flatten: deepMerge produces additive-by-id behavior across all 9 flatt
|
|
|
343
331
|
const replacementInvocations = [{ kind: 'slash-command' as const, command: '/custom-source' }]
|
|
344
332
|
|
|
345
333
|
const override: DeepPartial<OrganizationModel> = {
|
|
346
|
-
actions: {
|
|
347
|
-
'lead-gen.company.source': {
|
|
348
|
-
id: 'lead-gen.company.source',
|
|
349
|
-
order:
|
|
350
|
-
label: 'Source companies',
|
|
351
|
-
invocations: replacementInvocations
|
|
334
|
+
actions: {
|
|
335
|
+
'lead-gen.company.source': {
|
|
336
|
+
id: 'lead-gen.company.source',
|
|
337
|
+
order: 10,
|
|
338
|
+
label: 'Source companies',
|
|
339
|
+
invocations: replacementInvocations
|
|
352
340
|
}
|
|
353
341
|
}
|
|
354
342
|
}
|
|
@@ -1,11 +1,77 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { createFoundationOrganizationModel } from '../foundation'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
2
|
+
import { createFoundationOrganizationModel } from '../foundation'
|
|
3
|
+
|
|
4
|
+
const foundationFixture = {
|
|
5
|
+
branding: { organizationName: 'Acme', productName: 'Acme OS', shortName: 'Acme' },
|
|
6
|
+
systems: {
|
|
7
|
+
dashboard: { id: 'dashboard', order: 10, label: 'Dashboard', lifecycle: 'active' as const },
|
|
8
|
+
sales: { id: 'sales', order: 20, label: 'Sales', lifecycle: 'active' as const },
|
|
9
|
+
clients: { id: 'clients', order: 30, label: 'Clients', lifecycle: 'active' as const },
|
|
10
|
+
projects: { id: 'projects', order: 40, label: 'Projects', lifecycle: 'active' as const },
|
|
11
|
+
operations: { id: 'operations', order: 50, label: 'Operations', lifecycle: 'active' as const },
|
|
12
|
+
'settings.account': { id: 'settings.account', order: 60, label: 'Account', lifecycle: 'active' as const }
|
|
13
|
+
},
|
|
14
|
+
navigation: {
|
|
15
|
+
sidebar: {
|
|
16
|
+
primary: {
|
|
17
|
+
dashboard: {
|
|
18
|
+
type: 'surface' as const,
|
|
19
|
+
label: 'Dashboard',
|
|
20
|
+
path: '/',
|
|
21
|
+
surfaceType: 'dashboard' as const,
|
|
22
|
+
order: 10,
|
|
23
|
+
targets: { systems: ['dashboard'] }
|
|
24
|
+
},
|
|
25
|
+
sales: {
|
|
26
|
+
type: 'surface' as const,
|
|
27
|
+
label: 'Sales',
|
|
28
|
+
path: '/sales',
|
|
29
|
+
surfaceType: 'page' as const,
|
|
30
|
+
order: 20,
|
|
31
|
+
targets: { systems: ['sales'] }
|
|
32
|
+
},
|
|
33
|
+
clients: {
|
|
34
|
+
type: 'surface' as const,
|
|
35
|
+
label: 'Clients',
|
|
36
|
+
path: '/clients',
|
|
37
|
+
surfaceType: 'list' as const,
|
|
38
|
+
order: 30,
|
|
39
|
+
targets: { systems: ['clients'] }
|
|
40
|
+
},
|
|
41
|
+
projects: {
|
|
42
|
+
type: 'surface' as const,
|
|
43
|
+
label: 'Projects',
|
|
44
|
+
path: '/projects',
|
|
45
|
+
surfaceType: 'page' as const,
|
|
46
|
+
order: 40,
|
|
47
|
+
targets: { systems: ['projects'] }
|
|
48
|
+
},
|
|
49
|
+
'operations-overview': {
|
|
50
|
+
type: 'surface' as const,
|
|
51
|
+
label: 'Operations',
|
|
52
|
+
path: '/operations',
|
|
53
|
+
surfaceType: 'page' as const,
|
|
54
|
+
order: 50,
|
|
55
|
+
targets: { systems: ['operations'] }
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
bottom: {
|
|
59
|
+
'settings-account': {
|
|
60
|
+
type: 'surface' as const,
|
|
61
|
+
label: 'Account',
|
|
62
|
+
path: '/settings/account',
|
|
63
|
+
surfaceType: 'settings' as const,
|
|
64
|
+
order: 10,
|
|
65
|
+
targets: { systems: ['settings.account'] }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
describe('createFoundationOrganizationModel', () => {
|
|
73
|
+
it('builds the foundation model from derived sidebar navigation', () => {
|
|
74
|
+
const result = createFoundationOrganizationModel(foundationFixture)
|
|
9
75
|
|
|
10
76
|
expect(result.canonical.branding.organizationName).toBe('Acme')
|
|
11
77
|
expect(result.homeLabel).toBe('Dashboard')
|
|
@@ -27,13 +93,11 @@ describe('createFoundationOrganizationModel', () => {
|
|
|
27
93
|
|
|
28
94
|
it.skip('passes deeper overrides through to the canonical model (deferred - Phase 4: sales domain removed)', () => {
|
|
29
95
|
// Previously tested: result.canonical.sales.pipelines.
|
|
30
|
-
// Re-enable with
|
|
96
|
+
// Re-enable with an ontology catalog based pipeline override test if needed.
|
|
31
97
|
})
|
|
32
98
|
|
|
33
|
-
it('exposes a working getOrganizationSurface lookup', () => {
|
|
34
|
-
const result = createFoundationOrganizationModel(
|
|
35
|
-
branding: { organizationName: 'Acme', productName: 'Acme OS', shortName: 'Acme' }
|
|
36
|
-
})
|
|
99
|
+
it('exposes a working getOrganizationSurface lookup', () => {
|
|
100
|
+
const result = createFoundationOrganizationModel(foundationFixture)
|
|
37
101
|
|
|
38
102
|
const clientsSurface = result.getOrganizationSurface('clients')
|
|
39
103
|
expect(clientsSurface).toBeDefined()
|
|
@@ -44,8 +108,11 @@ describe('createFoundationOrganizationModel', () => {
|
|
|
44
108
|
})
|
|
45
109
|
|
|
46
110
|
it('does not require hardcoded system-backed foundation surfaces', () => {
|
|
47
|
-
const result = createFoundationOrganizationModel({
|
|
48
|
-
|
|
111
|
+
const result = createFoundationOrganizationModel({
|
|
112
|
+
systems: {
|
|
113
|
+
dashboard: { id: 'dashboard', order: 10, label: 'Dashboard', lifecycle: 'active' }
|
|
114
|
+
},
|
|
115
|
+
navigation: {
|
|
49
116
|
sidebar: {
|
|
50
117
|
primary: {
|
|
51
118
|
dashboard: {
|