@elevasis/sdk 1.17.0 → 1.19.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/cli.cjs +587 -175
- package/dist/index.d.ts +555 -83
- package/dist/index.js +1219 -66
- package/dist/node/index.d.ts +3 -0
- package/dist/node/index.js +34 -1
- package/dist/test-utils/index.d.ts +128 -81
- package/dist/test-utils/index.js +2007 -668
- package/dist/types/worker/index.d.ts +3 -2
- package/dist/worker/index.js +1507 -2
- package/package.json +2 -2
- package/reference/claude-config/registries/graph-skills.json +4 -0
- package/reference/claude-config/rules/package-taxonomy.md +33 -0
- package/reference/claude-config/rules/vibe.md +23 -0
- package/reference/claude-config/skills/knowledge/SKILL.md +46 -13
- package/reference/claude-config/skills/project/SKILL.md +21 -0
- package/reference/claude-config/skills/tutorial/SKILL.md +13 -3
- package/reference/claude-config/skills/tutorial/technical.md +6 -8
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -0
- package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -0
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -0
- package/reference/scaffold/reference/contracts.md +89 -69
- package/reference/scaffold/reference/feature-registry.md +1 -1
- package/reference/spine/spine-primer.md +99 -0
package/dist/worker/index.js
CHANGED
|
@@ -3652,6 +3652,29 @@ function estimateTokens(text) {
|
|
|
3652
3652
|
const chars = content.length;
|
|
3653
3653
|
return Math.ceil(chars / 3.5);
|
|
3654
3654
|
}
|
|
3655
|
+
var UuidSchema = z.string().uuid();
|
|
3656
|
+
var NonEmptyStringSchema = z.string().trim().min(1).max(1e3);
|
|
3657
|
+
z.enum(["agent", "workflow"]);
|
|
3658
|
+
z.enum(["agent", "workflow", "scheduler", "api"]);
|
|
3659
|
+
z.string().trim().toLowerCase().min(1, "Credential name required").max(100, "Credential name too long (max 100 chars)").regex(
|
|
3660
|
+
/^[a-z0-9]+(-[a-z0-9]+)+$/,
|
|
3661
|
+
"Credential name must be lowercase letters, numbers, and hyphens in format: service-environment (e.g., gmail-prod, attio-dev)"
|
|
3662
|
+
);
|
|
3663
|
+
z.enum(["google-sheets", "google-calendar", "dropbox"]);
|
|
3664
|
+
z.string().min(10, "Authorization code too short").max(1e3, "Authorization code too long");
|
|
3665
|
+
z.string().min(10, "State parameter too short").max(2048, "State parameter too long");
|
|
3666
|
+
z.string().trim().transform((str) => str.replace(/[<>'"]/g, ""));
|
|
3667
|
+
z.string().email();
|
|
3668
|
+
z.string().url();
|
|
3669
|
+
z.object({
|
|
3670
|
+
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
3671
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
3672
|
+
});
|
|
3673
|
+
z.string().datetime();
|
|
3674
|
+
z.object({
|
|
3675
|
+
startDate: z.string().datetime(),
|
|
3676
|
+
endDate: z.string().datetime()
|
|
3677
|
+
});
|
|
3655
3678
|
|
|
3656
3679
|
// ../core/src/platform/constants/limits.ts
|
|
3657
3680
|
var MAX_SESSION_MEMORY_KEYS = 25;
|
|
@@ -4580,6 +4603,1301 @@ Fix the errors and generate a valid output.
|
|
|
4580
4603
|
}
|
|
4581
4604
|
}
|
|
4582
4605
|
};
|
|
4606
|
+
var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
4607
|
+
"nav.dashboard",
|
|
4608
|
+
"nav.calendar",
|
|
4609
|
+
"nav.sales",
|
|
4610
|
+
"nav.crm",
|
|
4611
|
+
"nav.lead-gen",
|
|
4612
|
+
"nav.projects",
|
|
4613
|
+
"nav.operations",
|
|
4614
|
+
"nav.monitoring",
|
|
4615
|
+
"nav.knowledge",
|
|
4616
|
+
"nav.settings",
|
|
4617
|
+
"nav.admin",
|
|
4618
|
+
"nav.archive",
|
|
4619
|
+
"knowledge.playbook",
|
|
4620
|
+
"knowledge.strategy",
|
|
4621
|
+
"knowledge.reference",
|
|
4622
|
+
"feature.dashboard",
|
|
4623
|
+
"feature.calendar",
|
|
4624
|
+
"feature.sales",
|
|
4625
|
+
"feature.crm",
|
|
4626
|
+
"feature.finance",
|
|
4627
|
+
"feature.lead-gen",
|
|
4628
|
+
"feature.platform",
|
|
4629
|
+
"feature.projects",
|
|
4630
|
+
"feature.operations",
|
|
4631
|
+
"feature.knowledge",
|
|
4632
|
+
"feature.monitoring",
|
|
4633
|
+
"feature.settings",
|
|
4634
|
+
"feature.admin",
|
|
4635
|
+
"feature.archive",
|
|
4636
|
+
"feature.seo",
|
|
4637
|
+
"resource.agent",
|
|
4638
|
+
"resource.workflow",
|
|
4639
|
+
"resource.integration",
|
|
4640
|
+
"resource.database",
|
|
4641
|
+
"resource.user",
|
|
4642
|
+
"resource.team",
|
|
4643
|
+
"integration.gmail",
|
|
4644
|
+
"integration.google-sheets",
|
|
4645
|
+
"integration.attio",
|
|
4646
|
+
"surface.dashboard",
|
|
4647
|
+
"surface.calendar",
|
|
4648
|
+
"surface.overview",
|
|
4649
|
+
"surface.command-view",
|
|
4650
|
+
"surface.command-queue",
|
|
4651
|
+
"surface.pipeline",
|
|
4652
|
+
"surface.lists",
|
|
4653
|
+
"surface.resources",
|
|
4654
|
+
"surface.settings",
|
|
4655
|
+
"status.success",
|
|
4656
|
+
"status.error",
|
|
4657
|
+
"status.warning",
|
|
4658
|
+
"status.info",
|
|
4659
|
+
"status.pending",
|
|
4660
|
+
"action.approve",
|
|
4661
|
+
"action.reject",
|
|
4662
|
+
"action.retry",
|
|
4663
|
+
"action.edit",
|
|
4664
|
+
"action.view",
|
|
4665
|
+
"action.launch",
|
|
4666
|
+
"action.message",
|
|
4667
|
+
"action.escalate",
|
|
4668
|
+
"action.promote",
|
|
4669
|
+
"action.submit",
|
|
4670
|
+
"action.email"
|
|
4671
|
+
];
|
|
4672
|
+
var CustomIconTokenSchema = z.string().trim().max(80).regex(/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "Custom icon tokens must start with custom.");
|
|
4673
|
+
var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
|
|
4674
|
+
var OrganizationModelIconTokenSchema = z.union([
|
|
4675
|
+
OrganizationModelBuiltinIconTokenSchema,
|
|
4676
|
+
CustomIconTokenSchema
|
|
4677
|
+
]);
|
|
4678
|
+
|
|
4679
|
+
// ../core/src/organization-model/domains/shared.ts
|
|
4680
|
+
var ModelIdSchema = z.string().trim().min(1).max(100).regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "IDs must be lowercase and use -, _, or . separators");
|
|
4681
|
+
var LabelSchema = z.string().trim().min(1).max(120);
|
|
4682
|
+
var DescriptionSchema = z.string().trim().min(1).max(2e3);
|
|
4683
|
+
var ColorTokenSchema = z.string().trim().min(1).max(50);
|
|
4684
|
+
var IconNameSchema = OrganizationModelIconTokenSchema;
|
|
4685
|
+
z.string().trim().startsWith("/").max(300);
|
|
4686
|
+
var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
|
|
4687
|
+
var DisplayMetadataSchema = z.object({
|
|
4688
|
+
label: LabelSchema,
|
|
4689
|
+
description: DescriptionSchema.optional(),
|
|
4690
|
+
color: ColorTokenSchema.optional(),
|
|
4691
|
+
icon: IconNameSchema.optional()
|
|
4692
|
+
});
|
|
4693
|
+
var TechStackEntrySchema = z.object({
|
|
4694
|
+
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
4695
|
+
platform: z.string().trim().min(1).max(200),
|
|
4696
|
+
/** Free-form description of what this integration is used for. */
|
|
4697
|
+
purpose: z.string().trim().min(1).max(500),
|
|
4698
|
+
/**
|
|
4699
|
+
* Health of the credential backing this integration.
|
|
4700
|
+
* - configured: credential present and valid
|
|
4701
|
+
* - pending: not yet set up
|
|
4702
|
+
* - expired: credential existed but has lapsed
|
|
4703
|
+
* - missing: expected but not present
|
|
4704
|
+
*/
|
|
4705
|
+
credentialStatus: z.enum(["configured", "pending", "expired", "missing"]),
|
|
4706
|
+
/**
|
|
4707
|
+
* Whether this integration is the primary system of record for its domain
|
|
4708
|
+
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
4709
|
+
*/
|
|
4710
|
+
isSystemOfRecord: z.boolean().default(false)
|
|
4711
|
+
});
|
|
4712
|
+
DisplayMetadataSchema.extend({
|
|
4713
|
+
id: ModelIdSchema,
|
|
4714
|
+
resourceId: z.string().trim().min(1).max(255),
|
|
4715
|
+
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
|
|
4716
|
+
featureIds: ReferenceIdsSchema,
|
|
4717
|
+
entityIds: ReferenceIdsSchema,
|
|
4718
|
+
surfaceIds: ReferenceIdsSchema,
|
|
4719
|
+
capabilityIds: ReferenceIdsSchema,
|
|
4720
|
+
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
4721
|
+
techStack: TechStackEntrySchema.optional()
|
|
4722
|
+
});
|
|
4723
|
+
|
|
4724
|
+
// ../core/src/organization-model/domains/sales.ts
|
|
4725
|
+
var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
|
|
4726
|
+
var SalesStageSchema = DisplayMetadataSchema.extend({
|
|
4727
|
+
id: ModelIdSchema,
|
|
4728
|
+
order: z.number().int().min(0),
|
|
4729
|
+
semanticClass: SalesStageSemanticClassSchema,
|
|
4730
|
+
surfaceIds: ReferenceIdsSchema,
|
|
4731
|
+
resourceIds: ReferenceIdsSchema
|
|
4732
|
+
});
|
|
4733
|
+
var SalesPipelineSchema = z.object({
|
|
4734
|
+
id: ModelIdSchema,
|
|
4735
|
+
label: z.string().trim().min(1).max(120),
|
|
4736
|
+
description: DescriptionSchema.optional(),
|
|
4737
|
+
entityId: ModelIdSchema,
|
|
4738
|
+
stages: z.array(SalesStageSchema).min(1)
|
|
4739
|
+
});
|
|
4740
|
+
z.object({
|
|
4741
|
+
entityId: ModelIdSchema,
|
|
4742
|
+
defaultPipelineId: ModelIdSchema,
|
|
4743
|
+
pipelines: z.array(SalesPipelineSchema).min(1)
|
|
4744
|
+
});
|
|
4745
|
+
var CRM_DISCOVERY_REPLIED_STATE = {
|
|
4746
|
+
stateKey: "discovery_replied",
|
|
4747
|
+
label: "Discovery Replied"
|
|
4748
|
+
};
|
|
4749
|
+
var CRM_DISCOVERY_LINK_SENT_STATE = {
|
|
4750
|
+
stateKey: "discovery_link_sent",
|
|
4751
|
+
label: "Discovery Link Sent"
|
|
4752
|
+
};
|
|
4753
|
+
var CRM_DISCOVERY_NUDGING_STATE = {
|
|
4754
|
+
stateKey: "discovery_nudging",
|
|
4755
|
+
label: "Discovery Nudging"
|
|
4756
|
+
};
|
|
4757
|
+
var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
|
|
4758
|
+
stateKey: "discovery_booking_cancelled",
|
|
4759
|
+
label: "Discovery Booking Cancelled"
|
|
4760
|
+
};
|
|
4761
|
+
var CRM_REPLY_SENT_STATE = {
|
|
4762
|
+
stateKey: "reply_sent",
|
|
4763
|
+
label: "Reply Sent"
|
|
4764
|
+
};
|
|
4765
|
+
var CRM_FOLLOWUP_1_SENT_STATE = {
|
|
4766
|
+
stateKey: "followup_1_sent",
|
|
4767
|
+
label: "Follow-up 1 Sent"
|
|
4768
|
+
};
|
|
4769
|
+
var CRM_FOLLOWUP_2_SENT_STATE = {
|
|
4770
|
+
stateKey: "followup_2_sent",
|
|
4771
|
+
label: "Follow-up 2 Sent"
|
|
4772
|
+
};
|
|
4773
|
+
var CRM_FOLLOWUP_3_SENT_STATE = {
|
|
4774
|
+
stateKey: "followup_3_sent",
|
|
4775
|
+
label: "Follow-up 3 Sent"
|
|
4776
|
+
};
|
|
4777
|
+
var CRM_PIPELINE_DEFINITION = {
|
|
4778
|
+
pipelineKey: "crm",
|
|
4779
|
+
stages: [
|
|
4780
|
+
{
|
|
4781
|
+
stageKey: "interested",
|
|
4782
|
+
label: "Interested",
|
|
4783
|
+
color: "blue",
|
|
4784
|
+
states: [
|
|
4785
|
+
CRM_DISCOVERY_REPLIED_STATE,
|
|
4786
|
+
CRM_DISCOVERY_LINK_SENT_STATE,
|
|
4787
|
+
CRM_DISCOVERY_NUDGING_STATE,
|
|
4788
|
+
CRM_DISCOVERY_BOOKING_CANCELLED_STATE,
|
|
4789
|
+
CRM_REPLY_SENT_STATE,
|
|
4790
|
+
CRM_FOLLOWUP_1_SENT_STATE,
|
|
4791
|
+
CRM_FOLLOWUP_2_SENT_STATE,
|
|
4792
|
+
CRM_FOLLOWUP_3_SENT_STATE
|
|
4793
|
+
]
|
|
4794
|
+
},
|
|
4795
|
+
{ stageKey: "proposal", label: "Proposal", color: "yellow", states: [] },
|
|
4796
|
+
{ stageKey: "closing", label: "Closing", color: "orange", states: [] },
|
|
4797
|
+
{ stageKey: "closed_won", label: "Closed Won", color: "green", states: [] },
|
|
4798
|
+
{ stageKey: "closed_lost", label: "Closed Lost", color: "red", states: [] },
|
|
4799
|
+
{ stageKey: "nurturing", label: "Nurturing", color: "grape", states: [] }
|
|
4800
|
+
]
|
|
4801
|
+
};
|
|
4802
|
+
var LEAD_GEN_STAGE_CATALOG = {
|
|
4803
|
+
// Prospecting — company population
|
|
4804
|
+
scraped: {
|
|
4805
|
+
key: "scraped",
|
|
4806
|
+
label: "Scraped",
|
|
4807
|
+
description: "Company was scraped from a source directory (Apify actor run).",
|
|
4808
|
+
order: 1,
|
|
4809
|
+
entity: "company"
|
|
4810
|
+
},
|
|
4811
|
+
populated: {
|
|
4812
|
+
key: "populated",
|
|
4813
|
+
label: "Companies found",
|
|
4814
|
+
description: "Companies have been found and added to the lead-gen list.",
|
|
4815
|
+
order: 2,
|
|
4816
|
+
entity: "company"
|
|
4817
|
+
},
|
|
4818
|
+
extracted: {
|
|
4819
|
+
key: "extracted",
|
|
4820
|
+
label: "Websites analyzed",
|
|
4821
|
+
description: "Company websites have been analyzed for business signals.",
|
|
4822
|
+
order: 3,
|
|
4823
|
+
entity: "company"
|
|
4824
|
+
},
|
|
4825
|
+
enriched: {
|
|
4826
|
+
key: "enriched",
|
|
4827
|
+
label: "Enriched",
|
|
4828
|
+
description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
|
|
4829
|
+
order: 4,
|
|
4830
|
+
entity: "company"
|
|
4831
|
+
},
|
|
4832
|
+
"decision-makers-enriched": {
|
|
4833
|
+
key: "decision-makers-enriched",
|
|
4834
|
+
label: "Decision-makers found",
|
|
4835
|
+
description: "Decision-maker contacts discovered and attached to a qualified company.",
|
|
4836
|
+
order: 6,
|
|
4837
|
+
entity: "company"
|
|
4838
|
+
},
|
|
4839
|
+
// Prospecting — contact discovery
|
|
4840
|
+
discovered: {
|
|
4841
|
+
key: "discovered",
|
|
4842
|
+
label: "Decision-makers found",
|
|
4843
|
+
description: "Decision-maker contact details have been found.",
|
|
4844
|
+
order: 5,
|
|
4845
|
+
entity: "contact"
|
|
4846
|
+
},
|
|
4847
|
+
verified: {
|
|
4848
|
+
key: "verified",
|
|
4849
|
+
label: "Emails verified",
|
|
4850
|
+
description: "Contact email addresses have been checked for deliverability.",
|
|
4851
|
+
order: 7,
|
|
4852
|
+
entity: "contact"
|
|
4853
|
+
},
|
|
4854
|
+
// Qualification
|
|
4855
|
+
qualified: {
|
|
4856
|
+
key: "qualified",
|
|
4857
|
+
label: "Companies qualified",
|
|
4858
|
+
description: "Companies have been scored against the qualification criteria.",
|
|
4859
|
+
order: 8,
|
|
4860
|
+
entity: "company"
|
|
4861
|
+
},
|
|
4862
|
+
// Outreach
|
|
4863
|
+
personalized: {
|
|
4864
|
+
key: "personalized",
|
|
4865
|
+
label: "Personalized",
|
|
4866
|
+
description: "Outreach message personalized for the contact (Instantly personalization workflow).",
|
|
4867
|
+
order: 9,
|
|
4868
|
+
entity: "contact"
|
|
4869
|
+
},
|
|
4870
|
+
uploaded: {
|
|
4871
|
+
key: "uploaded",
|
|
4872
|
+
label: "Reviewed and exported",
|
|
4873
|
+
description: "Approved records have been reviewed and exported for handoff.",
|
|
4874
|
+
order: 10,
|
|
4875
|
+
entity: "contact"
|
|
4876
|
+
},
|
|
4877
|
+
interested: {
|
|
4878
|
+
key: "interested",
|
|
4879
|
+
label: "Interested",
|
|
4880
|
+
description: "Contact replied with a positive signal (Instantly reply-handler transition).",
|
|
4881
|
+
order: 11,
|
|
4882
|
+
entity: "contact"
|
|
4883
|
+
}
|
|
4884
|
+
};
|
|
4885
|
+
|
|
4886
|
+
// ../core/src/organization-model/domains/prospecting.ts
|
|
4887
|
+
var ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
|
|
4888
|
+
id: ModelIdSchema,
|
|
4889
|
+
order: z.number().int().min(0)
|
|
4890
|
+
});
|
|
4891
|
+
var ProspectingBuildTemplateStepSchema = DisplayMetadataSchema.extend({
|
|
4892
|
+
id: ModelIdSchema,
|
|
4893
|
+
primaryEntity: z.enum(["company", "contact"]),
|
|
4894
|
+
outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
|
|
4895
|
+
stageKey: ModelIdSchema,
|
|
4896
|
+
dependsOn: z.array(ModelIdSchema).optional(),
|
|
4897
|
+
dependencyMode: z.literal("per-record-eligibility"),
|
|
4898
|
+
capabilityKey: ModelIdSchema,
|
|
4899
|
+
defaultBatchSize: z.number().int().positive(),
|
|
4900
|
+
maxBatchSize: z.number().int().positive()
|
|
4901
|
+
}).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
|
|
4902
|
+
message: "defaultBatchSize must be less than or equal to maxBatchSize",
|
|
4903
|
+
path: ["defaultBatchSize"]
|
|
4904
|
+
});
|
|
4905
|
+
var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
|
|
4906
|
+
id: ModelIdSchema,
|
|
4907
|
+
steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
|
|
4908
|
+
});
|
|
4909
|
+
z.object({
|
|
4910
|
+
id: ModelIdSchema,
|
|
4911
|
+
label: z.string(),
|
|
4912
|
+
description: z.string(),
|
|
4913
|
+
resourceId: ModelIdSchema
|
|
4914
|
+
});
|
|
4915
|
+
var CAPABILITY_REGISTRY = [
|
|
4916
|
+
{
|
|
4917
|
+
id: "lead-gen.company.source",
|
|
4918
|
+
label: "Source companies",
|
|
4919
|
+
description: "Import source companies from a list provider.",
|
|
4920
|
+
resourceId: "lgn-import-workflow"
|
|
4921
|
+
},
|
|
4922
|
+
{
|
|
4923
|
+
id: "lead-gen.company.apollo-import",
|
|
4924
|
+
label: "Import from Apollo",
|
|
4925
|
+
description: "Pull companies and seed contact data from an Apollo search or list.",
|
|
4926
|
+
resourceId: "lgn-01c-apollo-import-workflow"
|
|
4927
|
+
},
|
|
4928
|
+
{
|
|
4929
|
+
id: "lead-gen.contact.discover",
|
|
4930
|
+
label: "Discover contact emails",
|
|
4931
|
+
description: "Find email addresses for contacts at qualified companies.",
|
|
4932
|
+
resourceId: "lgn-04-email-discovery-workflow"
|
|
4933
|
+
},
|
|
4934
|
+
{
|
|
4935
|
+
id: "lead-gen.contact.verify-email",
|
|
4936
|
+
label: "Verify emails",
|
|
4937
|
+
description: "Check email deliverability before outreach.",
|
|
4938
|
+
resourceId: "lgn-05-email-verification-workflow"
|
|
4939
|
+
},
|
|
4940
|
+
{
|
|
4941
|
+
id: "lead-gen.company.website-extract",
|
|
4942
|
+
label: "Extract website signals",
|
|
4943
|
+
description: "Scrape and analyze company websites for qualification signals.",
|
|
4944
|
+
resourceId: "lgn-02-website-extract-workflow"
|
|
4945
|
+
},
|
|
4946
|
+
{
|
|
4947
|
+
id: "lead-gen.company.qualify",
|
|
4948
|
+
label: "Qualify companies",
|
|
4949
|
+
description: "Score and filter companies against the ICP rubric.",
|
|
4950
|
+
resourceId: "lgn-03-company-qualification-workflow"
|
|
4951
|
+
},
|
|
4952
|
+
{
|
|
4953
|
+
id: "lead-gen.company.dtc-subscription-qualify",
|
|
4954
|
+
label: "Qualify DTC subscription fit",
|
|
4955
|
+
description: "Classify subscription potential and consumable-product fit for DTC brands.",
|
|
4956
|
+
resourceId: "lgn-03b-dtc-subscription-score-workflow"
|
|
4957
|
+
},
|
|
4958
|
+
{
|
|
4959
|
+
id: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
4960
|
+
label: "Enrich decision-makers",
|
|
4961
|
+
description: "Find and enrich qualified contacts at qualified companies via Apollo.",
|
|
4962
|
+
resourceId: "lgn-04b-apollo-decision-maker-enrich-workflow"
|
|
4963
|
+
},
|
|
4964
|
+
{
|
|
4965
|
+
id: "lead-gen.contact.personalize",
|
|
4966
|
+
label: "Personalize outreach",
|
|
4967
|
+
description: "Generate personalized opening lines for each contact.",
|
|
4968
|
+
resourceId: "ist-personalization-workflow"
|
|
4969
|
+
},
|
|
4970
|
+
{
|
|
4971
|
+
id: "lead-gen.review.outreach-ready",
|
|
4972
|
+
label: "Upload to outreach",
|
|
4973
|
+
description: "Upload approved contacts to the outreach sequence after QC review.",
|
|
4974
|
+
resourceId: "ist-upload-contacts-workflow"
|
|
4975
|
+
},
|
|
4976
|
+
{
|
|
4977
|
+
id: "lead-gen.export.list",
|
|
4978
|
+
label: "Export lead list",
|
|
4979
|
+
description: "Export approved leads as a downloadable lead list.",
|
|
4980
|
+
resourceId: "lgn-06-export-list-workflow"
|
|
4981
|
+
},
|
|
4982
|
+
{
|
|
4983
|
+
id: "lead-gen.company.cleanup",
|
|
4984
|
+
label: "Clean up companies",
|
|
4985
|
+
description: "Remove disqualified or duplicate companies from the list.",
|
|
4986
|
+
resourceId: "lgn-company-cleanup-workflow"
|
|
4987
|
+
}
|
|
4988
|
+
];
|
|
4989
|
+
var PROSPECTING_STEPS = {
|
|
4990
|
+
localServices: {
|
|
4991
|
+
sourceCompanies: {
|
|
4992
|
+
id: "source-companies",
|
|
4993
|
+
label: "Companies found",
|
|
4994
|
+
primaryEntity: "company",
|
|
4995
|
+
outputs: ["company"],
|
|
4996
|
+
stageKey: "populated",
|
|
4997
|
+
dependencyMode: "per-record-eligibility",
|
|
4998
|
+
capabilityKey: "lead-gen.company.source",
|
|
4999
|
+
defaultBatchSize: 100,
|
|
5000
|
+
maxBatchSize: 250
|
|
5001
|
+
},
|
|
5002
|
+
analyzeWebsites: {
|
|
5003
|
+
id: "analyze-websites",
|
|
5004
|
+
label: "Websites analyzed",
|
|
5005
|
+
primaryEntity: "company",
|
|
5006
|
+
outputs: ["company"],
|
|
5007
|
+
stageKey: "extracted",
|
|
5008
|
+
dependsOn: ["source-companies"],
|
|
5009
|
+
dependencyMode: "per-record-eligibility",
|
|
5010
|
+
capabilityKey: "lead-gen.company.website-extract",
|
|
5011
|
+
defaultBatchSize: 50,
|
|
5012
|
+
maxBatchSize: 100
|
|
5013
|
+
},
|
|
5014
|
+
qualifyCompanies: {
|
|
5015
|
+
id: "qualify-companies",
|
|
5016
|
+
label: "Companies qualified",
|
|
5017
|
+
primaryEntity: "company",
|
|
5018
|
+
outputs: ["company"],
|
|
5019
|
+
stageKey: "qualified",
|
|
5020
|
+
dependsOn: ["analyze-websites"],
|
|
5021
|
+
dependencyMode: "per-record-eligibility",
|
|
5022
|
+
capabilityKey: "lead-gen.company.qualify",
|
|
5023
|
+
defaultBatchSize: 100,
|
|
5024
|
+
maxBatchSize: 250
|
|
5025
|
+
},
|
|
5026
|
+
findContacts: {
|
|
5027
|
+
id: "find-contacts",
|
|
5028
|
+
label: "Decision-makers found",
|
|
5029
|
+
primaryEntity: "contact",
|
|
5030
|
+
outputs: ["contact"],
|
|
5031
|
+
stageKey: "discovered",
|
|
5032
|
+
dependsOn: ["qualify-companies"],
|
|
5033
|
+
dependencyMode: "per-record-eligibility",
|
|
5034
|
+
capabilityKey: "lead-gen.contact.discover",
|
|
5035
|
+
defaultBatchSize: 50,
|
|
5036
|
+
maxBatchSize: 100
|
|
5037
|
+
},
|
|
5038
|
+
verifyEmails: {
|
|
5039
|
+
id: "verify-emails",
|
|
5040
|
+
label: "Emails verified",
|
|
5041
|
+
primaryEntity: "contact",
|
|
5042
|
+
outputs: ["contact"],
|
|
5043
|
+
stageKey: "verified",
|
|
5044
|
+
dependsOn: ["find-contacts"],
|
|
5045
|
+
dependencyMode: "per-record-eligibility",
|
|
5046
|
+
capabilityKey: "lead-gen.contact.verify-email",
|
|
5047
|
+
defaultBatchSize: 100,
|
|
5048
|
+
maxBatchSize: 500
|
|
5049
|
+
},
|
|
5050
|
+
personalize: {
|
|
5051
|
+
id: "personalize",
|
|
5052
|
+
label: "Personalize",
|
|
5053
|
+
primaryEntity: "contact",
|
|
5054
|
+
outputs: ["contact"],
|
|
5055
|
+
stageKey: "personalized",
|
|
5056
|
+
dependsOn: ["verify-emails"],
|
|
5057
|
+
dependencyMode: "per-record-eligibility",
|
|
5058
|
+
capabilityKey: "lead-gen.contact.personalize",
|
|
5059
|
+
defaultBatchSize: 25,
|
|
5060
|
+
maxBatchSize: 100
|
|
5061
|
+
},
|
|
5062
|
+
review: {
|
|
5063
|
+
id: "review",
|
|
5064
|
+
label: "Reviewed and exported",
|
|
5065
|
+
primaryEntity: "contact",
|
|
5066
|
+
outputs: ["export"],
|
|
5067
|
+
stageKey: "uploaded",
|
|
5068
|
+
dependsOn: ["personalize"],
|
|
5069
|
+
dependencyMode: "per-record-eligibility",
|
|
5070
|
+
capabilityKey: "lead-gen.review.outreach-ready",
|
|
5071
|
+
defaultBatchSize: 25,
|
|
5072
|
+
maxBatchSize: 100
|
|
5073
|
+
}
|
|
5074
|
+
},
|
|
5075
|
+
dtcApolloClickup: {
|
|
5076
|
+
importApolloSearch: {
|
|
5077
|
+
id: "import-apollo-search",
|
|
5078
|
+
label: "Companies found",
|
|
5079
|
+
description: "Pull companies and seed contact data from a predefined Apollo search or list.",
|
|
5080
|
+
primaryEntity: "company",
|
|
5081
|
+
outputs: ["company", "contact"],
|
|
5082
|
+
stageKey: "populated",
|
|
5083
|
+
dependencyMode: "per-record-eligibility",
|
|
5084
|
+
capabilityKey: "lead-gen.company.apollo-import",
|
|
5085
|
+
defaultBatchSize: 250,
|
|
5086
|
+
maxBatchSize: 1e3
|
|
5087
|
+
},
|
|
5088
|
+
analyzeWebsites: {
|
|
5089
|
+
id: "analyze-websites",
|
|
5090
|
+
label: "Websites analyzed",
|
|
5091
|
+
description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
|
|
5092
|
+
primaryEntity: "company",
|
|
5093
|
+
outputs: ["company"],
|
|
5094
|
+
stageKey: "extracted",
|
|
5095
|
+
dependsOn: ["import-apollo-search"],
|
|
5096
|
+
dependencyMode: "per-record-eligibility",
|
|
5097
|
+
capabilityKey: "lead-gen.company.website-extract",
|
|
5098
|
+
defaultBatchSize: 50,
|
|
5099
|
+
maxBatchSize: 100
|
|
5100
|
+
},
|
|
5101
|
+
scoreDtcFit: {
|
|
5102
|
+
id: "score-dtc-fit",
|
|
5103
|
+
label: "Companies qualified",
|
|
5104
|
+
description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
|
|
5105
|
+
primaryEntity: "company",
|
|
5106
|
+
outputs: ["company"],
|
|
5107
|
+
stageKey: "qualified",
|
|
5108
|
+
dependsOn: ["analyze-websites"],
|
|
5109
|
+
dependencyMode: "per-record-eligibility",
|
|
5110
|
+
capabilityKey: "lead-gen.company.dtc-subscription-qualify",
|
|
5111
|
+
defaultBatchSize: 100,
|
|
5112
|
+
maxBatchSize: 250
|
|
5113
|
+
},
|
|
5114
|
+
enrichDecisionMakers: {
|
|
5115
|
+
id: "enrich-decision-makers",
|
|
5116
|
+
label: "Decision-makers found",
|
|
5117
|
+
description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
|
|
5118
|
+
primaryEntity: "company",
|
|
5119
|
+
outputs: ["contact"],
|
|
5120
|
+
stageKey: "decision-makers-enriched",
|
|
5121
|
+
dependsOn: ["score-dtc-fit"],
|
|
5122
|
+
dependencyMode: "per-record-eligibility",
|
|
5123
|
+
capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
5124
|
+
defaultBatchSize: 100,
|
|
5125
|
+
maxBatchSize: 250
|
|
5126
|
+
},
|
|
5127
|
+
verifyEmails: {
|
|
5128
|
+
id: "verify-emails",
|
|
5129
|
+
label: "Emails verified",
|
|
5130
|
+
description: "Verify deliverability before the QC and handoff step.",
|
|
5131
|
+
primaryEntity: "contact",
|
|
5132
|
+
outputs: ["contact"],
|
|
5133
|
+
stageKey: "verified",
|
|
5134
|
+
dependsOn: ["enrich-decision-makers"],
|
|
5135
|
+
dependencyMode: "per-record-eligibility",
|
|
5136
|
+
capabilityKey: "lead-gen.contact.verify-email",
|
|
5137
|
+
defaultBatchSize: 250,
|
|
5138
|
+
maxBatchSize: 500
|
|
5139
|
+
},
|
|
5140
|
+
reviewAndExport: {
|
|
5141
|
+
id: "review-and-export",
|
|
5142
|
+
label: "Reviewed and exported",
|
|
5143
|
+
description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
|
|
5144
|
+
primaryEntity: "company",
|
|
5145
|
+
outputs: ["export"],
|
|
5146
|
+
stageKey: "uploaded",
|
|
5147
|
+
dependsOn: ["verify-emails"],
|
|
5148
|
+
dependencyMode: "per-record-eligibility",
|
|
5149
|
+
capabilityKey: "lead-gen.export.list",
|
|
5150
|
+
defaultBatchSize: 100,
|
|
5151
|
+
maxBatchSize: 250
|
|
5152
|
+
}
|
|
5153
|
+
}
|
|
5154
|
+
};
|
|
5155
|
+
z.object({
|
|
5156
|
+
listEntityId: ModelIdSchema,
|
|
5157
|
+
companyEntityId: ModelIdSchema,
|
|
5158
|
+
contactEntityId: ModelIdSchema,
|
|
5159
|
+
description: DescriptionSchema.optional(),
|
|
5160
|
+
companyStages: z.array(ProspectingLifecycleStageSchema).min(1),
|
|
5161
|
+
contactStages: z.array(ProspectingLifecycleStageSchema).min(1),
|
|
5162
|
+
defaultBuildTemplateId: ModelIdSchema,
|
|
5163
|
+
buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
|
|
5164
|
+
});
|
|
5165
|
+
function toProspectingLifecycleStage(stage) {
|
|
5166
|
+
return {
|
|
5167
|
+
id: stage.key,
|
|
5168
|
+
label: stage.label,
|
|
5169
|
+
order: stage.order
|
|
5170
|
+
};
|
|
5171
|
+
}
|
|
5172
|
+
function leadGenStagesForEntity(entity) {
|
|
5173
|
+
return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity).sort((a, b) => a.order - b.order).map(toProspectingLifecycleStage);
|
|
5174
|
+
}
|
|
5175
|
+
var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
|
|
5176
|
+
companyStages: leadGenStagesForEntity("company"),
|
|
5177
|
+
contactStages: leadGenStagesForEntity("contact"),
|
|
5178
|
+
buildTemplates: [
|
|
5179
|
+
{
|
|
5180
|
+
id: "local-services",
|
|
5181
|
+
label: "Local Services Prospecting",
|
|
5182
|
+
description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
|
|
5183
|
+
steps: [
|
|
5184
|
+
PROSPECTING_STEPS.localServices.sourceCompanies,
|
|
5185
|
+
PROSPECTING_STEPS.localServices.analyzeWebsites,
|
|
5186
|
+
PROSPECTING_STEPS.localServices.qualifyCompanies,
|
|
5187
|
+
PROSPECTING_STEPS.localServices.findContacts,
|
|
5188
|
+
PROSPECTING_STEPS.localServices.verifyEmails,
|
|
5189
|
+
PROSPECTING_STEPS.localServices.personalize,
|
|
5190
|
+
PROSPECTING_STEPS.localServices.review
|
|
5191
|
+
]
|
|
5192
|
+
},
|
|
5193
|
+
{
|
|
5194
|
+
id: "dtc-subscription-apollo-clickup",
|
|
5195
|
+
label: "DTC Subscription Apollo Export",
|
|
5196
|
+
description: "Prospecting pipeline for DTC subscription or subscription-ready brands where Apollo is the source and contact-enrichment layer, Elevasis handles company research and fit scoring, and approved leads export as an approved lead list.",
|
|
5197
|
+
steps: [
|
|
5198
|
+
PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
|
|
5199
|
+
PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
|
|
5200
|
+
PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
|
|
5201
|
+
PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
|
|
5202
|
+
PROSPECTING_STEPS.dtcApolloClickup.verifyEmails,
|
|
5203
|
+
PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
|
|
5204
|
+
]
|
|
5205
|
+
}
|
|
5206
|
+
]
|
|
5207
|
+
};
|
|
5208
|
+
|
|
5209
|
+
// ../core/src/business/acquisition/build-templates.ts
|
|
5210
|
+
var PROSPECTING_BUILD_TEMPLATE_OPTIONS = DEFAULT_ORGANIZATION_MODEL_PROSPECTING.buildTemplates.map(
|
|
5211
|
+
({ id, label, description }) => ({
|
|
5212
|
+
id,
|
|
5213
|
+
label,
|
|
5214
|
+
description
|
|
5215
|
+
})
|
|
5216
|
+
);
|
|
5217
|
+
function isProspectingBuildTemplateId(value) {
|
|
5218
|
+
return PROSPECTING_BUILD_TEMPLATE_OPTIONS.some((template) => template.id === value);
|
|
5219
|
+
}
|
|
5220
|
+
var ProcessingStageStatusSchema = z.enum(["success", "no_result", "skipped", "error"]);
|
|
5221
|
+
var LeadGenStageKeySchema = z.string().refine((value) => Object.prototype.hasOwnProperty.call(LEAD_GEN_STAGE_CATALOG, value), {
|
|
5222
|
+
message: "processing state key must match LEAD_GEN_STAGE_CATALOG"
|
|
5223
|
+
});
|
|
5224
|
+
var LeadGenCapabilityKeySchema = z.string().refine((value) => CAPABILITY_REGISTRY.some((c) => c.id === value), {
|
|
5225
|
+
message: "capabilityKey must match CAPABILITY_REGISTRY"
|
|
5226
|
+
});
|
|
5227
|
+
var crmStageKeys = CRM_PIPELINE_DEFINITION.stages.map((stage) => stage.stageKey);
|
|
5228
|
+
var crmStateKeys = CRM_PIPELINE_DEFINITION.stages.flatMap((stage) => stage.states.map((state) => state.stateKey));
|
|
5229
|
+
var CrmStageKeySchema = z.enum(crmStageKeys);
|
|
5230
|
+
var CrmStateKeySchema = z.enum(crmStateKeys);
|
|
5231
|
+
var ProcessingStateEntrySchema = z.object({
|
|
5232
|
+
status: ProcessingStageStatusSchema,
|
|
5233
|
+
data: z.unknown().optional()
|
|
5234
|
+
}).passthrough();
|
|
5235
|
+
var ProcessingStateSchema = z.record(LeadGenStageKeySchema, ProcessingStateEntrySchema);
|
|
5236
|
+
var CompanyProcessingStateSchema = ProcessingStateSchema;
|
|
5237
|
+
var ContactProcessingStateSchema = ProcessingStateSchema;
|
|
5238
|
+
var DealStageSchema = CrmStageKeySchema;
|
|
5239
|
+
var AcqDealTaskKindSchema = z.enum(["call", "email", "meeting", "other"]);
|
|
5240
|
+
z.object({
|
|
5241
|
+
dealId: UuidSchema
|
|
5242
|
+
});
|
|
5243
|
+
z.object({
|
|
5244
|
+
dealId: UuidSchema,
|
|
5245
|
+
taskId: UuidSchema
|
|
5246
|
+
});
|
|
5247
|
+
z.object({
|
|
5248
|
+
stage: DealStageSchema.optional(),
|
|
5249
|
+
search: z.string().optional(),
|
|
5250
|
+
limit: z.coerce.number().int().positive().default(50),
|
|
5251
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
5252
|
+
}).strict();
|
|
5253
|
+
z.object({
|
|
5254
|
+
search: z.string().trim().min(1).max(200).optional(),
|
|
5255
|
+
limit: z.coerce.number().int().min(1).max(25).default(10)
|
|
5256
|
+
}).strict();
|
|
5257
|
+
z.object({
|
|
5258
|
+
window: z.enum(["overdue", "today", "today_and_overdue", "upcoming"]).optional(),
|
|
5259
|
+
assigneeUserId: UuidSchema.optional()
|
|
5260
|
+
}).strict();
|
|
5261
|
+
z.object({
|
|
5262
|
+
body: z.string().trim().min(1).max(1e4)
|
|
5263
|
+
}).strict();
|
|
5264
|
+
z.object({
|
|
5265
|
+
title: z.string().trim().min(1).max(255),
|
|
5266
|
+
description: z.string().nullable().optional(),
|
|
5267
|
+
kind: AcqDealTaskKindSchema.optional(),
|
|
5268
|
+
dueAt: z.string().datetime().nullable().optional(),
|
|
5269
|
+
assigneeUserId: UuidSchema.nullable().optional()
|
|
5270
|
+
}).strict();
|
|
5271
|
+
z.object({
|
|
5272
|
+
pipelineKey: z.string().min(1),
|
|
5273
|
+
stageKey: z.string().min(1),
|
|
5274
|
+
stateKey: z.string().min(1).nullable().optional(),
|
|
5275
|
+
reason: z.string().optional(),
|
|
5276
|
+
expectedUpdatedAt: z.string().datetime().optional()
|
|
5277
|
+
}).strict();
|
|
5278
|
+
z.object({
|
|
5279
|
+
pipelineKey: z.literal(CRM_PIPELINE_DEFINITION.pipelineKey),
|
|
5280
|
+
stageKey: CrmStageKeySchema,
|
|
5281
|
+
stateKey: CrmStateKeySchema.nullable().optional(),
|
|
5282
|
+
reason: z.string().optional(),
|
|
5283
|
+
expectedUpdatedAt: z.string().datetime().optional()
|
|
5284
|
+
}).strict();
|
|
5285
|
+
z.object({
|
|
5286
|
+
stateKey: CrmStateKeySchema,
|
|
5287
|
+
reason: z.string().optional(),
|
|
5288
|
+
expectedUpdatedAt: z.string().datetime().optional()
|
|
5289
|
+
}).strict();
|
|
5290
|
+
z.object({
|
|
5291
|
+
dealId: UuidSchema,
|
|
5292
|
+
actionKey: NonEmptyStringSchema
|
|
5293
|
+
}).strict();
|
|
5294
|
+
z.object({
|
|
5295
|
+
payload: z.record(z.string(), z.unknown()).optional()
|
|
5296
|
+
}).strict();
|
|
5297
|
+
var DealContactSummarySchema = z.object({
|
|
5298
|
+
id: z.string(),
|
|
5299
|
+
first_name: z.string().nullable(),
|
|
5300
|
+
last_name: z.string().nullable(),
|
|
5301
|
+
email: z.string(),
|
|
5302
|
+
title: z.string().nullable(),
|
|
5303
|
+
headline: z.string().nullable(),
|
|
5304
|
+
linkedin_url: z.string().nullable(),
|
|
5305
|
+
processing_state: ProcessingStateSchema.nullable(),
|
|
5306
|
+
enrichment_data: z.record(z.string(), z.unknown()).nullable(),
|
|
5307
|
+
company: z.object({
|
|
5308
|
+
id: z.string(),
|
|
5309
|
+
name: z.string(),
|
|
5310
|
+
domain: z.string().nullable(),
|
|
5311
|
+
website: z.string().nullable(),
|
|
5312
|
+
linkedin_url: z.string().nullable(),
|
|
5313
|
+
segment: z.string().nullable(),
|
|
5314
|
+
category: z.string().nullable(),
|
|
5315
|
+
num_employees: z.number().nullable()
|
|
5316
|
+
}).nullable()
|
|
5317
|
+
});
|
|
5318
|
+
var DealPrioritySchema = z.object({
|
|
5319
|
+
bucketKey: z.enum(["needs_response", "follow_up_due", "waiting", "stale", "closed_low"]),
|
|
5320
|
+
rank: z.number().int(),
|
|
5321
|
+
label: z.string(),
|
|
5322
|
+
color: z.string(),
|
|
5323
|
+
reason: z.string(),
|
|
5324
|
+
latestActivityAt: z.string().nullable(),
|
|
5325
|
+
nextActionAt: z.string().nullable()
|
|
5326
|
+
});
|
|
5327
|
+
var DealListItemSchema = z.object({
|
|
5328
|
+
// acq_deals columns
|
|
5329
|
+
id: z.string(),
|
|
5330
|
+
organization_id: z.string(),
|
|
5331
|
+
contact_id: z.string().nullable(),
|
|
5332
|
+
contact_email: z.string(),
|
|
5333
|
+
pipeline_key: z.string(),
|
|
5334
|
+
stage_key: z.string().nullable(),
|
|
5335
|
+
state_key: z.string().nullable(),
|
|
5336
|
+
activity_log: z.unknown(),
|
|
5337
|
+
discovery_data: z.unknown().nullable(),
|
|
5338
|
+
discovery_submitted_at: z.string().nullable(),
|
|
5339
|
+
discovery_submitted_by: z.string().nullable(),
|
|
5340
|
+
proposal_data: z.unknown().nullable(),
|
|
5341
|
+
proposal_sent_at: z.string().nullable(),
|
|
5342
|
+
proposal_pdf_url: z.string().nullable(),
|
|
5343
|
+
signature_envelope_id: z.string().nullable(),
|
|
5344
|
+
source_list_id: z.string().nullable(),
|
|
5345
|
+
source_type: z.string().nullable(),
|
|
5346
|
+
initial_fee: z.number().nullable(),
|
|
5347
|
+
monthly_fee: z.number().nullable(),
|
|
5348
|
+
closed_lost_at: z.string().nullable(),
|
|
5349
|
+
closed_lost_reason: z.string().nullable(),
|
|
5350
|
+
created_at: z.string(),
|
|
5351
|
+
updated_at: z.string(),
|
|
5352
|
+
priority: DealPrioritySchema,
|
|
5353
|
+
ownership: z.enum(["us", "them"]).nullable(),
|
|
5354
|
+
nextAction: z.string().nullable(),
|
|
5355
|
+
// joined relation
|
|
5356
|
+
contact: DealContactSummarySchema.nullable()
|
|
5357
|
+
});
|
|
5358
|
+
z.object({
|
|
5359
|
+
data: z.array(DealListItemSchema),
|
|
5360
|
+
total: z.number().int(),
|
|
5361
|
+
limit: z.number().int(),
|
|
5362
|
+
offset: z.number().int()
|
|
5363
|
+
});
|
|
5364
|
+
var DealStageSummarySchema = z.object({
|
|
5365
|
+
stage: z.string(),
|
|
5366
|
+
count: z.number().int(),
|
|
5367
|
+
totalValue: z.number(),
|
|
5368
|
+
oldestUpdatedAt: z.string().nullable(),
|
|
5369
|
+
newestUpdatedAt: z.string().nullable()
|
|
5370
|
+
});
|
|
5371
|
+
var StaleDealSummarySchema = z.object({
|
|
5372
|
+
id: z.string(),
|
|
5373
|
+
contactEmail: z.string(),
|
|
5374
|
+
stageKey: z.string(),
|
|
5375
|
+
updatedAt: z.string(),
|
|
5376
|
+
daysStale: z.number().int()
|
|
5377
|
+
});
|
|
5378
|
+
z.object({
|
|
5379
|
+
totalDeals: z.number().int(),
|
|
5380
|
+
openDeals: z.number().int(),
|
|
5381
|
+
wonDeals: z.number().int(),
|
|
5382
|
+
lostDeals: z.number().int(),
|
|
5383
|
+
winRate: z.number(),
|
|
5384
|
+
avgDealSize: z.number(),
|
|
5385
|
+
totalPipelineValue: z.number(),
|
|
5386
|
+
stageSummary: z.array(DealStageSummarySchema),
|
|
5387
|
+
staleDeals: z.array(StaleDealSummarySchema)
|
|
5388
|
+
});
|
|
5389
|
+
var DealLookupItemSchema = z.object({
|
|
5390
|
+
id: z.string(),
|
|
5391
|
+
contactEmail: z.string(),
|
|
5392
|
+
stageKey: z.string().nullable(),
|
|
5393
|
+
updatedAt: z.string(),
|
|
5394
|
+
contactName: z.string().nullable(),
|
|
5395
|
+
companyName: z.string().nullable(),
|
|
5396
|
+
displayLabel: z.string()
|
|
5397
|
+
});
|
|
5398
|
+
z.array(DealLookupItemSchema);
|
|
5399
|
+
var ConversationMessageSchema = z.object({
|
|
5400
|
+
id: z.string(),
|
|
5401
|
+
direction: z.enum(["inbound", "outbound"]),
|
|
5402
|
+
fromEmail: z.string(),
|
|
5403
|
+
toEmail: z.string(),
|
|
5404
|
+
subject: z.string().nullable(),
|
|
5405
|
+
body: z.string(),
|
|
5406
|
+
sentAt: z.string().nullable()
|
|
5407
|
+
});
|
|
5408
|
+
var DealConversationSchema = z.object({
|
|
5409
|
+
messages: z.array(ConversationMessageSchema)
|
|
5410
|
+
});
|
|
5411
|
+
DealListItemSchema.extend({
|
|
5412
|
+
conversation: DealConversationSchema
|
|
5413
|
+
});
|
|
5414
|
+
var DealNoteResponseSchema = z.object({
|
|
5415
|
+
id: z.string(),
|
|
5416
|
+
dealId: z.string(),
|
|
5417
|
+
organizationId: z.string(),
|
|
5418
|
+
authorUserId: z.string().nullable(),
|
|
5419
|
+
body: z.string(),
|
|
5420
|
+
createdAt: z.string(),
|
|
5421
|
+
updatedAt: z.string()
|
|
5422
|
+
});
|
|
5423
|
+
z.array(DealNoteResponseSchema);
|
|
5424
|
+
var DealTaskResponseSchema = z.object({
|
|
5425
|
+
id: z.string(),
|
|
5426
|
+
organizationId: z.string(),
|
|
5427
|
+
dealId: z.string(),
|
|
5428
|
+
title: z.string(),
|
|
5429
|
+
description: z.string().nullable(),
|
|
5430
|
+
kind: AcqDealTaskKindSchema,
|
|
5431
|
+
dueAt: z.string().nullable(),
|
|
5432
|
+
assigneeUserId: z.string().nullable(),
|
|
5433
|
+
completedAt: z.string().nullable(),
|
|
5434
|
+
completedByUserId: z.string().nullable(),
|
|
5435
|
+
createdAt: z.string(),
|
|
5436
|
+
updatedAt: z.string(),
|
|
5437
|
+
createdByUserId: z.string().nullable()
|
|
5438
|
+
});
|
|
5439
|
+
z.array(DealTaskResponseSchema);
|
|
5440
|
+
var ListStatusSchema = z.enum(["draft", "enriching", "launched", "closing", "archived"]);
|
|
5441
|
+
var ScrapingConfigSchema = z.object({
|
|
5442
|
+
vertical: z.string().trim().max(255).optional(),
|
|
5443
|
+
geography: z.string().trim().max(500).optional(),
|
|
5444
|
+
size: z.string().trim().max(255).optional(),
|
|
5445
|
+
apifyInput: z.record(z.string(), z.unknown()).optional()
|
|
5446
|
+
});
|
|
5447
|
+
var IcpRubricSchema = z.object({
|
|
5448
|
+
qualificationRubricKey: z.string().trim().max(255).nullish(),
|
|
5449
|
+
targetDescription: z.string().optional(),
|
|
5450
|
+
minReviewCount: z.number().int().min(0).optional(),
|
|
5451
|
+
minRating: z.number().min(0).max(5).optional(),
|
|
5452
|
+
excludeFranchises: z.boolean().optional(),
|
|
5453
|
+
customRules: z.string().optional()
|
|
5454
|
+
});
|
|
5455
|
+
var PipelineStageSchema = z.object({
|
|
5456
|
+
key: z.string().refine((value) => Object.prototype.hasOwnProperty.call(LEAD_GEN_STAGE_CATALOG, value), {
|
|
5457
|
+
message: "pipeline stage key must match LEAD_GEN_STAGE_CATALOG"
|
|
5458
|
+
}),
|
|
5459
|
+
label: z.string().optional(),
|
|
5460
|
+
enabled: z.boolean().optional(),
|
|
5461
|
+
order: z.number().int().optional()
|
|
5462
|
+
});
|
|
5463
|
+
var PipelineConfigSchema = z.object({
|
|
5464
|
+
stages: z.array(PipelineStageSchema).optional()
|
|
5465
|
+
});
|
|
5466
|
+
var BuildPlanSnapshotStepSchema = z.object({
|
|
5467
|
+
id: z.string().trim().min(1).max(100),
|
|
5468
|
+
label: z.string().trim().min(1).max(120),
|
|
5469
|
+
description: z.string().trim().min(1).max(2e3).optional(),
|
|
5470
|
+
primaryEntity: z.enum(["company", "contact"]),
|
|
5471
|
+
outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
|
|
5472
|
+
stageKey: LeadGenStageKeySchema,
|
|
5473
|
+
dependsOn: z.array(z.string().trim().min(1).max(100)).optional(),
|
|
5474
|
+
dependencyMode: z.literal("per-record-eligibility"),
|
|
5475
|
+
capabilityKey: LeadGenCapabilityKeySchema,
|
|
5476
|
+
defaultBatchSize: z.number().int().positive(),
|
|
5477
|
+
maxBatchSize: z.number().int().positive()
|
|
5478
|
+
}).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
|
|
5479
|
+
message: "defaultBatchSize must be less than or equal to maxBatchSize",
|
|
5480
|
+
path: ["defaultBatchSize"]
|
|
5481
|
+
});
|
|
5482
|
+
var BuildPlanSnapshotSchema = z.object({
|
|
5483
|
+
templateId: z.string().trim().min(1).max(100),
|
|
5484
|
+
templateLabel: z.string().trim().min(1).max(120),
|
|
5485
|
+
steps: z.array(BuildPlanSnapshotStepSchema).min(1)
|
|
5486
|
+
}).superRefine((snapshot, ctx) => {
|
|
5487
|
+
const stepIds = /* @__PURE__ */ new Set();
|
|
5488
|
+
snapshot.steps.forEach((step, index) => {
|
|
5489
|
+
if (stepIds.has(step.id)) {
|
|
5490
|
+
ctx.addIssue({
|
|
5491
|
+
code: z.ZodIssueCode.custom,
|
|
5492
|
+
message: `duplicate build-plan step id "${step.id}"`,
|
|
5493
|
+
path: ["steps", index, "id"]
|
|
5494
|
+
});
|
|
5495
|
+
}
|
|
5496
|
+
stepIds.add(step.id);
|
|
5497
|
+
});
|
|
5498
|
+
snapshot.steps.forEach((step, index) => {
|
|
5499
|
+
for (const dependencyId of step.dependsOn ?? []) {
|
|
5500
|
+
if (!stepIds.has(dependencyId)) {
|
|
5501
|
+
ctx.addIssue({
|
|
5502
|
+
code: z.ZodIssueCode.custom,
|
|
5503
|
+
message: `dependsOn references unknown build-plan step "${dependencyId}"`,
|
|
5504
|
+
path: ["steps", index, "dependsOn"]
|
|
5505
|
+
});
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
});
|
|
5509
|
+
});
|
|
5510
|
+
var AcqListMetadataSchema = z.object({
|
|
5511
|
+
buildPlanSnapshot: BuildPlanSnapshotSchema.optional()
|
|
5512
|
+
}).catchall(z.unknown());
|
|
5513
|
+
var ProspectingBuildTemplateIdSchema = z.string().trim().min(1).max(100).refine(isProspectingBuildTemplateId, {
|
|
5514
|
+
message: "buildTemplateId must match a known prospecting build template"
|
|
5515
|
+
});
|
|
5516
|
+
var ListStageCountsSchema = z.object({
|
|
5517
|
+
// Attempted counts by canonical lead-gen stage. The detailed status
|
|
5518
|
+
// distribution lives on ListProgress; telemetry keeps the overview payload small.
|
|
5519
|
+
stageCounts: z.object({
|
|
5520
|
+
populated: z.number().int(),
|
|
5521
|
+
extracted: z.number().int(),
|
|
5522
|
+
qualified: z.number().int(),
|
|
5523
|
+
discovered: z.number().int(),
|
|
5524
|
+
verified: z.number().int(),
|
|
5525
|
+
personalized: z.number().int(),
|
|
5526
|
+
uploaded: z.number().int()
|
|
5527
|
+
}),
|
|
5528
|
+
deliverability: z.object({
|
|
5529
|
+
valid: z.number().int(),
|
|
5530
|
+
risky: z.number().int(),
|
|
5531
|
+
invalid: z.number().int(),
|
|
5532
|
+
unknown: z.number().int(),
|
|
5533
|
+
bounced: z.number().int()
|
|
5534
|
+
})
|
|
5535
|
+
});
|
|
5536
|
+
var ListTelemetrySchema = z.object({
|
|
5537
|
+
listId: UuidSchema,
|
|
5538
|
+
totalCompanies: z.number().int(),
|
|
5539
|
+
totalContacts: z.number().int(),
|
|
5540
|
+
stageCounts: ListStageCountsSchema.shape.stageCounts,
|
|
5541
|
+
deliverability: ListStageCountsSchema.shape.deliverability,
|
|
5542
|
+
activeWorkflows: z.array(z.string()).optional()
|
|
5543
|
+
});
|
|
5544
|
+
z.object({
|
|
5545
|
+
listId: UuidSchema
|
|
5546
|
+
});
|
|
5547
|
+
z.object({
|
|
5548
|
+
name: z.string().trim().min(1).max(255),
|
|
5549
|
+
description: z.string().trim().nullable().optional(),
|
|
5550
|
+
status: ListStatusSchema.optional(),
|
|
5551
|
+
buildTemplateId: ProspectingBuildTemplateIdSchema.optional(),
|
|
5552
|
+
scrapingConfig: ScrapingConfigSchema.optional(),
|
|
5553
|
+
icp: IcpRubricSchema.optional(),
|
|
5554
|
+
pipelineConfig: PipelineConfigSchema.optional()
|
|
5555
|
+
}).strict();
|
|
5556
|
+
z.object({
|
|
5557
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
5558
|
+
description: z.string().trim().nullable().optional(),
|
|
5559
|
+
batchIds: z.array(z.string()).optional(),
|
|
5560
|
+
buildTemplateId: ProspectingBuildTemplateIdSchema.optional(),
|
|
5561
|
+
confirmBuildTemplateChange: z.literal(true).optional()
|
|
5562
|
+
}).strict().refine(
|
|
5563
|
+
(data) => data.name !== void 0 || data.description !== void 0 || data.batchIds !== void 0 || data.buildTemplateId !== void 0,
|
|
5564
|
+
{
|
|
5565
|
+
message: "At least one field (name, description, batchIds, or buildTemplateId) must be provided"
|
|
5566
|
+
}
|
|
5567
|
+
).refine((data) => data.buildTemplateId === void 0 || data.confirmBuildTemplateChange === true, {
|
|
5568
|
+
message: "confirmBuildTemplateChange must be true when changing buildTemplateId",
|
|
5569
|
+
path: ["confirmBuildTemplateChange"]
|
|
5570
|
+
});
|
|
5571
|
+
z.object({
|
|
5572
|
+
status: ListStatusSchema
|
|
5573
|
+
}).strict();
|
|
5574
|
+
z.object({
|
|
5575
|
+
scrapingConfig: ScrapingConfigSchema.partial().optional(),
|
|
5576
|
+
icp: IcpRubricSchema.partial().optional(),
|
|
5577
|
+
pipelineConfig: PipelineConfigSchema.partial().optional()
|
|
5578
|
+
}).strict().refine((data) => data.scrapingConfig !== void 0 || data.icp !== void 0 || data.pipelineConfig !== void 0, {
|
|
5579
|
+
message: "At least one of scrapingConfig, icp, or pipelineConfig must be provided"
|
|
5580
|
+
});
|
|
5581
|
+
z.object({
|
|
5582
|
+
companyIds: z.array(UuidSchema).min(1).max(1e3)
|
|
5583
|
+
}).strict();
|
|
5584
|
+
z.object({
|
|
5585
|
+
companyIds: z.array(UuidSchema).min(1).max(1e3)
|
|
5586
|
+
}).strict();
|
|
5587
|
+
z.object({
|
|
5588
|
+
contactIds: z.array(UuidSchema).min(1).max(1e3)
|
|
5589
|
+
}).strict();
|
|
5590
|
+
z.object({
|
|
5591
|
+
executionId: UuidSchema,
|
|
5592
|
+
configSnapshot: z.record(z.string(), z.unknown()).optional()
|
|
5593
|
+
}).strict();
|
|
5594
|
+
var AcqListResponseSchema = z.object({
|
|
5595
|
+
id: z.string(),
|
|
5596
|
+
organizationId: z.string(),
|
|
5597
|
+
name: z.string(),
|
|
5598
|
+
description: z.string().nullable(),
|
|
5599
|
+
batchIds: z.array(z.string()),
|
|
5600
|
+
instantlyCampaignId: z.string().nullable(),
|
|
5601
|
+
/** Lifecycle status (draft | enriching | launched | closing | archived). */
|
|
5602
|
+
status: ListStatusSchema,
|
|
5603
|
+
metadata: AcqListMetadataSchema,
|
|
5604
|
+
launchedAt: z.string().nullable(),
|
|
5605
|
+
completedAt: z.string().nullable(),
|
|
5606
|
+
createdAt: z.string(),
|
|
5607
|
+
/** Scraping criteria stored as jsonb on the row. */
|
|
5608
|
+
scrapingConfig: ScrapingConfigSchema,
|
|
5609
|
+
/** ICP / qualification rubric stored as jsonb on the row. */
|
|
5610
|
+
icp: IcpRubricSchema,
|
|
5611
|
+
/** Pipeline presentation contract stored as jsonb on the row. */
|
|
5612
|
+
pipelineConfig: PipelineConfigSchema
|
|
5613
|
+
});
|
|
5614
|
+
z.array(AcqListResponseSchema);
|
|
5615
|
+
z.array(ListTelemetrySchema);
|
|
5616
|
+
var ListStageProgressSchema = z.object({
|
|
5617
|
+
total: z.number().int().min(0),
|
|
5618
|
+
attempted: z.number().int().min(0),
|
|
5619
|
+
success: z.number().int().min(0),
|
|
5620
|
+
noResult: z.number().int().min(0),
|
|
5621
|
+
skipped: z.number().int().min(0),
|
|
5622
|
+
error: z.number().int().min(0),
|
|
5623
|
+
other: z.number().int().min(0),
|
|
5624
|
+
notAttempted: z.number().int().min(0)
|
|
5625
|
+
});
|
|
5626
|
+
z.object({
|
|
5627
|
+
totalMembers: z.number().int().min(0),
|
|
5628
|
+
totalCompanies: z.number().int().min(0),
|
|
5629
|
+
byCompanyStage: z.record(z.string(), ListStageProgressSchema),
|
|
5630
|
+
byContactStage: z.record(z.string(), ListStageProgressSchema)
|
|
5631
|
+
});
|
|
5632
|
+
var ListExecutionSummarySchema = z.object({
|
|
5633
|
+
executionId: z.string(),
|
|
5634
|
+
resourceId: z.string(),
|
|
5635
|
+
status: z.string(),
|
|
5636
|
+
createdAt: z.string(),
|
|
5637
|
+
completedAt: z.string().nullable(),
|
|
5638
|
+
durationMs: z.number().int().nullable(),
|
|
5639
|
+
input: z.unknown().nullable().optional()
|
|
5640
|
+
});
|
|
5641
|
+
z.array(ListExecutionSummarySchema);
|
|
5642
|
+
var QueryBooleanSchema = z.preprocess((value) => {
|
|
5643
|
+
if (value === "true" || value === "1" || value === true) return true;
|
|
5644
|
+
if (value === "false" || value === "0" || value === false) return false;
|
|
5645
|
+
return value;
|
|
5646
|
+
}, z.boolean());
|
|
5647
|
+
var AcqCompanyStatusSchema = z.enum(["active", "invalid"]);
|
|
5648
|
+
var AcqContactStatusSchema = z.enum(["active", "invalid"]);
|
|
5649
|
+
var AcqEmailValidSchema = z.enum(["VALID", "INVALID", "RISKY", "UNKNOWN"]);
|
|
5650
|
+
z.object({
|
|
5651
|
+
companyId: UuidSchema
|
|
5652
|
+
});
|
|
5653
|
+
z.object({
|
|
5654
|
+
contactId: UuidSchema
|
|
5655
|
+
});
|
|
5656
|
+
z.object({
|
|
5657
|
+
search: z.string().trim().min(1).max(200).optional(),
|
|
5658
|
+
listId: UuidSchema.optional(),
|
|
5659
|
+
domain: z.string().trim().min(1).max(255).optional(),
|
|
5660
|
+
website: z.string().trim().min(1).max(2048).optional(),
|
|
5661
|
+
segment: z.string().trim().min(1).max(255).optional(),
|
|
5662
|
+
category: z.string().trim().min(1).max(255).optional(),
|
|
5663
|
+
pipelineStatus: z.unknown().optional(),
|
|
5664
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
5665
|
+
status: AcqCompanyStatusSchema.optional(),
|
|
5666
|
+
includeAll: QueryBooleanSchema.optional(),
|
|
5667
|
+
limit: z.coerce.number().int().min(1).max(5e3).default(50),
|
|
5668
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
5669
|
+
}).strict();
|
|
5670
|
+
z.object({
|
|
5671
|
+
search: z.string().trim().min(1).max(200).optional(),
|
|
5672
|
+
listId: UuidSchema.optional(),
|
|
5673
|
+
openingLineIsNull: QueryBooleanSchema.optional(),
|
|
5674
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
5675
|
+
contactStatus: AcqContactStatusSchema.optional(),
|
|
5676
|
+
limit: z.coerce.number().int().min(1).max(5e3).default(5e3),
|
|
5677
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
5678
|
+
}).strict();
|
|
5679
|
+
z.object({
|
|
5680
|
+
name: z.string().trim().min(1).max(255),
|
|
5681
|
+
domain: z.string().trim().min(1).max(255).optional(),
|
|
5682
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
5683
|
+
website: z.string().trim().url().optional(),
|
|
5684
|
+
numEmployees: z.number().int().min(0).optional(),
|
|
5685
|
+
foundedYear: z.number().int().optional(),
|
|
5686
|
+
locationCity: z.string().trim().min(1).max(255).optional(),
|
|
5687
|
+
locationState: z.string().trim().min(1).max(255).optional(),
|
|
5688
|
+
category: z.string().trim().min(1).max(255).optional(),
|
|
5689
|
+
source: z.string().trim().min(1).max(255).optional(),
|
|
5690
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
5691
|
+
pipelineStatus: z.unknown().optional(),
|
|
5692
|
+
verticalResearch: z.string().trim().min(1).max(5e3).optional()
|
|
5693
|
+
}).strict();
|
|
5694
|
+
z.object({
|
|
5695
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
5696
|
+
domain: z.string().trim().min(1).max(255).optional(),
|
|
5697
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
5698
|
+
website: z.string().trim().url().optional(),
|
|
5699
|
+
numEmployees: z.number().int().min(0).optional(),
|
|
5700
|
+
foundedYear: z.number().int().optional(),
|
|
5701
|
+
locationCity: z.string().trim().min(1).max(255).optional(),
|
|
5702
|
+
locationState: z.string().trim().min(1).max(255).optional(),
|
|
5703
|
+
category: z.string().trim().min(1).max(255).optional(),
|
|
5704
|
+
segment: z.string().trim().min(1).max(255).optional(),
|
|
5705
|
+
processingState: CompanyProcessingStateSchema.optional(),
|
|
5706
|
+
pipelineStatus: z.unknown().optional(),
|
|
5707
|
+
enrichmentData: z.record(z.string(), z.unknown()).optional(),
|
|
5708
|
+
source: z.string().trim().min(1).max(255).optional(),
|
|
5709
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
5710
|
+
status: AcqCompanyStatusSchema.optional(),
|
|
5711
|
+
verticalResearch: z.string().trim().min(1).max(5e3).nullable().optional()
|
|
5712
|
+
}).strict().refine(
|
|
5713
|
+
(data) => data.name !== void 0 || data.domain !== void 0 || data.linkedinUrl !== void 0 || data.website !== void 0 || data.numEmployees !== void 0 || data.foundedYear !== void 0 || data.locationCity !== void 0 || data.locationState !== void 0 || data.category !== void 0 || data.segment !== void 0 || data.processingState !== void 0 || data.pipelineStatus !== void 0 || data.enrichmentData !== void 0 || data.source !== void 0 || data.batchId !== void 0 || data.status !== void 0 || data.verticalResearch !== void 0,
|
|
5714
|
+
{
|
|
5715
|
+
message: "At least one field must be provided"
|
|
5716
|
+
}
|
|
5717
|
+
);
|
|
5718
|
+
z.object({
|
|
5719
|
+
email: z.string().trim().email(),
|
|
5720
|
+
companyId: UuidSchema.optional(),
|
|
5721
|
+
firstName: z.string().trim().min(1).max(255).optional(),
|
|
5722
|
+
lastName: z.string().trim().min(1).max(255).optional(),
|
|
5723
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
5724
|
+
title: z.string().trim().min(1).max(255).optional(),
|
|
5725
|
+
source: z.string().trim().min(1).max(255).optional(),
|
|
5726
|
+
sourceId: z.string().trim().min(1).max(255).optional(),
|
|
5727
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
5728
|
+
pipelineStatus: z.unknown().optional()
|
|
5729
|
+
}).strict();
|
|
5730
|
+
z.object({
|
|
5731
|
+
companyId: UuidSchema.optional(),
|
|
5732
|
+
emailValid: AcqEmailValidSchema.optional(),
|
|
5733
|
+
firstName: z.string().trim().min(1).max(255).optional(),
|
|
5734
|
+
lastName: z.string().trim().min(1).max(255).optional(),
|
|
5735
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
5736
|
+
title: z.string().trim().min(1).max(255).optional(),
|
|
5737
|
+
headline: z.string().trim().min(1).max(5e3).optional(),
|
|
5738
|
+
filterReason: z.string().trim().min(1).max(5e3).optional(),
|
|
5739
|
+
openingLine: z.string().trim().min(1).max(5e3).optional(),
|
|
5740
|
+
processingState: ContactProcessingStateSchema.optional(),
|
|
5741
|
+
pipelineStatus: z.unknown().optional(),
|
|
5742
|
+
enrichmentData: z.record(z.string(), z.unknown()).optional(),
|
|
5743
|
+
status: AcqContactStatusSchema.optional()
|
|
5744
|
+
}).strict().refine(
|
|
5745
|
+
(data) => data.companyId !== void 0 || data.emailValid !== void 0 || data.firstName !== void 0 || data.lastName !== void 0 || data.linkedinUrl !== void 0 || data.title !== void 0 || data.headline !== void 0 || data.filterReason !== void 0 || data.openingLine !== void 0 || data.processingState !== void 0 || data.pipelineStatus !== void 0 || data.enrichmentData !== void 0 || data.status !== void 0,
|
|
5746
|
+
{
|
|
5747
|
+
message: "At least one field must be provided"
|
|
5748
|
+
}
|
|
5749
|
+
);
|
|
5750
|
+
var AcqCompanyResponseSchema = z.object({
|
|
5751
|
+
id: z.string(),
|
|
5752
|
+
organizationId: z.string(),
|
|
5753
|
+
name: z.string(),
|
|
5754
|
+
domain: z.string().nullable(),
|
|
5755
|
+
linkedinUrl: z.string().nullable(),
|
|
5756
|
+
website: z.string().nullable(),
|
|
5757
|
+
numEmployees: z.number().nullable(),
|
|
5758
|
+
foundedYear: z.number().nullable(),
|
|
5759
|
+
locationCity: z.string().nullable(),
|
|
5760
|
+
locationState: z.string().nullable(),
|
|
5761
|
+
category: z.string().nullable(),
|
|
5762
|
+
categoryPain: z.string().nullable(),
|
|
5763
|
+
segment: z.string().nullable(),
|
|
5764
|
+
processingState: CompanyProcessingStateSchema.nullable(),
|
|
5765
|
+
pipelineStatus: z.unknown().nullable().optional(),
|
|
5766
|
+
enrichmentData: z.record(z.string(), z.unknown()).nullable(),
|
|
5767
|
+
source: z.string().nullable(),
|
|
5768
|
+
batchId: z.string().nullable(),
|
|
5769
|
+
status: AcqCompanyStatusSchema,
|
|
5770
|
+
contactCount: z.number().int().min(0),
|
|
5771
|
+
verticalResearch: z.string().nullable(),
|
|
5772
|
+
createdAt: z.string(),
|
|
5773
|
+
updatedAt: z.string()
|
|
5774
|
+
});
|
|
5775
|
+
z.object({
|
|
5776
|
+
data: z.array(AcqCompanyResponseSchema),
|
|
5777
|
+
total: z.number().int(),
|
|
5778
|
+
limit: z.number().int(),
|
|
5779
|
+
offset: z.number().int()
|
|
5780
|
+
});
|
|
5781
|
+
z.object({
|
|
5782
|
+
segments: z.array(z.string()),
|
|
5783
|
+
categories: z.array(z.string()),
|
|
5784
|
+
statuses: z.array(AcqCompanyStatusSchema)
|
|
5785
|
+
});
|
|
5786
|
+
var AcqContactCompanySummarySchema = z.object({
|
|
5787
|
+
id: z.string(),
|
|
5788
|
+
name: z.string(),
|
|
5789
|
+
domain: z.string().nullable(),
|
|
5790
|
+
website: z.string().nullable(),
|
|
5791
|
+
linkedinUrl: z.string().nullable(),
|
|
5792
|
+
segment: z.string().nullable(),
|
|
5793
|
+
category: z.string().nullable(),
|
|
5794
|
+
status: AcqCompanyStatusSchema
|
|
5795
|
+
});
|
|
5796
|
+
var AcqContactResponseSchema = z.object({
|
|
5797
|
+
id: z.string(),
|
|
5798
|
+
organizationId: z.string(),
|
|
5799
|
+
companyId: z.string().nullable(),
|
|
5800
|
+
email: z.string(),
|
|
5801
|
+
emailValid: AcqEmailValidSchema.nullable(),
|
|
5802
|
+
firstName: z.string().nullable(),
|
|
5803
|
+
lastName: z.string().nullable(),
|
|
5804
|
+
linkedinUrl: z.string().nullable(),
|
|
5805
|
+
title: z.string().nullable(),
|
|
5806
|
+
headline: z.string().nullable(),
|
|
5807
|
+
filterReason: z.string().nullable(),
|
|
5808
|
+
openingLine: z.string().nullable(),
|
|
5809
|
+
source: z.string().nullable(),
|
|
5810
|
+
sourceId: z.string().nullable(),
|
|
5811
|
+
processingState: ContactProcessingStateSchema.nullable(),
|
|
5812
|
+
pipelineStatus: z.unknown().nullable().optional(),
|
|
5813
|
+
enrichmentData: z.record(z.string(), z.unknown()).nullable(),
|
|
5814
|
+
attioPersonId: z.string().nullable(),
|
|
5815
|
+
batchId: z.string().nullable(),
|
|
5816
|
+
status: AcqContactStatusSchema,
|
|
5817
|
+
company: AcqContactCompanySummarySchema.nullable().optional(),
|
|
5818
|
+
createdAt: z.string(),
|
|
5819
|
+
updatedAt: z.string()
|
|
5820
|
+
});
|
|
5821
|
+
z.object({
|
|
5822
|
+
data: z.array(AcqContactResponseSchema),
|
|
5823
|
+
total: z.number().int(),
|
|
5824
|
+
limit: z.number().int(),
|
|
5825
|
+
offset: z.number().int()
|
|
5826
|
+
});
|
|
5827
|
+
var AcqArtifactOwnerKindSchema = z.enum(["company", "contact", "deal", "list", "list_member"]);
|
|
5828
|
+
z.object({
|
|
5829
|
+
ownerKind: AcqArtifactOwnerKindSchema,
|
|
5830
|
+
ownerId: UuidSchema
|
|
5831
|
+
}).strict();
|
|
5832
|
+
z.object({
|
|
5833
|
+
ownerKind: AcqArtifactOwnerKindSchema,
|
|
5834
|
+
ownerId: UuidSchema,
|
|
5835
|
+
kind: z.string().trim().min(1).max(255),
|
|
5836
|
+
content: z.record(z.string(), z.unknown()),
|
|
5837
|
+
sourceExecutionId: UuidSchema.optional()
|
|
5838
|
+
}).strict();
|
|
5839
|
+
var AcqArtifactResponseSchema = z.object({
|
|
5840
|
+
id: z.string(),
|
|
5841
|
+
organizationId: z.string(),
|
|
5842
|
+
ownerKind: z.string(),
|
|
5843
|
+
ownerId: z.string(),
|
|
5844
|
+
kind: z.string(),
|
|
5845
|
+
content: z.record(z.string(), z.unknown()),
|
|
5846
|
+
sourceExecutionId: z.string().nullable(),
|
|
5847
|
+
createdBy: z.string().nullable(),
|
|
5848
|
+
createdAt: z.string(),
|
|
5849
|
+
version: z.number().int()
|
|
5850
|
+
});
|
|
5851
|
+
z.object({
|
|
5852
|
+
artifacts: z.array(AcqArtifactResponseSchema)
|
|
5853
|
+
});
|
|
5854
|
+
z.object({
|
|
5855
|
+
limit: z.coerce.number().int().min(1).max(500).default(50),
|
|
5856
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
5857
|
+
}).strict();
|
|
5858
|
+
z.object({
|
|
5859
|
+
memberId: UuidSchema
|
|
5860
|
+
});
|
|
5861
|
+
var AcqListMemberContactSummarySchema = z.object({
|
|
5862
|
+
id: z.string(),
|
|
5863
|
+
email: z.string(),
|
|
5864
|
+
firstName: z.string().nullable(),
|
|
5865
|
+
lastName: z.string().nullable(),
|
|
5866
|
+
title: z.string().nullable(),
|
|
5867
|
+
linkedinUrl: z.string().nullable(),
|
|
5868
|
+
companyId: z.string().nullable()
|
|
5869
|
+
});
|
|
5870
|
+
var AcqListMemberResponseSchema = z.object({
|
|
5871
|
+
id: z.string(),
|
|
5872
|
+
listId: z.string(),
|
|
5873
|
+
contactId: z.string(),
|
|
5874
|
+
pipelineKey: z.string(),
|
|
5875
|
+
stageKey: z.string(),
|
|
5876
|
+
stateKey: z.string(),
|
|
5877
|
+
activityLog: z.unknown(),
|
|
5878
|
+
addedAt: z.string(),
|
|
5879
|
+
addedBy: z.string().nullable(),
|
|
5880
|
+
sourceExecutionId: z.string().nullable(),
|
|
5881
|
+
contact: AcqListMemberContactSummarySchema.nullable()
|
|
5882
|
+
});
|
|
5883
|
+
z.object({
|
|
5884
|
+
members: z.array(AcqListMemberResponseSchema)
|
|
5885
|
+
});
|
|
5886
|
+
z.object({
|
|
5887
|
+
listCompanyId: UuidSchema
|
|
5888
|
+
});
|
|
5889
|
+
z.object({
|
|
5890
|
+
id: z.string(),
|
|
5891
|
+
listId: z.string(),
|
|
5892
|
+
companyId: z.string(),
|
|
5893
|
+
pipelineKey: z.string(),
|
|
5894
|
+
stageKey: z.string(),
|
|
5895
|
+
stateKey: z.string(),
|
|
5896
|
+
activityLog: z.unknown(),
|
|
5897
|
+
addedAt: z.string(),
|
|
5898
|
+
addedBy: z.string().nullable(),
|
|
5899
|
+
sourceExecutionId: z.string().nullable()
|
|
5900
|
+
});
|
|
4583
5901
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
4584
5902
|
"rate_limit_exceeded",
|
|
4585
5903
|
"network_error",
|
|
@@ -5067,7 +6385,9 @@ var list = createAdapter("list", [
|
|
|
5067
6385
|
"getConfig",
|
|
5068
6386
|
"recordExecution",
|
|
5069
6387
|
"updateCompanyStage",
|
|
5070
|
-
"updateContactStage"
|
|
6388
|
+
"updateContactStage",
|
|
6389
|
+
"listPendingCompanyIds",
|
|
6390
|
+
"listPendingContactIds"
|
|
5071
6391
|
]);
|
|
5072
6392
|
|
|
5073
6393
|
// src/worker/adapters/pdf.ts
|
|
@@ -5081,6 +6401,191 @@ var execution = createAdapter("execution", ["trigger", "triggerAsync"]);
|
|
|
5081
6401
|
|
|
5082
6402
|
// src/worker/adapters/email.ts
|
|
5083
6403
|
var email = createAdapter("email", ["send"]);
|
|
6404
|
+
var listBuilderStageKeys = Object.keys(LEAD_GEN_STAGE_CATALOG);
|
|
6405
|
+
var ListBuilderStageKeySchema = z.enum(listBuilderStageKeys);
|
|
6406
|
+
|
|
6407
|
+
// src/worker/list-builder-workflow.ts
|
|
6408
|
+
var ListBuilderResultSchema = z.object({
|
|
6409
|
+
entity: z.enum(["company", "contact"]),
|
|
6410
|
+
id: z.string().min(1),
|
|
6411
|
+
status: ProcessingStageStatusSchema,
|
|
6412
|
+
stageKey: ListBuilderStageKeySchema.optional(),
|
|
6413
|
+
data: z.unknown().optional()
|
|
6414
|
+
});
|
|
6415
|
+
var ListBuilderResultsSchema = z.array(ListBuilderResultSchema);
|
|
6416
|
+
function getObjectShape(schema) {
|
|
6417
|
+
const candidate = schema;
|
|
6418
|
+
if ("shape" in candidate && candidate.shape && typeof candidate.shape === "object") {
|
|
6419
|
+
return candidate.shape;
|
|
6420
|
+
}
|
|
6421
|
+
return null;
|
|
6422
|
+
}
|
|
6423
|
+
function assertNoReservedInputKeys(schema) {
|
|
6424
|
+
const shape = getObjectShape(schema);
|
|
6425
|
+
if (!shape) {
|
|
6426
|
+
return;
|
|
6427
|
+
}
|
|
6428
|
+
const reservedKeys = ["params", "batch"].filter((key) => Object.prototype.hasOwnProperty.call(shape, key));
|
|
6429
|
+
if (reservedKeys.length > 0) {
|
|
6430
|
+
throw new Error(`listBuilderWorkflow inputSchema cannot define reserved top-level key(s): ${reservedKeys.join(", ")}`);
|
|
6431
|
+
}
|
|
6432
|
+
}
|
|
6433
|
+
function resolveListAdapter(context) {
|
|
6434
|
+
const contextWithAdapters = context;
|
|
6435
|
+
return contextWithAdapters.adapters?.list ?? list;
|
|
6436
|
+
}
|
|
6437
|
+
function getRecordId(record) {
|
|
6438
|
+
return record.id;
|
|
6439
|
+
}
|
|
6440
|
+
function assertResultStageTarget(result, defaultStageKey) {
|
|
6441
|
+
const stageKey = result.stageKey ?? defaultStageKey;
|
|
6442
|
+
const catalogEntry = LEAD_GEN_STAGE_CATALOG[stageKey];
|
|
6443
|
+
if (!catalogEntry) {
|
|
6444
|
+
throw new Error(`listBuilderWorkflow result stageKey "${stageKey}" is not in LEAD_GEN_STAGE_CATALOG`);
|
|
6445
|
+
}
|
|
6446
|
+
if (catalogEntry.entity !== result.entity) {
|
|
6447
|
+
throw new Error(
|
|
6448
|
+
`listBuilderWorkflow result for ${result.entity} "${result.id}" targets ${catalogEntry.entity} stage "${stageKey}"; set result.stageKey to a ${result.entity} stage`
|
|
6449
|
+
);
|
|
6450
|
+
}
|
|
6451
|
+
return stageKey;
|
|
6452
|
+
}
|
|
6453
|
+
async function filterPendingRecords(records, params, context, options) {
|
|
6454
|
+
if (params.forceRefresh) {
|
|
6455
|
+
return records;
|
|
6456
|
+
}
|
|
6457
|
+
if (!params.listId) {
|
|
6458
|
+
if (params.batchId) {
|
|
6459
|
+
context.logger.warn(
|
|
6460
|
+
`[list-builder] batchId-only input for stage "${options.buildStep.stageKey}" cannot apply pending-ID filter; processing loaded records without resolving batchId to listId.`
|
|
6461
|
+
);
|
|
6462
|
+
}
|
|
6463
|
+
return records;
|
|
6464
|
+
}
|
|
6465
|
+
const listAdapter = resolveListAdapter(context);
|
|
6466
|
+
const limit = typeof params.limit === "number" ? params.limit : void 0;
|
|
6467
|
+
const pendingIds = options.buildStep.primaryEntity === "company" ? await listAdapter.listPendingCompanyIds({ listId: params.listId, stageKey: options.buildStep.stageKey, limit }) : await listAdapter.listPendingContactIds({ listId: params.listId, stageKey: options.buildStep.stageKey, limit });
|
|
6468
|
+
const pending = new Set(pendingIds);
|
|
6469
|
+
return records.filter((record) => pending.has(getRecordId(record)));
|
|
6470
|
+
}
|
|
6471
|
+
async function dispatchResults(envelope, context) {
|
|
6472
|
+
if (!envelope.batch.listId) {
|
|
6473
|
+
if (envelope.results.length > 0) {
|
|
6474
|
+
context.logger.warn(
|
|
6475
|
+
`[list-builder] stage "${envelope.batch.stageKey}" produced ${envelope.results.length} result(s), but no listId was provided; stage updates were skipped.`
|
|
6476
|
+
);
|
|
6477
|
+
}
|
|
6478
|
+
return envelope.results;
|
|
6479
|
+
}
|
|
6480
|
+
const listAdapter = resolveListAdapter(context);
|
|
6481
|
+
for (const result of envelope.results) {
|
|
6482
|
+
const stage = assertResultStageTarget(result, envelope.batch.stageKey);
|
|
6483
|
+
if (result.entity === "company") {
|
|
6484
|
+
await listAdapter.updateCompanyStage({
|
|
6485
|
+
listId: envelope.batch.listId,
|
|
6486
|
+
companyId: result.id,
|
|
6487
|
+
stage,
|
|
6488
|
+
status: result.status,
|
|
6489
|
+
...result.data !== void 0 ? { data: result.data } : {},
|
|
6490
|
+
executionId: context.executionId
|
|
6491
|
+
});
|
|
6492
|
+
continue;
|
|
6493
|
+
}
|
|
6494
|
+
await listAdapter.updateContactStage({
|
|
6495
|
+
listId: envelope.batch.listId,
|
|
6496
|
+
contactId: result.id,
|
|
6497
|
+
stage,
|
|
6498
|
+
status: result.status,
|
|
6499
|
+
...result.data !== void 0 ? { data: result.data } : {},
|
|
6500
|
+
executionId: context.executionId
|
|
6501
|
+
});
|
|
6502
|
+
}
|
|
6503
|
+
return envelope.results;
|
|
6504
|
+
}
|
|
6505
|
+
function listBuilderWorkflow(options) {
|
|
6506
|
+
const stageKey = ListBuilderStageKeySchema.parse(options.buildStep.stageKey);
|
|
6507
|
+
assertNoReservedInputKeys(options.inputSchema);
|
|
6508
|
+
const outputSchema = options.outputSchema ?? ListBuilderResultsSchema;
|
|
6509
|
+
const batchSchema = z.object({
|
|
6510
|
+
records: z.array(z.object({ id: z.string().min(1) }).passthrough()),
|
|
6511
|
+
stageKey: ListBuilderStageKeySchema,
|
|
6512
|
+
listId: z.string().optional()
|
|
6513
|
+
});
|
|
6514
|
+
const envelopeSchema = z.object({
|
|
6515
|
+
params: options.inputSchema,
|
|
6516
|
+
batch: batchSchema,
|
|
6517
|
+
results: ListBuilderResultsSchema
|
|
6518
|
+
});
|
|
6519
|
+
return {
|
|
6520
|
+
config: options.config,
|
|
6521
|
+
contract: {
|
|
6522
|
+
inputSchema: options.inputSchema,
|
|
6523
|
+
outputSchema
|
|
6524
|
+
},
|
|
6525
|
+
stageImplemented: stageKey,
|
|
6526
|
+
steps: {
|
|
6527
|
+
"prepare-batch": {
|
|
6528
|
+
id: "prepare-batch",
|
|
6529
|
+
name: `Prepare ${options.buildStep.label}`,
|
|
6530
|
+
description: `Load and filter records for ${options.buildStep.label}.`,
|
|
6531
|
+
inputSchema: options.inputSchema,
|
|
6532
|
+
outputSchema: envelopeSchema,
|
|
6533
|
+
handler: async (rawInput, context) => {
|
|
6534
|
+
const params = options.inputSchema.parse(rawInput);
|
|
6535
|
+
const runtimeContext = context;
|
|
6536
|
+
const initialRecords = await options.loadRecords(params, context);
|
|
6537
|
+
const additionallyFilteredRecords = options.additionalFilter ? await options.additionalFilter(initialRecords, params) : initialRecords;
|
|
6538
|
+
const records = await filterPendingRecords(
|
|
6539
|
+
additionallyFilteredRecords,
|
|
6540
|
+
params,
|
|
6541
|
+
runtimeContext,
|
|
6542
|
+
options
|
|
6543
|
+
);
|
|
6544
|
+
return {
|
|
6545
|
+
params,
|
|
6546
|
+
batch: {
|
|
6547
|
+
records,
|
|
6548
|
+
stageKey,
|
|
6549
|
+
listId: params.listId
|
|
6550
|
+
},
|
|
6551
|
+
results: []
|
|
6552
|
+
};
|
|
6553
|
+
},
|
|
6554
|
+
next: { type: "linear", target: "run-handler" }
|
|
6555
|
+
},
|
|
6556
|
+
"run-handler": {
|
|
6557
|
+
id: "run-handler",
|
|
6558
|
+
name: options.buildStep.label,
|
|
6559
|
+
description: options.buildStep.description ?? `Process ${options.buildStep.label}.`,
|
|
6560
|
+
inputSchema: envelopeSchema,
|
|
6561
|
+
outputSchema: envelopeSchema,
|
|
6562
|
+
handler: async (rawInput, context) => {
|
|
6563
|
+
const envelope = envelopeSchema.parse(rawInput);
|
|
6564
|
+
const results = await options.handler(envelope, context);
|
|
6565
|
+
return {
|
|
6566
|
+
...envelope,
|
|
6567
|
+
results: ListBuilderResultsSchema.parse(results)
|
|
6568
|
+
};
|
|
6569
|
+
},
|
|
6570
|
+
next: { type: "linear", target: "dispatch-results" }
|
|
6571
|
+
},
|
|
6572
|
+
"dispatch-results": {
|
|
6573
|
+
id: "dispatch-results",
|
|
6574
|
+
name: `Dispatch ${options.buildStep.label} Results`,
|
|
6575
|
+
description: `Persist ${options.buildStep.stageKey} processing-state results.`,
|
|
6576
|
+
inputSchema: envelopeSchema,
|
|
6577
|
+
outputSchema,
|
|
6578
|
+
handler: async (rawInput, context) => {
|
|
6579
|
+
const envelope = envelopeSchema.parse(rawInput);
|
|
6580
|
+
const results = await dispatchResults(envelope, context);
|
|
6581
|
+
return outputSchema.parse(results);
|
|
6582
|
+
},
|
|
6583
|
+
next: null
|
|
6584
|
+
}
|
|
6585
|
+
},
|
|
6586
|
+
entryPoint: "prepare-batch"
|
|
6587
|
+
};
|
|
6588
|
+
}
|
|
5084
6589
|
|
|
5085
6590
|
// src/worker/index.ts
|
|
5086
6591
|
function captureConsole(executionId, logs) {
|
|
@@ -5452,4 +6957,4 @@ if (workerData != null && workerData.kind === "static") {
|
|
|
5452
6957
|
})();
|
|
5453
6958
|
}
|
|
5454
6959
|
|
|
5455
|
-
export { PlatformToolError, acqDb, approval, createAdapter, createAnymailfinderAdapter, createApifyAdapter, createAttioAdapter, createDropboxAdapter, createGmailAdapter, createGoogleSheetsAdapter, createInstantlyAdapter, createMillionVerifierAdapter, createResendAdapter, createSignatureApiAdapter, createStripeAdapter, createTombaAdapter, crm, email, executeWorkflow, execution, list, llm, notifications, pdf, platform, projects, scheduler, startWorker, storage };
|
|
6960
|
+
export { ListBuilderResultSchema, ListBuilderResultsSchema, PlatformToolError, acqDb, approval, createAdapter, createAnymailfinderAdapter, createApifyAdapter, createAttioAdapter, createDropboxAdapter, createGmailAdapter, createGoogleSheetsAdapter, createInstantlyAdapter, createMillionVerifierAdapter, createResendAdapter, createSignatureApiAdapter, createStripeAdapter, createTombaAdapter, crm, email, executeWorkflow, execution, list, listBuilderWorkflow, llm, notifications, pdf, platform, projects, scheduler, startWorker, storage };
|