@elevasis/core 0.18.0 → 0.20.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 +82 -1
- package/dist/index.js +353 -171
- package/dist/knowledge/index.d.ts +44 -1
- package/dist/organization-model/index.d.ts +82 -1
- package/dist/organization-model/index.js +353 -171
- package/dist/test-utils/index.d.ts +41 -12
- package/dist/test-utils/index.js +352 -171
- package/package.json +4 -3
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +89 -69
- package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -0
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -128
- package/src/business/acquisition/api-schemas.test.ts +199 -15
- package/src/business/acquisition/api-schemas.ts +116 -51
- package/src/business/acquisition/build-templates.test.ts +212 -0
- package/src/business/acquisition/derive-actions.test.ts +1 -1
- package/src/business/acquisition/types.ts +21 -38
- package/src/business/deals/api-schemas.ts +2 -2
- package/src/execution/engine/index.ts +436 -434
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -0
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -0
- package/src/execution/engine/tools/lead-service-types.ts +51 -9
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -6
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -5
- package/src/execution/engine/tools/platform/acquisition/types.ts +20 -9
- package/src/execution/engine/tools/registry.ts +700 -698
- package/src/execution/engine/tools/tool-maps.ts +10 -0
- package/src/execution/external/__tests__/api-schemas.test.ts +127 -0
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -6
- package/src/integrations/oauth/provider-registry.ts +74 -61
- package/src/integrations/oauth/server/credentials.ts +43 -39
- package/src/knowledge/__tests__/queries.test.ts +89 -0
- package/src/organization-model/__tests__/graph.test.ts +108 -2
- package/src/organization-model/__tests__/icons.test.ts +61 -0
- package/src/organization-model/__tests__/knowledge.test.ts +118 -1
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +91 -0
- package/src/organization-model/__tests__/schema.test.ts +122 -0
- package/src/organization-model/__tests__/surface-projection.test.ts +174 -0
- package/src/organization-model/defaults.ts +8 -0
- package/src/organization-model/domains/knowledge.ts +9 -0
- package/src/organization-model/domains/prospecting.ts +347 -226
- package/src/organization-model/domains/sales.ts +40 -30
- package/src/organization-model/graph/build.ts +74 -0
- package/src/organization-model/graph/schema.ts +1 -0
- package/src/organization-model/graph/types.ts +1 -0
- package/src/organization-model/icons.ts +3 -0
- package/src/organization-model/schema.ts +63 -0
- package/src/organization-model/surface-projection.ts +218 -0
- package/src/organization-model/types.ts +9 -1
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/utils/__tests__/validation.test.ts +1084 -1083
- package/src/platform/utils/validation.ts +425 -425
- package/src/reference/_generated/contracts.md +89 -69
- package/src/server.ts +6 -0
- package/src/supabase/database.types.ts +6 -12
|
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
// src/organization-model/schema.ts
|
|
4
4
|
var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
5
5
|
"nav.dashboard",
|
|
6
|
+
"nav.calendar",
|
|
6
7
|
"nav.sales",
|
|
7
8
|
"nav.crm",
|
|
8
9
|
"nav.lead-gen",
|
|
@@ -17,6 +18,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
|
17
18
|
"knowledge.strategy",
|
|
18
19
|
"knowledge.reference",
|
|
19
20
|
"feature.dashboard",
|
|
21
|
+
"feature.calendar",
|
|
20
22
|
"feature.sales",
|
|
21
23
|
"feature.crm",
|
|
22
24
|
"feature.finance",
|
|
@@ -40,6 +42,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
|
40
42
|
"integration.google-sheets",
|
|
41
43
|
"integration.attio",
|
|
42
44
|
"surface.dashboard",
|
|
45
|
+
"surface.calendar",
|
|
43
46
|
"surface.overview",
|
|
44
47
|
"surface.command-view",
|
|
45
48
|
"surface.command-queue",
|
|
@@ -220,6 +223,89 @@ var DEFAULT_ORGANIZATION_MODEL_SALES = {
|
|
|
220
223
|
}
|
|
221
224
|
]
|
|
222
225
|
};
|
|
226
|
+
var LEAD_GEN_STAGE_CATALOG = {
|
|
227
|
+
// Prospecting — company population
|
|
228
|
+
scraped: {
|
|
229
|
+
key: "scraped",
|
|
230
|
+
label: "Scraped",
|
|
231
|
+
description: "Company was scraped from a source directory (Apify actor run).",
|
|
232
|
+
order: 1,
|
|
233
|
+
entity: "company"
|
|
234
|
+
},
|
|
235
|
+
populated: {
|
|
236
|
+
key: "populated",
|
|
237
|
+
label: "Companies found",
|
|
238
|
+
description: "Companies have been found and added to the lead-gen list.",
|
|
239
|
+
order: 2,
|
|
240
|
+
entity: "company"
|
|
241
|
+
},
|
|
242
|
+
extracted: {
|
|
243
|
+
key: "extracted",
|
|
244
|
+
label: "Websites analyzed",
|
|
245
|
+
description: "Company websites have been analyzed for business signals.",
|
|
246
|
+
order: 3,
|
|
247
|
+
entity: "company"
|
|
248
|
+
},
|
|
249
|
+
enriched: {
|
|
250
|
+
key: "enriched",
|
|
251
|
+
label: "Enriched",
|
|
252
|
+
description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
|
|
253
|
+
order: 4,
|
|
254
|
+
entity: "company"
|
|
255
|
+
},
|
|
256
|
+
"decision-makers-enriched": {
|
|
257
|
+
key: "decision-makers-enriched",
|
|
258
|
+
label: "Decision-makers found",
|
|
259
|
+
description: "Decision-maker contacts discovered and attached to a qualified company.",
|
|
260
|
+
order: 6,
|
|
261
|
+
entity: "company"
|
|
262
|
+
},
|
|
263
|
+
// Prospecting — contact discovery
|
|
264
|
+
discovered: {
|
|
265
|
+
key: "discovered",
|
|
266
|
+
label: "Decision-makers found",
|
|
267
|
+
description: "Decision-maker contact details have been found.",
|
|
268
|
+
order: 5,
|
|
269
|
+
entity: "contact"
|
|
270
|
+
},
|
|
271
|
+
verified: {
|
|
272
|
+
key: "verified",
|
|
273
|
+
label: "Emails verified",
|
|
274
|
+
description: "Contact email addresses have been checked for deliverability.",
|
|
275
|
+
order: 7,
|
|
276
|
+
entity: "contact"
|
|
277
|
+
},
|
|
278
|
+
// Qualification
|
|
279
|
+
qualified: {
|
|
280
|
+
key: "qualified",
|
|
281
|
+
label: "Companies qualified",
|
|
282
|
+
description: "Companies have been scored against the qualification criteria.",
|
|
283
|
+
order: 8,
|
|
284
|
+
entity: "company"
|
|
285
|
+
},
|
|
286
|
+
// Outreach
|
|
287
|
+
personalized: {
|
|
288
|
+
key: "personalized",
|
|
289
|
+
label: "Personalized",
|
|
290
|
+
description: "Outreach message personalized for the contact (Instantly personalization workflow).",
|
|
291
|
+
order: 9,
|
|
292
|
+
entity: "contact"
|
|
293
|
+
},
|
|
294
|
+
uploaded: {
|
|
295
|
+
key: "uploaded",
|
|
296
|
+
label: "Reviewed and exported",
|
|
297
|
+
description: "Approved records have been reviewed and exported for handoff.",
|
|
298
|
+
order: 10,
|
|
299
|
+
entity: "contact"
|
|
300
|
+
},
|
|
301
|
+
interested: {
|
|
302
|
+
key: "interested",
|
|
303
|
+
label: "Interested",
|
|
304
|
+
description: "Contact replied with a positive signal (Instantly reply-handler transition).",
|
|
305
|
+
order: 11,
|
|
306
|
+
entity: "contact"
|
|
307
|
+
}
|
|
308
|
+
};
|
|
223
309
|
var ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
|
|
224
310
|
id: ModelIdSchema,
|
|
225
311
|
order: z.number().int().min(0)
|
|
@@ -300,6 +386,178 @@ var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
|
|
|
300
386
|
id: ModelIdSchema,
|
|
301
387
|
steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
|
|
302
388
|
});
|
|
389
|
+
z.object({
|
|
390
|
+
id: ModelIdSchema,
|
|
391
|
+
label: z.string(),
|
|
392
|
+
description: z.string(),
|
|
393
|
+
resourceId: ModelIdSchema
|
|
394
|
+
});
|
|
395
|
+
var PROSPECTING_STEPS = {
|
|
396
|
+
localServices: {
|
|
397
|
+
sourceCompanies: {
|
|
398
|
+
id: "source-companies",
|
|
399
|
+
label: "Companies found",
|
|
400
|
+
primaryEntity: "company",
|
|
401
|
+
outputs: ["company"],
|
|
402
|
+
stageKey: "populated",
|
|
403
|
+
dependencyMode: "per-record-eligibility",
|
|
404
|
+
capabilityKey: "lead-gen.company.source",
|
|
405
|
+
defaultBatchSize: 100,
|
|
406
|
+
maxBatchSize: 250
|
|
407
|
+
},
|
|
408
|
+
analyzeWebsites: {
|
|
409
|
+
id: "analyze-websites",
|
|
410
|
+
label: "Websites analyzed",
|
|
411
|
+
primaryEntity: "company",
|
|
412
|
+
outputs: ["company"],
|
|
413
|
+
stageKey: "extracted",
|
|
414
|
+
dependsOn: ["source-companies"],
|
|
415
|
+
dependencyMode: "per-record-eligibility",
|
|
416
|
+
capabilityKey: "lead-gen.company.website-extract",
|
|
417
|
+
defaultBatchSize: 50,
|
|
418
|
+
maxBatchSize: 100
|
|
419
|
+
},
|
|
420
|
+
qualifyCompanies: {
|
|
421
|
+
id: "qualify-companies",
|
|
422
|
+
label: "Companies qualified",
|
|
423
|
+
primaryEntity: "company",
|
|
424
|
+
outputs: ["company"],
|
|
425
|
+
stageKey: "qualified",
|
|
426
|
+
dependsOn: ["analyze-websites"],
|
|
427
|
+
dependencyMode: "per-record-eligibility",
|
|
428
|
+
capabilityKey: "lead-gen.company.qualify",
|
|
429
|
+
defaultBatchSize: 100,
|
|
430
|
+
maxBatchSize: 250
|
|
431
|
+
},
|
|
432
|
+
findContacts: {
|
|
433
|
+
id: "find-contacts",
|
|
434
|
+
label: "Decision-makers found",
|
|
435
|
+
primaryEntity: "contact",
|
|
436
|
+
outputs: ["contact"],
|
|
437
|
+
stageKey: "discovered",
|
|
438
|
+
dependsOn: ["qualify-companies"],
|
|
439
|
+
dependencyMode: "per-record-eligibility",
|
|
440
|
+
capabilityKey: "lead-gen.contact.discover",
|
|
441
|
+
defaultBatchSize: 50,
|
|
442
|
+
maxBatchSize: 100
|
|
443
|
+
},
|
|
444
|
+
verifyEmails: {
|
|
445
|
+
id: "verify-emails",
|
|
446
|
+
label: "Emails verified",
|
|
447
|
+
primaryEntity: "contact",
|
|
448
|
+
outputs: ["contact"],
|
|
449
|
+
stageKey: "verified",
|
|
450
|
+
dependsOn: ["find-contacts"],
|
|
451
|
+
dependencyMode: "per-record-eligibility",
|
|
452
|
+
capabilityKey: "lead-gen.contact.verify-email",
|
|
453
|
+
defaultBatchSize: 100,
|
|
454
|
+
maxBatchSize: 500
|
|
455
|
+
},
|
|
456
|
+
personalize: {
|
|
457
|
+
id: "personalize",
|
|
458
|
+
label: "Personalize",
|
|
459
|
+
primaryEntity: "contact",
|
|
460
|
+
outputs: ["contact"],
|
|
461
|
+
stageKey: "personalized",
|
|
462
|
+
dependsOn: ["verify-emails"],
|
|
463
|
+
dependencyMode: "per-record-eligibility",
|
|
464
|
+
capabilityKey: "lead-gen.contact.personalize",
|
|
465
|
+
defaultBatchSize: 25,
|
|
466
|
+
maxBatchSize: 100
|
|
467
|
+
},
|
|
468
|
+
review: {
|
|
469
|
+
id: "review",
|
|
470
|
+
label: "Reviewed and exported",
|
|
471
|
+
primaryEntity: "contact",
|
|
472
|
+
outputs: ["export"],
|
|
473
|
+
stageKey: "uploaded",
|
|
474
|
+
dependsOn: ["personalize"],
|
|
475
|
+
dependencyMode: "per-record-eligibility",
|
|
476
|
+
capabilityKey: "lead-gen.review.outreach-ready",
|
|
477
|
+
defaultBatchSize: 25,
|
|
478
|
+
maxBatchSize: 100
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
dtcApolloClickup: {
|
|
482
|
+
importApolloSearch: {
|
|
483
|
+
id: "import-apollo-search",
|
|
484
|
+
label: "Companies found",
|
|
485
|
+
description: "Pull companies and seed contact data from a predefined Apollo search or list.",
|
|
486
|
+
primaryEntity: "company",
|
|
487
|
+
outputs: ["company", "contact"],
|
|
488
|
+
stageKey: "populated",
|
|
489
|
+
dependencyMode: "per-record-eligibility",
|
|
490
|
+
capabilityKey: "lead-gen.company.apollo-import",
|
|
491
|
+
defaultBatchSize: 250,
|
|
492
|
+
maxBatchSize: 1e3
|
|
493
|
+
},
|
|
494
|
+
analyzeWebsites: {
|
|
495
|
+
id: "analyze-websites",
|
|
496
|
+
label: "Websites analyzed",
|
|
497
|
+
description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
|
|
498
|
+
primaryEntity: "company",
|
|
499
|
+
outputs: ["company"],
|
|
500
|
+
stageKey: "extracted",
|
|
501
|
+
dependsOn: ["import-apollo-search"],
|
|
502
|
+
dependencyMode: "per-record-eligibility",
|
|
503
|
+
capabilityKey: "lead-gen.company.website-extract",
|
|
504
|
+
defaultBatchSize: 50,
|
|
505
|
+
maxBatchSize: 100
|
|
506
|
+
},
|
|
507
|
+
scoreDtcFit: {
|
|
508
|
+
id: "score-dtc-fit",
|
|
509
|
+
label: "Companies qualified",
|
|
510
|
+
description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
|
|
511
|
+
primaryEntity: "company",
|
|
512
|
+
outputs: ["company"],
|
|
513
|
+
stageKey: "qualified",
|
|
514
|
+
dependsOn: ["analyze-websites"],
|
|
515
|
+
dependencyMode: "per-record-eligibility",
|
|
516
|
+
capabilityKey: "lead-gen.company.dtc-subscription-qualify",
|
|
517
|
+
defaultBatchSize: 100,
|
|
518
|
+
maxBatchSize: 250
|
|
519
|
+
},
|
|
520
|
+
enrichDecisionMakers: {
|
|
521
|
+
id: "enrich-decision-makers",
|
|
522
|
+
label: "Decision-makers found",
|
|
523
|
+
description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
|
|
524
|
+
primaryEntity: "company",
|
|
525
|
+
outputs: ["contact"],
|
|
526
|
+
stageKey: "decision-makers-enriched",
|
|
527
|
+
dependsOn: ["score-dtc-fit"],
|
|
528
|
+
dependencyMode: "per-record-eligibility",
|
|
529
|
+
capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
530
|
+
defaultBatchSize: 100,
|
|
531
|
+
maxBatchSize: 250
|
|
532
|
+
},
|
|
533
|
+
verifyEmails: {
|
|
534
|
+
id: "verify-emails",
|
|
535
|
+
label: "Emails verified",
|
|
536
|
+
description: "Verify deliverability before the QC and handoff step.",
|
|
537
|
+
primaryEntity: "contact",
|
|
538
|
+
outputs: ["contact"],
|
|
539
|
+
stageKey: "verified",
|
|
540
|
+
dependsOn: ["enrich-decision-makers"],
|
|
541
|
+
dependencyMode: "per-record-eligibility",
|
|
542
|
+
capabilityKey: "lead-gen.contact.verify-email",
|
|
543
|
+
defaultBatchSize: 250,
|
|
544
|
+
maxBatchSize: 500
|
|
545
|
+
},
|
|
546
|
+
reviewAndExport: {
|
|
547
|
+
id: "review-and-export",
|
|
548
|
+
label: "Reviewed and exported",
|
|
549
|
+
description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
|
|
550
|
+
primaryEntity: "company",
|
|
551
|
+
outputs: ["export"],
|
|
552
|
+
stageKey: "uploaded",
|
|
553
|
+
dependsOn: ["verify-emails"],
|
|
554
|
+
dependencyMode: "per-record-eligibility",
|
|
555
|
+
capabilityKey: "lead-gen.export.list",
|
|
556
|
+
defaultBatchSize: 100,
|
|
557
|
+
maxBatchSize: 250
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
};
|
|
303
561
|
var OrganizationModelProspectingSchema = z.object({
|
|
304
562
|
listEntityId: ModelIdSchema,
|
|
305
563
|
companyEntityId: ModelIdSchema,
|
|
@@ -310,21 +568,22 @@ var OrganizationModelProspectingSchema = z.object({
|
|
|
310
568
|
defaultBuildTemplateId: ModelIdSchema,
|
|
311
569
|
buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
|
|
312
570
|
});
|
|
571
|
+
function toProspectingLifecycleStage(stage) {
|
|
572
|
+
return {
|
|
573
|
+
id: stage.key,
|
|
574
|
+
label: stage.label,
|
|
575
|
+
order: stage.order
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function leadGenStagesForEntity(entity) {
|
|
579
|
+
return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity).sort((a, b) => a.order - b.order).map(toProspectingLifecycleStage);
|
|
580
|
+
}
|
|
313
581
|
var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
|
|
314
582
|
listEntityId: "leadgen.list",
|
|
315
583
|
companyEntityId: "leadgen.company",
|
|
316
584
|
contactEntityId: "leadgen.contact",
|
|
317
|
-
companyStages:
|
|
318
|
-
|
|
319
|
-
{ id: "extracted", label: "Extracted", order: 2 },
|
|
320
|
-
{ id: "qualified", label: "Qualified", order: 3 }
|
|
321
|
-
],
|
|
322
|
-
contactStages: [
|
|
323
|
-
{ id: "discovered", label: "Discovered", order: 1 },
|
|
324
|
-
{ id: "verified", label: "Verified", order: 2 },
|
|
325
|
-
{ id: "personalized", label: "Personalized", order: 3 },
|
|
326
|
-
{ id: "uploaded", label: "Uploaded", order: 4 }
|
|
327
|
-
],
|
|
585
|
+
companyStages: leadGenStagesForEntity("company"),
|
|
586
|
+
contactStages: leadGenStagesForEntity("contact"),
|
|
328
587
|
defaultBuildTemplateId: "local-services",
|
|
329
588
|
buildTemplates: [
|
|
330
589
|
{
|
|
@@ -332,89 +591,13 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
|
|
|
332
591
|
label: "Local Services Prospecting",
|
|
333
592
|
description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
|
|
334
593
|
steps: [
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
capabilityKey: "lead-gen.company.source",
|
|
343
|
-
defaultBatchSize: 100,
|
|
344
|
-
maxBatchSize: 250
|
|
345
|
-
},
|
|
346
|
-
{
|
|
347
|
-
id: "analyze-websites",
|
|
348
|
-
label: "Analyze websites",
|
|
349
|
-
primaryEntity: "company",
|
|
350
|
-
outputs: ["company"],
|
|
351
|
-
stageKey: "extracted",
|
|
352
|
-
dependsOn: ["source-companies"],
|
|
353
|
-
dependencyMode: "per-record-eligibility",
|
|
354
|
-
capabilityKey: "lead-gen.company.website-extract",
|
|
355
|
-
defaultBatchSize: 50,
|
|
356
|
-
maxBatchSize: 100
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
id: "qualify-companies",
|
|
360
|
-
label: "Qualify companies",
|
|
361
|
-
primaryEntity: "company",
|
|
362
|
-
outputs: ["company"],
|
|
363
|
-
stageKey: "qualified",
|
|
364
|
-
dependsOn: ["analyze-websites"],
|
|
365
|
-
dependencyMode: "per-record-eligibility",
|
|
366
|
-
capabilityKey: "lead-gen.company.qualify",
|
|
367
|
-
defaultBatchSize: 100,
|
|
368
|
-
maxBatchSize: 250
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
id: "find-contacts",
|
|
372
|
-
label: "Find contacts",
|
|
373
|
-
primaryEntity: "contact",
|
|
374
|
-
outputs: ["contact"],
|
|
375
|
-
stageKey: "discovered",
|
|
376
|
-
dependsOn: ["qualify-companies"],
|
|
377
|
-
dependencyMode: "per-record-eligibility",
|
|
378
|
-
capabilityKey: "lead-gen.contact.discover",
|
|
379
|
-
defaultBatchSize: 50,
|
|
380
|
-
maxBatchSize: 100
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
id: "verify-emails",
|
|
384
|
-
label: "Verify emails",
|
|
385
|
-
primaryEntity: "contact",
|
|
386
|
-
outputs: ["contact"],
|
|
387
|
-
stageKey: "verified",
|
|
388
|
-
dependsOn: ["find-contacts"],
|
|
389
|
-
dependencyMode: "per-record-eligibility",
|
|
390
|
-
capabilityKey: "lead-gen.contact.verify-email",
|
|
391
|
-
defaultBatchSize: 100,
|
|
392
|
-
maxBatchSize: 500
|
|
393
|
-
},
|
|
394
|
-
{
|
|
395
|
-
id: "personalize",
|
|
396
|
-
label: "Personalize",
|
|
397
|
-
primaryEntity: "contact",
|
|
398
|
-
outputs: ["contact"],
|
|
399
|
-
stageKey: "personalized",
|
|
400
|
-
dependsOn: ["verify-emails"],
|
|
401
|
-
dependencyMode: "per-record-eligibility",
|
|
402
|
-
capabilityKey: "lead-gen.contact.personalize",
|
|
403
|
-
defaultBatchSize: 25,
|
|
404
|
-
maxBatchSize: 100
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
id: "review",
|
|
408
|
-
label: "Review",
|
|
409
|
-
primaryEntity: "contact",
|
|
410
|
-
outputs: ["export"],
|
|
411
|
-
stageKey: "uploaded",
|
|
412
|
-
dependsOn: ["personalize"],
|
|
413
|
-
dependencyMode: "per-record-eligibility",
|
|
414
|
-
capabilityKey: "lead-gen.review.outreach-ready",
|
|
415
|
-
defaultBatchSize: 25,
|
|
416
|
-
maxBatchSize: 100
|
|
417
|
-
}
|
|
594
|
+
PROSPECTING_STEPS.localServices.sourceCompanies,
|
|
595
|
+
PROSPECTING_STEPS.localServices.analyzeWebsites,
|
|
596
|
+
PROSPECTING_STEPS.localServices.qualifyCompanies,
|
|
597
|
+
PROSPECTING_STEPS.localServices.findContacts,
|
|
598
|
+
PROSPECTING_STEPS.localServices.verifyEmails,
|
|
599
|
+
PROSPECTING_STEPS.localServices.personalize,
|
|
600
|
+
PROSPECTING_STEPS.localServices.review
|
|
418
601
|
]
|
|
419
602
|
},
|
|
420
603
|
{
|
|
@@ -422,83 +605,12 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
|
|
|
422
605
|
label: "DTC Subscription Apollo Export",
|
|
423
606
|
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.",
|
|
424
607
|
steps: [
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
stageKey: "populated",
|
|
432
|
-
dependencyMode: "per-record-eligibility",
|
|
433
|
-
capabilityKey: "lead-gen.company.apollo-import",
|
|
434
|
-
defaultBatchSize: 250,
|
|
435
|
-
maxBatchSize: 1e3
|
|
436
|
-
},
|
|
437
|
-
{
|
|
438
|
-
id: "analyze-websites",
|
|
439
|
-
label: "Analyze websites",
|
|
440
|
-
description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
|
|
441
|
-
primaryEntity: "company",
|
|
442
|
-
outputs: ["company"],
|
|
443
|
-
stageKey: "extracted",
|
|
444
|
-
dependsOn: ["import-apollo-search"],
|
|
445
|
-
dependencyMode: "per-record-eligibility",
|
|
446
|
-
capabilityKey: "lead-gen.company.website-extract",
|
|
447
|
-
defaultBatchSize: 50,
|
|
448
|
-
maxBatchSize: 100
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
id: "score-dtc-fit",
|
|
452
|
-
label: "Score DTC fit",
|
|
453
|
-
description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
|
|
454
|
-
primaryEntity: "company",
|
|
455
|
-
outputs: ["company"],
|
|
456
|
-
stageKey: "qualified",
|
|
457
|
-
dependsOn: ["analyze-websites"],
|
|
458
|
-
dependencyMode: "per-record-eligibility",
|
|
459
|
-
capabilityKey: "lead-gen.company.dtc-subscription-qualify",
|
|
460
|
-
defaultBatchSize: 100,
|
|
461
|
-
maxBatchSize: 250
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
id: "enrich-decision-makers",
|
|
465
|
-
label: "Enrich decision-makers",
|
|
466
|
-
description: "Use Apollo to find qualified contacts such as founders, retention leads, lifecycle leads, and marketing owners.",
|
|
467
|
-
primaryEntity: "contact",
|
|
468
|
-
outputs: ["contact"],
|
|
469
|
-
stageKey: "discovered",
|
|
470
|
-
dependsOn: ["score-dtc-fit"],
|
|
471
|
-
dependencyMode: "per-record-eligibility",
|
|
472
|
-
capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
473
|
-
defaultBatchSize: 100,
|
|
474
|
-
maxBatchSize: 250
|
|
475
|
-
},
|
|
476
|
-
{
|
|
477
|
-
id: "verify-emails",
|
|
478
|
-
label: "Verify emails",
|
|
479
|
-
description: "Verify deliverability before the QC and handoff step.",
|
|
480
|
-
primaryEntity: "contact",
|
|
481
|
-
outputs: ["contact"],
|
|
482
|
-
stageKey: "verified",
|
|
483
|
-
dependsOn: ["enrich-decision-makers"],
|
|
484
|
-
dependencyMode: "per-record-eligibility",
|
|
485
|
-
capabilityKey: "lead-gen.contact.verify-email",
|
|
486
|
-
defaultBatchSize: 250,
|
|
487
|
-
maxBatchSize: 500
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
id: "review-and-export",
|
|
491
|
-
label: "Review and export",
|
|
492
|
-
description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
|
|
493
|
-
primaryEntity: "company",
|
|
494
|
-
outputs: ["export"],
|
|
495
|
-
stageKey: "uploaded",
|
|
496
|
-
dependsOn: ["verify-emails"],
|
|
497
|
-
dependencyMode: "per-record-eligibility",
|
|
498
|
-
capabilityKey: "lead-gen.export.list",
|
|
499
|
-
defaultBatchSize: 100,
|
|
500
|
-
maxBatchSize: 250
|
|
501
|
-
}
|
|
608
|
+
PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
|
|
609
|
+
PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
|
|
610
|
+
PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
|
|
611
|
+
PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
|
|
612
|
+
PROSPECTING_STEPS.dtcApolloClickup.verifyEmails,
|
|
613
|
+
PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
|
|
502
614
|
]
|
|
503
615
|
}
|
|
504
616
|
]
|
|
@@ -945,6 +1057,8 @@ var DEFAULT_ORGANIZATION_MODEL_STATUSES = {
|
|
|
945
1057
|
var KnowledgeLinkSchema = z.object({
|
|
946
1058
|
nodeId: NodeIdStringSchema
|
|
947
1059
|
});
|
|
1060
|
+
var KnowledgeSkillBindingSchema = z.string().trim().min(1).max(120);
|
|
1061
|
+
var KnowledgeDomainBindingSchema = z.string().trim().min(1).max(80);
|
|
948
1062
|
var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]);
|
|
949
1063
|
var OrgKnowledgeNodeSchema = z.object({
|
|
950
1064
|
id: ModelIdSchema,
|
|
@@ -959,6 +1073,10 @@ var OrgKnowledgeNodeSchema = z.object({
|
|
|
959
1073
|
* Each link emits a `governs` edge: knowledge-node -> target node.
|
|
960
1074
|
*/
|
|
961
1075
|
links: z.array(KnowledgeLinkSchema).default([]),
|
|
1076
|
+
/** Operator skill or command bindings relevant to this node. */
|
|
1077
|
+
skills: z.array(KnowledgeSkillBindingSchema).optional(),
|
|
1078
|
+
/** Domain key used to derive fast graph->skill registries. */
|
|
1079
|
+
domain: KnowledgeDomainBindingSchema.optional(),
|
|
962
1080
|
/** Identifiers of the roles or members who own this knowledge node. */
|
|
963
1081
|
ownerIds: z.array(ModelIdSchema).default([]),
|
|
964
1082
|
/** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
|
|
@@ -1012,8 +1130,12 @@ var LEGACY_FEATURE_ALIASES = /* @__PURE__ */ new Map([
|
|
|
1012
1130
|
function hasFeature(featuresById, featureId) {
|
|
1013
1131
|
return featuresById.has(featureId) || featuresById.has(LEGACY_FEATURE_ALIASES.get(featureId) ?? "");
|
|
1014
1132
|
}
|
|
1133
|
+
function defaultFeaturePathFor(id) {
|
|
1134
|
+
return `/${id.replaceAll(".", "/")}`;
|
|
1135
|
+
}
|
|
1015
1136
|
var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
1016
1137
|
const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
|
|
1138
|
+
const featureIdsByEffectivePath = /* @__PURE__ */ new Map();
|
|
1017
1139
|
model.features.forEach((feature, featureIndex) => {
|
|
1018
1140
|
const segments = feature.id.split(".");
|
|
1019
1141
|
if (segments.length > 1) {
|
|
@@ -1029,6 +1151,20 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
1029
1151
|
const hasChildren = model.features.some(
|
|
1030
1152
|
(candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.id !== feature.id
|
|
1031
1153
|
);
|
|
1154
|
+
const contributesRoutePath = feature.path !== void 0 || !hasChildren;
|
|
1155
|
+
if (contributesRoutePath) {
|
|
1156
|
+
const effectivePath = feature.path ?? defaultFeaturePathFor(feature.id);
|
|
1157
|
+
const existingFeatureId = featureIdsByEffectivePath.get(effectivePath);
|
|
1158
|
+
if (existingFeatureId !== void 0) {
|
|
1159
|
+
addIssue(
|
|
1160
|
+
ctx,
|
|
1161
|
+
["features", featureIndex, feature.path === void 0 ? "id" : "path"],
|
|
1162
|
+
`Feature "${feature.id}" effective path "${effectivePath}" duplicates feature "${existingFeatureId}"`
|
|
1163
|
+
);
|
|
1164
|
+
} else {
|
|
1165
|
+
featureIdsByEffectivePath.set(effectivePath, feature.id);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1032
1168
|
if (hasChildren && feature.enabled) {
|
|
1033
1169
|
const hasEnabledDescendant = model.features.some(
|
|
1034
1170
|
(candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.enabled
|
|
@@ -1042,6 +1178,43 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
1042
1178
|
}
|
|
1043
1179
|
}
|
|
1044
1180
|
});
|
|
1181
|
+
const surfacesById = collectIds(model.navigation.surfaces, ctx, ["navigation", "surfaces"], "Navigation surface");
|
|
1182
|
+
if (model.navigation.defaultSurfaceId !== void 0 && !surfacesById.has(model.navigation.defaultSurfaceId)) {
|
|
1183
|
+
addIssue(
|
|
1184
|
+
ctx,
|
|
1185
|
+
["navigation", "defaultSurfaceId"],
|
|
1186
|
+
`Navigation defaultSurfaceId references unknown surface "${model.navigation.defaultSurfaceId}"`
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
model.navigation.groups.forEach((group, groupIndex) => {
|
|
1190
|
+
group.surfaceIds.forEach((surfaceId, surfaceIndex) => {
|
|
1191
|
+
if (!surfacesById.has(surfaceId)) {
|
|
1192
|
+
addIssue(
|
|
1193
|
+
ctx,
|
|
1194
|
+
["navigation", "groups", groupIndex, "surfaceIds", surfaceIndex],
|
|
1195
|
+
`Navigation group "${group.id}" references unknown surface "${surfaceId}"`
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
});
|
|
1200
|
+
model.navigation.surfaces.forEach((surface, surfaceIndex) => {
|
|
1201
|
+
if (surface.featureId !== void 0 && !hasFeature(featuresById, surface.featureId)) {
|
|
1202
|
+
addIssue(
|
|
1203
|
+
ctx,
|
|
1204
|
+
["navigation", "surfaces", surfaceIndex, "featureId"],
|
|
1205
|
+
`Navigation surface "${surface.id}" references unknown feature "${surface.featureId}"`
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
surface.featureIds.forEach((featureId, featureIndex) => {
|
|
1209
|
+
if (!hasFeature(featuresById, featureId)) {
|
|
1210
|
+
addIssue(
|
|
1211
|
+
ctx,
|
|
1212
|
+
["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
|
|
1213
|
+
`Navigation surface "${surface.id}" references unknown feature "${featureId}"`
|
|
1214
|
+
);
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
});
|
|
1045
1218
|
const segmentsById = new Map(model.customers.segments.map((seg) => [seg.id, seg]));
|
|
1046
1219
|
model.offerings.products.forEach((product, productIndex) => {
|
|
1047
1220
|
product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
|
|
@@ -1087,6 +1260,7 @@ var OrganizationGraphNodeKindSchema = z.enum([
|
|
|
1087
1260
|
"surface",
|
|
1088
1261
|
"entity",
|
|
1089
1262
|
"capability",
|
|
1263
|
+
"stage",
|
|
1090
1264
|
"resource",
|
|
1091
1265
|
"knowledge"
|
|
1092
1266
|
]);
|
|
@@ -1262,6 +1436,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
1262
1436
|
enabled: true,
|
|
1263
1437
|
uiPosition: "sidebar-primary"
|
|
1264
1438
|
},
|
|
1439
|
+
{
|
|
1440
|
+
id: "monitoring.calendar",
|
|
1441
|
+
label: "Calendar",
|
|
1442
|
+
description: "Google Calendar events and agenda views",
|
|
1443
|
+
enabled: true,
|
|
1444
|
+
path: "/monitoring/calendar",
|
|
1445
|
+
icon: "feature.calendar"
|
|
1446
|
+
},
|
|
1265
1447
|
{
|
|
1266
1448
|
id: "monitoring.activity-log",
|
|
1267
1449
|
label: "Activity Log",
|