@elevasis/ui 2.33.1 → 2.34.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/api/index.d.ts +9 -2
- package/dist/api/index.js +1 -1
- package/dist/app/index.css +452 -0
- package/dist/app/index.d.ts +1250 -3
- package/dist/app/index.js +144 -8
- package/dist/charts/index.js +2 -3
- package/dist/{chunk-3YZRKADM.js → chunk-3AJVNMY5.js} +45 -28
- package/dist/chunk-3QXJK5IY.js +25 -0
- package/dist/chunk-4O4MII5S.js +4716 -0
- package/dist/{chunk-KW7ZNQD7.js → chunk-5EYJ2GIN.js} +4 -8
- package/dist/{chunk-53436UTQ.js → chunk-BPQVTIUP.js} +12 -3
- package/dist/{chunk-DYIDXUJS.js → chunk-DTFKWZ7A.js} +1098 -2280
- package/dist/{chunk-EPTHX4VZ.js → chunk-HRWLKKWM.js} +11 -2
- package/dist/{chunk-SWMQTF2H.js → chunk-IGDYWFNE.js} +2 -2
- package/dist/{chunk-QVTIOT73.js → chunk-IVGI4GDL.js} +3 -3
- package/dist/{chunk-4DYOXEH6.js → chunk-LAWLB6CT.js} +1 -1
- package/dist/{chunk-UYRT7SPM.js → chunk-LRWTWOGP.js} +3 -3
- package/dist/{chunk-2VYMDNJ3.js → chunk-MP3GPBPX.js} +3 -3
- package/dist/{chunk-YENKDBUU.js → chunk-NLBQTDOW.js} +12 -17
- package/dist/{chunk-WJOE76FI.js → chunk-O6JXQ6UQ.js} +5 -4
- package/dist/{chunk-F3MXFE72.js → chunk-OBBQ2JCM.js} +3 -3
- package/dist/{chunk-WGUEIGPC.js → chunk-PLP3NYPL.js} +80 -171
- package/dist/{chunk-AV2TKVVV.js → chunk-RIAXZ6AH.js} +5 -6
- package/dist/chunk-SDXSB3HN.js +425 -0
- package/dist/{chunk-JA5ECJJB.js → chunk-VTXTZXAU.js} +156 -4
- package/dist/{chunk-H6EFQP2P.js → chunk-W73ZABT6.js} +1 -1
- package/dist/{chunk-UNVRVCXZ.js → chunk-WU4FNWCW.js} +3 -3
- package/dist/{chunk-NCEQGEW5.js → chunk-YNWZIWJL.js} +4 -5
- package/dist/components/index.d.ts +0 -23
- package/dist/components/index.js +27 -448
- package/dist/components/navigation/index.js +4 -6
- package/dist/features/clients/index.js +7 -12
- package/dist/features/crm/index.js +9 -14
- package/dist/features/dashboard/index.d.ts +0 -23
- package/dist/features/dashboard/index.js +9 -14
- package/dist/features/delivery/index.js +8 -13
- package/dist/features/knowledge/index.js +5 -7
- package/dist/features/lead-gen/index.js +9 -14
- package/dist/features/monitoring/index.js +10 -15
- package/dist/features/monitoring/requests/index.js +7 -12
- package/dist/features/operations/index.d.ts +44 -35
- package/dist/features/operations/index.js +12 -17
- package/dist/features/settings/index.js +8 -13
- package/dist/hooks/index.d.ts +20 -27
- package/dist/hooks/index.js +7 -12
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +20 -27
- package/dist/hooks/published.d.ts +20 -27
- package/dist/hooks/published.js +7 -12
- package/dist/index.d.ts +54 -39
- package/dist/index.js +8 -13
- package/dist/knowledge/index.d.ts +30 -38
- package/dist/knowledge/index.js +37 -201
- package/dist/{knowledge-search-index-P7PR626V.js → knowledge-search-index-ORIJCEZX.js} +142 -150
- package/dist/organization/index.js +1 -2
- package/dist/provider/index.d.ts +25 -32
- package/dist/provider/index.js +6 -11
- package/dist/provider/published.d.ts +25 -32
- package/dist/provider/published.js +5 -9
- package/dist/test-utils/index.d.ts +2 -0
- package/dist/test-utils/index.js +14 -2
- package/dist/test-utils/setup.js +38 -0
- package/dist/types/index.d.ts +20 -27
- package/dist/utils/index.d.ts +0 -23
- package/dist/zustand/index.d.ts +15 -2
- package/dist/zustand/index.js +35 -1
- package/package.json +5 -5
- package/dist/chunk-4AAZXKLL.js +0 -347
- package/dist/chunk-DWXDNT7P.js +0 -145
- package/dist/chunk-FOUYP4JX.js +0 -13
- package/dist/chunk-HUJCU55S.js +0 -159
- package/dist/chunk-PIS24NIV.js +0 -29
- package/dist/chunk-SZHARWKU.js +0 -15
- package/dist/chunk-XCYKC6OZ.js +0 -1
|
@@ -1,6 +1,148 @@
|
|
|
1
|
+
import { IconMail, IconSend, IconFileText, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconShieldLock, IconActivity, IconTopologyStar3, IconApps, IconBriefcase, IconBuilding, IconBolt, IconSearch, IconChartBar, IconUsers, IconInfoCircle, IconDatabase, IconGitBranch, IconDashboard, IconBuildingStore, IconUser, IconPlug, IconBrain, IconTargetArrow, IconBook, IconLayoutGrid, IconArchive, IconSettings, IconTool, IconCalendar } from '@tabler/icons-react';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
1
3
|
import { z } from 'zod';
|
|
2
4
|
|
|
3
|
-
//
|
|
5
|
+
// src/icons/registry.tsx
|
|
6
|
+
var DEFAULT_SEMANTIC_ICON_REGISTRY = {
|
|
7
|
+
// Navigation / app areas
|
|
8
|
+
dashboard: IconDashboard,
|
|
9
|
+
calendar: IconCalendar,
|
|
10
|
+
sales: IconChartBar,
|
|
11
|
+
crm: IconBuildingStore,
|
|
12
|
+
"lead-gen": IconTargetArrow,
|
|
13
|
+
projects: IconBriefcase,
|
|
14
|
+
clients: IconUsers,
|
|
15
|
+
operations: IconTool,
|
|
16
|
+
monitoring: IconChartBar,
|
|
17
|
+
knowledge: IconBrain,
|
|
18
|
+
settings: IconSettings,
|
|
19
|
+
admin: IconShieldLock,
|
|
20
|
+
archive: IconArchive,
|
|
21
|
+
business: IconBriefcase,
|
|
22
|
+
finance: IconChartBar,
|
|
23
|
+
platform: IconLayoutGrid,
|
|
24
|
+
seo: IconSearch,
|
|
25
|
+
// Knowledge kinds
|
|
26
|
+
playbook: IconBook,
|
|
27
|
+
strategy: IconTargetArrow,
|
|
28
|
+
reference: IconFileText,
|
|
29
|
+
// Resource kinds
|
|
30
|
+
agent: IconBrain,
|
|
31
|
+
workflow: IconGitBranch,
|
|
32
|
+
integration: IconPlug,
|
|
33
|
+
database: IconDatabase,
|
|
34
|
+
user: IconUser,
|
|
35
|
+
team: IconUsers,
|
|
36
|
+
// Integration specifics
|
|
37
|
+
gmail: IconMail,
|
|
38
|
+
"google-sheets": IconDatabase,
|
|
39
|
+
attio: IconBuildingStore,
|
|
40
|
+
// Surface / UI views
|
|
41
|
+
overview: IconDashboard,
|
|
42
|
+
"command-view": IconTopologyStar3,
|
|
43
|
+
"command-queue": IconSend,
|
|
44
|
+
pipeline: IconGitBranch,
|
|
45
|
+
lists: IconFileText,
|
|
46
|
+
resources: IconDatabase,
|
|
47
|
+
// Actions
|
|
48
|
+
approve: IconCheck,
|
|
49
|
+
reject: IconX,
|
|
50
|
+
retry: IconRefresh,
|
|
51
|
+
edit: IconEdit,
|
|
52
|
+
view: IconEye,
|
|
53
|
+
launch: IconRocket,
|
|
54
|
+
message: IconMessageCircle,
|
|
55
|
+
escalate: IconAlertTriangle,
|
|
56
|
+
promote: IconArrowUp,
|
|
57
|
+
submit: IconSend,
|
|
58
|
+
email: IconMail,
|
|
59
|
+
// Status
|
|
60
|
+
success: IconCheck,
|
|
61
|
+
error: IconX,
|
|
62
|
+
warning: IconAlertTriangle,
|
|
63
|
+
info: IconInfoCircle,
|
|
64
|
+
pending: IconClock,
|
|
65
|
+
// OM / UI group icons
|
|
66
|
+
bolt: IconBolt,
|
|
67
|
+
building: IconBuilding,
|
|
68
|
+
briefcase: IconBriefcase,
|
|
69
|
+
apps: IconApps,
|
|
70
|
+
graph: IconTopologyStar3,
|
|
71
|
+
shield: IconShieldLock,
|
|
72
|
+
users: IconUsers,
|
|
73
|
+
"chart-bar": IconChartBar,
|
|
74
|
+
search: IconSearch,
|
|
75
|
+
// UI-only om.* group tokens (not in the core enum — kept for registry lookup
|
|
76
|
+
// by components that reference them directly via extendSemanticIconRegistry)
|
|
77
|
+
"om.quick-access": IconBolt,
|
|
78
|
+
"om.profile": IconBuilding,
|
|
79
|
+
"om.business-model": IconBriefcase,
|
|
80
|
+
"om.systems": IconApps,
|
|
81
|
+
"om.graph": IconTopologyStar3,
|
|
82
|
+
"om.governance-wiring": IconShieldLock,
|
|
83
|
+
// Graph node-kind fallback tokens (used internally by knowledge-tree helpers)
|
|
84
|
+
"entity.record": IconActivity,
|
|
85
|
+
"event.lifecycle": IconActivity,
|
|
86
|
+
"policy.governance": IconShieldLock,
|
|
87
|
+
// Compatibility aliases for existing command queue payloads.
|
|
88
|
+
IconCheck,
|
|
89
|
+
IconX,
|
|
90
|
+
IconRefresh,
|
|
91
|
+
IconAlertTriangle,
|
|
92
|
+
IconEdit,
|
|
93
|
+
IconEye,
|
|
94
|
+
IconRocket,
|
|
95
|
+
IconMessageCircle,
|
|
96
|
+
IconArrowUp,
|
|
97
|
+
IconClock,
|
|
98
|
+
IconFileText,
|
|
99
|
+
IconSend,
|
|
100
|
+
IconMail
|
|
101
|
+
};
|
|
102
|
+
var semanticIconRegistry = { ...DEFAULT_SEMANTIC_ICON_REGISTRY };
|
|
103
|
+
function extendSemanticIconRegistry(overrides) {
|
|
104
|
+
semanticIconRegistry = { ...semanticIconRegistry, ...overrides };
|
|
105
|
+
}
|
|
106
|
+
function getSemanticIconComponent(token, fallbackToken) {
|
|
107
|
+
const icon = resolveSemanticIconComponent(token);
|
|
108
|
+
if (icon) return icon;
|
|
109
|
+
if (fallbackToken && semanticIconRegistry[fallbackToken]) return semanticIconRegistry[fallbackToken];
|
|
110
|
+
return IconInfoCircle;
|
|
111
|
+
}
|
|
112
|
+
function resolveSemanticIconComponent(token) {
|
|
113
|
+
if (!token) return null;
|
|
114
|
+
return semanticIconRegistry[token] ?? null;
|
|
115
|
+
}
|
|
116
|
+
function SemanticIcon({
|
|
117
|
+
token,
|
|
118
|
+
fallbackToken,
|
|
119
|
+
size = 16,
|
|
120
|
+
stroke = 1.8,
|
|
121
|
+
className,
|
|
122
|
+
style,
|
|
123
|
+
"aria-hidden": ariaHidden = true
|
|
124
|
+
}) {
|
|
125
|
+
const Icon = getSemanticIconComponent(token, fallbackToken);
|
|
126
|
+
return /* @__PURE__ */ jsx(
|
|
127
|
+
"span",
|
|
128
|
+
{
|
|
129
|
+
className,
|
|
130
|
+
"aria-hidden": ariaHidden,
|
|
131
|
+
style: {
|
|
132
|
+
display: "inline-flex",
|
|
133
|
+
alignItems: "center",
|
|
134
|
+
justifyContent: "center",
|
|
135
|
+
width: size,
|
|
136
|
+
height: size,
|
|
137
|
+
minWidth: size,
|
|
138
|
+
color: "currentColor",
|
|
139
|
+
flexShrink: 0,
|
|
140
|
+
...style
|
|
141
|
+
},
|
|
142
|
+
children: /* @__PURE__ */ jsx(Icon, { size, stroke })
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
4
146
|
var OntologyKindSchema = z.enum([
|
|
5
147
|
"object",
|
|
6
148
|
"link",
|
|
@@ -332,40 +474,6 @@ function addLegacyActionProjections(index, diagnostics, sourcesById, actions, en
|
|
|
332
474
|
});
|
|
333
475
|
}
|
|
334
476
|
}
|
|
335
|
-
function addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, schemaPath) {
|
|
336
|
-
const content = system.content ?? {};
|
|
337
|
-
for (const [localId, node] of Object.entries(content)) {
|
|
338
|
-
if (node.kind !== "schema") continue;
|
|
339
|
-
const entries = Object.fromEntries(
|
|
340
|
-
Object.entries(content).filter(([, candidate]) => candidate.parentContentId === localId).map(([entryId, candidate]) => [
|
|
341
|
-
entryId,
|
|
342
|
-
{
|
|
343
|
-
label: candidate.label ?? entryId,
|
|
344
|
-
type: candidate.type,
|
|
345
|
-
...candidate.description !== void 0 ? { description: candidate.description } : {},
|
|
346
|
-
...candidate.data !== void 0 ? candidate.data : {}
|
|
347
|
-
}
|
|
348
|
-
])
|
|
349
|
-
);
|
|
350
|
-
const catalogType = {
|
|
351
|
-
id: formatOntologyId({ scope: systemPath, kind: "catalog", localId }),
|
|
352
|
-
label: node.label ?? localId,
|
|
353
|
-
description: node.description,
|
|
354
|
-
ownerSystemId: systemPath,
|
|
355
|
-
kind: node.type,
|
|
356
|
-
...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
|
|
357
|
-
...Object.keys(entries).length > 0 ? { entries } : {},
|
|
358
|
-
...node.data !== void 0 ? { data: node.data } : {}
|
|
359
|
-
};
|
|
360
|
-
addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
|
|
361
|
-
source: "legacy.system.content",
|
|
362
|
-
path: [...schemaPath, "content", localId],
|
|
363
|
-
kind: "projected",
|
|
364
|
-
systemPath,
|
|
365
|
-
legacyId: `${systemPath}:${localId}`
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
477
|
function addSystemScopes(index, diagnostics, sourcesById, systems, prefix, schemaPath) {
|
|
370
478
|
for (const [key, system] of Object.entries(systems)) {
|
|
371
479
|
const systemPath = prefix ? `${prefix}.${key}` : key;
|
|
@@ -374,7 +482,6 @@ function addSystemScopes(index, diagnostics, sourcesById, systems, prefix, schem
|
|
|
374
482
|
...currentPath,
|
|
375
483
|
"ontology"
|
|
376
484
|
]);
|
|
377
|
-
addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, currentPath);
|
|
378
485
|
addSystemScopes(index, diagnostics, sourcesById, childSystemsOf(system), systemPath, [
|
|
379
486
|
...currentPath,
|
|
380
487
|
system.systems !== void 0 ? "systems" : "subsystems"
|
|
@@ -399,6 +506,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
|
399
506
|
"crm",
|
|
400
507
|
"lead-gen",
|
|
401
508
|
"projects",
|
|
509
|
+
"clients",
|
|
402
510
|
"operations",
|
|
403
511
|
"monitoring",
|
|
404
512
|
"knowledge",
|
|
@@ -698,265 +806,7 @@ var ActionSchema = z.object({
|
|
|
698
806
|
var ActionsDomainSchema = z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
699
807
|
message: "Each action entry id must match its map key"
|
|
700
808
|
}).default({});
|
|
701
|
-
var
|
|
702
|
-
{
|
|
703
|
-
id: "lead-gen.company.source",
|
|
704
|
-
order: 10,
|
|
705
|
-
label: "Source companies",
|
|
706
|
-
description: "Import source companies from a list provider.",
|
|
707
|
-
scope: { domain: "sales" },
|
|
708
|
-
resourceId: "lgn-import-workflow",
|
|
709
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/source" }]
|
|
710
|
-
},
|
|
711
|
-
{
|
|
712
|
-
id: "lead-gen.company.apollo-import",
|
|
713
|
-
order: 20,
|
|
714
|
-
label: "Import from Apollo",
|
|
715
|
-
description: "Pull companies and seed contact data from an Apollo search or list.",
|
|
716
|
-
scope: { domain: "sales" },
|
|
717
|
-
resourceId: "lgn-01c-apollo-import-workflow",
|
|
718
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/apollo-import" }]
|
|
719
|
-
},
|
|
720
|
-
{
|
|
721
|
-
id: "lead-gen.contact.discover",
|
|
722
|
-
order: 30,
|
|
723
|
-
label: "Discover contact emails",
|
|
724
|
-
description: "Find email addresses for contacts at qualified companies.",
|
|
725
|
-
scope: { domain: "sales" },
|
|
726
|
-
resourceId: "lgn-04-email-discovery-workflow",
|
|
727
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/discover" }]
|
|
728
|
-
},
|
|
729
|
-
{
|
|
730
|
-
id: "lead-gen.contact.verify-email",
|
|
731
|
-
order: 40,
|
|
732
|
-
label: "Verify emails",
|
|
733
|
-
description: "Check email deliverability before outreach.",
|
|
734
|
-
scope: { domain: "sales" },
|
|
735
|
-
resourceId: "lgn-05-email-verification-workflow",
|
|
736
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/verify-email" }]
|
|
737
|
-
},
|
|
738
|
-
{
|
|
739
|
-
id: "lead-gen.company.apify-crawl",
|
|
740
|
-
order: 50,
|
|
741
|
-
label: "Crawl websites",
|
|
742
|
-
description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis.",
|
|
743
|
-
scope: { domain: "sales" },
|
|
744
|
-
resourceId: "lgn-02a-apify-website-crawl-workflow",
|
|
745
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/apify-crawl" }]
|
|
746
|
-
},
|
|
747
|
-
{
|
|
748
|
-
id: "lead-gen.company.website-extract",
|
|
749
|
-
order: 60,
|
|
750
|
-
label: "Extract website signals",
|
|
751
|
-
description: "Scrape and analyze company websites for qualification signals.",
|
|
752
|
-
scope: { domain: "sales" },
|
|
753
|
-
resourceId: "lgn-02-website-extract-workflow",
|
|
754
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/website-extract" }]
|
|
755
|
-
},
|
|
756
|
-
{
|
|
757
|
-
id: "lead-gen.company.qualify",
|
|
758
|
-
order: 70,
|
|
759
|
-
label: "Qualify companies",
|
|
760
|
-
description: "Score and filter companies against the ICP rubric.",
|
|
761
|
-
scope: { domain: "sales" },
|
|
762
|
-
resourceId: "lgn-03-company-qualification-workflow",
|
|
763
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/qualify" }]
|
|
764
|
-
},
|
|
765
|
-
{
|
|
766
|
-
id: "lead-gen.company.dtc-subscription-qualify",
|
|
767
|
-
order: 80,
|
|
768
|
-
label: "Qualify DTC subscription fit",
|
|
769
|
-
description: "Classify subscription potential and consumable-product fit for DTC brands.",
|
|
770
|
-
scope: { domain: "sales" },
|
|
771
|
-
resourceId: "lgn-03b-dtc-subscription-score-workflow",
|
|
772
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/dtc-subscription-qualify" }]
|
|
773
|
-
},
|
|
774
|
-
{
|
|
775
|
-
id: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
776
|
-
order: 90,
|
|
777
|
-
label: "Enrich decision-makers",
|
|
778
|
-
description: "Find and enrich qualified contacts at qualified companies via Apollo.",
|
|
779
|
-
scope: { domain: "sales" },
|
|
780
|
-
resourceId: "lgn-04b-apollo-decision-maker-enrich-workflow",
|
|
781
|
-
invocations: [
|
|
782
|
-
{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/apollo-decision-maker-enrich" }
|
|
783
|
-
]
|
|
784
|
-
},
|
|
785
|
-
{
|
|
786
|
-
id: "lead-gen.contact.personalize",
|
|
787
|
-
order: 100,
|
|
788
|
-
label: "Personalize outreach",
|
|
789
|
-
description: "Generate personalized opening lines for each contact.",
|
|
790
|
-
scope: { domain: "sales" },
|
|
791
|
-
resourceId: "ist-personalization-workflow",
|
|
792
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/personalize" }]
|
|
793
|
-
},
|
|
794
|
-
{
|
|
795
|
-
id: "lead-gen.review.outreach-ready",
|
|
796
|
-
order: 110,
|
|
797
|
-
label: "Upload to outreach",
|
|
798
|
-
description: "Upload approved contacts to the outreach sequence after QC review.",
|
|
799
|
-
scope: { domain: "sales" },
|
|
800
|
-
resourceId: "ist-upload-contacts-workflow",
|
|
801
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/review/outreach-ready" }]
|
|
802
|
-
},
|
|
803
|
-
{
|
|
804
|
-
id: "lead-gen.export.list",
|
|
805
|
-
order: 120,
|
|
806
|
-
label: "Export lead list",
|
|
807
|
-
description: "Export approved leads as a downloadable lead list.",
|
|
808
|
-
scope: { domain: "sales" },
|
|
809
|
-
resourceId: "lgn-06-export-list-workflow",
|
|
810
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/export/list" }]
|
|
811
|
-
},
|
|
812
|
-
{
|
|
813
|
-
id: "lead-gen.company.cleanup",
|
|
814
|
-
order: 130,
|
|
815
|
-
label: "Clean up companies",
|
|
816
|
-
description: "Remove disqualified or duplicate companies from the list.",
|
|
817
|
-
scope: { domain: "sales" },
|
|
818
|
-
resourceId: "lgn-company-cleanup-workflow",
|
|
819
|
-
invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/cleanup" }]
|
|
820
|
-
}
|
|
821
|
-
];
|
|
822
|
-
var LEAD_GEN_ACTION_ENTRIES = Object.fromEntries(
|
|
823
|
-
LEAD_GEN_ACTION_ENTRY_INPUTS.map((action) => {
|
|
824
|
-
const parsed = ActionSchema.parse(action);
|
|
825
|
-
return [parsed.id, parsed];
|
|
826
|
-
})
|
|
827
|
-
);
|
|
828
|
-
var CRM_ACTION_ENTRY_INPUTS = [
|
|
829
|
-
{
|
|
830
|
-
id: "send_reply",
|
|
831
|
-
order: 210,
|
|
832
|
-
label: "Send Reply",
|
|
833
|
-
description: "Send a contextual reply for an active CRM deal.",
|
|
834
|
-
scope: { domain: "sales" },
|
|
835
|
-
resourceId: "crm-send-reply-workflow",
|
|
836
|
-
affects: ["crm.deal"]
|
|
837
|
-
},
|
|
838
|
-
{
|
|
839
|
-
id: "send_link",
|
|
840
|
-
order: 220,
|
|
841
|
-
label: "Send Booking Link",
|
|
842
|
-
description: "Send a booking link to move a deal toward a scheduled call.",
|
|
843
|
-
scope: { domain: "sales" },
|
|
844
|
-
resourceId: "crm-send-booking-link-workflow",
|
|
845
|
-
affects: ["crm.deal"]
|
|
846
|
-
},
|
|
847
|
-
{
|
|
848
|
-
id: "send_nudge",
|
|
849
|
-
order: 230,
|
|
850
|
-
label: "Send Nudge",
|
|
851
|
-
description: "Send a follow-up nudge for a stalled CRM deal.",
|
|
852
|
-
scope: { domain: "sales" },
|
|
853
|
-
resourceId: "crm-send-nudge-workflow",
|
|
854
|
-
affects: ["crm.deal"]
|
|
855
|
-
},
|
|
856
|
-
{
|
|
857
|
-
id: "rebook",
|
|
858
|
-
order: 240,
|
|
859
|
-
label: "Rebook",
|
|
860
|
-
description: "Rebook a missed or rescheduled CRM appointment.",
|
|
861
|
-
scope: { domain: "sales" },
|
|
862
|
-
resourceId: "crm-rebook-workflow",
|
|
863
|
-
affects: ["crm.deal"]
|
|
864
|
-
},
|
|
865
|
-
{
|
|
866
|
-
id: "move_to_proposal",
|
|
867
|
-
order: 250,
|
|
868
|
-
label: "Move to Proposal",
|
|
869
|
-
description: "Advance a qualified CRM deal into the proposal stage.",
|
|
870
|
-
scope: { domain: "sales" },
|
|
871
|
-
resourceId: "move_to_proposal-workflow",
|
|
872
|
-
affects: ["crm.deal"]
|
|
873
|
-
},
|
|
874
|
-
{
|
|
875
|
-
id: "move_to_closing",
|
|
876
|
-
order: 260,
|
|
877
|
-
label: "Move to Closing",
|
|
878
|
-
description: "Advance a proposal-stage CRM deal into closing.",
|
|
879
|
-
scope: { domain: "sales" },
|
|
880
|
-
resourceId: "move_to_closing-workflow",
|
|
881
|
-
affects: ["crm.deal"]
|
|
882
|
-
},
|
|
883
|
-
{
|
|
884
|
-
id: "move_to_closed_won",
|
|
885
|
-
order: 270,
|
|
886
|
-
label: "Close Won",
|
|
887
|
-
description: "Mark a CRM deal as closed won.",
|
|
888
|
-
scope: { domain: "sales" },
|
|
889
|
-
resourceId: "move_to_closed_won-workflow",
|
|
890
|
-
affects: ["crm.deal"]
|
|
891
|
-
},
|
|
892
|
-
{
|
|
893
|
-
id: "move_to_closed_lost",
|
|
894
|
-
order: 280,
|
|
895
|
-
label: "Close Lost",
|
|
896
|
-
description: "Mark a CRM deal as closed lost.",
|
|
897
|
-
scope: { domain: "sales" },
|
|
898
|
-
resourceId: "move_to_closed_lost-workflow",
|
|
899
|
-
affects: ["crm.deal"]
|
|
900
|
-
},
|
|
901
|
-
{
|
|
902
|
-
id: "move_to_nurturing",
|
|
903
|
-
order: 290,
|
|
904
|
-
label: "Move to Nurturing",
|
|
905
|
-
description: "Move a CRM deal into nurturing for future follow-up.",
|
|
906
|
-
scope: { domain: "sales" },
|
|
907
|
-
resourceId: "move_to_nurturing-workflow",
|
|
908
|
-
affects: ["crm.deal"]
|
|
909
|
-
}
|
|
910
|
-
];
|
|
911
|
-
var CRM_ACTION_ENTRIES = Object.fromEntries(
|
|
912
|
-
CRM_ACTION_ENTRY_INPUTS.map((action) => {
|
|
913
|
-
const parsed = ActionSchema.parse(action);
|
|
914
|
-
return [parsed.id, parsed];
|
|
915
|
-
})
|
|
916
|
-
);
|
|
917
|
-
var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {
|
|
918
|
-
...LEAD_GEN_ACTION_ENTRIES,
|
|
919
|
-
...CRM_ACTION_ENTRIES
|
|
920
|
-
};
|
|
921
|
-
var ContentNodeBaseSchema = z.object({
|
|
922
|
-
/** Human-readable label for the content node. */
|
|
923
|
-
label: z.string().trim().min(1).max(120).meta({ label: "Label" }),
|
|
924
|
-
/** Optional one-paragraph description. */
|
|
925
|
-
description: z.string().trim().min(1).max(2e3).optional().meta({ label: "Description" }),
|
|
926
|
-
/** Optional display order within the system content map. */
|
|
927
|
-
order: z.number().int().optional().meta({ label: "Order" }),
|
|
928
|
-
/**
|
|
929
|
-
* Local NodeId of the parent content node within the SAME system.
|
|
930
|
-
* Per B4/L9: MUST resolve to a sibling in the same `system.content` map.
|
|
931
|
-
* Per L19: parent and child MUST share the same `kind` (meta-category).
|
|
932
|
-
*/
|
|
933
|
-
parentContentId: z.string().trim().min(1).max(200).optional().meta({ label: "Parent content id" })
|
|
934
|
-
});
|
|
935
|
-
var ContentNodeSchema = ContentNodeBaseSchema.extend({
|
|
936
|
-
/** Meta-category (e.g. 'schema', 'config', 'knowledge', tenant-defined). */
|
|
937
|
-
kind: z.string().trim().min(1).max(100).meta({ label: "Kind" }),
|
|
938
|
-
/** Specific family within the meta-category (e.g. 'pipeline', 'kv'). */
|
|
939
|
-
type: z.string().trim().min(1).max(100).meta({ label: "Type" }),
|
|
940
|
-
/** Payload data; validated against registered payloadSchema when (kind, type) is known. */
|
|
941
|
-
data: z.record(z.string(), z.unknown()).optional().meta({ label: "Data" })
|
|
942
|
-
});
|
|
943
|
-
z.object({
|
|
944
|
-
/** Meta-category (tenant-defined or registry-shipped). */
|
|
945
|
-
kind: z.string().trim().min(1).max(100).meta({ label: "Kind" }),
|
|
946
|
-
/** Specific family within the meta-category. */
|
|
947
|
-
type: z.string().trim().min(1).max(100).meta({ label: "Type" }),
|
|
948
|
-
/** Human-readable label shown in the KB tree and describe views. */
|
|
949
|
-
label: z.string().trim().min(1).max(120).meta({ label: "Label" }),
|
|
950
|
-
/** Optional description. */
|
|
951
|
-
description: z.string().trim().min(1).max(2e3).optional().meta({ label: "Description" }),
|
|
952
|
-
/**
|
|
953
|
-
* Which KB tree group this extension renders in.
|
|
954
|
-
* Per L6: 'business-model' places it alongside Customers / Offerings / Goals.
|
|
955
|
-
*/
|
|
956
|
-
treeGroup: z.union([z.enum(["profile", "business-model", "systems", "graph", "governance-wiring"]), z.string().min(1).max(100)]).meta({ label: "Tree group" }),
|
|
957
|
-
/** Untyped payload; shape governed by the registered payloadSchema when available. */
|
|
958
|
-
data: z.record(z.string(), z.unknown()).optional().meta({ label: "Data" })
|
|
959
|
-
});
|
|
809
|
+
var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {};
|
|
960
810
|
|
|
961
811
|
// ../core/src/organization-model/domains/systems.ts
|
|
962
812
|
var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
|
|
@@ -970,7 +820,7 @@ var SystemPathSchema = z.string().trim().min(1).regex(
|
|
|
970
820
|
var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]).meta({ label: "UI position" });
|
|
971
821
|
var NodeIdStringSchema = z.string().trim().min(1).max(200).regex(
|
|
972
822
|
/^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
|
|
973
|
-
"Node references must use kind:dotted-path (e.g. system:sales.crm or
|
|
823
|
+
"Node references must use kind:dotted-path (e.g. system:sales.crm or resource:lead-gen.company.qualify)"
|
|
974
824
|
);
|
|
975
825
|
var SystemUiSchema = z.object({
|
|
976
826
|
path: PathSchema,
|
|
@@ -1044,13 +894,6 @@ var SystemEntrySchema = z.object({
|
|
|
1044
894
|
* shared contract records owned by this system.
|
|
1045
895
|
*/
|
|
1046
896
|
ontology: OntologyScopeSchema.optional(),
|
|
1047
|
-
/**
|
|
1048
|
-
* @deprecated Compatibility-only bridge for old tenant content nodes and
|
|
1049
|
-
* migration readers. New schema/catalog authoring belongs in ontology;
|
|
1050
|
-
* new system-local settings belong in config. Bridge nodes are keyed by
|
|
1051
|
-
* local NodeId and may still project to content-node:* graph IDs.
|
|
1052
|
-
*/
|
|
1053
|
-
content: z.record(z.string().trim().min(1).max(200), ContentNodeSchema).optional(),
|
|
1054
897
|
/**
|
|
1055
898
|
* Recursive child systems, authored via nesting (per L11).
|
|
1056
899
|
* The key is the local system id; the full path is computed by joining
|
|
@@ -1061,7 +904,7 @@ var SystemEntrySchema = z.object({
|
|
|
1061
904
|
systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
|
|
1062
905
|
/** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
|
|
1063
906
|
subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
|
|
1064
|
-
}).refine((system) => system.label !== void 0 || system.title !== void 0, {
|
|
907
|
+
}).strict().refine((system) => system.label !== void 0 || system.title !== void 0, {
|
|
1065
908
|
path: ["label"],
|
|
1066
909
|
message: "System must provide label or title"
|
|
1067
910
|
}).transform((system) => {
|
|
@@ -1140,6 +983,10 @@ var DEFAULT_ORGANIZATION_MODEL_IDENTITY = {
|
|
|
1140
983
|
businessHours: {},
|
|
1141
984
|
clientBrief: ""
|
|
1142
985
|
};
|
|
986
|
+
var ContractRefSchema = z.string().trim().min(1).max(500).regex(
|
|
987
|
+
/^[A-Za-z0-9@](?:[A-Za-z0-9_./@-]*[A-Za-z0-9_])?\/?[A-Za-z0-9_./@-]*#[A-Za-z_$][A-Za-z0-9_$]*$/,
|
|
988
|
+
"ContractRef must be in the format package/subpath#ExportName (e.g. @repo/elevasis-core/contracts/apollo-import#inputSchema)"
|
|
989
|
+
);
|
|
1143
990
|
z.enum(["workflow", "agent", "integration", "script"]).meta({ label: "Resource kind", color: "orange" });
|
|
1144
991
|
var ResourceGovernanceStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Governance status", color: "teal" });
|
|
1145
992
|
var AgentKindSchema = z.enum(["orchestrator", "specialist", "utility", "platform"]).meta({ label: "Agent kind", color: "violet" });
|
|
@@ -1168,7 +1015,20 @@ var ResourceOntologyBindingSchema = z.object({
|
|
|
1168
1015
|
reads: z.array(OntologyIdSchema).optional(),
|
|
1169
1016
|
writes: z.array(OntologyIdSchema).optional(),
|
|
1170
1017
|
usesCatalogs: z.array(OntologyIdSchema).optional(),
|
|
1171
|
-
emits: z.array(OntologyIdSchema).optional()
|
|
1018
|
+
emits: z.array(OntologyIdSchema).optional(),
|
|
1019
|
+
/**
|
|
1020
|
+
* Optional typed contract binding for this resource's workflow I/O.
|
|
1021
|
+
* Each ref is a `package/subpath#ExportName` string that resolves to a
|
|
1022
|
+
* Zod schema in `@repo/elevasis-core` (or the consumer's equivalent package).
|
|
1023
|
+
*
|
|
1024
|
+
* Absence of this field preserves all existing behavior — it is additive + optional.
|
|
1025
|
+
* Tier-1 validation (schema.ts): ref-string shape only (browser-safe, no imports).
|
|
1026
|
+
* Tier-2 validation (om:verify): intra-package typed-map resolution asserts ZodType.
|
|
1027
|
+
*/
|
|
1028
|
+
contract: z.object({
|
|
1029
|
+
input: ContractRefSchema.optional(),
|
|
1030
|
+
output: ContractRefSchema.optional()
|
|
1031
|
+
}).optional()
|
|
1172
1032
|
}).superRefine((binding, ctx) => {
|
|
1173
1033
|
if (binding.primaryAction === void 0) return;
|
|
1174
1034
|
if (binding.actions?.includes(binding.primaryAction)) return;
|
|
@@ -1248,6 +1108,11 @@ var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((re
|
|
|
1248
1108
|
message: "Each resource entry id must match its map key"
|
|
1249
1109
|
}).default({});
|
|
1250
1110
|
var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
|
|
1111
|
+
function defineResources(resources) {
|
|
1112
|
+
return Object.fromEntries(
|
|
1113
|
+
Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1251
1116
|
|
|
1252
1117
|
// ../core/src/organization-model/helpers.ts
|
|
1253
1118
|
function childSystemsOf2(system) {
|
|
@@ -1319,8 +1184,8 @@ function getSystemAncestors(model, path) {
|
|
|
1319
1184
|
function listAllSystems(model) {
|
|
1320
1185
|
const results = [];
|
|
1321
1186
|
function walk(map, prefix) {
|
|
1322
|
-
for (const [
|
|
1323
|
-
const fullPath = prefix ? `${prefix}.${
|
|
1187
|
+
for (const [localId2, system] of Object.entries(map)) {
|
|
1188
|
+
const fullPath = prefix ? `${prefix}.${localId2}` : localId2;
|
|
1324
1189
|
results.push({ path: fullPath, system });
|
|
1325
1190
|
const childSystems = childSystemsOf2(system);
|
|
1326
1191
|
if (Object.keys(childSystems).length > 0) {
|
|
@@ -1331,15 +1196,6 @@ function listAllSystems(model) {
|
|
|
1331
1196
|
walk(model.systems, "");
|
|
1332
1197
|
return results;
|
|
1333
1198
|
}
|
|
1334
|
-
function getContent(model, qualifiedId) {
|
|
1335
|
-
const colonIndex = qualifiedId.indexOf(":");
|
|
1336
|
-
if (colonIndex === -1) return void 0;
|
|
1337
|
-
const systemPath = qualifiedId.slice(0, colonIndex);
|
|
1338
|
-
const localId = qualifiedId.slice(colonIndex + 1);
|
|
1339
|
-
if (!systemPath || !localId) return void 0;
|
|
1340
|
-
const system = getSystem(model, systemPath);
|
|
1341
|
-
return system?.content?.[localId];
|
|
1342
|
-
}
|
|
1343
1199
|
function isPlainJsonObject(value) {
|
|
1344
1200
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1345
1201
|
}
|
|
@@ -1354,15 +1210,7 @@ function mergeJsonConfig(base, override) {
|
|
|
1354
1210
|
function resolveSystemConfig(model, path) {
|
|
1355
1211
|
const system = getSystem(model, path);
|
|
1356
1212
|
if (system === void 0) return {};
|
|
1357
|
-
|
|
1358
|
-
for (const node of Object.values(system.content ?? {})) {
|
|
1359
|
-
if (node.kind !== "config" || node.type !== "kv") continue;
|
|
1360
|
-
const entries = node.data?.entries;
|
|
1361
|
-
if (isPlainJsonObject(entries)) {
|
|
1362
|
-
resolved = mergeJsonConfig(resolved, entries);
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
return mergeJsonConfig(resolved, system.config ?? {});
|
|
1213
|
+
return mergeJsonConfig({}, system.config ?? {});
|
|
1366
1214
|
}
|
|
1367
1215
|
function getResourcesForSystem(model, systemPath, options = {}) {
|
|
1368
1216
|
const { includeDescendants = false } = options;
|
|
@@ -1371,861 +1219,241 @@ function getResourcesForSystem(model, systemPath, options = {}) {
|
|
|
1371
1219
|
(r) => r.systemPath === systemPath || includeDescendants && r.systemPath.startsWith(prefix)
|
|
1372
1220
|
);
|
|
1373
1221
|
}
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1222
|
+
|
|
1223
|
+
// ../core/src/organization-model/migration-helpers.ts
|
|
1224
|
+
function catalogRecords(model) {
|
|
1225
|
+
return Object.values(compileOrganizationOntology(model).ontology.catalogTypes);
|
|
1226
|
+
}
|
|
1227
|
+
function localId(id) {
|
|
1228
|
+
return parseOntologyId(id).localId;
|
|
1229
|
+
}
|
|
1230
|
+
function systemScope(id, fallback) {
|
|
1231
|
+
return parseOntologyId(id).scope || fallback || "";
|
|
1232
|
+
}
|
|
1233
|
+
function entriesOf(catalog) {
|
|
1234
|
+
return Object.entries(catalog.entries ?? {}).map(([id, value]) => [
|
|
1235
|
+
id,
|
|
1236
|
+
value && typeof value === "object" && !Array.isArray(value) ? value : {}
|
|
1237
|
+
]);
|
|
1238
|
+
}
|
|
1239
|
+
function stringValue(value) {
|
|
1240
|
+
return typeof value === "string" ? value : void 0;
|
|
1241
|
+
}
|
|
1242
|
+
function stringArray(value) {
|
|
1243
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
1244
|
+
}
|
|
1245
|
+
function numberValue(value, fallback = 0) {
|
|
1246
|
+
return typeof value === "number" ? value : fallback;
|
|
1247
|
+
}
|
|
1248
|
+
function stageFromEntry(entryId, entry) {
|
|
1249
|
+
return {
|
|
1250
|
+
id: entryId,
|
|
1251
|
+
label: stringValue(entry.label) ?? entryId,
|
|
1252
|
+
order: numberValue(entry.order),
|
|
1253
|
+
semanticClass: stringValue(entry.semanticClass) ?? "open",
|
|
1254
|
+
surfaceIds: stringArray(entry.surfaceIds),
|
|
1255
|
+
resourceIds: stringArray(entry.resourceIds),
|
|
1256
|
+
color: stringValue(entry.color)
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
function appliesToLocalId(catalog) {
|
|
1260
|
+
const appliesTo = catalog.appliesTo;
|
|
1261
|
+
if (appliesTo === void 0) return void 0;
|
|
1262
|
+
return parseOntologyId(appliesTo).localId;
|
|
1263
|
+
}
|
|
1264
|
+
function appliesToEntityKind(catalog) {
|
|
1265
|
+
const id = appliesToLocalId(catalog);
|
|
1266
|
+
if (id === "company" || id === "contact" || id === "project" || id === "milestone" || id === "task") return id;
|
|
1267
|
+
if (id === "deal") return void 0;
|
|
1268
|
+
return void 0;
|
|
1269
|
+
}
|
|
1270
|
+
function getAllPipelines(model) {
|
|
1271
|
+
return catalogRecords(model).filter((catalog) => catalog.kind === "pipeline").map((catalog) => {
|
|
1272
|
+
const pipeline = {
|
|
1273
|
+
id: localId(catalog.id),
|
|
1274
|
+
label: catalog.label ?? localId(catalog.id),
|
|
1275
|
+
...catalog.description ? { description: catalog.description } : {},
|
|
1276
|
+
entityId: appliesToLocalId(catalog) ?? "",
|
|
1277
|
+
stages: entriesOf(catalog).map(([entryId, entry]) => stageFromEntry(entryId, entry)).sort((a, b) => a.order - b.order || a.id.localeCompare(b.id))
|
|
1278
|
+
};
|
|
1279
|
+
return { systemPath: catalog.ownerSystemId ?? systemScope(catalog.id), pipeline };
|
|
1280
|
+
}).sort((a, b) => a.systemPath.localeCompare(b.systemPath) || a.pipeline.id.localeCompare(b.pipeline.id));
|
|
1281
|
+
}
|
|
1282
|
+
function getAllBuildTemplates(model) {
|
|
1283
|
+
const catalogs = catalogRecords(model);
|
|
1284
|
+
const stepCatalogs = new Map(
|
|
1285
|
+
catalogs.filter((catalog) => catalog.kind === "template-step").map((catalog) => [catalog.id, catalog])
|
|
1286
|
+
);
|
|
1287
|
+
return catalogs.filter((catalog) => catalog.kind === "template").flatMap(
|
|
1288
|
+
(catalog) => entriesOf(catalog).map(([templateId, templateEntry]) => {
|
|
1289
|
+
const stepCatalogId = stringValue(templateEntry.stepCatalog);
|
|
1290
|
+
const stepCatalog = stepCatalogId !== void 0 ? stepCatalogs.get(stepCatalogId) : void 0;
|
|
1291
|
+
const steps = stepCatalog === void 0 ? [] : entriesOf(stepCatalog);
|
|
1292
|
+
return {
|
|
1293
|
+
id: templateId,
|
|
1294
|
+
label: stringValue(templateEntry.label) ?? templateId,
|
|
1295
|
+
...stringValue(templateEntry.description) ? { description: stringValue(templateEntry.description) } : {},
|
|
1296
|
+
...stringValue(templateEntry.color) ? { color: stringValue(templateEntry.color) } : {},
|
|
1297
|
+
steps: steps.map(([stepId, step]) => ({
|
|
1298
|
+
id: stepId,
|
|
1299
|
+
label: stringValue(step.label) ?? stepId,
|
|
1300
|
+
...stringValue(step.description) ? { description: stringValue(step.description) } : {},
|
|
1301
|
+
...step
|
|
1302
|
+
}))
|
|
1303
|
+
};
|
|
1304
|
+
})
|
|
1305
|
+
).sort((a, b) => a.id.localeCompare(b.id));
|
|
1306
|
+
}
|
|
1307
|
+
function getAllProspectingStages(model, kind) {
|
|
1308
|
+
return catalogRecords(model).filter((catalog) => catalog.kind === "stage" && appliesToEntityKind(catalog) === kind).flatMap(
|
|
1309
|
+
(catalog) => entriesOf(catalog).map(([entryId, entry]) => ({
|
|
1310
|
+
id: entryId,
|
|
1311
|
+
label: stringValue(entry.label) ?? entryId,
|
|
1312
|
+
order: numberValue(entry.order),
|
|
1313
|
+
...stringValue(entry.color) ? { color: stringValue(entry.color) } : {},
|
|
1314
|
+
...stringValue(entry.description) ? { description: stringValue(entry.description) } : {}
|
|
1315
|
+
}))
|
|
1316
|
+
).sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
|
|
1317
|
+
}
|
|
1318
|
+
function getLeadGenStageCatalog(model) {
|
|
1319
|
+
const results = {};
|
|
1320
|
+
for (const catalog of catalogRecords(model).filter(
|
|
1321
|
+
(record) => record.kind === "stage" && (record.ownerSystemId ?? systemScope(record.id)) === "sales.lead-gen"
|
|
1322
|
+
)) {
|
|
1323
|
+
const catalogEntity = appliesToEntityKind(catalog);
|
|
1324
|
+
if (catalogEntity !== "company" && catalogEntity !== "contact") continue;
|
|
1325
|
+
for (const [entryId, entry] of entriesOf(catalog)) {
|
|
1326
|
+
const entity = entry.entity === "contact" ? "contact" : entry.entity === "company" ? "company" : catalogEntity;
|
|
1327
|
+
const additionalEntities = stringArray(entry.additionalEntities).filter(
|
|
1328
|
+
(item) => item === "company" || item === "contact"
|
|
1329
|
+
);
|
|
1330
|
+
const recordEntity = entry.recordEntity === "company" || entry.recordEntity === "contact" ? entry.recordEntity : void 0;
|
|
1331
|
+
const recordStageKey = stringValue(entry.recordStageKey);
|
|
1332
|
+
results[entryId] = {
|
|
1333
|
+
key: entryId,
|
|
1334
|
+
label: stringValue(entry.label) ?? entryId,
|
|
1335
|
+
description: stringValue(entry.description) ?? "",
|
|
1336
|
+
order: numberValue(entry.order),
|
|
1337
|
+
entity,
|
|
1338
|
+
...additionalEntities.length > 0 ? { additionalEntities } : {},
|
|
1339
|
+
...recordEntity ? { recordEntity } : {},
|
|
1340
|
+
...recordStageKey ? { recordStageKey } : {}
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
return Object.fromEntries(
|
|
1345
|
+
Object.entries(results).sort(([, a], [, b]) => a.order - b.order || a.key.localeCompare(b.key))
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
function getAllProjectStatuses(model, appliesTo) {
|
|
1349
|
+
return catalogRecords(model).filter((catalog) => catalog.kind === "status-flow" && appliesToEntityKind(catalog) === appliesTo).flatMap(
|
|
1350
|
+
(catalog) => entriesOf(catalog).map(([entryId, entry]) => ({
|
|
1351
|
+
id: entryId,
|
|
1352
|
+
label: stringValue(entry.label) ?? entryId,
|
|
1353
|
+
order: numberValue(entry.order),
|
|
1354
|
+
...stringValue(entry.color) ? { color: stringValue(entry.color) } : {},
|
|
1355
|
+
...stringValue(entry.description) ? { description: stringValue(entry.description) } : {}
|
|
1356
|
+
}))
|
|
1357
|
+
).sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
// ../core/src/organization-model/contracts.ts
|
|
1361
|
+
var PROJECTS_VIEW_ACTION_ID = "delivery.projects.view";
|
|
1362
|
+
var OrganizationModelBrandingSchema = z.object({
|
|
1363
|
+
organizationName: LabelSchema,
|
|
1364
|
+
productName: LabelSchema,
|
|
1365
|
+
shortName: z.string().trim().min(1).max(40),
|
|
1366
|
+
description: DescriptionSchema.optional(),
|
|
1367
|
+
logos: z.object({
|
|
1368
|
+
light: z.string().trim().min(1).max(2048).optional(),
|
|
1369
|
+
dark: z.string().trim().min(1).max(2048).optional()
|
|
1370
|
+
}).default({})
|
|
1377
1371
|
});
|
|
1378
|
-
var
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1372
|
+
var DEFAULT_ORGANIZATION_MODEL_BRANDING = {
|
|
1373
|
+
organizationName: "Default Organization",
|
|
1374
|
+
productName: "Elevasis",
|
|
1375
|
+
shortName: "Elevasis",
|
|
1376
|
+
logos: {}
|
|
1377
|
+
};
|
|
1378
|
+
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]).meta({ label: "Surface type", color: "blue" });
|
|
1379
|
+
var SurfaceDefinitionSchema = z.object({
|
|
1380
|
+
id: ModelIdSchema,
|
|
1381
|
+
label: LabelSchema,
|
|
1382
|
+
path: PathSchema,
|
|
1383
|
+
surfaceType: SurfaceTypeSchema,
|
|
1384
|
+
description: DescriptionSchema.optional(),
|
|
1385
|
+
enabled: z.boolean().default(true),
|
|
1386
|
+
devOnly: z.boolean().optional(),
|
|
1387
|
+
icon: IconNameSchema.optional(),
|
|
1388
|
+
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
1389
|
+
entityIds: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]),
|
|
1390
|
+
resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
|
|
1391
|
+
actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
|
|
1392
|
+
parentId: ModelIdSchema.meta({ ref: "surface" }).optional()
|
|
1385
1393
|
});
|
|
1386
|
-
var
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1394
|
+
var SidebarSurfaceTargetsSchema = z.object({
|
|
1395
|
+
systems: z.array(ModelIdSchema.meta({ ref: "system" })).default([]).optional(),
|
|
1396
|
+
entities: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]).optional(),
|
|
1397
|
+
resources: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]).optional(),
|
|
1398
|
+
actions: z.array(ModelIdSchema.meta({ ref: "action" })).default([]).optional()
|
|
1399
|
+
}).default({});
|
|
1400
|
+
var SidebarNodeSchema = z.lazy(
|
|
1401
|
+
() => z.discriminatedUnion("type", [
|
|
1402
|
+
z.object({
|
|
1403
|
+
type: z.literal("group"),
|
|
1404
|
+
label: LabelSchema,
|
|
1405
|
+
description: DescriptionSchema.optional(),
|
|
1406
|
+
icon: IconNameSchema.optional(),
|
|
1407
|
+
order: z.number().int().optional(),
|
|
1408
|
+
children: z.record(z.string(), SidebarNodeSchema).default({})
|
|
1409
|
+
}),
|
|
1410
|
+
z.object({
|
|
1411
|
+
type: z.literal("surface"),
|
|
1412
|
+
label: LabelSchema,
|
|
1413
|
+
path: PathSchema,
|
|
1414
|
+
surfaceType: SurfaceTypeSchema,
|
|
1415
|
+
description: DescriptionSchema.optional(),
|
|
1416
|
+
icon: IconNameSchema.optional(),
|
|
1417
|
+
order: z.number().int().optional(),
|
|
1418
|
+
targets: SidebarSurfaceTargetsSchema.optional(),
|
|
1419
|
+
devOnly: z.boolean().optional(),
|
|
1420
|
+
requiresAdmin: z.boolean().optional()
|
|
1421
|
+
})
|
|
1422
|
+
])
|
|
1423
|
+
);
|
|
1424
|
+
var SidebarSectionSchema = z.record(z.string(), SidebarNodeSchema).default({});
|
|
1425
|
+
var SidebarNavigationSchema = z.object({
|
|
1426
|
+
primary: SidebarSectionSchema,
|
|
1427
|
+
bottom: SidebarSectionSchema
|
|
1428
|
+
}).default({ primary: {}, bottom: {} });
|
|
1429
|
+
var OrganizationModelNavigationSchema = z.object({
|
|
1430
|
+
sidebar: SidebarNavigationSchema
|
|
1431
|
+
}).default({ sidebar: { primary: {}, bottom: {} } });
|
|
1432
|
+
function getSortedSidebarEntries(nodes) {
|
|
1433
|
+
return Object.entries(nodes).sort(([leftId, left], [rightId, right]) => {
|
|
1434
|
+
const orderDelta = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
|
|
1435
|
+
return orderDelta === 0 ? leftId.localeCompare(rightId) : orderDelta;
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
z.object({
|
|
1439
|
+
id: ModelIdSchema,
|
|
1440
|
+
label: LabelSchema,
|
|
1441
|
+
placement: z.string().trim().min(1).max(50),
|
|
1442
|
+
surfaceIds: z.array(ModelIdSchema.meta({ ref: "surface" })).default([])
|
|
1391
1443
|
});
|
|
1392
|
-
var
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
|
|
1406
|
-
stageKey: ModelIdSchema,
|
|
1407
|
-
recordEntity: z.enum(["company", "contact"]).optional(),
|
|
1408
|
-
recordsStageKey: ModelIdSchema.optional(),
|
|
1409
|
-
recordSourceStageKey: ModelIdSchema.optional(),
|
|
1410
|
-
dependsOn: z.array(ModelIdSchema).optional(),
|
|
1411
|
-
dependencyMode: z.literal("per-record-eligibility"),
|
|
1412
|
-
actionKey: ModelIdSchema,
|
|
1413
|
-
defaultBatchSize: z.number().int().positive(),
|
|
1414
|
-
maxBatchSize: z.number().int().positive(),
|
|
1415
|
-
recordColumns: RecordColumnsConfigSchema.optional(),
|
|
1416
|
-
credentialRequirements: z.array(CredentialRequirementSchema).optional()
|
|
1417
|
-
}).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
|
|
1418
|
-
message: "defaultBatchSize must be less than or equal to maxBatchSize",
|
|
1419
|
-
path: ["defaultBatchSize"]
|
|
1420
|
-
});
|
|
1421
|
-
DisplayMetadataSchema.extend({
|
|
1422
|
-
id: ModelIdSchema,
|
|
1423
|
-
steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
|
|
1424
|
-
});
|
|
1425
|
-
var DTC_RECORD_COLUMNS = {
|
|
1426
|
-
populated: {
|
|
1427
|
-
company: [
|
|
1428
|
-
{ key: "name", label: "Company", path: "company.name" },
|
|
1429
|
-
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
1430
|
-
{ key: "employee-count", label: "Employees", path: "company.numEmployees", renderType: "count" },
|
|
1431
|
-
{ key: "apollo-industry", label: "Apollo industry", path: "company.category" },
|
|
1432
|
-
{ key: "location", label: "Location", path: "company.locationState" }
|
|
1433
|
-
]
|
|
1434
|
-
},
|
|
1435
|
-
crawled: {
|
|
1436
|
-
company: [
|
|
1437
|
-
{ key: "name", label: "Company", path: "company.name" },
|
|
1438
|
-
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
1439
|
-
{ key: "page-count", label: "Pages", path: "company.enrichmentData.websiteCrawl.pageCount", renderType: "count" },
|
|
1440
|
-
{ key: "crawl-status", label: "Crawl status", path: "processingState.crawled.status", renderType: "badge" }
|
|
1441
|
-
]
|
|
1442
|
-
},
|
|
1443
|
-
extracted: {
|
|
1444
|
-
company: [
|
|
1445
|
-
{ key: "name", label: "Company", path: "company.name" },
|
|
1446
|
-
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
1447
|
-
{ key: "description", label: "Description", path: "company.enrichmentData.websiteCrawl.companyDescription" },
|
|
1448
|
-
{ key: "services", label: "Services", path: "company.enrichmentData.websiteCrawl.services", renderType: "json" },
|
|
1449
|
-
{
|
|
1450
|
-
key: "automation-gaps",
|
|
1451
|
-
label: "Automation gaps",
|
|
1452
|
-
path: "company.enrichmentData.websiteCrawl.automationGaps",
|
|
1453
|
-
renderType: "json"
|
|
1454
|
-
},
|
|
1455
|
-
{
|
|
1456
|
-
key: "contact-count",
|
|
1457
|
-
label: "Contacts",
|
|
1458
|
-
path: "company.enrichmentData.websiteCrawl.emailCount",
|
|
1459
|
-
renderType: "count"
|
|
1460
|
-
}
|
|
1461
|
-
]
|
|
1462
|
-
},
|
|
1463
|
-
qualified: {
|
|
1464
|
-
company: [
|
|
1465
|
-
{ key: "name", label: "Company", path: "company.name" },
|
|
1466
|
-
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
1467
|
-
{ key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
|
|
1468
|
-
{ key: "signals", label: "Signals", path: "company.qualificationSignals", renderType: "json" },
|
|
1469
|
-
{
|
|
1470
|
-
key: "disqualified-reason",
|
|
1471
|
-
label: "Disqualified reason",
|
|
1472
|
-
path: "processingState.qualified.data.disqualifiedReason"
|
|
1473
|
-
}
|
|
1474
|
-
]
|
|
1475
|
-
},
|
|
1476
|
-
decisionMakers: {
|
|
1477
|
-
contact: [
|
|
1478
|
-
{ key: "name", label: "Name", path: "contact.name" },
|
|
1479
|
-
{ key: "title", label: "Title", path: "contact.title" },
|
|
1480
|
-
{ key: "email", label: "Email", path: "contact.email" },
|
|
1481
|
-
{ key: "linkedin", label: "LinkedIn", path: "contact.linkedinUrl" },
|
|
1482
|
-
{
|
|
1483
|
-
key: "priority-score",
|
|
1484
|
-
label: "Priority",
|
|
1485
|
-
path: "contact.enrichmentData.apollo.priorityScore",
|
|
1486
|
-
renderType: "badge"
|
|
1487
|
-
}
|
|
1488
|
-
]
|
|
1489
|
-
},
|
|
1490
|
-
uploaded: {
|
|
1491
|
-
company: [
|
|
1492
|
-
{ key: "name", label: "Company", path: "company.name" },
|
|
1493
|
-
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
1494
|
-
{
|
|
1495
|
-
key: "contacts",
|
|
1496
|
-
label: "Contacts",
|
|
1497
|
-
path: "company.enrichmentData.approvedLeadListExport.contacts",
|
|
1498
|
-
renderType: "json"
|
|
1499
|
-
},
|
|
1500
|
-
{ key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
|
|
1501
|
-
{
|
|
1502
|
-
key: "approval",
|
|
1503
|
-
label: "Approval",
|
|
1504
|
-
path: "company.enrichmentData.approvedLeadListExport.approvalStatus",
|
|
1505
|
-
renderType: "badge"
|
|
1506
|
-
}
|
|
1507
|
-
]
|
|
1508
|
-
}
|
|
1509
|
-
};
|
|
1510
|
-
Object.values(LEAD_GEN_ACTION_ENTRIES);
|
|
1511
|
-
var PROSPECTING_STEPS = {
|
|
1512
|
-
localServices: {
|
|
1513
|
-
sourceCompanies: {
|
|
1514
|
-
id: "source-companies",
|
|
1515
|
-
label: "Companies found",
|
|
1516
|
-
primaryEntity: "company",
|
|
1517
|
-
outputs: ["company"],
|
|
1518
|
-
stageKey: "populated",
|
|
1519
|
-
dependencyMode: "per-record-eligibility",
|
|
1520
|
-
actionKey: "lead-gen.company.source",
|
|
1521
|
-
defaultBatchSize: 100,
|
|
1522
|
-
maxBatchSize: 250
|
|
1523
|
-
},
|
|
1524
|
-
analyzeWebsites: {
|
|
1525
|
-
id: "analyze-websites",
|
|
1526
|
-
label: "Websites analyzed",
|
|
1527
|
-
primaryEntity: "company",
|
|
1528
|
-
outputs: ["company"],
|
|
1529
|
-
stageKey: "extracted",
|
|
1530
|
-
dependsOn: ["source-companies"],
|
|
1531
|
-
dependencyMode: "per-record-eligibility",
|
|
1532
|
-
actionKey: "lead-gen.company.website-extract",
|
|
1533
|
-
defaultBatchSize: 50,
|
|
1534
|
-
maxBatchSize: 100
|
|
1535
|
-
},
|
|
1536
|
-
qualifyCompanies: {
|
|
1537
|
-
id: "qualify-companies",
|
|
1538
|
-
label: "Companies qualified",
|
|
1539
|
-
primaryEntity: "company",
|
|
1540
|
-
outputs: ["company"],
|
|
1541
|
-
stageKey: "qualified",
|
|
1542
|
-
dependsOn: ["analyze-websites"],
|
|
1543
|
-
dependencyMode: "per-record-eligibility",
|
|
1544
|
-
actionKey: "lead-gen.company.qualify",
|
|
1545
|
-
defaultBatchSize: 100,
|
|
1546
|
-
maxBatchSize: 250
|
|
1547
|
-
},
|
|
1548
|
-
findContacts: {
|
|
1549
|
-
id: "find-contacts",
|
|
1550
|
-
label: "Decision-makers found",
|
|
1551
|
-
primaryEntity: "contact",
|
|
1552
|
-
outputs: ["contact"],
|
|
1553
|
-
stageKey: "discovered",
|
|
1554
|
-
dependsOn: ["qualify-companies"],
|
|
1555
|
-
dependencyMode: "per-record-eligibility",
|
|
1556
|
-
actionKey: "lead-gen.contact.discover",
|
|
1557
|
-
defaultBatchSize: 50,
|
|
1558
|
-
maxBatchSize: 100
|
|
1559
|
-
},
|
|
1560
|
-
verifyEmails: {
|
|
1561
|
-
id: "verify-emails",
|
|
1562
|
-
label: "Emails verified",
|
|
1563
|
-
primaryEntity: "contact",
|
|
1564
|
-
outputs: ["contact"],
|
|
1565
|
-
stageKey: "verified",
|
|
1566
|
-
dependsOn: ["find-contacts"],
|
|
1567
|
-
dependencyMode: "per-record-eligibility",
|
|
1568
|
-
actionKey: "lead-gen.contact.verify-email",
|
|
1569
|
-
defaultBatchSize: 100,
|
|
1570
|
-
maxBatchSize: 500
|
|
1571
|
-
},
|
|
1572
|
-
personalize: {
|
|
1573
|
-
id: "personalize",
|
|
1574
|
-
label: "Personalize",
|
|
1575
|
-
primaryEntity: "contact",
|
|
1576
|
-
outputs: ["contact"],
|
|
1577
|
-
stageKey: "personalized",
|
|
1578
|
-
dependsOn: ["verify-emails"],
|
|
1579
|
-
dependencyMode: "per-record-eligibility",
|
|
1580
|
-
actionKey: "lead-gen.contact.personalize",
|
|
1581
|
-
defaultBatchSize: 25,
|
|
1582
|
-
maxBatchSize: 100
|
|
1583
|
-
},
|
|
1584
|
-
review: {
|
|
1585
|
-
id: "review",
|
|
1586
|
-
label: "Reviewed and exported",
|
|
1587
|
-
primaryEntity: "contact",
|
|
1588
|
-
outputs: ["export"],
|
|
1589
|
-
stageKey: "uploaded",
|
|
1590
|
-
dependsOn: ["personalize"],
|
|
1591
|
-
dependencyMode: "per-record-eligibility",
|
|
1592
|
-
actionKey: "lead-gen.review.outreach-ready",
|
|
1593
|
-
defaultBatchSize: 25,
|
|
1594
|
-
maxBatchSize: 100
|
|
1595
|
-
}
|
|
1596
|
-
},
|
|
1597
|
-
dtcApolloClickup: {
|
|
1598
|
-
importApolloSearch: {
|
|
1599
|
-
id: "import-apollo-search",
|
|
1600
|
-
label: "Companies found",
|
|
1601
|
-
description: "Pull companies and seed contact data from a predefined Apollo search or list.",
|
|
1602
|
-
primaryEntity: "company",
|
|
1603
|
-
outputs: ["company", "contact"],
|
|
1604
|
-
stageKey: "populated",
|
|
1605
|
-
dependencyMode: "per-record-eligibility",
|
|
1606
|
-
actionKey: "lead-gen.company.apollo-import",
|
|
1607
|
-
defaultBatchSize: 250,
|
|
1608
|
-
maxBatchSize: 1e3,
|
|
1609
|
-
recordColumns: DTC_RECORD_COLUMNS.populated,
|
|
1610
|
-
credentialRequirements: [
|
|
1611
|
-
{
|
|
1612
|
-
key: "apollo",
|
|
1613
|
-
provider: "apollo",
|
|
1614
|
-
credentialType: "api-key-secret",
|
|
1615
|
-
label: "Apollo API key",
|
|
1616
|
-
required: true,
|
|
1617
|
-
selectionMode: "single",
|
|
1618
|
-
inputPath: "credential"
|
|
1619
|
-
}
|
|
1620
|
-
]
|
|
1621
|
-
},
|
|
1622
|
-
apifyCrawl: {
|
|
1623
|
-
id: "apify-crawl",
|
|
1624
|
-
label: "Websites crawled",
|
|
1625
|
-
description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis. Overwrites the synthetic seed Apollo Import wrote with real page content.",
|
|
1626
|
-
primaryEntity: "company",
|
|
1627
|
-
outputs: ["company"],
|
|
1628
|
-
stageKey: "crawled",
|
|
1629
|
-
dependsOn: ["import-apollo-search"],
|
|
1630
|
-
dependencyMode: "per-record-eligibility",
|
|
1631
|
-
actionKey: "lead-gen.company.apify-crawl",
|
|
1632
|
-
defaultBatchSize: 50,
|
|
1633
|
-
maxBatchSize: 100,
|
|
1634
|
-
recordColumns: DTC_RECORD_COLUMNS.crawled,
|
|
1635
|
-
credentialRequirements: [
|
|
1636
|
-
{
|
|
1637
|
-
key: "apify",
|
|
1638
|
-
provider: "apify",
|
|
1639
|
-
credentialType: "api-key-secret",
|
|
1640
|
-
label: "Apify API token",
|
|
1641
|
-
required: true,
|
|
1642
|
-
selectionMode: "single",
|
|
1643
|
-
inputPath: "credential",
|
|
1644
|
-
verifyOnRun: true
|
|
1645
|
-
}
|
|
1646
|
-
]
|
|
1647
|
-
},
|
|
1648
|
-
analyzeWebsites: {
|
|
1649
|
-
id: "analyze-websites",
|
|
1650
|
-
label: "Websites analyzed",
|
|
1651
|
-
description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
|
|
1652
|
-
primaryEntity: "company",
|
|
1653
|
-
outputs: ["company"],
|
|
1654
|
-
stageKey: "extracted",
|
|
1655
|
-
dependsOn: ["apify-crawl"],
|
|
1656
|
-
dependencyMode: "per-record-eligibility",
|
|
1657
|
-
actionKey: "lead-gen.company.website-extract",
|
|
1658
|
-
defaultBatchSize: 50,
|
|
1659
|
-
maxBatchSize: 100,
|
|
1660
|
-
recordColumns: DTC_RECORD_COLUMNS.extracted
|
|
1661
|
-
},
|
|
1662
|
-
scoreDtcFit: {
|
|
1663
|
-
id: "score-dtc-fit",
|
|
1664
|
-
label: "Companies qualified",
|
|
1665
|
-
description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
|
|
1666
|
-
primaryEntity: "company",
|
|
1667
|
-
outputs: ["company"],
|
|
1668
|
-
stageKey: "qualified",
|
|
1669
|
-
dependsOn: ["analyze-websites"],
|
|
1670
|
-
dependencyMode: "per-record-eligibility",
|
|
1671
|
-
actionKey: "lead-gen.company.dtc-subscription-qualify",
|
|
1672
|
-
defaultBatchSize: 100,
|
|
1673
|
-
maxBatchSize: 250,
|
|
1674
|
-
recordColumns: DTC_RECORD_COLUMNS.qualified
|
|
1675
|
-
},
|
|
1676
|
-
enrichDecisionMakers: {
|
|
1677
|
-
id: "enrich-decision-makers",
|
|
1678
|
-
label: "Decision-makers found",
|
|
1679
|
-
description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
|
|
1680
|
-
primaryEntity: "company",
|
|
1681
|
-
outputs: ["contact"],
|
|
1682
|
-
stageKey: "decision-makers-enriched",
|
|
1683
|
-
recordEntity: "contact",
|
|
1684
|
-
dependsOn: ["score-dtc-fit"],
|
|
1685
|
-
dependencyMode: "per-record-eligibility",
|
|
1686
|
-
actionKey: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
1687
|
-
defaultBatchSize: 100,
|
|
1688
|
-
maxBatchSize: 250,
|
|
1689
|
-
recordColumns: DTC_RECORD_COLUMNS.decisionMakers,
|
|
1690
|
-
credentialRequirements: [
|
|
1691
|
-
{
|
|
1692
|
-
key: "apollo",
|
|
1693
|
-
provider: "apollo",
|
|
1694
|
-
credentialType: "api-key-secret",
|
|
1695
|
-
label: "Apollo API key",
|
|
1696
|
-
required: true,
|
|
1697
|
-
selectionMode: "single",
|
|
1698
|
-
inputPath: "credential"
|
|
1699
|
-
}
|
|
1700
|
-
]
|
|
1701
|
-
},
|
|
1702
|
-
reviewAndExport: {
|
|
1703
|
-
id: "review-and-export",
|
|
1704
|
-
label: "Reviewed and exported",
|
|
1705
|
-
description: "Operator QC approves or rejects qualified companies, then approved records are exported as a lead list with unverified emails.",
|
|
1706
|
-
primaryEntity: "company",
|
|
1707
|
-
outputs: ["export"],
|
|
1708
|
-
stageKey: "uploaded",
|
|
1709
|
-
recordsStageKey: "uploaded",
|
|
1710
|
-
recordSourceStageKey: "qualified",
|
|
1711
|
-
dependsOn: ["enrich-decision-makers"],
|
|
1712
|
-
dependencyMode: "per-record-eligibility",
|
|
1713
|
-
actionKey: "lead-gen.export.list",
|
|
1714
|
-
defaultBatchSize: 100,
|
|
1715
|
-
maxBatchSize: 250,
|
|
1716
|
-
recordColumns: DTC_RECORD_COLUMNS.uploaded,
|
|
1717
|
-
credentialRequirements: [
|
|
1718
|
-
{
|
|
1719
|
-
key: "clickup",
|
|
1720
|
-
provider: "clickup",
|
|
1721
|
-
credentialType: "api-key-secret",
|
|
1722
|
-
label: "ClickUp API token",
|
|
1723
|
-
required: true,
|
|
1724
|
-
selectionMode: "single",
|
|
1725
|
-
inputPath: "clickupCredential",
|
|
1726
|
-
verifyOnRun: true
|
|
1727
|
-
}
|
|
1728
|
-
]
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
};
|
|
1732
|
-
|
|
1733
|
-
// ../core/src/organization-model/catalogs/lead-gen.ts
|
|
1734
|
-
var LEAD_GEN_STAGE_CATALOG = {
|
|
1735
|
-
// Prospecting - company population
|
|
1736
|
-
scraped: {
|
|
1737
|
-
key: "scraped",
|
|
1738
|
-
label: "Scraped",
|
|
1739
|
-
description: "Company was scraped from a source directory (Apify actor run).",
|
|
1740
|
-
order: 1,
|
|
1741
|
-
entity: "company"
|
|
1742
|
-
},
|
|
1743
|
-
populated: {
|
|
1744
|
-
key: "populated",
|
|
1745
|
-
label: "Companies found",
|
|
1746
|
-
description: "Companies have been found and added to the lead-gen list.",
|
|
1747
|
-
order: 2,
|
|
1748
|
-
entity: "company"
|
|
1749
|
-
},
|
|
1750
|
-
crawled: {
|
|
1751
|
-
key: "crawled",
|
|
1752
|
-
label: "Websites crawled",
|
|
1753
|
-
description: "Company websites have been crawled (e.g. via Apify) and raw page content stored for downstream LLM analysis.",
|
|
1754
|
-
order: 2.5,
|
|
1755
|
-
entity: "company"
|
|
1756
|
-
},
|
|
1757
|
-
extracted: {
|
|
1758
|
-
key: "extracted",
|
|
1759
|
-
label: "Websites analyzed",
|
|
1760
|
-
description: "Company websites have been analyzed for business signals.",
|
|
1761
|
-
order: 3,
|
|
1762
|
-
entity: "company"
|
|
1763
|
-
},
|
|
1764
|
-
enriched: {
|
|
1765
|
-
key: "enriched",
|
|
1766
|
-
label: "Enriched",
|
|
1767
|
-
description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
|
|
1768
|
-
order: 4,
|
|
1769
|
-
entity: "company"
|
|
1770
|
-
},
|
|
1771
|
-
"decision-makers-enriched": {
|
|
1772
|
-
key: "decision-makers-enriched",
|
|
1773
|
-
label: "Decision-makers found",
|
|
1774
|
-
description: "Decision-maker contacts discovered and attached to a qualified company.",
|
|
1775
|
-
order: 6,
|
|
1776
|
-
entity: "company",
|
|
1777
|
-
recordEntity: "contact",
|
|
1778
|
-
recordStageKey: "discovered"
|
|
1779
|
-
},
|
|
1780
|
-
// Prospecting - contact discovery
|
|
1781
|
-
discovered: {
|
|
1782
|
-
key: "discovered",
|
|
1783
|
-
label: "Decision-makers found",
|
|
1784
|
-
description: "Decision-maker contact details have been found.",
|
|
1785
|
-
order: 5,
|
|
1786
|
-
entity: "contact"
|
|
1787
|
-
},
|
|
1788
|
-
verified: {
|
|
1789
|
-
key: "verified",
|
|
1790
|
-
label: "Emails verified",
|
|
1791
|
-
description: "Contact email addresses have been checked for deliverability.",
|
|
1792
|
-
order: 7,
|
|
1793
|
-
entity: "contact"
|
|
1794
|
-
},
|
|
1795
|
-
// Qualification
|
|
1796
|
-
qualified: {
|
|
1797
|
-
key: "qualified",
|
|
1798
|
-
label: "Companies qualified",
|
|
1799
|
-
description: "Companies have been scored against the qualification criteria.",
|
|
1800
|
-
order: 8,
|
|
1801
|
-
entity: "company"
|
|
1802
|
-
},
|
|
1803
|
-
// Outreach
|
|
1804
|
-
personalized: {
|
|
1805
|
-
key: "personalized",
|
|
1806
|
-
label: "Personalized",
|
|
1807
|
-
description: "Outreach message personalized for the contact (Instantly personalization workflow).",
|
|
1808
|
-
order: 9,
|
|
1809
|
-
entity: "contact"
|
|
1810
|
-
},
|
|
1811
|
-
uploaded: {
|
|
1812
|
-
key: "uploaded",
|
|
1813
|
-
label: "Reviewed and exported",
|
|
1814
|
-
description: "Approved records have been reviewed and exported for handoff.",
|
|
1815
|
-
order: 10,
|
|
1816
|
-
entity: "company",
|
|
1817
|
-
additionalEntities: ["contact"]
|
|
1818
|
-
},
|
|
1819
|
-
interested: {
|
|
1820
|
-
key: "interested",
|
|
1821
|
-
label: "Interested",
|
|
1822
|
-
description: "Contact replied with a positive signal (Instantly reply-handler transition).",
|
|
1823
|
-
order: 11,
|
|
1824
|
-
entity: "contact"
|
|
1825
|
-
}
|
|
1826
|
-
};
|
|
1827
|
-
var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
|
|
1828
|
-
var SalesStageSchema = DisplayMetadataSchema.extend({
|
|
1829
|
-
id: ModelIdSchema,
|
|
1830
|
-
order: z.number().int().min(0),
|
|
1831
|
-
semanticClass: SalesStageSemanticClassSchema,
|
|
1832
|
-
surfaceIds: ReferenceIdsSchema,
|
|
1833
|
-
resourceIds: ReferenceIdsSchema
|
|
1834
|
-
});
|
|
1835
|
-
z.object({
|
|
1836
|
-
id: ModelIdSchema,
|
|
1837
|
-
label: z.string().trim().min(1).max(120),
|
|
1838
|
-
description: DescriptionSchema.optional(),
|
|
1839
|
-
entityId: ModelIdSchema,
|
|
1840
|
-
stages: z.array(SalesStageSchema).min(1)
|
|
1841
|
-
});
|
|
1842
|
-
function findPipeline(definitions, pipelineKey) {
|
|
1843
|
-
return definitions.find((def) => def.pipelineKey === pipelineKey);
|
|
1844
|
-
}
|
|
1845
|
-
var CRM_DISCOVERY_REPLIED_STATE = {
|
|
1846
|
-
stateKey: "discovery_replied",
|
|
1847
|
-
label: "Discovery Replied"
|
|
1848
|
-
};
|
|
1849
|
-
var CRM_DISCOVERY_LINK_SENT_STATE = {
|
|
1850
|
-
stateKey: "discovery_link_sent",
|
|
1851
|
-
label: "Discovery Link Sent"
|
|
1852
|
-
};
|
|
1853
|
-
var CRM_DISCOVERY_NUDGING_STATE = {
|
|
1854
|
-
stateKey: "discovery_nudging",
|
|
1855
|
-
label: "Discovery Nudging"
|
|
1856
|
-
};
|
|
1857
|
-
var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
|
|
1858
|
-
stateKey: "discovery_booking_cancelled",
|
|
1859
|
-
label: "Discovery Booking Cancelled"
|
|
1860
|
-
};
|
|
1861
|
-
var CRM_REPLY_SENT_STATE = {
|
|
1862
|
-
stateKey: "reply_sent",
|
|
1863
|
-
label: "Reply Sent"
|
|
1864
|
-
};
|
|
1865
|
-
var CRM_FOLLOWUP_1_SENT_STATE = {
|
|
1866
|
-
stateKey: "followup_1_sent",
|
|
1867
|
-
label: "Follow-up 1 Sent"
|
|
1868
|
-
};
|
|
1869
|
-
var CRM_FOLLOWUP_2_SENT_STATE = {
|
|
1870
|
-
stateKey: "followup_2_sent",
|
|
1871
|
-
label: "Follow-up 2 Sent"
|
|
1872
|
-
};
|
|
1873
|
-
var CRM_FOLLOWUP_3_SENT_STATE = {
|
|
1874
|
-
stateKey: "followup_3_sent",
|
|
1875
|
-
label: "Follow-up 3 Sent"
|
|
1876
|
-
};
|
|
1877
|
-
var CRM_PIPELINE_DEFINITION = {
|
|
1878
|
-
pipelineKey: "crm",
|
|
1879
|
-
label: "CRM",
|
|
1880
|
-
entityKey: "crm.deal",
|
|
1881
|
-
stages: [
|
|
1882
|
-
{
|
|
1883
|
-
stageKey: "interested",
|
|
1884
|
-
label: "Interested",
|
|
1885
|
-
color: "blue",
|
|
1886
|
-
states: [
|
|
1887
|
-
CRM_DISCOVERY_REPLIED_STATE,
|
|
1888
|
-
CRM_DISCOVERY_LINK_SENT_STATE,
|
|
1889
|
-
CRM_DISCOVERY_NUDGING_STATE,
|
|
1890
|
-
CRM_DISCOVERY_BOOKING_CANCELLED_STATE,
|
|
1891
|
-
CRM_REPLY_SENT_STATE,
|
|
1892
|
-
CRM_FOLLOWUP_1_SENT_STATE,
|
|
1893
|
-
CRM_FOLLOWUP_2_SENT_STATE,
|
|
1894
|
-
CRM_FOLLOWUP_3_SENT_STATE
|
|
1895
|
-
]
|
|
1896
|
-
},
|
|
1897
|
-
{ stageKey: "proposal", label: "Proposal", color: "yellow", states: [] },
|
|
1898
|
-
{ stageKey: "closing", label: "Closing", color: "orange", states: [] },
|
|
1899
|
-
{ stageKey: "closed_won", label: "Closed Won", color: "green", states: [] },
|
|
1900
|
-
{ stageKey: "closed_lost", label: "Closed Lost", color: "red", states: [] },
|
|
1901
|
-
{ stageKey: "nurturing", label: "Nurturing", color: "grape", states: [] }
|
|
1902
|
-
]
|
|
1903
|
-
};
|
|
1904
|
-
var CRM_PRIORITY_BUCKETS = [
|
|
1905
|
-
{ bucketKey: "needs_response", label: "Needs Response", rank: 10, color: "red" },
|
|
1906
|
-
{ bucketKey: "follow_up_due", label: "Follow-up Due", rank: 20, color: "orange" },
|
|
1907
|
-
{ bucketKey: "waiting", label: "Waiting", rank: 30, color: "blue" },
|
|
1908
|
-
{ bucketKey: "stale", label: "Stale", rank: 40, color: "gray" },
|
|
1909
|
-
{ bucketKey: "closed_low", label: "Closed", rank: 50, color: "dark" }
|
|
1910
|
-
];
|
|
1911
|
-
var DEFAULT_CRM_PRIORITY_RULE_CONFIG = {
|
|
1912
|
-
buckets: CRM_PRIORITY_BUCKETS,
|
|
1913
|
-
closedStageKeys: ["closed_won", "closed_lost"],
|
|
1914
|
-
followUpAfterDaysByStateKey: {
|
|
1915
|
-
discovery_link_sent: 3,
|
|
1916
|
-
discovery_nudging: 2,
|
|
1917
|
-
reply_sent: 3,
|
|
1918
|
-
followup_1_sent: 3,
|
|
1919
|
-
followup_2_sent: 5,
|
|
1920
|
-
followup_3_sent: 7
|
|
1921
|
-
},
|
|
1922
|
-
staleAfterDays: 14
|
|
1923
|
-
};
|
|
1924
|
-
var PENDING_STATE = { stateKey: "pending", label: "Pending" };
|
|
1925
|
-
var ACQ_LIST_MEMBERS_LEAD_GEN_PIPELINE = {
|
|
1926
|
-
pipelineKey: "lead-gen",
|
|
1927
|
-
label: "Lead Generation",
|
|
1928
|
-
entityKey: "acq.list-member",
|
|
1929
|
-
stages: [
|
|
1930
|
-
{
|
|
1931
|
-
stageKey: "outreach",
|
|
1932
|
-
label: "Outreach",
|
|
1933
|
-
states: [
|
|
1934
|
-
PENDING_STATE,
|
|
1935
|
-
{ stateKey: "personalized", label: "Personalized" },
|
|
1936
|
-
{ stateKey: "uploaded", label: "Uploaded" },
|
|
1937
|
-
{ stateKey: "interested", label: "Interested" }
|
|
1938
|
-
]
|
|
1939
|
-
},
|
|
1940
|
-
{
|
|
1941
|
-
stageKey: "prospecting",
|
|
1942
|
-
label: "Prospecting",
|
|
1943
|
-
states: [
|
|
1944
|
-
PENDING_STATE,
|
|
1945
|
-
{ stateKey: "discovered", label: "Discovered" },
|
|
1946
|
-
{ stateKey: "verified", label: "Verified" }
|
|
1947
|
-
]
|
|
1948
|
-
},
|
|
1949
|
-
{
|
|
1950
|
-
stageKey: "qualification",
|
|
1951
|
-
label: "Qualification",
|
|
1952
|
-
states: [PENDING_STATE]
|
|
1953
|
-
}
|
|
1954
|
-
]
|
|
1955
|
-
};
|
|
1956
|
-
var ACQ_LIST_COMPANIES_LEAD_GEN_PIPELINE = {
|
|
1957
|
-
pipelineKey: "lead-gen",
|
|
1958
|
-
label: "Lead Generation",
|
|
1959
|
-
entityKey: "acq.list-company",
|
|
1960
|
-
stages: [
|
|
1961
|
-
{
|
|
1962
|
-
stageKey: "outreach",
|
|
1963
|
-
label: "Outreach",
|
|
1964
|
-
states: [PENDING_STATE, { stateKey: "uploaded", label: "Uploaded" }]
|
|
1965
|
-
},
|
|
1966
|
-
{
|
|
1967
|
-
stageKey: "prospecting",
|
|
1968
|
-
label: "Prospecting",
|
|
1969
|
-
states: [
|
|
1970
|
-
PENDING_STATE,
|
|
1971
|
-
{ stateKey: "populated", label: "Populated" },
|
|
1972
|
-
{ stateKey: "extracted", label: "Extracted" }
|
|
1973
|
-
]
|
|
1974
|
-
},
|
|
1975
|
-
{
|
|
1976
|
-
stageKey: "qualification",
|
|
1977
|
-
label: "Qualification",
|
|
1978
|
-
states: [PENDING_STATE, { stateKey: "qualified", label: "Qualified" }]
|
|
1979
|
-
}
|
|
1980
|
-
]
|
|
1981
|
-
};
|
|
1982
|
-
var LEAD_GEN_PIPELINE_DEFINITIONS = {
|
|
1983
|
-
"acq.list-member": [ACQ_LIST_MEMBERS_LEAD_GEN_PIPELINE],
|
|
1984
|
-
"acq.list-company": [ACQ_LIST_COMPANIES_LEAD_GEN_PIPELINE]
|
|
1985
|
-
};
|
|
1986
|
-
|
|
1987
|
-
// ../core/src/organization-model/contracts.ts
|
|
1988
|
-
var PROJECTS_VIEW_ACTION_ID = "delivery.projects.view";
|
|
1989
|
-
|
|
1990
|
-
// ../core/src/organization-model/content-kinds/registry.ts
|
|
1991
|
-
function defineContentType(def) {
|
|
1992
|
-
return def;
|
|
1993
|
-
}
|
|
1994
|
-
var PipelinePayloadSchema = z.object({
|
|
1995
|
-
/**
|
|
1996
|
-
* Local NodeId of the entity this pipeline applies to (e.g. 'crm.deal').
|
|
1997
|
-
* `.meta({ ref: 'entity' })` enables SchemaDrivenFieldList to render a
|
|
1998
|
-
* clickable graph link to the referenced entity node.
|
|
1999
|
-
*/
|
|
2000
|
-
entityId: z.string().trim().min(1).max(200).meta({ label: "Entity", ref: "entity", hint: "The entity type this pipeline tracks" }),
|
|
2001
|
-
/**
|
|
2002
|
-
* Optional Kanban column color token for UI rendering.
|
|
2003
|
-
*/
|
|
2004
|
-
kanbanColor: z.string().trim().min(1).max(40).optional().meta({ label: "Kanban color", hint: "UI color token" })
|
|
2005
|
-
});
|
|
2006
|
-
var pipelineKind = defineContentType({
|
|
2007
|
-
kind: "schema",
|
|
2008
|
-
type: "pipeline",
|
|
2009
|
-
label: "Pipeline",
|
|
2010
|
-
description: "A named progression pipeline that applies to a specific entity type.",
|
|
2011
|
-
payloadSchema: PipelinePayloadSchema,
|
|
2012
|
-
parentTypes: []
|
|
2013
|
-
});
|
|
2014
|
-
var StagePayloadSchema = z.object({
|
|
2015
|
-
/**
|
|
2016
|
-
* Semantic classification for this stage.
|
|
2017
|
-
* Drives color, icon, and CRM-priority logic in consuming views.
|
|
2018
|
-
* Optional — prospecting stages use data.entityKind instead.
|
|
2019
|
-
* Enum aligned with SalesStageSemanticClassSchema (sales.ts).
|
|
2020
|
-
*/
|
|
2021
|
-
semanticClass: z.enum(["open", "active", "nurturing", "closed_won", "closed_lost", "won", "lost", "closed"]).optional().meta({ label: "Semantic class", hint: "Semantic meaning of this stage", color: "blue" })
|
|
2022
|
-
});
|
|
2023
|
-
var stageKind = defineContentType({
|
|
2024
|
-
kind: "schema",
|
|
2025
|
-
type: "stage",
|
|
2026
|
-
label: "Stage",
|
|
2027
|
-
description: "A stage within a pipeline. Must be parented under a schema:pipeline content node.",
|
|
2028
|
-
payloadSchema: StagePayloadSchema,
|
|
2029
|
-
parentTypes: ["schema:pipeline"]
|
|
2030
|
-
});
|
|
2031
|
-
var TemplatePayloadSchema = z.object({
|
|
2032
|
-
/**
|
|
2033
|
-
* Optional description surfaced in the KB describe view and tooling.
|
|
2034
|
-
*/
|
|
2035
|
-
description: z.string().trim().min(1).max(2e3).optional().meta({ label: "Description", hint: "What this template is used for" })
|
|
2036
|
-
});
|
|
2037
|
-
var templateKind = defineContentType({
|
|
2038
|
-
kind: "schema",
|
|
2039
|
-
type: "template",
|
|
2040
|
-
label: "Template",
|
|
2041
|
-
description: "A named build template (e.g. a prospecting pipeline sequence).",
|
|
2042
|
-
payloadSchema: TemplatePayloadSchema,
|
|
2043
|
-
parentTypes: []
|
|
2044
|
-
});
|
|
2045
|
-
var TemplateStepPayloadSchema = z.object({
|
|
2046
|
-
/**
|
|
2047
|
-
* Which entity type this step primarily operates on.
|
|
2048
|
-
*/
|
|
2049
|
-
primaryEntity: z.enum(["company", "contact"]).meta({ label: "Primary entity", hint: "Entity type this step processes", color: "blue" }),
|
|
2050
|
-
/**
|
|
2051
|
-
* Action key identifying the workflow action executed by this step.
|
|
2052
|
-
* `.meta({ ref: 'action' })` enables SchemaDrivenFieldList to render a
|
|
2053
|
-
* clickable graph link.
|
|
2054
|
-
*/
|
|
2055
|
-
actionKey: z.string().trim().min(1).max(200).meta({ label: "Action", ref: "action", hint: "Workflow action executed by this step" }),
|
|
2056
|
-
/**
|
|
2057
|
-
* IDs of sibling step local NodeIds this step depends on.
|
|
2058
|
-
*/
|
|
2059
|
-
dependsOn: z.array(z.string().trim().min(1).max(200)).optional().meta({ label: "Depends on", hint: "Local NodeIds of prerequisite steps" })
|
|
2060
|
-
});
|
|
2061
|
-
var templateStepKind = defineContentType({
|
|
2062
|
-
kind: "schema",
|
|
2063
|
-
type: "template-step",
|
|
2064
|
-
label: "Template Step",
|
|
2065
|
-
description: "A step within a build template. Must be parented under a schema:template content node.",
|
|
2066
|
-
payloadSchema: TemplateStepPayloadSchema,
|
|
2067
|
-
parentTypes: ["schema:template"]
|
|
2068
|
-
});
|
|
2069
|
-
var StatusFlowPayloadSchema = z.object({
|
|
2070
|
-
/**
|
|
2071
|
-
* Which entity scope this status flow governs.
|
|
2072
|
-
*/
|
|
2073
|
-
appliesTo: z.enum(["project", "milestone", "task"]).meta({ label: "Applies to", hint: "Entity scope governed by this status flow", color: "blue" })
|
|
2074
|
-
});
|
|
2075
|
-
var statusFlowKind = defineContentType({
|
|
2076
|
-
kind: "schema",
|
|
2077
|
-
type: "status-flow",
|
|
2078
|
-
label: "Status Flow",
|
|
2079
|
-
description: "A named set of statuses governing a project, milestone, or task entity.",
|
|
2080
|
-
payloadSchema: StatusFlowPayloadSchema,
|
|
2081
|
-
parentTypes: []
|
|
2082
|
-
});
|
|
2083
|
-
var StatusPayloadSchema = z.object({
|
|
2084
|
-
/**
|
|
2085
|
-
* Semantic classification string for this status.
|
|
2086
|
-
* Free-form to allow tenant-defined classifications (e.g. 'active', 'blocked',
|
|
2087
|
-
* 'completed'). Used by UI to apply color and icon fallbacks.
|
|
2088
|
-
* Optional — status nodes may omit this when the label is self-descriptive.
|
|
2089
|
-
*/
|
|
2090
|
-
semanticClass: z.string().trim().min(1).max(100).optional().meta({ label: "Semantic class", hint: "Semantic meaning of this status (e.g. active, blocked, completed)" }),
|
|
2091
|
-
/**
|
|
2092
|
-
* Optional UI color token override for this status.
|
|
2093
|
-
*/
|
|
2094
|
-
color: z.string().trim().min(1).max(40).optional().meta({ label: "Color", hint: "UI color token" })
|
|
2095
|
-
});
|
|
2096
|
-
var statusKind = defineContentType({
|
|
2097
|
-
kind: "schema",
|
|
2098
|
-
type: "status",
|
|
2099
|
-
label: "Status",
|
|
2100
|
-
description: "A single status within a status flow. Must be parented under a schema:status-flow content node.",
|
|
2101
|
-
payloadSchema: StatusPayloadSchema,
|
|
2102
|
-
parentTypes: ["schema:status-flow"]
|
|
2103
|
-
});
|
|
2104
|
-
var ConfigKvPayloadSchema = z.object({
|
|
2105
|
-
/**
|
|
2106
|
-
* Flat key-value entries. Values are JSON primitives.
|
|
2107
|
-
* Keys are short identifiers (e.g. 'maxBatchSize', 'featureEnabled').
|
|
2108
|
-
*/
|
|
2109
|
-
entries: z.record(z.string().trim().min(1).max(200), z.union([z.string(), z.number(), z.boolean(), z.null()])).meta({ label: "Entries", hint: "Key-value configuration entries (string, number, boolean, or null values)" })
|
|
2110
|
-
});
|
|
2111
|
-
var configKvKind = defineContentType({
|
|
2112
|
-
kind: "config",
|
|
2113
|
-
type: "kv",
|
|
2114
|
-
label: "Key-Value Config",
|
|
2115
|
-
description: "A flat key-value configuration store co-located with a system. Values are JSON primitives.",
|
|
2116
|
-
payloadSchema: ConfigKvPayloadSchema,
|
|
2117
|
-
parentTypes: []
|
|
2118
|
-
});
|
|
2119
|
-
|
|
2120
|
-
// ../core/src/organization-model/content-kinds/index.ts
|
|
2121
|
-
var CONTENT_KIND_REGISTRY = {
|
|
2122
|
-
"schema:pipeline": pipelineKind,
|
|
2123
|
-
"schema:stage": stageKind,
|
|
2124
|
-
"schema:template": templateKind,
|
|
2125
|
-
"schema:template-step": templateStepKind,
|
|
2126
|
-
"schema:status-flow": statusFlowKind,
|
|
2127
|
-
"schema:status": statusKind,
|
|
2128
|
-
"config:kv": configKvKind
|
|
2129
|
-
};
|
|
2130
|
-
function lookupContentType(kind, type) {
|
|
2131
|
-
const key = `${kind}:${type}`;
|
|
2132
|
-
return CONTENT_KIND_REGISTRY[key];
|
|
2133
|
-
}
|
|
2134
|
-
var OrganizationModelBrandingSchema = z.object({
|
|
2135
|
-
organizationName: LabelSchema,
|
|
2136
|
-
productName: LabelSchema,
|
|
2137
|
-
shortName: z.string().trim().min(1).max(40),
|
|
2138
|
-
description: DescriptionSchema.optional(),
|
|
2139
|
-
logos: z.object({
|
|
2140
|
-
light: z.string().trim().min(1).max(2048).optional(),
|
|
2141
|
-
dark: z.string().trim().min(1).max(2048).optional()
|
|
2142
|
-
}).default({})
|
|
2143
|
-
});
|
|
2144
|
-
var DEFAULT_ORGANIZATION_MODEL_BRANDING = {
|
|
2145
|
-
organizationName: "Default Organization",
|
|
2146
|
-
productName: "Elevasis",
|
|
2147
|
-
shortName: "Elevasis",
|
|
2148
|
-
logos: {}
|
|
2149
|
-
};
|
|
2150
|
-
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]).meta({ label: "Surface type", color: "blue" });
|
|
2151
|
-
var SurfaceDefinitionSchema = z.object({
|
|
2152
|
-
id: ModelIdSchema,
|
|
2153
|
-
label: LabelSchema,
|
|
2154
|
-
path: PathSchema,
|
|
2155
|
-
surfaceType: SurfaceTypeSchema,
|
|
2156
|
-
description: DescriptionSchema.optional(),
|
|
2157
|
-
enabled: z.boolean().default(true),
|
|
2158
|
-
devOnly: z.boolean().optional(),
|
|
2159
|
-
icon: IconNameSchema.optional(),
|
|
2160
|
-
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
2161
|
-
entityIds: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]),
|
|
2162
|
-
resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
|
|
2163
|
-
actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
|
|
2164
|
-
parentId: ModelIdSchema.meta({ ref: "surface" }).optional()
|
|
2165
|
-
});
|
|
2166
|
-
var SidebarSurfaceTargetsSchema = z.object({
|
|
2167
|
-
systems: z.array(ModelIdSchema.meta({ ref: "system" })).default([]).optional(),
|
|
2168
|
-
entities: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]).optional(),
|
|
2169
|
-
resources: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]).optional(),
|
|
2170
|
-
actions: z.array(ModelIdSchema.meta({ ref: "action" })).default([]).optional()
|
|
2171
|
-
}).default({});
|
|
2172
|
-
var SidebarNodeSchema = z.lazy(
|
|
2173
|
-
() => z.discriminatedUnion("type", [
|
|
2174
|
-
z.object({
|
|
2175
|
-
type: z.literal("group"),
|
|
2176
|
-
label: LabelSchema,
|
|
2177
|
-
description: DescriptionSchema.optional(),
|
|
2178
|
-
icon: IconNameSchema.optional(),
|
|
2179
|
-
order: z.number().int().optional(),
|
|
2180
|
-
children: z.record(z.string(), SidebarNodeSchema).default({})
|
|
2181
|
-
}),
|
|
2182
|
-
z.object({
|
|
2183
|
-
type: z.literal("surface"),
|
|
2184
|
-
label: LabelSchema,
|
|
2185
|
-
path: PathSchema,
|
|
2186
|
-
surfaceType: SurfaceTypeSchema,
|
|
2187
|
-
description: DescriptionSchema.optional(),
|
|
2188
|
-
icon: IconNameSchema.optional(),
|
|
2189
|
-
order: z.number().int().optional(),
|
|
2190
|
-
targets: SidebarSurfaceTargetsSchema.optional(),
|
|
2191
|
-
devOnly: z.boolean().optional(),
|
|
2192
|
-
requiresAdmin: z.boolean().optional()
|
|
2193
|
-
})
|
|
2194
|
-
])
|
|
2195
|
-
);
|
|
2196
|
-
var SidebarSectionSchema = z.record(z.string(), SidebarNodeSchema).default({});
|
|
2197
|
-
var SidebarNavigationSchema = z.object({
|
|
2198
|
-
primary: SidebarSectionSchema,
|
|
2199
|
-
bottom: SidebarSectionSchema
|
|
2200
|
-
}).default({ primary: {}, bottom: {} });
|
|
2201
|
-
var OrganizationModelNavigationSchema = z.object({
|
|
2202
|
-
sidebar: SidebarNavigationSchema
|
|
2203
|
-
}).default({ sidebar: { primary: {}, bottom: {} } });
|
|
2204
|
-
function getSortedSidebarEntries(nodes) {
|
|
2205
|
-
return Object.entries(nodes).sort(([leftId, left], [rightId, right]) => {
|
|
2206
|
-
const orderDelta = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
|
|
2207
|
-
return orderDelta === 0 ? leftId.localeCompare(rightId) : orderDelta;
|
|
2208
|
-
});
|
|
2209
|
-
}
|
|
2210
|
-
z.object({
|
|
2211
|
-
id: ModelIdSchema,
|
|
2212
|
-
label: LabelSchema,
|
|
2213
|
-
placement: z.string().trim().min(1).max(50),
|
|
2214
|
-
surfaceIds: z.array(ModelIdSchema.meta({ ref: "surface" })).default([])
|
|
2215
|
-
});
|
|
2216
|
-
var FirmographicsSchema = z.object({
|
|
2217
|
-
/** Industry vertical (e.g. "Marketing Agency", "Legal", "Real Estate"). */
|
|
2218
|
-
industry: z.string().trim().max(200).optional(),
|
|
2219
|
-
/**
|
|
2220
|
-
* Company headcount band (e.g. "1–10", "11–50", "51–200", "200+").
|
|
2221
|
-
* Free-form string to accommodate any band notation.
|
|
2222
|
-
*/
|
|
2223
|
-
companySize: z.string().trim().max(100).optional(),
|
|
2224
|
-
/**
|
|
2225
|
-
* Primary geographic region the segment operates in or is targeted from
|
|
2226
|
-
* (e.g. "North America", "Europe", "Global").
|
|
2227
|
-
*/
|
|
2228
|
-
region: z.string().trim().max(200).optional()
|
|
1444
|
+
var FirmographicsSchema = z.object({
|
|
1445
|
+
/** Industry vertical (e.g. "Marketing Agency", "Legal", "Real Estate"). */
|
|
1446
|
+
industry: z.string().trim().max(200).optional(),
|
|
1447
|
+
/**
|
|
1448
|
+
* Company headcount band (e.g. "1–10", "11–50", "51–200", "200+").
|
|
1449
|
+
* Free-form string to accommodate any band notation.
|
|
1450
|
+
*/
|
|
1451
|
+
companySize: z.string().trim().max(100).optional(),
|
|
1452
|
+
/**
|
|
1453
|
+
* Primary geographic region the segment operates in or is targeted from
|
|
1454
|
+
* (e.g. "North America", "Europe", "Global").
|
|
1455
|
+
*/
|
|
1456
|
+
region: z.string().trim().max(200).optional()
|
|
2229
1457
|
});
|
|
2230
1458
|
var CustomerSegmentSchema = z.object({
|
|
2231
1459
|
/** Stable unique identifier for the segment (e.g. "segment-smb-agencies"). */
|
|
@@ -2415,13 +1643,10 @@ var KnowledgeTargetKindSchema = z.enum([
|
|
|
2415
1643
|
"goal",
|
|
2416
1644
|
"customer-segment",
|
|
2417
1645
|
"offering",
|
|
2418
|
-
"ontology"
|
|
2419
|
-
// D4: content nodes are a valid knowledge target after compound-domain data moved into system.content
|
|
2420
|
-
"content-node"
|
|
1646
|
+
"ontology"
|
|
2421
1647
|
]).meta({ label: "Target kind" });
|
|
2422
1648
|
var KnowledgeTargetRefSchema = z.object({
|
|
2423
1649
|
kind: KnowledgeTargetKindSchema,
|
|
2424
|
-
// D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'.
|
|
2425
1650
|
// Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
|
|
2426
1651
|
// Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
|
|
2427
1652
|
id: z.string().trim().min(1).max(300)
|
|
@@ -2438,6 +1663,15 @@ var KnowledgeTargetRefSchema = z.object({
|
|
|
2438
1663
|
});
|
|
2439
1664
|
var LegacyKnowledgeLinkSchema = z.object({
|
|
2440
1665
|
nodeId: z.union([NodeIdStringSchema, z.templateLiteral(["ontology:", OntologyIdSchema])])
|
|
1666
|
+
}).superRefine((link, ctx) => {
|
|
1667
|
+
const [kind] = link.nodeId.split(":");
|
|
1668
|
+
if (!KnowledgeTargetKindSchema.safeParse(kind).success) {
|
|
1669
|
+
ctx.addIssue({
|
|
1670
|
+
code: z.ZodIssueCode.custom,
|
|
1671
|
+
path: ["nodeId"],
|
|
1672
|
+
message: `Unknown knowledge target kind "${kind}"`
|
|
1673
|
+
});
|
|
1674
|
+
}
|
|
2441
1675
|
});
|
|
2442
1676
|
var CanonicalKnowledgeLinkSchema = z.object({
|
|
2443
1677
|
target: KnowledgeTargetRefSchema
|
|
@@ -2550,6 +1784,90 @@ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
|
|
|
2550
1784
|
version: 1,
|
|
2551
1785
|
relationships: {}
|
|
2552
1786
|
};
|
|
1787
|
+
function idFrom(input) {
|
|
1788
|
+
return typeof input === "string" ? input : input.id;
|
|
1789
|
+
}
|
|
1790
|
+
function parseRef(kind, id) {
|
|
1791
|
+
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1792
|
+
}
|
|
1793
|
+
function isNodeRef(input) {
|
|
1794
|
+
return OmTopologyNodeRefSchema.safeParse(input).success;
|
|
1795
|
+
}
|
|
1796
|
+
function isResourceEntry(input) {
|
|
1797
|
+
if (typeof input !== "object" || input === null) return false;
|
|
1798
|
+
const candidate = input;
|
|
1799
|
+
return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
|
|
1800
|
+
}
|
|
1801
|
+
var topologyRef = {
|
|
1802
|
+
system: (system) => parseRef("system", idFrom(system)),
|
|
1803
|
+
resource: (resource) => parseRef("resource", idFrom(resource)),
|
|
1804
|
+
ontology: (record) => parseRef("ontology", idFrom(record)),
|
|
1805
|
+
policy: (policy) => parseRef("policy", idFrom(policy)),
|
|
1806
|
+
role: (role) => parseRef("role", idFrom(role)),
|
|
1807
|
+
trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
|
|
1808
|
+
humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
|
|
1809
|
+
externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
|
|
1810
|
+
};
|
|
1811
|
+
var topologyRelationship = {
|
|
1812
|
+
triggers: (from, to, options = {}) => defineTopologyRelationship({
|
|
1813
|
+
...options,
|
|
1814
|
+
from,
|
|
1815
|
+
kind: "triggers",
|
|
1816
|
+
to
|
|
1817
|
+
}),
|
|
1818
|
+
uses: (from, to, options = {}) => defineTopologyRelationship({
|
|
1819
|
+
...options,
|
|
1820
|
+
from,
|
|
1821
|
+
kind: "uses",
|
|
1822
|
+
to
|
|
1823
|
+
}),
|
|
1824
|
+
approval: (from, to, options = {}) => defineTopologyRelationship({
|
|
1825
|
+
...options,
|
|
1826
|
+
from,
|
|
1827
|
+
kind: "approval",
|
|
1828
|
+
to
|
|
1829
|
+
}),
|
|
1830
|
+
usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
|
|
1831
|
+
required: true,
|
|
1832
|
+
...options,
|
|
1833
|
+
from,
|
|
1834
|
+
kind: "uses",
|
|
1835
|
+
to: integration
|
|
1836
|
+
}),
|
|
1837
|
+
requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
|
|
1838
|
+
required: true,
|
|
1839
|
+
...options,
|
|
1840
|
+
from,
|
|
1841
|
+
kind: "approval",
|
|
1842
|
+
to: topologyRef.humanCheckpoint(checkpoint)
|
|
1843
|
+
}),
|
|
1844
|
+
checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
|
|
1845
|
+
required: true,
|
|
1846
|
+
...options,
|
|
1847
|
+
from: topologyRef.humanCheckpoint(checkpoint),
|
|
1848
|
+
kind: "triggers",
|
|
1849
|
+
to
|
|
1850
|
+
})
|
|
1851
|
+
};
|
|
1852
|
+
function compileTopologyNodeRef(input) {
|
|
1853
|
+
if (isNodeRef(input)) return input;
|
|
1854
|
+
if (isResourceEntry(input)) return topologyRef.resource(input);
|
|
1855
|
+
throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
|
|
1856
|
+
}
|
|
1857
|
+
function defineTopologyRelationship(input) {
|
|
1858
|
+
return OmTopologyRelationshipSchema.parse({
|
|
1859
|
+
...input,
|
|
1860
|
+
from: compileTopologyNodeRef(input.from),
|
|
1861
|
+
to: compileTopologyNodeRef(input.to)
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
function defineTopology(relationships) {
|
|
1865
|
+
const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
|
|
1866
|
+
return OmTopologyDomainSchema.parse({
|
|
1867
|
+
version: 1,
|
|
1868
|
+
relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
2553
1871
|
var PolicyIdSchema = ModelIdSchema;
|
|
2554
1872
|
var PolicyApplicabilitySchema = z.object({
|
|
2555
1873
|
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
@@ -2741,7 +2059,10 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2741
2059
|
const childSystems = system.systems ?? system.subsystems;
|
|
2742
2060
|
if (childSystems !== void 0) {
|
|
2743
2061
|
result.push(
|
|
2744
|
-
...collectAllSystems(childSystems, path, [
|
|
2062
|
+
...collectAllSystems(childSystems, path, [
|
|
2063
|
+
...currentSchemaPath,
|
|
2064
|
+
system.systems !== void 0 ? "systems" : "subsystems"
|
|
2065
|
+
])
|
|
2745
2066
|
);
|
|
2746
2067
|
}
|
|
2747
2068
|
}
|
|
@@ -2762,7 +2083,9 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2762
2083
|
`System "${system.id}" references unknown parent "${system.parentSystemId}"`
|
|
2763
2084
|
);
|
|
2764
2085
|
}
|
|
2765
|
-
const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some(
|
|
2086
|
+
const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some(
|
|
2087
|
+
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".")
|
|
2088
|
+
);
|
|
2766
2089
|
const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
|
|
2767
2090
|
if (contributesRoutePath) {
|
|
2768
2091
|
const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path);
|
|
@@ -2784,11 +2107,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2784
2107
|
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
|
|
2785
2108
|
);
|
|
2786
2109
|
if (!hasEnabledDescendant) {
|
|
2787
|
-
addIssue(
|
|
2788
|
-
ctx,
|
|
2789
|
-
[...schemaPath, "lifecycle"],
|
|
2790
|
-
`System "${path}" is active but has no active descendants`
|
|
2791
|
-
);
|
|
2110
|
+
addIssue(ctx, [...schemaPath, "lifecycle"], `System "${path}" is active but has no active descendants`);
|
|
2792
2111
|
}
|
|
2793
2112
|
}
|
|
2794
2113
|
});
|
|
@@ -3020,10 +2339,16 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
3020
2339
|
}
|
|
3021
2340
|
});
|
|
3022
2341
|
});
|
|
3023
|
-
const stageIds = /* @__PURE__ */ new Set();
|
|
3024
2342
|
const actionIds = new Set(Object.keys(model.actions));
|
|
3025
2343
|
const offeringsById = new Map(Object.entries(model.offerings));
|
|
3026
2344
|
const ontologyCompilation = compileOrganizationOntology(model);
|
|
2345
|
+
const stageIds = /* @__PURE__ */ new Set();
|
|
2346
|
+
for (const catalog of Object.values(ontologyCompilation.ontology.catalogTypes)) {
|
|
2347
|
+
if (catalog.kind !== "stage") continue;
|
|
2348
|
+
for (const stageId of Object.keys(catalog.entries ?? {})) {
|
|
2349
|
+
stageIds.add(stageId);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
3027
2352
|
const ontologyIndexByKind = {
|
|
3028
2353
|
object: ontologyCompilation.ontology.objectTypes,
|
|
3029
2354
|
link: ontologyCompilation.ontology.linkTypes,
|
|
@@ -3199,13 +2524,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
3199
2524
|
if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
|
|
3200
2525
|
addIssue(
|
|
3201
2526
|
ctx,
|
|
3202
|
-
[
|
|
3203
|
-
"resources",
|
|
3204
|
-
resourceId,
|
|
3205
|
-
"ontology",
|
|
3206
|
-
bindingKey,
|
|
3207
|
-
...Array.isArray(ids) ? [ontologyIndex] : []
|
|
3208
|
-
],
|
|
2527
|
+
["resources", resourceId, "ontology", bindingKey, ...Array.isArray(ids) ? [ontologyIndex] : []],
|
|
3209
2528
|
`Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
|
|
3210
2529
|
);
|
|
3211
2530
|
}
|
|
@@ -3220,6 +2539,23 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
3220
2539
|
validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
|
|
3221
2540
|
validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
|
|
3222
2541
|
validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
|
|
2542
|
+
if (binding.contract !== void 0) {
|
|
2543
|
+
const contractEntries = [
|
|
2544
|
+
["input", binding.contract.input],
|
|
2545
|
+
["output", binding.contract.output]
|
|
2546
|
+
];
|
|
2547
|
+
for (const [side, ref] of contractEntries) {
|
|
2548
|
+
if (ref === void 0) continue;
|
|
2549
|
+
const result = ContractRefSchema.safeParse(ref);
|
|
2550
|
+
if (!result.success) {
|
|
2551
|
+
addIssue(
|
|
2552
|
+
ctx,
|
|
2553
|
+
["resources", resource.id, "ontology", "contract", side],
|
|
2554
|
+
`Resource "${resource.id}" contract.${side} "${ref}" is not a valid ContractRef (expected "package/subpath#ExportName")`
|
|
2555
|
+
);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
3223
2559
|
});
|
|
3224
2560
|
Object.values(model.roles).forEach((role) => {
|
|
3225
2561
|
if (role.heldBy === void 0) return;
|
|
@@ -3254,78 +2590,6 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
3254
2590
|
}
|
|
3255
2591
|
});
|
|
3256
2592
|
});
|
|
3257
|
-
function validateSystemContent(system, systemPath) {
|
|
3258
|
-
const childSystems = system.systems ?? system.subsystems;
|
|
3259
|
-
const childKey = system.systems !== void 0 ? "systems" : "subsystems";
|
|
3260
|
-
const content = system.content;
|
|
3261
|
-
if (content === void 0 || Object.keys(content).length === 0) {
|
|
3262
|
-
if (childSystems !== void 0) {
|
|
3263
|
-
Object.entries(childSystems).forEach(([childLocalId, child]) => {
|
|
3264
|
-
validateSystemContent(child, [...systemPath, childKey, childLocalId]);
|
|
3265
|
-
});
|
|
3266
|
-
}
|
|
3267
|
-
return;
|
|
3268
|
-
}
|
|
3269
|
-
Object.entries(content).forEach(([localId, node]) => {
|
|
3270
|
-
if (node.parentContentId !== void 0 && !(node.parentContentId in content)) {
|
|
3271
|
-
addIssue(
|
|
3272
|
-
ctx,
|
|
3273
|
-
[...systemPath, "content", localId, "parentContentId"],
|
|
3274
|
-
`Content node "${localId}" parentContentId "${node.parentContentId}" does not resolve within the same system`
|
|
3275
|
-
);
|
|
3276
|
-
}
|
|
3277
|
-
});
|
|
3278
|
-
Object.entries(content).forEach(([localId, node]) => {
|
|
3279
|
-
const visited = /* @__PURE__ */ new Set();
|
|
3280
|
-
let currentId = node.parentContentId;
|
|
3281
|
-
while (currentId !== void 0) {
|
|
3282
|
-
if (currentId === localId || visited.has(currentId)) {
|
|
3283
|
-
addIssue(
|
|
3284
|
-
ctx,
|
|
3285
|
-
[...systemPath, "content", localId, "parentContentId"],
|
|
3286
|
-
`Content node "${localId}" has a parentContentId cycle`
|
|
3287
|
-
);
|
|
3288
|
-
break;
|
|
3289
|
-
}
|
|
3290
|
-
visited.add(currentId);
|
|
3291
|
-
currentId = content[currentId]?.parentContentId;
|
|
3292
|
-
}
|
|
3293
|
-
});
|
|
3294
|
-
Object.entries(content).forEach(([localId, node]) => {
|
|
3295
|
-
const childDef = lookupContentType(node.kind, node.type);
|
|
3296
|
-
if (childDef !== void 0 && node.data !== void 0) {
|
|
3297
|
-
const result = childDef.payloadSchema.safeParse(node.data);
|
|
3298
|
-
if (!result.success) {
|
|
3299
|
-
addIssue(
|
|
3300
|
-
ctx,
|
|
3301
|
-
[...systemPath, "content", localId, "data"],
|
|
3302
|
-
`Content node "${localId}" (${node.kind}:${node.type}) data failed payload validation: ${result.error.message}`
|
|
3303
|
-
);
|
|
3304
|
-
}
|
|
3305
|
-
}
|
|
3306
|
-
if (node.parentContentId !== void 0 && childDef !== void 0) {
|
|
3307
|
-
const parentNode = content[node.parentContentId];
|
|
3308
|
-
if (parentNode !== void 0) {
|
|
3309
|
-
const parentDef = lookupContentType(parentNode.kind, parentNode.type);
|
|
3310
|
-
if (parentDef !== void 0 && childDef.kind !== parentDef.kind) {
|
|
3311
|
-
addIssue(
|
|
3312
|
-
ctx,
|
|
3313
|
-
[...systemPath, "content", localId, "parentContentId"],
|
|
3314
|
-
`Content node "${localId}" kind "${childDef.kind}" cannot parent under "${node.parentContentId}" kind "${parentDef.kind}": parentContentId must be same-meta-kind (per L19)`
|
|
3315
|
-
);
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
}
|
|
3319
|
-
});
|
|
3320
|
-
if (childSystems !== void 0) {
|
|
3321
|
-
Object.entries(childSystems).forEach(([childLocalId, child]) => {
|
|
3322
|
-
validateSystemContent(child, [...systemPath, childKey, childLocalId]);
|
|
3323
|
-
});
|
|
3324
|
-
}
|
|
3325
|
-
}
|
|
3326
|
-
Object.entries(model.systems).forEach(([systemKey, system]) => {
|
|
3327
|
-
validateSystemContent(system, ["systems", systemKey]);
|
|
3328
|
-
});
|
|
3329
2593
|
for (const diagnostic of ontologyCompilation.diagnostics) {
|
|
3330
2594
|
addIssue(ctx, diagnostic.path, diagnostic.message);
|
|
3331
2595
|
}
|
|
@@ -3348,9 +2612,8 @@ var OrganizationGraphNodeKindSchema = z.enum([
|
|
|
3348
2612
|
"goal",
|
|
3349
2613
|
"surface",
|
|
3350
2614
|
"navigation-group",
|
|
3351
|
-
//
|
|
3352
|
-
"ontology"
|
|
3353
|
-
"content-node"
|
|
2615
|
+
// Ontology records are projected from compiled System.ontology scopes.
|
|
2616
|
+
"ontology"
|
|
3354
2617
|
]);
|
|
3355
2618
|
var OrganizationGraphEdgeKindSchema = z.enum([
|
|
3356
2619
|
"contains",
|
|
@@ -3379,133 +2642,27 @@ var OrganizationGraphNodeSchema = z.object({
|
|
|
3379
2642
|
description: DescriptionSchema.optional(),
|
|
3380
2643
|
icon: IconNameSchema.optional(),
|
|
3381
2644
|
enabled: z.boolean().optional(),
|
|
3382
|
-
ontologyKind: z.string().trim().min(1).max(80).optional(),
|
|
3383
|
-
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint", "script"]).optional()
|
|
3384
|
-
});
|
|
3385
|
-
var OrganizationGraphEdgeSchema = z.object({
|
|
3386
|
-
id: z.string().trim().min(1).max(900),
|
|
3387
|
-
kind: OrganizationGraphEdgeKindSchema,
|
|
3388
|
-
sourceId: z.string().trim().min(1).max(400),
|
|
3389
|
-
targetId: z.string().trim().min(1).max(400),
|
|
3390
|
-
label: z.string().trim().min(1).max(120).optional(),
|
|
3391
|
-
relationshipType: z.enum(["triggers", "uses", "approval"]).optional()
|
|
3392
|
-
});
|
|
3393
|
-
var OrganizationGraphSchema = z.object({
|
|
3394
|
-
version: z.literal(1),
|
|
3395
|
-
organizationModelVersion: OrganizationModelSchema.shape.version,
|
|
3396
|
-
nodes: z.array(OrganizationGraphNodeSchema),
|
|
3397
|
-
edges: z.array(OrganizationGraphEdgeSchema)
|
|
3398
|
-
});
|
|
3399
|
-
var BuildOrganizationGraphInputSchema = z.object({
|
|
3400
|
-
organizationModel: OrganizationModelSchema,
|
|
3401
|
-
commandViewData: z.unknown().optional()
|
|
3402
|
-
});
|
|
3403
|
-
|
|
3404
|
-
// ../core/src/organization-model/migration-helpers.ts
|
|
3405
|
-
function getAllPipelines(model) {
|
|
3406
|
-
const results = [];
|
|
3407
|
-
for (const { path: systemPath, system } of listAllSystems(model)) {
|
|
3408
|
-
const content = system.content ?? {};
|
|
3409
|
-
for (const [localId, node] of Object.entries(content)) {
|
|
3410
|
-
if (node.kind !== "schema" || node.type !== "pipeline") continue;
|
|
3411
|
-
const data = node.data ?? {};
|
|
3412
|
-
const stages = Object.entries(content).filter(([, s]) => s.kind === "schema" && s.type === "stage" && s.parentContentId === localId).map(([stageLocalId, s]) => {
|
|
3413
|
-
const sd = s.data ?? {};
|
|
3414
|
-
return {
|
|
3415
|
-
id: stageLocalId,
|
|
3416
|
-
label: s.label ?? stageLocalId,
|
|
3417
|
-
order: typeof sd.order === "number" ? sd.order : 0,
|
|
3418
|
-
semanticClass: sd.semanticClass ?? "open",
|
|
3419
|
-
surfaceIds: Array.isArray(sd.surfaceIds) ? sd.surfaceIds : [],
|
|
3420
|
-
resourceIds: Array.isArray(sd.resourceIds) ? sd.resourceIds : [],
|
|
3421
|
-
color: typeof sd.color === "string" ? sd.color : void 0
|
|
3422
|
-
};
|
|
3423
|
-
}).sort((a, b) => a.order - b.order);
|
|
3424
|
-
const pipeline = {
|
|
3425
|
-
id: localId,
|
|
3426
|
-
label: node.label ?? localId,
|
|
3427
|
-
entityId: typeof data.entityId === "string" ? data.entityId : "",
|
|
3428
|
-
stages,
|
|
3429
|
-
...typeof node.description === "string" ? { description: node.description } : {}
|
|
3430
|
-
};
|
|
3431
|
-
results.push({ systemPath, pipeline });
|
|
3432
|
-
}
|
|
3433
|
-
}
|
|
3434
|
-
return results;
|
|
3435
|
-
}
|
|
3436
|
-
function getAllBuildTemplates(model) {
|
|
3437
|
-
const results = [];
|
|
3438
|
-
for (const { system } of listAllSystems(model)) {
|
|
3439
|
-
const content = system.content ?? {};
|
|
3440
|
-
for (const [localId, node] of Object.entries(content)) {
|
|
3441
|
-
if (node.kind !== "schema" || node.type !== "template") continue;
|
|
3442
|
-
const nd = node.data ?? {};
|
|
3443
|
-
const steps = Object.entries(content).filter(([, s]) => s.kind === "schema" && s.type === "template-step" && s.parentContentId === localId).map(([stepLocalId, s]) => {
|
|
3444
|
-
const sd = s.data ?? {};
|
|
3445
|
-
return {
|
|
3446
|
-
id: stepLocalId,
|
|
3447
|
-
label: s.label ?? stepLocalId,
|
|
3448
|
-
...s.description ? { description: s.description } : {},
|
|
3449
|
-
// Pass through all data fields — template-step payload is richer than Pipeline;
|
|
3450
|
-
// Bridge readers preserve the historical shape for round-trip fidelity.
|
|
3451
|
-
...sd
|
|
3452
|
-
};
|
|
3453
|
-
});
|
|
3454
|
-
results.push({
|
|
3455
|
-
id: localId,
|
|
3456
|
-
label: node.label ?? localId,
|
|
3457
|
-
...node.description ? { description: node.description } : {},
|
|
3458
|
-
...typeof nd.color === "string" ? { color: nd.color } : {},
|
|
3459
|
-
// BuildTemplate requires steps array — cast via spread; Wave 4 adds type-safe assertions.
|
|
3460
|
-
steps
|
|
3461
|
-
});
|
|
3462
|
-
}
|
|
3463
|
-
}
|
|
3464
|
-
return results;
|
|
3465
|
-
}
|
|
3466
|
-
function getAllProspectingStages(model, kind) {
|
|
3467
|
-
const results = [];
|
|
3468
|
-
for (const { system } of listAllSystems(model)) {
|
|
3469
|
-
const content = system.content ?? {};
|
|
3470
|
-
for (const [localId, node] of Object.entries(content)) {
|
|
3471
|
-
if (node.kind !== "schema" || node.type !== "stage") continue;
|
|
3472
|
-
const sd = node.data ?? {};
|
|
3473
|
-
if (sd.entityKind !== kind) continue;
|
|
3474
|
-
results.push({
|
|
3475
|
-
id: localId,
|
|
3476
|
-
label: node.label ?? localId,
|
|
3477
|
-
order: typeof sd.order === "number" ? sd.order : 0,
|
|
3478
|
-
...typeof sd.color === "string" ? { color: sd.color } : {},
|
|
3479
|
-
...node.description ? { description: node.description } : {}
|
|
3480
|
-
});
|
|
3481
|
-
}
|
|
3482
|
-
}
|
|
3483
|
-
return results.sort((a, b) => a.order - b.order);
|
|
3484
|
-
}
|
|
3485
|
-
function getAllProjectStatuses(model, appliesTo) {
|
|
3486
|
-
const results = [];
|
|
3487
|
-
for (const { system } of listAllSystems(model)) {
|
|
3488
|
-
const content = system.content ?? {};
|
|
3489
|
-
for (const [flowLocalId, flowNode] of Object.entries(content)) {
|
|
3490
|
-
if (flowNode.kind !== "schema" || flowNode.type !== "status-flow") continue;
|
|
3491
|
-
const fd = flowNode.data ?? {};
|
|
3492
|
-
if (fd.appliesTo !== appliesTo) continue;
|
|
3493
|
-
for (const [statusLocalId, statusNode] of Object.entries(content)) {
|
|
3494
|
-
if (statusNode.kind !== "schema" || statusNode.type !== "status") continue;
|
|
3495
|
-
if (statusNode.parentContentId !== flowLocalId) continue;
|
|
3496
|
-
const sd = statusNode.data ?? {};
|
|
3497
|
-
results.push({
|
|
3498
|
-
id: statusLocalId,
|
|
3499
|
-
label: statusNode.label ?? statusLocalId,
|
|
3500
|
-
order: typeof sd.order === "number" ? sd.order : 0,
|
|
3501
|
-
...typeof sd.color === "string" ? { color: sd.color } : {},
|
|
3502
|
-
...statusNode.description ? { description: statusNode.description } : {}
|
|
3503
|
-
});
|
|
3504
|
-
}
|
|
3505
|
-
}
|
|
3506
|
-
}
|
|
3507
|
-
return results.sort((a, b) => a.order - b.order);
|
|
3508
|
-
}
|
|
2645
|
+
ontologyKind: z.string().trim().min(1).max(80).optional(),
|
|
2646
|
+
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint", "script"]).optional()
|
|
2647
|
+
});
|
|
2648
|
+
var OrganizationGraphEdgeSchema = z.object({
|
|
2649
|
+
id: z.string().trim().min(1).max(900),
|
|
2650
|
+
kind: OrganizationGraphEdgeKindSchema,
|
|
2651
|
+
sourceId: z.string().trim().min(1).max(400),
|
|
2652
|
+
targetId: z.string().trim().min(1).max(400),
|
|
2653
|
+
label: z.string().trim().min(1).max(120).optional(),
|
|
2654
|
+
relationshipType: z.enum(["triggers", "uses", "approval"]).optional()
|
|
2655
|
+
});
|
|
2656
|
+
var OrganizationGraphSchema = z.object({
|
|
2657
|
+
version: z.literal(1),
|
|
2658
|
+
organizationModelVersion: OrganizationModelSchema.shape.version,
|
|
2659
|
+
nodes: z.array(OrganizationGraphNodeSchema),
|
|
2660
|
+
edges: z.array(OrganizationGraphEdgeSchema)
|
|
2661
|
+
});
|
|
2662
|
+
var BuildOrganizationGraphInputSchema = z.object({
|
|
2663
|
+
organizationModel: OrganizationModelSchema,
|
|
2664
|
+
commandViewData: z.unknown().optional()
|
|
2665
|
+
});
|
|
3509
2666
|
|
|
3510
2667
|
// ../core/src/organization-model/graph/build.ts
|
|
3511
2668
|
function nodeId(kind, sourceId) {
|
|
@@ -3979,7 +3136,7 @@ function buildOrganizationGraph(input) {
|
|
|
3979
3136
|
}
|
|
3980
3137
|
if (entity.stateCatalogId === "lead-gen.company" || entity.stateCatalogId === "lead-gen.contact") {
|
|
3981
3138
|
const leadGenEntity = entity.stateCatalogId === "lead-gen.company" ? "company" : "contact";
|
|
3982
|
-
for (const stage of Object.values(
|
|
3139
|
+
for (const stage of Object.values(getLeadGenStageCatalog(organizationModel)).sort(
|
|
3983
3140
|
(a, b) => a.order - b.order || a.key.localeCompare(b.key)
|
|
3984
3141
|
)) {
|
|
3985
3142
|
if (stage.entity !== leadGenEntity && !(stage.additionalEntities ?? []).includes(leadGenEntity)) continue;
|
|
@@ -4283,49 +3440,6 @@ function buildOrganizationGraph(input) {
|
|
|
4283
3440
|
targetId: id
|
|
4284
3441
|
});
|
|
4285
3442
|
}
|
|
4286
|
-
for (const { path, system } of listAllSystems(organizationModel).sort((a, b) => a.path.localeCompare(b.path))) {
|
|
4287
|
-
const contentMap = system.content ?? {};
|
|
4288
|
-
const systemSpineId = nodeId("system", path);
|
|
4289
|
-
for (const [localId, contentNode] of Object.entries(contentMap).sort(([a], [b]) => a.localeCompare(b))) {
|
|
4290
|
-
const contentNodeGraphId = `content-node:${path}:${localId}`;
|
|
4291
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
4292
|
-
id: contentNodeGraphId,
|
|
4293
|
-
kind: "content-node",
|
|
4294
|
-
label: contentNode.label,
|
|
4295
|
-
sourceId: `${path}:${localId}`,
|
|
4296
|
-
description: contentNode.description
|
|
4297
|
-
// Spread contentKind and contentType into attributes; the node schema
|
|
4298
|
-
// does not have custom attribute slots, so we encode them in the label
|
|
4299
|
-
// suffix for now. The actual kind/type are recoverable from sourceId +
|
|
4300
|
-
// the registry lookup by consumers.
|
|
4301
|
-
});
|
|
4302
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
4303
|
-
id: edgeId("contains", systemSpineId, contentNodeGraphId, "system-content"),
|
|
4304
|
-
kind: "contains",
|
|
4305
|
-
sourceId: systemSpineId,
|
|
4306
|
-
targetId: contentNodeGraphId
|
|
4307
|
-
});
|
|
4308
|
-
if (contentNode.parentContentId) {
|
|
4309
|
-
const parentContentNodeGraphId = `content-node:${path}:${contentNode.parentContentId}`;
|
|
4310
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
4311
|
-
id: edgeId("contains", parentContentNodeGraphId, contentNodeGraphId, "content-parent"),
|
|
4312
|
-
kind: "contains",
|
|
4313
|
-
sourceId: parentContentNodeGraphId,
|
|
4314
|
-
targetId: contentNodeGraphId
|
|
4315
|
-
});
|
|
4316
|
-
}
|
|
4317
|
-
if (contentNode.kind === "schema" && contentNode.type === "pipeline" && contentNode.data && typeof contentNode.data["entityId"] === "string") {
|
|
4318
|
-
const targetEntityId = nodeId("entity", contentNode.data["entityId"]);
|
|
4319
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
4320
|
-
id: edgeId("references", contentNodeGraphId, targetEntityId, "pipeline-entity"),
|
|
4321
|
-
kind: "references",
|
|
4322
|
-
sourceId: contentNodeGraphId,
|
|
4323
|
-
targetId: targetEntityId,
|
|
4324
|
-
label: "applies to entity"
|
|
4325
|
-
});
|
|
4326
|
-
}
|
|
4327
|
-
}
|
|
4328
|
-
}
|
|
4329
3443
|
for (const template of getAllBuildTemplates(organizationModel).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
4330
3444
|
const steps = template.steps;
|
|
4331
3445
|
const stepById = new Map(steps.map((s) => [s.id, s]));
|
|
@@ -4411,863 +3525,567 @@ function buildOrganizationGraph(input) {
|
|
|
4411
3525
|
|
|
4412
3526
|
// ../core/src/organization-model/defaults.ts
|
|
4413
3527
|
var DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE = {};
|
|
4414
|
-
var DEFAULT_ORGANIZATION_MODEL_ENTITIES2 =
|
|
3528
|
+
var DEFAULT_ORGANIZATION_MODEL_ENTITIES2 = {};
|
|
4415
3529
|
var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
4416
3530
|
sidebar: {
|
|
4417
|
-
primary: {
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
}
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
3531
|
+
primary: {},
|
|
3532
|
+
bottom: {}
|
|
3533
|
+
}
|
|
3534
|
+
};
|
|
3535
|
+
var DEFAULT_ORGANIZATION_MODEL = {
|
|
3536
|
+
version: 1,
|
|
3537
|
+
domainMetadata: DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA,
|
|
3538
|
+
branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
|
|
3539
|
+
navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
|
|
3540
|
+
identity: DEFAULT_ORGANIZATION_MODEL_IDENTITY,
|
|
3541
|
+
customers: DEFAULT_ORGANIZATION_MODEL_CUSTOMERS,
|
|
3542
|
+
offerings: DEFAULT_ORGANIZATION_MODEL_OFFERINGS,
|
|
3543
|
+
roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
|
|
3544
|
+
goals: DEFAULT_ORGANIZATION_MODEL_GOALS,
|
|
3545
|
+
// Generic empty systems map. Elevasis-specific systems (platform, sales, sales.crm,
|
|
3546
|
+
// sales.lead-gen, monitoring, settings, admin, etc.) have been relocated to
|
|
3547
|
+
// `@repo/elevasis-core/src/organization-model/systems.ts` via `canonicalOrganizationModel`.
|
|
3548
|
+
// Tenant OM configs supply their own systems via `resolveOrganizationModel`.
|
|
3549
|
+
systems: {},
|
|
3550
|
+
ontology: DEFAULT_ONTOLOGY_SCOPE,
|
|
3551
|
+
resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
|
|
3552
|
+
topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
|
|
3553
|
+
// Generic empty actions map. Elevasis-specific action entries have been relocated to
|
|
3554
|
+
// `@repo/elevasis-core/src/organization-model/actions.ts`.
|
|
3555
|
+
actions: {},
|
|
3556
|
+
entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
|
|
3557
|
+
policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
|
|
3558
|
+
knowledge: DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE
|
|
3559
|
+
};
|
|
3560
|
+
|
|
3561
|
+
// ../core/src/organization-model/resolve.ts
|
|
3562
|
+
function isPlainObject(value) {
|
|
3563
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3564
|
+
}
|
|
3565
|
+
function collectNestedSystemPaths(systems, prefix = "") {
|
|
3566
|
+
const paths = /* @__PURE__ */ new Set();
|
|
3567
|
+
for (const [key, value] of Object.entries(systems)) {
|
|
3568
|
+
if (!isPlainObject(value)) continue;
|
|
3569
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
3570
|
+
for (const childKey of ["systems", "subsystems"]) {
|
|
3571
|
+
const childSystems = value[childKey];
|
|
3572
|
+
if (!isPlainObject(childSystems)) continue;
|
|
3573
|
+
for (const childPath of collectNestedSystemPaths(childSystems, path)) {
|
|
3574
|
+
paths.add(childPath);
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
if (prefix !== "") {
|
|
3578
|
+
paths.add(path);
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
return paths;
|
|
3582
|
+
}
|
|
3583
|
+
function pruneFlatSystemDescendantCollisions(base, override) {
|
|
3584
|
+
const result = { ...base };
|
|
3585
|
+
for (const nestedPath of collectNestedSystemPaths(override)) {
|
|
3586
|
+
delete result[nestedPath];
|
|
3587
|
+
}
|
|
3588
|
+
return result;
|
|
3589
|
+
}
|
|
3590
|
+
function deepMerge(base, override) {
|
|
3591
|
+
if (override === void 0) {
|
|
3592
|
+
return base;
|
|
3593
|
+
}
|
|
3594
|
+
if (Array.isArray(base)) {
|
|
3595
|
+
return override ?? base;
|
|
3596
|
+
}
|
|
3597
|
+
if (!isPlainObject(base) || !isPlainObject(override)) {
|
|
3598
|
+
return override ?? base;
|
|
3599
|
+
}
|
|
3600
|
+
const result = { ...base };
|
|
3601
|
+
for (const [key, value] of Object.entries(override)) {
|
|
3602
|
+
if (value === void 0) continue;
|
|
3603
|
+
const existing = result[key];
|
|
3604
|
+
if (key === "systems" && isPlainObject(existing) && isPlainObject(value)) {
|
|
3605
|
+
result[key] = deepMerge(pruneFlatSystemDescendantCollisions(existing, value), value);
|
|
3606
|
+
continue;
|
|
3607
|
+
}
|
|
3608
|
+
result[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
|
|
3609
|
+
}
|
|
3610
|
+
return result;
|
|
3611
|
+
}
|
|
3612
|
+
function resolveOrganizationModel(override, organizationIdOrOptions, options) {
|
|
3613
|
+
const resolvedOptions = typeof organizationIdOrOptions === "object" ? organizationIdOrOptions : options;
|
|
3614
|
+
const mergeDefaults = resolvedOptions?.mergeDefaults ?? true;
|
|
3615
|
+
const merged = mergeDefaults ? deepMerge(DEFAULT_ORGANIZATION_MODEL, override) : override ?? {};
|
|
3616
|
+
return OrganizationModelSchema.parse(merged);
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
// ../core/src/organization-model/surface-projection.ts
|
|
3620
|
+
function collectSystemsById(model) {
|
|
3621
|
+
const systemsById = /* @__PURE__ */ new Map();
|
|
3622
|
+
for (const { path, system } of listAllSystems(model)) {
|
|
3623
|
+
systemsById.set(path, system);
|
|
3624
|
+
systemsById.set(system.id, system);
|
|
3625
|
+
}
|
|
3626
|
+
return systemsById;
|
|
3627
|
+
}
|
|
3628
|
+
function getSystemWithAncestors(systemsById, systemId) {
|
|
3629
|
+
const systems = [];
|
|
3630
|
+
let current = systemsById.get(systemId);
|
|
3631
|
+
while (current !== void 0) {
|
|
3632
|
+
systems.unshift(current);
|
|
3633
|
+
current = current.parentSystemId ? systemsById.get(current.parentSystemId) : void 0;
|
|
3634
|
+
}
|
|
3635
|
+
return systems;
|
|
3636
|
+
}
|
|
3637
|
+
function hasInheritedFlag(systemsById, systemIds, flag) {
|
|
3638
|
+
return systemIds.some(
|
|
3639
|
+
(systemId) => getSystemWithAncestors(systemsById, systemId).some((system) => system[flag] === true)
|
|
3640
|
+
);
|
|
3641
|
+
}
|
|
3642
|
+
function isLifecycleEnabled2(system) {
|
|
3643
|
+
if (system.enabled === false) return false;
|
|
3644
|
+
return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
|
|
3645
|
+
}
|
|
3646
|
+
function isLifecycleDevOnly(system) {
|
|
3647
|
+
return system.devOnly === true || system.lifecycle === "beta";
|
|
3648
|
+
}
|
|
3649
|
+
function isSystemEnabled(systemsById, systemId) {
|
|
3650
|
+
const systemLineage = getSystemWithAncestors(systemsById, systemId);
|
|
3651
|
+
return systemLineage.length > 0 && systemLineage.every(isLifecycleEnabled2);
|
|
3652
|
+
}
|
|
3653
|
+
function unique(values) {
|
|
3654
|
+
return [...new Set(values)];
|
|
3655
|
+
}
|
|
3656
|
+
function collectSidebarSurfaces(nodes, schemaPath, surfaces = []) {
|
|
3657
|
+
getSortedSidebarEntries(nodes).forEach(([id, node]) => {
|
|
3658
|
+
const nodePath = [...schemaPath, id];
|
|
3659
|
+
if (node.type === "group") {
|
|
3660
|
+
collectSidebarSurfaces(node.children, [...nodePath, "children"], surfaces);
|
|
3661
|
+
return;
|
|
3662
|
+
}
|
|
3663
|
+
surfaces.push({ id, surface: node, path: nodePath });
|
|
3664
|
+
});
|
|
3665
|
+
return surfaces;
|
|
3666
|
+
}
|
|
3667
|
+
function getSidebarSurfaces(model) {
|
|
3668
|
+
return [
|
|
3669
|
+
...collectSidebarSurfaces(model.navigation.sidebar.primary, ["navigation", "sidebar", "primary"]),
|
|
3670
|
+
...collectSidebarSurfaces(model.navigation.sidebar.bottom, ["navigation", "sidebar", "bottom"])
|
|
3671
|
+
];
|
|
3672
|
+
}
|
|
3673
|
+
function projectOrganizationSurfaces(model) {
|
|
3674
|
+
const systemsById = collectSystemsById(model);
|
|
3675
|
+
return getSidebarSurfaces(model).map(({ id, surface }) => {
|
|
3676
|
+
const targets = surface.targets ?? {};
|
|
3677
|
+
const systemIds = unique((targets.systems ?? []).filter((systemId) => systemsById.has(systemId)));
|
|
3678
|
+
const enabled = systemIds.every((candidate) => isSystemEnabled(systemsById, candidate));
|
|
3679
|
+
const devOnly = surface.devOnly === true || hasInheritedFlag(systemsById, systemIds, "devOnly") || systemIds.some((candidate) => getSystemWithAncestors(systemsById, candidate).some(isLifecycleDevOnly));
|
|
3680
|
+
const requiresAdmin = hasInheritedFlag(systemsById, systemIds, "requiresAdmin");
|
|
3681
|
+
return {
|
|
3682
|
+
id,
|
|
3683
|
+
label: surface.label,
|
|
3684
|
+
path: surface.path,
|
|
3685
|
+
surfaceType: surface.surfaceType,
|
|
3686
|
+
...surface.description !== void 0 ? { description: surface.description } : {},
|
|
3687
|
+
...surface.icon !== void 0 ? { icon: surface.icon } : {},
|
|
3688
|
+
...surface.order !== void 0 ? { order: surface.order } : {},
|
|
3689
|
+
systemIds,
|
|
3690
|
+
entityIds: [...targets.entities ?? []],
|
|
3691
|
+
resourceIds: [...targets.resources ?? []],
|
|
3692
|
+
actionIds: [...targets.actions ?? []],
|
|
3693
|
+
enabled,
|
|
3694
|
+
...devOnly ? { devOnly } : {},
|
|
3695
|
+
...surface.requiresAdmin === true || requiresAdmin ? { requiresAdmin: true } : {}
|
|
3696
|
+
};
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3699
|
+
var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
|
|
3700
|
+
var SalesStageSchema = DisplayMetadataSchema.extend({
|
|
3701
|
+
id: ModelIdSchema,
|
|
3702
|
+
order: z.number().int().min(0),
|
|
3703
|
+
semanticClass: SalesStageSemanticClassSchema,
|
|
3704
|
+
surfaceIds: ReferenceIdsSchema,
|
|
3705
|
+
resourceIds: ReferenceIdsSchema
|
|
3706
|
+
});
|
|
3707
|
+
z.object({
|
|
3708
|
+
id: ModelIdSchema,
|
|
3709
|
+
label: z.string().trim().min(1).max(120),
|
|
3710
|
+
description: DescriptionSchema.optional(),
|
|
3711
|
+
entityId: ModelIdSchema,
|
|
3712
|
+
stages: z.array(SalesStageSchema).min(1)
|
|
3713
|
+
});
|
|
3714
|
+
function findPipeline(definitions, pipelineKey) {
|
|
3715
|
+
return definitions.find((def) => def.pipelineKey === pipelineKey);
|
|
3716
|
+
}
|
|
3717
|
+
var CRM_DISCOVERY_REPLIED_STATE = {
|
|
3718
|
+
stateKey: "discovery_replied",
|
|
3719
|
+
label: "Discovery Replied"
|
|
3720
|
+
};
|
|
3721
|
+
var CRM_DISCOVERY_LINK_SENT_STATE = {
|
|
3722
|
+
stateKey: "discovery_link_sent",
|
|
3723
|
+
label: "Discovery Link Sent"
|
|
3724
|
+
};
|
|
3725
|
+
var CRM_DISCOVERY_NUDGING_STATE = {
|
|
3726
|
+
stateKey: "discovery_nudging",
|
|
3727
|
+
label: "Discovery Nudging"
|
|
3728
|
+
};
|
|
3729
|
+
var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
|
|
3730
|
+
stateKey: "discovery_booking_cancelled",
|
|
3731
|
+
label: "Discovery Booking Cancelled"
|
|
3732
|
+
};
|
|
3733
|
+
DisplayMetadataSchema.extend({
|
|
3734
|
+
id: ModelIdSchema,
|
|
3735
|
+
order: z.number().min(0)
|
|
3736
|
+
});
|
|
3737
|
+
var RecordColumnConfigSchema = z.object({
|
|
3738
|
+
key: ModelIdSchema,
|
|
3739
|
+
label: z.string().trim().min(1).max(120),
|
|
3740
|
+
path: z.string().trim().min(1).max(500),
|
|
3741
|
+
width: z.union([z.number().positive(), z.string().trim().min(1).max(100)]).optional(),
|
|
3742
|
+
renderType: z.enum(["text", "badge", "datetime", "count", "json"]).optional(),
|
|
3743
|
+
badgeColor: z.string().trim().min(1).max(40).optional()
|
|
3744
|
+
});
|
|
3745
|
+
var RecordColumnsConfigSchema = z.object({
|
|
3746
|
+
company: z.array(RecordColumnConfigSchema).optional(),
|
|
3747
|
+
contact: z.array(RecordColumnConfigSchema).optional()
|
|
3748
|
+
}).refine((columns) => Boolean(columns.company?.length || columns.contact?.length), {
|
|
3749
|
+
message: "recordColumns must include at least one entity column set"
|
|
3750
|
+
});
|
|
3751
|
+
var CredentialRequirementSchema = z.object({
|
|
3752
|
+
key: ModelIdSchema,
|
|
3753
|
+
provider: ModelIdSchema,
|
|
3754
|
+
credentialType: z.enum(["api-key", "api-key-secret", "oauth", "webhook-secret"]),
|
|
3755
|
+
label: z.string().trim().min(1).max(120),
|
|
3756
|
+
required: z.boolean(),
|
|
3757
|
+
selectionMode: z.enum(["single", "multiple"]).optional(),
|
|
3758
|
+
inputPath: z.string().trim().min(1).max(500),
|
|
3759
|
+
verifyOnRun: z.boolean().optional()
|
|
3760
|
+
});
|
|
3761
|
+
var ProspectingBuildTemplateStepSchema = DisplayMetadataSchema.extend({
|
|
3762
|
+
id: ModelIdSchema,
|
|
3763
|
+
primaryEntity: z.enum(["company", "contact"]),
|
|
3764
|
+
outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
|
|
3765
|
+
stageKey: ModelIdSchema,
|
|
3766
|
+
recordEntity: z.enum(["company", "contact"]).optional(),
|
|
3767
|
+
recordsStageKey: ModelIdSchema.optional(),
|
|
3768
|
+
recordSourceStageKey: ModelIdSchema.optional(),
|
|
3769
|
+
dependsOn: z.array(ModelIdSchema).optional(),
|
|
3770
|
+
dependencyMode: z.literal("per-record-eligibility"),
|
|
3771
|
+
actionKey: ModelIdSchema,
|
|
3772
|
+
defaultBatchSize: z.number().int().positive(),
|
|
3773
|
+
maxBatchSize: z.number().int().positive(),
|
|
3774
|
+
recordColumns: RecordColumnsConfigSchema.optional(),
|
|
3775
|
+
credentialRequirements: z.array(CredentialRequirementSchema).optional()
|
|
3776
|
+
}).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
|
|
3777
|
+
message: "defaultBatchSize must be less than or equal to maxBatchSize",
|
|
3778
|
+
path: ["defaultBatchSize"]
|
|
3779
|
+
});
|
|
3780
|
+
DisplayMetadataSchema.extend({
|
|
3781
|
+
id: ModelIdSchema,
|
|
3782
|
+
steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
|
|
3783
|
+
});
|
|
3784
|
+
var DTC_RECORD_COLUMNS = {
|
|
3785
|
+
populated: {
|
|
3786
|
+
company: [
|
|
3787
|
+
{ key: "name", label: "Company", path: "company.name" },
|
|
3788
|
+
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
3789
|
+
{ key: "employee-count", label: "Employees", path: "company.numEmployees", renderType: "count" },
|
|
3790
|
+
{ key: "apollo-industry", label: "Apollo industry", path: "company.category" },
|
|
3791
|
+
{ key: "location", label: "Location", path: "company.locationState" }
|
|
3792
|
+
]
|
|
3793
|
+
},
|
|
3794
|
+
crawled: {
|
|
3795
|
+
company: [
|
|
3796
|
+
{ key: "name", label: "Company", path: "company.name" },
|
|
3797
|
+
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
3798
|
+
{ key: "page-count", label: "Pages", path: "company.enrichmentData.websiteCrawl.pageCount", renderType: "count" },
|
|
3799
|
+
{ key: "crawl-status", label: "Crawl status", path: "processingState.crawled.status", renderType: "badge" }
|
|
3800
|
+
]
|
|
3801
|
+
},
|
|
3802
|
+
extracted: {
|
|
3803
|
+
company: [
|
|
3804
|
+
{ key: "name", label: "Company", path: "company.name" },
|
|
3805
|
+
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
3806
|
+
{ key: "description", label: "Description", path: "company.enrichmentData.websiteCrawl.companyDescription" },
|
|
3807
|
+
{ key: "services", label: "Services", path: "company.enrichmentData.websiteCrawl.services", renderType: "json" },
|
|
3808
|
+
{
|
|
3809
|
+
key: "automation-gaps",
|
|
3810
|
+
label: "Automation gaps",
|
|
3811
|
+
path: "company.enrichmentData.websiteCrawl.automationGaps",
|
|
3812
|
+
renderType: "json"
|
|
4573
3813
|
},
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
label: "
|
|
4577
|
-
path: "
|
|
4578
|
-
|
|
4579
|
-
icon: "knowledge",
|
|
4580
|
-
order: 50
|
|
3814
|
+
{
|
|
3815
|
+
key: "contact-count",
|
|
3816
|
+
label: "Contacts",
|
|
3817
|
+
path: "company.enrichmentData.websiteCrawl.emailCount",
|
|
3818
|
+
renderType: "count"
|
|
4581
3819
|
}
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
targets: { systems: ["settings.organization"] }
|
|
4621
|
-
},
|
|
4622
|
-
"settings-credentials": {
|
|
4623
|
-
type: "surface",
|
|
4624
|
-
label: "Credentials",
|
|
4625
|
-
path: "/settings/credentials",
|
|
4626
|
-
surfaceType: "settings",
|
|
4627
|
-
order: 50,
|
|
4628
|
-
targets: { systems: ["settings.credentials"] }
|
|
4629
|
-
},
|
|
4630
|
-
"settings-api-keys": {
|
|
4631
|
-
type: "surface",
|
|
4632
|
-
label: "API Keys",
|
|
4633
|
-
path: "/settings/api-keys",
|
|
4634
|
-
surfaceType: "settings",
|
|
4635
|
-
order: 60,
|
|
4636
|
-
targets: { systems: ["settings.api-keys"] }
|
|
4637
|
-
},
|
|
4638
|
-
"settings-webhooks": {
|
|
4639
|
-
type: "surface",
|
|
4640
|
-
label: "Webhooks",
|
|
4641
|
-
path: "/settings/webhooks",
|
|
4642
|
-
surfaceType: "settings",
|
|
4643
|
-
order: 70,
|
|
4644
|
-
targets: { systems: ["settings.webhooks"] }
|
|
4645
|
-
},
|
|
4646
|
-
"settings-deployments": {
|
|
4647
|
-
type: "surface",
|
|
4648
|
-
label: "Deployments",
|
|
4649
|
-
path: "/settings/deployments",
|
|
4650
|
-
surfaceType: "settings",
|
|
4651
|
-
order: 80,
|
|
4652
|
-
targets: { systems: ["settings.deployments"] }
|
|
4653
|
-
}
|
|
4654
|
-
}
|
|
3820
|
+
]
|
|
3821
|
+
},
|
|
3822
|
+
qualified: {
|
|
3823
|
+
company: [
|
|
3824
|
+
{ key: "name", label: "Company", path: "company.name" },
|
|
3825
|
+
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
3826
|
+
{ key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
|
|
3827
|
+
{ key: "signals", label: "Signals", path: "company.qualificationSignals", renderType: "json" },
|
|
3828
|
+
{
|
|
3829
|
+
key: "disqualified-reason",
|
|
3830
|
+
label: "Disqualified reason",
|
|
3831
|
+
path: "processingState.qualified.data.disqualifiedReason"
|
|
3832
|
+
}
|
|
3833
|
+
]
|
|
3834
|
+
},
|
|
3835
|
+
decisionMakers: {
|
|
3836
|
+
contact: [
|
|
3837
|
+
{ key: "name", label: "Name", path: "contact.name" },
|
|
3838
|
+
{ key: "title", label: "Title", path: "contact.title" },
|
|
3839
|
+
{ key: "email", label: "Email", path: "contact.email" },
|
|
3840
|
+
{ key: "linkedin", label: "LinkedIn", path: "contact.linkedinUrl" },
|
|
3841
|
+
{
|
|
3842
|
+
key: "priority-score",
|
|
3843
|
+
label: "Priority",
|
|
3844
|
+
path: "contact.enrichmentData.apollo.priorityScore",
|
|
3845
|
+
renderType: "badge"
|
|
3846
|
+
}
|
|
3847
|
+
]
|
|
3848
|
+
},
|
|
3849
|
+
uploaded: {
|
|
3850
|
+
company: [
|
|
3851
|
+
{ key: "name", label: "Company", path: "company.name" },
|
|
3852
|
+
{ key: "domain", label: "Domain", path: "company.domain" },
|
|
3853
|
+
{
|
|
3854
|
+
key: "contacts",
|
|
3855
|
+
label: "Contacts",
|
|
3856
|
+
path: "company.enrichmentData.approvedLeadListExport.contacts",
|
|
3857
|
+
renderType: "json"
|
|
4655
3858
|
},
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
"admin-dashboard": {
|
|
4663
|
-
type: "surface",
|
|
4664
|
-
label: "Dashboard",
|
|
4665
|
-
path: "/admin/dashboard",
|
|
4666
|
-
surfaceType: "dashboard",
|
|
4667
|
-
order: 10,
|
|
4668
|
-
targets: { systems: ["admin"] },
|
|
4669
|
-
requiresAdmin: true
|
|
4670
|
-
},
|
|
4671
|
-
"admin-system-health": {
|
|
4672
|
-
type: "surface",
|
|
4673
|
-
label: "System Health",
|
|
4674
|
-
path: "/admin/system-health",
|
|
4675
|
-
surfaceType: "dashboard",
|
|
4676
|
-
order: 20,
|
|
4677
|
-
targets: { systems: ["admin.system-health"] },
|
|
4678
|
-
requiresAdmin: true
|
|
4679
|
-
},
|
|
4680
|
-
"admin-organizations": {
|
|
4681
|
-
type: "surface",
|
|
4682
|
-
label: "Organizations",
|
|
4683
|
-
path: "/admin/organizations",
|
|
4684
|
-
surfaceType: "list",
|
|
4685
|
-
order: 30,
|
|
4686
|
-
targets: { systems: ["admin.organizations"] },
|
|
4687
|
-
requiresAdmin: true
|
|
4688
|
-
},
|
|
4689
|
-
"admin-users": {
|
|
4690
|
-
type: "surface",
|
|
4691
|
-
label: "Users",
|
|
4692
|
-
path: "/admin/users",
|
|
4693
|
-
surfaceType: "list",
|
|
4694
|
-
order: 40,
|
|
4695
|
-
targets: { systems: ["admin.users"] },
|
|
4696
|
-
requiresAdmin: true
|
|
4697
|
-
},
|
|
4698
|
-
"admin-design-showcase": {
|
|
4699
|
-
type: "surface",
|
|
4700
|
-
label: "Design Showcase",
|
|
4701
|
-
path: "/admin/design-showcase",
|
|
4702
|
-
surfaceType: "page",
|
|
4703
|
-
order: 50,
|
|
4704
|
-
targets: { systems: ["admin.design-showcase"] },
|
|
4705
|
-
requiresAdmin: true
|
|
4706
|
-
},
|
|
4707
|
-
"admin-debug": {
|
|
4708
|
-
type: "surface",
|
|
4709
|
-
label: "Debug",
|
|
4710
|
-
path: "/admin/debug",
|
|
4711
|
-
surfaceType: "page",
|
|
4712
|
-
order: 60,
|
|
4713
|
-
targets: { systems: ["admin.debug"] },
|
|
4714
|
-
requiresAdmin: true
|
|
4715
|
-
}
|
|
4716
|
-
}
|
|
3859
|
+
{ key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
|
|
3860
|
+
{
|
|
3861
|
+
key: "approval",
|
|
3862
|
+
label: "Approval",
|
|
3863
|
+
path: "company.enrichmentData.approvedLeadListExport.approvalStatus",
|
|
3864
|
+
renderType: "badge"
|
|
4717
3865
|
}
|
|
4718
|
-
|
|
3866
|
+
]
|
|
4719
3867
|
}
|
|
4720
3868
|
};
|
|
4721
|
-
var
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
id: "dashboard",
|
|
4734
|
-
order: 10,
|
|
4735
|
-
label: "Dashboard",
|
|
4736
|
-
enabled: true,
|
|
4737
|
-
lifecycle: "active",
|
|
4738
|
-
path: "/",
|
|
4739
|
-
icon: "dashboard"
|
|
4740
|
-
},
|
|
4741
|
-
platform: {
|
|
4742
|
-
id: "platform",
|
|
4743
|
-
order: 30,
|
|
4744
|
-
label: "Platform",
|
|
4745
|
-
description: "Elevasis platform architecture, capabilities, and implementation patterns",
|
|
4746
|
-
enabled: true,
|
|
4747
|
-
lifecycle: "active",
|
|
4748
|
-
color: "cyan",
|
|
4749
|
-
icon: "platform"
|
|
4750
|
-
},
|
|
4751
|
-
finance: {
|
|
4752
|
-
id: "finance",
|
|
4753
|
-
order: 40,
|
|
4754
|
-
label: "Finance",
|
|
4755
|
-
description: "Finance operations, accounting, billing, reconciliation, and tax prep",
|
|
4756
|
-
enabled: true,
|
|
4757
|
-
lifecycle: "active",
|
|
4758
|
-
color: "green",
|
|
4759
|
-
icon: "finance"
|
|
4760
|
-
},
|
|
4761
|
-
sales: {
|
|
4762
|
-
id: "sales",
|
|
4763
|
-
order: 60,
|
|
4764
|
-
label: "Sales",
|
|
4765
|
-
description: "Revenue workflows and customer acquisition",
|
|
4766
|
-
enabled: true,
|
|
4767
|
-
lifecycle: "active",
|
|
4768
|
-
color: "blue",
|
|
4769
|
-
icon: "sales",
|
|
4770
|
-
path: "/sales"
|
|
4771
|
-
},
|
|
4772
|
-
"sales.crm": {
|
|
4773
|
-
id: "sales.crm",
|
|
4774
|
-
order: 70,
|
|
4775
|
-
label: "CRM",
|
|
4776
|
-
description: "Relationship pipeline and deal management",
|
|
4777
|
-
enabled: true,
|
|
4778
|
-
lifecycle: "active",
|
|
4779
|
-
actions: Object.values(CRM_ACTION_ENTRIES).map((action) => ({
|
|
4780
|
-
actionId: action.id,
|
|
4781
|
-
intent: "exposes"
|
|
4782
|
-
})),
|
|
4783
|
-
color: "blue",
|
|
4784
|
-
icon: "crm",
|
|
4785
|
-
path: "/crm"
|
|
4786
|
-
},
|
|
4787
|
-
"sales.lead-gen": {
|
|
4788
|
-
id: "sales.lead-gen",
|
|
4789
|
-
order: 80,
|
|
4790
|
-
label: "Lead Gen",
|
|
4791
|
-
description: "Prospecting, qualification, and outreach preparation",
|
|
4792
|
-
enabled: true,
|
|
4793
|
-
lifecycle: "active",
|
|
4794
|
-
actions: Object.values(LEAD_GEN_ACTION_ENTRIES).map((action) => ({
|
|
4795
|
-
actionId: action.id,
|
|
4796
|
-
intent: "exposes"
|
|
4797
|
-
})),
|
|
4798
|
-
color: "cyan",
|
|
4799
|
-
icon: "lead-gen",
|
|
4800
|
-
path: "/lead-gen"
|
|
4801
|
-
},
|
|
4802
|
-
projects: {
|
|
4803
|
-
id: "projects",
|
|
4804
|
-
order: 90,
|
|
4805
|
-
label: "Projects",
|
|
4806
|
-
description: "Projects, milestones, and client work execution",
|
|
4807
|
-
enabled: true,
|
|
4808
|
-
lifecycle: "active",
|
|
4809
|
-
color: "orange",
|
|
4810
|
-
icon: "projects",
|
|
4811
|
-
path: "/projects"
|
|
4812
|
-
},
|
|
4813
|
-
clients: {
|
|
4814
|
-
id: "clients",
|
|
4815
|
-
order: 100,
|
|
4816
|
-
label: "Clients",
|
|
4817
|
-
description: "Client relationships, accounts, and business context",
|
|
4818
|
-
enabled: true,
|
|
4819
|
-
lifecycle: "active",
|
|
4820
|
-
color: "orange",
|
|
4821
|
-
icon: "projects",
|
|
4822
|
-
path: "/clients"
|
|
4823
|
-
},
|
|
4824
|
-
operations: {
|
|
4825
|
-
id: "operations",
|
|
4826
|
-
order: 110,
|
|
4827
|
-
label: "Operations",
|
|
4828
|
-
description: "Operational resources, topology, and orchestration visibility",
|
|
4829
|
-
enabled: true,
|
|
4830
|
-
lifecycle: "active",
|
|
4831
|
-
color: "violet",
|
|
4832
|
-
icon: "operations"
|
|
4833
|
-
},
|
|
4834
|
-
"knowledge.command-view": {
|
|
4835
|
-
id: "knowledge.command-view",
|
|
4836
|
-
order: 120,
|
|
4837
|
-
label: "Command View",
|
|
4838
|
-
enabled: true,
|
|
4839
|
-
lifecycle: "active",
|
|
4840
|
-
path: "/knowledge/command-view",
|
|
4841
|
-
devOnly: true
|
|
4842
|
-
},
|
|
4843
|
-
"operations.overview": {
|
|
4844
|
-
id: "operations.overview",
|
|
4845
|
-
order: 130,
|
|
4846
|
-
label: "Overview",
|
|
4847
|
-
enabled: true,
|
|
4848
|
-
lifecycle: "active",
|
|
4849
|
-
path: "/operations"
|
|
4850
|
-
},
|
|
4851
|
-
"operations.resources": {
|
|
4852
|
-
id: "operations.resources",
|
|
4853
|
-
order: 140,
|
|
4854
|
-
label: "Resources",
|
|
4855
|
-
enabled: true,
|
|
4856
|
-
lifecycle: "active",
|
|
4857
|
-
path: "/operations/resources"
|
|
4858
|
-
},
|
|
4859
|
-
"operations.command-queue": {
|
|
4860
|
-
id: "operations.command-queue",
|
|
4861
|
-
order: 150,
|
|
4862
|
-
label: "Command Queue",
|
|
4863
|
-
enabled: true,
|
|
4864
|
-
lifecycle: "active",
|
|
4865
|
-
path: "/operations/command-queue"
|
|
4866
|
-
},
|
|
4867
|
-
"operations.sessions": {
|
|
4868
|
-
id: "operations.sessions",
|
|
4869
|
-
order: 160,
|
|
4870
|
-
label: "Sessions",
|
|
4871
|
-
enabled: false,
|
|
4872
|
-
lifecycle: "deprecated",
|
|
4873
|
-
path: "/operations/sessions"
|
|
4874
|
-
},
|
|
4875
|
-
"operations.task-scheduler": {
|
|
4876
|
-
id: "operations.task-scheduler",
|
|
4877
|
-
order: 170,
|
|
4878
|
-
label: "Task Scheduler",
|
|
4879
|
-
enabled: true,
|
|
4880
|
-
lifecycle: "active",
|
|
4881
|
-
path: "/operations/task-scheduler"
|
|
4882
|
-
},
|
|
4883
|
-
monitoring: {
|
|
4884
|
-
id: "monitoring",
|
|
4885
|
-
order: 180,
|
|
4886
|
-
label: "Monitoring",
|
|
4887
|
-
enabled: true,
|
|
4888
|
-
lifecycle: "active"
|
|
4889
|
-
},
|
|
4890
|
-
"monitoring.calendar": {
|
|
4891
|
-
id: "monitoring.calendar",
|
|
4892
|
-
order: 190,
|
|
4893
|
-
label: "Calendar",
|
|
4894
|
-
description: "Google Calendar events and agenda views",
|
|
4895
|
-
enabled: true,
|
|
4896
|
-
lifecycle: "active",
|
|
4897
|
-
path: "/monitoring/calendar",
|
|
4898
|
-
icon: "calendar"
|
|
4899
|
-
},
|
|
4900
|
-
"monitoring.activity-log": {
|
|
4901
|
-
id: "monitoring.activity-log",
|
|
4902
|
-
order: 200,
|
|
4903
|
-
label: "Activity Log",
|
|
4904
|
-
enabled: true,
|
|
4905
|
-
lifecycle: "active",
|
|
4906
|
-
path: "/monitoring/activity-log"
|
|
4907
|
-
},
|
|
4908
|
-
"monitoring.execution-logs": {
|
|
4909
|
-
id: "monitoring.execution-logs",
|
|
4910
|
-
order: 210,
|
|
4911
|
-
label: "Execution Logs",
|
|
4912
|
-
enabled: true,
|
|
4913
|
-
lifecycle: "active",
|
|
4914
|
-
path: "/monitoring/execution-logs"
|
|
4915
|
-
},
|
|
4916
|
-
"monitoring.execution-health": {
|
|
4917
|
-
id: "monitoring.execution-health",
|
|
4918
|
-
order: 220,
|
|
4919
|
-
label: "Execution Health",
|
|
4920
|
-
enabled: true,
|
|
4921
|
-
lifecycle: "active",
|
|
4922
|
-
path: "/monitoring/execution-health"
|
|
4923
|
-
},
|
|
4924
|
-
"monitoring.cost-analytics": {
|
|
4925
|
-
id: "monitoring.cost-analytics",
|
|
4926
|
-
order: 230,
|
|
4927
|
-
label: "Cost Analytics",
|
|
4928
|
-
enabled: false,
|
|
4929
|
-
lifecycle: "deprecated",
|
|
4930
|
-
path: "/monitoring/cost-analytics"
|
|
4931
|
-
},
|
|
4932
|
-
"monitoring.notifications": {
|
|
4933
|
-
id: "monitoring.notifications",
|
|
4934
|
-
order: 240,
|
|
4935
|
-
label: "Notifications",
|
|
4936
|
-
enabled: true,
|
|
4937
|
-
lifecycle: "active",
|
|
4938
|
-
path: "/monitoring/notifications"
|
|
4939
|
-
},
|
|
4940
|
-
"monitoring.submitted-requests": {
|
|
4941
|
-
id: "monitoring.submitted-requests",
|
|
4942
|
-
order: 250,
|
|
4943
|
-
label: "Submitted Requests",
|
|
4944
|
-
enabled: true,
|
|
4945
|
-
lifecycle: "active",
|
|
4946
|
-
path: "/monitoring/requests"
|
|
4947
|
-
},
|
|
4948
|
-
settings: {
|
|
4949
|
-
id: "settings",
|
|
4950
|
-
order: 260,
|
|
4951
|
-
label: "Settings",
|
|
4952
|
-
enabled: true,
|
|
4953
|
-
lifecycle: "active",
|
|
4954
|
-
icon: "settings"
|
|
4955
|
-
},
|
|
4956
|
-
"settings.account": {
|
|
4957
|
-
id: "settings.account",
|
|
4958
|
-
order: 270,
|
|
4959
|
-
label: "Account",
|
|
4960
|
-
enabled: true,
|
|
4961
|
-
lifecycle: "active",
|
|
4962
|
-
path: "/settings/account"
|
|
4963
|
-
},
|
|
4964
|
-
"settings.appearance": {
|
|
4965
|
-
id: "settings.appearance",
|
|
4966
|
-
order: 280,
|
|
4967
|
-
label: "Appearance",
|
|
4968
|
-
enabled: true,
|
|
4969
|
-
lifecycle: "active",
|
|
4970
|
-
path: "/settings/appearance"
|
|
4971
|
-
},
|
|
4972
|
-
"settings.roles": {
|
|
4973
|
-
id: "settings.roles",
|
|
4974
|
-
order: 290,
|
|
4975
|
-
label: "My Roles",
|
|
4976
|
-
enabled: true,
|
|
4977
|
-
lifecycle: "active",
|
|
4978
|
-
path: "/settings/roles"
|
|
4979
|
-
},
|
|
4980
|
-
"settings.organization": {
|
|
4981
|
-
id: "settings.organization",
|
|
4982
|
-
order: 300,
|
|
4983
|
-
label: "Organization",
|
|
4984
|
-
enabled: true,
|
|
4985
|
-
lifecycle: "active",
|
|
4986
|
-
path: "/settings/organization"
|
|
4987
|
-
},
|
|
4988
|
-
"settings.credentials": {
|
|
4989
|
-
id: "settings.credentials",
|
|
4990
|
-
order: 310,
|
|
4991
|
-
label: "Credentials",
|
|
4992
|
-
enabled: true,
|
|
4993
|
-
lifecycle: "active",
|
|
4994
|
-
path: "/settings/credentials"
|
|
4995
|
-
},
|
|
4996
|
-
"settings.api-keys": {
|
|
4997
|
-
id: "settings.api-keys",
|
|
4998
|
-
order: 320,
|
|
4999
|
-
label: "API Keys",
|
|
5000
|
-
enabled: true,
|
|
5001
|
-
lifecycle: "active",
|
|
5002
|
-
path: "/settings/api-keys"
|
|
5003
|
-
},
|
|
5004
|
-
"settings.webhooks": {
|
|
5005
|
-
id: "settings.webhooks",
|
|
5006
|
-
order: 330,
|
|
5007
|
-
label: "Webhooks",
|
|
5008
|
-
enabled: true,
|
|
5009
|
-
lifecycle: "active",
|
|
5010
|
-
path: "/settings/webhooks"
|
|
5011
|
-
},
|
|
5012
|
-
"settings.deployments": {
|
|
5013
|
-
id: "settings.deployments",
|
|
5014
|
-
order: 340,
|
|
5015
|
-
label: "Deployments",
|
|
5016
|
-
enabled: true,
|
|
5017
|
-
lifecycle: "active",
|
|
5018
|
-
path: "/settings/deployments"
|
|
5019
|
-
},
|
|
5020
|
-
admin: {
|
|
5021
|
-
id: "admin",
|
|
5022
|
-
order: 350,
|
|
5023
|
-
label: "Admin",
|
|
5024
|
-
enabled: true,
|
|
5025
|
-
lifecycle: "active",
|
|
5026
|
-
path: "/admin",
|
|
5027
|
-
icon: "admin",
|
|
5028
|
-
requiresAdmin: true
|
|
3869
|
+
var PROSPECTING_STEPS = {
|
|
3870
|
+
localServices: {
|
|
3871
|
+
sourceCompanies: {
|
|
3872
|
+
id: "source-companies",
|
|
3873
|
+
label: "Companies found",
|
|
3874
|
+
primaryEntity: "company",
|
|
3875
|
+
outputs: ["company"],
|
|
3876
|
+
stageKey: "populated",
|
|
3877
|
+
dependencyMode: "per-record-eligibility",
|
|
3878
|
+
actionKey: "lead-gen.company.source",
|
|
3879
|
+
defaultBatchSize: 100,
|
|
3880
|
+
maxBatchSize: 250
|
|
5029
3881
|
},
|
|
5030
|
-
|
|
5031
|
-
id: "
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
3882
|
+
analyzeWebsites: {
|
|
3883
|
+
id: "analyze-websites",
|
|
3884
|
+
label: "Websites analyzed",
|
|
3885
|
+
primaryEntity: "company",
|
|
3886
|
+
outputs: ["company"],
|
|
3887
|
+
stageKey: "extracted",
|
|
3888
|
+
dependsOn: ["source-companies"],
|
|
3889
|
+
dependencyMode: "per-record-eligibility",
|
|
3890
|
+
actionKey: "lead-gen.company.website-extract",
|
|
3891
|
+
defaultBatchSize: 50,
|
|
3892
|
+
maxBatchSize: 100
|
|
5037
3893
|
},
|
|
5038
|
-
|
|
5039
|
-
id: "
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
3894
|
+
qualifyCompanies: {
|
|
3895
|
+
id: "qualify-companies",
|
|
3896
|
+
label: "Companies qualified",
|
|
3897
|
+
primaryEntity: "company",
|
|
3898
|
+
outputs: ["company"],
|
|
3899
|
+
stageKey: "qualified",
|
|
3900
|
+
dependsOn: ["analyze-websites"],
|
|
3901
|
+
dependencyMode: "per-record-eligibility",
|
|
3902
|
+
actionKey: "lead-gen.company.qualify",
|
|
3903
|
+
defaultBatchSize: 100,
|
|
3904
|
+
maxBatchSize: 250
|
|
5045
3905
|
},
|
|
5046
|
-
|
|
5047
|
-
id: "
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
3906
|
+
findContacts: {
|
|
3907
|
+
id: "find-contacts",
|
|
3908
|
+
label: "Decision-makers found",
|
|
3909
|
+
primaryEntity: "contact",
|
|
3910
|
+
outputs: ["contact"],
|
|
3911
|
+
stageKey: "discovered",
|
|
3912
|
+
dependsOn: ["qualify-companies"],
|
|
3913
|
+
dependencyMode: "per-record-eligibility",
|
|
3914
|
+
actionKey: "lead-gen.contact.discover",
|
|
3915
|
+
defaultBatchSize: 50,
|
|
3916
|
+
maxBatchSize: 100
|
|
5053
3917
|
},
|
|
5054
|
-
|
|
5055
|
-
id: "
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
3918
|
+
verifyEmails: {
|
|
3919
|
+
id: "verify-emails",
|
|
3920
|
+
label: "Emails verified",
|
|
3921
|
+
primaryEntity: "contact",
|
|
3922
|
+
outputs: ["contact"],
|
|
3923
|
+
stageKey: "verified",
|
|
3924
|
+
dependsOn: ["find-contacts"],
|
|
3925
|
+
dependencyMode: "per-record-eligibility",
|
|
3926
|
+
actionKey: "lead-gen.contact.verify-email",
|
|
3927
|
+
defaultBatchSize: 100,
|
|
3928
|
+
maxBatchSize: 500
|
|
5061
3929
|
},
|
|
5062
|
-
|
|
5063
|
-
id: "
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
3930
|
+
personalize: {
|
|
3931
|
+
id: "personalize",
|
|
3932
|
+
label: "Personalize",
|
|
3933
|
+
primaryEntity: "contact",
|
|
3934
|
+
outputs: ["contact"],
|
|
3935
|
+
stageKey: "personalized",
|
|
3936
|
+
dependsOn: ["verify-emails"],
|
|
3937
|
+
dependencyMode: "per-record-eligibility",
|
|
3938
|
+
actionKey: "lead-gen.contact.personalize",
|
|
3939
|
+
defaultBatchSize: 25,
|
|
3940
|
+
maxBatchSize: 100
|
|
5069
3941
|
},
|
|
5070
|
-
|
|
5071
|
-
id: "
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
3942
|
+
review: {
|
|
3943
|
+
id: "review",
|
|
3944
|
+
label: "Reviewed and exported",
|
|
3945
|
+
primaryEntity: "contact",
|
|
3946
|
+
outputs: ["export"],
|
|
3947
|
+
stageKey: "uploaded",
|
|
3948
|
+
dependsOn: ["personalize"],
|
|
3949
|
+
dependencyMode: "per-record-eligibility",
|
|
3950
|
+
actionKey: "lead-gen.review.outreach-ready",
|
|
3951
|
+
defaultBatchSize: 25,
|
|
3952
|
+
maxBatchSize: 100
|
|
3953
|
+
}
|
|
3954
|
+
},
|
|
3955
|
+
dtcApolloClickup: {
|
|
3956
|
+
importApolloSearch: {
|
|
3957
|
+
id: "import-apollo-search",
|
|
3958
|
+
label: "Companies found",
|
|
3959
|
+
description: "Pull companies and seed contact data from a predefined Apollo search or list.",
|
|
3960
|
+
primaryEntity: "company",
|
|
3961
|
+
outputs: ["company", "contact"],
|
|
3962
|
+
stageKey: "populated",
|
|
3963
|
+
dependencyMode: "per-record-eligibility",
|
|
3964
|
+
actionKey: "lead-gen.company.apollo-import",
|
|
3965
|
+
defaultBatchSize: 250,
|
|
3966
|
+
maxBatchSize: 1e3,
|
|
3967
|
+
recordColumns: DTC_RECORD_COLUMNS.populated,
|
|
3968
|
+
credentialRequirements: [
|
|
3969
|
+
{
|
|
3970
|
+
key: "apollo",
|
|
3971
|
+
provider: "apollo",
|
|
3972
|
+
credentialType: "api-key-secret",
|
|
3973
|
+
label: "Apollo API key",
|
|
3974
|
+
required: true,
|
|
3975
|
+
selectionMode: "single",
|
|
3976
|
+
inputPath: "credential"
|
|
3977
|
+
}
|
|
3978
|
+
]
|
|
5079
3979
|
},
|
|
5080
|
-
|
|
5081
|
-
id: "
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
3980
|
+
apifyCrawl: {
|
|
3981
|
+
id: "apify-crawl",
|
|
3982
|
+
label: "Websites crawled",
|
|
3983
|
+
description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis. Overwrites the synthetic seed Apollo Import wrote with real page content.",
|
|
3984
|
+
primaryEntity: "company",
|
|
3985
|
+
outputs: ["company"],
|
|
3986
|
+
stageKey: "crawled",
|
|
3987
|
+
dependsOn: ["import-apollo-search"],
|
|
3988
|
+
dependencyMode: "per-record-eligibility",
|
|
3989
|
+
actionKey: "lead-gen.company.apify-crawl",
|
|
3990
|
+
defaultBatchSize: 50,
|
|
3991
|
+
maxBatchSize: 100,
|
|
3992
|
+
recordColumns: DTC_RECORD_COLUMNS.crawled,
|
|
3993
|
+
credentialRequirements: [
|
|
3994
|
+
{
|
|
3995
|
+
key: "apify",
|
|
3996
|
+
provider: "apify",
|
|
3997
|
+
credentialType: "api-key-secret",
|
|
3998
|
+
label: "Apify API token",
|
|
3999
|
+
required: true,
|
|
4000
|
+
selectionMode: "single",
|
|
4001
|
+
inputPath: "credential",
|
|
4002
|
+
verifyOnRun: true
|
|
4003
|
+
}
|
|
4004
|
+
]
|
|
5087
4005
|
},
|
|
5088
|
-
|
|
5089
|
-
id: "
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
4006
|
+
analyzeWebsites: {
|
|
4007
|
+
id: "analyze-websites",
|
|
4008
|
+
label: "Websites analyzed",
|
|
4009
|
+
description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
|
|
4010
|
+
primaryEntity: "company",
|
|
4011
|
+
outputs: ["company"],
|
|
4012
|
+
stageKey: "extracted",
|
|
4013
|
+
dependsOn: ["apify-crawl"],
|
|
4014
|
+
dependencyMode: "per-record-eligibility",
|
|
4015
|
+
actionKey: "lead-gen.company.website-extract",
|
|
4016
|
+
defaultBatchSize: 50,
|
|
4017
|
+
maxBatchSize: 100,
|
|
4018
|
+
recordColumns: DTC_RECORD_COLUMNS.extracted
|
|
5095
4019
|
},
|
|
5096
|
-
|
|
5097
|
-
id: "
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
4020
|
+
scoreDtcFit: {
|
|
4021
|
+
id: "score-dtc-fit",
|
|
4022
|
+
label: "Companies qualified",
|
|
4023
|
+
description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
|
|
4024
|
+
primaryEntity: "company",
|
|
4025
|
+
outputs: ["company"],
|
|
4026
|
+
stageKey: "qualified",
|
|
4027
|
+
dependsOn: ["analyze-websites"],
|
|
4028
|
+
dependencyMode: "per-record-eligibility",
|
|
4029
|
+
actionKey: "lead-gen.company.dtc-subscription-qualify",
|
|
4030
|
+
defaultBatchSize: 100,
|
|
4031
|
+
maxBatchSize: 250,
|
|
4032
|
+
recordColumns: DTC_RECORD_COLUMNS.qualified
|
|
5103
4033
|
},
|
|
5104
|
-
|
|
5105
|
-
id: "
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
4034
|
+
enrichDecisionMakers: {
|
|
4035
|
+
id: "enrich-decision-makers",
|
|
4036
|
+
label: "Decision-makers found",
|
|
4037
|
+
description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
|
|
4038
|
+
primaryEntity: "company",
|
|
4039
|
+
outputs: ["contact"],
|
|
4040
|
+
stageKey: "decision-makers-enriched",
|
|
4041
|
+
recordEntity: "contact",
|
|
4042
|
+
dependsOn: ["score-dtc-fit"],
|
|
4043
|
+
dependencyMode: "per-record-eligibility",
|
|
4044
|
+
actionKey: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
4045
|
+
defaultBatchSize: 100,
|
|
4046
|
+
maxBatchSize: 250,
|
|
4047
|
+
recordColumns: DTC_RECORD_COLUMNS.decisionMakers,
|
|
4048
|
+
credentialRequirements: [
|
|
4049
|
+
{
|
|
4050
|
+
key: "apollo",
|
|
4051
|
+
provider: "apollo",
|
|
4052
|
+
credentialType: "api-key-secret",
|
|
4053
|
+
label: "Apollo API key",
|
|
4054
|
+
required: true,
|
|
4055
|
+
selectionMode: "single",
|
|
4056
|
+
inputPath: "credential"
|
|
4057
|
+
}
|
|
4058
|
+
]
|
|
5113
4059
|
},
|
|
5114
|
-
|
|
5115
|
-
id: "
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
if (!isPlainObject(value)) continue;
|
|
5142
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
5143
|
-
for (const childKey of ["systems", "subsystems"]) {
|
|
5144
|
-
const childSystems = value[childKey];
|
|
5145
|
-
if (!isPlainObject(childSystems)) continue;
|
|
5146
|
-
for (const childPath of collectNestedSystemPaths(childSystems, path)) {
|
|
5147
|
-
paths.add(childPath);
|
|
5148
|
-
}
|
|
5149
|
-
}
|
|
5150
|
-
if (prefix !== "") {
|
|
5151
|
-
paths.add(path);
|
|
5152
|
-
}
|
|
5153
|
-
}
|
|
5154
|
-
return paths;
|
|
5155
|
-
}
|
|
5156
|
-
function pruneFlatSystemDescendantCollisions(base, override) {
|
|
5157
|
-
const result = { ...base };
|
|
5158
|
-
for (const nestedPath of collectNestedSystemPaths(override)) {
|
|
5159
|
-
delete result[nestedPath];
|
|
5160
|
-
}
|
|
5161
|
-
return result;
|
|
5162
|
-
}
|
|
5163
|
-
function deepMerge(base, override) {
|
|
5164
|
-
if (override === void 0) {
|
|
5165
|
-
return base;
|
|
5166
|
-
}
|
|
5167
|
-
if (Array.isArray(base)) {
|
|
5168
|
-
return override ?? base;
|
|
5169
|
-
}
|
|
5170
|
-
if (!isPlainObject(base) || !isPlainObject(override)) {
|
|
5171
|
-
return override ?? base;
|
|
5172
|
-
}
|
|
5173
|
-
const result = { ...base };
|
|
5174
|
-
for (const [key, value] of Object.entries(override)) {
|
|
5175
|
-
if (value === void 0) continue;
|
|
5176
|
-
const existing = result[key];
|
|
5177
|
-
if (key === "systems" && isPlainObject(existing) && isPlainObject(value)) {
|
|
5178
|
-
result[key] = deepMerge(pruneFlatSystemDescendantCollisions(existing, value), value);
|
|
5179
|
-
continue;
|
|
4060
|
+
reviewAndExport: {
|
|
4061
|
+
id: "review-and-export",
|
|
4062
|
+
label: "Reviewed and exported",
|
|
4063
|
+
description: "Operator QC approves or rejects qualified companies, then approved records are exported as a lead list with unverified emails.",
|
|
4064
|
+
primaryEntity: "company",
|
|
4065
|
+
outputs: ["export"],
|
|
4066
|
+
stageKey: "uploaded",
|
|
4067
|
+
recordsStageKey: "uploaded",
|
|
4068
|
+
recordSourceStageKey: "qualified",
|
|
4069
|
+
dependsOn: ["enrich-decision-makers"],
|
|
4070
|
+
dependencyMode: "per-record-eligibility",
|
|
4071
|
+
actionKey: "lead-gen.export.list",
|
|
4072
|
+
defaultBatchSize: 100,
|
|
4073
|
+
maxBatchSize: 250,
|
|
4074
|
+
recordColumns: DTC_RECORD_COLUMNS.uploaded,
|
|
4075
|
+
credentialRequirements: [
|
|
4076
|
+
{
|
|
4077
|
+
key: "clickup",
|
|
4078
|
+
provider: "clickup",
|
|
4079
|
+
credentialType: "api-key-secret",
|
|
4080
|
+
label: "ClickUp API token",
|
|
4081
|
+
required: true,
|
|
4082
|
+
selectionMode: "single",
|
|
4083
|
+
inputPath: "clickupCredential",
|
|
4084
|
+
verifyOnRun: true
|
|
4085
|
+
}
|
|
4086
|
+
]
|
|
5180
4087
|
}
|
|
5181
|
-
result[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
|
|
5182
|
-
}
|
|
5183
|
-
return result;
|
|
5184
|
-
}
|
|
5185
|
-
function resolveOrganizationModel(override, organizationIdOrOptions, options) {
|
|
5186
|
-
const resolvedOptions = typeof organizationIdOrOptions === "object" ? organizationIdOrOptions : options;
|
|
5187
|
-
const mergeDefaults = resolvedOptions?.mergeDefaults ?? true;
|
|
5188
|
-
const merged = mergeDefaults ? deepMerge(DEFAULT_ORGANIZATION_MODEL, override) : override ?? {};
|
|
5189
|
-
return OrganizationModelSchema.parse(merged);
|
|
5190
|
-
}
|
|
5191
|
-
|
|
5192
|
-
// ../core/src/organization-model/surface-projection.ts
|
|
5193
|
-
function collectSystemsById(model) {
|
|
5194
|
-
const systemsById = /* @__PURE__ */ new Map();
|
|
5195
|
-
for (const { path, system } of listAllSystems(model)) {
|
|
5196
|
-
systemsById.set(path, system);
|
|
5197
|
-
systemsById.set(system.id, system);
|
|
5198
|
-
}
|
|
5199
|
-
return systemsById;
|
|
5200
|
-
}
|
|
5201
|
-
function getSystemWithAncestors(systemsById, systemId) {
|
|
5202
|
-
const systems = [];
|
|
5203
|
-
let current = systemsById.get(systemId);
|
|
5204
|
-
while (current !== void 0) {
|
|
5205
|
-
systems.unshift(current);
|
|
5206
|
-
current = current.parentSystemId ? systemsById.get(current.parentSystemId) : void 0;
|
|
5207
4088
|
}
|
|
5208
|
-
|
|
5209
|
-
}
|
|
5210
|
-
function hasInheritedFlag(systemsById, systemIds, flag) {
|
|
5211
|
-
return systemIds.some(
|
|
5212
|
-
(systemId) => getSystemWithAncestors(systemsById, systemId).some((system) => system[flag] === true)
|
|
5213
|
-
);
|
|
5214
|
-
}
|
|
5215
|
-
function isLifecycleEnabled2(system) {
|
|
5216
|
-
if (system.enabled === false) return false;
|
|
5217
|
-
return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
|
|
5218
|
-
}
|
|
5219
|
-
function isLifecycleDevOnly(system) {
|
|
5220
|
-
return system.devOnly === true || system.lifecycle === "beta";
|
|
5221
|
-
}
|
|
5222
|
-
function isSystemEnabled(systemsById, systemId) {
|
|
5223
|
-
const systemLineage = getSystemWithAncestors(systemsById, systemId);
|
|
5224
|
-
return systemLineage.length > 0 && systemLineage.every(isLifecycleEnabled2);
|
|
5225
|
-
}
|
|
5226
|
-
function unique(values) {
|
|
5227
|
-
return [...new Set(values)];
|
|
5228
|
-
}
|
|
5229
|
-
function collectSidebarSurfaces(nodes, schemaPath, surfaces = []) {
|
|
5230
|
-
getSortedSidebarEntries(nodes).forEach(([id, node]) => {
|
|
5231
|
-
const nodePath = [...schemaPath, id];
|
|
5232
|
-
if (node.type === "group") {
|
|
5233
|
-
collectSidebarSurfaces(node.children, [...nodePath, "children"], surfaces);
|
|
5234
|
-
return;
|
|
5235
|
-
}
|
|
5236
|
-
surfaces.push({ id, surface: node, path: nodePath });
|
|
5237
|
-
});
|
|
5238
|
-
return surfaces;
|
|
5239
|
-
}
|
|
5240
|
-
function getSidebarSurfaces(model) {
|
|
5241
|
-
return [
|
|
5242
|
-
...collectSidebarSurfaces(model.navigation.sidebar.primary, ["navigation", "sidebar", "primary"]),
|
|
5243
|
-
...collectSidebarSurfaces(model.navigation.sidebar.bottom, ["navigation", "sidebar", "bottom"])
|
|
5244
|
-
];
|
|
5245
|
-
}
|
|
5246
|
-
function projectOrganizationSurfaces(model) {
|
|
5247
|
-
const systemsById = collectSystemsById(model);
|
|
5248
|
-
return getSidebarSurfaces(model).map(({ id, surface }) => {
|
|
5249
|
-
const targets = surface.targets ?? {};
|
|
5250
|
-
const systemIds = unique((targets.systems ?? []).filter((systemId) => systemsById.has(systemId)));
|
|
5251
|
-
const enabled = systemIds.every((candidate) => isSystemEnabled(systemsById, candidate));
|
|
5252
|
-
const devOnly = surface.devOnly === true || hasInheritedFlag(systemsById, systemIds, "devOnly") || systemIds.some((candidate) => getSystemWithAncestors(systemsById, candidate).some(isLifecycleDevOnly));
|
|
5253
|
-
const requiresAdmin = hasInheritedFlag(systemsById, systemIds, "requiresAdmin");
|
|
5254
|
-
return {
|
|
5255
|
-
id,
|
|
5256
|
-
label: surface.label,
|
|
5257
|
-
path: surface.path,
|
|
5258
|
-
surfaceType: surface.surfaceType,
|
|
5259
|
-
...surface.description !== void 0 ? { description: surface.description } : {},
|
|
5260
|
-
...surface.icon !== void 0 ? { icon: surface.icon } : {},
|
|
5261
|
-
...surface.order !== void 0 ? { order: surface.order } : {},
|
|
5262
|
-
systemIds,
|
|
5263
|
-
entityIds: [...targets.entities ?? []],
|
|
5264
|
-
resourceIds: [...targets.resources ?? []],
|
|
5265
|
-
actionIds: [...targets.actions ?? []],
|
|
5266
|
-
enabled,
|
|
5267
|
-
...devOnly ? { devOnly } : {},
|
|
5268
|
-
...surface.requiresAdmin === true || requiresAdmin ? { requiresAdmin: true } : {}
|
|
5269
|
-
};
|
|
5270
|
-
});
|
|
5271
|
-
}
|
|
4089
|
+
};
|
|
5272
4090
|
|
|
5273
|
-
export { ActionSchema, AgentResourceEntrySchema, CRM_DISCOVERY_BOOKING_CANCELLED_STATE, CRM_DISCOVERY_LINK_SENT_STATE, CRM_DISCOVERY_NUDGING_STATE, CRM_DISCOVERY_REPLIED_STATE,
|
|
4091
|
+
export { ActionSchema, AgentResourceEntrySchema, CRM_DISCOVERY_BOOKING_CANCELLED_STATE, CRM_DISCOVERY_LINK_SENT_STATE, CRM_DISCOVERY_NUDGING_STATE, CRM_DISCOVERY_REPLIED_STATE, EntitySchema, IdentityDomainSchema, IntegrationResourceEntrySchema, OntologyIdSchema, OrgKnowledgeNodeSchema, PROJECTS_VIEW_ACTION_ID, PROSPECTING_STEPS, PolicySchema, RoleSchema, ScriptResourceEntrySchema, SemanticIcon, SurfaceDefinitionSchema, SystemEntrySchema, WorkflowResourceEntrySchema, ancestorsOf, buildOrganizationGraph, childrenOf, compileOrganizationOntology, defaultPathFor, defineResources, defineTopology, devOnlyFor, extendSemanticIconRegistry, findById, findByPath, findPipeline, getLeadGenStageCatalog, getResourcesForSystem, getSemanticIconComponent, getSortedSidebarEntries, getSystem, getSystemAncestors, listAllSystems, ontologyGraphNodeId, parentOf, parseOntologyId, projectOrganizationSurfaces, requiresAdminFor, resolveOrganizationModel, resolveSemanticIconComponent, resolveSystemConfig, topLevel, topologyRef, topologyRelationship };
|