@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.
Files changed (112) hide show
  1. package/dist/index.d.ts +2330 -2391
  2. package/dist/index.js +2322 -1147
  3. package/dist/knowledge/index.d.ts +702 -1136
  4. package/dist/knowledge/index.js +9 -9
  5. package/dist/organization-model/index.d.ts +2330 -2391
  6. package/dist/organization-model/index.js +2322 -1147
  7. package/dist/test-utils/index.d.ts +703 -1106
  8. package/dist/test-utils/index.js +1735 -1089
  9. package/package.json +1 -1
  10. package/src/__tests__/template-core-compatibility.test.ts +11 -79
  11. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +360 -98
  12. package/src/business/acquisition/api-schemas.test.ts +2 -2
  13. package/src/business/acquisition/api-schemas.ts +7 -9
  14. package/src/business/acquisition/build-templates.test.ts +4 -4
  15. package/src/business/acquisition/build-templates.ts +72 -30
  16. package/src/business/acquisition/crm-state-actions.test.ts +13 -11
  17. package/src/business/acquisition/types.ts +7 -3
  18. package/src/execution/engine/agent/core/types.ts +1 -1
  19. package/src/execution/engine/workflow/types.ts +2 -2
  20. package/src/knowledge/README.md +8 -7
  21. package/src/knowledge/__tests__/queries.test.ts +74 -73
  22. package/src/knowledge/format.ts +10 -9
  23. package/src/knowledge/index.ts +1 -1
  24. package/src/knowledge/published.ts +1 -1
  25. package/src/knowledge/queries.ts +26 -25
  26. package/src/organization-model/README.md +66 -26
  27. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
  28. package/src/organization-model/__tests__/defaults.test.ts +72 -98
  29. package/src/organization-model/__tests__/domains/actions.test.ts +56 -0
  30. package/src/organization-model/__tests__/domains/customers.test.ts +299 -295
  31. package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
  32. package/src/organization-model/__tests__/domains/goals.test.ts +493 -479
  33. package/src/organization-model/__tests__/domains/identity.test.ts +280 -279
  34. package/src/organization-model/__tests__/domains/navigation.test.ts +268 -212
  35. package/src/organization-model/__tests__/domains/offerings.test.ts +414 -419
  36. package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
  37. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +271 -271
  38. package/src/organization-model/__tests__/domains/resources.test.ts +159 -37
  39. package/src/organization-model/__tests__/domains/roles.test.ts +147 -86
  40. package/src/organization-model/__tests__/domains/statuses.test.ts +246 -243
  41. package/src/organization-model/__tests__/domains/systems.test.ts +67 -51
  42. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +361 -0
  43. package/src/organization-model/__tests__/foundation.test.ts +74 -102
  44. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
  45. package/src/organization-model/__tests__/graph.test.ts +899 -71
  46. package/src/organization-model/__tests__/knowledge.test.ts +173 -52
  47. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
  48. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
  49. package/src/organization-model/__tests__/prospecting-ssot.test.ts +36 -27
  50. package/src/organization-model/__tests__/recursive-system-schema.test.ts +520 -0
  51. package/src/organization-model/__tests__/resolve.test.ts +174 -23
  52. package/src/organization-model/__tests__/schema.test.ts +291 -114
  53. package/src/organization-model/__tests__/surface-projection.test.ts +207 -97
  54. package/src/organization-model/catalogs/lead-gen.ts +144 -0
  55. package/src/organization-model/content-kinds/config.ts +36 -0
  56. package/src/organization-model/content-kinds/index.ts +74 -0
  57. package/src/organization-model/content-kinds/pipeline.ts +68 -0
  58. package/src/organization-model/content-kinds/registry.ts +44 -0
  59. package/src/organization-model/content-kinds/status.ts +71 -0
  60. package/src/organization-model/content-kinds/template.ts +83 -0
  61. package/src/organization-model/content-kinds/types.ts +117 -0
  62. package/src/organization-model/contracts.ts +13 -3
  63. package/src/organization-model/defaults.ts +488 -96
  64. package/src/organization-model/domains/actions.ts +239 -0
  65. package/src/organization-model/domains/customers.ts +78 -75
  66. package/src/organization-model/domains/entities.ts +144 -0
  67. package/src/organization-model/domains/goals.ts +83 -80
  68. package/src/organization-model/domains/knowledge.ts +74 -16
  69. package/src/organization-model/domains/navigation.ts +107 -384
  70. package/src/organization-model/domains/offerings.ts +71 -66
  71. package/src/organization-model/domains/policies.ts +102 -0
  72. package/src/organization-model/domains/projects.ts +14 -48
  73. package/src/organization-model/domains/prospecting.ts +62 -181
  74. package/src/organization-model/domains/resources.ts +81 -24
  75. package/src/organization-model/domains/roles.ts +13 -10
  76. package/src/organization-model/domains/sales.ts +10 -219
  77. package/src/organization-model/domains/shared.ts +57 -57
  78. package/src/organization-model/domains/statuses.ts +339 -130
  79. package/src/organization-model/domains/systems.ts +186 -29
  80. package/src/organization-model/foundation.ts +54 -67
  81. package/src/organization-model/graph/build.ts +682 -54
  82. package/src/organization-model/graph/link.ts +1 -1
  83. package/src/organization-model/graph/schema.ts +24 -9
  84. package/src/organization-model/graph/types.ts +20 -7
  85. package/src/organization-model/helpers.ts +231 -26
  86. package/src/organization-model/index.ts +116 -5
  87. package/src/organization-model/migration-helpers.ts +249 -0
  88. package/src/organization-model/organization-graph.mdx +16 -15
  89. package/src/organization-model/organization-model.mdx +89 -41
  90. package/src/organization-model/published.ts +120 -18
  91. package/src/organization-model/resolve.ts +117 -54
  92. package/src/organization-model/schema.ts +561 -140
  93. package/src/organization-model/surface-projection.ts +116 -122
  94. package/src/organization-model/types.ts +102 -21
  95. package/src/platform/constants/versions.ts +1 -1
  96. package/src/platform/registry/__tests__/command-view.test.ts +6 -8
  97. package/src/platform/registry/__tests__/resource-link.test.ts +13 -8
  98. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +16 -31
  99. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
  100. package/src/platform/registry/__tests__/resource-registry.test.ts +9 -7
  101. package/src/platform/registry/__tests__/validation.test.ts +15 -11
  102. package/src/platform/registry/resource-registry.ts +20 -8
  103. package/src/platform/registry/serialization.ts +7 -7
  104. package/src/platform/registry/types.ts +3 -3
  105. package/src/platform/registry/validation.ts +17 -15
  106. package/src/reference/_generated/contracts.md +362 -99
  107. package/src/reference/glossary.md +18 -18
  108. package/src/supabase/database.types.ts +60 -0
  109. package/src/test-utils/test-utils.test.ts +1 -6
  110. package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
  111. package/src/organization-model/domains/features.ts +0 -31
  112. 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 { SystemIdSchema } from './systems'
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.enum(['workflow', 'agent', 'integration'])
13
- export const ResourceGovernanceStatusSchema = z.enum(['active', 'deprecated', 'archived'])
14
- export const AgentKindSchema = z.enum(['orchestrator', 'specialist', 'utility', 'system'])
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
- /** Required single System membership. */
27
- systemId: SystemIdSchema,
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.capabilityKey when the runtime workflow has one. */
36
- capabilityKey: z.string().trim().min(1).max(255).optional()
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.object({
61
- entries: z.array(ResourceEntrySchema).default([])
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>>(resources: TResources): TResources {
73
- for (const resource of Object.values(resources)) {
74
- ResourceEntrySchema.parse(resource)
75
- }
76
-
77
- return resources
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
- // Cycle detection is NOT enforced (known limitation; document if needed).
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.object({
76
- roles: z.array(RoleSchema).default([])
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
- featureIds: ReferenceIdsSchema,
58
- entityIds: ReferenceIdsSchema,
59
- surfaceIds: ReferenceIdsSchema,
60
- capabilityIds: ReferenceIdsSchema,
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
+ })