@elevasis/core 0.22.0 → 0.24.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 +3214 -2501
- package/dist/index.js +3112 -1222
- package/dist/knowledge/index.d.ts +1108 -1264
- package/dist/knowledge/index.js +112 -9
- package/dist/organization-model/index.d.ts +3214 -2501
- package/dist/organization-model/index.js +3112 -1222
- package/dist/test-utils/index.d.ts +985 -1103
- package/dist/test-utils/index.js +2464 -1165
- package/package.json +5 -5
- package/src/README.md +14 -14
- package/src/__tests__/publish.test.ts +24 -24
- package/src/__tests__/template-core-compatibility.test.ts +9 -80
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2389 -2121
- package/src/_gen/__tests__/scaffold-contracts.test.ts +30 -30
- package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -217
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +69 -69
- package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +37 -37
- package/src/auth/multi-tenancy/index.ts +26 -26
- package/src/auth/multi-tenancy/invitations/api-schemas.ts +104 -104
- package/src/auth/multi-tenancy/memberships/api-schemas.ts +143 -143
- package/src/auth/multi-tenancy/memberships/index.ts +26 -26
- package/src/auth/multi-tenancy/memberships/membership.ts +130 -130
- package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -194
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -136
- package/src/auth/multi-tenancy/permissions.test.ts +42 -42
- package/src/auth/multi-tenancy/permissions.ts +123 -123
- package/src/auth/multi-tenancy/role-management/api-schemas.ts +78 -78
- package/src/auth/multi-tenancy/role-management/index.ts +16 -16
- package/src/auth/multi-tenancy/theme-presets.ts +45 -45
- package/src/auth/multi-tenancy/types.ts +57 -57
- package/src/auth/multi-tenancy/users/api-schemas.ts +165 -165
- package/src/business/README.md +2 -2
- package/src/business/acquisition/activity-events.test.ts +250 -250
- package/src/business/acquisition/activity-events.ts +93 -93
- package/src/business/acquisition/api-schemas.test.ts +1883 -1843
- package/src/business/acquisition/api-schemas.ts +1493 -1500
- package/src/business/acquisition/build-templates.test.ts +240 -240
- package/src/business/acquisition/build-templates.ts +83 -41
- package/src/business/acquisition/crm-next-action.test.ts +262 -262
- package/src/business/acquisition/crm-next-action.ts +220 -220
- package/src/business/acquisition/crm-priority.test.ts +216 -216
- package/src/business/acquisition/crm-priority.ts +349 -349
- package/src/business/acquisition/crm-state-actions.test.ts +153 -151
- package/src/business/acquisition/deal-ownership.test.ts +351 -351
- package/src/business/acquisition/deal-ownership.ts +120 -120
- package/src/business/acquisition/derive-actions.test.ts +129 -104
- package/src/business/acquisition/derive-actions.ts +74 -84
- package/src/business/acquisition/index.ts +171 -170
- package/src/business/acquisition/ontology-validation.ts +309 -0
- package/src/business/acquisition/stateful.ts +30 -30
- package/src/business/acquisition/types.ts +396 -392
- package/src/business/clients/api-schemas.test.ts +115 -115
- package/src/business/clients/api-schemas.ts +158 -158
- package/src/business/clients/index.ts +1 -1
- package/src/business/crm/api-schemas.ts +40 -40
- package/src/business/crm/index.ts +1 -1
- package/src/business/deals/api-schemas.ts +87 -87
- package/src/business/deals/index.ts +1 -1
- package/src/business/index.ts +5 -5
- package/src/business/projects/types.ts +144 -144
- package/src/commands/queue/types/task.ts +15 -15
- package/src/execution/core/runner-types.ts +61 -61
- package/src/execution/core/sse-executions.ts +7 -7
- package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -10
- package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -16
- package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -4
- package/src/execution/engine/agent/core/types.ts +25 -25
- package/src/execution/engine/agent/index.ts +6 -6
- package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -24
- package/src/execution/engine/index.ts +443 -443
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +298 -298
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -55
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -107
- package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -48
- package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -99
- package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -1
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -363
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -162
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -316
- package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -18
- package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -194
- package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -7
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -204
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -105
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -428
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -2
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1474
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -103
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -88
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -141
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -76
- package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -182
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -310
- package/src/execution/engine/tools/integration/service.test.ts +239 -239
- package/src/execution/engine/tools/integration/service.ts +172 -172
- package/src/execution/engine/tools/integration/tool.ts +255 -255
- package/src/execution/engine/tools/lead-service-types.ts +1005 -1005
- package/src/execution/engine/tools/messages.ts +43 -43
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -7
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -6
- package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -6
- package/src/execution/engine/tools/platform/acquisition/types.ts +280 -280
- package/src/execution/engine/tools/platform/email/types.ts +97 -97
- package/src/execution/engine/tools/registry.ts +704 -704
- package/src/execution/engine/tools/tool-maps.ts +831 -831
- package/src/execution/engine/tools/types.ts +234 -234
- package/src/execution/engine/workflow/types.ts +202 -202
- package/src/execution/external/__tests__/api-schemas.test.ts +127 -127
- package/src/execution/external/api-schemas.ts +40 -40
- package/src/execution/external/index.ts +1 -1
- package/src/index.ts +18 -18
- package/src/integrations/credentials/__tests__/api-schemas.test.ts +420 -420
- package/src/integrations/credentials/api-schemas.ts +146 -146
- package/src/integrations/credentials/schemas.ts +200 -200
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -7
- package/src/integrations/oauth/provider-registry.ts +74 -74
- package/src/integrations/oauth/server/credentials.ts +43 -43
- package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +327 -327
- package/src/integrations/webhook-endpoints/api-schemas.ts +103 -103
- package/src/integrations/webhook-endpoints/types.ts +58 -58
- package/src/knowledge/README.md +33 -32
- package/src/knowledge/__tests__/queries.test.ts +633 -541
- package/src/knowledge/format.ts +100 -99
- package/src/knowledge/index.ts +5 -5
- package/src/knowledge/published.ts +5 -5
- package/src/knowledge/queries.ts +274 -222
- package/src/operations/activities/api-schemas.ts +80 -80
- package/src/operations/activities/types.ts +64 -64
- package/src/organization-model/README.md +149 -109
- package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
- package/src/organization-model/__tests__/defaults.test.ts +168 -194
- package/src/organization-model/__tests__/domains/actions.test.ts +78 -0
- package/src/organization-model/__tests__/domains/customers.test.ts +48 -44
- package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
- package/src/organization-model/__tests__/domains/goals.test.ts +110 -96
- package/src/organization-model/__tests__/domains/identity.test.ts +4 -3
- package/src/organization-model/__tests__/domains/navigation.test.ts +222 -166
- package/src/organization-model/__tests__/domains/offerings.test.ts +83 -88
- package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
- package/src/organization-model/__tests__/domains/resource-mappings.test.ts +30 -30
- package/src/organization-model/__tests__/domains/resources.test.ts +396 -175
- package/src/organization-model/__tests__/domains/roles.test.ts +463 -402
- package/src/organization-model/__tests__/domains/statuses.test.ts +13 -10
- package/src/organization-model/__tests__/domains/systems.test.ts +209 -193
- package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -0
- package/src/organization-model/__tests__/foundation.test.ts +47 -75
- package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
- package/src/organization-model/__tests__/graph.test.ts +1336 -149
- package/src/organization-model/__tests__/icons.test.ts +10 -1
- package/src/organization-model/__tests__/knowledge.test.ts +418 -61
- package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
- package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -94
- package/src/organization-model/__tests__/recursive-system-schema.test.ts +549 -0
- package/src/organization-model/__tests__/resolve.test.ts +303 -42
- package/src/organization-model/__tests__/schema.test.ts +863 -153
- package/src/organization-model/__tests__/surface-projection.test.ts +284 -174
- package/src/organization-model/catalogs/lead-gen.ts +144 -0
- package/src/organization-model/content-kinds/config.ts +36 -0
- package/src/organization-model/content-kinds/index.ts +78 -0
- package/src/organization-model/content-kinds/pipeline.ts +68 -0
- package/src/organization-model/content-kinds/registry.ts +44 -0
- package/src/organization-model/content-kinds/status.ts +71 -0
- package/src/organization-model/content-kinds/template.ts +83 -0
- package/src/organization-model/content-kinds/types.ts +117 -0
- package/src/organization-model/contracts.ts +27 -17
- package/src/organization-model/defaults.ts +489 -107
- package/src/organization-model/domains/actions.ts +333 -0
- package/src/organization-model/domains/customers.ts +10 -7
- package/src/organization-model/domains/entities.ts +144 -0
- package/src/organization-model/domains/goals.ts +9 -6
- package/src/organization-model/domains/knowledge.ts +128 -54
- package/src/organization-model/domains/navigation.ts +139 -416
- package/src/organization-model/domains/offerings.ts +15 -10
- package/src/organization-model/domains/policies.ts +102 -0
- package/src/organization-model/domains/projects.ts +6 -40
- package/src/organization-model/domains/prospecting.ts +395 -514
- package/src/organization-model/domains/resources.ts +173 -81
- package/src/organization-model/domains/roles.ts +96 -93
- package/src/organization-model/domains/sales.test.ts +218 -218
- package/src/organization-model/domains/sales.ts +380 -589
- package/src/organization-model/domains/shared.ts +8 -8
- package/src/organization-model/domains/statuses.ts +298 -89
- package/src/organization-model/domains/systems.ts +240 -38
- package/src/organization-model/foundation.ts +35 -48
- package/src/organization-model/graph/build.ts +1035 -279
- package/src/organization-model/graph/index.ts +4 -4
- package/src/organization-model/graph/link.ts +10 -10
- package/src/organization-model/graph/schema.ts +77 -56
- package/src/organization-model/graph/types.ts +75 -56
- package/src/organization-model/helpers.ts +312 -59
- package/src/organization-model/icons.ts +78 -66
- package/src/organization-model/index.ts +129 -16
- package/src/organization-model/migration-helpers.ts +252 -0
- package/src/organization-model/ontology.ts +661 -0
- package/src/organization-model/organization-graph.mdx +110 -89
- package/src/organization-model/organization-model.mdx +226 -171
- package/src/organization-model/published.ts +295 -139
- package/src/organization-model/resolve.ts +139 -21
- package/src/organization-model/schema.ts +841 -301
- package/src/organization-model/surface-projection.ts +212 -218
- package/src/organization-model/types.ts +181 -90
- package/src/platform/api/types.ts +38 -38
- package/src/platform/constants/versions.ts +3 -3
- package/src/platform/index.ts +23 -23
- package/src/platform/registry/__tests__/command-view.test.ts +5 -7
- package/src/platform/registry/__tests__/resource-link.test.ts +35 -30
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +17 -32
- package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
- package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2051
- package/src/platform/registry/__tests__/validation.test.ts +1347 -1343
- package/src/platform/registry/command-view.ts +10 -10
- package/src/platform/registry/index.ts +103 -103
- package/src/platform/registry/resource-link.ts +32 -32
- package/src/platform/registry/resource-registry.ts +890 -878
- package/src/platform/registry/serialization.ts +295 -295
- package/src/platform/registry/serialized-types.ts +166 -166
- package/src/platform/registry/stats-types.ts +68 -68
- package/src/platform/registry/types.ts +425 -425
- package/src/platform/registry/validation.ts +745 -743
- package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
- package/src/platform/utils/validation.ts +425 -425
- package/src/projects/api-schemas.test.ts +39 -39
- package/src/projects/api-schemas.ts +291 -291
- package/src/reference/_generated/contracts.md +2389 -2121
- package/src/reference/glossary.md +76 -76
- package/src/scaffold-registry/__tests__/index.test.ts +206 -206
- package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
- package/src/scaffold-registry/index.ts +392 -392
- package/src/scaffold-registry/schema.ts +243 -243
- package/src/server.ts +289 -289
- package/src/supabase/database.types.ts +3153 -3093
- package/src/test-utils/README.md +37 -37
- package/src/test-utils/entities.ts +108 -108
- package/src/test-utils/fixtures/memberships.ts +82 -82
- package/src/test-utils/index.ts +12 -12
- package/src/test-utils/organization-model.ts +65 -65
- package/src/test-utils/published.ts +6 -6
- package/src/test-utils/rls/RLSTestContext.ts +588 -588
- package/src/test-utils/test-utils.test.ts +44 -49
- package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
- package/src/organization-model/domains/features.ts +0 -31
- package/src/organization-model/domains/operations.ts +0 -85
|
@@ -16,6 +16,7 @@ describe('StatusEntrySchema — positive parse', () => {
|
|
|
16
16
|
it('accepts a fully-specified entry (id, label, semanticClass, category)', () => {
|
|
17
17
|
const result = StatusEntrySchema.safeParse({
|
|
18
18
|
id: 'delivery.task.planned',
|
|
19
|
+
order: 10,
|
|
19
20
|
label: 'Planned',
|
|
20
21
|
semanticClass: 'delivery.task',
|
|
21
22
|
category: 'delivery'
|
|
@@ -26,6 +27,7 @@ describe('StatusEntrySchema — positive parse', () => {
|
|
|
26
27
|
it('accepts a minimal entry without category (category is optional)', () => {
|
|
27
28
|
const result = StatusEntrySchema.safeParse({
|
|
28
29
|
id: 'queue.pending',
|
|
30
|
+
order: 10,
|
|
29
31
|
label: 'Pending',
|
|
30
32
|
semanticClass: 'queue'
|
|
31
33
|
})
|
|
@@ -38,6 +40,7 @@ describe('StatusEntrySchema — positive parse', () => {
|
|
|
38
40
|
it('trims whitespace from id and label', () => {
|
|
39
41
|
const result = StatusEntrySchema.safeParse({
|
|
40
42
|
id: ' trimmed-id ',
|
|
43
|
+
order: 10,
|
|
41
44
|
label: ' Trimmed Label ',
|
|
42
45
|
semanticClass: 'execution'
|
|
43
46
|
})
|
|
@@ -111,16 +114,16 @@ describe('StatusEntrySchema — negative parse', () => {
|
|
|
111
114
|
// ---------------------------------------------------------------------------
|
|
112
115
|
|
|
113
116
|
describe('StatusesDomainSchema — structural tests', () => {
|
|
114
|
-
it('accepts an
|
|
115
|
-
const result = StatusesDomainSchema.safeParse({
|
|
117
|
+
it('accepts an empty record', () => {
|
|
118
|
+
const result = StatusesDomainSchema.safeParse({})
|
|
116
119
|
expect(result.success).toBe(true)
|
|
117
120
|
})
|
|
118
121
|
|
|
119
|
-
it('applies an empty-
|
|
120
|
-
const result = StatusesDomainSchema.safeParse(
|
|
122
|
+
it('applies an empty-record default when the domain is omitted', () => {
|
|
123
|
+
const result = StatusesDomainSchema.safeParse(undefined)
|
|
121
124
|
expect(result.success).toBe(true)
|
|
122
125
|
if (result.success) {
|
|
123
|
-
expect(result.data
|
|
126
|
+
expect(result.data).toEqual({})
|
|
124
127
|
}
|
|
125
128
|
})
|
|
126
129
|
})
|
|
@@ -152,7 +155,7 @@ describe('StatusSemanticClassSchema — enum coverage', () => {
|
|
|
152
155
|
|
|
153
156
|
it('every entry in the seed uses one of the 8 known semanticClass values', () => {
|
|
154
157
|
const valid = new Set<string>(StatusSemanticClassSchema.options)
|
|
155
|
-
for (const entry of DEFAULT_ORGANIZATION_MODEL_STATUSES
|
|
158
|
+
for (const entry of Object.values(DEFAULT_ORGANIZATION_MODEL_STATUSES)) {
|
|
156
159
|
expect(
|
|
157
160
|
valid.has(entry.semanticClass),
|
|
158
161
|
`Unexpected semanticClass "${entry.semanticClass}" on entry "${entry.id}"`
|
|
@@ -161,7 +164,7 @@ describe('StatusSemanticClassSchema — enum coverage', () => {
|
|
|
161
164
|
})
|
|
162
165
|
|
|
163
166
|
it('all 8 semanticClass values have at least one seed entry', () => {
|
|
164
|
-
const presentClasses = new Set(DEFAULT_ORGANIZATION_MODEL_STATUSES.
|
|
167
|
+
const presentClasses = new Set(Object.values(DEFAULT_ORGANIZATION_MODEL_STATUSES).map((e) => e.semanticClass))
|
|
165
168
|
for (const cls of StatusSemanticClassSchema.options) {
|
|
166
169
|
expect(presentClasses.has(cls), `No seed entry found for semanticClass "${cls}"`).toBe(true)
|
|
167
170
|
}
|
|
@@ -174,7 +177,7 @@ describe('StatusSemanticClassSchema — enum coverage', () => {
|
|
|
174
177
|
|
|
175
178
|
describe('DEFAULT_ORGANIZATION_MODEL_STATUSES seed — per-group counts', () => {
|
|
176
179
|
function countBySemClass(cls: string) {
|
|
177
|
-
return DEFAULT_ORGANIZATION_MODEL_STATUSES.
|
|
180
|
+
return Object.values(DEFAULT_ORGANIZATION_MODEL_STATUSES).filter((e) => e.semanticClass === cls).length
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
it('has 6 delivery.project entries', () => {
|
|
@@ -208,7 +211,7 @@ describe('DEFAULT_ORGANIZATION_MODEL_STATUSES seed — per-group counts', () =>
|
|
|
208
211
|
|
|
209
212
|
describe('QueueTaskStatus coverage in seed', () => {
|
|
210
213
|
const queueValues: QueueTaskStatus[] = ['pending', 'processing', 'completed', 'failed', 'expired']
|
|
211
|
-
const queueIds = DEFAULT_ORGANIZATION_MODEL_STATUSES
|
|
214
|
+
const queueIds = Object.values(DEFAULT_ORGANIZATION_MODEL_STATUSES)
|
|
212
215
|
.filter((e) => e.semanticClass === 'queue')
|
|
213
216
|
.map((e) => e.id)
|
|
214
217
|
|
|
@@ -233,7 +236,7 @@ describe('TaskStatus (delivery) coverage in seed', () => {
|
|
|
233
236
|
'cancelled',
|
|
234
237
|
'completed'
|
|
235
238
|
]
|
|
236
|
-
const taskIds = DEFAULT_ORGANIZATION_MODEL_STATUSES
|
|
239
|
+
const taskIds = Object.values(DEFAULT_ORGANIZATION_MODEL_STATUSES)
|
|
237
240
|
.filter((e) => e.semanticClass === 'delivery.task')
|
|
238
241
|
.map((e) => e.id)
|
|
239
242
|
|
|
@@ -1,193 +1,209 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
DEFAULT_ORGANIZATION_MODEL_SYSTEMS,
|
|
4
|
-
SystemEntrySchema,
|
|
5
|
-
SystemKindSchema,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '../../domains/systems'
|
|
9
|
-
import { resolveOrganizationModel } from '../../resolve'
|
|
10
|
-
|
|
11
|
-
const VALID_SYSTEM = {
|
|
12
|
-
id: 'sys.lead-gen',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe('SystemEntrySchema - positive parse', () => {
|
|
20
|
-
it('accepts a minimal tenant-defined system', () => {
|
|
21
|
-
const result = SystemEntrySchema.safeParse(VALID_SYSTEM)
|
|
22
|
-
|
|
23
|
-
expect(result.success).toBe(true)
|
|
24
|
-
if (result.success) {
|
|
25
|
-
expect(result.data.governedByKnowledge).toEqual([])
|
|
26
|
-
expect(result.data.drivesGoals).toEqual([])
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('accepts all optional governance references when present', () => {
|
|
31
|
-
const result = SystemEntrySchema.safeParse({
|
|
32
|
-
...VALID_SYSTEM,
|
|
33
|
-
responsibleRoleId: 'role.sales-ops',
|
|
34
|
-
governedByKnowledge: ['knowledge.lead-gen-playbook'],
|
|
35
|
-
drivesGoals: ['goal.pipeline-coverage']
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
expect(result.success).toBe(true)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('trims id, title, and description', () => {
|
|
42
|
-
const result = SystemEntrySchema.safeParse({
|
|
43
|
-
...VALID_SYSTEM,
|
|
44
|
-
id: ' sys.crm ',
|
|
45
|
-
title: ' CRM ',
|
|
46
|
-
description: ' Owns relationship and deal pipeline operations. '
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
expect(result.success).toBe(true)
|
|
50
|
-
if (result.success) {
|
|
51
|
-
expect(result.data.id).toBe('sys.crm')
|
|
52
|
-
expect(result.data.title).toBe('CRM')
|
|
53
|
-
expect(result.data.description).toBe('Owns relationship and deal pipeline operations.')
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
describe('
|
|
77
|
-
it('
|
|
78
|
-
expect(
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('
|
|
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
|
-
|
|
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
|
-
|
|
160
|
-
|
|
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
|
-
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_ORGANIZATION_MODEL_SYSTEMS,
|
|
4
|
+
SystemEntrySchema,
|
|
5
|
+
SystemKindSchema,
|
|
6
|
+
SystemStatusSchema,
|
|
7
|
+
SystemsDomainSchema
|
|
8
|
+
} from '../../domains/systems'
|
|
9
|
+
import { resolveOrganizationModel } from '../../resolve'
|
|
10
|
+
|
|
11
|
+
const VALID_SYSTEM = {
|
|
12
|
+
id: 'sys.lead-gen',
|
|
13
|
+
order: 10,
|
|
14
|
+
title: 'Lead Generation Pipeline',
|
|
15
|
+
description: 'Coordinates prospecting, enrichment, qualification, and outreach preparation.',
|
|
16
|
+
kind: 'operational' as const
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('SystemEntrySchema - positive parse', () => {
|
|
20
|
+
it('accepts a minimal tenant-defined system', () => {
|
|
21
|
+
const result = SystemEntrySchema.safeParse(VALID_SYSTEM)
|
|
22
|
+
|
|
23
|
+
expect(result.success).toBe(true)
|
|
24
|
+
if (result.success) {
|
|
25
|
+
expect(result.data.governedByKnowledge).toEqual([])
|
|
26
|
+
expect(result.data.drivesGoals).toEqual([])
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('accepts all optional governance references when present', () => {
|
|
31
|
+
const result = SystemEntrySchema.safeParse({
|
|
32
|
+
...VALID_SYSTEM,
|
|
33
|
+
responsibleRoleId: 'role.sales-ops',
|
|
34
|
+
governedByKnowledge: ['knowledge.lead-gen-playbook'],
|
|
35
|
+
drivesGoals: ['goal.pipeline-coverage']
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
expect(result.success).toBe(true)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('trims id, title, and description', () => {
|
|
42
|
+
const result = SystemEntrySchema.safeParse({
|
|
43
|
+
...VALID_SYSTEM,
|
|
44
|
+
id: ' sys.crm ',
|
|
45
|
+
title: ' CRM ',
|
|
46
|
+
description: ' Owns relationship and deal pipeline operations. '
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
expect(result.success).toBe(true)
|
|
50
|
+
if (result.success) {
|
|
51
|
+
expect(result.data.id).toBe('sys.crm')
|
|
52
|
+
expect(result.data.title).toBe('CRM')
|
|
53
|
+
expect(result.data.description).toBe('Owns relationship and deal pipeline operations.')
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('accepts deprecated status and maps it to lifecycle for one-cycle compatibility', () => {
|
|
58
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined)
|
|
59
|
+
|
|
60
|
+
const result = SystemEntrySchema.safeParse({
|
|
61
|
+
...VALID_SYSTEM,
|
|
62
|
+
status: 'deprecated'
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
expect(result.success).toBe(true)
|
|
66
|
+
if (result.success) {
|
|
67
|
+
expect(result.data.status).toBe('deprecated')
|
|
68
|
+
expect(result.data.lifecycle).toBe('deprecated')
|
|
69
|
+
}
|
|
70
|
+
expect(warn).toHaveBeenCalledWith('[organization-model] System.status is deprecated; use System.lifecycle instead.')
|
|
71
|
+
|
|
72
|
+
warn.mockRestore()
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('SystemEntrySchema - negative parse', () => {
|
|
77
|
+
it('rejects missing required fields', () => {
|
|
78
|
+
expect(SystemEntrySchema.safeParse({ id: 'sys.missing' }).success).toBe(false)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('rejects an unknown system kind', () => {
|
|
82
|
+
expect(SystemEntrySchema.safeParse({ ...VALID_SYSTEM, kind: 'sales' }).success).toBe(false)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('rejects an unknown deprecated system status', () => {
|
|
86
|
+
expect(SystemEntrySchema.safeParse({ ...VALID_SYSTEM, status: 'paused' }).success).toBe(false)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('rejects IDs that do not match the OM model-id format', () => {
|
|
90
|
+
expect(SystemEntrySchema.safeParse({ ...VALID_SYSTEM, id: 'Sys Lead Gen' }).success).toBe(false)
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('SystemsDomainSchema', () => {
|
|
95
|
+
it('accepts an empty systems record', () => {
|
|
96
|
+
expect(SystemsDomainSchema.safeParse({}).success).toBe(true)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('defaults systems to an empty record when omitted', () => {
|
|
100
|
+
const result = SystemsDomainSchema.safeParse({})
|
|
101
|
+
|
|
102
|
+
expect(result.success).toBe(true)
|
|
103
|
+
if (result.success) {
|
|
104
|
+
expect(result.data).toEqual(DEFAULT_ORGANIZATION_MODEL_SYSTEMS)
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('SystemKindSchema', () => {
|
|
110
|
+
it.each(['product', 'operational', 'platform', 'diagnostic'] as const)('accepts kind "%s"', (kind) => {
|
|
111
|
+
expect(SystemKindSchema.safeParse(kind).success).toBe(true)
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe('SystemStatusSchema', () => {
|
|
116
|
+
it.each(['active', 'deprecated', 'archived'] as const)('accepts deprecated status "%s"', (status) => {
|
|
117
|
+
expect(SystemStatusSchema.safeParse(status).success).toBe(true)
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe('resolveOrganizationModel - systems domain integration', () => {
|
|
122
|
+
it('omitting systems keeps default system entries', () => {
|
|
123
|
+
const model = resolveOrganizationModel({})
|
|
124
|
+
|
|
125
|
+
expect(Object.keys(model.systems).length).toBeGreaterThan(Object.keys(DEFAULT_ORGANIZATION_MODEL_SYSTEMS).length)
|
|
126
|
+
expect(model.systems['sales.crm']?.path).toBe('/crm')
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('accepts valid responsible role, knowledge, and goal references', () => {
|
|
130
|
+
expect(() =>
|
|
131
|
+
resolveOrganizationModel({
|
|
132
|
+
roles: {
|
|
133
|
+
'role.sales-ops': { id: 'role.sales-ops', order: 10, title: 'Sales Ops' }
|
|
134
|
+
},
|
|
135
|
+
goals: {
|
|
136
|
+
'goal.pipeline-coverage': {
|
|
137
|
+
id: 'goal.pipeline-coverage',
|
|
138
|
+
order: 10,
|
|
139
|
+
description: 'Improve sales pipeline coverage',
|
|
140
|
+
periodStart: '2026-01-01',
|
|
141
|
+
periodEnd: '2026-12-31'
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
knowledge: {
|
|
145
|
+
'knowledge.lead-gen-playbook': {
|
|
146
|
+
id: 'knowledge.lead-gen-playbook',
|
|
147
|
+
kind: 'playbook',
|
|
148
|
+
title: 'Lead Gen Playbook',
|
|
149
|
+
summary: 'How lead generation is governed.',
|
|
150
|
+
body: '## Lead Gen',
|
|
151
|
+
updatedAt: '2026-05-08'
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
systems: {
|
|
155
|
+
'sys.lead-gen': {
|
|
156
|
+
...VALID_SYSTEM,
|
|
157
|
+
responsibleRoleId: 'role.sales-ops',
|
|
158
|
+
governedByKnowledge: ['knowledge.lead-gen-playbook'],
|
|
159
|
+
drivesGoals: ['goal.pipeline-coverage']
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
).not.toThrow()
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('throws when system IDs are duplicated', () => {
|
|
167
|
+
expect(() =>
|
|
168
|
+
resolveOrganizationModel({
|
|
169
|
+
systems: {
|
|
170
|
+
'sys.lead-gen': VALID_SYSTEM,
|
|
171
|
+
'sys.lead-gen-dup': {
|
|
172
|
+
...VALID_SYSTEM,
|
|
173
|
+
id: 'sys.lead-gen'
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
).toThrow()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('throws when responsibleRoleId references an unknown role', () => {
|
|
181
|
+
expect(() =>
|
|
182
|
+
resolveOrganizationModel({
|
|
183
|
+
systems: {
|
|
184
|
+
'sys.lead-gen': { ...VALID_SYSTEM, responsibleRoleId: 'role.missing' }
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
).toThrow(/unknown responsibleRoleId \\"role\.missing\\"/)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('throws when governedByKnowledge references an unknown knowledge node', () => {
|
|
191
|
+
expect(() =>
|
|
192
|
+
resolveOrganizationModel({
|
|
193
|
+
systems: {
|
|
194
|
+
'sys.lead-gen': { ...VALID_SYSTEM, governedByKnowledge: ['knowledge.missing'] }
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
).toThrow(/unknown knowledge node \\"knowledge\.missing\\"/)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('throws when drivesGoals references an unknown goal', () => {
|
|
201
|
+
expect(() =>
|
|
202
|
+
resolveOrganizationModel({
|
|
203
|
+
systems: {
|
|
204
|
+
'sys.lead-gen': { ...VALID_SYSTEM, drivesGoals: ['goal.missing'] }
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
).toThrow(/unknown goal \\"goal\.missing\\"/)
|
|
208
|
+
})
|
|
209
|
+
})
|