@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.
@@ -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(branding: FoundationBranding): {
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: "crm",
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: ["crm.pipeline"],
725
+ surfaceIds: [CRM_PIPELINE_SURFACE_ID],
717
726
  resourceIds: [],
718
727
  capabilityIds: ["crm.pipeline.manage"]
719
728
  },
720
729
  {
721
- id: "lead-gen",
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: ["lead-gen.lists"],
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: "operations",
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
- "operations.organization-graph",
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: "monitoring",
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: "settings",
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: "seo",
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(branding) {
860
- const canonical = resolveOrganizationModel({ branding });
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(branding: FoundationBranding): {
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: "crm",
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: ["crm.pipeline"],
725
+ surfaceIds: [CRM_PIPELINE_SURFACE_ID],
717
726
  resourceIds: [],
718
727
  capabilityIds: ["crm.pipeline.manage"]
719
728
  },
720
729
  {
721
- id: "lead-gen",
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: ["lead-gen.lists"],
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: "operations",
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
- "operations.organization-graph",
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: "monitoring",
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: "settings",
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: "seo",
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(branding) {
860
- const canonical = resolveOrganizationModel({ branding });
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.4.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
- const SKIP_TESTS = !process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_KEY || !process.env.SECRETS_ENCRYPTION_KEY
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 { DELIVERY_PROJECTS_VIEW_CAPABILITY_ID, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from './contracts'
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: 'crm',
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: ['crm.pipeline'],
32
+ surfaceIds: [CRM_PIPELINE_SURFACE_ID],
20
33
  resourceIds: [],
21
34
  capabilityIds: ['crm.pipeline.manage']
22
35
  },
23
36
  {
24
- id: 'lead-gen',
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: ['lead-gen.lists'],
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: 'operations',
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
- 'operations.organization-graph',
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: 'monitoring',
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: 'settings',
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: 'seo',
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(branding: FoundationBranding): {
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({ branding })
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 { PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID } from './contracts'
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,3 +1,3 @@
1
1
  export const VERSION = {
2
- CURRENT: '1.6.0'
2
+ CURRENT: '1.6.1'
3
3
  }
@@ -1,4 +1,4 @@
1
- <!-- Auto-generated on 2026-04-18T10:41:03.508Z by scripts/monorepo/generate-scaffold-contracts.js -->
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.