@ecodrix/erix-api 1.0.1 → 1.0.3

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.
Files changed (38) hide show
  1. package/dist/cli.js +38 -0
  2. package/dist/index.d.cts +1871 -0
  3. package/dist/index.d.ts +902 -42
  4. package/dist/ts/browser/index.global.js +14 -14
  5. package/dist/ts/browser/index.global.js.map +1 -1
  6. package/dist/ts/cjs/index.cjs +1 -1
  7. package/dist/ts/cjs/index.cjs.map +1 -1
  8. package/dist/ts/cjs/index.d.cts +902 -42
  9. package/dist/ts/esm/index.d.ts +902 -42
  10. package/dist/ts/esm/index.js +1 -1
  11. package/dist/ts/esm/index.js.map +1 -1
  12. package/package.json +7 -2
  13. package/src/cli.ts +318 -0
  14. package/src/core.ts +20 -0
  15. package/src/index.ts +17 -1
  16. package/src/resource.ts +44 -5
  17. package/src/resources/crm/activities.ts +89 -0
  18. package/src/resources/crm/analytics.ts +89 -0
  19. package/src/resources/crm/automationDashboard.ts +24 -0
  20. package/src/resources/crm/automations.ts +145 -0
  21. package/src/resources/crm/index.ts +24 -0
  22. package/src/resources/crm/leads.ts +170 -42
  23. package/src/resources/crm/payments.ts +10 -0
  24. package/src/resources/crm/pipelines.ts +117 -0
  25. package/src/resources/crm/scoring.ts +33 -0
  26. package/src/resources/crm/sequences.ts +24 -0
  27. package/src/resources/events.ts +41 -0
  28. package/src/resources/health.ts +61 -0
  29. package/src/resources/marketing.ts +104 -0
  30. package/src/resources/meet.ts +9 -2
  31. package/src/resources/notifications.ts +30 -0
  32. package/src/resources/queue.ts +39 -0
  33. package/src/resources/storage.ts +72 -0
  34. package/src/resources/whatsapp/broadcasts.ts +31 -0
  35. package/src/resources/whatsapp/conversations.ts +34 -9
  36. package/src/resources/whatsapp/index.ts +20 -0
  37. package/src/resources/whatsapp/messages.ts +24 -0
  38. package/src/resources/whatsapp/templates.ts +99 -0
@@ -0,0 +1,145 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export interface AutomationRulePayload {
4
+ name: string;
5
+ trigger: string;
6
+ isActive?: boolean;
7
+ nodes: any[];
8
+ edges: any[];
9
+ }
10
+
11
+ export class Automations extends APIResource {
12
+ /**
13
+ * List all automation rules for the tenant.
14
+ */
15
+ async list<T = any>() {
16
+ return this.get<T>("/api/saas/crm/automations");
17
+ }
18
+
19
+ /**
20
+ * Create a new automation rule.
21
+ */
22
+ async create<T = any>(payload: AutomationRulePayload) {
23
+ return this.post<T>("/api/saas/crm/automations", payload);
24
+ }
25
+
26
+ /**
27
+ * Update an existing automation rule.
28
+ */
29
+ async update<T = any>(ruleId: string, payload: Partial<AutomationRulePayload>) {
30
+ return this.patch<T>(`/api/saas/crm/automations/${ruleId}`, payload as any);
31
+ }
32
+
33
+ /**
34
+ * Enable or disable an automation rule.
35
+ */
36
+ async toggle<T = any>(ruleId: string) {
37
+ return this.patch<T>(`/api/saas/crm/automations/${ruleId}/toggle`);
38
+ }
39
+
40
+ /**
41
+ * Delete an automation rule.
42
+ */
43
+ async deleteRule<T = any>(ruleId: string) {
44
+ return this.deleteRequest<T>(`/api/saas/crm/automations/${ruleId}`);
45
+ }
46
+
47
+ /**
48
+ * Bulk delete rules.
49
+ */
50
+ async bulkDelete<T = any>(ruleIds: string[]) {
51
+ return this.post<T>("/api/saas/crm/automations/bulk-delete", { ids: ruleIds });
52
+ }
53
+
54
+ /**
55
+ * Dry-run test an automation rule against a specific lead.
56
+ */
57
+ async test<T = any>(ruleId: string, leadId: string) {
58
+ return this.post<T>(`/api/saas/crm/automations/${ruleId}/test`, { leadId });
59
+ }
60
+
61
+ /**
62
+ * Get available event triggers for automations.
63
+ */
64
+ async getAvailableEvents<T = any>() {
65
+ return this.post<T>("/api/saas/crm/automations/events", {});
66
+ }
67
+
68
+ /**
69
+ * List enrollments for a rule.
70
+ */
71
+ async enrollments<T = any>(
72
+ ruleId: string,
73
+ params?: {
74
+ status?: string;
75
+ page?: number;
76
+ limit?: number;
77
+ startDate?: string;
78
+ endDate?: string;
79
+ }
80
+ ) {
81
+ return this.get<T>(`/api/saas/crm/automations/${ruleId}/enrollments`, { params });
82
+ }
83
+
84
+ /**
85
+ * Get an enrollment detail.
86
+ */
87
+ async getEnrollment<T = any>(enrollmentId: string) {
88
+ return this.get<T>(`/api/saas/crm/automations/enrollments/${enrollmentId}`);
89
+ }
90
+
91
+ /**
92
+ * Pause an enrollment.
93
+ */
94
+ async pauseEnrollment<T = any>(ruleId: string, enrollmentId: string) {
95
+ return this.post<T>(`/api/saas/crm/automations/${ruleId}/enrollments/${enrollmentId}/pause`, {});
96
+ }
97
+
98
+ /**
99
+ * Resume an enrollment.
100
+ */
101
+ async resumeEnrollment<T = any>(ruleId: string, enrollmentId: string) {
102
+ return this.post<T>(`/api/saas/crm/automations/${ruleId}/enrollments/${enrollmentId}/resume`, {});
103
+ }
104
+
105
+ /**
106
+ * List workflow runs.
107
+ */
108
+ async runs<T = any>(ruleId: string) {
109
+ return this.get<T>(`/api/saas/crm/automations/${ruleId}/runs`);
110
+ }
111
+
112
+ /**
113
+ * Get run details.
114
+ */
115
+ async getRun<T = any>(runId: string) {
116
+ return this.get<T>(`/api/saas/crm/automations/runs/${runId}`);
117
+ }
118
+
119
+ /**
120
+ * Resume a paused run.
121
+ */
122
+ async resumeRun<T = any>(runId: string) {
123
+ return this.post<T>(`/api/saas/crm/automations/runs/${runId}/resume`, {});
124
+ }
125
+
126
+ /**
127
+ * Abort a running workflow.
128
+ */
129
+ async abortRun<T = any>(runId: string) {
130
+ return this.post<T>(`/api/saas/crm/automations/runs/${runId}/abort`, {});
131
+ }
132
+
133
+ /**
134
+ * Emit an external webhook event to unlock a `wait_event` node inside a
135
+ * paused workflow run. Required when integrating third-party tools that
136
+ * need to resume a suspended automation.
137
+ *
138
+ * @param ruleId - The automation rule that contains the wait_event node.
139
+ * @param eventName - The event name that should match the node's condition.
140
+ * @param payload - Arbitrary data forwarded to the node context.
141
+ */
142
+ async webhookEvent<T = any>(ruleId: string, eventName: string, payload?: any) {
143
+ return this.post<T>("/api/saas/crm/webhook-event", { ruleId, eventName, payload });
144
+ }
145
+ }
@@ -1,10 +1,34 @@
1
1
  import { Leads } from "./leads";
2
+ import { Pipelines } from "./pipelines";
3
+ import { Activities } from "./activities";
4
+ import { Analytics } from "./analytics";
5
+ import { Automations } from "./automations";
6
+ import { Sequences } from "./sequences";
7
+ import { Scoring } from "./scoring";
8
+ import { Payments } from "./payments";
9
+ import { AutomationDashboard } from "./automationDashboard";
2
10
  import type { AxiosInstance } from "axios";
3
11
 
4
12
  export class CRM {
5
13
  public leads: Leads;
14
+ public pipelines: Pipelines;
15
+ public activities: Activities;
16
+ public analytics: Analytics;
17
+ public automations: Automations;
18
+ public sequences: Sequences;
19
+ public scoring: Scoring;
20
+ public payments: Payments;
21
+ public automationDashboard: AutomationDashboard;
6
22
 
7
23
  constructor(client: AxiosInstance) {
8
24
  this.leads = new Leads(client);
25
+ this.pipelines = new Pipelines(client);
26
+ this.activities = new Activities(client);
27
+ this.analytics = new Analytics(client);
28
+ this.automations = new Automations(client);
29
+ this.sequences = new Sequences(client);
30
+ this.scoring = new Scoring(client);
31
+ this.payments = new Payments(client);
32
+ this.automationDashboard = new AutomationDashboard(client);
9
33
  }
10
34
  }
@@ -1,5 +1,15 @@
1
1
  import { APIResource } from "../../resource";
2
2
 
3
+ /**
4
+ * Valid statuses for a CRM Lead.
5
+ */
6
+ export type LeadStatus = "new" | "contacted" | "qualified" | "won" | "lost" | "archived";
7
+
8
+ /**
9
+ * Common lead acquisition sources. Additional string values are allowed.
10
+ */
11
+ export type LeadSource = "website" | "whatsapp" | "direct" | "referral" | string;
12
+
3
13
  /**
4
14
  * Parameters for creating a new CRM Lead.
5
15
  */
@@ -14,11 +24,49 @@ export interface CreateLeadParams {
14
24
  phone?: string;
15
25
  /**
16
26
  * Acquisition channel.
17
- * @example "website" | "whatsapp" | "direct" | "referral"
18
27
  */
19
- source?: string;
28
+ source?: LeadSource;
20
29
  /** Arbitrary key-value metadata (UTM params, order IDs, etc.). */
21
30
  metadata?: Record<string, any>;
31
+ /** Pipeline ID to assign the lead */
32
+ pipelineId?: string;
33
+ /** Stage ID to assign the lead */
34
+ stageId?: string;
35
+ }
36
+
37
+ /**
38
+ * Options for listing leads.
39
+ */
40
+ export interface ListLeadsParams {
41
+ status?: LeadStatus;
42
+ pipelineId?: string;
43
+ stageId?: string;
44
+ source?: LeadSource;
45
+ assignedTo?: string;
46
+ tags?: string[] | string;
47
+ minScore?: number;
48
+ search?: string;
49
+ startDate?: string;
50
+ endDate?: string;
51
+ appointmentId?: string;
52
+ bookingId?: string;
53
+ orderId?: string;
54
+ meetingId?: string;
55
+ page?: number;
56
+ limit?: number;
57
+ sortBy?: string;
58
+ sortDir?: "asc" | "desc";
59
+ }
60
+
61
+ /**
62
+ * Options for upserting a lead.
63
+ */
64
+ export interface UpsertLeadParams {
65
+ leadData: Partial<CreateLeadParams> & { phone: string; name?: string };
66
+ moduleInfo?: any;
67
+ trigger?: string;
68
+ pipelineId?: string;
69
+ stageId?: string;
22
70
  }
23
71
 
24
72
  /**
@@ -41,19 +89,21 @@ export class Leads extends APIResource {
41
89
  *
42
90
  * @param params - Lead creation parameters. `firstName` is required.
43
91
  * @returns The newly created Lead document.
44
- *
45
- * @example
46
- * ```typescript
47
- * const { data } = await ecod.crm.leads.create({
48
- * firstName: "Alice",
49
- * phone: "+919876543210",
50
- * });
51
- * ```
52
92
  */
53
93
  async create<T = any>(params: CreateLeadParams) {
54
94
  return this.post<T>("/api/services/leads", params);
55
95
  }
56
96
 
97
+ /**
98
+ * Upsert a lead by phone number. Creates if not exists, updates if exists.
99
+ *
100
+ * @param params - Upsert parameters containing leadData with a phone number.
101
+ * @returns The newly created or updated Lead document.
102
+ */
103
+ async upsert<T = any>(params: UpsertLeadParams) {
104
+ return this.post<T>("/api/services/leads/upsert", params);
105
+ }
106
+
57
107
  /**
58
108
  * Bulk ingest leads efficiently in parallel using automatic chunking.
59
109
  * Prevents rate limit exhaustion by executing `chunkSize` requests at a time.
@@ -83,38 +133,46 @@ export class Leads extends APIResource {
83
133
  return results;
84
134
  }
85
135
 
136
+ /**
137
+ * Bulk upsert (import) leads.
138
+ *
139
+ * @param leads - Array of leads to import.
140
+ */
141
+ async import<T = any>(leads: Partial<CreateLeadParams>[]) {
142
+ return this.post<T>("/api/services/leads/import", { leads });
143
+ }
144
+
86
145
  /**
87
146
  * List leads with optional filtering and pagination.
88
147
  *
89
148
  * @param params - Filter options (status, source, pipelineId, page, limit, etc.)
90
149
  * @returns Paginated list of Lead documents.
91
- *
92
- * @example
93
- * ```typescript
94
- * const { data } = await ecod.crm.leads.list({ status: "new", limit: 25 });
95
- * ```
96
150
  */
97
- async list<T = any>(params?: Record<string, any>) {
98
- return this.get<T>("/api/services/leads", { params } as any);
151
+ async list<T = any>(params?: ListLeadsParams) {
152
+ let queryParams = { ...params } as any;
153
+ if (Array.isArray(queryParams.tags)) {
154
+ queryParams.tags = queryParams.tags.join(",");
155
+ }
156
+ return this.get<T>("/api/services/leads", { params: queryParams } as any);
99
157
  }
100
158
 
101
159
  /**
102
160
  * Auto-paginating iterator for leads.
103
161
  * Seamlessly fetches leads page by page as you iterate.
104
- *
162
+ *
105
163
  * @example
106
164
  * ```typescript
107
- * for await (const lead of ecod.crm.leads.listAutoPaging({ status: "won" })) {
165
+ * for await (const lead of ecod.crm.leads.listAutoPaging<Lead>()) {
108
166
  * console.log(lead.firstName);
109
167
  * }
110
168
  * ```
111
169
  */
112
- async *listAutoPaging(params?: Record<string, any>): AsyncGenerator<any, void, unknown> {
170
+ async *listAutoPaging<T = any>(params?: ListLeadsParams): AsyncGenerator<T, void, unknown> {
113
171
  let currentPage = params?.page || 1;
114
172
  let hasMore = true;
115
173
 
116
174
  while (hasMore) {
117
- const response: any = await this.list({ ...params, page: currentPage });
175
+ const response: any = await this.list<any>({ ...params, page: currentPage });
118
176
 
119
177
  const items = Array.isArray(response.data) ? response.data : response || [];
120
178
 
@@ -124,7 +182,7 @@ export class Leads extends APIResource {
124
182
  }
125
183
 
126
184
  for (const item of items) {
127
- yield item;
185
+ yield item as T;
128
186
  }
129
187
 
130
188
  if (response.pagination && currentPage < response.pagination.pages) {
@@ -143,14 +201,29 @@ export class Leads extends APIResource {
143
201
  *
144
202
  * @param leadId - The MongoDB ObjectId of the lead.
145
203
  * @returns The Lead document, or a 404 error if not found.
204
+ */
205
+ async retrieve<T = any>(leadId: string) {
206
+ return this.get<T>(`/api/services/leads/${leadId}`);
207
+ }
208
+
209
+ /**
210
+ * Retrieve a single lead by its phone number.
146
211
  *
147
- * @example
148
- * ```typescript
149
- * const { data } = await ecod.crm.leads.retrieve("64abc...");
150
- * ```
212
+ * @param phone - Lead's phone number.
151
213
  */
152
- async retrieve(leadId: string) {
153
- return this.get(`/api/services/leads/${leadId}`);
214
+ async retrieveByPhone<T = any>(phone: string) {
215
+ // URL-encode the phone to handle '+' safe
216
+ return this.get<T>(`/api/services/leads/phone/${encodeURIComponent(phone)}`);
217
+ }
218
+
219
+ /**
220
+ * Retrieve a single lead by a reference key and value.
221
+ *
222
+ * @param refKey - Reference key metadata.
223
+ * @param refValue - Reference value.
224
+ */
225
+ async retrieveByRef<T = any>(refKey: string, refValue: string) {
226
+ return this.get<T>(`/api/services/leads/ref/${encodeURIComponent(refKey)}/${encodeURIComponent(refValue)}`);
154
227
  }
155
228
 
156
229
  /**
@@ -159,28 +232,83 @@ export class Leads extends APIResource {
159
232
  * @param leadId - The ID of the lead to update.
160
233
  * @param params - Partial lead fields to update.
161
234
  * @returns The updated Lead document.
162
- *
163
- * @example
164
- * ```typescript
165
- * await ecod.crm.leads.update("64abc...", { email: "new@email.com" });
166
- * ```
167
235
  */
168
- async update(leadId: string, params: Partial<CreateLeadParams>) {
169
- return this.post(`/api/services/leads/${leadId}`, params);
236
+ async update<T = any>(leadId: string, params: Partial<CreateLeadParams>) {
237
+ return this.post<T>(`/api/services/leads/${leadId}`, params);
238
+ }
239
+
240
+ /**
241
+ * Move a lead to a new stage in a pipeline.
242
+ *
243
+ * @param leadId - ID of the lead.
244
+ * @param stageId - Target stage ID.
245
+ */
246
+ async move<T = any>(leadId: string, stageId: string) {
247
+ return this.patch<T>(`/api/services/leads/${leadId}/move`, { stageId });
248
+ }
249
+
250
+ /**
251
+ * Convert a lead (mark as won or lost with reason).
252
+ *
253
+ * @param leadId - ID of the lead.
254
+ * @param outcome - "won" | "lost"
255
+ * @param reason - Reason for the outcome.
256
+ */
257
+ async convert<T = any>(leadId: string, outcome: "won" | "lost", reason?: string) {
258
+ return this.post<T>(`/api/services/leads/${leadId}/convert`, { outcome, reason });
259
+ }
260
+
261
+ /**
262
+ * Update the tags of a lead.
263
+ *
264
+ * @param leadId - ID of the lead.
265
+ * @param options - Tags to add or remove.
266
+ */
267
+ async tags<T = any>(leadId: string, options: { add?: string[]; remove?: string[] }) {
268
+ return this.patch<T>(`/api/services/leads/${leadId}/tags`, options);
170
269
  }
171
270
 
172
271
  /**
173
- * Archive (soft-delete) a lead. The record is retained in the database
174
- * for audit purposes but is excluded from all standard list views.
272
+ * Recalculate lead score based on activities and interactions.
273
+ *
274
+ * @param leadId - ID of the lead.
275
+ */
276
+ async recalculateScore<T = any>(leadId: string) {
277
+ return this.post<T>(`/api/services/leads/${leadId}/score`, {});
278
+ }
279
+
280
+ /**
281
+ * Update embedded metadata/references of a lead without touching core fields.
282
+ *
283
+ * @param leadId - ID of the lead.
284
+ * @param metadata - Metadata object indicating { refs, extra }
285
+ */
286
+ async updateMetadata<T = any>(leadId: string, metadata: { refs?: Record<string, any>; extra?: Record<string, any> }) {
287
+ return this.patch<T>(`/api/services/leads/${leadId}/metadata`, metadata);
288
+ }
289
+
290
+ /**
291
+ * Introspect available custom fields configured by the tenant limit.
292
+ */
293
+ async fields<T = any>() {
294
+ return this.get<T>("/api/services/leads/fields");
295
+ }
296
+
297
+ /**
298
+ * Archive (soft-delete) a single lead.
175
299
  *
176
300
  * @param leadId - The ID of the lead to archive.
177
- *
178
- * @example
179
- * ```typescript
180
- * await ecod.crm.leads.delete("64abc...");
181
- * ```
182
301
  */
183
302
  async delete(leadId: string) {
184
303
  return this.deleteRequest(`/api/services/leads/${leadId}`);
185
304
  }
305
+
306
+ /**
307
+ * Bulk archive multiple leads.
308
+ *
309
+ * @param ids - Array of lead IDs to archive.
310
+ */
311
+ async bulkDelete(ids: string[]) {
312
+ return this.deleteRequest("/api/services/leads", { data: { ids } });
313
+ }
186
314
  }
@@ -0,0 +1,10 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export class Payments extends APIResource {
4
+ /**
5
+ * Record an inbound payment against a lead or appointment.
6
+ */
7
+ async capture<T = any>(payload: { leadId: string; amount: number; currency?: string; description?: string; appointmentId?: string }) {
8
+ return this.post<T>("/api/saas/crm/payments/capture", payload);
9
+ }
10
+ }
@@ -0,0 +1,117 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export interface CreatePipelineParams {
4
+ name: string;
5
+ isDefault?: boolean;
6
+ stages?: any[]; // Typically an array of stage objects
7
+ }
8
+
9
+ export interface PipelineStageParams {
10
+ name: string;
11
+ color?: string;
12
+ probability?: number;
13
+ }
14
+
15
+ export class Pipelines extends APIResource {
16
+ /**
17
+ * List all pipelines matching the optional query parameters.
18
+ */
19
+ async list<T = any>(params?: Record<string, any>) {
20
+ return this.get<T>("/api/saas/crm/pipelines", { params } as any);
21
+ }
22
+
23
+ /**
24
+ * Create a new pipeline.
25
+ */
26
+ async create<T = any>(params: CreatePipelineParams) {
27
+ return this.post<T>("/api/saas/crm/pipelines", params);
28
+ }
29
+
30
+ /**
31
+ * Retrieve a single pipeline.
32
+ */
33
+ async retrieve<T = any>(pipelineId: string) {
34
+ return this.get<T>(`/api/saas/crm/pipelines/${pipelineId}`);
35
+ }
36
+
37
+ /**
38
+ * Update a pipeline's details.
39
+ */
40
+ async update<T = any>(pipelineId: string, params: { name?: string; description?: string }) {
41
+ return this.patch<T>(`/api/saas/crm/pipelines/${pipelineId}`, params);
42
+ }
43
+
44
+ /**
45
+ * Set pipeline as the tenant's default.
46
+ */
47
+ async setDefault<T = any>(pipelineId: string) {
48
+ return this.post<T>(`/api/saas/crm/pipelines/${pipelineId}/default`, {});
49
+ }
50
+
51
+ /**
52
+ * Duplicate a pipeline with a new name.
53
+ */
54
+ async duplicate<T = any>(pipelineId: string, newName: string) {
55
+ return this.post<T>(`/api/saas/crm/pipelines/${pipelineId}/duplicate`, { newName });
56
+ }
57
+
58
+ /**
59
+ * Archive a pipeline.
60
+ */
61
+ async archive<T = any>(pipelineId: string) {
62
+ return this.post<T>(`/api/saas/crm/pipelines/${pipelineId}/archive`, {});
63
+ }
64
+
65
+ /**
66
+ * Delete a pipeline permanently.
67
+ */
68
+ async delete(pipelineId: string) {
69
+ return this.deleteRequest(`/api/saas/crm/pipelines/${pipelineId}`);
70
+ }
71
+
72
+ /**
73
+ * Retrieve a Kanban-style board representation of the pipeline with leads nested.
74
+ */
75
+ async board<T = any>(pipelineId: string) {
76
+ return this.get<T>(`/api/saas/crm/pipelines/${pipelineId}/board`);
77
+ }
78
+
79
+ /**
80
+ * Retrieve a revenue forecast based on stage probabilities for a pipeline.
81
+ */
82
+ async forecast<T = any>(pipelineId: string) {
83
+ return this.get<T>(`/api/saas/crm/pipelines/${pipelineId}/forecast`);
84
+ }
85
+
86
+ // --- Stage Management ---
87
+
88
+ /**
89
+ * Add a new stage to the pipeline.
90
+ */
91
+ async addStage<T = any>(pipelineId: string, params: PipelineStageParams) {
92
+ return this.post<T>(`/api/saas/crm/pipelines/${pipelineId}/stages`, params);
93
+ }
94
+
95
+ /**
96
+ * Change the order of stages inside the pipeline.
97
+ */
98
+ async reorderStages<T = any>(pipelineId: string, orderArray: string[]) {
99
+ return this.put<T>(`/api/saas/crm/pipelines/${pipelineId}/stages/reorder`, { order: orderArray });
100
+ }
101
+
102
+ /**
103
+ * Update a specific stage.
104
+ */
105
+ async updateStage<T = any>(stageId: string, params: Partial<PipelineStageParams>) {
106
+ return this.patch<T>(`/api/saas/crm/stages/${stageId}`, params);
107
+ }
108
+
109
+ /**
110
+ * Delete a stage. Optionally provide a fallback stageId to move active leads to.
111
+ */
112
+ async deleteStage(stageId: string, moveLeadsToStageId?: string) {
113
+ return this.deleteRequest(`/api/saas/crm/stages/${stageId}`, {
114
+ data: moveLeadsToStageId ? { moveLeadsToStageId } : undefined,
115
+ });
116
+ }
117
+ }
@@ -0,0 +1,33 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export interface ScoringConfig {
4
+ decayDays: number;
5
+ thresholds: {
6
+ hot: number;
7
+ warm: number;
8
+ };
9
+ rules: any[]; // Specific rule shapes
10
+ }
11
+
12
+ export class Scoring extends APIResource {
13
+ /**
14
+ * Retrieve the tenant's global lead scoring configuration.
15
+ */
16
+ async getConfig<T = any>() {
17
+ return this.get<T>("/api/saas/crm/scoring");
18
+ }
19
+
20
+ /**
21
+ * Update scoring configuration.
22
+ */
23
+ async updateConfig<T = any>(payload: Partial<ScoringConfig>) {
24
+ return this.patch<T>("/api/saas/crm/scoring", payload as any);
25
+ }
26
+
27
+ /**
28
+ * Force recalculate the score for a specific lead.
29
+ */
30
+ async recalculate<T = any>(leadId: string) {
31
+ return this.post<T>(`/api/saas/crm/scoring/${leadId}/recalculate`, {});
32
+ }
33
+ }
@@ -0,0 +1,24 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export class Sequences extends APIResource {
4
+ /**
5
+ * Manually enroll a lead in a drip sequence (automation rule).
6
+ */
7
+ async enroll<T = any>(payload: { leadId: string; ruleId: string; variables?: Record<string, any> }) {
8
+ return this.post<T>("/api/saas/crm/sequences/enroll", payload);
9
+ }
10
+
11
+ /**
12
+ * Unenroll a lead from a running sequence.
13
+ */
14
+ async unenroll<T = any>(enrollmentId: string) {
15
+ return this.deleteRequest<T>(`/api/saas/crm/sequences/unenroll/${enrollmentId}`);
16
+ }
17
+
18
+ /**
19
+ * List active sequence enrollments for a specific lead.
20
+ */
21
+ async listForLead<T = any>(leadId: string) {
22
+ return this.get<T>(`/api/saas/crm/sequences/lead/${leadId}`);
23
+ }
24
+ }