@elevasis/core 0.4.0 → 0.5.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/business/entities-published.d.ts +215 -0
- package/dist/business/entities-published.js +69 -0
- package/dist/index.d.ts +14 -5
- package/dist/index.js +21 -12
- package/dist/organization-model/index.d.ts +14 -5
- package/dist/organization-model/index.js +21 -12
- package/package.json +5 -1
- package/src/__tests__/publish.test.ts +1 -1
- package/src/business/README.md +52 -0
- package/src/business/__tests__/entities-published.test.ts +33 -0
- package/src/business/entities-published.ts +24 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +2 -3
- package/src/organization-model/__tests__/foundation.test.ts +105 -0
- package/src/organization-model/contracts.ts +11 -0
- package/src/organization-model/defaults.ts +23 -10
- package/src/organization-model/foundation.ts +3 -3
- package/src/organization-model/published.ts +14 -1
- package/src/platform/constants/versions.ts +1 -1
- package/src/reference/_generated/contracts.md +1 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base Entity Contracts
|
|
5
|
+
*
|
|
6
|
+
* Typed base interfaces for CRM, Lead-Gen (Acquisition), and Projects domains.
|
|
7
|
+
* Each uses a `<TMeta>` generic parameter so client projects can narrow the
|
|
8
|
+
* metadata type in their own `foundations/types/` directory.
|
|
9
|
+
*
|
|
10
|
+
* These are PARALLEL abstractions — they do NOT replace or modify the existing
|
|
11
|
+
* row types (ProjectRow, AcqDealRow, etc.). Use these as the SDK-facing contract
|
|
12
|
+
* layer; use the row types internally for direct Supabase access.
|
|
13
|
+
*
|
|
14
|
+
* Usage in a client project:
|
|
15
|
+
* import { BaseProject } from '@elevasis/core' (or '@repo/core' internally)
|
|
16
|
+
* type Project = BaseProject<{ budget: number; riskScore: 'low' | 'medium' | 'high' }>
|
|
17
|
+
*
|
|
18
|
+
* Extending a Zod schema in a client project:
|
|
19
|
+
* import { BaseProjectSchema } from '@elevasis/core'
|
|
20
|
+
* const ProjectMetaSchema = z.object({ budget: z.number(), riskScore: z.enum(['low','medium','high']) })
|
|
21
|
+
* const ProjectSchema = BaseProjectSchema.extend({ metadata: ProjectMetaSchema })
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Common fields shared across all project implementations.
|
|
25
|
+
* `TMeta` narrows the `metadata` JSONB column (prj_projects.metadata).
|
|
26
|
+
*/
|
|
27
|
+
interface BaseProject<TMeta = Record<string, unknown>> {
|
|
28
|
+
id: string;
|
|
29
|
+
organizationId: string;
|
|
30
|
+
name: string;
|
|
31
|
+
kind: string;
|
|
32
|
+
status: string;
|
|
33
|
+
description: string | null;
|
|
34
|
+
metadata: TMeta;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
updatedAt: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Common fields shared across all milestone implementations.
|
|
40
|
+
* `TMeta` narrows the `metadata` JSONB column (prj_milestones.metadata).
|
|
41
|
+
*/
|
|
42
|
+
interface BaseMilestone<TMeta = Record<string, unknown>> {
|
|
43
|
+
id: string;
|
|
44
|
+
organizationId: string;
|
|
45
|
+
projectId: string;
|
|
46
|
+
name: string;
|
|
47
|
+
status: string;
|
|
48
|
+
description: string | null;
|
|
49
|
+
metadata: TMeta;
|
|
50
|
+
createdAt: string;
|
|
51
|
+
updatedAt: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Common fields shared across all task implementations.
|
|
55
|
+
* `TMeta` narrows the `metadata` JSONB column (prj_tasks.metadata).
|
|
56
|
+
*/
|
|
57
|
+
interface BaseTask<TMeta = Record<string, unknown>> {
|
|
58
|
+
id: string;
|
|
59
|
+
organizationId: string;
|
|
60
|
+
projectId: string;
|
|
61
|
+
name: string;
|
|
62
|
+
status: string;
|
|
63
|
+
type: string;
|
|
64
|
+
description: string | null;
|
|
65
|
+
metadata: TMeta;
|
|
66
|
+
createdAt: string;
|
|
67
|
+
updatedAt: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Common fields shared across all deal implementations.
|
|
71
|
+
* `TMeta` is an extension point for client-specific deal metadata.
|
|
72
|
+
* Note: The underlying acq_deals table does not have a `metadata` column;
|
|
73
|
+
* this field serves as a typed extension slot for SDK consumers.
|
|
74
|
+
*/
|
|
75
|
+
interface BaseDeal<TMeta = Record<string, unknown>> {
|
|
76
|
+
id: string;
|
|
77
|
+
organizationId: string;
|
|
78
|
+
contactEmail: string;
|
|
79
|
+
stage: string | null;
|
|
80
|
+
metadata: TMeta;
|
|
81
|
+
createdAt: string;
|
|
82
|
+
updatedAt: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Common fields shared across all company implementations.
|
|
86
|
+
* `TMeta` is an extension point for client-specific company metadata.
|
|
87
|
+
*/
|
|
88
|
+
interface BaseCompany<TMeta = Record<string, unknown>> {
|
|
89
|
+
id: string;
|
|
90
|
+
organizationId: string;
|
|
91
|
+
name: string;
|
|
92
|
+
domain: string | null;
|
|
93
|
+
status: string;
|
|
94
|
+
metadata: TMeta;
|
|
95
|
+
createdAt: string;
|
|
96
|
+
updatedAt: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Common fields shared across all contact implementations.
|
|
100
|
+
* `TMeta` is an extension point for client-specific contact metadata.
|
|
101
|
+
*/
|
|
102
|
+
interface BaseContact<TMeta = Record<string, unknown>> {
|
|
103
|
+
id: string;
|
|
104
|
+
organizationId: string;
|
|
105
|
+
email: string;
|
|
106
|
+
firstName: string | null;
|
|
107
|
+
lastName: string | null;
|
|
108
|
+
status: string;
|
|
109
|
+
metadata: TMeta;
|
|
110
|
+
createdAt: string;
|
|
111
|
+
updatedAt: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Base Zod schema for a project record.
|
|
115
|
+
* Extend with `BaseProjectSchema.extend({ metadata: ProjectMetaSchema })`.
|
|
116
|
+
*/
|
|
117
|
+
declare const BaseProjectSchema: z.ZodObject<{
|
|
118
|
+
id: z.ZodString;
|
|
119
|
+
organizationId: z.ZodString;
|
|
120
|
+
name: z.ZodString;
|
|
121
|
+
kind: z.ZodString;
|
|
122
|
+
status: z.ZodString;
|
|
123
|
+
description: z.ZodNullable<z.ZodString>;
|
|
124
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
125
|
+
createdAt: z.ZodString;
|
|
126
|
+
updatedAt: z.ZodString;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
/**
|
|
129
|
+
* Base Zod schema for a milestone record.
|
|
130
|
+
* Extend with `BaseMilestoneSchema.extend({ metadata: MilestoneMetaSchema })`.
|
|
131
|
+
*/
|
|
132
|
+
declare const BaseMilestoneSchema: z.ZodObject<{
|
|
133
|
+
id: z.ZodString;
|
|
134
|
+
organizationId: z.ZodString;
|
|
135
|
+
projectId: z.ZodString;
|
|
136
|
+
name: z.ZodString;
|
|
137
|
+
status: z.ZodString;
|
|
138
|
+
description: z.ZodNullable<z.ZodString>;
|
|
139
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
140
|
+
createdAt: z.ZodString;
|
|
141
|
+
updatedAt: z.ZodString;
|
|
142
|
+
}, z.core.$strip>;
|
|
143
|
+
/**
|
|
144
|
+
* Base Zod schema for a task record.
|
|
145
|
+
* Extend with `BaseTaskSchema.extend({ metadata: TaskMetaSchema })`.
|
|
146
|
+
*/
|
|
147
|
+
declare const BaseTaskSchema: z.ZodObject<{
|
|
148
|
+
id: z.ZodString;
|
|
149
|
+
organizationId: z.ZodString;
|
|
150
|
+
projectId: z.ZodString;
|
|
151
|
+
name: z.ZodString;
|
|
152
|
+
status: z.ZodString;
|
|
153
|
+
type: z.ZodString;
|
|
154
|
+
description: z.ZodNullable<z.ZodString>;
|
|
155
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
156
|
+
createdAt: z.ZodString;
|
|
157
|
+
updatedAt: z.ZodString;
|
|
158
|
+
}, z.core.$strip>;
|
|
159
|
+
/**
|
|
160
|
+
* Base Zod schema for a deal record.
|
|
161
|
+
* Extend with `BaseDealSchema.extend({ metadata: DealMetaSchema })`.
|
|
162
|
+
*/
|
|
163
|
+
declare const BaseDealSchema: z.ZodObject<{
|
|
164
|
+
id: z.ZodString;
|
|
165
|
+
organizationId: z.ZodString;
|
|
166
|
+
contactEmail: z.ZodString;
|
|
167
|
+
stage: z.ZodNullable<z.ZodString>;
|
|
168
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
169
|
+
createdAt: z.ZodString;
|
|
170
|
+
updatedAt: z.ZodString;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
/**
|
|
173
|
+
* Base Zod schema for a company record.
|
|
174
|
+
* Extend with `BaseCompanySchema.extend({ metadata: CompanyMetaSchema })`.
|
|
175
|
+
*/
|
|
176
|
+
declare const BaseCompanySchema: z.ZodObject<{
|
|
177
|
+
id: z.ZodString;
|
|
178
|
+
organizationId: z.ZodString;
|
|
179
|
+
name: z.ZodString;
|
|
180
|
+
domain: z.ZodNullable<z.ZodString>;
|
|
181
|
+
status: z.ZodString;
|
|
182
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
183
|
+
createdAt: z.ZodString;
|
|
184
|
+
updatedAt: z.ZodString;
|
|
185
|
+
}, z.core.$strip>;
|
|
186
|
+
/**
|
|
187
|
+
* Base Zod schema for a contact record.
|
|
188
|
+
* Extend with `BaseContactSchema.extend({ metadata: ContactMetaSchema })`.
|
|
189
|
+
*/
|
|
190
|
+
declare const BaseContactSchema: z.ZodObject<{
|
|
191
|
+
id: z.ZodString;
|
|
192
|
+
organizationId: z.ZodString;
|
|
193
|
+
email: z.ZodString;
|
|
194
|
+
firstName: z.ZodNullable<z.ZodString>;
|
|
195
|
+
lastName: z.ZodNullable<z.ZodString>;
|
|
196
|
+
status: z.ZodString;
|
|
197
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
198
|
+
createdAt: z.ZodString;
|
|
199
|
+
updatedAt: z.ZodString;
|
|
200
|
+
}, z.core.$strip>;
|
|
201
|
+
/** Default (unnarrowed) inferred type from BaseProjectSchema */
|
|
202
|
+
type BaseProjectInput = z.infer<typeof BaseProjectSchema>;
|
|
203
|
+
/** Default (unnarrowed) inferred type from BaseMilestoneSchema */
|
|
204
|
+
type BaseMilestoneInput = z.infer<typeof BaseMilestoneSchema>;
|
|
205
|
+
/** Default (unnarrowed) inferred type from BaseTaskSchema */
|
|
206
|
+
type BaseTaskInput = z.infer<typeof BaseTaskSchema>;
|
|
207
|
+
/** Default (unnarrowed) inferred type from BaseDealSchema */
|
|
208
|
+
type BaseDealInput = z.infer<typeof BaseDealSchema>;
|
|
209
|
+
/** Default (unnarrowed) inferred type from BaseCompanySchema */
|
|
210
|
+
type BaseCompanyInput = z.infer<typeof BaseCompanySchema>;
|
|
211
|
+
/** Default (unnarrowed) inferred type from BaseContactSchema */
|
|
212
|
+
type BaseContactInput = z.infer<typeof BaseContactSchema>;
|
|
213
|
+
|
|
214
|
+
export { BaseCompanySchema, BaseContactSchema, BaseDealSchema, BaseMilestoneSchema, BaseProjectSchema, BaseTaskSchema };
|
|
215
|
+
export type { BaseCompany, BaseCompanyInput, BaseContact, BaseContactInput, BaseDeal, BaseDealInput, BaseMilestone, BaseMilestoneInput, BaseProject, BaseProjectInput, BaseTask, BaseTaskInput };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/business/base-entities.ts
|
|
4
|
+
var BaseProjectSchema = z.object({
|
|
5
|
+
id: z.string(),
|
|
6
|
+
organizationId: z.string(),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
kind: z.string(),
|
|
9
|
+
status: z.string(),
|
|
10
|
+
description: z.string().nullable(),
|
|
11
|
+
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
12
|
+
createdAt: z.string(),
|
|
13
|
+
updatedAt: z.string()
|
|
14
|
+
});
|
|
15
|
+
var BaseMilestoneSchema = z.object({
|
|
16
|
+
id: z.string(),
|
|
17
|
+
organizationId: z.string(),
|
|
18
|
+
projectId: z.string(),
|
|
19
|
+
name: z.string(),
|
|
20
|
+
status: z.string(),
|
|
21
|
+
description: z.string().nullable(),
|
|
22
|
+
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
23
|
+
createdAt: z.string(),
|
|
24
|
+
updatedAt: z.string()
|
|
25
|
+
});
|
|
26
|
+
var BaseTaskSchema = z.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
organizationId: z.string(),
|
|
29
|
+
projectId: z.string(),
|
|
30
|
+
name: z.string(),
|
|
31
|
+
status: z.string(),
|
|
32
|
+
type: z.string(),
|
|
33
|
+
description: z.string().nullable(),
|
|
34
|
+
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
35
|
+
createdAt: z.string(),
|
|
36
|
+
updatedAt: z.string()
|
|
37
|
+
});
|
|
38
|
+
var BaseDealSchema = z.object({
|
|
39
|
+
id: z.string(),
|
|
40
|
+
organizationId: z.string(),
|
|
41
|
+
contactEmail: z.string(),
|
|
42
|
+
stage: z.string().nullable(),
|
|
43
|
+
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
44
|
+
createdAt: z.string(),
|
|
45
|
+
updatedAt: z.string()
|
|
46
|
+
});
|
|
47
|
+
var BaseCompanySchema = z.object({
|
|
48
|
+
id: z.string(),
|
|
49
|
+
organizationId: z.string(),
|
|
50
|
+
name: z.string(),
|
|
51
|
+
domain: z.string().nullable(),
|
|
52
|
+
status: z.string(),
|
|
53
|
+
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
54
|
+
createdAt: z.string(),
|
|
55
|
+
updatedAt: z.string()
|
|
56
|
+
});
|
|
57
|
+
var BaseContactSchema = z.object({
|
|
58
|
+
id: z.string(),
|
|
59
|
+
organizationId: z.string(),
|
|
60
|
+
email: z.string(),
|
|
61
|
+
firstName: z.string().nullable(),
|
|
62
|
+
lastName: z.string().nullable(),
|
|
63
|
+
status: z.string(),
|
|
64
|
+
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
65
|
+
createdAt: z.string(),
|
|
66
|
+
updatedAt: z.string()
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export { BaseCompanySchema, BaseContactSchema, BaseDealSchema, BaseMilestoneSchema, BaseProjectSchema, BaseTaskSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -32,11 +32,11 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
32
32
|
path: z.ZodString;
|
|
33
33
|
surfaceType: z.ZodEnum<{
|
|
34
34
|
list: "list";
|
|
35
|
+
settings: "settings";
|
|
35
36
|
page: "page";
|
|
36
37
|
dashboard: "dashboard";
|
|
37
38
|
graph: "graph";
|
|
38
39
|
detail: "detail";
|
|
39
|
-
settings: "settings";
|
|
40
40
|
}>;
|
|
41
41
|
description: z.ZodOptional<z.ZodString>;
|
|
42
42
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -175,6 +175,15 @@ declare const FeatureSchema: z.ZodObject<{
|
|
|
175
175
|
declare const PROJECTS_FEATURE_ID: "projects";
|
|
176
176
|
declare const PROJECTS_INDEX_SURFACE_ID: "projects.index";
|
|
177
177
|
declare const DELIVERY_PROJECTS_VIEW_CAPABILITY_ID: "delivery.projects.view";
|
|
178
|
+
declare const CRM_FEATURE_ID: "crm";
|
|
179
|
+
declare const LEAD_GEN_FEATURE_ID: "lead-gen";
|
|
180
|
+
declare const OPERATIONS_FEATURE_ID: "operations";
|
|
181
|
+
declare const MONITORING_FEATURE_ID: "monitoring";
|
|
182
|
+
declare const SETTINGS_FEATURE_ID: "settings";
|
|
183
|
+
declare const SEO_FEATURE_ID: "seo";
|
|
184
|
+
declare const CRM_PIPELINE_SURFACE_ID: "crm.pipeline";
|
|
185
|
+
declare const LEAD_GEN_LISTS_SURFACE_ID: "lead-gen.lists";
|
|
186
|
+
declare const OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID: "operations.organization-graph";
|
|
178
187
|
|
|
179
188
|
declare const OrganizationModelBrandingSchema: z.ZodObject<{
|
|
180
189
|
organizationName: z.ZodString;
|
|
@@ -274,11 +283,11 @@ declare const SurfaceDefinitionSchema: z.ZodObject<{
|
|
|
274
283
|
path: z.ZodString;
|
|
275
284
|
surfaceType: z.ZodEnum<{
|
|
276
285
|
list: "list";
|
|
286
|
+
settings: "settings";
|
|
277
287
|
page: "page";
|
|
278
288
|
dashboard: "dashboard";
|
|
279
289
|
graph: "graph";
|
|
280
290
|
detail: "detail";
|
|
281
|
-
settings: "settings";
|
|
282
291
|
}>;
|
|
283
292
|
description: z.ZodOptional<z.ZodString>;
|
|
284
293
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -298,11 +307,11 @@ declare const OrganizationModelNavigationSchema: z.ZodObject<{
|
|
|
298
307
|
path: z.ZodString;
|
|
299
308
|
surfaceType: z.ZodEnum<{
|
|
300
309
|
list: "list";
|
|
310
|
+
settings: "settings";
|
|
301
311
|
page: "page";
|
|
302
312
|
dashboard: "dashboard";
|
|
303
313
|
graph: "graph";
|
|
304
314
|
detail: "detail";
|
|
305
|
-
settings: "settings";
|
|
306
315
|
}>;
|
|
307
316
|
description: z.ZodOptional<z.ZodString>;
|
|
308
317
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -383,7 +392,7 @@ interface FoundationBranding {
|
|
|
383
392
|
productName: string;
|
|
384
393
|
shortName: string;
|
|
385
394
|
}
|
|
386
|
-
declare function createFoundationOrganizationModel(
|
|
395
|
+
declare function createFoundationOrganizationModel(override: DeepPartial<OrganizationModel>): {
|
|
387
396
|
canonical: OrganizationModel;
|
|
388
397
|
model: FoundationOrganizationModel;
|
|
389
398
|
homeLabel: string;
|
|
@@ -391,5 +400,5 @@ declare function createFoundationOrganizationModel(branding: FoundationBranding)
|
|
|
391
400
|
getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined;
|
|
392
401
|
};
|
|
393
402
|
|
|
394
|
-
export { DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
403
|
+
export { CRM_FEATURE_ID, CRM_PIPELINE_SURFACE_ID, DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, LEAD_GEN_FEATURE_ID, LEAD_GEN_LISTS_SURFACE_ID, MONITORING_FEATURE_ID, OPERATIONS_FEATURE_ID, OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, SEO_FEATURE_ID, SETTINGS_FEATURE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
395
404
|
export type { DeepPartial, FoundationBranding, FoundationNavigationSurface, FoundationOrganizationModel, FoundationSurfaceIcon, FoundationSurfaceType, OrganizationModel, OrganizationModelBranding, OrganizationModelCrm, OrganizationModelDelivery, OrganizationModelFeature, OrganizationModelLeadGen, OrganizationModelNavigation, OrganizationModelResourceMapping, OrganizationModelSurface };
|
package/dist/index.js
CHANGED
|
@@ -168,6 +168,15 @@ var DEFAULT_ORGANIZATION_MODEL_LEAD_GEN = {
|
|
|
168
168
|
var PROJECTS_FEATURE_ID = "projects";
|
|
169
169
|
var PROJECTS_INDEX_SURFACE_ID = "projects.index";
|
|
170
170
|
var DELIVERY_PROJECTS_VIEW_CAPABILITY_ID = "delivery.projects.view";
|
|
171
|
+
var CRM_FEATURE_ID = "crm";
|
|
172
|
+
var LEAD_GEN_FEATURE_ID = "lead-gen";
|
|
173
|
+
var OPERATIONS_FEATURE_ID = "operations";
|
|
174
|
+
var MONITORING_FEATURE_ID = "monitoring";
|
|
175
|
+
var SETTINGS_FEATURE_ID = "settings";
|
|
176
|
+
var SEO_FEATURE_ID = "seo";
|
|
177
|
+
var CRM_PIPELINE_SURFACE_ID = "crm.pipeline";
|
|
178
|
+
var LEAD_GEN_LISTS_SURFACE_ID = "lead-gen.lists";
|
|
179
|
+
var OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID = "operations.organization-graph";
|
|
171
180
|
|
|
172
181
|
// src/organization-model/domains/navigation.ts
|
|
173
182
|
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]);
|
|
@@ -707,24 +716,24 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
707
716
|
version: 1,
|
|
708
717
|
features: [
|
|
709
718
|
{
|
|
710
|
-
id:
|
|
719
|
+
id: CRM_FEATURE_ID,
|
|
711
720
|
label: "CRM",
|
|
712
721
|
description: "Relationship pipeline and deal management",
|
|
713
722
|
enabled: true,
|
|
714
723
|
color: "blue",
|
|
715
724
|
entityIds: ["crm.deal"],
|
|
716
|
-
surfaceIds: [
|
|
725
|
+
surfaceIds: [CRM_PIPELINE_SURFACE_ID],
|
|
717
726
|
resourceIds: [],
|
|
718
727
|
capabilityIds: ["crm.pipeline.manage"]
|
|
719
728
|
},
|
|
720
729
|
{
|
|
721
|
-
id:
|
|
730
|
+
id: LEAD_GEN_FEATURE_ID,
|
|
722
731
|
label: "Lead Gen",
|
|
723
732
|
description: "Prospecting, qualification, and outreach preparation",
|
|
724
733
|
enabled: true,
|
|
725
734
|
color: "cyan",
|
|
726
735
|
entityIds: ["leadgen.list", "leadgen.company", "leadgen.contact"],
|
|
727
|
-
surfaceIds: [
|
|
736
|
+
surfaceIds: [LEAD_GEN_LISTS_SURFACE_ID],
|
|
728
737
|
resourceIds: [],
|
|
729
738
|
capabilityIds: ["leadgen.lists.manage"]
|
|
730
739
|
},
|
|
@@ -740,14 +749,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
740
749
|
capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
|
|
741
750
|
},
|
|
742
751
|
{
|
|
743
|
-
id:
|
|
752
|
+
id: OPERATIONS_FEATURE_ID,
|
|
744
753
|
label: "Operations",
|
|
745
754
|
description: "Operational resources, topology, and orchestration visibility",
|
|
746
755
|
enabled: true,
|
|
747
756
|
color: "violet",
|
|
748
757
|
entityIds: [],
|
|
749
758
|
surfaceIds: [
|
|
750
|
-
|
|
759
|
+
OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID,
|
|
751
760
|
"operations.command-view",
|
|
752
761
|
"operations.overview",
|
|
753
762
|
"operations.resources",
|
|
@@ -759,7 +768,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
759
768
|
capabilityIds: ["operations.organization-graph", "operations.command-view"]
|
|
760
769
|
},
|
|
761
770
|
{
|
|
762
|
-
id:
|
|
771
|
+
id: MONITORING_FEATURE_ID,
|
|
763
772
|
label: "Monitoring",
|
|
764
773
|
enabled: true,
|
|
765
774
|
entityIds: [],
|
|
@@ -774,7 +783,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
774
783
|
capabilityIds: []
|
|
775
784
|
},
|
|
776
785
|
{
|
|
777
|
-
id:
|
|
786
|
+
id: SETTINGS_FEATURE_ID,
|
|
778
787
|
label: "Settings",
|
|
779
788
|
enabled: true,
|
|
780
789
|
entityIds: [],
|
|
@@ -791,7 +800,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
791
800
|
capabilityIds: []
|
|
792
801
|
},
|
|
793
802
|
{
|
|
794
|
-
id:
|
|
803
|
+
id: SEO_FEATURE_ID,
|
|
795
804
|
label: "SEO",
|
|
796
805
|
enabled: false,
|
|
797
806
|
entityIds: [],
|
|
@@ -856,8 +865,8 @@ function resolveOrganizationModel(override) {
|
|
|
856
865
|
}
|
|
857
866
|
|
|
858
867
|
// src/organization-model/foundation.ts
|
|
859
|
-
function createFoundationOrganizationModel(
|
|
860
|
-
const canonical = resolveOrganizationModel(
|
|
868
|
+
function createFoundationOrganizationModel(override) {
|
|
869
|
+
const canonical = resolveOrganizationModel(override);
|
|
861
870
|
function requireCoreSurface(surfaceId) {
|
|
862
871
|
const surface = canonical.navigation.surfaces.find((candidate) => candidate.id === surfaceId);
|
|
863
872
|
if (!surface) {
|
|
@@ -912,4 +921,4 @@ function createFoundationOrganizationModel(branding) {
|
|
|
912
921
|
};
|
|
913
922
|
}
|
|
914
923
|
|
|
915
|
-
export { DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
924
|
+
export { CRM_FEATURE_ID, CRM_PIPELINE_SURFACE_ID, DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, LEAD_GEN_FEATURE_ID, LEAD_GEN_LISTS_SURFACE_ID, MONITORING_FEATURE_ID, OPERATIONS_FEATURE_ID, OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, SEO_FEATURE_ID, SETTINGS_FEATURE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
@@ -32,11 +32,11 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
32
32
|
path: z.ZodString;
|
|
33
33
|
surfaceType: z.ZodEnum<{
|
|
34
34
|
list: "list";
|
|
35
|
+
settings: "settings";
|
|
35
36
|
page: "page";
|
|
36
37
|
dashboard: "dashboard";
|
|
37
38
|
graph: "graph";
|
|
38
39
|
detail: "detail";
|
|
39
|
-
settings: "settings";
|
|
40
40
|
}>;
|
|
41
41
|
description: z.ZodOptional<z.ZodString>;
|
|
42
42
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -175,6 +175,15 @@ declare const FeatureSchema: z.ZodObject<{
|
|
|
175
175
|
declare const PROJECTS_FEATURE_ID: "projects";
|
|
176
176
|
declare const PROJECTS_INDEX_SURFACE_ID: "projects.index";
|
|
177
177
|
declare const DELIVERY_PROJECTS_VIEW_CAPABILITY_ID: "delivery.projects.view";
|
|
178
|
+
declare const CRM_FEATURE_ID: "crm";
|
|
179
|
+
declare const LEAD_GEN_FEATURE_ID: "lead-gen";
|
|
180
|
+
declare const OPERATIONS_FEATURE_ID: "operations";
|
|
181
|
+
declare const MONITORING_FEATURE_ID: "monitoring";
|
|
182
|
+
declare const SETTINGS_FEATURE_ID: "settings";
|
|
183
|
+
declare const SEO_FEATURE_ID: "seo";
|
|
184
|
+
declare const CRM_PIPELINE_SURFACE_ID: "crm.pipeline";
|
|
185
|
+
declare const LEAD_GEN_LISTS_SURFACE_ID: "lead-gen.lists";
|
|
186
|
+
declare const OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID: "operations.organization-graph";
|
|
178
187
|
|
|
179
188
|
declare const OrganizationModelBrandingSchema: z.ZodObject<{
|
|
180
189
|
organizationName: z.ZodString;
|
|
@@ -274,11 +283,11 @@ declare const SurfaceDefinitionSchema: z.ZodObject<{
|
|
|
274
283
|
path: z.ZodString;
|
|
275
284
|
surfaceType: z.ZodEnum<{
|
|
276
285
|
list: "list";
|
|
286
|
+
settings: "settings";
|
|
277
287
|
page: "page";
|
|
278
288
|
dashboard: "dashboard";
|
|
279
289
|
graph: "graph";
|
|
280
290
|
detail: "detail";
|
|
281
|
-
settings: "settings";
|
|
282
291
|
}>;
|
|
283
292
|
description: z.ZodOptional<z.ZodString>;
|
|
284
293
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -298,11 +307,11 @@ declare const OrganizationModelNavigationSchema: z.ZodObject<{
|
|
|
298
307
|
path: z.ZodString;
|
|
299
308
|
surfaceType: z.ZodEnum<{
|
|
300
309
|
list: "list";
|
|
310
|
+
settings: "settings";
|
|
301
311
|
page: "page";
|
|
302
312
|
dashboard: "dashboard";
|
|
303
313
|
graph: "graph";
|
|
304
314
|
detail: "detail";
|
|
305
|
-
settings: "settings";
|
|
306
315
|
}>;
|
|
307
316
|
description: z.ZodOptional<z.ZodString>;
|
|
308
317
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -383,7 +392,7 @@ interface FoundationBranding {
|
|
|
383
392
|
productName: string;
|
|
384
393
|
shortName: string;
|
|
385
394
|
}
|
|
386
|
-
declare function createFoundationOrganizationModel(
|
|
395
|
+
declare function createFoundationOrganizationModel(override: DeepPartial<OrganizationModel>): {
|
|
387
396
|
canonical: OrganizationModel;
|
|
388
397
|
model: FoundationOrganizationModel;
|
|
389
398
|
homeLabel: string;
|
|
@@ -391,5 +400,5 @@ declare function createFoundationOrganizationModel(branding: FoundationBranding)
|
|
|
391
400
|
getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined;
|
|
392
401
|
};
|
|
393
402
|
|
|
394
|
-
export { DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
403
|
+
export { CRM_FEATURE_ID, CRM_PIPELINE_SURFACE_ID, DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, LEAD_GEN_FEATURE_ID, LEAD_GEN_LISTS_SURFACE_ID, MONITORING_FEATURE_ID, OPERATIONS_FEATURE_ID, OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, SEO_FEATURE_ID, SETTINGS_FEATURE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
395
404
|
export type { DeepPartial, FoundationBranding, FoundationNavigationSurface, FoundationOrganizationModel, FoundationSurfaceIcon, FoundationSurfaceType, OrganizationModel, OrganizationModelBranding, OrganizationModelCrm, OrganizationModelDelivery, OrganizationModelFeature, OrganizationModelLeadGen, OrganizationModelNavigation, OrganizationModelResourceMapping, OrganizationModelSurface };
|
|
@@ -168,6 +168,15 @@ var DEFAULT_ORGANIZATION_MODEL_LEAD_GEN = {
|
|
|
168
168
|
var PROJECTS_FEATURE_ID = "projects";
|
|
169
169
|
var PROJECTS_INDEX_SURFACE_ID = "projects.index";
|
|
170
170
|
var DELIVERY_PROJECTS_VIEW_CAPABILITY_ID = "delivery.projects.view";
|
|
171
|
+
var CRM_FEATURE_ID = "crm";
|
|
172
|
+
var LEAD_GEN_FEATURE_ID = "lead-gen";
|
|
173
|
+
var OPERATIONS_FEATURE_ID = "operations";
|
|
174
|
+
var MONITORING_FEATURE_ID = "monitoring";
|
|
175
|
+
var SETTINGS_FEATURE_ID = "settings";
|
|
176
|
+
var SEO_FEATURE_ID = "seo";
|
|
177
|
+
var CRM_PIPELINE_SURFACE_ID = "crm.pipeline";
|
|
178
|
+
var LEAD_GEN_LISTS_SURFACE_ID = "lead-gen.lists";
|
|
179
|
+
var OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID = "operations.organization-graph";
|
|
171
180
|
|
|
172
181
|
// src/organization-model/domains/navigation.ts
|
|
173
182
|
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]);
|
|
@@ -707,24 +716,24 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
707
716
|
version: 1,
|
|
708
717
|
features: [
|
|
709
718
|
{
|
|
710
|
-
id:
|
|
719
|
+
id: CRM_FEATURE_ID,
|
|
711
720
|
label: "CRM",
|
|
712
721
|
description: "Relationship pipeline and deal management",
|
|
713
722
|
enabled: true,
|
|
714
723
|
color: "blue",
|
|
715
724
|
entityIds: ["crm.deal"],
|
|
716
|
-
surfaceIds: [
|
|
725
|
+
surfaceIds: [CRM_PIPELINE_SURFACE_ID],
|
|
717
726
|
resourceIds: [],
|
|
718
727
|
capabilityIds: ["crm.pipeline.manage"]
|
|
719
728
|
},
|
|
720
729
|
{
|
|
721
|
-
id:
|
|
730
|
+
id: LEAD_GEN_FEATURE_ID,
|
|
722
731
|
label: "Lead Gen",
|
|
723
732
|
description: "Prospecting, qualification, and outreach preparation",
|
|
724
733
|
enabled: true,
|
|
725
734
|
color: "cyan",
|
|
726
735
|
entityIds: ["leadgen.list", "leadgen.company", "leadgen.contact"],
|
|
727
|
-
surfaceIds: [
|
|
736
|
+
surfaceIds: [LEAD_GEN_LISTS_SURFACE_ID],
|
|
728
737
|
resourceIds: [],
|
|
729
738
|
capabilityIds: ["leadgen.lists.manage"]
|
|
730
739
|
},
|
|
@@ -740,14 +749,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
740
749
|
capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
|
|
741
750
|
},
|
|
742
751
|
{
|
|
743
|
-
id:
|
|
752
|
+
id: OPERATIONS_FEATURE_ID,
|
|
744
753
|
label: "Operations",
|
|
745
754
|
description: "Operational resources, topology, and orchestration visibility",
|
|
746
755
|
enabled: true,
|
|
747
756
|
color: "violet",
|
|
748
757
|
entityIds: [],
|
|
749
758
|
surfaceIds: [
|
|
750
|
-
|
|
759
|
+
OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID,
|
|
751
760
|
"operations.command-view",
|
|
752
761
|
"operations.overview",
|
|
753
762
|
"operations.resources",
|
|
@@ -759,7 +768,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
759
768
|
capabilityIds: ["operations.organization-graph", "operations.command-view"]
|
|
760
769
|
},
|
|
761
770
|
{
|
|
762
|
-
id:
|
|
771
|
+
id: MONITORING_FEATURE_ID,
|
|
763
772
|
label: "Monitoring",
|
|
764
773
|
enabled: true,
|
|
765
774
|
entityIds: [],
|
|
@@ -774,7 +783,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
774
783
|
capabilityIds: []
|
|
775
784
|
},
|
|
776
785
|
{
|
|
777
|
-
id:
|
|
786
|
+
id: SETTINGS_FEATURE_ID,
|
|
778
787
|
label: "Settings",
|
|
779
788
|
enabled: true,
|
|
780
789
|
entityIds: [],
|
|
@@ -791,7 +800,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
791
800
|
capabilityIds: []
|
|
792
801
|
},
|
|
793
802
|
{
|
|
794
|
-
id:
|
|
803
|
+
id: SEO_FEATURE_ID,
|
|
795
804
|
label: "SEO",
|
|
796
805
|
enabled: false,
|
|
797
806
|
entityIds: [],
|
|
@@ -856,8 +865,8 @@ function resolveOrganizationModel(override) {
|
|
|
856
865
|
}
|
|
857
866
|
|
|
858
867
|
// src/organization-model/foundation.ts
|
|
859
|
-
function createFoundationOrganizationModel(
|
|
860
|
-
const canonical = resolveOrganizationModel(
|
|
868
|
+
function createFoundationOrganizationModel(override) {
|
|
869
|
+
const canonical = resolveOrganizationModel(override);
|
|
861
870
|
function requireCoreSurface(surfaceId) {
|
|
862
871
|
const surface = canonical.navigation.surfaces.find((candidate) => candidate.id === surfaceId);
|
|
863
872
|
if (!surface) {
|
|
@@ -912,4 +921,4 @@ function createFoundationOrganizationModel(branding) {
|
|
|
912
921
|
};
|
|
913
922
|
}
|
|
914
923
|
|
|
915
|
-
export { DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
|
924
|
+
export { CRM_FEATURE_ID, CRM_PIPELINE_SURFACE_ID, DEFAULT_ORGANIZATION_MODEL, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, FeatureSchema, LEAD_GEN_FEATURE_ID, LEAD_GEN_LISTS_SURFACE_ID, MONITORING_FEATURE_ID, OPERATIONS_FEATURE_ID, OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, SEO_FEATURE_ID, SETTINGS_FEATURE_ID, createFoundationOrganizationModel, defineOrganizationModel, resolveOrganizationModel };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elevasis/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Minimal shared constants across Elevasis monorepo",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"./organization-model": {
|
|
20
20
|
"types": "./dist/organization-model/index.d.ts",
|
|
21
21
|
"import": "./dist/organization-model/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./entities": {
|
|
24
|
+
"types": "./dist/business/entities-published.d.ts",
|
|
25
|
+
"import": "./dist/business/entities-published.js"
|
|
22
26
|
}
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
@@ -13,6 +13,6 @@ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as {
|
|
|
13
13
|
describe('core publish surface', () => {
|
|
14
14
|
it('publishes the curated @elevasis/core organization-model wrapper', () => {
|
|
15
15
|
expect(packageJson.publishConfig?.name).toBe('@elevasis/core')
|
|
16
|
-
expect(Object.keys(packageJson.publishConfig?.exports ?? {})).toEqual(['.', './organization-model'])
|
|
16
|
+
expect(Object.keys(packageJson.publishConfig?.exports ?? {})).toEqual(['.', './organization-model', './entities'])
|
|
17
17
|
})
|
|
18
18
|
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Entities
|
|
2
|
+
|
|
3
|
+
Published base entity contracts for the Elevasis platform. Each entity ships as a TypeScript interface, a matching Zod schema, and an inferred `Input` type, generic over a `<TMeta>` extension slot.
|
|
4
|
+
|
|
5
|
+
External projects extend these in `foundations/types/entities.ts` to attach project-specific metadata while keeping the canonical shape stable.
|
|
6
|
+
|
|
7
|
+
## Published Exports
|
|
8
|
+
|
|
9
|
+
The published entry point exposes six entity contracts:
|
|
10
|
+
|
|
11
|
+
- `BaseProject<TMeta>`, `BaseProjectSchema`, `BaseProjectInput`
|
|
12
|
+
- `BaseMilestone<TMeta>`, `BaseMilestoneSchema`, `BaseMilestoneInput`
|
|
13
|
+
- `BaseTask<TMeta>`, `BaseTaskSchema`, `BaseTaskInput`
|
|
14
|
+
- `BaseDeal<TMeta>`, `BaseDealSchema`, `BaseDealInput`
|
|
15
|
+
- `BaseCompany<TMeta>`, `BaseCompanySchema`, `BaseCompanyInput`
|
|
16
|
+
- `BaseContact<TMeta>`, `BaseContactSchema`, `BaseContactInput`
|
|
17
|
+
|
|
18
|
+
Import them from the published subpath:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { BaseDealSchema, type BaseDeal } from '@elevasis/core/entities'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Extension Pattern
|
|
25
|
+
|
|
26
|
+
Each base interface accepts a generic metadata type. Extend the schema with `.extend({ metadata: ... })` and infer the type with `BaseProject<z.infer<typeof MetaSchema>>`.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { z } from 'zod'
|
|
30
|
+
import { BaseProjectSchema, type BaseProject } from '@elevasis/core/entities'
|
|
31
|
+
|
|
32
|
+
const ProjectMetaSchema = z.object({
|
|
33
|
+
budget: z.number().int().nonnegative(),
|
|
34
|
+
clientPriority: z.enum(['low', 'medium', 'high'])
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
export const ProjectSchema = BaseProjectSchema.extend({ metadata: ProjectMetaSchema })
|
|
38
|
+
export type Project = BaseProject<z.infer<typeof ProjectMetaSchema>>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use the base shape as-is when no extension is needed:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
export const DealSchema = BaseDealSchema
|
|
45
|
+
export type Deal = BaseDeal
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Recipe
|
|
49
|
+
|
|
50
|
+
The full pattern is documented in the SDK scaffold bundle: `node_modules/@elevasis/sdk/reference/scaffold/recipes/extend-a-base-entity.md`.
|
|
51
|
+
|
|
52
|
+
The canonical template demo lives at `external/_template/foundations/types/entities.ts`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
|
|
3
|
+
describe('entities-published barrel', () => {
|
|
4
|
+
it('exports all base entity Zod schemas', async () => {
|
|
5
|
+
const barrel = await import('../entities-published')
|
|
6
|
+
|
|
7
|
+
expect(barrel.BaseProjectSchema).toBeDefined()
|
|
8
|
+
expect(barrel.BaseMilestoneSchema).toBeDefined()
|
|
9
|
+
expect(barrel.BaseTaskSchema).toBeDefined()
|
|
10
|
+
expect(barrel.BaseDealSchema).toBeDefined()
|
|
11
|
+
expect(barrel.BaseCompanySchema).toBeDefined()
|
|
12
|
+
expect(barrel.BaseContactSchema).toBeDefined()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('round-trips a valid project through the barrel-exported schema', async () => {
|
|
16
|
+
const { BaseProjectSchema } = await import('../entities-published')
|
|
17
|
+
|
|
18
|
+
const validProject = {
|
|
19
|
+
id: '00000000-0000-0000-0000-000000000010',
|
|
20
|
+
organizationId: '00000000-0000-0000-0000-000000000001',
|
|
21
|
+
name: 'Website Rebuild',
|
|
22
|
+
kind: 'client_engagement',
|
|
23
|
+
status: 'active',
|
|
24
|
+
description: 'Rebuild the client website.',
|
|
25
|
+
metadata: { budget: 50000 },
|
|
26
|
+
createdAt: '2026-04-17T00:00:00.000Z',
|
|
27
|
+
updatedAt: '2026-04-17T00:00:00.000Z'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const result = BaseProjectSchema.safeParse(validProject)
|
|
31
|
+
expect(result.success).toBe(true)
|
|
32
|
+
})
|
|
33
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Public re-export barrel for @elevasis/core/entities (and @repo/core/entities internally)
|
|
2
|
+
export type {
|
|
3
|
+
BaseProject,
|
|
4
|
+
BaseMilestone,
|
|
5
|
+
BaseTask,
|
|
6
|
+
BaseDeal,
|
|
7
|
+
BaseCompany,
|
|
8
|
+
BaseContact,
|
|
9
|
+
BaseProjectInput,
|
|
10
|
+
BaseMilestoneInput,
|
|
11
|
+
BaseTaskInput,
|
|
12
|
+
BaseDealInput,
|
|
13
|
+
BaseCompanyInput,
|
|
14
|
+
BaseContactInput
|
|
15
|
+
} from './base-entities'
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
BaseProjectSchema,
|
|
19
|
+
BaseMilestoneSchema,
|
|
20
|
+
BaseTaskSchema,
|
|
21
|
+
BaseDealSchema,
|
|
22
|
+
BaseCompanySchema,
|
|
23
|
+
BaseContactSchema
|
|
24
|
+
} from './base-entities'
|
|
@@ -34,9 +34,8 @@ import type {
|
|
|
34
34
|
* Run: pnpm test attio-crud.integration.test.ts
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
describe.skipIf(SKIP_TESTS)('Attio CRUD Integration Tests', () => {
|
|
37
|
+
// Attio integration currently unused -- tests skipped unconditionally.
|
|
38
|
+
describe.skip('Attio CRUD Integration Tests', () => {
|
|
40
39
|
const adapter = new AttioAdapter()
|
|
41
40
|
const organizationId = 'f9aa5a56-8c13-4cd1-9161-8827ae7b452b'
|
|
42
41
|
const credentialName = 'elevasis-attio'
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { createFoundationOrganizationModel } from '../foundation'
|
|
3
|
+
|
|
4
|
+
describe('createFoundationOrganizationModel', () => {
|
|
5
|
+
it('builds the foundation model from a branding-only override', () => {
|
|
6
|
+
const result = createFoundationOrganizationModel({
|
|
7
|
+
branding: { organizationName: 'Acme', productName: 'Acme OS', shortName: 'Acme' }
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
expect(result.canonical.branding.organizationName).toBe('Acme')
|
|
11
|
+
expect(result.homeLabel).toBe('Dashboard')
|
|
12
|
+
expect(result.model.navigation.defaultSurfaceId).toBe('operations')
|
|
13
|
+
|
|
14
|
+
const surfaces = result.model.navigation.surfaces
|
|
15
|
+
expect(surfaces.find((s) => s.id === 'crm')).toBeDefined()
|
|
16
|
+
expect(surfaces.find((s) => s.id === 'lead-gen')).toBeDefined()
|
|
17
|
+
expect(surfaces.find((s) => s.id === 'projects')).toBeDefined()
|
|
18
|
+
expect(surfaces.find((s) => s.id === 'operations')).toBeDefined()
|
|
19
|
+
expect(surfaces.find((s) => s.id === 'settings')).toBeDefined()
|
|
20
|
+
|
|
21
|
+
expect(result.quickAccessSurfaceIds).toContain('operations')
|
|
22
|
+
expect(result.quickAccessSurfaceIds).toContain('projects')
|
|
23
|
+
expect(result.quickAccessSurfaceIds).toContain('lead-gen')
|
|
24
|
+
expect(result.quickAccessSurfaceIds).toContain('crm')
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('passes deeper overrides through to the canonical model', () => {
|
|
28
|
+
const result = createFoundationOrganizationModel({
|
|
29
|
+
branding: { organizationName: 'Acme', productName: 'Acme OS', shortName: 'Acme' },
|
|
30
|
+
crm: {
|
|
31
|
+
pipelines: [
|
|
32
|
+
{
|
|
33
|
+
id: 'custom-pipeline',
|
|
34
|
+
label: 'Custom Pipeline',
|
|
35
|
+
description: 'A custom pipeline',
|
|
36
|
+
entityId: 'crm.deal',
|
|
37
|
+
stages: [
|
|
38
|
+
{
|
|
39
|
+
id: 'stage-1',
|
|
40
|
+
label: 'Stage 1',
|
|
41
|
+
color: 'blue',
|
|
42
|
+
order: 0,
|
|
43
|
+
semanticClass: 'open' as const,
|
|
44
|
+
surfaceIds: ['crm.pipeline'],
|
|
45
|
+
resourceIds: []
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
expect(result.canonical.crm.pipelines).toHaveLength(1)
|
|
54
|
+
expect(result.canonical.crm.pipelines[0]?.id).toBe('custom-pipeline')
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('exposes a working getOrganizationSurface lookup', () => {
|
|
58
|
+
const result = createFoundationOrganizationModel({
|
|
59
|
+
branding: { organizationName: 'Acme', productName: 'Acme OS', shortName: 'Acme' }
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const crmSurface = result.getOrganizationSurface('crm')
|
|
63
|
+
expect(crmSurface).toBeDefined()
|
|
64
|
+
expect(crmSurface?.id).toBe('crm')
|
|
65
|
+
expect(crmSurface?.icon).toBe('crm')
|
|
66
|
+
|
|
67
|
+
expect(result.getOrganizationSurface('nonexistent')).toBeUndefined()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('throws when a required core surface is missing', () => {
|
|
71
|
+
const override = {
|
|
72
|
+
features: [
|
|
73
|
+
{
|
|
74
|
+
id: 'crm',
|
|
75
|
+
label: 'CRM',
|
|
76
|
+
description: 'CRM workspace',
|
|
77
|
+
enabled: true,
|
|
78
|
+
color: 'blue',
|
|
79
|
+
entityIds: [],
|
|
80
|
+
surfaceIds: ['custom.home'],
|
|
81
|
+
resourceIds: [],
|
|
82
|
+
capabilityIds: []
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
navigation: {
|
|
86
|
+
defaultSurfaceId: 'custom.home',
|
|
87
|
+
surfaces: [
|
|
88
|
+
{
|
|
89
|
+
id: 'custom.home',
|
|
90
|
+
label: 'Home',
|
|
91
|
+
path: '/home',
|
|
92
|
+
surfaceType: 'page' as const,
|
|
93
|
+
featureIds: ['crm'],
|
|
94
|
+
entityIds: [],
|
|
95
|
+
resourceIds: [],
|
|
96
|
+
capabilityIds: []
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
groups: [{ id: 'primary', label: 'Primary', placement: 'primary', surfaceIds: ['custom.home'] }]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
expect(() => createFoundationOrganizationModel(override)).toThrow(/Missing organization surface/)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
export const PROJECTS_FEATURE_ID = 'projects' as const
|
|
2
2
|
export const PROJECTS_INDEX_SURFACE_ID = 'projects.index' as const
|
|
3
3
|
export const DELIVERY_PROJECTS_VIEW_CAPABILITY_ID = 'delivery.projects.view' as const
|
|
4
|
+
|
|
5
|
+
export const CRM_FEATURE_ID = 'crm' as const
|
|
6
|
+
export const LEAD_GEN_FEATURE_ID = 'lead-gen' as const
|
|
7
|
+
export const OPERATIONS_FEATURE_ID = 'operations' as const
|
|
8
|
+
export const MONITORING_FEATURE_ID = 'monitoring' as const
|
|
9
|
+
export const SETTINGS_FEATURE_ID = 'settings' as const
|
|
10
|
+
export const SEO_FEATURE_ID = 'seo' as const
|
|
11
|
+
|
|
12
|
+
export const CRM_PIPELINE_SURFACE_ID = 'crm.pipeline' as const
|
|
13
|
+
export const LEAD_GEN_LISTS_SURFACE_ID = 'lead-gen.lists' as const
|
|
14
|
+
export const OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID = 'operations.organization-graph' as const
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { OrganizationModel } from './types'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CRM_FEATURE_ID,
|
|
4
|
+
CRM_PIPELINE_SURFACE_ID,
|
|
5
|
+
DELIVERY_PROJECTS_VIEW_CAPABILITY_ID,
|
|
6
|
+
LEAD_GEN_FEATURE_ID,
|
|
7
|
+
LEAD_GEN_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'
|
|
3
16
|
import { DEFAULT_ORGANIZATION_MODEL_BRANDING } from './domains/branding'
|
|
4
17
|
import { DEFAULT_ORGANIZATION_MODEL_CRM } from './domains/crm'
|
|
5
18
|
import { DEFAULT_ORGANIZATION_MODEL_DELIVERY } from './domains/delivery'
|
|
@@ -10,24 +23,24 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
|
|
|
10
23
|
version: 1,
|
|
11
24
|
features: [
|
|
12
25
|
{
|
|
13
|
-
id:
|
|
26
|
+
id: CRM_FEATURE_ID,
|
|
14
27
|
label: 'CRM',
|
|
15
28
|
description: 'Relationship pipeline and deal management',
|
|
16
29
|
enabled: true,
|
|
17
30
|
color: 'blue',
|
|
18
31
|
entityIds: ['crm.deal'],
|
|
19
|
-
surfaceIds: [
|
|
32
|
+
surfaceIds: [CRM_PIPELINE_SURFACE_ID],
|
|
20
33
|
resourceIds: [],
|
|
21
34
|
capabilityIds: ['crm.pipeline.manage']
|
|
22
35
|
},
|
|
23
36
|
{
|
|
24
|
-
id:
|
|
37
|
+
id: LEAD_GEN_FEATURE_ID,
|
|
25
38
|
label: 'Lead Gen',
|
|
26
39
|
description: 'Prospecting, qualification, and outreach preparation',
|
|
27
40
|
enabled: true,
|
|
28
41
|
color: 'cyan',
|
|
29
42
|
entityIds: ['leadgen.list', 'leadgen.company', 'leadgen.contact'],
|
|
30
|
-
surfaceIds: [
|
|
43
|
+
surfaceIds: [LEAD_GEN_LISTS_SURFACE_ID],
|
|
31
44
|
resourceIds: [],
|
|
32
45
|
capabilityIds: ['leadgen.lists.manage']
|
|
33
46
|
},
|
|
@@ -43,14 +56,14 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
|
|
|
43
56
|
capabilityIds: [DELIVERY_PROJECTS_VIEW_CAPABILITY_ID]
|
|
44
57
|
},
|
|
45
58
|
{
|
|
46
|
-
id:
|
|
59
|
+
id: OPERATIONS_FEATURE_ID,
|
|
47
60
|
label: 'Operations',
|
|
48
61
|
description: 'Operational resources, topology, and orchestration visibility',
|
|
49
62
|
enabled: true,
|
|
50
63
|
color: 'violet',
|
|
51
64
|
entityIds: [],
|
|
52
65
|
surfaceIds: [
|
|
53
|
-
|
|
66
|
+
OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID,
|
|
54
67
|
'operations.command-view',
|
|
55
68
|
'operations.overview',
|
|
56
69
|
'operations.resources',
|
|
@@ -62,7 +75,7 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
|
|
|
62
75
|
capabilityIds: ['operations.organization-graph', 'operations.command-view']
|
|
63
76
|
},
|
|
64
77
|
{
|
|
65
|
-
id:
|
|
78
|
+
id: MONITORING_FEATURE_ID,
|
|
66
79
|
label: 'Monitoring',
|
|
67
80
|
enabled: true,
|
|
68
81
|
entityIds: [],
|
|
@@ -77,7 +90,7 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
|
|
|
77
90
|
capabilityIds: []
|
|
78
91
|
},
|
|
79
92
|
{
|
|
80
|
-
id:
|
|
93
|
+
id: SETTINGS_FEATURE_ID,
|
|
81
94
|
label: 'Settings',
|
|
82
95
|
enabled: true,
|
|
83
96
|
entityIds: [],
|
|
@@ -94,7 +107,7 @@ export const DEFAULT_ORGANIZATION_MODEL: OrganizationModel = {
|
|
|
94
107
|
capabilityIds: []
|
|
95
108
|
},
|
|
96
109
|
{
|
|
97
|
-
id:
|
|
110
|
+
id: SEO_FEATURE_ID,
|
|
98
111
|
label: 'SEO',
|
|
99
112
|
enabled: false,
|
|
100
113
|
entityIds: [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from './contracts'
|
|
2
2
|
import { resolveOrganizationModel } from './resolve'
|
|
3
|
-
import type { OrganizationModel, OrganizationModelSurface } from './types'
|
|
3
|
+
import type { DeepPartial, OrganizationModel, OrganizationModelSurface } from './types'
|
|
4
4
|
|
|
5
5
|
export type FoundationSurfaceType = OrganizationModelSurface['surfaceType']
|
|
6
6
|
|
|
@@ -25,14 +25,14 @@ export interface FoundationBranding {
|
|
|
25
25
|
shortName: string
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function createFoundationOrganizationModel(
|
|
28
|
+
export function createFoundationOrganizationModel(override: DeepPartial<OrganizationModel>): {
|
|
29
29
|
canonical: OrganizationModel
|
|
30
30
|
model: FoundationOrganizationModel
|
|
31
31
|
homeLabel: string
|
|
32
32
|
quickAccessSurfaceIds: readonly string[]
|
|
33
33
|
getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
|
|
34
34
|
} {
|
|
35
|
-
const canonical = resolveOrganizationModel(
|
|
35
|
+
const canonical = resolveOrganizationModel(override)
|
|
36
36
|
|
|
37
37
|
function requireCoreSurface(surfaceId: string): OrganizationModelSurface {
|
|
38
38
|
const surface = canonical.navigation.surfaces.find((candidate) => candidate.id === surfaceId)
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
export { OrganizationModelSchema } from './schema'
|
|
2
2
|
export { FeatureSchema } from './domains/features'
|
|
3
|
-
export {
|
|
3
|
+
export {
|
|
4
|
+
PROJECTS_FEATURE_ID,
|
|
5
|
+
PROJECTS_INDEX_SURFACE_ID,
|
|
6
|
+
DELIVERY_PROJECTS_VIEW_CAPABILITY_ID,
|
|
7
|
+
CRM_FEATURE_ID,
|
|
8
|
+
LEAD_GEN_FEATURE_ID,
|
|
9
|
+
OPERATIONS_FEATURE_ID,
|
|
10
|
+
MONITORING_FEATURE_ID,
|
|
11
|
+
SETTINGS_FEATURE_ID,
|
|
12
|
+
SEO_FEATURE_ID,
|
|
13
|
+
CRM_PIPELINE_SURFACE_ID,
|
|
14
|
+
LEAD_GEN_LISTS_SURFACE_ID,
|
|
15
|
+
OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID
|
|
16
|
+
} from './contracts'
|
|
4
17
|
export { DEFAULT_ORGANIZATION_MODEL } from './defaults'
|
|
5
18
|
export { defineOrganizationModel, resolveOrganizationModel } from './resolve'
|
|
6
19
|
export { createFoundationOrganizationModel } from './foundation'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Auto-generated on 2026-04-
|
|
1
|
+
<!-- Auto-generated on 2026-04-19T04:30:03.546Z by scripts/monorepo/generate-scaffold-contracts.js -->
|
|
2
2
|
---
|
|
3
3
|
title: Reference Contracts
|
|
4
4
|
description: Auto-generated TypeScript contracts for SDK consumers. Do not edit manually.
|