@elevasis/core 0.2.0 → 0.3.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 +60 -103
- package/dist/index.js +162 -109
- package/dist/organization-model/index.d.ts +60 -103
- package/dist/organization-model/index.js +162 -109
- package/package.json +1 -1
- package/src/README.md +24 -17
- package/src/__tests__/template-foundations-compatibility.test.ts +28 -36
- package/src/auth/multi-tenancy/types.ts +4 -11
- package/src/auth/multi-tenancy/users/api-schemas.ts +1 -1
- package/src/business/base-entities.test.ts +481 -0
- package/src/business/base-entities.ts +241 -0
- package/src/business/delivery/types.ts +1 -1
- package/src/business/index.ts +3 -0
- package/src/execution/index.ts +3 -6
- package/src/index.ts +1 -1
- package/src/organization-model/README.md +25 -26
- package/src/organization-model/__tests__/graph.test.ts +103 -71
- package/src/organization-model/__tests__/resolve.test.ts +20 -29
- package/src/organization-model/contracts.ts +3 -0
- package/src/organization-model/defaults.ts +40 -6
- package/src/organization-model/domains/features.ts +19 -54
- package/src/organization-model/domains/navigation.ts +25 -16
- package/src/organization-model/domains/shared.ts +1 -10
- package/src/organization-model/foundation.ts +96 -0
- package/src/organization-model/graph/build.ts +34 -67
- package/src/organization-model/graph/schema.ts +2 -4
- package/src/organization-model/graph/types.ts +3 -15
- package/src/organization-model/index.ts +2 -0
- package/src/organization-model/organization-model.mdx +34 -36
- package/src/organization-model/published.ts +12 -3
- package/src/organization-model/schema.ts +38 -34
- package/src/organization-model/types.ts +5 -10
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/sse/events.ts +1 -34
- package/src/projects/api-schemas.ts +2 -1
- package/src/reference/_generated/contracts.md +10 -31
- package/src/reference/glossary.md +14 -18
- package/src/supabase/database.types.ts +0 -107
- package/src/test-utils/rls/RLSTestContext.ts +1 -31
- package/src/execution/calibration/__tests__/schemas.test.ts +0 -320
- package/src/execution/calibration/index.ts +0 -3
- package/src/execution/calibration/schemas.ts +0 -121
- package/src/execution/calibration/sse-events.ts +0 -125
- package/src/execution/calibration/types.ts +0 -190
|
@@ -14,18 +14,11 @@ var DisplayMetadataSchema = z.object({
|
|
|
14
14
|
color: ColorTokenSchema.optional(),
|
|
15
15
|
icon: IconNameSchema.optional()
|
|
16
16
|
});
|
|
17
|
-
var SemanticDomainSchema = DisplayMetadataSchema.extend({
|
|
18
|
-
id: ModelIdSchema,
|
|
19
|
-
entityIds: ReferenceIdsSchema,
|
|
20
|
-
surfaceIds: ReferenceIdsSchema,
|
|
21
|
-
resourceIds: ReferenceIdsSchema,
|
|
22
|
-
capabilityIds: ReferenceIdsSchema
|
|
23
|
-
});
|
|
24
17
|
var ResourceMappingSchema = DisplayMetadataSchema.extend({
|
|
25
18
|
id: ModelIdSchema,
|
|
26
19
|
resourceId: z.string().trim().min(1).max(255),
|
|
27
20
|
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
|
|
28
|
-
|
|
21
|
+
featureIds: ReferenceIdsSchema,
|
|
29
22
|
entityIds: ReferenceIdsSchema,
|
|
30
23
|
surfaceIds: ReferenceIdsSchema,
|
|
31
24
|
capabilityIds: ReferenceIdsSchema
|
|
@@ -130,55 +123,18 @@ var DEFAULT_ORGANIZATION_MODEL_DELIVERY = {
|
|
|
130
123
|
{ id: "completed", label: "Completed", order: 9 }
|
|
131
124
|
]
|
|
132
125
|
};
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
acquisition: z.boolean().default(true),
|
|
145
|
-
delivery: z.boolean().default(true),
|
|
146
|
-
operations: z.boolean().default(true),
|
|
147
|
-
monitoring: z.boolean().default(true),
|
|
148
|
-
settings: z.boolean().default(true),
|
|
149
|
-
seo: z.boolean().default(false),
|
|
150
|
-
calibration: z.boolean().default(false)
|
|
151
|
-
}).default({
|
|
152
|
-
acquisition: true,
|
|
153
|
-
delivery: true,
|
|
154
|
-
operations: true,
|
|
155
|
-
monitoring: true,
|
|
156
|
-
settings: true,
|
|
157
|
-
seo: false,
|
|
158
|
-
calibration: false
|
|
159
|
-
}),
|
|
160
|
-
labels: z.object({
|
|
161
|
-
acquisition: z.string().trim().min(1).max(80).optional(),
|
|
162
|
-
delivery: z.string().trim().min(1).max(80).optional(),
|
|
163
|
-
operations: z.string().trim().min(1).max(80).optional(),
|
|
164
|
-
monitoring: z.string().trim().min(1).max(80).optional(),
|
|
165
|
-
settings: z.string().trim().min(1).max(80).optional(),
|
|
166
|
-
seo: z.string().trim().min(1).max(80).optional(),
|
|
167
|
-
calibration: z.string().trim().min(1).max(80).optional()
|
|
168
|
-
}).default({})
|
|
126
|
+
var FeatureSchema = z.object({
|
|
127
|
+
id: ModelIdSchema,
|
|
128
|
+
label: LabelSchema,
|
|
129
|
+
description: DescriptionSchema.optional(),
|
|
130
|
+
enabled: z.boolean().default(true),
|
|
131
|
+
color: ColorTokenSchema.optional(),
|
|
132
|
+
icon: IconNameSchema.optional(),
|
|
133
|
+
entityIds: ReferenceIdsSchema,
|
|
134
|
+
surfaceIds: ReferenceIdsSchema,
|
|
135
|
+
resourceIds: ReferenceIdsSchema,
|
|
136
|
+
capabilityIds: ReferenceIdsSchema
|
|
169
137
|
});
|
|
170
|
-
var DEFAULT_ORGANIZATION_MODEL_FEATURES = {
|
|
171
|
-
enabled: {
|
|
172
|
-
acquisition: true,
|
|
173
|
-
delivery: true,
|
|
174
|
-
operations: true,
|
|
175
|
-
monitoring: true,
|
|
176
|
-
settings: true,
|
|
177
|
-
seo: false,
|
|
178
|
-
calibration: false
|
|
179
|
-
},
|
|
180
|
-
labels: {}
|
|
181
|
-
};
|
|
182
138
|
var LeadGenLifecycleStageSchema = DisplayMetadataSchema.extend({
|
|
183
139
|
id: ModelIdSchema,
|
|
184
140
|
order: z.number().int().min(0)
|
|
@@ -207,6 +163,13 @@ var DEFAULT_ORGANIZATION_MODEL_LEAD_GEN = {
|
|
|
207
163
|
{ id: "uploaded", label: "Uploaded", order: 4 }
|
|
208
164
|
]
|
|
209
165
|
};
|
|
166
|
+
|
|
167
|
+
// src/organization-model/contracts.ts
|
|
168
|
+
var PROJECTS_FEATURE_ID = "projects";
|
|
169
|
+
var PROJECTS_INDEX_SURFACE_ID = "projects.index";
|
|
170
|
+
var DELIVERY_PROJECTS_VIEW_CAPABILITY_ID = "delivery.projects.view";
|
|
171
|
+
|
|
172
|
+
// src/organization-model/domains/navigation.ts
|
|
210
173
|
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]);
|
|
211
174
|
var SurfaceDefinitionSchema = z.object({
|
|
212
175
|
id: ModelIdSchema,
|
|
@@ -215,8 +178,8 @@ var SurfaceDefinitionSchema = z.object({
|
|
|
215
178
|
surfaceType: SurfaceTypeSchema,
|
|
216
179
|
description: DescriptionSchema.optional(),
|
|
217
180
|
icon: IconNameSchema.optional(),
|
|
218
|
-
|
|
219
|
-
|
|
181
|
+
featureId: ModelIdSchema.optional(),
|
|
182
|
+
featureIds: ReferenceIdsSchema,
|
|
220
183
|
entityIds: ReferenceIdsSchema,
|
|
221
184
|
resourceIds: ReferenceIdsSchema,
|
|
222
185
|
capabilityIds: ReferenceIdsSchema,
|
|
@@ -241,8 +204,8 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
241
204
|
label: "Pipeline",
|
|
242
205
|
path: "/crm/pipeline",
|
|
243
206
|
surfaceType: "graph",
|
|
244
|
-
|
|
245
|
-
|
|
207
|
+
featureId: "crm",
|
|
208
|
+
featureIds: ["crm"],
|
|
246
209
|
entityIds: ["crm.deal"],
|
|
247
210
|
resourceIds: [],
|
|
248
211
|
capabilityIds: ["crm.pipeline.manage"]
|
|
@@ -252,30 +215,30 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
252
215
|
label: "Lists",
|
|
253
216
|
path: "/lead-gen/lists",
|
|
254
217
|
surfaceType: "list",
|
|
255
|
-
|
|
256
|
-
|
|
218
|
+
featureId: "lead-gen",
|
|
219
|
+
featureIds: ["lead-gen"],
|
|
257
220
|
entityIds: ["leadgen.list"],
|
|
258
221
|
resourceIds: [],
|
|
259
222
|
capabilityIds: ["leadgen.lists.manage"]
|
|
260
223
|
},
|
|
261
224
|
{
|
|
262
|
-
id:
|
|
225
|
+
id: PROJECTS_INDEX_SURFACE_ID,
|
|
263
226
|
label: "Projects",
|
|
264
227
|
path: "/projects",
|
|
265
228
|
surfaceType: "list",
|
|
266
|
-
|
|
267
|
-
|
|
229
|
+
featureId: PROJECTS_FEATURE_ID,
|
|
230
|
+
featureIds: [PROJECTS_FEATURE_ID],
|
|
268
231
|
entityIds: ["delivery.project"],
|
|
269
232
|
resourceIds: [],
|
|
270
|
-
capabilityIds: [
|
|
233
|
+
capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
|
|
271
234
|
},
|
|
272
235
|
{
|
|
273
236
|
id: "operations.organization-graph",
|
|
274
237
|
label: "Organization Graph",
|
|
275
238
|
path: "/operations/organization-graph",
|
|
276
239
|
surfaceType: "graph",
|
|
277
|
-
|
|
278
|
-
|
|
240
|
+
featureId: "operations",
|
|
241
|
+
featureIds: ["operations"],
|
|
279
242
|
entityIds: [],
|
|
280
243
|
resourceIds: [],
|
|
281
244
|
capabilityIds: ["operations.organization-graph"]
|
|
@@ -285,15 +248,20 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
285
248
|
label: "Command View",
|
|
286
249
|
path: "/operations/command-view",
|
|
287
250
|
surfaceType: "graph",
|
|
288
|
-
|
|
289
|
-
|
|
251
|
+
featureId: "operations",
|
|
252
|
+
featureIds: ["operations"],
|
|
290
253
|
entityIds: [],
|
|
291
254
|
resourceIds: [],
|
|
292
255
|
capabilityIds: ["operations.command-view"]
|
|
293
256
|
}
|
|
294
257
|
],
|
|
295
258
|
groups: [
|
|
296
|
-
{
|
|
259
|
+
{
|
|
260
|
+
id: "primary-workspace",
|
|
261
|
+
label: "Workspace",
|
|
262
|
+
placement: "primary",
|
|
263
|
+
surfaceIds: ["crm.pipeline", "lead-gen.lists", PROJECTS_INDEX_SURFACE_ID]
|
|
264
|
+
},
|
|
297
265
|
{
|
|
298
266
|
id: "primary-operations",
|
|
299
267
|
label: "Operations",
|
|
@@ -306,9 +274,8 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
306
274
|
// src/organization-model/schema.ts
|
|
307
275
|
var OrganizationModelSchemaBase = z.object({
|
|
308
276
|
version: z.literal(1).default(1),
|
|
309
|
-
|
|
277
|
+
features: z.array(FeatureSchema).default([]),
|
|
310
278
|
branding: OrganizationModelBrandingSchema,
|
|
311
|
-
features: OrganizationModelFeaturesSchema,
|
|
312
279
|
navigation: OrganizationModelNavigationSchema,
|
|
313
280
|
crm: OrganizationModelCrmSchema,
|
|
314
281
|
leadGen: OrganizationModelLeadGenSchema,
|
|
@@ -334,7 +301,7 @@ function collectIds(items, ctx, collectionPath, label) {
|
|
|
334
301
|
return itemsById;
|
|
335
302
|
}
|
|
336
303
|
var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
337
|
-
const
|
|
304
|
+
const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
|
|
338
305
|
const surfacesById = collectIds(model.navigation.surfaces, ctx, ["navigation", "surfaces"], "Surface");
|
|
339
306
|
collectIds(model.navigation.groups, ctx, ["navigation", "groups"], "Navigation group");
|
|
340
307
|
collectIds(model.resourceMappings, ctx, ["resourceMappings"], "Resource mapping");
|
|
@@ -368,40 +335,40 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
368
335
|
}
|
|
369
336
|
});
|
|
370
337
|
});
|
|
371
|
-
model.
|
|
372
|
-
|
|
338
|
+
model.features.forEach((feature, featureIndex) => {
|
|
339
|
+
feature.surfaceIds.forEach((surfaceId, surfaceIndex) => {
|
|
373
340
|
const surface = surfacesById.get(surfaceId);
|
|
374
341
|
if (!surface) {
|
|
375
342
|
addIssue(
|
|
376
343
|
ctx,
|
|
377
|
-
["
|
|
378
|
-
`
|
|
344
|
+
["features", featureIndex, "surfaceIds", surfaceIndex],
|
|
345
|
+
`Feature "${feature.id}" references unknown surface "${surfaceId}"`
|
|
379
346
|
);
|
|
380
347
|
return;
|
|
381
348
|
}
|
|
382
|
-
if (!surface.
|
|
349
|
+
if (!surface.featureIds.includes(feature.id)) {
|
|
383
350
|
addIssue(
|
|
384
351
|
ctx,
|
|
385
|
-
["
|
|
386
|
-
`
|
|
352
|
+
["features", featureIndex, "surfaceIds", surfaceIndex],
|
|
353
|
+
`Feature "${feature.id}" references surface "${surfaceId}" but that surface does not include feature "${feature.id}"`
|
|
387
354
|
);
|
|
388
355
|
}
|
|
389
356
|
});
|
|
390
|
-
|
|
357
|
+
feature.resourceIds.forEach((resourceId, resourceIndex) => {
|
|
391
358
|
const resourceMapping = resourceMappingsByResourceId.get(resourceId);
|
|
392
359
|
if (!resourceMapping) {
|
|
393
360
|
addIssue(
|
|
394
361
|
ctx,
|
|
395
|
-
["
|
|
396
|
-
`
|
|
362
|
+
["features", featureIndex, "resourceIds", resourceIndex],
|
|
363
|
+
`Feature "${feature.id}" references unknown resource "${resourceId}"`
|
|
397
364
|
);
|
|
398
365
|
return;
|
|
399
366
|
}
|
|
400
|
-
if (!resourceMapping.
|
|
367
|
+
if (!resourceMapping.featureIds.includes(feature.id)) {
|
|
401
368
|
addIssue(
|
|
402
369
|
ctx,
|
|
403
|
-
["
|
|
404
|
-
`
|
|
370
|
+
["features", featureIndex, "resourceIds", resourceIndex],
|
|
371
|
+
`Feature "${feature.id}" references resource "${resourceId}" but that resource mapping does not include feature "${feature.id}"`
|
|
405
372
|
);
|
|
406
373
|
}
|
|
407
374
|
});
|
|
@@ -414,21 +381,21 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
414
381
|
`Surface "${surface.id}" references unknown parent surface "${surface.parentId}"`
|
|
415
382
|
);
|
|
416
383
|
}
|
|
417
|
-
surface.
|
|
418
|
-
const
|
|
419
|
-
if (!
|
|
384
|
+
surface.featureIds.forEach((featureId, featureIndex) => {
|
|
385
|
+
const feature = featuresById.get(featureId);
|
|
386
|
+
if (!feature) {
|
|
420
387
|
addIssue(
|
|
421
388
|
ctx,
|
|
422
|
-
["navigation", "surfaces", surfaceIndex, "
|
|
423
|
-
`Surface "${surface.id}" references unknown
|
|
389
|
+
["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
|
|
390
|
+
`Surface "${surface.id}" references unknown feature "${featureId}"`
|
|
424
391
|
);
|
|
425
392
|
return;
|
|
426
393
|
}
|
|
427
|
-
if (!
|
|
394
|
+
if (!feature.surfaceIds.includes(surface.id)) {
|
|
428
395
|
addIssue(
|
|
429
396
|
ctx,
|
|
430
|
-
["navigation", "surfaces", surfaceIndex, "
|
|
431
|
-
`Surface "${surface.id}" references
|
|
397
|
+
["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
|
|
398
|
+
`Surface "${surface.id}" references feature "${featureId}" but that feature does not include surface "${surface.id}"`
|
|
432
399
|
);
|
|
433
400
|
}
|
|
434
401
|
});
|
|
@@ -452,21 +419,21 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
452
419
|
});
|
|
453
420
|
});
|
|
454
421
|
model.resourceMappings.forEach((resourceMapping, resourceIndex) => {
|
|
455
|
-
resourceMapping.
|
|
456
|
-
const
|
|
457
|
-
if (!
|
|
422
|
+
resourceMapping.featureIds.forEach((featureId, featureIndex) => {
|
|
423
|
+
const feature = featuresById.get(featureId);
|
|
424
|
+
if (!feature) {
|
|
458
425
|
addIssue(
|
|
459
426
|
ctx,
|
|
460
|
-
["resourceMappings", resourceIndex, "
|
|
461
|
-
`Resource mapping "${resourceMapping.id}" references unknown
|
|
427
|
+
["resourceMappings", resourceIndex, "featureIds", featureIndex],
|
|
428
|
+
`Resource mapping "${resourceMapping.id}" references unknown feature "${featureId}"`
|
|
462
429
|
);
|
|
463
430
|
return;
|
|
464
431
|
}
|
|
465
|
-
if (!
|
|
432
|
+
if (!feature.resourceIds.includes(resourceMapping.resourceId)) {
|
|
466
433
|
addIssue(
|
|
467
434
|
ctx,
|
|
468
|
-
["resourceMappings", resourceIndex, "
|
|
469
|
-
`Resource mapping "${resourceMapping.id}" references
|
|
435
|
+
["resourceMappings", resourceIndex, "featureIds", featureIndex],
|
|
436
|
+
`Resource mapping "${resourceMapping.id}" references feature "${featureId}" but that feature does not include resource "${resourceMapping.resourceId}"`
|
|
470
437
|
);
|
|
471
438
|
}
|
|
472
439
|
});
|
|
@@ -494,11 +461,12 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
494
461
|
// src/organization-model/defaults.ts
|
|
495
462
|
var DEFAULT_ORGANIZATION_MODEL = {
|
|
496
463
|
version: 1,
|
|
497
|
-
|
|
464
|
+
features: [
|
|
498
465
|
{
|
|
499
466
|
id: "crm",
|
|
500
467
|
label: "CRM",
|
|
501
468
|
description: "Relationship pipeline and deal management",
|
|
469
|
+
enabled: true,
|
|
502
470
|
color: "blue",
|
|
503
471
|
entityIds: ["crm.deal"],
|
|
504
472
|
surfaceIds: ["crm.pipeline"],
|
|
@@ -509,6 +477,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
509
477
|
id: "lead-gen",
|
|
510
478
|
label: "Lead Gen",
|
|
511
479
|
description: "Prospecting, qualification, and outreach preparation",
|
|
480
|
+
enabled: true,
|
|
512
481
|
color: "cyan",
|
|
513
482
|
entityIds: ["leadgen.list", "leadgen.company", "leadgen.contact"],
|
|
514
483
|
surfaceIds: ["lead-gen.lists"],
|
|
@@ -516,28 +485,56 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
516
485
|
capabilityIds: ["leadgen.lists.manage"]
|
|
517
486
|
},
|
|
518
487
|
{
|
|
519
|
-
id:
|
|
488
|
+
id: PROJECTS_FEATURE_ID,
|
|
520
489
|
label: "Projects",
|
|
521
490
|
description: "Projects, milestones, and client work execution",
|
|
491
|
+
enabled: true,
|
|
522
492
|
color: "orange",
|
|
523
493
|
entityIds: ["delivery.project", "delivery.milestone", "delivery.task"],
|
|
524
|
-
surfaceIds: [
|
|
494
|
+
surfaceIds: [PROJECTS_INDEX_SURFACE_ID],
|
|
525
495
|
resourceIds: [],
|
|
526
|
-
capabilityIds: [
|
|
496
|
+
capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
|
|
527
497
|
},
|
|
528
498
|
{
|
|
529
499
|
id: "operations",
|
|
530
500
|
label: "Operations",
|
|
531
501
|
description: "Operational resources, topology, and orchestration visibility",
|
|
502
|
+
enabled: true,
|
|
532
503
|
color: "violet",
|
|
533
504
|
entityIds: [],
|
|
534
505
|
surfaceIds: ["operations.organization-graph", "operations.command-view"],
|
|
535
506
|
resourceIds: [],
|
|
536
507
|
capabilityIds: ["operations.organization-graph", "operations.command-view"]
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
id: "monitoring",
|
|
511
|
+
label: "Monitoring",
|
|
512
|
+
enabled: true,
|
|
513
|
+
entityIds: [],
|
|
514
|
+
surfaceIds: [],
|
|
515
|
+
resourceIds: [],
|
|
516
|
+
capabilityIds: []
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
id: "settings",
|
|
520
|
+
label: "Settings",
|
|
521
|
+
enabled: true,
|
|
522
|
+
entityIds: [],
|
|
523
|
+
surfaceIds: [],
|
|
524
|
+
resourceIds: [],
|
|
525
|
+
capabilityIds: []
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
id: "seo",
|
|
529
|
+
label: "SEO",
|
|
530
|
+
enabled: false,
|
|
531
|
+
entityIds: [],
|
|
532
|
+
surfaceIds: [],
|
|
533
|
+
resourceIds: [],
|
|
534
|
+
capabilityIds: []
|
|
537
535
|
}
|
|
538
536
|
],
|
|
539
537
|
branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
|
|
540
|
-
features: DEFAULT_ORGANIZATION_MODEL_FEATURES,
|
|
541
538
|
navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
|
|
542
539
|
crm: DEFAULT_ORGANIZATION_MODEL_CRM,
|
|
543
540
|
leadGen: DEFAULT_ORGANIZATION_MODEL_LEAD_GEN,
|
|
@@ -592,4 +589,60 @@ function resolveOrganizationModel(override) {
|
|
|
592
589
|
return OrganizationModelSchema.parse(merged);
|
|
593
590
|
}
|
|
594
591
|
|
|
595
|
-
|
|
592
|
+
// src/organization-model/foundation.ts
|
|
593
|
+
function createFoundationOrganizationModel(branding) {
|
|
594
|
+
const canonical = resolveOrganizationModel({ branding });
|
|
595
|
+
function requireCoreSurface(surfaceId) {
|
|
596
|
+
const surface = canonical.navigation.surfaces.find((candidate) => candidate.id === surfaceId);
|
|
597
|
+
if (!surface) {
|
|
598
|
+
throw new Error(`Missing organization surface: ${surfaceId}`);
|
|
599
|
+
}
|
|
600
|
+
return surface;
|
|
601
|
+
}
|
|
602
|
+
const operationsGraphSurface = requireCoreSurface("operations.organization-graph");
|
|
603
|
+
const projectsSurface = requireCoreSurface(PROJECTS_INDEX_SURFACE_ID);
|
|
604
|
+
const leadGenSurface = requireCoreSurface("lead-gen.lists");
|
|
605
|
+
const crmSurface = requireCoreSurface("crm.pipeline");
|
|
606
|
+
const navigationSurfaces = [
|
|
607
|
+
{ ...operationsGraphSurface, id: "operations", path: "/operations", icon: "operations" },
|
|
608
|
+
{ ...operationsGraphSurface, path: "/operations", icon: "operations" },
|
|
609
|
+
{ ...projectsSurface, id: PROJECTS_FEATURE_ID, icon: "projects" },
|
|
610
|
+
{ ...leadGenSurface, id: "lead-gen", icon: "lead-gen" },
|
|
611
|
+
{ ...crmSurface, id: "crm", icon: "crm" },
|
|
612
|
+
{
|
|
613
|
+
id: "settings",
|
|
614
|
+
label: "Settings",
|
|
615
|
+
path: "/settings/account",
|
|
616
|
+
surfaceType: "settings",
|
|
617
|
+
icon: "settings",
|
|
618
|
+
featureId: "settings",
|
|
619
|
+
featureIds: ["settings"],
|
|
620
|
+
entityIds: [],
|
|
621
|
+
resourceIds: [],
|
|
622
|
+
capabilityIds: []
|
|
623
|
+
}
|
|
624
|
+
];
|
|
625
|
+
const homeLabel = "Dashboard";
|
|
626
|
+
const quickAccessSurfaceIds = ["operations", PROJECTS_FEATURE_ID, "lead-gen", "crm"];
|
|
627
|
+
const model = {
|
|
628
|
+
...canonical,
|
|
629
|
+
navigation: {
|
|
630
|
+
defaultSurfaceId: "operations",
|
|
631
|
+
homeLabel,
|
|
632
|
+
quickAccessSurfaceIds: [...quickAccessSurfaceIds],
|
|
633
|
+
surfaces: navigationSurfaces
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
function getOrganizationSurface(surfaceId) {
|
|
637
|
+
return model.navigation.surfaces.find((candidate) => candidate.id === surfaceId);
|
|
638
|
+
}
|
|
639
|
+
return {
|
|
640
|
+
canonical,
|
|
641
|
+
model,
|
|
642
|
+
homeLabel,
|
|
643
|
+
quickAccessSurfaceIds,
|
|
644
|
+
getOrganizationSurface
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
export { DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
package/package.json
CHANGED
package/src/README.md
CHANGED
|
@@ -6,26 +6,33 @@ This package is the source of truth for shared types, schemas, and contract help
|
|
|
6
6
|
|
|
7
7
|
## Import Rules
|
|
8
8
|
|
|
9
|
-
- Use `@elevasis/core` for browser-safe shared types and schemas.
|
|
10
|
-
- Use `@elevasis/core/
|
|
11
|
-
-
|
|
12
|
-
-
|
|
9
|
+
- Use `@elevasis/core` (root export) for browser-safe shared types and schemas.
|
|
10
|
+
- Use `@elevasis/core/organization-model` for the semantic contract layer.
|
|
11
|
+
- These are the only two subpaths available to external consumers of the published npm package.
|
|
12
|
+
- Paths like `@elevasis/core/server`, `@elevasis/core/test-utils`, `@elevasis/core/platform`, etc. are internal monorepo paths (`@repo/core/...`) and are NOT available to external consumers.
|
|
13
13
|
|
|
14
14
|
## Published Surface Groups
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- `
|
|
24
|
-
- `
|
|
25
|
-
- `
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
28
|
-
- `
|
|
16
|
+
The published `@elevasis/core` npm package exposes exactly two subpaths:
|
|
17
|
+
|
|
18
|
+
- `.` (`@elevasis/core`) - browser-safe shared types, schemas, and constants.
|
|
19
|
+
- `./organization-model` (`@elevasis/core/organization-model`) - the semantic contract layer for CRM, lead gen, delivery, features, branding, and navigation.
|
|
20
|
+
|
|
21
|
+
Within the monorepo, the internal `@repo/core` package exposes additional subpaths for use by `apps/` and other packages:
|
|
22
|
+
|
|
23
|
+
- `@repo/core/server` - Node.js-only helpers and services.
|
|
24
|
+
- `@repo/core/platform` - shared constants, utilities, registry, SSE, and API types.
|
|
25
|
+
- `@repo/core/auth` - multi-tenancy types for organizations, users, memberships, invitations, and credentials.
|
|
26
|
+
- `@repo/core/execution` - workflow, agent, scheduler, and execution-interface contracts.
|
|
27
|
+
- `@repo/core/commands` - command queue types and schemas.
|
|
28
|
+
- `@repo/core/operations` - sessions, notifications, observability, activities, triggers, and debug logs.
|
|
29
|
+
- `@repo/core/supabase` - generated database types and helpers.
|
|
30
|
+
- `@repo/core/integrations/...` - OAuth and credential contracts.
|
|
31
|
+
- `@repo/core/projects/api-schemas` - project management request and response schemas.
|
|
32
|
+
- `@repo/core/content` - published content metadata types.
|
|
33
|
+
- `@repo/core/test-utils` - test fixtures and mocks (internal use only).
|
|
34
|
+
|
|
35
|
+
These `@repo/core/*` subpaths are NOT available in the published `@elevasis/core` package.
|
|
29
36
|
|
|
30
37
|
## When To Read Deeper
|
|
31
38
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, PROJECTS_FEATURE_ID } from '../organization-model/published'
|
|
2
3
|
import {
|
|
3
4
|
getOrganizationSurface,
|
|
4
5
|
homeLabel,
|
|
@@ -14,18 +15,18 @@ describe('template foundations compatibility', () => {
|
|
|
14
15
|
expect(foundationOrganizationModel.navigation.defaultSurfaceId).toBe('operations')
|
|
15
16
|
expect(getOrganizationSurface('operations')).toMatchObject({
|
|
16
17
|
id: 'operations',
|
|
17
|
-
label: '
|
|
18
|
+
label: 'Organization Graph',
|
|
18
19
|
path: '/operations',
|
|
19
20
|
surfaceType: 'graph',
|
|
20
|
-
|
|
21
|
+
featureId: 'operations'
|
|
21
22
|
})
|
|
22
23
|
|
|
23
24
|
expect(getOrganizationSurface('operations.organization-graph')).toMatchObject({
|
|
24
25
|
id: 'operations.organization-graph',
|
|
25
|
-
label: '
|
|
26
|
+
label: 'Organization Graph',
|
|
26
27
|
path: '/operations',
|
|
27
28
|
surfaceType: 'graph',
|
|
28
|
-
|
|
29
|
+
featureId: 'operations'
|
|
29
30
|
})
|
|
30
31
|
})
|
|
31
32
|
|
|
@@ -33,45 +34,41 @@ describe('template foundations compatibility', () => {
|
|
|
33
34
|
const legacySurfaces = [
|
|
34
35
|
{
|
|
35
36
|
id: 'operations',
|
|
36
|
-
label: '
|
|
37
|
+
label: 'Organization Graph',
|
|
37
38
|
surfaceType: 'graph',
|
|
38
|
-
|
|
39
|
+
expectedFeatureId: 'operations',
|
|
39
40
|
expectedIcon: 'operations',
|
|
40
41
|
expectedPath: '/operations',
|
|
41
|
-
expectedDomainIds: ['operations'],
|
|
42
42
|
expectedEntityIds: [],
|
|
43
|
-
expectedCapabilityIds: ['operations.organization-graph'
|
|
43
|
+
expectedCapabilityIds: ['operations.organization-graph']
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
-
id:
|
|
46
|
+
id: PROJECTS_FEATURE_ID,
|
|
47
47
|
label: 'Projects',
|
|
48
48
|
surfaceType: 'list',
|
|
49
|
-
|
|
49
|
+
expectedFeatureId: PROJECTS_FEATURE_ID,
|
|
50
50
|
expectedIcon: 'projects',
|
|
51
51
|
expectedPath: '/projects',
|
|
52
|
-
expectedDomainIds: ['delivery'],
|
|
53
52
|
expectedEntityIds: ['delivery.project'],
|
|
54
|
-
expectedCapabilityIds: [
|
|
53
|
+
expectedCapabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
|
|
55
54
|
},
|
|
56
55
|
{
|
|
57
56
|
id: 'lead-gen',
|
|
58
|
-
label: '
|
|
57
|
+
label: 'Lists',
|
|
59
58
|
surfaceType: 'list',
|
|
60
|
-
|
|
59
|
+
expectedFeatureId: 'lead-gen',
|
|
61
60
|
expectedIcon: 'lead-gen',
|
|
62
|
-
expectedPath: '/lead-gen',
|
|
63
|
-
expectedDomainIds: ['lead-gen'],
|
|
61
|
+
expectedPath: '/lead-gen/lists',
|
|
64
62
|
expectedEntityIds: ['leadgen.list'],
|
|
65
63
|
expectedCapabilityIds: ['leadgen.lists.manage']
|
|
66
64
|
},
|
|
67
65
|
{
|
|
68
66
|
id: 'crm',
|
|
69
|
-
label: '
|
|
67
|
+
label: 'Pipeline',
|
|
70
68
|
surfaceType: 'graph',
|
|
71
|
-
|
|
69
|
+
expectedFeatureId: 'crm',
|
|
72
70
|
expectedIcon: 'crm',
|
|
73
|
-
expectedPath: '/crm',
|
|
74
|
-
expectedDomainIds: ['crm'],
|
|
71
|
+
expectedPath: '/crm/pipeline',
|
|
75
72
|
expectedEntityIds: ['crm.deal'],
|
|
76
73
|
expectedCapabilityIds: ['crm.pipeline.manage']
|
|
77
74
|
}
|
|
@@ -86,8 +83,7 @@ describe('template foundations compatibility', () => {
|
|
|
86
83
|
path: surface.expectedPath,
|
|
87
84
|
surfaceType: surface.surfaceType,
|
|
88
85
|
icon: surface.expectedIcon,
|
|
89
|
-
|
|
90
|
-
domainIds: surface.expectedDomainIds,
|
|
86
|
+
featureId: surface.expectedFeatureId,
|
|
91
87
|
entityIds: surface.expectedEntityIds,
|
|
92
88
|
resourceIds: [],
|
|
93
89
|
capabilityIds: surface.expectedCapabilityIds
|
|
@@ -96,20 +92,16 @@ describe('template foundations compatibility', () => {
|
|
|
96
92
|
})
|
|
97
93
|
|
|
98
94
|
it('maps grouped core features onto the legacy template feature vocabulary', () => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
expect(foundationOrganizationModel.features.enabled.crm).toBe(
|
|
102
|
-
foundationOrganizationModel.features.enabled.acquisition
|
|
103
|
-
)
|
|
104
|
-
expect(foundationOrganizationModel.features.enabled['lead-gen']).toBe(
|
|
105
|
-
foundationOrganizationModel.features.enabled.acquisition
|
|
106
|
-
)
|
|
107
|
-
expect(foundationOrganizationModel.features.enabled.projects).toBe(
|
|
108
|
-
foundationOrganizationModel.features.enabled.delivery
|
|
109
|
-
)
|
|
95
|
+
const features = foundationOrganizationModel.features as Array<{ id: string; label: string; enabled: boolean }>
|
|
96
|
+
const featureById = (id: string) => features.find((f) => f.id === id)
|
|
110
97
|
|
|
111
|
-
expect(
|
|
112
|
-
expect(
|
|
113
|
-
expect(
|
|
98
|
+
expect(featureById('crm')?.enabled).toBe(true)
|
|
99
|
+
expect(featureById('lead-gen')?.enabled).toBe(true)
|
|
100
|
+
expect(featureById('projects')?.enabled).toBe(true)
|
|
101
|
+
expect(featureById('operations')?.enabled).toBe(true)
|
|
102
|
+
|
|
103
|
+
expect(featureById('crm')?.label).toBe('CRM')
|
|
104
|
+
expect(featureById('lead-gen')?.label).toBe('Lead Gen')
|
|
105
|
+
expect(featureById('projects')?.label).toBe('Projects')
|
|
114
106
|
})
|
|
115
107
|
})
|