@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.
Files changed (244) hide show
  1. package/dist/index.d.ts +3214 -2501
  2. package/dist/index.js +3112 -1222
  3. package/dist/knowledge/index.d.ts +1108 -1264
  4. package/dist/knowledge/index.js +112 -9
  5. package/dist/organization-model/index.d.ts +3214 -2501
  6. package/dist/organization-model/index.js +3112 -1222
  7. package/dist/test-utils/index.d.ts +985 -1103
  8. package/dist/test-utils/index.js +2464 -1165
  9. package/package.json +5 -5
  10. package/src/README.md +14 -14
  11. package/src/__tests__/publish.test.ts +24 -24
  12. package/src/__tests__/template-core-compatibility.test.ts +9 -80
  13. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2389 -2121
  14. package/src/_gen/__tests__/scaffold-contracts.test.ts +30 -30
  15. package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -217
  16. package/src/auth/multi-tenancy/credentials/server/encryption.ts +69 -69
  17. package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +37 -37
  18. package/src/auth/multi-tenancy/index.ts +26 -26
  19. package/src/auth/multi-tenancy/invitations/api-schemas.ts +104 -104
  20. package/src/auth/multi-tenancy/memberships/api-schemas.ts +143 -143
  21. package/src/auth/multi-tenancy/memberships/index.ts +26 -26
  22. package/src/auth/multi-tenancy/memberships/membership.ts +130 -130
  23. package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -194
  24. package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -136
  25. package/src/auth/multi-tenancy/permissions.test.ts +42 -42
  26. package/src/auth/multi-tenancy/permissions.ts +123 -123
  27. package/src/auth/multi-tenancy/role-management/api-schemas.ts +78 -78
  28. package/src/auth/multi-tenancy/role-management/index.ts +16 -16
  29. package/src/auth/multi-tenancy/theme-presets.ts +45 -45
  30. package/src/auth/multi-tenancy/types.ts +57 -57
  31. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -165
  32. package/src/business/README.md +2 -2
  33. package/src/business/acquisition/activity-events.test.ts +250 -250
  34. package/src/business/acquisition/activity-events.ts +93 -93
  35. package/src/business/acquisition/api-schemas.test.ts +1883 -1843
  36. package/src/business/acquisition/api-schemas.ts +1493 -1500
  37. package/src/business/acquisition/build-templates.test.ts +240 -240
  38. package/src/business/acquisition/build-templates.ts +83 -41
  39. package/src/business/acquisition/crm-next-action.test.ts +262 -262
  40. package/src/business/acquisition/crm-next-action.ts +220 -220
  41. package/src/business/acquisition/crm-priority.test.ts +216 -216
  42. package/src/business/acquisition/crm-priority.ts +349 -349
  43. package/src/business/acquisition/crm-state-actions.test.ts +153 -151
  44. package/src/business/acquisition/deal-ownership.test.ts +351 -351
  45. package/src/business/acquisition/deal-ownership.ts +120 -120
  46. package/src/business/acquisition/derive-actions.test.ts +129 -104
  47. package/src/business/acquisition/derive-actions.ts +74 -84
  48. package/src/business/acquisition/index.ts +171 -170
  49. package/src/business/acquisition/ontology-validation.ts +309 -0
  50. package/src/business/acquisition/stateful.ts +30 -30
  51. package/src/business/acquisition/types.ts +396 -392
  52. package/src/business/clients/api-schemas.test.ts +115 -115
  53. package/src/business/clients/api-schemas.ts +158 -158
  54. package/src/business/clients/index.ts +1 -1
  55. package/src/business/crm/api-schemas.ts +40 -40
  56. package/src/business/crm/index.ts +1 -1
  57. package/src/business/deals/api-schemas.ts +87 -87
  58. package/src/business/deals/index.ts +1 -1
  59. package/src/business/index.ts +5 -5
  60. package/src/business/projects/types.ts +144 -144
  61. package/src/commands/queue/types/task.ts +15 -15
  62. package/src/execution/core/runner-types.ts +61 -61
  63. package/src/execution/core/sse-executions.ts +7 -7
  64. package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -10
  65. package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -16
  66. package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -4
  67. package/src/execution/engine/agent/core/types.ts +25 -25
  68. package/src/execution/engine/agent/index.ts +6 -6
  69. package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -24
  70. package/src/execution/engine/index.ts +443 -443
  71. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +298 -298
  72. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -55
  73. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -107
  74. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -48
  75. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -99
  76. package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -1
  77. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -363
  78. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -162
  79. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -316
  80. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -18
  81. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -194
  82. package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -7
  83. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -204
  84. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -105
  85. package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -428
  86. package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -2
  87. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  88. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1474
  89. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -103
  90. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -88
  91. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -141
  92. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -76
  93. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -182
  94. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -310
  95. package/src/execution/engine/tools/integration/service.test.ts +239 -239
  96. package/src/execution/engine/tools/integration/service.ts +172 -172
  97. package/src/execution/engine/tools/integration/tool.ts +255 -255
  98. package/src/execution/engine/tools/lead-service-types.ts +1005 -1005
  99. package/src/execution/engine/tools/messages.ts +43 -43
  100. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -7
  101. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -6
  102. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -6
  103. package/src/execution/engine/tools/platform/acquisition/types.ts +280 -280
  104. package/src/execution/engine/tools/platform/email/types.ts +97 -97
  105. package/src/execution/engine/tools/registry.ts +704 -704
  106. package/src/execution/engine/tools/tool-maps.ts +831 -831
  107. package/src/execution/engine/tools/types.ts +234 -234
  108. package/src/execution/engine/workflow/types.ts +202 -202
  109. package/src/execution/external/__tests__/api-schemas.test.ts +127 -127
  110. package/src/execution/external/api-schemas.ts +40 -40
  111. package/src/execution/external/index.ts +1 -1
  112. package/src/index.ts +18 -18
  113. package/src/integrations/credentials/__tests__/api-schemas.test.ts +420 -420
  114. package/src/integrations/credentials/api-schemas.ts +146 -146
  115. package/src/integrations/credentials/schemas.ts +200 -200
  116. package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -7
  117. package/src/integrations/oauth/provider-registry.ts +74 -74
  118. package/src/integrations/oauth/server/credentials.ts +43 -43
  119. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +327 -327
  120. package/src/integrations/webhook-endpoints/api-schemas.ts +103 -103
  121. package/src/integrations/webhook-endpoints/types.ts +58 -58
  122. package/src/knowledge/README.md +33 -32
  123. package/src/knowledge/__tests__/queries.test.ts +633 -541
  124. package/src/knowledge/format.ts +100 -99
  125. package/src/knowledge/index.ts +5 -5
  126. package/src/knowledge/published.ts +5 -5
  127. package/src/knowledge/queries.ts +274 -222
  128. package/src/operations/activities/api-schemas.ts +80 -80
  129. package/src/operations/activities/types.ts +64 -64
  130. package/src/organization-model/README.md +149 -109
  131. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
  132. package/src/organization-model/__tests__/defaults.test.ts +168 -194
  133. package/src/organization-model/__tests__/domains/actions.test.ts +78 -0
  134. package/src/organization-model/__tests__/domains/customers.test.ts +48 -44
  135. package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
  136. package/src/organization-model/__tests__/domains/goals.test.ts +110 -96
  137. package/src/organization-model/__tests__/domains/identity.test.ts +4 -3
  138. package/src/organization-model/__tests__/domains/navigation.test.ts +222 -166
  139. package/src/organization-model/__tests__/domains/offerings.test.ts +83 -88
  140. package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
  141. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +30 -30
  142. package/src/organization-model/__tests__/domains/resources.test.ts +396 -175
  143. package/src/organization-model/__tests__/domains/roles.test.ts +463 -402
  144. package/src/organization-model/__tests__/domains/statuses.test.ts +13 -10
  145. package/src/organization-model/__tests__/domains/systems.test.ts +209 -193
  146. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -0
  147. package/src/organization-model/__tests__/foundation.test.ts +47 -75
  148. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
  149. package/src/organization-model/__tests__/graph.test.ts +1336 -149
  150. package/src/organization-model/__tests__/icons.test.ts +10 -1
  151. package/src/organization-model/__tests__/knowledge.test.ts +418 -61
  152. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
  153. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
  154. package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -94
  155. package/src/organization-model/__tests__/recursive-system-schema.test.ts +549 -0
  156. package/src/organization-model/__tests__/resolve.test.ts +303 -42
  157. package/src/organization-model/__tests__/schema.test.ts +863 -153
  158. package/src/organization-model/__tests__/surface-projection.test.ts +284 -174
  159. package/src/organization-model/catalogs/lead-gen.ts +144 -0
  160. package/src/organization-model/content-kinds/config.ts +36 -0
  161. package/src/organization-model/content-kinds/index.ts +78 -0
  162. package/src/organization-model/content-kinds/pipeline.ts +68 -0
  163. package/src/organization-model/content-kinds/registry.ts +44 -0
  164. package/src/organization-model/content-kinds/status.ts +71 -0
  165. package/src/organization-model/content-kinds/template.ts +83 -0
  166. package/src/organization-model/content-kinds/types.ts +117 -0
  167. package/src/organization-model/contracts.ts +27 -17
  168. package/src/organization-model/defaults.ts +489 -107
  169. package/src/organization-model/domains/actions.ts +333 -0
  170. package/src/organization-model/domains/customers.ts +10 -7
  171. package/src/organization-model/domains/entities.ts +144 -0
  172. package/src/organization-model/domains/goals.ts +9 -6
  173. package/src/organization-model/domains/knowledge.ts +128 -54
  174. package/src/organization-model/domains/navigation.ts +139 -416
  175. package/src/organization-model/domains/offerings.ts +15 -10
  176. package/src/organization-model/domains/policies.ts +102 -0
  177. package/src/organization-model/domains/projects.ts +6 -40
  178. package/src/organization-model/domains/prospecting.ts +395 -514
  179. package/src/organization-model/domains/resources.ts +173 -81
  180. package/src/organization-model/domains/roles.ts +96 -93
  181. package/src/organization-model/domains/sales.test.ts +218 -218
  182. package/src/organization-model/domains/sales.ts +380 -589
  183. package/src/organization-model/domains/shared.ts +8 -8
  184. package/src/organization-model/domains/statuses.ts +298 -89
  185. package/src/organization-model/domains/systems.ts +240 -38
  186. package/src/organization-model/foundation.ts +35 -48
  187. package/src/organization-model/graph/build.ts +1035 -279
  188. package/src/organization-model/graph/index.ts +4 -4
  189. package/src/organization-model/graph/link.ts +10 -10
  190. package/src/organization-model/graph/schema.ts +77 -56
  191. package/src/organization-model/graph/types.ts +75 -56
  192. package/src/organization-model/helpers.ts +312 -59
  193. package/src/organization-model/icons.ts +78 -66
  194. package/src/organization-model/index.ts +129 -16
  195. package/src/organization-model/migration-helpers.ts +252 -0
  196. package/src/organization-model/ontology.ts +661 -0
  197. package/src/organization-model/organization-graph.mdx +110 -89
  198. package/src/organization-model/organization-model.mdx +226 -171
  199. package/src/organization-model/published.ts +295 -139
  200. package/src/organization-model/resolve.ts +139 -21
  201. package/src/organization-model/schema.ts +841 -301
  202. package/src/organization-model/surface-projection.ts +212 -218
  203. package/src/organization-model/types.ts +181 -90
  204. package/src/platform/api/types.ts +38 -38
  205. package/src/platform/constants/versions.ts +3 -3
  206. package/src/platform/index.ts +23 -23
  207. package/src/platform/registry/__tests__/command-view.test.ts +5 -7
  208. package/src/platform/registry/__tests__/resource-link.test.ts +35 -30
  209. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +17 -32
  210. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
  211. package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2051
  212. package/src/platform/registry/__tests__/validation.test.ts +1347 -1343
  213. package/src/platform/registry/command-view.ts +10 -10
  214. package/src/platform/registry/index.ts +103 -103
  215. package/src/platform/registry/resource-link.ts +32 -32
  216. package/src/platform/registry/resource-registry.ts +890 -878
  217. package/src/platform/registry/serialization.ts +295 -295
  218. package/src/platform/registry/serialized-types.ts +166 -166
  219. package/src/platform/registry/stats-types.ts +68 -68
  220. package/src/platform/registry/types.ts +425 -425
  221. package/src/platform/registry/validation.ts +745 -743
  222. package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
  223. package/src/platform/utils/validation.ts +425 -425
  224. package/src/projects/api-schemas.test.ts +39 -39
  225. package/src/projects/api-schemas.ts +291 -291
  226. package/src/reference/_generated/contracts.md +2389 -2121
  227. package/src/reference/glossary.md +76 -76
  228. package/src/scaffold-registry/__tests__/index.test.ts +206 -206
  229. package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
  230. package/src/scaffold-registry/index.ts +392 -392
  231. package/src/scaffold-registry/schema.ts +243 -243
  232. package/src/server.ts +289 -289
  233. package/src/supabase/database.types.ts +3153 -3093
  234. package/src/test-utils/README.md +37 -37
  235. package/src/test-utils/entities.ts +108 -108
  236. package/src/test-utils/fixtures/memberships.ts +82 -82
  237. package/src/test-utils/index.ts +12 -12
  238. package/src/test-utils/organization-model.ts +65 -65
  239. package/src/test-utils/published.ts +6 -6
  240. package/src/test-utils/rls/RLSTestContext.ts +588 -588
  241. package/src/test-utils/test-utils.test.ts +44 -49
  242. package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
  243. package/src/organization-model/domains/features.ts +0 -31
  244. package/src/organization-model/domains/operations.ts +0 -85
@@ -1,46 +1,248 @@
1
- import { z } from 'zod'
2
- import { DescriptionSchema, LabelSchema, ModelIdSchema, ReferenceIdsSchema } from './shared'
1
+ import { z, type ZodType } from 'zod'
2
+ import { ActionRefSchema } from './actions'
3
+ import {
4
+ ColorTokenSchema,
5
+ DescriptionSchema,
6
+ IconNameSchema,
7
+ LabelSchema,
8
+ ModelIdSchema,
9
+ PathSchema,
10
+ ReferenceIdsSchema
11
+ } from './shared'
12
+ import { ContentNodeSchema } from '../content-kinds/types'
13
+ import { OntologyScopeSchema, type OntologyScope } from '../ontology'
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Systems domain
17
+ // ---------------------------------------------------------------------------
18
+ //
19
+ // A System is a tenant-defined bounded context. It can carry UI presence,
20
+ // hierarchy, and governance metadata; non-UI systems simply omit `ui`.
21
+
22
+ export const SystemKindSchema = z
23
+ .enum(['product', 'operational', 'platform', 'diagnostic'])
24
+ .meta({ label: 'System kind', color: 'blue' })
25
+ export const SystemLifecycleSchema = z
26
+ .enum(['draft', 'beta', 'active', 'deprecated', 'archived'])
27
+ .meta({ label: 'Lifecycle', color: 'teal' })
28
+ /** @deprecated Use SystemLifecycleSchema. Accepted for one publish cycle. */
29
+ export const SystemStatusSchema = z.enum(['active', 'deprecated', 'archived']).meta({ label: 'Status', color: 'teal' })
30
+ export const SystemIdSchema = ModelIdSchema
31
+ /**
32
+ * Validates a dot-separated system path (e.g. "sales.lead-gen", "sales.crm").
33
+ * Each segment is lowercase, starts with a letter or digit, and may contain hyphens.
34
+ * This is the canonical form used in `resource.systemPath`.
35
+ */
36
+ export const SystemPathSchema = z
37
+ .string()
38
+ .trim()
39
+ .min(1)
40
+ .regex(
41
+ /^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
42
+ 'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
43
+ )
44
+ export const UiPositionSchema = z.enum(['sidebar-primary', 'sidebar-bottom']).meta({ label: 'UI position' })
45
+ export const NodeIdPathSchema = SystemIdSchema
46
+ export const NodeIdStringSchema = z
47
+ .string()
48
+ .trim()
49
+ .min(1)
50
+ .max(200)
51
+ // D4: kind prefix allows hyphens (e.g. 'content-node'); id allows colons for
52
+ // qualified content-node references ('content-node:sales.crm:default-pipeline').
53
+ .regex(
54
+ /^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
55
+ 'Node references must use kind:dotted-path (e.g. system:sales.crm or content-node:sales.crm:pipeline-id)'
56
+ )
57
+
58
+ export const SystemUiSchema = z.object({
59
+ path: PathSchema,
60
+ surfaces: ReferenceIdsSchema,
61
+ icon: IconNameSchema.optional(),
62
+ order: z.number().int().optional()
63
+ })
64
+
65
+ // ---------------------------------------------------------------------------
66
+ // Recursive SystemEntry schema.
67
+ //
68
+ // TypeScript cannot infer the type of a schema that references itself through
69
+ // z.lazy(). The standard Zod fix is to:
70
+ // 1. Declare the output type as an explicit interface BEFORE the schema.
71
+ // 2. Annotate the schema variable with `ZodType<SystemEntry>` so TS uses
72
+ // the declared interface instead of trying to infer through the cycle.
73
+ // ---------------------------------------------------------------------------
74
+
75
+ import type { ContentNode } from '../content-kinds/types'
3
76
 
4
- // ---------------------------------------------------------------------------
5
- // Systems domain
6
- // ---------------------------------------------------------------------------
7
- //
8
- // A System is a tenant-defined bounded context that groups operational
9
- // resources and carries governance metadata. The shared schema validates the
10
- // shape and references; each tenant supplies its own catalog.
77
+ export type JsonPrimitive = string | number | boolean | null
78
+ export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }
11
79
 
12
- export const SystemKindSchema = z.enum(['product', 'operational', 'platform', 'diagnostic'])
13
- export const SystemStatusSchema = z.enum(['active', 'deprecated', 'archived'])
14
- export const SystemIdSchema = ModelIdSchema
80
+ export const JsonValueSchema: ZodType<JsonValue> = z.lazy(() =>
81
+ z.union([
82
+ z.string(),
83
+ z.number(),
84
+ z.boolean(),
85
+ z.null(),
86
+ z.array(JsonValueSchema),
87
+ z.record(z.string(), JsonValueSchema)
88
+ ])
89
+ )
15
90
 
16
- export const SystemEntrySchema = z.object({
17
- /** Stable tenant-defined system id (e.g. "sys.lead-gen"). */
18
- id: SystemIdSchema,
19
- /** Human-readable system title shown in governance and operations UI. */
20
- title: LabelSchema,
21
- /** One-paragraph purpose statement for the bounded context. */
22
- description: DescriptionSchema,
23
- /** Closed system shape enum; catalog values remain tenant-defined. */
24
- kind: SystemKindSchema,
25
- /** Optional role responsible for this system. */
26
- responsibleRoleId: ModelIdSchema.optional(),
27
- /** Optional knowledge nodes that govern this system. */
28
- governedByKnowledge: ReferenceIdsSchema,
29
- /** Optional goals this system contributes to. */
30
- drivesGoals: ReferenceIdsSchema,
31
- status: SystemStatusSchema
32
- })
91
+ export const SystemConfigSchema = z
92
+ .record(z.string().trim().min(1).max(200), JsonValueSchema)
93
+ .default({})
94
+ .optional()
33
95
 
34
- export const SystemsDomainSchema = z.object({
35
- systems: z.array(SystemEntrySchema).default([])
36
- })
37
-
38
- export const DEFAULT_ORGANIZATION_MODEL_SYSTEMS: z.infer<typeof SystemsDomainSchema> = {
39
- systems: []
96
+ /** Explicit interface needed to annotate the recursive SystemEntrySchema. */
97
+ export interface SystemEntry {
98
+ id: string
99
+ label?: string
100
+ title?: string
101
+ description?: string
102
+ kind?: 'product' | 'operational' | 'platform' | 'diagnostic'
103
+ parentSystemId?: string
104
+ ui?: { path: string; surfaces: string[]; icon?: string; order?: number }
105
+ lifecycle?: 'draft' | 'beta' | 'active' | 'deprecated' | 'archived'
106
+ responsibleRoleId?: string
107
+ governedByKnowledge?: string[]
108
+ actions?: { actionId: string; intent: 'exposes' | 'consumes'; invocation?: unknown }[]
109
+ policies?: string[]
110
+ drivesGoals?: string[]
111
+ /** @deprecated Use lifecycle. Accepted for one publish cycle. */
112
+ status?: 'active' | 'deprecated' | 'archived'
113
+ path?: string
114
+ icon?: string
115
+ color?: string
116
+ uiPosition?: 'sidebar-primary' | 'sidebar-bottom'
117
+ enabled?: boolean
118
+ devOnly?: boolean
119
+ requiresAdmin?: boolean
120
+ order: number
121
+ config?: Record<string, JsonValue>
122
+ ontology?: OntologyScope
123
+ systems?: Record<string, SystemEntry>
124
+ /**
125
+ * @deprecated Compatibility-only bridge for old tenant data and migration readers.
126
+ * Author new semantic catalogs in `ontology` and local settings in `config`.
127
+ */
128
+ content?: Record<string, ContentNode>
129
+ subsystems?: Record<string, SystemEntry>
40
130
  }
131
+
132
+ export const SystemEntrySchema: ZodType<SystemEntry> = z
133
+ .object({
134
+ /** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
135
+ id: SystemIdSchema,
136
+ /** Human-readable system label shown in UI, governance, and operations surfaces. */
137
+ label: LabelSchema.optional(),
138
+ /** @deprecated Use label. Accepted for pre-consolidation System declarations. */
139
+ title: LabelSchema.optional(),
140
+ /** One-paragraph purpose statement for the bounded context. */
141
+ description: DescriptionSchema.optional(),
142
+ /** Closed system shape enum; catalog values remain tenant-defined. */
143
+ kind: SystemKindSchema.optional(),
144
+ /** Optional self-reference for System hierarchy. */
145
+ parentSystemId: SystemIdSchema.optional(),
146
+ /** Optional UI presence. Systems without UI omit this. */
147
+ ui: SystemUiSchema.optional(),
148
+ /** Canonical lifecycle state. Replaces Feature.enabled/devOnly and System.status. */
149
+ lifecycle: SystemLifecycleSchema.optional(),
150
+ /** Optional role responsible for this system. */
151
+ responsibleRoleId: ModelIdSchema.meta({ ref: 'role' }).optional(),
152
+ /** Optional knowledge nodes that govern this system. */
153
+ governedByKnowledge: z
154
+ .array(ModelIdSchema.meta({ ref: 'knowledge' }))
155
+ .default([])
156
+ .optional(),
157
+ /** Optional actions this system exposes or consumes. */
158
+ actions: z.array(ActionRefSchema).optional(),
159
+ /** Optional operational policies that apply to this system. */
160
+ policies: z
161
+ .array(ModelIdSchema.meta({ ref: 'policy' }))
162
+ .default([])
163
+ .optional(),
164
+ /** Optional goals this system contributes to. */
165
+ drivesGoals: z
166
+ .array(ModelIdSchema.meta({ ref: 'goal' }))
167
+ .default([])
168
+ .optional(),
169
+ /** @deprecated Use lifecycle. Accepted for one publish cycle. */
170
+ status: SystemStatusSchema.optional(),
171
+ /** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
172
+ path: PathSchema.optional(),
173
+ /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
174
+ icon: IconNameSchema.optional(),
175
+ /** @deprecated Feature color token, retained for one-cycle compatibility. */
176
+ color: ColorTokenSchema.optional(),
177
+ /** @deprecated UI placement hint, retained for one-cycle compatibility. */
178
+ uiPosition: UiPositionSchema.optional(),
179
+ /** @deprecated Use lifecycle. */
180
+ enabled: z.boolean().optional(),
181
+ /** @deprecated Use lifecycle: "beta". */
182
+ devOnly: z.boolean().optional(),
183
+ requiresAdmin: z.boolean().optional(),
184
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
185
+ order: z.number(),
186
+ /**
187
+ * System-local JSON settings and defaults. Strongly typed OM fields,
188
+ * secrets, credentials, and runtime state stay outside this bucket.
189
+ */
190
+ config: SystemConfigSchema,
191
+ /**
192
+ * System-owned ontology declarations. `systems` is now the canonical child
193
+ * key; this scope holds the object, action, catalog, link, event, and
194
+ * shared contract records owned by this system.
195
+ */
196
+ ontology: OntologyScopeSchema.optional(),
197
+ /**
198
+ * @deprecated Compatibility-only bridge for old tenant content nodes and
199
+ * migration readers. New schema/catalog authoring belongs in ontology;
200
+ * new system-local settings belong in config. Bridge nodes are keyed by
201
+ * local NodeId and may still project to content-node:* graph IDs.
202
+ */
203
+ content: z.record(z.string().trim().min(1).max(200), ContentNodeSchema).optional(),
204
+ /**
205
+ * Recursive child systems, authored via nesting (per L11).
206
+ * The key is the local system id; the full path is computed by joining
207
+ * ancestor keys with `.` (e.g. parent key `'sales'` + child key `'crm'` → `'sales.crm'`).
208
+ * Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
209
+ * position-derived paths. Both still exist on this schema for backward compat.
210
+ */
211
+ systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
212
+ /** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
213
+ subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
214
+ })
215
+ .refine((system: SystemEntry) => system.label !== undefined || system.title !== undefined, {
216
+ path: ['label'],
217
+ message: 'System must provide label or title'
218
+ })
219
+ .transform((system: SystemEntry) => {
220
+ const normalizedSystem =
221
+ system.systems !== undefined && system.subsystems === undefined ? { ...system, subsystems: system.systems } : system
222
+
223
+ if (normalizedSystem.status === undefined) return normalizedSystem
41
224
 
42
- export type SystemId = z.infer<typeof SystemIdSchema>
225
+ console.warn('[organization-model] System.status is deprecated; use System.lifecycle instead.')
226
+ return normalizedSystem.lifecycle === undefined
227
+ ? { ...normalizedSystem, lifecycle: normalizedSystem.status }
228
+ : normalizedSystem
229
+ })
230
+
231
+ export const SystemsDomainSchema = z
232
+ .record(z.string(), SystemEntrySchema)
233
+ .refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
234
+ message: 'Each system entry id must match its map key'
235
+ })
236
+ .default({})
237
+
238
+ export const DEFAULT_ORGANIZATION_MODEL_SYSTEMS: z.infer<typeof SystemsDomainSchema> = {}
239
+
240
+ export type SystemId = z.infer<typeof SystemIdSchema>
43
241
  export type SystemKind = z.infer<typeof SystemKindSchema>
242
+ export type SystemLifecycle = z.infer<typeof SystemLifecycleSchema>
243
+ /** @deprecated Use SystemLifecycle. Accepted for one publish cycle. */
44
244
  export type SystemStatus = z.infer<typeof SystemStatusSchema>
45
- export type SystemEntry = z.infer<typeof SystemEntrySchema>
46
- export type SystemsDomain = z.infer<typeof SystemsDomainSchema>
245
+ export type SystemLocalConfig = z.infer<typeof SystemConfigSchema>
246
+ // SystemEntry is declared as an explicit interface above the schema (required for
247
+ // recursive z.lazy() type inference). Re-export omitted — the interface IS the type.
248
+ export type SystemsDomain = z.infer<typeof SystemsDomainSchema>
@@ -1,23 +1,29 @@
1
- import { resolveOrganizationModel } from './resolve'
2
- import type { OrganizationModelBuiltinIconToken } from './icons'
3
- import type { DeepPartial, OrganizationModel, OrganizationModelFeature } from './types'
4
-
5
- export type FoundationSurfaceType = 'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'
6
-
7
- export type FoundationSurfaceIcon = Extract<
8
- OrganizationModelBuiltinIconToken,
9
- 'feature.dashboard' | 'feature.crm' | 'feature.lead-gen' | 'feature.projects' | 'feature.operations' | 'feature.settings'
10
- >
11
-
12
- export interface FoundationNavigationSurface extends Omit<OrganizationModelFeature, 'icon' | 'uiPosition'> {
13
- icon?: FoundationSurfaceIcon
14
- surfaceType?: FoundationSurfaceType
15
- }
16
-
17
- export interface FoundationOrganizationModel extends Omit<OrganizationModel, 'navigation'> {
18
- navigation: {
19
- defaultSurfaceId: string
20
- homeLabel: string
1
+ import { resolveOrganizationModel } from './resolve'
2
+ import type { OrganizationModelBuiltinIconToken } from './icons'
3
+ import { projectOrganizationSurfaces, type OrganizationSurfaceProjection } from './surface-projection'
4
+ import type { DeepPartial, OrganizationModel } from './types'
5
+
6
+ export type FoundationSurfaceType = 'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'
7
+
8
+ export type FoundationSurfaceIcon = Extract<
9
+ OrganizationModelBuiltinIconToken,
10
+ | 'feature.dashboard'
11
+ | 'feature.crm'
12
+ | 'feature.lead-gen'
13
+ | 'feature.projects'
14
+ | 'feature.operations'
15
+ | 'feature.settings'
16
+ >
17
+
18
+ export type FoundationNavigationSurface = Omit<OrganizationSurfaceProjection, 'icon' | 'surfaceType'> & {
19
+ icon?: FoundationSurfaceIcon | OrganizationModelBuiltinIconToken | string
20
+ surfaceType: FoundationSurfaceType
21
+ }
22
+
23
+ export interface FoundationOrganizationModel extends Omit<OrganizationModel, 'navigation'> {
24
+ navigation: {
25
+ defaultSurfaceId: string
26
+ homeLabel: string
21
27
  quickAccessSurfaceIds: readonly string[]
22
28
  surfaces: FoundationNavigationSurface[]
23
29
  }
@@ -36,38 +42,19 @@ export function createFoundationOrganizationModel(override: DeepPartial<Organiza
36
42
  quickAccessSurfaceIds: readonly string[]
37
43
  getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
38
44
  } {
39
- const canonical = resolveOrganizationModel(override)
40
-
41
- function requireCoreFeature(featureId: string): OrganizationModelFeature {
42
- const feature = canonical.features.find((candidate) => candidate.id === featureId)
43
-
44
- if (!feature) {
45
- throw new Error(`Missing organization surface/feature: ${featureId}`)
46
- }
47
-
48
- return feature
49
- }
50
-
51
- const operationsFeature = requireCoreFeature('operations')
52
- const projectsFeature = requireCoreFeature('projects')
53
- const leadGenFeature = requireCoreFeature('sales.lead-gen')
54
- const crmFeature = requireCoreFeature('sales.crm')
55
-
56
- const navigationSurfaces: FoundationNavigationSurface[] = [
57
- { ...operationsFeature, id: 'operations', path: '/operations', icon: 'feature.operations', surfaceType: 'dashboard' },
58
- { ...projectsFeature, icon: 'feature.projects', surfaceType: 'list' },
59
- { ...leadGenFeature, id: 'lead-gen', icon: 'feature.lead-gen', surfaceType: 'list' },
60
- { ...crmFeature, id: 'crm', icon: 'feature.crm', surfaceType: 'graph' },
61
- { ...requireCoreFeature('settings.account'), id: 'settings', icon: 'feature.settings', surfaceType: 'settings' }
62
- ]
63
-
64
- const homeLabel = 'Dashboard'
65
- const quickAccessSurfaceIds = ['operations', 'projects', 'lead-gen', 'crm'] as const
45
+ const canonical = resolveOrganizationModel(override)
46
+ const navigationSurfaces: FoundationNavigationSurface[] = projectOrganizationSurfaces(canonical)
47
+ const defaultSurface = navigationSurfaces.find((surface) => surface.path === '/') ?? navigationSurfaces[0]
48
+ const homeLabel = defaultSurface?.label ?? 'Dashboard'
49
+ const quickAccessSurfaceIds = navigationSurfaces
50
+ .filter((surface) => surface.id !== defaultSurface?.id && surface.surfaceType !== 'settings')
51
+ .slice(0, 4)
52
+ .map((surface) => surface.id)
66
53
 
67
54
  const model: FoundationOrganizationModel = {
68
55
  ...canonical,
69
56
  navigation: {
70
- defaultSurfaceId: 'operations',
57
+ defaultSurfaceId: defaultSurface?.id ?? '',
71
58
  homeLabel,
72
59
  quickAccessSurfaceIds: [...quickAccessSurfaceIds],
73
60
  surfaces: navigationSurfaces