@elevasis/core 0.22.0 → 0.23.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 +2330 -2391
- package/dist/index.js +2322 -1147
- package/dist/knowledge/index.d.ts +702 -1136
- package/dist/knowledge/index.js +9 -9
- package/dist/organization-model/index.d.ts +2330 -2391
- package/dist/organization-model/index.js +2322 -1147
- package/dist/test-utils/index.d.ts +703 -1106
- package/dist/test-utils/index.js +1735 -1089
- package/package.json +1 -1
- package/src/__tests__/template-core-compatibility.test.ts +11 -79
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +360 -98
- package/src/business/acquisition/api-schemas.test.ts +2 -2
- package/src/business/acquisition/api-schemas.ts +7 -9
- package/src/business/acquisition/build-templates.test.ts +4 -4
- package/src/business/acquisition/build-templates.ts +72 -30
- package/src/business/acquisition/crm-state-actions.test.ts +13 -11
- package/src/business/acquisition/types.ts +7 -3
- package/src/execution/engine/agent/core/types.ts +1 -1
- package/src/execution/engine/workflow/types.ts +2 -2
- package/src/knowledge/README.md +8 -7
- package/src/knowledge/__tests__/queries.test.ts +74 -73
- package/src/knowledge/format.ts +10 -9
- package/src/knowledge/index.ts +1 -1
- package/src/knowledge/published.ts +1 -1
- package/src/knowledge/queries.ts +26 -25
- package/src/organization-model/README.md +66 -26
- package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
- package/src/organization-model/__tests__/defaults.test.ts +72 -98
- package/src/organization-model/__tests__/domains/actions.test.ts +56 -0
- package/src/organization-model/__tests__/domains/customers.test.ts +299 -295
- package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
- package/src/organization-model/__tests__/domains/goals.test.ts +493 -479
- package/src/organization-model/__tests__/domains/identity.test.ts +280 -279
- package/src/organization-model/__tests__/domains/navigation.test.ts +268 -212
- package/src/organization-model/__tests__/domains/offerings.test.ts +414 -419
- package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
- package/src/organization-model/__tests__/domains/resource-mappings.test.ts +271 -271
- package/src/organization-model/__tests__/domains/resources.test.ts +159 -37
- package/src/organization-model/__tests__/domains/roles.test.ts +147 -86
- package/src/organization-model/__tests__/domains/statuses.test.ts +246 -243
- package/src/organization-model/__tests__/domains/systems.test.ts +67 -51
- package/src/organization-model/__tests__/flatten-additive-merge.test.ts +361 -0
- package/src/organization-model/__tests__/foundation.test.ts +74 -102
- package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
- package/src/organization-model/__tests__/graph.test.ts +899 -71
- package/src/organization-model/__tests__/knowledge.test.ts +173 -52
- package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
- package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +36 -27
- package/src/organization-model/__tests__/recursive-system-schema.test.ts +520 -0
- package/src/organization-model/__tests__/resolve.test.ts +174 -23
- package/src/organization-model/__tests__/schema.test.ts +291 -114
- package/src/organization-model/__tests__/surface-projection.test.ts +207 -97
- package/src/organization-model/catalogs/lead-gen.ts +144 -0
- package/src/organization-model/content-kinds/config.ts +36 -0
- package/src/organization-model/content-kinds/index.ts +74 -0
- package/src/organization-model/content-kinds/pipeline.ts +68 -0
- package/src/organization-model/content-kinds/registry.ts +44 -0
- package/src/organization-model/content-kinds/status.ts +71 -0
- package/src/organization-model/content-kinds/template.ts +83 -0
- package/src/organization-model/content-kinds/types.ts +117 -0
- package/src/organization-model/contracts.ts +13 -3
- package/src/organization-model/defaults.ts +488 -96
- package/src/organization-model/domains/actions.ts +239 -0
- package/src/organization-model/domains/customers.ts +78 -75
- package/src/organization-model/domains/entities.ts +144 -0
- package/src/organization-model/domains/goals.ts +83 -80
- package/src/organization-model/domains/knowledge.ts +74 -16
- package/src/organization-model/domains/navigation.ts +107 -384
- package/src/organization-model/domains/offerings.ts +71 -66
- package/src/organization-model/domains/policies.ts +102 -0
- package/src/organization-model/domains/projects.ts +14 -48
- package/src/organization-model/domains/prospecting.ts +62 -181
- package/src/organization-model/domains/resources.ts +81 -24
- package/src/organization-model/domains/roles.ts +13 -10
- package/src/organization-model/domains/sales.ts +10 -219
- package/src/organization-model/domains/shared.ts +57 -57
- package/src/organization-model/domains/statuses.ts +339 -130
- package/src/organization-model/domains/systems.ts +186 -29
- package/src/organization-model/foundation.ts +54 -67
- package/src/organization-model/graph/build.ts +682 -54
- package/src/organization-model/graph/link.ts +1 -1
- package/src/organization-model/graph/schema.ts +24 -9
- package/src/organization-model/graph/types.ts +20 -7
- package/src/organization-model/helpers.ts +231 -26
- package/src/organization-model/index.ts +116 -5
- package/src/organization-model/migration-helpers.ts +249 -0
- package/src/organization-model/organization-graph.mdx +16 -15
- package/src/organization-model/organization-model.mdx +89 -41
- package/src/organization-model/published.ts +120 -18
- package/src/organization-model/resolve.ts +117 -54
- package/src/organization-model/schema.ts +561 -140
- package/src/organization-model/surface-projection.ts +116 -122
- package/src/organization-model/types.ts +102 -21
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/registry/__tests__/command-view.test.ts +6 -8
- package/src/platform/registry/__tests__/resource-link.test.ts +13 -8
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +16 -31
- package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
- package/src/platform/registry/__tests__/resource-registry.test.ts +9 -7
- package/src/platform/registry/__tests__/validation.test.ts +15 -11
- package/src/platform/registry/resource-registry.ts +20 -8
- package/src/platform/registry/serialization.ts +7 -7
- package/src/platform/registry/types.ts +3 -3
- package/src/platform/registry/validation.ts +17 -15
- package/src/reference/_generated/contracts.md +362 -99
- package/src/reference/glossary.md +18 -18
- package/src/supabase/database.types.ts +60 -0
- package/src/test-utils/test-utils.test.ts +1 -6
- package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
- package/src/organization-model/domains/features.ts +0 -31
- package/src/organization-model/domains/operations.ts +0 -85
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { ModelIdSchema } from './shared'
|
|
3
|
-
import {
|
|
3
|
+
import { SystemPathSchema, SystemLifecycleSchema } from './systems'
|
|
4
|
+
import { ActionInvocationSchema } from './actions'
|
|
4
5
|
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// Resources domain
|
|
@@ -9,9 +10,16 @@ import { SystemIdSchema } from './systems'
|
|
|
9
10
|
// Resources are governance-only OM descriptors. Runtime code imports these
|
|
10
11
|
// descriptors and attaches executable behavior; it does not re-author identity.
|
|
11
12
|
|
|
12
|
-
export const ResourceKindSchema = z
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
export const ResourceKindSchema = z
|
|
14
|
+
.enum(['workflow', 'agent', 'integration', 'script'])
|
|
15
|
+
.meta({ label: 'Resource kind', color: 'orange' })
|
|
16
|
+
export const ResourceGovernanceStatusSchema = z
|
|
17
|
+
.enum(['active', 'deprecated', 'archived'])
|
|
18
|
+
.meta({ label: 'Governance status', color: 'teal' })
|
|
19
|
+
export const AgentKindSchema = z
|
|
20
|
+
.enum(['orchestrator', 'specialist', 'utility', 'platform'])
|
|
21
|
+
.meta({ label: 'Agent kind', color: 'violet' })
|
|
22
|
+
export const ScriptResourceLanguageSchema = z.enum(['shell', 'sql', 'typescript', 'python']).meta({ label: 'Language' })
|
|
15
23
|
|
|
16
24
|
export const ResourceIdSchema = z
|
|
17
25
|
.string()
|
|
@@ -20,20 +28,48 @@ export const ResourceIdSchema = z
|
|
|
20
28
|
.max(255)
|
|
21
29
|
.regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, 'Resource IDs must use letters, numbers, -, _, or . separators')
|
|
22
30
|
|
|
31
|
+
export const EventIdSchema = z
|
|
32
|
+
.string()
|
|
33
|
+
.trim()
|
|
34
|
+
.min(1)
|
|
35
|
+
.max(300)
|
|
36
|
+
.regex(
|
|
37
|
+
/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*:[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
38
|
+
'Event IDs must use <owner-id>:<event-key>'
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
export const EventKeySchema = ModelIdSchema
|
|
42
|
+
|
|
43
|
+
export const EventEmissionDescriptorSchema = z.object({
|
|
44
|
+
eventKey: EventKeySchema,
|
|
45
|
+
label: z.string().trim().min(1).max(120),
|
|
46
|
+
payloadSchema: ModelIdSchema.optional(),
|
|
47
|
+
lifecycle: SystemLifecycleSchema.optional()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
export const EventDescriptorSchema = EventEmissionDescriptorSchema.extend({
|
|
51
|
+
id: EventIdSchema,
|
|
52
|
+
ownerId: z.union([ResourceIdSchema, ModelIdSchema]),
|
|
53
|
+
ownerKind: z.enum(['resource', 'entity']).meta({ label: 'Owner kind' })
|
|
54
|
+
})
|
|
55
|
+
|
|
23
56
|
const ResourceEntryBaseSchema = z.object({
|
|
24
57
|
/** Canonical resource id; runtime resourceId derives from this value. */
|
|
25
58
|
id: ResourceIdSchema,
|
|
26
|
-
/**
|
|
27
|
-
|
|
59
|
+
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
60
|
+
order: z.number().default(0),
|
|
61
|
+
/** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
|
|
62
|
+
systemPath: SystemPathSchema.meta({ ref: 'system' }),
|
|
28
63
|
/** Optional role responsible for maintaining this resource. */
|
|
29
|
-
ownerRoleId: ModelIdSchema.optional(),
|
|
64
|
+
ownerRoleId: ModelIdSchema.meta({ ref: 'role' }).optional(),
|
|
30
65
|
status: ResourceGovernanceStatusSchema
|
|
31
66
|
})
|
|
32
67
|
|
|
33
68
|
export const WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
34
69
|
kind: z.literal('workflow'),
|
|
35
|
-
/** Mirrors WorkflowConfig.
|
|
36
|
-
|
|
70
|
+
/** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
|
|
71
|
+
actionKey: z.string().trim().min(1).max(255).optional(),
|
|
72
|
+
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
37
73
|
})
|
|
38
74
|
|
|
39
75
|
export const AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
@@ -41,9 +77,12 @@ export const AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
|
41
77
|
/** Mirrors code-side AgentConfig.kind. */
|
|
42
78
|
agentKind: AgentKindSchema,
|
|
43
79
|
/** Role this agent embodies, if any. */
|
|
44
|
-
actsAsRoleId: ModelIdSchema.optional(),
|
|
80
|
+
actsAsRoleId: ModelIdSchema.meta({ ref: 'role' }).optional(),
|
|
45
81
|
/** Mirrors AgentConfig.sessionCapable. */
|
|
46
|
-
sessionCapable: z.boolean()
|
|
82
|
+
sessionCapable: z.boolean(),
|
|
83
|
+
/** Broad/composite callable entry points orchestrated by this agent. */
|
|
84
|
+
invocations: z.array(ActionInvocationSchema).default([]),
|
|
85
|
+
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
47
86
|
})
|
|
48
87
|
|
|
49
88
|
export const IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
@@ -51,38 +90,56 @@ export const IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
|
51
90
|
provider: z.string().trim().min(1).max(100)
|
|
52
91
|
})
|
|
53
92
|
|
|
93
|
+
export const ScriptResourceSourceSchema = z.union([
|
|
94
|
+
z.string().trim().min(1).max(50_000),
|
|
95
|
+
z.object({
|
|
96
|
+
file: z.string().trim().min(1).max(500)
|
|
97
|
+
})
|
|
98
|
+
])
|
|
99
|
+
|
|
100
|
+
export const ScriptResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
101
|
+
kind: z.literal('script'),
|
|
102
|
+
language: ScriptResourceLanguageSchema,
|
|
103
|
+
source: ScriptResourceSourceSchema
|
|
104
|
+
})
|
|
105
|
+
|
|
54
106
|
export const ResourceEntrySchema = z.discriminatedUnion('kind', [
|
|
55
107
|
WorkflowResourceEntrySchema,
|
|
56
108
|
AgentResourceEntrySchema,
|
|
57
|
-
IntegrationResourceEntrySchema
|
|
109
|
+
IntegrationResourceEntrySchema,
|
|
110
|
+
ScriptResourceEntrySchema
|
|
58
111
|
])
|
|
59
112
|
|
|
60
|
-
export const ResourcesDomainSchema = z
|
|
61
|
-
|
|
62
|
-
|
|
113
|
+
export const ResourcesDomainSchema = z
|
|
114
|
+
.record(z.string(), ResourceEntrySchema)
|
|
115
|
+
.refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
116
|
+
message: 'Each resource entry id must match its map key'
|
|
117
|
+
})
|
|
118
|
+
.default({})
|
|
63
119
|
|
|
64
|
-
export const DEFAULT_ORGANIZATION_MODEL_RESOURCES: z.infer<typeof ResourcesDomainSchema> = {
|
|
65
|
-
entries: []
|
|
66
|
-
}
|
|
120
|
+
export const DEFAULT_ORGANIZATION_MODEL_RESOURCES: z.infer<typeof ResourcesDomainSchema> = {}
|
|
67
121
|
|
|
68
122
|
export function defineResource<const TResource extends ResourceEntry>(resource: TResource): TResource {
|
|
69
123
|
return ResourceEntrySchema.parse(resource) as TResource
|
|
70
124
|
}
|
|
71
125
|
|
|
72
|
-
export function defineResources<const TResources extends Record<string, ResourceEntry>>(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
126
|
+
export function defineResources<const TResources extends Record<string, ResourceEntry>>(
|
|
127
|
+
resources: TResources
|
|
128
|
+
): TResources {
|
|
129
|
+
return Object.fromEntries(
|
|
130
|
+
Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
|
|
131
|
+
) as TResources
|
|
78
132
|
}
|
|
79
133
|
|
|
80
134
|
export type ResourceId = z.infer<typeof ResourceIdSchema>
|
|
81
135
|
export type ResourceKind = z.infer<typeof ResourceKindSchema>
|
|
82
136
|
export type ResourceGovernanceStatus = z.infer<typeof ResourceGovernanceStatusSchema>
|
|
83
137
|
export type ResourceAgentKind = z.infer<typeof AgentKindSchema>
|
|
138
|
+
export type ScriptResourceLanguage = z.infer<typeof ScriptResourceLanguageSchema>
|
|
139
|
+
export type ScriptResourceSource = z.infer<typeof ScriptResourceSourceSchema>
|
|
84
140
|
export type WorkflowResourceEntry = z.infer<typeof WorkflowResourceEntrySchema>
|
|
85
141
|
export type AgentResourceEntry = z.infer<typeof AgentResourceEntrySchema>
|
|
86
142
|
export type IntegrationResourceEntry = z.infer<typeof IntegrationResourceEntrySchema>
|
|
143
|
+
export type ScriptResourceEntry = z.infer<typeof ScriptResourceEntrySchema>
|
|
87
144
|
export type ResourceEntry = z.infer<typeof ResourceEntrySchema>
|
|
88
145
|
export type ResourcesDomain = z.infer<typeof ResourcesDomainSchema>
|
|
@@ -12,7 +12,7 @@ import { SystemIdSchema } from './systems'
|
|
|
12
12
|
// Cross-reference enforcement lives in `OrganizationModelSchema.superRefine()`:
|
|
13
13
|
// `reportsToId` must resolve to another Role, `responsibleFor` entries must
|
|
14
14
|
// resolve to Systems, and agent holders must resolve to Agent Resources.
|
|
15
|
-
//
|
|
15
|
+
// Role hierarchy cycle detection is also enforced at the model level.
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
|
|
18
18
|
export const RoleIdSchema = ModelIdSchema
|
|
@@ -24,7 +24,7 @@ export const HumanRoleHolderSchema = z.object({
|
|
|
24
24
|
|
|
25
25
|
export const AgentRoleHolderSchema = z.object({
|
|
26
26
|
kind: z.literal('agent'),
|
|
27
|
-
agentId: ResourceIdSchema
|
|
27
|
+
agentId: ResourceIdSchema.meta({ ref: 'resource' })
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
export const TeamRoleHolderSchema = z.object({
|
|
@@ -43,6 +43,8 @@ export const RoleHoldersSchema = z.union([RoleHolderSchema, z.array(RoleHolderSc
|
|
|
43
43
|
export const RoleSchema = z.object({
|
|
44
44
|
/** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
|
|
45
45
|
id: RoleIdSchema,
|
|
46
|
+
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
47
|
+
order: z.number(),
|
|
46
48
|
/** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
|
|
47
49
|
title: z.string().trim().min(1).max(200),
|
|
48
50
|
/**
|
|
@@ -55,7 +57,7 @@ export const RoleSchema = z.object({
|
|
|
55
57
|
* Optional: ID of another role this role reports to.
|
|
56
58
|
* When present, must reference another `roles[].id` in the same organization.
|
|
57
59
|
*/
|
|
58
|
-
reportsToId: RoleIdSchema.optional(),
|
|
60
|
+
reportsToId: RoleIdSchema.meta({ ref: 'role' }).optional(),
|
|
59
61
|
/**
|
|
60
62
|
* Optional: human, agent, or team holder currently filling this role.
|
|
61
63
|
* Agent holders reference OM Resource IDs and are validated at the model level.
|
|
@@ -65,24 +67,25 @@ export const RoleSchema = z.object({
|
|
|
65
67
|
* Optional Systems this role is accountable for.
|
|
66
68
|
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
67
69
|
*/
|
|
68
|
-
responsibleFor: z.array(SystemIdSchema).optional()
|
|
70
|
+
responsibleFor: z.array(SystemIdSchema.meta({ ref: 'system' })).optional()
|
|
69
71
|
})
|
|
70
72
|
|
|
71
73
|
// ---------------------------------------------------------------------------
|
|
72
74
|
// Roles domain schema - a collection of roles.
|
|
73
75
|
// ---------------------------------------------------------------------------
|
|
74
76
|
|
|
75
|
-
export const RolesDomainSchema = z
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
export const RolesDomainSchema = z
|
|
78
|
+
.record(z.string(), RoleSchema)
|
|
79
|
+
.refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
80
|
+
message: 'Each role entry id must match its map key'
|
|
81
|
+
})
|
|
82
|
+
.default({})
|
|
78
83
|
|
|
79
84
|
// ---------------------------------------------------------------------------
|
|
80
85
|
// Seed - empty by default; adapters populate with real role definitions.
|
|
81
86
|
// ---------------------------------------------------------------------------
|
|
82
87
|
|
|
83
|
-
export const DEFAULT_ORGANIZATION_MODEL_ROLES: z.infer<typeof RolesDomainSchema> = {
|
|
84
|
-
roles: []
|
|
85
|
-
}
|
|
88
|
+
export const DEFAULT_ORGANIZATION_MODEL_ROLES: z.infer<typeof RolesDomainSchema> = {}
|
|
86
89
|
|
|
87
90
|
export type RoleId = z.infer<typeof RoleIdSchema>
|
|
88
91
|
export type HumanRoleHolder = z.infer<typeof HumanRoleHolderSchema>
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { DescriptionSchema, DisplayMetadataSchema, ModelIdSchema, ReferenceIdsSchema } from './shared'
|
|
3
3
|
|
|
4
|
+
export { LEAD_GEN_STAGE_CATALOG, type LeadGenStageCatalogEntry } from '../catalogs/lead-gen'
|
|
5
|
+
|
|
6
|
+
// Phase 4 cut: OrganizationModelSalesSchema and DEFAULT_ORGANIZATION_MODEL_SALES removed.
|
|
7
|
+
// Pipeline/stage data moved into system.content as (schema:pipeline) and (schema:stage)
|
|
8
|
+
// content nodes on the owning system (e.g. sales.crm). Use getAllPipelines() /
|
|
9
|
+
// getStagesInPipeline() from migration-helpers to read pipeline data portably.
|
|
10
|
+
//
|
|
11
|
+
// SalesStageSemanticClassSchema, SalesStageSchema, SalesPipelineSchema are retained
|
|
12
|
+
// below as TypeScript types used by CRM business logic and the Stateful pipeline definitions.
|
|
13
|
+
|
|
4
14
|
export const SalesStageSemanticClassSchema = z.enum(['open', 'active', 'nurturing', 'closed_won', 'closed_lost'])
|
|
5
15
|
|
|
6
16
|
export const SalesStageSchema = DisplayMetadataSchema.extend({
|
|
@@ -19,80 +29,6 @@ export const SalesPipelineSchema = z.object({
|
|
|
19
29
|
stages: z.array(SalesStageSchema).min(1)
|
|
20
30
|
})
|
|
21
31
|
|
|
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
|
-
}
|
|
95
|
-
|
|
96
32
|
// ============================================================================
|
|
97
33
|
// Lead-Gen Stateful Pipeline Definitions (Decision N8, Wave 4)
|
|
98
34
|
//
|
|
@@ -442,148 +378,3 @@ export const LEAD_GEN_PIPELINE_DEFINITIONS: Record<string, StatefulPipelineDefin
|
|
|
442
378
|
'acq.list-member': [ACQ_LIST_MEMBERS_LEAD_GEN_PIPELINE],
|
|
443
379
|
'acq.list-company': [ACQ_LIST_COMPANIES_LEAD_GEN_PIPELINE]
|
|
444
380
|
}
|
|
445
|
-
|
|
446
|
-
// ============================================================================
|
|
447
|
-
// Lead-Gen Stage Catalog (OM Spine processing-state model)
|
|
448
|
-
//
|
|
449
|
-
// Canonical set of processing stage keys for acq_companies.processing_state and
|
|
450
|
-
// acq_contacts.processing_state. These keys coordinate build templates, workflow
|
|
451
|
-
// factory validation, API filters, and UI progress projections.
|
|
452
|
-
//
|
|
453
|
-
// State is sparse: absent keys mean "not attempted"; present keys hold terminal
|
|
454
|
-
// status entries such as success, no_result, skipped, or error.
|
|
455
|
-
//
|
|
456
|
-
// Historical sources:
|
|
457
|
-
// ACQ_LIST_MEMBERS_LEAD_GEN_PIPELINE → personalized, uploaded, interested,
|
|
458
|
-
// discovered, verified
|
|
459
|
-
// ACQ_LIST_COMPANIES_LEAD_GEN_PIPELINE → populated, extracted, qualified
|
|
460
|
-
// Design plan hint (lead-gen-domain-cleanup.mdx §4) → scraped, enriched
|
|
461
|
-
//
|
|
462
|
-
// ============================================================================
|
|
463
|
-
|
|
464
|
-
/** One entry in the lead-gen stage catalog. */
|
|
465
|
-
export interface LeadGenStageCatalogEntry {
|
|
466
|
-
/** Matches the status key written into processing_state jsonb (e.g. 'scraped'). */
|
|
467
|
-
key: string
|
|
468
|
-
/** Human-readable label for UI display. */
|
|
469
|
-
label: string
|
|
470
|
-
/** Short description of what this stage represents. */
|
|
471
|
-
description: string
|
|
472
|
-
/** Canonical pipeline order for UI sorting. Lower = earlier in the funnel. */
|
|
473
|
-
order: number
|
|
474
|
-
/** Which entity's processing_state jsonb carries this stage status. */
|
|
475
|
-
entity: 'company' | 'contact'
|
|
476
|
-
/** Additional entities allowed to write/read this processing_state key. */
|
|
477
|
-
additionalEntities?: Array<'company' | 'contact'>
|
|
478
|
-
/**
|
|
479
|
-
* Optional read-side override for Records views when a company-scoped step
|
|
480
|
-
* produces records on a different entity.
|
|
481
|
-
*/
|
|
482
|
-
recordEntity?: 'company' | 'contact'
|
|
483
|
-
/** Stage key to read from recordEntity.processing_state for Records views. */
|
|
484
|
-
recordStageKey?: string
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Canonical lead-gen processing stage catalog.
|
|
489
|
-
* Keys are the stage names written by workflow steps into processing_state jsonb.
|
|
490
|
-
*
|
|
491
|
-
* Ordered roughly by pipeline progression (prospecting → outreach → qualification).
|
|
492
|
-
*/
|
|
493
|
-
export const LEAD_GEN_STAGE_CATALOG: Record<string, LeadGenStageCatalogEntry> = {
|
|
494
|
-
// Prospecting — company population
|
|
495
|
-
scraped: {
|
|
496
|
-
key: 'scraped',
|
|
497
|
-
label: 'Scraped',
|
|
498
|
-
description: 'Company was scraped from a source directory (Apify actor run).',
|
|
499
|
-
order: 1,
|
|
500
|
-
entity: 'company'
|
|
501
|
-
},
|
|
502
|
-
populated: {
|
|
503
|
-
key: 'populated',
|
|
504
|
-
label: 'Companies found',
|
|
505
|
-
description: 'Companies have been found and added to the lead-gen list.',
|
|
506
|
-
order: 2,
|
|
507
|
-
entity: 'company'
|
|
508
|
-
},
|
|
509
|
-
crawled: {
|
|
510
|
-
key: 'crawled',
|
|
511
|
-
label: 'Websites crawled',
|
|
512
|
-
description:
|
|
513
|
-
'Company websites have been crawled (e.g. via Apify) and raw page content stored for downstream LLM analysis.',
|
|
514
|
-
order: 2.5,
|
|
515
|
-
entity: 'company'
|
|
516
|
-
},
|
|
517
|
-
extracted: {
|
|
518
|
-
key: 'extracted',
|
|
519
|
-
label: 'Websites analyzed',
|
|
520
|
-
description: 'Company websites have been analyzed for business signals.',
|
|
521
|
-
order: 3,
|
|
522
|
-
entity: 'company'
|
|
523
|
-
},
|
|
524
|
-
enriched: {
|
|
525
|
-
key: 'enriched',
|
|
526
|
-
label: 'Enriched',
|
|
527
|
-
description: 'Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).',
|
|
528
|
-
order: 4,
|
|
529
|
-
entity: 'company'
|
|
530
|
-
},
|
|
531
|
-
'decision-makers-enriched': {
|
|
532
|
-
key: 'decision-makers-enriched',
|
|
533
|
-
label: 'Decision-makers found',
|
|
534
|
-
description: 'Decision-maker contacts discovered and attached to a qualified company.',
|
|
535
|
-
order: 6,
|
|
536
|
-
entity: 'company',
|
|
537
|
-
recordEntity: 'contact',
|
|
538
|
-
recordStageKey: 'discovered'
|
|
539
|
-
},
|
|
540
|
-
|
|
541
|
-
// Prospecting — contact discovery
|
|
542
|
-
discovered: {
|
|
543
|
-
key: 'discovered',
|
|
544
|
-
label: 'Decision-makers found',
|
|
545
|
-
description: 'Decision-maker contact details have been found.',
|
|
546
|
-
order: 5,
|
|
547
|
-
entity: 'contact'
|
|
548
|
-
},
|
|
549
|
-
verified: {
|
|
550
|
-
key: 'verified',
|
|
551
|
-
label: 'Emails verified',
|
|
552
|
-
description: 'Contact email addresses have been checked for deliverability.',
|
|
553
|
-
order: 7,
|
|
554
|
-
entity: 'contact'
|
|
555
|
-
},
|
|
556
|
-
|
|
557
|
-
// Qualification
|
|
558
|
-
qualified: {
|
|
559
|
-
key: 'qualified',
|
|
560
|
-
label: 'Companies qualified',
|
|
561
|
-
description: 'Companies have been scored against the qualification criteria.',
|
|
562
|
-
order: 8,
|
|
563
|
-
entity: 'company'
|
|
564
|
-
},
|
|
565
|
-
|
|
566
|
-
// Outreach
|
|
567
|
-
personalized: {
|
|
568
|
-
key: 'personalized',
|
|
569
|
-
label: 'Personalized',
|
|
570
|
-
description: 'Outreach message personalized for the contact (Instantly personalization workflow).',
|
|
571
|
-
order: 9,
|
|
572
|
-
entity: 'contact'
|
|
573
|
-
},
|
|
574
|
-
uploaded: {
|
|
575
|
-
key: 'uploaded',
|
|
576
|
-
label: 'Reviewed and exported',
|
|
577
|
-
description: 'Approved records have been reviewed and exported for handoff.',
|
|
578
|
-
order: 10,
|
|
579
|
-
entity: 'company',
|
|
580
|
-
additionalEntities: ['contact']
|
|
581
|
-
},
|
|
582
|
-
interested: {
|
|
583
|
-
key: 'interested',
|
|
584
|
-
label: 'Interested',
|
|
585
|
-
description: 'Contact replied with a positive signal (Instantly reply-handler transition).',
|
|
586
|
-
order: 11,
|
|
587
|
-
entity: 'contact'
|
|
588
|
-
}
|
|
589
|
-
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { OrganizationModelIconTokenSchema } from '../icons'
|
|
3
|
-
|
|
4
|
-
export const ModelIdSchema = z
|
|
5
|
-
.string()
|
|
6
|
-
.trim()
|
|
7
|
-
.min(1)
|
|
8
|
-
.max(100)
|
|
9
|
-
.regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, 'IDs must be lowercase and use -, _, or . separators')
|
|
10
|
-
|
|
11
|
-
export const LabelSchema = z.string().trim().min(1).max(120)
|
|
3
|
+
|
|
4
|
+
export const ModelIdSchema = z
|
|
5
|
+
.string()
|
|
6
|
+
.trim()
|
|
7
|
+
.min(1)
|
|
8
|
+
.max(100)
|
|
9
|
+
.regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, 'IDs must be lowercase and use -, _, or . separators')
|
|
10
|
+
|
|
11
|
+
export const LabelSchema = z.string().trim().min(1).max(120)
|
|
12
12
|
export const DescriptionSchema = z.string().trim().min(1).max(2000)
|
|
13
13
|
export const ColorTokenSchema = z.string().trim().min(1).max(50)
|
|
14
14
|
export const IconNameSchema = OrganizationModelIconTokenSchema
|
|
15
15
|
export const PathSchema = z.string().trim().startsWith('/').max(300)
|
|
16
|
-
|
|
17
|
-
export const ReferenceIdsSchema = z.array(ModelIdSchema).default([])
|
|
18
|
-
|
|
19
|
-
export const DisplayMetadataSchema = z.object({
|
|
20
|
-
label: LabelSchema,
|
|
21
|
-
description: DescriptionSchema.optional(),
|
|
22
|
-
color: ColorTokenSchema.optional(),
|
|
23
|
-
icon: IconNameSchema.optional()
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
// TechStack subsection — optional extension on a ResourceMapping entry that
|
|
28
|
-
// captures external-SaaS integration metadata: which platform, its purpose,
|
|
29
|
-
// credential health, and whether it is the system of record for its domain.
|
|
30
|
-
// Backward-compatible: existing entries without this key parse cleanly.
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
export const TechStackEntrySchema = z.object({
|
|
34
|
-
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
35
|
-
platform: z.string().trim().min(1).max(200),
|
|
36
|
-
/** Free-form description of what this integration is used for. */
|
|
37
|
-
purpose: z.string().trim().min(1).max(500),
|
|
38
|
-
/**
|
|
39
|
-
* Health of the credential backing this integration.
|
|
40
|
-
* - configured: credential present and valid
|
|
41
|
-
* - pending: not yet set up
|
|
42
|
-
* - expired: credential existed but has lapsed
|
|
43
|
-
* - missing: expected but not present
|
|
44
|
-
*/
|
|
45
|
-
credentialStatus: z.enum(['configured', 'pending', 'expired', 'missing']),
|
|
46
|
-
/**
|
|
47
|
-
* Whether this integration is the primary system of record for its domain
|
|
48
|
-
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
49
|
-
*/
|
|
50
|
-
isSystemOfRecord: z.boolean().default(false)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
export const ResourceMappingSchema = DisplayMetadataSchema.extend({
|
|
54
|
-
id: ModelIdSchema,
|
|
55
|
-
resourceId: z.string().trim().min(1).max(255),
|
|
56
|
-
resourceType: z.enum(['workflow', 'agent', 'trigger', 'integration', 'external', 'human_checkpoint']),
|
|
57
|
-
|
|
58
|
-
entityIds: ReferenceIdsSchema,
|
|
59
|
-
surfaceIds: ReferenceIdsSchema,
|
|
60
|
-
|
|
61
|
-
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
62
|
-
techStack: TechStackEntrySchema.optional()
|
|
63
|
-
})
|
|
16
|
+
|
|
17
|
+
export const ReferenceIdsSchema = z.array(ModelIdSchema).default([])
|
|
18
|
+
|
|
19
|
+
export const DisplayMetadataSchema = z.object({
|
|
20
|
+
label: LabelSchema,
|
|
21
|
+
description: DescriptionSchema.optional(),
|
|
22
|
+
color: ColorTokenSchema.optional(),
|
|
23
|
+
icon: IconNameSchema.optional()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// TechStack subsection — optional extension on a ResourceMapping entry that
|
|
28
|
+
// captures external-SaaS integration metadata: which platform, its purpose,
|
|
29
|
+
// credential health, and whether it is the system of record for its domain.
|
|
30
|
+
// Backward-compatible: existing entries without this key parse cleanly.
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
export const TechStackEntrySchema = z.object({
|
|
34
|
+
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
35
|
+
platform: z.string().trim().min(1).max(200),
|
|
36
|
+
/** Free-form description of what this integration is used for. */
|
|
37
|
+
purpose: z.string().trim().min(1).max(500),
|
|
38
|
+
/**
|
|
39
|
+
* Health of the credential backing this integration.
|
|
40
|
+
* - configured: credential present and valid
|
|
41
|
+
* - pending: not yet set up
|
|
42
|
+
* - expired: credential existed but has lapsed
|
|
43
|
+
* - missing: expected but not present
|
|
44
|
+
*/
|
|
45
|
+
credentialStatus: z.enum(['configured', 'pending', 'expired', 'missing']),
|
|
46
|
+
/**
|
|
47
|
+
* Whether this integration is the primary system of record for its domain
|
|
48
|
+
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
49
|
+
*/
|
|
50
|
+
isSystemOfRecord: z.boolean().default(false)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
export const ResourceMappingSchema = DisplayMetadataSchema.extend({
|
|
54
|
+
id: ModelIdSchema,
|
|
55
|
+
resourceId: z.string().trim().min(1).max(255),
|
|
56
|
+
resourceType: z.enum(['workflow', 'agent', 'trigger', 'integration', 'external', 'human_checkpoint']),
|
|
57
|
+
systemIds: ReferenceIdsSchema,
|
|
58
|
+
entityIds: ReferenceIdsSchema,
|
|
59
|
+
surfaceIds: ReferenceIdsSchema,
|
|
60
|
+
actionIds: ReferenceIdsSchema,
|
|
61
|
+
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
62
|
+
techStack: TechStackEntrySchema.optional()
|
|
63
|
+
})
|