@elevasis/core 0.2.1 → 0.4.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 (45) hide show
  1. package/dist/index.d.ts +63 -103
  2. package/dist/index.js +431 -111
  3. package/dist/organization-model/index.d.ts +63 -103
  4. package/dist/organization-model/index.js +431 -111
  5. package/package.json +1 -1
  6. package/src/README.md +1 -1
  7. package/src/__tests__/template-foundations-compatibility.test.ts +28 -36
  8. package/src/auth/multi-tenancy/types.ts +4 -11
  9. package/src/auth/multi-tenancy/users/api-schemas.ts +1 -1
  10. package/src/business/base-entities.test.ts +481 -0
  11. package/src/business/base-entities.ts +241 -0
  12. package/src/business/delivery/types.ts +1 -1
  13. package/src/business/index.ts +3 -0
  14. package/src/execution/index.ts +3 -6
  15. package/src/index.ts +1 -1
  16. package/src/organization-model/README.md +25 -26
  17. package/src/organization-model/__tests__/graph.test.ts +103 -71
  18. package/src/organization-model/__tests__/resolve.test.ts +22 -31
  19. package/src/organization-model/contracts.ts +3 -0
  20. package/src/organization-model/defaults.ts +59 -7
  21. package/src/organization-model/domains/features.ts +19 -54
  22. package/src/organization-model/domains/navigation.ts +266 -17
  23. package/src/organization-model/domains/shared.ts +1 -10
  24. package/src/organization-model/foundation.ts +97 -0
  25. package/src/organization-model/graph/build.ts +34 -67
  26. package/src/organization-model/graph/schema.ts +2 -4
  27. package/src/organization-model/graph/types.ts +3 -15
  28. package/src/organization-model/index.ts +2 -0
  29. package/src/organization-model/organization-graph.mdx +37 -28
  30. package/src/organization-model/organization-model.mdx +34 -36
  31. package/src/organization-model/published.ts +12 -3
  32. package/src/organization-model/schema.ts +38 -34
  33. package/src/organization-model/types.ts +5 -10
  34. package/src/platform/constants/versions.ts +1 -1
  35. package/src/platform/sse/events.ts +1 -34
  36. package/src/projects/api-schemas.ts +2 -1
  37. package/src/reference/_generated/contracts.md +10 -31
  38. package/src/reference/glossary.md +14 -18
  39. package/src/supabase/database.types.ts +0 -107
  40. package/src/test-utils/rls/RLSTestContext.ts +1 -31
  41. package/src/execution/calibration/__tests__/schemas.test.ts +0 -320
  42. package/src/execution/calibration/index.ts +0 -3
  43. package/src/execution/calibration/schemas.ts +0 -121
  44. package/src/execution/calibration/sse-events.ts +0 -125
  45. package/src/execution/calibration/types.ts +0 -190
@@ -1,18 +1,19 @@
1
1
  import type { OrganizationModel } from './types'
2
+ import { DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from './contracts'
2
3
  import { DEFAULT_ORGANIZATION_MODEL_BRANDING } from './domains/branding'
3
4
  import { DEFAULT_ORGANIZATION_MODEL_CRM } from './domains/crm'
4
5
  import { DEFAULT_ORGANIZATION_MODEL_DELIVERY } from './domains/delivery'
5
- import { DEFAULT_ORGANIZATION_MODEL_FEATURES } from './domains/features'
6
6
  import { DEFAULT_ORGANIZATION_MODEL_LEAD_GEN } from './domains/lead-gen'
7
7
  import { DEFAULT_ORGANIZATION_MODEL_NAVIGATION } from './domains/navigation'
8
8
 
9
9
  export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
10
10
  version: 1,
11
- domains: [
11
+ features: [
12
12
  {
13
13
  id: 'crm',
14
14
  label: 'CRM',
15
15
  description: 'Relationship pipeline and deal management',
16
+ enabled: true,
16
17
  color: 'blue',
17
18
  entityIds: ['crm.deal'],
18
19
  surfaceIds: ['crm.pipeline'],
@@ -23,6 +24,7 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
23
24
  id: 'lead-gen',
24
25
  label: 'Lead Gen',
25
26
  description: 'Prospecting, qualification, and outreach preparation',
27
+ enabled: true,
26
28
  color: 'cyan',
27
29
  entityIds: ['leadgen.list', 'leadgen.company', 'leadgen.contact'],
28
30
  surfaceIds: ['lead-gen.lists'],
@@ -30,28 +32,78 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
30
32
  capabilityIds: ['leadgen.lists.manage']
31
33
  },
32
34
  {
33
- id: 'delivery',
35
+ id: PROJECTS_FEATURE_ID,
34
36
  label: 'Projects',
35
37
  description: 'Projects, milestones, and client work execution',
38
+ enabled: true,
36
39
  color: 'orange',
37
40
  entityIds: ['delivery.project', 'delivery.milestone', 'delivery.task'],
38
- surfaceIds: ['projects.index'],
41
+ surfaceIds: [PROJECTS_INDEX_SURFACE_ID],
39
42
  resourceIds: [],
40
- capabilityIds: ['delivery.projects.view']
43
+ capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
41
44
  },
42
45
  {
43
46
  id: 'operations',
44
47
  label: 'Operations',
45
48
  description: 'Operational resources, topology, and orchestration visibility',
49
+ enabled: true,
46
50
  color: 'violet',
47
51
  entityIds: [],
48
- surfaceIds: ['operations.organization-graph', 'operations.command-view'],
52
+ surfaceIds: [
53
+ 'operations.organization-graph',
54
+ 'operations.command-view',
55
+ 'operations.overview',
56
+ 'operations.resources',
57
+ 'operations.command-queue',
58
+ 'operations.sessions',
59
+ 'operations.task-scheduler'
60
+ ],
49
61
  resourceIds: [],
50
62
  capabilityIds: ['operations.organization-graph', 'operations.command-view']
63
+ },
64
+ {
65
+ id: 'monitoring',
66
+ label: 'Monitoring',
67
+ enabled: true,
68
+ entityIds: [],
69
+ surfaceIds: [
70
+ 'monitoring.activity-log',
71
+ 'monitoring.execution-logs',
72
+ 'monitoring.execution-health',
73
+ 'monitoring.cost-analytics',
74
+ 'monitoring.notifications'
75
+ ],
76
+ resourceIds: [],
77
+ capabilityIds: []
78
+ },
79
+ {
80
+ id: 'settings',
81
+ label: 'Settings',
82
+ enabled: true,
83
+ entityIds: [],
84
+ surfaceIds: [
85
+ 'settings.account',
86
+ 'settings.appearance',
87
+ 'settings.organization',
88
+ 'settings.credentials',
89
+ 'settings.api-keys',
90
+ 'settings.webhooks',
91
+ 'settings.deployments'
92
+ ],
93
+ resourceIds: [],
94
+ capabilityIds: []
95
+ },
96
+ {
97
+ id: 'seo',
98
+ label: 'SEO',
99
+ enabled: false,
100
+ entityIds: [],
101
+ surfaceIds: [],
102
+ resourceIds: [],
103
+ capabilityIds: []
51
104
  }
52
105
  ],
53
106
  branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
54
- features: DEFAULT_ORGANIZATION_MODEL_FEATURES,
55
107
  navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
56
108
  crm: DEFAULT_ORGANIZATION_MODEL_CRM,
57
109
  leadGen: DEFAULT_ORGANIZATION_MODEL_LEAD_GEN,
@@ -1,57 +1,22 @@
1
1
  import { z } from 'zod'
2
+ import {
3
+ ColorTokenSchema,
4
+ DescriptionSchema,
5
+ IconNameSchema,
6
+ LabelSchema,
7
+ ModelIdSchema,
8
+ ReferenceIdsSchema
9
+ } from './shared'
2
10
 
3
- export const FeatureKeySchema = z.enum([
4
- 'acquisition',
5
- 'delivery',
6
- 'operations',
7
- 'monitoring',
8
- 'settings',
9
- 'seo',
10
- 'calibration'
11
- ])
12
-
13
- export const OrganizationModelFeaturesSchema = z.object({
14
- enabled: z
15
- .object({
16
- acquisition: z.boolean().default(true),
17
- delivery: z.boolean().default(true),
18
- operations: z.boolean().default(true),
19
- monitoring: z.boolean().default(true),
20
- settings: z.boolean().default(true),
21
- seo: z.boolean().default(false),
22
- calibration: z.boolean().default(false)
23
- })
24
- .default({
25
- acquisition: true,
26
- delivery: true,
27
- operations: true,
28
- monitoring: true,
29
- settings: true,
30
- seo: false,
31
- calibration: false
32
- }),
33
- labels: z
34
- .object({
35
- acquisition: z.string().trim().min(1).max(80).optional(),
36
- delivery: z.string().trim().min(1).max(80).optional(),
37
- operations: z.string().trim().min(1).max(80).optional(),
38
- monitoring: z.string().trim().min(1).max(80).optional(),
39
- settings: z.string().trim().min(1).max(80).optional(),
40
- seo: z.string().trim().min(1).max(80).optional(),
41
- calibration: z.string().trim().min(1).max(80).optional()
42
- })
43
- .default({})
11
+ export const FeatureSchema = z.object({
12
+ id: ModelIdSchema,
13
+ label: LabelSchema,
14
+ description: DescriptionSchema.optional(),
15
+ enabled: z.boolean().default(true),
16
+ color: ColorTokenSchema.optional(),
17
+ icon: IconNameSchema.optional(),
18
+ entityIds: ReferenceIdsSchema,
19
+ surfaceIds: ReferenceIdsSchema,
20
+ resourceIds: ReferenceIdsSchema,
21
+ capabilityIds: ReferenceIdsSchema
44
22
  })
45
-
46
- export const DEFAULT_ORGANIZATION_MODEL_FEATURES: z.infer<typeof OrganizationModelFeaturesSchema> = {
47
- enabled: {
48
- acquisition: true,
49
- delivery: true,
50
- operations: true,
51
- monitoring: true,
52
- settings: true,
53
- seo: false,
54
- calibration: false
55
- },
56
- labels: {}
57
- }
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod'
2
- import { FeatureKeySchema } from './features'
2
+ import { DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from '../contracts'
3
3
  import { DescriptionSchema, IconNameSchema, LabelSchema, ModelIdSchema, PathSchema, ReferenceIdsSchema } from './shared'
4
4
 
5
5
  export const SurfaceTypeSchema = z.enum(['page', 'dashboard', 'graph', 'detail', 'list', 'settings'])
@@ -10,9 +10,10 @@ export const SurfaceDefinitionSchema = z.object({
10
10
  path: PathSchema,
11
11
  surfaceType: SurfaceTypeSchema,
12
12
  description: DescriptionSchema.optional(),
13
+ enabled: z.boolean().default(true),
13
14
  icon: IconNameSchema.optional(),
14
- featureKey: FeatureKeySchema.optional(),
15
- domainIds: ReferenceIdsSchema,
15
+ featureId: ModelIdSchema.optional(),
16
+ featureIds: ReferenceIdsSchema,
16
17
  entityIds: ReferenceIdsSchema,
17
18
  resourceIds: ReferenceIdsSchema,
18
19
  capabilityIds: ReferenceIdsSchema,
@@ -40,8 +41,9 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
40
41
  label: 'Pipeline',
41
42
  path: '/crm/pipeline',
42
43
  surfaceType: 'graph',
43
- featureKey: 'acquisition',
44
- domainIds: ['crm'],
44
+ enabled: true,
45
+ featureId: 'crm',
46
+ featureIds: ['crm'],
45
47
  entityIds: ['crm.deal'],
46
48
  resourceIds: [],
47
49
  capabilityIds: ['crm.pipeline.manage']
@@ -51,30 +53,33 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
51
53
  label: 'Lists',
52
54
  path: '/lead-gen/lists',
53
55
  surfaceType: 'list',
54
- featureKey: 'acquisition',
55
- domainIds: ['lead-gen'],
56
+ enabled: true,
57
+ featureId: 'lead-gen',
58
+ featureIds: ['lead-gen'],
56
59
  entityIds: ['leadgen.list'],
57
60
  resourceIds: [],
58
61
  capabilityIds: ['leadgen.lists.manage']
59
62
  },
60
63
  {
61
- id: 'projects.index',
64
+ id: PROJECTS_INDEX_SURFACE_ID,
62
65
  label: 'Projects',
63
66
  path: '/projects',
64
67
  surfaceType: 'list',
65
- featureKey: 'delivery',
66
- domainIds: ['delivery'],
68
+ enabled: true,
69
+ featureId: PROJECTS_FEATURE_ID,
70
+ featureIds: [PROJECTS_FEATURE_ID],
67
71
  entityIds: ['delivery.project'],
68
72
  resourceIds: [],
69
- capabilityIds: ['delivery.projects.view']
73
+ capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
70
74
  },
71
75
  {
72
76
  id: 'operations.organization-graph',
73
77
  label: 'Organization Graph',
74
78
  path: '/operations/organization-graph',
75
79
  surfaceType: 'graph',
76
- featureKey: 'operations',
77
- domainIds: ['operations'],
80
+ enabled: true,
81
+ featureId: 'operations',
82
+ featureIds: ['operations'],
78
83
  entityIds: [],
79
84
  resourceIds: [],
80
85
  capabilityIds: ['operations.organization-graph']
@@ -84,20 +89,264 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
84
89
  label: 'Command View',
85
90
  path: '/operations/command-view',
86
91
  surfaceType: 'graph',
87
- featureKey: 'operations',
88
- domainIds: ['operations'],
92
+ enabled: false,
93
+ featureId: 'operations',
94
+ featureIds: ['operations'],
89
95
  entityIds: [],
90
96
  resourceIds: [],
91
97
  capabilityIds: ['operations.command-view']
98
+ },
99
+ {
100
+ id: 'operations.overview',
101
+ label: 'Overview',
102
+ path: '/operations',
103
+ surfaceType: 'dashboard',
104
+ enabled: true,
105
+ featureId: 'operations',
106
+ featureIds: ['operations'],
107
+ entityIds: [],
108
+ resourceIds: [],
109
+ capabilityIds: []
110
+ },
111
+ {
112
+ id: 'operations.resources',
113
+ label: 'Resources',
114
+ path: '/operations/resources',
115
+ surfaceType: 'list',
116
+ enabled: true,
117
+ featureId: 'operations',
118
+ featureIds: ['operations'],
119
+ entityIds: [],
120
+ resourceIds: [],
121
+ capabilityIds: []
122
+ },
123
+ {
124
+ id: 'operations.command-queue',
125
+ label: 'Command Queue',
126
+ path: '/operations/command-queue',
127
+ surfaceType: 'list',
128
+ enabled: true,
129
+ featureId: 'operations',
130
+ featureIds: ['operations'],
131
+ entityIds: [],
132
+ resourceIds: [],
133
+ capabilityIds: []
134
+ },
135
+ {
136
+ id: 'operations.sessions',
137
+ label: 'Sessions',
138
+ path: '/operations/sessions',
139
+ surfaceType: 'page',
140
+ enabled: false,
141
+ featureId: 'operations',
142
+ featureIds: ['operations'],
143
+ entityIds: [],
144
+ resourceIds: [],
145
+ capabilityIds: []
146
+ },
147
+ {
148
+ id: 'operations.task-scheduler',
149
+ label: 'Task Scheduler',
150
+ path: '/operations/task-scheduler',
151
+ surfaceType: 'page',
152
+ enabled: true,
153
+ featureId: 'operations',
154
+ featureIds: ['operations'],
155
+ entityIds: [],
156
+ resourceIds: [],
157
+ capabilityIds: []
158
+ },
159
+ {
160
+ id: 'monitoring.activity-log',
161
+ label: 'Activity Log',
162
+ path: '/monitoring/activity-log',
163
+ surfaceType: 'list',
164
+ enabled: true,
165
+ featureId: 'monitoring',
166
+ featureIds: ['monitoring'],
167
+ entityIds: [],
168
+ resourceIds: [],
169
+ capabilityIds: []
170
+ },
171
+ {
172
+ id: 'monitoring.execution-logs',
173
+ label: 'Execution Logs',
174
+ path: '/monitoring/execution-logs',
175
+ surfaceType: 'list',
176
+ enabled: true,
177
+ featureId: 'monitoring',
178
+ featureIds: ['monitoring'],
179
+ entityIds: [],
180
+ resourceIds: [],
181
+ capabilityIds: []
182
+ },
183
+ {
184
+ id: 'monitoring.execution-health',
185
+ label: 'Execution Health',
186
+ path: '/monitoring/execution-health',
187
+ surfaceType: 'dashboard',
188
+ enabled: true,
189
+ featureId: 'monitoring',
190
+ featureIds: ['monitoring'],
191
+ entityIds: [],
192
+ resourceIds: [],
193
+ capabilityIds: []
194
+ },
195
+ {
196
+ id: 'monitoring.cost-analytics',
197
+ label: 'Cost Analytics',
198
+ path: '/monitoring/cost-analytics',
199
+ surfaceType: 'dashboard',
200
+ enabled: false,
201
+ featureId: 'monitoring',
202
+ featureIds: ['monitoring'],
203
+ entityIds: [],
204
+ resourceIds: [],
205
+ capabilityIds: []
206
+ },
207
+ {
208
+ id: 'monitoring.notifications',
209
+ label: 'Notifications',
210
+ path: '/monitoring/notifications',
211
+ surfaceType: 'page',
212
+ enabled: true,
213
+ featureId: 'monitoring',
214
+ featureIds: ['monitoring'],
215
+ entityIds: [],
216
+ resourceIds: [],
217
+ capabilityIds: []
218
+ },
219
+ {
220
+ id: 'settings.account',
221
+ label: 'Account',
222
+ path: '/settings/account',
223
+ surfaceType: 'settings',
224
+ enabled: true,
225
+ featureId: 'settings',
226
+ featureIds: ['settings'],
227
+ entityIds: [],
228
+ resourceIds: [],
229
+ capabilityIds: []
230
+ },
231
+ {
232
+ id: 'settings.appearance',
233
+ label: 'Appearance',
234
+ path: '/settings/appearance',
235
+ surfaceType: 'settings',
236
+ enabled: true,
237
+ featureId: 'settings',
238
+ featureIds: ['settings'],
239
+ entityIds: [],
240
+ resourceIds: [],
241
+ capabilityIds: []
242
+ },
243
+ {
244
+ id: 'settings.organization',
245
+ label: 'Organization',
246
+ path: '/settings/organization',
247
+ surfaceType: 'settings',
248
+ enabled: true,
249
+ featureId: 'settings',
250
+ featureIds: ['settings'],
251
+ entityIds: [],
252
+ resourceIds: [],
253
+ capabilityIds: []
254
+ },
255
+ {
256
+ id: 'settings.credentials',
257
+ label: 'Credentials',
258
+ path: '/settings/credentials',
259
+ surfaceType: 'settings',
260
+ enabled: true,
261
+ featureId: 'settings',
262
+ featureIds: ['settings'],
263
+ entityIds: [],
264
+ resourceIds: [],
265
+ capabilityIds: []
266
+ },
267
+ {
268
+ id: 'settings.api-keys',
269
+ label: 'API Keys',
270
+ path: '/settings/api-keys',
271
+ surfaceType: 'settings',
272
+ enabled: true,
273
+ featureId: 'settings',
274
+ featureIds: ['settings'],
275
+ entityIds: [],
276
+ resourceIds: [],
277
+ capabilityIds: []
278
+ },
279
+ {
280
+ id: 'settings.webhooks',
281
+ label: 'Webhooks',
282
+ path: '/settings/webhooks',
283
+ surfaceType: 'settings',
284
+ enabled: true,
285
+ featureId: 'settings',
286
+ featureIds: ['settings'],
287
+ entityIds: [],
288
+ resourceIds: [],
289
+ capabilityIds: []
290
+ },
291
+ {
292
+ id: 'settings.deployments',
293
+ label: 'Deployments',
294
+ path: '/settings/deployments',
295
+ surfaceType: 'settings',
296
+ enabled: true,
297
+ featureId: 'settings',
298
+ featureIds: ['settings'],
299
+ entityIds: [],
300
+ resourceIds: [],
301
+ capabilityIds: []
92
302
  }
93
303
  ],
94
304
  groups: [
95
- { id: 'primary-workspace', label: 'Workspace', placement: 'primary', surfaceIds: ['crm.pipeline', 'lead-gen.lists', 'projects.index'] },
305
+ {
306
+ id: 'primary-workspace',
307
+ label: 'Workspace',
308
+ placement: 'primary',
309
+ surfaceIds: ['crm.pipeline', 'lead-gen.lists', PROJECTS_INDEX_SURFACE_ID]
310
+ },
96
311
  {
97
312
  id: 'primary-operations',
98
313
  label: 'Operations',
99
314
  placement: 'primary',
100
- surfaceIds: ['operations.organization-graph', 'operations.command-view']
315
+ surfaceIds: [
316
+ 'operations.organization-graph',
317
+ 'operations.command-view',
318
+ 'operations.overview',
319
+ 'operations.resources',
320
+ 'operations.command-queue',
321
+ 'operations.sessions',
322
+ 'operations.task-scheduler'
323
+ ]
324
+ },
325
+ {
326
+ id: 'primary-monitoring',
327
+ label: 'Monitoring',
328
+ placement: 'primary',
329
+ surfaceIds: [
330
+ 'monitoring.activity-log',
331
+ 'monitoring.execution-logs',
332
+ 'monitoring.execution-health',
333
+ 'monitoring.cost-analytics',
334
+ 'monitoring.notifications'
335
+ ]
336
+ },
337
+ {
338
+ id: 'primary-settings',
339
+ label: 'Settings',
340
+ placement: 'bottom',
341
+ surfaceIds: [
342
+ 'settings.account',
343
+ 'settings.appearance',
344
+ 'settings.organization',
345
+ 'settings.credentials',
346
+ 'settings.api-keys',
347
+ 'settings.webhooks',
348
+ 'settings.deployments'
349
+ ]
101
350
  }
102
351
  ]
103
352
  }
@@ -22,21 +22,12 @@ export const DisplayMetadataSchema = z.object({
22
22
  icon: IconNameSchema.optional()
23
23
  })
24
24
 
25
- export const SemanticDomainSchema = DisplayMetadataSchema.extend({
26
- id: ModelIdSchema,
27
- entityIds: ReferenceIdsSchema,
28
- surfaceIds: ReferenceIdsSchema,
29
- resourceIds: ReferenceIdsSchema,
30
- capabilityIds: ReferenceIdsSchema
31
- })
32
-
33
25
  export const ResourceMappingSchema = DisplayMetadataSchema.extend({
34
26
  id: ModelIdSchema,
35
27
  resourceId: z.string().trim().min(1).max(255),
36
28
  resourceType: z.enum(['workflow', 'agent', 'trigger', 'integration', 'external', 'human_checkpoint']),
37
- domainIds: ReferenceIdsSchema,
29
+ featureIds: ReferenceIdsSchema,
38
30
  entityIds: ReferenceIdsSchema,
39
31
  surfaceIds: ReferenceIdsSchema,
40
32
  capabilityIds: ReferenceIdsSchema
41
33
  })
42
-
@@ -0,0 +1,97 @@
1
+ import { PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from './contracts'
2
+ import { resolveOrganizationModel } from './resolve'
3
+ import type { OrganizationModel, OrganizationModelSurface } from './types'
4
+
5
+ export type FoundationSurfaceType = OrganizationModelSurface['surfaceType']
6
+
7
+ export type FoundationSurfaceIcon = 'dashboard' | 'crm' | 'lead-gen' | 'projects' | 'operations' | 'settings'
8
+
9
+ export interface FoundationNavigationSurface extends Omit<OrganizationModelSurface, 'icon'> {
10
+ icon?: FoundationSurfaceIcon
11
+ }
12
+
13
+ export interface FoundationOrganizationModel extends Omit<OrganizationModel, 'navigation'> {
14
+ navigation: {
15
+ defaultSurfaceId: string
16
+ homeLabel: string
17
+ quickAccessSurfaceIds: readonly string[]
18
+ surfaces: FoundationNavigationSurface[]
19
+ }
20
+ }
21
+
22
+ export interface FoundationBranding {
23
+ organizationName: string
24
+ productName: string
25
+ shortName: string
26
+ }
27
+
28
+ export function createFoundationOrganizationModel(branding: FoundationBranding): {
29
+ canonical: OrganizationModel
30
+ model: FoundationOrganizationModel
31
+ homeLabel: string
32
+ quickAccessSurfaceIds: readonly string[]
33
+ getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
34
+ } {
35
+ const canonical = resolveOrganizationModel({ branding })
36
+
37
+ function requireCoreSurface(surfaceId: string): OrganizationModelSurface {
38
+ const surface = canonical.navigation.surfaces.find((candidate) => candidate.id === surfaceId)
39
+
40
+ if (!surface) {
41
+ throw new Error(`Missing organization surface: ${surfaceId}`)
42
+ }
43
+
44
+ return surface
45
+ }
46
+
47
+ const operationsGraphSurface = requireCoreSurface('operations.organization-graph')
48
+ const projectsSurface = requireCoreSurface(PROJECTS_INDEX_SURFACE_ID)
49
+ const leadGenSurface = requireCoreSurface('lead-gen.lists')
50
+ const crmSurface = requireCoreSurface('crm.pipeline')
51
+
52
+ const navigationSurfaces: FoundationNavigationSurface[] = [
53
+ { ...operationsGraphSurface, id: 'operations', path: '/operations', icon: 'operations' },
54
+ { ...operationsGraphSurface, path: '/operations', icon: 'operations' },
55
+ { ...projectsSurface, id: PROJECTS_FEATURE_ID, icon: 'projects' },
56
+ { ...leadGenSurface, id: 'lead-gen', icon: 'lead-gen' },
57
+ { ...crmSurface, id: 'crm', icon: 'crm' },
58
+ {
59
+ id: 'settings',
60
+ label: 'Settings',
61
+ path: '/settings/account',
62
+ surfaceType: 'settings',
63
+ enabled: true,
64
+ icon: 'settings',
65
+ featureId: 'settings',
66
+ featureIds: ['settings'],
67
+ entityIds: [],
68
+ resourceIds: [],
69
+ capabilityIds: []
70
+ }
71
+ ]
72
+
73
+ const homeLabel = 'Dashboard'
74
+ const quickAccessSurfaceIds = ['operations', PROJECTS_FEATURE_ID, 'lead-gen', 'crm'] as const
75
+
76
+ const model: FoundationOrganizationModel = {
77
+ ...canonical,
78
+ navigation: {
79
+ defaultSurfaceId: 'operations',
80
+ homeLabel,
81
+ quickAccessSurfaceIds: [...quickAccessSurfaceIds],
82
+ surfaces: navigationSurfaces
83
+ }
84
+ }
85
+
86
+ function getOrganizationSurface(surfaceId: string): FoundationNavigationSurface | undefined {
87
+ return model.navigation.surfaces.find((candidate) => candidate.id === surfaceId)
88
+ }
89
+
90
+ return {
91
+ canonical,
92
+ model,
93
+ homeLabel,
94
+ quickAccessSurfaceIds,
95
+ getOrganizationSurface
96
+ }
97
+ }