@elevasis/core 0.10.0 → 0.11.1

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 (58) hide show
  1. package/dist/index.d.ts +69 -159
  2. package/dist/index.js +324 -613
  3. package/dist/organization-model/index.d.ts +69 -159
  4. package/dist/organization-model/index.js +324 -613
  5. package/dist/test-utils/index.d.ts +192 -45
  6. package/dist/test-utils/index.js +260 -600
  7. package/package.json +1 -1
  8. package/src/__tests__/template-core-compatibility.test.ts +73 -91
  9. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +94 -182
  10. package/src/auth/multi-tenancy/index.ts +20 -17
  11. package/src/auth/multi-tenancy/memberships/api-schemas.ts +142 -126
  12. package/src/auth/multi-tenancy/memberships/index.ts +26 -22
  13. package/src/auth/multi-tenancy/permissions.test.ts +42 -0
  14. package/src/auth/multi-tenancy/permissions.ts +104 -0
  15. package/src/organization-model/README.md +102 -97
  16. package/src/organization-model/__tests__/defaults.test.ts +19 -6
  17. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +24 -93
  18. package/src/organization-model/__tests__/graph.test.ts +82 -894
  19. package/src/organization-model/__tests__/resolve.test.ts +59 -690
  20. package/src/organization-model/__tests__/schema.test.ts +83 -407
  21. package/src/organization-model/contracts.ts +4 -3
  22. package/src/organization-model/defaults.ts +277 -141
  23. package/src/organization-model/domains/features.ts +31 -22
  24. package/src/organization-model/domains/navigation.ts +27 -20
  25. package/src/organization-model/foundation.ts +42 -54
  26. package/src/organization-model/graph/build.ts +42 -217
  27. package/src/organization-model/graph/index.ts +4 -4
  28. package/src/organization-model/graph/link.ts +10 -0
  29. package/src/organization-model/graph/schema.ts +21 -16
  30. package/src/organization-model/graph/types.ts +10 -10
  31. package/src/organization-model/helpers.ts +74 -0
  32. package/src/organization-model/index.ts +7 -7
  33. package/src/organization-model/organization-graph.mdx +89 -272
  34. package/src/organization-model/organization-model.mdx +152 -320
  35. package/src/organization-model/published.ts +20 -19
  36. package/src/organization-model/resolve.ts +8 -33
  37. package/src/organization-model/schema.ts +63 -205
  38. package/src/organization-model/types.ts +12 -11
  39. package/src/platform/constants/versions.ts +3 -3
  40. package/src/platform/registry/__tests__/command-view.test.ts +6 -5
  41. package/src/platform/registry/__tests__/resource-link.test.ts +30 -0
  42. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +15 -15
  43. package/src/platform/registry/command-view.ts +10 -12
  44. package/src/platform/registry/index.ts +93 -93
  45. package/src/platform/registry/resource-link.ts +32 -0
  46. package/src/platform/registry/resource-registry.ts +917 -876
  47. package/src/platform/registry/serialization.ts +56 -73
  48. package/src/platform/registry/serialized-types.ts +17 -12
  49. package/src/platform/registry/types.ts +14 -43
  50. package/src/reference/_generated/contracts.md +94 -182
  51. package/src/reference/glossary.md +71 -105
  52. package/src/scaffold-registry/__tests__/index.test.ts +125 -1
  53. package/src/scaffold-registry/__tests__/schema.test.ts +48 -20
  54. package/src/scaffold-registry/index.ts +236 -188
  55. package/src/scaffold-registry/schema.ts +47 -22
  56. package/src/supabase/database.types.ts +2880 -2719
  57. package/src/test-utils/fixtures/memberships.ts +82 -80
  58. package/src/platform/registry/domains.ts +0 -165
@@ -1,148 +1,284 @@
1
- import type { OrganizationModel } from './types'
2
- import {
3
- SALES_FEATURE_ID,
4
- SALES_PIPELINE_SURFACE_ID,
5
- PROJECTS_VIEW_CAPABILITY_ID,
6
- PROSPECTING_FEATURE_ID,
7
- PROSPECTING_LISTS_SURFACE_ID,
8
- MONITORING_FEATURE_ID,
9
- OPERATIONS_FEATURE_ID,
10
- OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID,
11
- PROJECTS_FEATURE_ID,
12
- PROJECTS_INDEX_SURFACE_ID,
13
- SETTINGS_FEATURE_ID,
14
- SEO_FEATURE_ID
15
- } from './contracts'
16
- import { DEFAULT_ORGANIZATION_MODEL_BRANDING } from './domains/branding'
17
- import { DEFAULT_ORGANIZATION_MODEL_IDENTITY } from './domains/identity'
18
- import { DEFAULT_ORGANIZATION_MODEL_CUSTOMERS } from './domains/customers'
1
+ import type { OrganizationModel } from './types'
2
+ import { DEFAULT_ORGANIZATION_MODEL_BRANDING } from './domains/branding'
3
+ import { DEFAULT_ORGANIZATION_MODEL_IDENTITY } from './domains/identity'
4
+ import { DEFAULT_ORGANIZATION_MODEL_CUSTOMERS } from './domains/customers'
19
5
  import { DEFAULT_ORGANIZATION_MODEL_OFFERINGS } from './domains/offerings'
20
- import { DEFAULT_ORGANIZATION_MODEL_SALES } from './domains/sales'
21
- import { DEFAULT_ORGANIZATION_MODEL_PROJECTS } from './domains/projects'
22
- import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from './domains/prospecting'
23
- import { DEFAULT_ORGANIZATION_MODEL_NAVIGATION } from './domains/navigation'
24
- import { DEFAULT_ORGANIZATION_MODEL_OPERATIONS } from './domains/operations'
25
- import { DEFAULT_ORGANIZATION_MODEL_ROLES } from './domains/roles'
26
- import { DEFAULT_ORGANIZATION_MODEL_GOALS } from './domains/goals'
6
+ import { DEFAULT_ORGANIZATION_MODEL_SALES } from './domains/sales'
7
+ import { DEFAULT_ORGANIZATION_MODEL_PROJECTS } from './domains/projects'
8
+ import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from './domains/prospecting'
9
+ import { DEFAULT_ORGANIZATION_MODEL_OPERATIONS } from './domains/operations'
10
+ import { DEFAULT_ORGANIZATION_MODEL_ROLES } from './domains/roles'
11
+ import { DEFAULT_ORGANIZATION_MODEL_GOALS } from './domains/goals'
27
12
  import { DEFAULT_ORGANIZATION_MODEL_STATUSES } from './domains/statuses'
28
13
 
29
14
  export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
30
- version: 1,
31
- features: [
32
- {
33
- id: SALES_FEATURE_ID,
34
- label: 'CRM',
35
- description: 'Relationship pipeline and deal management',
36
- enabled: true,
37
- color: 'blue',
38
- entityIds: ['crm.deal'],
39
- surfaceIds: [SALES_PIPELINE_SURFACE_ID],
40
- resourceIds: [],
41
- capabilityIds: ['crm.pipeline.manage']
42
- },
43
- {
44
- id: PROSPECTING_FEATURE_ID,
45
- label: 'Lead Gen',
46
- description: 'Prospecting, qualification, and outreach preparation',
47
- enabled: true,
48
- color: 'cyan',
49
- entityIds: ['leadgen.list', 'leadgen.company', 'leadgen.contact'],
50
- surfaceIds: [PROSPECTING_LISTS_SURFACE_ID],
51
- resourceIds: [],
52
- capabilityIds: ['leadgen.lists.manage']
53
- },
54
- {
55
- id: PROJECTS_FEATURE_ID,
56
- label: 'Projects',
57
- description: 'Projects, milestones, and client work execution',
58
- enabled: true,
59
- color: 'orange',
60
- entityIds: ['delivery.project', 'delivery.milestone', 'delivery.task'],
61
- surfaceIds: [PROJECTS_INDEX_SURFACE_ID],
62
- resourceIds: [],
63
- capabilityIds: [PROJECTS_VIEW_CAPABILITY_ID]
64
- },
65
- {
66
- id: OPERATIONS_FEATURE_ID,
67
- label: 'Operations',
68
- description: 'Operational resources, topology, and orchestration visibility',
69
- enabled: true,
70
- color: 'violet',
71
- entityIds: [],
72
- surfaceIds: [
73
- OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID,
74
- 'operations.command-view',
75
- 'operations.overview',
76
- 'operations.resources',
77
- 'operations.command-queue',
78
- 'operations.sessions',
79
- 'operations.task-scheduler'
80
- ],
81
- resourceIds: [],
82
- capabilityIds: ['operations.organization-graph', 'operations.command-view']
83
- },
84
- {
85
- id: MONITORING_FEATURE_ID,
86
- label: 'Monitoring',
87
- enabled: true,
88
- entityIds: [],
89
- surfaceIds: [
90
- 'monitoring.activity-log',
91
- 'monitoring.execution-logs',
92
- 'monitoring.execution-health',
93
- 'monitoring.cost-analytics',
94
- 'monitoring.notifications'
95
- ],
96
- resourceIds: [],
97
- capabilityIds: []
98
- },
99
- {
100
- id: SETTINGS_FEATURE_ID,
101
- label: 'Settings',
102
- enabled: true,
103
- entityIds: [],
104
- surfaceIds: [
105
- 'settings.account',
106
- 'settings.appearance',
107
- 'settings.organization',
108
- 'settings.credentials',
109
- 'settings.api-keys',
110
- 'settings.webhooks',
111
- 'settings.deployments'
112
- ],
113
- resourceIds: [],
114
- capabilityIds: []
115
- },
116
- {
117
- id: 'submitted-requests',
118
- label: 'Submitted Requests',
119
- enabled: true,
120
- entityIds: ['reported_request'],
121
- surfaceIds: ['submitted-requests.list', 'submitted-requests.detail'],
122
- resourceIds: [],
123
- capabilityIds: []
124
- },
125
- {
126
- id: SEO_FEATURE_ID,
127
- label: 'SEO',
128
- enabled: false,
129
- entityIds: [],
130
- surfaceIds: [],
131
- resourceIds: [],
132
- capabilityIds: []
133
- }
134
- ],
135
- branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
136
- navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
137
- sales: DEFAULT_ORGANIZATION_MODEL_SALES,
138
- prospecting: DEFAULT_ORGANIZATION_MODEL_PROSPECTING,
139
- projects: DEFAULT_ORGANIZATION_MODEL_PROJECTS,
15
+ version: 1,
16
+ features: [
17
+ {
18
+ id: 'dashboard',
19
+ label: 'Dashboard',
20
+ enabled: true,
21
+ path: '/',
22
+ icon: 'dashboard',
23
+ uiPosition: 'sidebar-primary'
24
+ },
25
+ {
26
+ id: 'sales',
27
+ label: 'Sales',
28
+ description: 'Revenue workflows and customer acquisition',
29
+ enabled: true,
30
+ color: 'blue',
31
+ icon: 'crm',
32
+ uiPosition: 'sidebar-primary'
33
+ },
34
+ {
35
+ id: 'sales.crm',
36
+ label: 'CRM',
37
+ description: 'Relationship pipeline and deal management',
38
+ enabled: true,
39
+ color: 'blue',
40
+ icon: 'crm',
41
+ path: '/crm'
42
+ },
43
+ {
44
+ id: 'sales.lead-gen',
45
+ label: 'Lead Gen',
46
+ description: 'Prospecting, qualification, and outreach preparation',
47
+ enabled: true,
48
+ color: 'cyan',
49
+ icon: 'lead-gen',
50
+ path: '/lead-gen'
51
+ },
52
+ {
53
+ id: 'projects',
54
+ label: 'Projects',
55
+ description: 'Projects, milestones, and client work execution',
56
+ enabled: true,
57
+ color: 'orange',
58
+ icon: 'projects',
59
+ path: '/projects',
60
+ uiPosition: 'sidebar-primary'
61
+ },
62
+ {
63
+ id: 'operations',
64
+ label: 'Operations',
65
+ description: 'Operational resources, topology, and orchestration visibility',
66
+ enabled: true,
67
+ color: 'violet',
68
+ icon: 'operations',
69
+ uiPosition: 'sidebar-primary'
70
+ },
71
+ {
72
+ id: 'operations.graph',
73
+ label: 'Organization Graph',
74
+ enabled: true,
75
+ path: '/operations/organization-graph'
76
+ },
77
+ {
78
+ id: 'operations.command-view',
79
+ label: 'Command View',
80
+ enabled: true,
81
+ path: '/operations/command-view',
82
+ devOnly: true
83
+ },
84
+ {
85
+ id: 'operations.overview',
86
+ label: 'Overview',
87
+ enabled: true,
88
+ path: '/operations'
89
+ },
90
+ {
91
+ id: 'operations.resources',
92
+ label: 'Resources',
93
+ enabled: true,
94
+ path: '/operations/resources'
95
+ },
96
+ {
97
+ id: 'operations.command-queue',
98
+ label: 'Command Queue',
99
+ enabled: true,
100
+ path: '/operations/command-queue'
101
+ },
102
+ {
103
+ id: 'operations.sessions',
104
+ label: 'Sessions',
105
+ enabled: false,
106
+ path: '/operations/sessions'
107
+ },
108
+ {
109
+ id: 'operations.task-scheduler',
110
+ label: 'Task Scheduler',
111
+ enabled: true,
112
+ path: '/operations/task-scheduler'
113
+ },
114
+ {
115
+ id: 'monitoring',
116
+ label: 'Monitoring',
117
+ enabled: true,
118
+ uiPosition: 'sidebar-primary'
119
+ },
120
+ {
121
+ id: 'monitoring.activity-log',
122
+ label: 'Activity Log',
123
+ enabled: true,
124
+ path: '/monitoring/activity-log'
125
+ },
126
+ {
127
+ id: 'monitoring.execution-logs',
128
+ label: 'Execution Logs',
129
+ enabled: true,
130
+ path: '/monitoring/execution-logs'
131
+ },
132
+ {
133
+ id: 'monitoring.execution-health',
134
+ label: 'Execution Health',
135
+ enabled: true,
136
+ path: '/monitoring/execution-health'
137
+ },
138
+ {
139
+ id: 'monitoring.cost-analytics',
140
+ label: 'Cost Analytics',
141
+ enabled: false,
142
+ path: '/monitoring/cost-analytics'
143
+ },
144
+ {
145
+ id: 'monitoring.notifications',
146
+ label: 'Notifications',
147
+ enabled: true,
148
+ path: '/monitoring/notifications'
149
+ },
150
+ {
151
+ id: 'monitoring.submitted-requests',
152
+ label: 'Submitted Requests',
153
+ enabled: true,
154
+ path: '/monitoring/requests'
155
+ },
156
+ {
157
+ id: 'settings',
158
+ label: 'Settings',
159
+ enabled: true,
160
+ icon: 'settings',
161
+ uiPosition: 'sidebar-bottom'
162
+ },
163
+ {
164
+ id: 'settings.account',
165
+ label: 'Account',
166
+ enabled: true,
167
+ path: '/settings/account'
168
+ },
169
+ {
170
+ id: 'settings.appearance',
171
+ label: 'Appearance',
172
+ enabled: true,
173
+ path: '/settings/appearance'
174
+ },
175
+ {
176
+ id: 'settings.organization',
177
+ label: 'Organization',
178
+ enabled: true,
179
+ path: '/settings/organization'
180
+ },
181
+ {
182
+ id: 'settings.credentials',
183
+ label: 'Credentials',
184
+ enabled: true,
185
+ path: '/settings/credentials'
186
+ },
187
+ {
188
+ id: 'settings.api-keys',
189
+ label: 'API Keys',
190
+ enabled: true,
191
+ path: '/settings/api-keys'
192
+ },
193
+ {
194
+ id: 'settings.webhooks',
195
+ label: 'Webhooks',
196
+ enabled: true,
197
+ path: '/settings/webhooks'
198
+ },
199
+ {
200
+ id: 'settings.deployments',
201
+ label: 'Deployments',
202
+ enabled: true,
203
+ path: '/settings/deployments'
204
+ },
205
+ {
206
+ id: 'admin',
207
+ label: 'Admin',
208
+ enabled: true,
209
+ path: '/admin',
210
+ icon: 'settings',
211
+ uiPosition: 'sidebar-bottom',
212
+ requiresAdmin: true
213
+ },
214
+ {
215
+ id: 'admin.system-health',
216
+ label: 'System Health',
217
+ enabled: true,
218
+ path: '/admin/system-health'
219
+ },
220
+ {
221
+ id: 'admin.organizations',
222
+ label: 'Organizations',
223
+ enabled: true,
224
+ path: '/admin/organizations'
225
+ },
226
+ {
227
+ id: 'admin.users',
228
+ label: 'Users',
229
+ enabled: true,
230
+ path: '/admin/users'
231
+ },
232
+ {
233
+ id: 'admin.design-showcase',
234
+ label: 'Design Showcase',
235
+ enabled: true,
236
+ path: '/admin/design-showcase'
237
+ },
238
+ {
239
+ id: 'admin.debug',
240
+ label: 'Debug',
241
+ enabled: true,
242
+ path: '/admin/debug'
243
+ },
244
+ {
245
+ id: 'archive',
246
+ label: 'Archive',
247
+ enabled: true,
248
+ path: '/archive',
249
+ icon: 'archive',
250
+ uiPosition: 'sidebar-bottom',
251
+ devOnly: true
252
+ },
253
+ {
254
+ id: 'archive.agent-chat',
255
+ label: 'Agent Chat',
256
+ enabled: true,
257
+ path: '/archive/agent-chat'
258
+ },
259
+ {
260
+ id: 'archive.execution-runner',
261
+ label: 'Execution Runner',
262
+ enabled: true,
263
+ path: '/archive/execution-runner'
264
+ },
265
+ {
266
+ id: 'seo',
267
+ label: 'SEO',
268
+ enabled: false,
269
+ path: '/seo'
270
+ }
271
+ ],
272
+ branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
273
+ navigation: { surfaces: [], groups: [] },
274
+ sales: DEFAULT_ORGANIZATION_MODEL_SALES,
275
+ prospecting: DEFAULT_ORGANIZATION_MODEL_PROSPECTING,
276
+ projects: DEFAULT_ORGANIZATION_MODEL_PROJECTS,
140
277
  identity: DEFAULT_ORGANIZATION_MODEL_IDENTITY,
141
278
  customers: DEFAULT_ORGANIZATION_MODEL_CUSTOMERS,
142
279
  offerings: DEFAULT_ORGANIZATION_MODEL_OFFERINGS,
143
- roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
144
- goals: DEFAULT_ORGANIZATION_MODEL_GOALS,
145
- statuses: DEFAULT_ORGANIZATION_MODEL_STATUSES,
146
- operations: DEFAULT_ORGANIZATION_MODEL_OPERATIONS,
147
- resourceMappings: []
148
- }
280
+ roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
281
+ goals: DEFAULT_ORGANIZATION_MODEL_GOALS,
282
+ statuses: DEFAULT_ORGANIZATION_MODEL_STATUSES,
283
+ operations: DEFAULT_ORGANIZATION_MODEL_OPERATIONS
284
+ }
@@ -1,22 +1,31 @@
1
- import { z } from 'zod'
2
- import {
3
- ColorTokenSchema,
4
- DescriptionSchema,
5
- IconNameSchema,
6
- LabelSchema,
7
- ModelIdSchema,
8
- ReferenceIdsSchema
9
- } from './shared'
10
-
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
22
- })
1
+ import { z } from 'zod'
2
+ import { ColorTokenSchema, DescriptionSchema, IconNameSchema, LabelSchema, PathSchema } from './shared'
3
+
4
+ export const NodeIdPathSchema = z
5
+ .string()
6
+ .trim()
7
+ .min(1)
8
+ .max(100)
9
+ .regex(/^([a-z0-9-]+)(\.[a-z0-9-]+)*$/, 'Node IDs must be lowercase dotted paths')
10
+
11
+ export const NodeIdStringSchema = z
12
+ .string()
13
+ .trim()
14
+ .min(1)
15
+ .max(200)
16
+ .regex(/^[a-z]+:([a-z0-9-]+)(\.[a-z0-9-]+)*$/, 'Node references must use kind:dotted-path')
17
+
18
+ export const UiPositionSchema = z.enum(['sidebar-primary', 'sidebar-bottom'])
19
+
20
+ export const FeatureSchema = z.object({
21
+ id: NodeIdPathSchema,
22
+ label: LabelSchema,
23
+ description: DescriptionSchema.optional(),
24
+ enabled: z.boolean().default(true),
25
+ path: PathSchema.optional(),
26
+ icon: IconNameSchema.optional(),
27
+ color: ColorTokenSchema.optional(),
28
+ uiPosition: UiPositionSchema.optional(),
29
+ requiresAdmin: z.boolean().optional(),
30
+ devOnly: z.boolean().optional()
31
+ })
@@ -1,5 +1,10 @@
1
1
  import { z } from 'zod'
2
- import { PROJECTS_VIEW_CAPABILITY_ID, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from '../contracts'
2
+ import {
3
+ OPERATIONS_COMMAND_VIEW_SURFACE_ID,
4
+ PROJECTS_VIEW_CAPABILITY_ID,
5
+ PROJECTS_FEATURE_ID,
6
+ PROJECTS_INDEX_SURFACE_ID
7
+ } from '../contracts'
3
8
  import { DescriptionSchema, IconNameSchema, LabelSchema, ModelIdSchema, PathSchema, ReferenceIdsSchema } from './shared'
4
9
 
5
10
  export const SurfaceTypeSchema = z.enum(['page', 'dashboard', 'graph', 'detail', 'list', 'settings'])
@@ -9,9 +14,10 @@ export const SurfaceDefinitionSchema = z.object({
9
14
  label: LabelSchema,
10
15
  path: PathSchema,
11
16
  surfaceType: SurfaceTypeSchema,
12
- description: DescriptionSchema.optional(),
13
- enabled: z.boolean().default(true),
14
- icon: IconNameSchema.optional(),
17
+ description: DescriptionSchema.optional(),
18
+ enabled: z.boolean().default(true),
19
+ devOnly: z.boolean().optional(),
20
+ icon: IconNameSchema.optional(),
15
21
  featureId: ModelIdSchema.optional(),
16
22
  featureIds: ReferenceIdsSchema,
17
23
  entityIds: ReferenceIdsSchema,
@@ -96,16 +102,17 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
96
102
  entityIds: [],
97
103
  resourceIds: [],
98
104
  capabilityIds: ['operations.organization-graph']
99
- },
100
- {
101
- id: 'operations.command-view',
102
- label: 'Command View',
103
- path: '/operations/command-view',
104
- surfaceType: 'graph',
105
- enabled: false,
106
- featureId: 'operations',
107
- featureIds: ['operations'],
108
- entityIds: [],
105
+ },
106
+ {
107
+ id: OPERATIONS_COMMAND_VIEW_SURFACE_ID,
108
+ label: 'Command View',
109
+ path: '/operations/command-view',
110
+ surfaceType: 'graph',
111
+ enabled: true,
112
+ devOnly: true,
113
+ featureId: 'operations',
114
+ featureIds: ['operations'],
115
+ entityIds: [],
109
116
  resourceIds: [],
110
117
  capabilityIds: ['operations.command-view']
111
118
  },
@@ -347,12 +354,12 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
347
354
  },
348
355
  {
349
356
  id: 'primary-operations',
350
- label: 'Operations',
351
- placement: 'primary',
352
- surfaceIds: [
353
- 'operations.organization-graph',
354
- 'operations.command-view',
355
- 'operations.overview',
357
+ label: 'Operations',
358
+ placement: 'primary',
359
+ surfaceIds: [
360
+ 'operations.organization-graph',
361
+ OPERATIONS_COMMAND_VIEW_SURFACE_ID,
362
+ 'operations.overview',
356
363
  'operations.resources',
357
364
  'operations.command-queue',
358
365
  'operations.sessions',
@@ -1,19 +1,19 @@
1
- import { PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from './contracts'
2
- import { resolveOrganizationModel } from './resolve'
3
- import type { DeepPartial, 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
1
+ import { resolveOrganizationModel } from './resolve'
2
+ import type { DeepPartial, OrganizationModel, OrganizationModelFeature } from './types'
3
+
4
+ export type FoundationSurfaceType = 'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'
5
+
6
+ export type FoundationSurfaceIcon = 'dashboard' | 'crm' | 'lead-gen' | 'projects' | 'operations' | 'settings'
7
+
8
+ export interface FoundationNavigationSurface extends Omit<OrganizationModelFeature, 'icon' | 'uiPosition'> {
9
+ icon?: FoundationSurfaceIcon
10
+ surfaceType?: FoundationSurfaceType
11
+ }
12
+
13
+ export interface FoundationOrganizationModel extends Omit<OrganizationModel, 'navigation'> {
14
+ navigation: {
15
+ defaultSurfaceId: string
16
+ homeLabel: string
17
17
  quickAccessSurfaceIds: readonly string[]
18
18
  surfaces: FoundationNavigationSurface[]
19
19
  }
@@ -32,46 +32,34 @@ export function createFoundationOrganizationModel(override: DeepPartial<Organiza
32
32
  quickAccessSurfaceIds: readonly string[]
33
33
  getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
34
34
  } {
35
- const canonical = resolveOrganizationModel(override)
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
- ]
35
+ const canonical = resolveOrganizationModel(override)
36
+
37
+ function requireCoreFeature(featureId: string): OrganizationModelFeature {
38
+ const feature = canonical.features.find((candidate) => candidate.id === featureId)
39
+
40
+ if (!feature) {
41
+ throw new Error(`Missing organization surface/feature: ${featureId}`)
42
+ }
43
+
44
+ return feature
45
+ }
46
+
47
+ const operationsGraphFeature = requireCoreFeature('operations.graph')
48
+ const projectsFeature = requireCoreFeature('projects')
49
+ const leadGenFeature = requireCoreFeature('sales.lead-gen')
50
+ const crmFeature = requireCoreFeature('sales.crm')
51
+
52
+ const navigationSurfaces: FoundationNavigationSurface[] = [
53
+ { ...operationsGraphFeature, id: 'operations', path: '/operations', icon: 'operations', surfaceType: 'graph' },
54
+ { ...operationsGraphFeature, path: '/operations', icon: 'operations', surfaceType: 'graph' },
55
+ { ...projectsFeature, icon: 'projects', surfaceType: 'list' },
56
+ { ...leadGenFeature, id: 'lead-gen', icon: 'lead-gen', surfaceType: 'list' },
57
+ { ...crmFeature, id: 'crm', icon: 'crm', surfaceType: 'graph' },
58
+ { ...requireCoreFeature('settings.account'), id: 'settings', icon: 'settings', surfaceType: 'settings' }
59
+ ]
72
60
 
73
61
  const homeLabel = 'Dashboard'
74
- const quickAccessSurfaceIds = ['operations', PROJECTS_FEATURE_ID, 'lead-gen', 'crm'] as const
62
+ const quickAccessSurfaceIds = ['operations', 'projects', 'lead-gen', 'crm'] as const
75
63
 
76
64
  const model: FoundationOrganizationModel = {
77
65
  ...canonical,