@elevasis/sdk 1.14.1 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -37,6 +37,77 @@ var ToolingError = class extends ExecutionError {
37
37
  this.details = details;
38
38
  }
39
39
  };
40
+ var ModelIdSchema = z.string().trim().min(1).max(100).regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "IDs must be lowercase and use -, _, or . separators");
41
+ var LabelSchema = z.string().trim().min(1).max(120);
42
+ var DescriptionSchema = z.string().trim().min(1).max(2e3);
43
+ var ColorTokenSchema = z.string().trim().min(1).max(50);
44
+ var IconNameSchema = z.string().trim().min(1).max(80);
45
+ z.string().trim().startsWith("/").max(300);
46
+ var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
47
+ var DisplayMetadataSchema = z.object({
48
+ label: LabelSchema,
49
+ description: DescriptionSchema.optional(),
50
+ color: ColorTokenSchema.optional(),
51
+ icon: IconNameSchema.optional()
52
+ });
53
+ var TechStackEntrySchema = z.object({
54
+ /** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
55
+ platform: z.string().trim().min(1).max(200),
56
+ /** Free-form description of what this integration is used for. */
57
+ purpose: z.string().trim().min(1).max(500),
58
+ /**
59
+ * Health of the credential backing this integration.
60
+ * - configured: credential present and valid
61
+ * - pending: not yet set up
62
+ * - expired: credential existed but has lapsed
63
+ * - missing: expected but not present
64
+ */
65
+ credentialStatus: z.enum(["configured", "pending", "expired", "missing"]),
66
+ /**
67
+ * Whether this integration is the primary system of record for its domain
68
+ * (e.g. HubSpot is SoR for contacts). Defaults to false.
69
+ */
70
+ isSystemOfRecord: z.boolean().default(false)
71
+ });
72
+ DisplayMetadataSchema.extend({
73
+ id: ModelIdSchema,
74
+ resourceId: z.string().trim().min(1).max(255),
75
+ resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
76
+ featureIds: ReferenceIdsSchema,
77
+ entityIds: ReferenceIdsSchema,
78
+ surfaceIds: ReferenceIdsSchema,
79
+ capabilityIds: ReferenceIdsSchema,
80
+ /** Optional tech-stack metadata for external-SaaS integrations. */
81
+ techStack: TechStackEntrySchema.optional()
82
+ });
83
+ var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
84
+ var SalesStageSchema = DisplayMetadataSchema.extend({
85
+ id: ModelIdSchema,
86
+ order: z.number().int().min(0),
87
+ semanticClass: SalesStageSemanticClassSchema,
88
+ surfaceIds: ReferenceIdsSchema,
89
+ resourceIds: ReferenceIdsSchema
90
+ });
91
+ var SalesPipelineSchema = z.object({
92
+ id: ModelIdSchema,
93
+ label: z.string().trim().min(1).max(120),
94
+ description: DescriptionSchema.optional(),
95
+ entityId: ModelIdSchema,
96
+ stages: z.array(SalesStageSchema).min(1)
97
+ });
98
+ z.object({
99
+ entityId: ModelIdSchema,
100
+ defaultPipelineId: ModelIdSchema,
101
+ pipelines: z.array(SalesPipelineSchema).min(1)
102
+ });
103
+ var CRM_DISCOVERY_REPLIED_STATE = {
104
+ stateKey: "discovery_replied"};
105
+ var CRM_DISCOVERY_LINK_SENT_STATE = {
106
+ stateKey: "discovery_link_sent"};
107
+ var CRM_DISCOVERY_NUDGING_STATE = {
108
+ stateKey: "discovery_nudging"};
109
+ var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
110
+ stateKey: "discovery_booking_cancelled"};
40
111
 
41
112
  // ../core/src/platform/registry/reserved.ts
42
113
  var RESERVED_RESOURCE_IDS = /* @__PURE__ */ new Set(["command-center-assistant"]);
@@ -3716,6 +3787,13 @@ var DealCreatedEventSchema = z.object({
3716
3787
  type: z.literal("deal_created"),
3717
3788
  timestamp: z.string().datetime()
3718
3789
  });
3790
+ var ActionFailedEventSchema = z.object({
3791
+ type: z.literal("action_failed"),
3792
+ timestamp: z.string().datetime(),
3793
+ actionKey: z.string(),
3794
+ errorMessage: z.string(),
3795
+ payload: z.record(z.string(), z.unknown()).optional()
3796
+ });
3719
3797
  var ActivityEventSchema = z.discriminatedUnion("type", [
3720
3798
  StageChangeEventSchema,
3721
3799
  StateChangeEventSchema,
@@ -3724,8 +3802,67 @@ var ActivityEventSchema = z.discriminatedUnion("type", [
3724
3802
  ApprovalResolvedEventSchema,
3725
3803
  ApprovalStaleEventSchema,
3726
3804
  TaskCreatedEventSchema,
3727
- DealCreatedEventSchema
3805
+ DealCreatedEventSchema,
3806
+ ActionFailedEventSchema
3728
3807
  ]);
3808
+
3809
+ // ../core/src/business/acquisition/deal-ownership.ts
3810
+ var INBOUND_EVENT_TYPES = ["reply_received"];
3811
+ var OUTBOUND_EVENT_TYPES = [
3812
+ "reply_sent_to_lead",
3813
+ "booking_nudge_sent",
3814
+ "reminder_sent",
3815
+ "rebook_sent",
3816
+ "followup_email_sent",
3817
+ "reply_followup_sent",
3818
+ "lead_deferred_next_step"
3819
+ ];
3820
+ var INBOUND_SET = new Set(INBOUND_EVENT_TYPES);
3821
+ var OUTBOUND_SET = new Set(OUTBOUND_EVENT_TYPES);
3822
+ function getDealOwnership(deal) {
3823
+ if (deal.state_key === "closed_won" || deal.state_key === "closed_lost") {
3824
+ return null;
3825
+ }
3826
+ if (!Array.isArray(deal.activity_log)) return null;
3827
+ let latestInboundMs = null;
3828
+ let latestOutboundMs = null;
3829
+ for (const entry of deal.activity_log) {
3830
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
3831
+ const record = entry;
3832
+ const type = typeof record.type === "string" ? record.type : null;
3833
+ if (!type) continue;
3834
+ const isInbound = INBOUND_SET.has(type);
3835
+ const isOutbound = OUTBOUND_SET.has(type);
3836
+ if (!isInbound && !isOutbound) continue;
3837
+ const occurredAt = resolveTimestamp(record);
3838
+ if (occurredAt === null) continue;
3839
+ if (isInbound && (latestInboundMs === null || occurredAt > latestInboundMs)) {
3840
+ latestInboundMs = occurredAt;
3841
+ }
3842
+ if (isOutbound && (latestOutboundMs === null || occurredAt > latestOutboundMs)) {
3843
+ latestOutboundMs = occurredAt;
3844
+ }
3845
+ }
3846
+ if (latestInboundMs === null && latestOutboundMs === null) return null;
3847
+ if (latestOutboundMs !== null && (latestInboundMs === null || latestOutboundMs >= latestInboundMs)) {
3848
+ return "them";
3849
+ }
3850
+ return "us";
3851
+ }
3852
+ function resolveTimestamp(record) {
3853
+ return parseMs(record.timestamp) ?? parseMs(record.occurredAt) ?? parseMs(record.createdAt) ?? parseMs(record.updatedAt) ?? parseMs(record.sentAt) ?? null;
3854
+ }
3855
+ function parseMs(value) {
3856
+ if (value instanceof Date) {
3857
+ const ms2 = value.getTime();
3858
+ return Number.isNaN(ms2) ? null : ms2;
3859
+ }
3860
+ if (typeof value !== "string") return null;
3861
+ const ms = new Date(value).getTime();
3862
+ return Number.isNaN(ms) ? null : ms;
3863
+ }
3864
+
3865
+ // ../core/src/business/acquisition/derive-actions.ts
3729
3866
  var SendReplyActionPayloadSchema = z.object({
3730
3867
  replyBody: z.string().trim().min(1).max(1e4)
3731
3868
  }).strict();
@@ -3763,26 +3900,26 @@ var DEFAULT_CRM_ACTIONS = [
3763
3900
  {
3764
3901
  key: "send_reply",
3765
3902
  label: "Send Reply",
3766
- isAvailableFor: (deal) => deal.stage_key === "interested" && (deal.state_key === "discovery_replied" || deal.state_key === "discovery_link_sent" || deal.state_key === "discovery_nudging"),
3903
+ isAvailableFor: (deal) => deal.stage_key === "interested" && isOurReplyAction(deal) && (deal.state_key === CRM_DISCOVERY_REPLIED_STATE.stateKey || deal.state_key === CRM_DISCOVERY_LINK_SENT_STATE.stateKey || deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey),
3767
3904
  workflowId: "crm-send-reply-workflow",
3768
3905
  payloadSchema: SendReplyActionPayloadSchema
3769
3906
  },
3770
3907
  {
3771
3908
  key: "send_link",
3772
3909
  label: "Send Booking Link",
3773
- isAvailableFor: (deal) => deal.stage_key === "interested" && deal.state_key === "discovery_replied",
3910
+ isAvailableFor: (deal) => deal.stage_key === "interested" && deal.state_key === CRM_DISCOVERY_REPLIED_STATE.stateKey,
3774
3911
  workflowId: "crm-send-booking-link-workflow"
3775
3912
  },
3776
3913
  {
3777
3914
  key: "send_nudge",
3778
3915
  label: "Send Nudge",
3779
- isAvailableFor: (deal) => deal.stage_key === "interested" && (deal.state_key === "discovery_link_sent" || deal.state_key === "discovery_nudging"),
3916
+ isAvailableFor: (deal) => deal.stage_key === "interested" && (deal.state_key === CRM_DISCOVERY_LINK_SENT_STATE.stateKey || deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey),
3780
3917
  workflowId: "crm-send-nudge-workflow"
3781
3918
  },
3782
3919
  {
3783
3920
  key: "mark_no_show",
3784
3921
  label: "Mark No-Show",
3785
- isAvailableFor: (deal) => deal.stage_key === "interested" && deal.state_key === "discovery_nudging",
3922
+ isAvailableFor: (deal) => deal.stage_key === "interested" && deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey,
3786
3923
  // Mirrors the auto-timeout precedent in operations/sales/crm/pipeline/timeout-actions.ts:
3787
3924
  // both manual-click and timeout move the deal to closed_lost. The action_taken activity
3788
3925
  // event captures operator intent and distinguishes the manual variant from the timed one.
@@ -3791,12 +3928,18 @@ var DEFAULT_CRM_ACTIONS = [
3791
3928
  {
3792
3929
  key: "rebook",
3793
3930
  label: "Rebook",
3794
- isAvailableFor: (deal) => deal.stage_key === "interested" && deal.state_key === "discovery_booking_cancelled",
3931
+ isAvailableFor: (deal) => deal.stage_key === "interested" && deal.state_key === CRM_DISCOVERY_BOOKING_CANCELLED_STATE.stateKey,
3795
3932
  workflowId: "crm-rebook-workflow"
3796
3933
  }
3797
3934
  ];
3798
3935
  function deriveActions(deal, actions = DEFAULT_CRM_ACTIONS) {
3799
3936
  return actions.filter((a) => a.isAvailableFor(deal)).map(({ key, label, payloadSchema }) => ({ key, label, payloadSchema }));
3800
3937
  }
3938
+ function isOurReplyAction(deal) {
3939
+ if (Object.prototype.hasOwnProperty.call(deal, "nextAction")) {
3940
+ return deal.nextAction === "send_reply";
3941
+ }
3942
+ return (deal.ownership ?? getDealOwnership(deal)) === "us";
3943
+ }
3801
3944
 
3802
3945
  export { ActivityEventSchema, DEFAULT_CRM_ACTIONS, ExecutionError, RegistryValidationError, ResourceRegistry, StepType, ToolingError, deriveActions };