@elevasis/core 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +428 -42
- package/dist/index.js +596 -47
- package/dist/organization-model/index.d.ts +428 -42
- package/dist/organization-model/index.js +596 -47
- package/package.json +4 -3
- package/src/__tests__/template-foundations-compatibility.test.ts +2 -2
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1131 -0
- package/src/_gen/__tests__/scaffold-contracts.test.ts +53 -0
- package/src/_gen/scaffold-contracts.ts +45 -0
- package/src/business/acquisition/types.ts +2 -0
- package/src/commands/queue/types/task.ts +3 -3
- package/src/execution/engine/index.ts +8 -0
- package/src/execution/engine/tools/registry.ts +26 -24
- package/src/execution/engine/tools/tool-maps.ts +13 -9
- package/src/execution/engine/workflow/types.ts +2 -3
- package/src/index.ts +10 -0
- package/src/organization-model/README.md +16 -12
- package/src/organization-model/__tests__/defaults.test.ts +175 -0
- package/src/organization-model/__tests__/domains/customers.test.ts +295 -0
- package/src/organization-model/__tests__/domains/goals.test.ts +479 -0
- package/src/organization-model/__tests__/domains/identity.test.ts +279 -0
- package/src/organization-model/__tests__/domains/navigation.test.ts +212 -0
- package/src/organization-model/__tests__/domains/offerings.test.ts +419 -0
- package/src/organization-model/__tests__/domains/operations.test.ts +203 -0
- package/src/organization-model/__tests__/domains/resource-mappings.test.ts +362 -0
- package/src/organization-model/__tests__/domains/roles.test.ts +347 -0
- package/src/organization-model/__tests__/domains/statuses.test.ts +243 -0
- package/src/organization-model/__tests__/foundation.test.ts +3 -3
- package/src/organization-model/__tests__/resolve.test.ts +447 -3
- package/src/organization-model/__tests__/schema.test.ts +407 -0
- package/src/organization-model/contracts.ts +5 -5
- package/src/organization-model/defaults.ts +39 -16
- package/src/organization-model/domains/customers.ts +75 -0
- package/src/organization-model/domains/goals.ts +80 -0
- package/src/organization-model/domains/identity.ts +94 -0
- package/src/organization-model/domains/navigation.ts +43 -4
- package/src/organization-model/domains/offerings.ts +66 -0
- package/src/organization-model/domains/operations.ts +85 -0
- package/src/organization-model/domains/{delivery.ts → projects.ts} +6 -6
- package/src/organization-model/domains/{lead-gen.ts → prospecting.ts} +5 -5
- package/src/organization-model/domains/roles.ts +55 -0
- package/src/organization-model/domains/sales.ts +94 -0
- package/src/organization-model/domains/shared.ts +30 -1
- package/src/organization-model/domains/statuses.ts +130 -0
- package/src/organization-model/index.ts +3 -3
- package/src/organization-model/organization-graph.mdx +1 -0
- package/src/organization-model/organization-model.mdx +84 -19
- package/src/organization-model/published.ts +53 -8
- package/src/organization-model/schema.ts +67 -7
- package/src/organization-model/types.ts +31 -7
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/registry/types.ts +1 -1
- package/src/projects/api-schemas.ts +1 -0
- package/src/reference/_generated/contracts.md +116 -8
- package/src/reference/glossary.md +25 -4
- package/src/requests/__tests__/api-schemas.test.ts +277 -0
- package/src/requests/api-schemas.ts +83 -0
- package/src/requests/index.ts +1 -0
- package/src/scaffold-registry/__tests__/schema.test.ts +280 -0
- package/src/scaffold-registry/index.ts +194 -0
- package/src/scaffold-registry/schema.ts +144 -0
- package/src/supabase/database.types.ts +158 -6
- package/src/organization-model/domains/crm.ts +0 -46
- /package/src/business/{delivery → projects}/index.ts +0 -0
- /package/src/business/{delivery → projects}/types.ts +0 -0
- /package/src/business/{crm → sales}/api-schemas.ts +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Measurable outcome schema — one trackable result that supports a goal.
|
|
5
|
+
// The field name `keyResults` is used for compatibility with OKR tooling;
|
|
6
|
+
// user-facing surfaces and documentation MUST say "measurable outcomes",
|
|
7
|
+
// never "key results" or "OKR".
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
export const KeyResultSchema = z.object({
|
|
11
|
+
/** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
|
|
12
|
+
id: z.string().trim().min(1).max(100),
|
|
13
|
+
/** Plain-language description of this measurable outcome (e.g. "Increase trial-to-paid conversion"). */
|
|
14
|
+
description: z.string().trim().min(1).max(500),
|
|
15
|
+
/**
|
|
16
|
+
* What is being measured — the metric name (e.g. "monthly revenue", "NPS score",
|
|
17
|
+
* "trial-to-paid conversion rate"). Free-form string.
|
|
18
|
+
*/
|
|
19
|
+
targetMetric: z.string().trim().min(1).max(200),
|
|
20
|
+
/** Current measured value. Defaults to 0 when not yet tracked. */
|
|
21
|
+
currentValue: z.number().default(0),
|
|
22
|
+
/**
|
|
23
|
+
* Target value to reach for this measurable outcome to be considered achieved.
|
|
24
|
+
* Optional — omit if the outcome is directional (e.g. "reduce churn") without
|
|
25
|
+
* a hard numeric target.
|
|
26
|
+
*/
|
|
27
|
+
targetValue: z.number().optional()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Objective schema — one goal the organization is working toward.
|
|
32
|
+
// User-facing label is "goal"; this schema type is named Objective for
|
|
33
|
+
// structural continuity with OKR tooling. Do NOT expose "OKR", "objective",
|
|
34
|
+
// or "key result" in any user-facing label or documentation.
|
|
35
|
+
//
|
|
36
|
+
// Period fields use ISO 8601 date strings (YYYY-MM-DD). Cross-schema
|
|
37
|
+
// validation (periodEnd > periodStart) is enforced in
|
|
38
|
+
// `OrganizationModelSchema.superRefine()`.
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
|
|
42
|
+
|
|
43
|
+
export const ObjectiveSchema = z.object({
|
|
44
|
+
/** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
|
|
45
|
+
id: z.string().trim().min(1).max(100),
|
|
46
|
+
/** Plain-language description of what the organization wants to achieve. */
|
|
47
|
+
description: z.string().trim().min(1).max(1000),
|
|
48
|
+
/**
|
|
49
|
+
* Start of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
|
|
50
|
+
* Must be strictly before `periodEnd`.
|
|
51
|
+
*/
|
|
52
|
+
periodStart: z.string().regex(ISO_DATE_REGEX, 'periodStart must be an ISO date string (YYYY-MM-DD)'),
|
|
53
|
+
/**
|
|
54
|
+
* End of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
|
|
55
|
+
* Must be strictly after `periodStart`.
|
|
56
|
+
* Enforced via `OrganizationModelSchema.superRefine()`.
|
|
57
|
+
*/
|
|
58
|
+
periodEnd: z.string().regex(ISO_DATE_REGEX, 'periodEnd must be an ISO date string (YYYY-MM-DD)'),
|
|
59
|
+
/**
|
|
60
|
+
* List of measurable outcomes that define success for this goal.
|
|
61
|
+
* Defaults to empty array so goals can be declared before outcomes are defined.
|
|
62
|
+
*/
|
|
63
|
+
keyResults: z.array(KeyResultSchema).default([])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Goals domain schema — a collection of goals the organization is pursuing.
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
export const GoalsDomainSchema = z.object({
|
|
71
|
+
objectives: z.array(ObjectiveSchema).default([])
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Seed — empty by default; adapters populate with real goal definitions.
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
export const DEFAULT_ORGANIZATION_MODEL_GOALS: z.infer<typeof GoalsDomainSchema> = {
|
|
79
|
+
objectives: []
|
|
80
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Business hours — simplest shape that captures weekday ranges.
|
|
5
|
+
// Each day of the week is optional; when present it holds open/close times
|
|
6
|
+
// in "HH:MM" 24-hour format. An empty object (default) means "not configured".
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
export const BusinessHoursDaySchema = z.object({
|
|
10
|
+
open: z
|
|
11
|
+
.string()
|
|
12
|
+
.trim()
|
|
13
|
+
.regex(/^\d{2}:\d{2}$/, 'Expected HH:MM format'),
|
|
14
|
+
close: z
|
|
15
|
+
.string()
|
|
16
|
+
.trim()
|
|
17
|
+
.regex(/^\d{2}:\d{2}$/, 'Expected HH:MM format')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export const BusinessHoursSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
monday: BusinessHoursDaySchema.optional(),
|
|
23
|
+
tuesday: BusinessHoursDaySchema.optional(),
|
|
24
|
+
wednesday: BusinessHoursDaySchema.optional(),
|
|
25
|
+
thursday: BusinessHoursDaySchema.optional(),
|
|
26
|
+
friday: BusinessHoursDaySchema.optional(),
|
|
27
|
+
saturday: BusinessHoursDaySchema.optional(),
|
|
28
|
+
sunday: BusinessHoursDaySchema.optional()
|
|
29
|
+
})
|
|
30
|
+
.default({})
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Identity domain schema — legal identity, mission/vision, industry anchors,
|
|
34
|
+
// and temporal/geographic context. Distinct from branding (display identity).
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
export const IdentityDomainSchema = z.object({
|
|
38
|
+
/** Why the organization exists — one or two plain-language sentences. */
|
|
39
|
+
mission: z.string().trim().max(1000).default(''),
|
|
40
|
+
/** Long-term direction the organization is moving toward. */
|
|
41
|
+
vision: z.string().trim().max(1000).default(''),
|
|
42
|
+
/** Legal registered name of the entity. */
|
|
43
|
+
legalName: z.string().trim().max(200).default(''),
|
|
44
|
+
/**
|
|
45
|
+
* Type of legal entity (e.g. "LLC", "Corporation", "Sole Proprietor",
|
|
46
|
+
* "Non-profit"). Free-form string so it covers any jurisdiction.
|
|
47
|
+
*/
|
|
48
|
+
entityType: z.string().trim().max(100).default(''),
|
|
49
|
+
/**
|
|
50
|
+
* Primary jurisdiction of registration or operation
|
|
51
|
+
* (e.g. "United States – Delaware", "Canada – Ontario").
|
|
52
|
+
*/
|
|
53
|
+
jurisdiction: z.string().trim().max(200).default(''),
|
|
54
|
+
/**
|
|
55
|
+
* Industry category — broad classification (e.g. "Marketing Agency",
|
|
56
|
+
* "Software / SaaS", "Professional Services").
|
|
57
|
+
*/
|
|
58
|
+
industryCategory: z.string().trim().max(200).default(''),
|
|
59
|
+
/**
|
|
60
|
+
* Geographic focus — where the organization primarily operates or serves
|
|
61
|
+
* (e.g. "North America", "Global", "Southeast Asia").
|
|
62
|
+
*/
|
|
63
|
+
geographicFocus: z.string().trim().max(200).default(''),
|
|
64
|
+
/**
|
|
65
|
+
* IANA timezone identifier for the organization's primary operating timezone
|
|
66
|
+
* (e.g. "America/Los_Angeles", "Europe/London", "UTC").
|
|
67
|
+
*/
|
|
68
|
+
timeZone: z.string().trim().max(100).default('UTC'),
|
|
69
|
+
/** Typical operating hours per day of week. Empty object means not configured. */
|
|
70
|
+
businessHours: BusinessHoursSchema,
|
|
71
|
+
/**
|
|
72
|
+
* Long-form markdown capturing client context, problem narrative, and domain
|
|
73
|
+
* background. Populated by /setup; surfaced to agents as organizational context.
|
|
74
|
+
* Optional — many projects have no external client.
|
|
75
|
+
*/
|
|
76
|
+
clientBrief: z.string().trim().default('')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Seed — placeholder defaults; external adapters override per organization.
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
export const DEFAULT_ORGANIZATION_MODEL_IDENTITY: z.infer<typeof IdentityDomainSchema> = {
|
|
84
|
+
mission: '',
|
|
85
|
+
vision: '',
|
|
86
|
+
legalName: '',
|
|
87
|
+
entityType: '',
|
|
88
|
+
jurisdiction: '',
|
|
89
|
+
industryCategory: '',
|
|
90
|
+
geographicFocus: '',
|
|
91
|
+
timeZone: 'UTC',
|
|
92
|
+
businessHours: {},
|
|
93
|
+
clientBrief: ''
|
|
94
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
|
-
import {
|
|
2
|
+
import { PROJECTS_VIEW_CAPABILITY_ID, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID } from '../contracts'
|
|
3
3
|
import { DescriptionSchema, IconNameSchema, LabelSchema, ModelIdSchema, PathSchema, ReferenceIdsSchema } from './shared'
|
|
4
4
|
|
|
5
5
|
export const SurfaceTypeSchema = z.enum(['page', 'dashboard', 'graph', 'detail', 'list', 'settings'])
|
|
@@ -20,10 +20,23 @@ export const SurfaceDefinitionSchema = z.object({
|
|
|
20
20
|
parentId: ModelIdSchema.optional()
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Core placement values: 'primary' | 'secondary' | 'bottom'.
|
|
25
|
+
*
|
|
26
|
+
* `placement` is intentionally open (`z.string()`) so that per-project adapters can
|
|
27
|
+
* introduce additional placement IDs (e.g. 'pinned', 'spotlight', 'contextual') without
|
|
28
|
+
* forking core. Extension pattern: add the new string literal to the project's
|
|
29
|
+
* `foundations/config/organization-model.ts` adapter — no changes to this file required.
|
|
30
|
+
*
|
|
31
|
+
* `surfaceType` and `resourceType` remain closed enums (UI/runtime invariants).
|
|
32
|
+
*/
|
|
33
|
+
export const CORE_PLACEMENT_VALUES = ['primary', 'secondary', 'bottom'] as const
|
|
34
|
+
export type CorePlacement = (typeof CORE_PLACEMENT_VALUES)[number]
|
|
35
|
+
|
|
23
36
|
export const NavigationGroupSchema = z.object({
|
|
24
37
|
id: ModelIdSchema,
|
|
25
38
|
label: LabelSchema,
|
|
26
|
-
placement: z.
|
|
39
|
+
placement: z.string().trim().min(1).max(50),
|
|
27
40
|
surfaceIds: z.array(ModelIdSchema).default([])
|
|
28
41
|
})
|
|
29
42
|
|
|
@@ -70,7 +83,7 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
|
|
|
70
83
|
featureIds: [PROJECTS_FEATURE_ID],
|
|
71
84
|
entityIds: ['delivery.project'],
|
|
72
85
|
resourceIds: [],
|
|
73
|
-
capabilityIds: [
|
|
86
|
+
capabilityIds: [PROJECTS_VIEW_CAPABILITY_ID]
|
|
74
87
|
},
|
|
75
88
|
{
|
|
76
89
|
id: 'operations.organization-graph',
|
|
@@ -216,6 +229,30 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
|
|
|
216
229
|
resourceIds: [],
|
|
217
230
|
capabilityIds: []
|
|
218
231
|
},
|
|
232
|
+
{
|
|
233
|
+
id: 'submitted-requests.list',
|
|
234
|
+
label: 'Submitted Requests',
|
|
235
|
+
path: '/monitoring/requests',
|
|
236
|
+
surfaceType: 'list',
|
|
237
|
+
enabled: true,
|
|
238
|
+
featureId: 'submitted-requests',
|
|
239
|
+
featureIds: ['submitted-requests'],
|
|
240
|
+
entityIds: ['reported_request'],
|
|
241
|
+
resourceIds: [],
|
|
242
|
+
capabilityIds: []
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
id: 'submitted-requests.detail',
|
|
246
|
+
label: 'Request Detail',
|
|
247
|
+
path: '/monitoring/requests/:requestId',
|
|
248
|
+
surfaceType: 'detail',
|
|
249
|
+
enabled: true,
|
|
250
|
+
featureId: 'submitted-requests',
|
|
251
|
+
featureIds: ['submitted-requests'],
|
|
252
|
+
entityIds: ['reported_request'],
|
|
253
|
+
resourceIds: [],
|
|
254
|
+
capabilityIds: []
|
|
255
|
+
},
|
|
219
256
|
{
|
|
220
257
|
id: 'settings.account',
|
|
221
258
|
label: 'Account',
|
|
@@ -331,7 +368,9 @@ export const DEFAULT_ORGANIZATION_MODEL_NAVIGATION: z.infer<typeof OrganizationM
|
|
|
331
368
|
'monitoring.execution-logs',
|
|
332
369
|
'monitoring.execution-health',
|
|
333
370
|
'monitoring.cost-analytics',
|
|
334
|
-
'monitoring.notifications'
|
|
371
|
+
'monitoring.notifications',
|
|
372
|
+
'submitted-requests.list',
|
|
373
|
+
'submitted-requests.detail'
|
|
335
374
|
]
|
|
336
375
|
},
|
|
337
376
|
{
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Pricing model — the four canonical pricing structures used in B2B SaaS and
|
|
5
|
+
// professional services. "custom" covers bespoke / negotiated pricing.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
export const PricingModelSchema = z.enum(['one-time', 'subscription', 'usage-based', 'custom'])
|
|
9
|
+
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Product schema — one entry per distinct offering (product or service).
|
|
12
|
+
// Modeled after Business Model Canvas "Value Propositions" and company profile
|
|
13
|
+
// product/service catalog language. Fields use plain English throughout.
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
export const ProductSchema = z.object({
|
|
17
|
+
/** Stable unique identifier for the product (e.g. "product-starter-plan"). */
|
|
18
|
+
id: z.string().trim().min(1).max(100),
|
|
19
|
+
/** Human-readable name shown to agents and in UI (e.g. "Starter Plan"). */
|
|
20
|
+
name: z.string().trim().max(200).default(''),
|
|
21
|
+
/** One or two sentences describing what this product/service delivers. */
|
|
22
|
+
description: z.string().trim().max(2000).default(''),
|
|
23
|
+
/**
|
|
24
|
+
* How this product is priced:
|
|
25
|
+
* - "one-time" — single purchase (setup fee, project fee)
|
|
26
|
+
* - "subscription" — recurring (monthly/annual SaaS, retainer)
|
|
27
|
+
* - "usage-based" — metered by consumption (API calls, seats)
|
|
28
|
+
* - "custom" — negotiated or bespoke pricing
|
|
29
|
+
*/
|
|
30
|
+
pricingModel: PricingModelSchema.default('custom'),
|
|
31
|
+
/** Base price amount (≥ 0). Currency unit defined by `currency`. */
|
|
32
|
+
price: z.number().min(0).default(0),
|
|
33
|
+
/**
|
|
34
|
+
* ISO 4217 currency code (e.g. "USD", "EUR", "GBP").
|
|
35
|
+
* Free-form string to accommodate any currency; defaults to "USD".
|
|
36
|
+
*/
|
|
37
|
+
currency: z.string().trim().max(10).default('USD'),
|
|
38
|
+
/**
|
|
39
|
+
* IDs of customer segments this product targets.
|
|
40
|
+
* Each id must reference a declared `customers.segments[].id`.
|
|
41
|
+
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
42
|
+
*/
|
|
43
|
+
targetSegmentIds: z.array(z.string().trim().min(1)).default([]),
|
|
44
|
+
/**
|
|
45
|
+
* Optional: ID of the platform feature responsible for delivering this product.
|
|
46
|
+
* When present, must reference a declared `features[].id`.
|
|
47
|
+
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
48
|
+
*/
|
|
49
|
+
deliveryFeatureId: z.string().trim().min(1).optional()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Offerings domain schema — a collection of products and services.
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
export const OfferingsDomainSchema = z.object({
|
|
57
|
+
products: z.array(ProductSchema).default([])
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Seed — empty by default; adapters populate with real product definitions.
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
export const DEFAULT_ORGANIZATION_MODEL_OFFERINGS: z.infer<typeof OfferingsDomainSchema> = {
|
|
65
|
+
products: []
|
|
66
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Semantic class enum — one value per stateful runtime entity category.
|
|
5
|
+
// Every operation entry declares which category it belongs to via semanticClass.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
export const OperationSemanticClassSchema = z.enum(['queue', 'executions', 'sessions', 'notifications', 'schedules'])
|
|
9
|
+
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Operation entry schema
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
export const OperationEntrySchema = z.object({
|
|
15
|
+
id: z.string().trim().min(1).max(100),
|
|
16
|
+
label: z.string().trim().min(1).max(120),
|
|
17
|
+
semanticClass: OperationSemanticClassSchema,
|
|
18
|
+
/** Optional reference to the feature that owns this runtime entity. */
|
|
19
|
+
featureId: z.string().trim().min(1).max(100).optional(),
|
|
20
|
+
/**
|
|
21
|
+
* Optional pointer to the status semanticClass values that apply to this
|
|
22
|
+
* entity — ties operations back to the statuses domain for vibe rendering.
|
|
23
|
+
*/
|
|
24
|
+
supportedStatusSemanticClass: z.array(z.string().trim().min(1).max(80)).optional()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Domain schema — a flat array of operation entries
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
export const OperationsDomainSchema = z.object({
|
|
32
|
+
entries: z.array(OperationEntrySchema).default([])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Seed — one entry per stateful runtime entity category.
|
|
37
|
+
// Categories: queue (HITL), executions, sessions, notifications, schedules.
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
export const DEFAULT_ORGANIZATION_MODEL_OPERATIONS: z.infer<typeof OperationsDomainSchema> = {
|
|
41
|
+
entries: [
|
|
42
|
+
// --- queue (HITL command queue) ---
|
|
43
|
+
{
|
|
44
|
+
id: 'operations.queue',
|
|
45
|
+
label: 'HITL Queue',
|
|
46
|
+
semanticClass: 'queue',
|
|
47
|
+
featureId: 'operations',
|
|
48
|
+
supportedStatusSemanticClass: ['queue']
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// --- executions (workflow / agent executions) ---
|
|
52
|
+
{
|
|
53
|
+
id: 'operations.executions',
|
|
54
|
+
label: 'Executions',
|
|
55
|
+
semanticClass: 'executions',
|
|
56
|
+
featureId: 'operations',
|
|
57
|
+
supportedStatusSemanticClass: ['execution']
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// --- sessions (agent conversation sessions) ---
|
|
61
|
+
{
|
|
62
|
+
id: 'operations.sessions',
|
|
63
|
+
label: 'Sessions',
|
|
64
|
+
semanticClass: 'sessions',
|
|
65
|
+
featureId: 'operations'
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// --- notifications (platform in-app notifications) ---
|
|
69
|
+
{
|
|
70
|
+
id: 'operations.notifications',
|
|
71
|
+
label: 'Notifications',
|
|
72
|
+
semanticClass: 'notifications',
|
|
73
|
+
featureId: 'monitoring'
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// --- schedules (task scheduler) ---
|
|
77
|
+
{
|
|
78
|
+
id: 'operations.schedules',
|
|
79
|
+
label: 'Schedules',
|
|
80
|
+
semanticClass: 'schedules',
|
|
81
|
+
featureId: 'operations',
|
|
82
|
+
supportedStatusSemanticClass: ['schedule', 'schedule.run']
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { DisplayMetadataSchema, ModelIdSchema } from './shared'
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
|
|
5
5
|
id: ModelIdSchema,
|
|
6
6
|
order: z.number().int().min(0)
|
|
7
7
|
})
|
|
8
8
|
|
|
9
|
-
export const
|
|
9
|
+
export const OrganizationModelProjectsSchema = z.object({
|
|
10
10
|
projectEntityId: ModelIdSchema,
|
|
11
11
|
milestoneEntityId: ModelIdSchema,
|
|
12
12
|
taskEntityId: ModelIdSchema,
|
|
13
|
-
projectStatuses: z.array(
|
|
14
|
-
milestoneStatuses: z.array(
|
|
15
|
-
taskStatuses: z.array(
|
|
13
|
+
projectStatuses: z.array(ProjectsDomainStateSchema).min(1),
|
|
14
|
+
milestoneStatuses: z.array(ProjectsDomainStateSchema).min(1),
|
|
15
|
+
taskStatuses: z.array(ProjectsDomainStateSchema).min(1)
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
-
export const
|
|
18
|
+
export const DEFAULT_ORGANIZATION_MODEL_PROJECTS: z.infer<typeof OrganizationModelProjectsSchema> = {
|
|
19
19
|
projectEntityId: 'delivery.project',
|
|
20
20
|
milestoneEntityId: 'delivery.milestone',
|
|
21
21
|
taskEntityId: 'delivery.task',
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { DescriptionSchema, DisplayMetadataSchema, ModelIdSchema } from './shared'
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
|
|
5
5
|
id: ModelIdSchema,
|
|
6
6
|
order: z.number().int().min(0)
|
|
7
7
|
})
|
|
8
8
|
|
|
9
|
-
export const
|
|
9
|
+
export const OrganizationModelProspectingSchema = z.object({
|
|
10
10
|
listEntityId: ModelIdSchema,
|
|
11
11
|
companyEntityId: ModelIdSchema,
|
|
12
12
|
contactEntityId: ModelIdSchema,
|
|
13
13
|
description: DescriptionSchema.optional(),
|
|
14
|
-
companyStages: z.array(
|
|
15
|
-
contactStages: z.array(
|
|
14
|
+
companyStages: z.array(ProspectingLifecycleStageSchema).min(1),
|
|
15
|
+
contactStages: z.array(ProspectingLifecycleStageSchema).min(1)
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
-
export const
|
|
18
|
+
export const DEFAULT_ORGANIZATION_MODEL_PROSPECTING: z.infer<typeof OrganizationModelProspectingSchema> = {
|
|
19
19
|
listEntityId: 'leadgen.list',
|
|
20
20
|
companyEntityId: 'leadgen.company',
|
|
21
21
|
contactEntityId: 'leadgen.contact',
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Role schema — one entry per distinct role in the organization's chart.
|
|
5
|
+
// Inspired by the EOS Accountability Chart but uses plain-language field names
|
|
6
|
+
// throughout. No EOS jargon: "title" (not seatTitle), "responsibilities"
|
|
7
|
+
// (not accountabilities), "reportsToId", "heldBy".
|
|
8
|
+
//
|
|
9
|
+
// Cross-reference: `reportsToId` (when present) must resolve to another
|
|
10
|
+
// `roles[].id` in the same collection. Enforcement is via
|
|
11
|
+
// `OrganizationModelSchema.superRefine()` — not at the individual schema level.
|
|
12
|
+
// Cycle detection is NOT enforced (known limitation; document if needed).
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
export const RoleSchema = z.object({
|
|
16
|
+
/** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
|
|
17
|
+
id: z.string().trim().min(1).max(100),
|
|
18
|
+
/** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
|
|
19
|
+
title: z.string().trim().min(1).max(200),
|
|
20
|
+
/**
|
|
21
|
+
* List of responsibilities this role owns — plain-language descriptions of
|
|
22
|
+
* what the person in this role is accountable for delivering.
|
|
23
|
+
* Defaults to empty array so minimal role definitions stay concise.
|
|
24
|
+
*/
|
|
25
|
+
responsibilities: z.array(z.string().trim().max(500)).default([]),
|
|
26
|
+
/**
|
|
27
|
+
* Optional: ID of another role this role reports to.
|
|
28
|
+
* When present, must reference another `roles[].id` in the same organization.
|
|
29
|
+
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
30
|
+
* Absence indicates a top-level role (no reporting line).
|
|
31
|
+
*/
|
|
32
|
+
reportsToId: z.string().trim().min(1).max(100).optional(),
|
|
33
|
+
/**
|
|
34
|
+
* Optional: name or email of the person currently holding this role.
|
|
35
|
+
* Free-form string — supports "Alice Johnson", "alice@example.com", or
|
|
36
|
+
* any human-readable identifier. Not validated against any user registry.
|
|
37
|
+
*/
|
|
38
|
+
heldBy: z.string().trim().max(200).optional()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Roles domain schema — a collection of roles.
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
export const RolesDomainSchema = z.object({
|
|
46
|
+
roles: z.array(RoleSchema).default([])
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Seed — empty by default; adapters populate with real role definitions.
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
export const DEFAULT_ORGANIZATION_MODEL_ROLES: z.infer<typeof RolesDomainSchema> = {
|
|
54
|
+
roles: []
|
|
55
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { DescriptionSchema, DisplayMetadataSchema, ModelIdSchema, ReferenceIdsSchema } from './shared'
|
|
3
|
+
|
|
4
|
+
export const SalesStageSemanticClassSchema = z.enum(['open', 'active', 'nurturing', 'closed_won', 'closed_lost'])
|
|
5
|
+
|
|
6
|
+
export const SalesStageSchema = DisplayMetadataSchema.extend({
|
|
7
|
+
id: ModelIdSchema,
|
|
8
|
+
order: z.number().int().min(0),
|
|
9
|
+
semanticClass: SalesStageSemanticClassSchema,
|
|
10
|
+
surfaceIds: ReferenceIdsSchema,
|
|
11
|
+
resourceIds: ReferenceIdsSchema
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export const SalesPipelineSchema = z.object({
|
|
15
|
+
id: ModelIdSchema,
|
|
16
|
+
label: z.string().trim().min(1).max(120),
|
|
17
|
+
description: DescriptionSchema.optional(),
|
|
18
|
+
entityId: ModelIdSchema,
|
|
19
|
+
stages: z.array(SalesStageSchema).min(1)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export const OrganizationModelSalesSchema = z.object({
|
|
23
|
+
entityId: ModelIdSchema,
|
|
24
|
+
defaultPipelineId: ModelIdSchema,
|
|
25
|
+
pipelines: z.array(SalesPipelineSchema).min(1)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export const DEFAULT_ORGANIZATION_MODEL_SALES: z.infer<typeof OrganizationModelSalesSchema> = {
|
|
29
|
+
entityId: 'crm.deal',
|
|
30
|
+
defaultPipelineId: 'default',
|
|
31
|
+
pipelines: [
|
|
32
|
+
{
|
|
33
|
+
id: 'default',
|
|
34
|
+
label: 'Default Pipeline',
|
|
35
|
+
entityId: 'crm.deal',
|
|
36
|
+
stages: [
|
|
37
|
+
{
|
|
38
|
+
id: 'interested',
|
|
39
|
+
label: 'Interested',
|
|
40
|
+
color: 'blue',
|
|
41
|
+
order: 1,
|
|
42
|
+
semanticClass: 'open',
|
|
43
|
+
surfaceIds: ['crm.pipeline'],
|
|
44
|
+
resourceIds: []
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'proposal',
|
|
48
|
+
label: 'Proposal',
|
|
49
|
+
color: 'yellow',
|
|
50
|
+
order: 2,
|
|
51
|
+
semanticClass: 'active',
|
|
52
|
+
surfaceIds: ['crm.pipeline'],
|
|
53
|
+
resourceIds: []
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'closing',
|
|
57
|
+
label: 'Closing',
|
|
58
|
+
color: 'lime',
|
|
59
|
+
order: 3,
|
|
60
|
+
semanticClass: 'active',
|
|
61
|
+
surfaceIds: ['crm.pipeline'],
|
|
62
|
+
resourceIds: []
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'closed_won',
|
|
66
|
+
label: 'Closed Won',
|
|
67
|
+
color: 'green',
|
|
68
|
+
order: 4,
|
|
69
|
+
semanticClass: 'closed_won',
|
|
70
|
+
surfaceIds: ['crm.pipeline'],
|
|
71
|
+
resourceIds: []
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'closed_lost',
|
|
75
|
+
label: 'Closed Lost',
|
|
76
|
+
color: 'red',
|
|
77
|
+
order: 5,
|
|
78
|
+
semanticClass: 'closed_lost',
|
|
79
|
+
surfaceIds: ['crm.pipeline'],
|
|
80
|
+
resourceIds: []
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'nurturing',
|
|
84
|
+
label: 'Nurturing',
|
|
85
|
+
color: 'grape',
|
|
86
|
+
order: 6,
|
|
87
|
+
semanticClass: 'nurturing',
|
|
88
|
+
surfaceIds: ['crm.pipeline'],
|
|
89
|
+
resourceIds: []
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
@@ -22,6 +22,33 @@ export const DisplayMetadataSchema = z.object({
|
|
|
22
22
|
icon: IconNameSchema.optional()
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// TechStack subsection — optional extension on a ResourceMapping entry that
|
|
27
|
+
// captures external-SaaS integration metadata: which platform, its purpose,
|
|
28
|
+
// credential health, and whether it is the system of record for its domain.
|
|
29
|
+
// Backward-compatible: existing entries without this key parse cleanly.
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
export const TechStackEntrySchema = z.object({
|
|
33
|
+
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
34
|
+
platform: z.string().trim().min(1).max(200),
|
|
35
|
+
/** Free-form description of what this integration is used for. */
|
|
36
|
+
purpose: z.string().trim().min(1).max(500),
|
|
37
|
+
/**
|
|
38
|
+
* Health of the credential backing this integration.
|
|
39
|
+
* - configured: credential present and valid
|
|
40
|
+
* - pending: not yet set up
|
|
41
|
+
* - expired: credential existed but has lapsed
|
|
42
|
+
* - missing: expected but not present
|
|
43
|
+
*/
|
|
44
|
+
credentialStatus: z.enum(['configured', 'pending', 'expired', 'missing']),
|
|
45
|
+
/**
|
|
46
|
+
* Whether this integration is the primary system of record for its domain
|
|
47
|
+
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
48
|
+
*/
|
|
49
|
+
isSystemOfRecord: z.boolean().default(false)
|
|
50
|
+
})
|
|
51
|
+
|
|
25
52
|
export const ResourceMappingSchema = DisplayMetadataSchema.extend({
|
|
26
53
|
id: ModelIdSchema,
|
|
27
54
|
resourceId: z.string().trim().min(1).max(255),
|
|
@@ -29,5 +56,7 @@ export const ResourceMappingSchema = DisplayMetadataSchema.extend({
|
|
|
29
56
|
featureIds: ReferenceIdsSchema,
|
|
30
57
|
entityIds: ReferenceIdsSchema,
|
|
31
58
|
surfaceIds: ReferenceIdsSchema,
|
|
32
|
-
capabilityIds: ReferenceIdsSchema
|
|
59
|
+
capabilityIds: ReferenceIdsSchema,
|
|
60
|
+
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
61
|
+
techStack: TechStackEntrySchema.optional()
|
|
33
62
|
})
|