@elevasis/core 0.28.0 → 0.29.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 +11 -11
- package/dist/knowledge/index.d.ts +1 -1
- package/dist/organization-model/index.d.ts +11 -11
- package/dist/test-utils/index.d.ts +4 -1
- package/package.json +3 -3
- package/src/business/acquisition/api-schemas.test.ts +59 -8
- package/src/business/acquisition/api-schemas.ts +10 -5
- package/src/business/acquisition/build-templates.test.ts +187 -240
- package/src/business/acquisition/build-templates.ts +87 -98
- package/src/business/acquisition/types.ts +390 -389
- package/src/execution/engine/index.ts +6 -4
- package/src/execution/engine/tools/lead-service-types.ts +63 -34
- package/src/execution/engine/tools/platform/acquisition/types.ts +7 -8
- package/src/execution/engine/tools/registry.ts +6 -4
- package/src/execution/engine/tools/tool-maps.ts +23 -1
- package/src/organization-model/domains/prospecting.ts +2 -327
- package/src/organization-model/migration-helpers.ts +16 -12
- package/src/reference/_generated/contracts.md +352 -328
- package/src/supabase/database.types.ts +3 -0
|
@@ -326,10 +326,12 @@ export {
|
|
|
326
326
|
type TransitionDealParams,
|
|
327
327
|
type LoadDealParams,
|
|
328
328
|
// List-oriented lead gen params (Step 3 of list-oriented migration)
|
|
329
|
-
type UpdateListConfigParams,
|
|
330
|
-
type UpdateCompanyStageParams,
|
|
331
|
-
type UpdateContactStageParams,
|
|
332
|
-
type
|
|
329
|
+
type UpdateListConfigParams,
|
|
330
|
+
type UpdateCompanyStageParams,
|
|
331
|
+
type UpdateContactStageParams,
|
|
332
|
+
type ClearCompanyStagesParams,
|
|
333
|
+
type ClearContactStagesParams,
|
|
334
|
+
type ListPendingCompanyIdsParams,
|
|
333
335
|
type ListPendingContactIdsParams,
|
|
334
336
|
type AddCompaniesToListParams,
|
|
335
337
|
type AddCompaniesToListResult,
|
|
@@ -529,23 +529,39 @@ export interface UpdateListConfigParams {
|
|
|
529
529
|
pipelineConfig?: PipelineConfig
|
|
530
530
|
}
|
|
531
531
|
|
|
532
|
-
export interface UpdateCompanyStageParams {
|
|
533
|
-
organizationId: string
|
|
534
|
-
listId: string
|
|
535
|
-
companyId: string
|
|
536
|
-
stage: string
|
|
537
|
-
status?: ProcessingStageStatus
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
532
|
+
export interface UpdateCompanyStageParams {
|
|
533
|
+
organizationId: string
|
|
534
|
+
listId: string
|
|
535
|
+
companyId: string
|
|
536
|
+
stage: string
|
|
537
|
+
status?: ProcessingStageStatus
|
|
538
|
+
data?: unknown
|
|
539
|
+
executionId?: string
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
export interface UpdateContactStageParams {
|
|
543
|
+
organizationId: string
|
|
544
|
+
listId: string
|
|
545
|
+
contactId: string
|
|
546
|
+
stage: string
|
|
547
|
+
status?: ProcessingStageStatus
|
|
548
|
+
data?: unknown
|
|
549
|
+
executionId?: string
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export interface ClearCompanyStagesParams {
|
|
553
|
+
organizationId: string
|
|
554
|
+
listId: string
|
|
555
|
+
companyId: string
|
|
556
|
+
stages: string[]
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export interface ClearContactStagesParams {
|
|
560
|
+
organizationId: string
|
|
561
|
+
listId: string
|
|
562
|
+
contactId: string
|
|
563
|
+
stages: string[]
|
|
564
|
+
}
|
|
549
565
|
|
|
550
566
|
export interface ListPendingCompanyIdsParams {
|
|
551
567
|
organizationId: string
|
|
@@ -589,14 +605,15 @@ export interface RecordListExecutionParams {
|
|
|
589
605
|
configSnapshot?: Record<string, unknown>
|
|
590
606
|
}
|
|
591
607
|
|
|
592
|
-
export interface ListExecutionSummary {
|
|
593
|
-
executionId: string
|
|
594
|
-
resourceId: string
|
|
595
|
-
status: string
|
|
596
|
-
createdAt: string
|
|
597
|
-
completedAt: string | null
|
|
598
|
-
durationMs: number | null
|
|
599
|
-
|
|
608
|
+
export interface ListExecutionSummary {
|
|
609
|
+
executionId: string
|
|
610
|
+
resourceId: string
|
|
611
|
+
status: string
|
|
612
|
+
createdAt: string
|
|
613
|
+
completedAt: string | null
|
|
614
|
+
durationMs: number | null
|
|
615
|
+
input?: unknown
|
|
616
|
+
}
|
|
600
617
|
|
|
601
618
|
// Bulk import (contacts)
|
|
602
619
|
export interface BulkImportParams {
|
|
@@ -712,15 +729,27 @@ export interface ILeadService {
|
|
|
712
729
|
*/
|
|
713
730
|
getListProgress(listId: string, organizationId: string): Promise<ListProgress | null>
|
|
714
731
|
|
|
715
|
-
/**
|
|
716
|
-
* Advance a company row within a list's explicit stage journey.
|
|
717
|
-
*/
|
|
718
|
-
updateCompanyStage(params: UpdateCompanyStageParams): Promise<void>
|
|
719
|
-
|
|
720
|
-
/**
|
|
721
|
-
* Advance a contact row within a list's explicit stage journey.
|
|
722
|
-
*/
|
|
723
|
-
updateContactStage(params: UpdateContactStageParams): Promise<void>
|
|
732
|
+
/**
|
|
733
|
+
* Advance a company row within a list's explicit stage journey.
|
|
734
|
+
*/
|
|
735
|
+
updateCompanyStage(params: UpdateCompanyStageParams): Promise<void>
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Advance a contact row within a list's explicit stage journey.
|
|
739
|
+
*/
|
|
740
|
+
updateContactStage(params: UpdateContactStageParams): Promise<void>
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Clear company stage entries by deleting keys from processing_state.
|
|
744
|
+
* Missing stage keys represent "not attempted"; never persist null markers.
|
|
745
|
+
*/
|
|
746
|
+
clearCompanyStages(params: ClearCompanyStagesParams): Promise<void>
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Clear contact stage entries by deleting keys from processing_state.
|
|
750
|
+
* Missing stage keys represent "not attempted"; never persist null markers.
|
|
751
|
+
*/
|
|
752
|
+
clearContactStages(params: ClearContactStagesParams): Promise<void>
|
|
724
753
|
|
|
725
754
|
/**
|
|
726
755
|
* Return the company_ids in acq_list_companies for the given list where
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import {
|
|
4
3
|
CompanyProcessingStateSchema,
|
|
5
4
|
ContactProcessingStateSchema
|
|
6
5
|
} from '../../../../../business/acquisition/api-schemas'
|
|
@@ -10,11 +9,11 @@ import { EmailSchema } from '../../../../../platform/utils/validation'
|
|
|
10
9
|
// LIST SCHEMAS
|
|
11
10
|
// ============================================
|
|
12
11
|
|
|
13
|
-
export const CreateListInputSchema = z.object({
|
|
14
|
-
name: z.string().min(1),
|
|
15
|
-
description: z.string().optional(),
|
|
16
|
-
buildTemplateId: z.string().
|
|
17
|
-
})
|
|
12
|
+
export const CreateListInputSchema = z.object({
|
|
13
|
+
name: z.string().min(1),
|
|
14
|
+
description: z.string().optional(),
|
|
15
|
+
buildTemplateId: z.string().trim().min(1).max(100).optional()
|
|
16
|
+
})
|
|
18
17
|
|
|
19
18
|
export const UpdateListInputSchema = z.object({
|
|
20
19
|
id: z.string().uuid(),
|
|
@@ -587,10 +587,12 @@ export {
|
|
|
587
587
|
type GetDealByIdParams,
|
|
588
588
|
type GetContactByIdParams,
|
|
589
589
|
type GetCompanyByIdParams,
|
|
590
|
-
type UpdateListConfigParams,
|
|
591
|
-
type UpdateCompanyStageParams,
|
|
592
|
-
type UpdateContactStageParams,
|
|
593
|
-
type
|
|
590
|
+
type UpdateListConfigParams,
|
|
591
|
+
type UpdateCompanyStageParams,
|
|
592
|
+
type UpdateContactStageParams,
|
|
593
|
+
type ClearCompanyStagesParams,
|
|
594
|
+
type ClearContactStagesParams,
|
|
595
|
+
type ListPendingCompanyIdsParams,
|
|
594
596
|
type ListPendingContactIdsParams,
|
|
595
597
|
type AddCompaniesToListParams,
|
|
596
598
|
type AddCompaniesToListResult,
|
|
@@ -258,6 +258,8 @@ import type {
|
|
|
258
258
|
RecordListExecutionParams,
|
|
259
259
|
UpdateCompanyStageParams,
|
|
260
260
|
UpdateContactStageParams,
|
|
261
|
+
ClearCompanyStagesParams,
|
|
262
|
+
ClearContactStagesParams,
|
|
261
263
|
ListPendingCompanyIdsParams,
|
|
262
264
|
ListPendingContactIdsParams,
|
|
263
265
|
UpsertSocialPostParams,
|
|
@@ -589,6 +591,14 @@ export type LeadToolMap = {
|
|
|
589
591
|
params: Omit<UpdateContactStageParams, 'organizationId'>
|
|
590
592
|
result: void
|
|
591
593
|
}
|
|
594
|
+
clearCompanyStages: {
|
|
595
|
+
params: Omit<ClearCompanyStagesParams, 'organizationId'>
|
|
596
|
+
result: void
|
|
597
|
+
}
|
|
598
|
+
clearContactStages: {
|
|
599
|
+
params: Omit<ClearContactStagesParams, 'organizationId'>
|
|
600
|
+
result: void
|
|
601
|
+
}
|
|
592
602
|
// Company operations
|
|
593
603
|
createCompany: { params: Omit<CreateCompanyParams, 'organizationId'>; result: AcqCompany }
|
|
594
604
|
upsertCompany: { params: Omit<UpsertCompanyParams, 'organizationId'>; result: AcqCompany }
|
|
@@ -713,7 +723,11 @@ export type LeadToolMap = {
|
|
|
713
723
|
export type ListToolMap = {
|
|
714
724
|
getConfig: {
|
|
715
725
|
params: { listId: string }
|
|
716
|
-
result: {
|
|
726
|
+
result: {
|
|
727
|
+
scrapingConfig: ScrapingConfig
|
|
728
|
+
icp: IcpRubric
|
|
729
|
+
pipelineConfig: PipelineConfig & { dataMode: 'mock' | 'live' }
|
|
730
|
+
}
|
|
717
731
|
}
|
|
718
732
|
recordExecution: {
|
|
719
733
|
params: Omit<RecordListExecutionParams, 'organizationId'>
|
|
@@ -727,6 +741,14 @@ export type ListToolMap = {
|
|
|
727
741
|
params: Omit<UpdateContactStageParams, 'organizationId'>
|
|
728
742
|
result: void
|
|
729
743
|
}
|
|
744
|
+
clearCompanyStages: {
|
|
745
|
+
params: Omit<ClearCompanyStagesParams, 'organizationId'>
|
|
746
|
+
result: void
|
|
747
|
+
}
|
|
748
|
+
clearContactStages: {
|
|
749
|
+
params: Omit<ClearContactStagesParams, 'organizationId'>
|
|
750
|
+
result: void
|
|
751
|
+
}
|
|
730
752
|
listPendingCompanyIds: {
|
|
731
753
|
params: Omit<ListPendingCompanyIdsParams, 'organizationId'>
|
|
732
754
|
result: string[]
|
|
@@ -62,344 +62,19 @@ export const ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
|
|
|
62
62
|
})
|
|
63
63
|
|
|
64
64
|
export type ListBuilderStep = z.infer<typeof ProspectingBuildTemplateStepSchema>
|
|
65
|
+
export type ProspectingBuildTemplate = z.infer<typeof ProspectingBuildTemplateSchema>
|
|
65
66
|
export type RecordColumnConfig = z.infer<typeof RecordColumnConfigSchema>
|
|
66
67
|
export type CredentialRequirement = z.infer<typeof CredentialRequirementSchema>
|
|
67
|
-
/**
|
|
68
|
-
* Generic template name type. Elevasis-specific template names
|
|
69
|
-
* ('localServices' | 'dtcApolloClickup') have been relocated to
|
|
70
|
-
* `@repo/elevasis-core/src/organization-model/actions.ts`.
|
|
71
|
-
*/
|
|
72
68
|
export type TemplateName = string
|
|
73
69
|
export type StepName = string
|
|
74
|
-
|
|
75
|
-
const DTC_RECORD_COLUMNS = {
|
|
76
|
-
populated: {
|
|
77
|
-
company: [
|
|
78
|
-
{ key: 'name', label: 'Company', path: 'company.name' },
|
|
79
|
-
{ key: 'domain', label: 'Domain', path: 'company.domain' },
|
|
80
|
-
{ key: 'employee-count', label: 'Employees', path: 'company.numEmployees', renderType: 'count' },
|
|
81
|
-
{ key: 'apollo-industry', label: 'Apollo industry', path: 'company.category' },
|
|
82
|
-
{ key: 'location', label: 'Location', path: 'company.locationState' }
|
|
83
|
-
]
|
|
84
|
-
},
|
|
85
|
-
crawled: {
|
|
86
|
-
company: [
|
|
87
|
-
{ key: 'name', label: 'Company', path: 'company.name' },
|
|
88
|
-
{ key: 'domain', label: 'Domain', path: 'company.domain' },
|
|
89
|
-
{ key: 'page-count', label: 'Pages', path: 'company.enrichmentData.websiteCrawl.pageCount', renderType: 'count' },
|
|
90
|
-
{ key: 'crawl-status', label: 'Crawl status', path: 'processingState.crawled.status', renderType: 'badge' }
|
|
91
|
-
]
|
|
92
|
-
},
|
|
93
|
-
extracted: {
|
|
94
|
-
company: [
|
|
95
|
-
{ key: 'name', label: 'Company', path: 'company.name' },
|
|
96
|
-
{ key: 'domain', label: 'Domain', path: 'company.domain' },
|
|
97
|
-
{ key: 'description', label: 'Description', path: 'company.enrichmentData.websiteCrawl.companyDescription' },
|
|
98
|
-
{ key: 'services', label: 'Services', path: 'company.enrichmentData.websiteCrawl.services', renderType: 'json' },
|
|
99
|
-
{
|
|
100
|
-
key: 'automation-gaps',
|
|
101
|
-
label: 'Automation gaps',
|
|
102
|
-
path: 'company.enrichmentData.websiteCrawl.automationGaps',
|
|
103
|
-
renderType: 'json'
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
key: 'contact-count',
|
|
107
|
-
label: 'Contacts',
|
|
108
|
-
path: 'company.enrichmentData.websiteCrawl.emailCount',
|
|
109
|
-
renderType: 'count'
|
|
110
|
-
}
|
|
111
|
-
]
|
|
112
|
-
},
|
|
113
|
-
qualified: {
|
|
114
|
-
company: [
|
|
115
|
-
{ key: 'name', label: 'Company', path: 'company.name' },
|
|
116
|
-
{ key: 'domain', label: 'Domain', path: 'company.domain' },
|
|
117
|
-
{ key: 'score', label: 'Score', path: 'company.qualificationScore', renderType: 'badge', badgeColor: 'green' },
|
|
118
|
-
{ key: 'signals', label: 'Signals', path: 'company.qualificationSignals', renderType: 'json' },
|
|
119
|
-
{
|
|
120
|
-
key: 'disqualified-reason',
|
|
121
|
-
label: 'Disqualified reason',
|
|
122
|
-
path: 'processingState.qualified.data.disqualifiedReason'
|
|
123
|
-
}
|
|
124
|
-
]
|
|
125
|
-
},
|
|
126
|
-
decisionMakers: {
|
|
127
|
-
contact: [
|
|
128
|
-
{ key: 'name', label: 'Name', path: 'contact.name' },
|
|
129
|
-
{ key: 'title', label: 'Title', path: 'contact.title' },
|
|
130
|
-
{ key: 'email', label: 'Email', path: 'contact.email' },
|
|
131
|
-
{ key: 'linkedin', label: 'LinkedIn', path: 'contact.linkedinUrl' },
|
|
132
|
-
{
|
|
133
|
-
key: 'priority-score',
|
|
134
|
-
label: 'Priority',
|
|
135
|
-
path: 'contact.enrichmentData.apollo.priorityScore',
|
|
136
|
-
renderType: 'badge'
|
|
137
|
-
}
|
|
138
|
-
]
|
|
139
|
-
},
|
|
140
|
-
uploaded: {
|
|
141
|
-
company: [
|
|
142
|
-
{ key: 'name', label: 'Company', path: 'company.name' },
|
|
143
|
-
{ key: 'domain', label: 'Domain', path: 'company.domain' },
|
|
144
|
-
{
|
|
145
|
-
key: 'contacts',
|
|
146
|
-
label: 'Contacts',
|
|
147
|
-
path: 'company.enrichmentData.approvedLeadListExport.contacts',
|
|
148
|
-
renderType: 'json'
|
|
149
|
-
},
|
|
150
|
-
{ key: 'score', label: 'Score', path: 'company.qualificationScore', renderType: 'badge', badgeColor: 'green' },
|
|
151
|
-
{
|
|
152
|
-
key: 'approval',
|
|
153
|
-
label: 'Approval',
|
|
154
|
-
path: 'company.enrichmentData.approvedLeadListExport.approvalStatus',
|
|
155
|
-
renderType: 'badge'
|
|
156
|
-
}
|
|
157
|
-
]
|
|
158
|
-
}
|
|
159
|
-
} as const satisfies Record<string, z.infer<typeof RecordColumnsConfigSchema>>
|
|
160
|
-
|
|
161
70
|
export type ActionRegistry = TopLevelAction[]
|
|
162
71
|
|
|
163
72
|
/**
|
|
164
73
|
* Generic empty default for the action registry.
|
|
165
|
-
*
|
|
166
|
-
* `@repo/elevasis-core/src/organization-model/actions.ts`.
|
|
74
|
+
* Tenant-specific lead-gen action lists belong in tenant Organization Models.
|
|
167
75
|
*/
|
|
168
76
|
export const ACTION_REGISTRY: ActionRegistry = []
|
|
169
77
|
|
|
170
78
|
export function findActionById(id: string): TopLevelAction | undefined {
|
|
171
79
|
return findOrganizationActionById(id)
|
|
172
80
|
}
|
|
173
|
-
|
|
174
|
-
export const PROSPECTING_STEPS = {
|
|
175
|
-
localServices: {
|
|
176
|
-
sourceCompanies: {
|
|
177
|
-
id: 'source-companies',
|
|
178
|
-
label: 'Companies found',
|
|
179
|
-
primaryEntity: 'company',
|
|
180
|
-
outputs: ['company'],
|
|
181
|
-
stageKey: 'populated',
|
|
182
|
-
dependencyMode: 'per-record-eligibility',
|
|
183
|
-
actionKey: 'lead-gen.company.source',
|
|
184
|
-
defaultBatchSize: 100,
|
|
185
|
-
maxBatchSize: 250
|
|
186
|
-
},
|
|
187
|
-
analyzeWebsites: {
|
|
188
|
-
id: 'analyze-websites',
|
|
189
|
-
label: 'Websites analyzed',
|
|
190
|
-
primaryEntity: 'company',
|
|
191
|
-
outputs: ['company'],
|
|
192
|
-
stageKey: 'extracted',
|
|
193
|
-
dependsOn: ['source-companies'],
|
|
194
|
-
dependencyMode: 'per-record-eligibility',
|
|
195
|
-
actionKey: 'lead-gen.company.website-extract',
|
|
196
|
-
defaultBatchSize: 50,
|
|
197
|
-
maxBatchSize: 100
|
|
198
|
-
},
|
|
199
|
-
qualifyCompanies: {
|
|
200
|
-
id: 'qualify-companies',
|
|
201
|
-
label: 'Companies qualified',
|
|
202
|
-
primaryEntity: 'company',
|
|
203
|
-
outputs: ['company'],
|
|
204
|
-
stageKey: 'qualified',
|
|
205
|
-
dependsOn: ['analyze-websites'],
|
|
206
|
-
dependencyMode: 'per-record-eligibility',
|
|
207
|
-
actionKey: 'lead-gen.company.qualify',
|
|
208
|
-
defaultBatchSize: 100,
|
|
209
|
-
maxBatchSize: 250
|
|
210
|
-
},
|
|
211
|
-
findContacts: {
|
|
212
|
-
id: 'find-contacts',
|
|
213
|
-
label: 'Decision-makers found',
|
|
214
|
-
primaryEntity: 'contact',
|
|
215
|
-
outputs: ['contact'],
|
|
216
|
-
stageKey: 'discovered',
|
|
217
|
-
dependsOn: ['qualify-companies'],
|
|
218
|
-
dependencyMode: 'per-record-eligibility',
|
|
219
|
-
actionKey: 'lead-gen.contact.discover',
|
|
220
|
-
defaultBatchSize: 50,
|
|
221
|
-
maxBatchSize: 100
|
|
222
|
-
},
|
|
223
|
-
verifyEmails: {
|
|
224
|
-
id: 'verify-emails',
|
|
225
|
-
label: 'Emails verified',
|
|
226
|
-
primaryEntity: 'contact',
|
|
227
|
-
outputs: ['contact'],
|
|
228
|
-
stageKey: 'verified',
|
|
229
|
-
dependsOn: ['find-contacts'],
|
|
230
|
-
dependencyMode: 'per-record-eligibility',
|
|
231
|
-
actionKey: 'lead-gen.contact.verify-email',
|
|
232
|
-
defaultBatchSize: 100,
|
|
233
|
-
maxBatchSize: 500
|
|
234
|
-
},
|
|
235
|
-
personalize: {
|
|
236
|
-
id: 'personalize',
|
|
237
|
-
label: 'Personalize',
|
|
238
|
-
primaryEntity: 'contact',
|
|
239
|
-
outputs: ['contact'],
|
|
240
|
-
stageKey: 'personalized',
|
|
241
|
-
dependsOn: ['verify-emails'],
|
|
242
|
-
dependencyMode: 'per-record-eligibility',
|
|
243
|
-
actionKey: 'lead-gen.contact.personalize',
|
|
244
|
-
defaultBatchSize: 25,
|
|
245
|
-
maxBatchSize: 100
|
|
246
|
-
},
|
|
247
|
-
review: {
|
|
248
|
-
id: 'review',
|
|
249
|
-
label: 'Reviewed and exported',
|
|
250
|
-
primaryEntity: 'contact',
|
|
251
|
-
outputs: ['export'],
|
|
252
|
-
stageKey: 'uploaded',
|
|
253
|
-
dependsOn: ['personalize'],
|
|
254
|
-
dependencyMode: 'per-record-eligibility',
|
|
255
|
-
actionKey: 'lead-gen.review.outreach-ready',
|
|
256
|
-
defaultBatchSize: 25,
|
|
257
|
-
maxBatchSize: 100
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
|
-
dtcApolloClickup: {
|
|
261
|
-
importApolloSearch: {
|
|
262
|
-
id: 'import-apollo-search',
|
|
263
|
-
label: 'Companies found',
|
|
264
|
-
description: 'Pull companies and seed contact data from a predefined Apollo search or list.',
|
|
265
|
-
primaryEntity: 'company',
|
|
266
|
-
outputs: ['company', 'contact'],
|
|
267
|
-
stageKey: 'populated',
|
|
268
|
-
dependencyMode: 'per-record-eligibility',
|
|
269
|
-
actionKey: 'lead-gen.company.apollo-import',
|
|
270
|
-
defaultBatchSize: 250,
|
|
271
|
-
maxBatchSize: 1000,
|
|
272
|
-
recordColumns: DTC_RECORD_COLUMNS.populated,
|
|
273
|
-
credentialRequirements: [
|
|
274
|
-
{
|
|
275
|
-
key: 'apollo',
|
|
276
|
-
provider: 'apollo',
|
|
277
|
-
credentialType: 'api-key-secret',
|
|
278
|
-
label: 'Apollo API key',
|
|
279
|
-
required: true,
|
|
280
|
-
selectionMode: 'single',
|
|
281
|
-
inputPath: 'credential'
|
|
282
|
-
}
|
|
283
|
-
]
|
|
284
|
-
},
|
|
285
|
-
apifyCrawl: {
|
|
286
|
-
id: 'apify-crawl',
|
|
287
|
-
label: 'Websites crawled',
|
|
288
|
-
description:
|
|
289
|
-
'Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis. Overwrites the synthetic seed Apollo Import wrote with real page content.',
|
|
290
|
-
primaryEntity: 'company',
|
|
291
|
-
outputs: ['company'],
|
|
292
|
-
stageKey: 'crawled',
|
|
293
|
-
dependsOn: ['import-apollo-search'],
|
|
294
|
-
dependencyMode: 'per-record-eligibility',
|
|
295
|
-
actionKey: 'lead-gen.company.apify-crawl',
|
|
296
|
-
defaultBatchSize: 50,
|
|
297
|
-
maxBatchSize: 100,
|
|
298
|
-
recordColumns: DTC_RECORD_COLUMNS.crawled,
|
|
299
|
-
credentialRequirements: [
|
|
300
|
-
{
|
|
301
|
-
key: 'apify',
|
|
302
|
-
provider: 'apify',
|
|
303
|
-
credentialType: 'api-key-secret',
|
|
304
|
-
label: 'Apify API token',
|
|
305
|
-
required: true,
|
|
306
|
-
selectionMode: 'single',
|
|
307
|
-
inputPath: 'credential',
|
|
308
|
-
verifyOnRun: true
|
|
309
|
-
}
|
|
310
|
-
]
|
|
311
|
-
},
|
|
312
|
-
analyzeWebsites: {
|
|
313
|
-
id: 'analyze-websites',
|
|
314
|
-
label: 'Websites analyzed',
|
|
315
|
-
description: 'Extract subscription, product, retention, and tech-stack signals from each brand website.',
|
|
316
|
-
primaryEntity: 'company',
|
|
317
|
-
outputs: ['company'],
|
|
318
|
-
stageKey: 'extracted',
|
|
319
|
-
dependsOn: ['apify-crawl'],
|
|
320
|
-
dependencyMode: 'per-record-eligibility',
|
|
321
|
-
actionKey: 'lead-gen.company.website-extract',
|
|
322
|
-
defaultBatchSize: 50,
|
|
323
|
-
maxBatchSize: 100,
|
|
324
|
-
recordColumns: DTC_RECORD_COLUMNS.extracted
|
|
325
|
-
},
|
|
326
|
-
scoreDtcFit: {
|
|
327
|
-
id: 'score-dtc-fit',
|
|
328
|
-
label: 'Companies qualified',
|
|
329
|
-
description: 'Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.',
|
|
330
|
-
primaryEntity: 'company',
|
|
331
|
-
outputs: ['company'],
|
|
332
|
-
stageKey: 'qualified',
|
|
333
|
-
dependsOn: ['analyze-websites'],
|
|
334
|
-
dependencyMode: 'per-record-eligibility',
|
|
335
|
-
actionKey: 'lead-gen.company.dtc-subscription-qualify',
|
|
336
|
-
defaultBatchSize: 100,
|
|
337
|
-
maxBatchSize: 250,
|
|
338
|
-
recordColumns: DTC_RECORD_COLUMNS.qualified
|
|
339
|
-
},
|
|
340
|
-
enrichDecisionMakers: {
|
|
341
|
-
id: 'enrich-decision-makers',
|
|
342
|
-
label: 'Decision-makers found',
|
|
343
|
-
description:
|
|
344
|
-
'Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.',
|
|
345
|
-
primaryEntity: 'company',
|
|
346
|
-
outputs: ['contact'],
|
|
347
|
-
stageKey: 'decision-makers-enriched',
|
|
348
|
-
recordEntity: 'contact',
|
|
349
|
-
dependsOn: ['score-dtc-fit'],
|
|
350
|
-
dependencyMode: 'per-record-eligibility',
|
|
351
|
-
actionKey: 'lead-gen.contact.apollo-decision-maker-enrich',
|
|
352
|
-
defaultBatchSize: 100,
|
|
353
|
-
maxBatchSize: 250,
|
|
354
|
-
recordColumns: DTC_RECORD_COLUMNS.decisionMakers,
|
|
355
|
-
credentialRequirements: [
|
|
356
|
-
{
|
|
357
|
-
key: 'apollo',
|
|
358
|
-
provider: 'apollo',
|
|
359
|
-
credentialType: 'api-key-secret',
|
|
360
|
-
label: 'Apollo API key',
|
|
361
|
-
required: true,
|
|
362
|
-
selectionMode: 'single',
|
|
363
|
-
inputPath: 'credential'
|
|
364
|
-
}
|
|
365
|
-
]
|
|
366
|
-
},
|
|
367
|
-
reviewAndExport: {
|
|
368
|
-
id: 'review-and-export',
|
|
369
|
-
label: 'Reviewed and exported',
|
|
370
|
-
description:
|
|
371
|
-
'Operator QC approves or rejects qualified companies, then approved records are exported as a lead list with unverified emails.',
|
|
372
|
-
primaryEntity: 'company',
|
|
373
|
-
outputs: ['export'],
|
|
374
|
-
stageKey: 'uploaded',
|
|
375
|
-
recordsStageKey: 'uploaded',
|
|
376
|
-
recordSourceStageKey: 'qualified',
|
|
377
|
-
dependsOn: ['enrich-decision-makers'],
|
|
378
|
-
dependencyMode: 'per-record-eligibility',
|
|
379
|
-
actionKey: 'lead-gen.export.list',
|
|
380
|
-
defaultBatchSize: 100,
|
|
381
|
-
maxBatchSize: 250,
|
|
382
|
-
recordColumns: DTC_RECORD_COLUMNS.uploaded,
|
|
383
|
-
credentialRequirements: [
|
|
384
|
-
{
|
|
385
|
-
key: 'clickup',
|
|
386
|
-
provider: 'clickup',
|
|
387
|
-
credentialType: 'api-key-secret',
|
|
388
|
-
label: 'ClickUp API token',
|
|
389
|
-
required: true,
|
|
390
|
-
selectionMode: 'single',
|
|
391
|
-
inputPath: 'clickupCredential',
|
|
392
|
-
verifyOnRun: true
|
|
393
|
-
}
|
|
394
|
-
]
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
} as const satisfies Record<TemplateName, Record<StepName, ListBuilderStep>>
|
|
398
|
-
|
|
399
|
-
// OrganizationModelProspectingSchema and DEFAULT_ORGANIZATION_MODEL_PROSPECTING are retired.
|
|
400
|
-
// Build-template/stage data lives in System.ontology.catalogTypes. Use
|
|
401
|
-
// getAllBuildTemplates() / getAllProspectingStages() from migration-helpers to
|
|
402
|
-
// read prospecting data portably.
|
|
403
|
-
//
|
|
404
|
-
// ProspectingBuildTemplateSchema, ProspectingBuildTemplateStepSchema, ProspectingLifecycleStageSchema,
|
|
405
|
-
// PROSPECTING_STEPS, and ACTION_REGISTRY are retained for use by business logic and UI.
|
|
@@ -127,20 +127,24 @@ export function getAllBuildTemplates(model: OrganizationModel): BuildTemplate[]
|
|
|
127
127
|
const steps = stepCatalog === undefined ? [] : entriesOf(stepCatalog)
|
|
128
128
|
|
|
129
129
|
return {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
order: numberValue(templateEntry.order, Number.MAX_SAFE_INTEGER),
|
|
131
|
+
template: {
|
|
132
|
+
id: templateId,
|
|
133
|
+
label: stringValue(templateEntry.label) ?? templateId,
|
|
134
|
+
...(stringValue(templateEntry.description) ? { description: stringValue(templateEntry.description) } : {}),
|
|
135
|
+
...(stringValue(templateEntry.color) ? { color: stringValue(templateEntry.color) } : {}),
|
|
136
|
+
steps: steps.map(([stepId, step]) => ({
|
|
137
|
+
id: stepId,
|
|
138
|
+
label: stringValue(step.label) ?? stepId,
|
|
139
|
+
...(stringValue(step.description) ? { description: stringValue(step.description) } : {}),
|
|
140
|
+
...step
|
|
141
|
+
})) as BuildTemplate['steps']
|
|
142
|
+
} satisfies BuildTemplate
|
|
143
|
+
}
|
|
141
144
|
})
|
|
142
145
|
)
|
|
143
|
-
.sort((a, b) => a.id.localeCompare(b.id))
|
|
146
|
+
.sort((a, b) => a.order - b.order || a.template.id.localeCompare(b.template.id))
|
|
147
|
+
.map(({ template }) => template)
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
export function getAllProspectingStages(model: OrganizationModel, kind: 'company' | 'contact'): ProspectingStage[] {
|