@ecodrix/erix-api 1.0.0 → 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 (39) hide show
  1. package/README.md +32 -25
  2. package/dist/cli.js +38 -0
  3. package/dist/index.d.cts +1871 -0
  4. package/dist/index.d.ts +902 -42
  5. package/dist/ts/browser/index.global.js +14 -14
  6. package/dist/ts/browser/index.global.js.map +1 -1
  7. package/dist/ts/cjs/index.cjs +1 -1
  8. package/dist/ts/cjs/index.cjs.map +1 -1
  9. package/dist/ts/cjs/index.d.cts +902 -42
  10. package/dist/ts/esm/index.d.ts +902 -42
  11. package/dist/ts/esm/index.js +1 -1
  12. package/dist/ts/esm/index.js.map +1 -1
  13. package/package.json +7 -2
  14. package/src/cli.ts +318 -0
  15. package/src/core.ts +20 -0
  16. package/src/index.ts +17 -1
  17. package/src/resource.ts +44 -5
  18. package/src/resources/crm/activities.ts +89 -0
  19. package/src/resources/crm/analytics.ts +89 -0
  20. package/src/resources/crm/automationDashboard.ts +24 -0
  21. package/src/resources/crm/automations.ts +145 -0
  22. package/src/resources/crm/index.ts +24 -0
  23. package/src/resources/crm/leads.ts +170 -42
  24. package/src/resources/crm/payments.ts +10 -0
  25. package/src/resources/crm/pipelines.ts +117 -0
  26. package/src/resources/crm/scoring.ts +33 -0
  27. package/src/resources/crm/sequences.ts +24 -0
  28. package/src/resources/events.ts +41 -0
  29. package/src/resources/health.ts +61 -0
  30. package/src/resources/marketing.ts +104 -0
  31. package/src/resources/meet.ts +9 -2
  32. package/src/resources/notifications.ts +30 -0
  33. package/src/resources/queue.ts +39 -0
  34. package/src/resources/storage.ts +72 -0
  35. package/src/resources/whatsapp/broadcasts.ts +31 -0
  36. package/src/resources/whatsapp/conversations.ts +34 -9
  37. package/src/resources/whatsapp/index.ts +20 -0
  38. package/src/resources/whatsapp/messages.ts +24 -0
  39. package/src/resources/whatsapp/templates.ts +99 -0
package/src/cli.ts ADDED
@@ -0,0 +1,318 @@
1
+ import { Command } from "commander";
2
+ import dotenv from "dotenv";
3
+ import pc from "picocolors";
4
+ import repl from "node:repl";
5
+ import { Ecodrix } from "./core";
6
+
7
+ // Setup environment
8
+ dotenv.config();
9
+
10
+ // Build-time constants injected by tsup
11
+ declare const process: any;
12
+ const VERSION = process.env.SDK_VERSION || "1.0.2";
13
+ const NAME = process.env.SDK_NAME || "@ecodrix/erix-api";
14
+ const DESCRIPTION = process.env.SDK_DESCRIPTION || "Official ECODrIx SDK CLI";
15
+
16
+ const program = new Command();
17
+
18
+ program.name("erix").description(DESCRIPTION).version(VERSION);
19
+
20
+ /**
21
+ * Helper to initialize the Ecodrix client from environment or flags.
22
+ */
23
+ function getClient(options: any): Ecodrix {
24
+ const apiKey = options.key || process.env.ECOD_API_KEY;
25
+ const clientCode = options.client || process.env.ECOD_CLIENT_CODE;
26
+
27
+ if (!apiKey) {
28
+ console.error(pc.red("Error: API Key is missing."));
29
+ console.log(
30
+ pc.yellow("Set ECOD_API_KEY environment variable or use --key <key>"),
31
+ );
32
+ process.exit(1);
33
+ }
34
+
35
+ return new Ecodrix({
36
+ apiKey,
37
+ clientCode,
38
+ baseUrl: options.baseUrl || process.env.ECOD_BASE_URL,
39
+ });
40
+ }
41
+
42
+ program
43
+ .option("-k, --key <key>", "ECODrIx API Key")
44
+ .option("-c, --client <code...", "Tenant Client Code")
45
+ .option("--base-url <url>", "API Base URL override");
46
+
47
+ // --- WHOAMI ---
48
+ program
49
+ .command("whoami")
50
+ .description("Verify current authentication and tenant status")
51
+ .action(async (options, command) => {
52
+ const globalOptions = command.parent.opts();
53
+ const ecod = getClient(globalOptions);
54
+
55
+ console.log(pc.cyan("Checking connection to ECODrIx Platform..."));
56
+ try {
57
+ const me = (await ecod.request("GET", "/api/saas/me/profile")) as any;
58
+ console.log(pc.green("✔ Authenticated successfully!"));
59
+ console.log(`${pc.bold("User ID:")} ${me.id}`);
60
+ console.log(
61
+ `${pc.bold("Organisation:")} ${me.organisation?.name || "N/A"}`,
62
+ );
63
+ if (globalOptions.client) {
64
+ console.log(
65
+ `${pc.bold("Tenant Code:")} ${pc.magenta(globalOptions.client)}`,
66
+ );
67
+ }
68
+ } catch (error: any) {
69
+ console.error(pc.red("✖ Authentication failed"));
70
+ console.error(pc.dim(error.message));
71
+ process.exit(1);
72
+ }
73
+ });
74
+
75
+ // --- WHATSAPP ---
76
+ const whatsapp = program
77
+ .command("whatsapp")
78
+ .description("WhatsApp Business API operations");
79
+
80
+ whatsapp
81
+ .command("send-template")
82
+ .description("Send a WhatsApp template message")
83
+ .argument("<phone>", "Recipient phone number")
84
+ .argument("<template>", "Template name")
85
+ .option("-v, --vars <json>", "Template variables as JSON string", "[]")
86
+ .action(async (phone, template, options, command) => {
87
+ const globalOptions = command.parent.parent.opts();
88
+ const ecod = getClient(globalOptions);
89
+
90
+ try {
91
+ const vars = JSON.parse(options.vars);
92
+ console.log(pc.cyan(`Sending template '${template}' to ${phone}...`));
93
+
94
+ const result = (await ecod.whatsapp.messages.sendTemplate({
95
+ to: phone,
96
+ templateName: template,
97
+ language: "en_US",
98
+ variables: vars,
99
+ })) as any;
100
+
101
+ console.log(pc.green("✔ Message sent successfully!"));
102
+ console.log(pc.dim(`ID: ${result?.id || "N/A"}`));
103
+ } catch (error: any) {
104
+ console.error(pc.red("✖ Failed to send message"));
105
+ console.error(pc.dim(error.message));
106
+ }
107
+ });
108
+
109
+ // --- CRM ---
110
+ const crm = program.command("crm").description("CRM and Lead management");
111
+
112
+ crm
113
+ .command("leads")
114
+ .description("List recent leads")
115
+ .option("-l, --limit <number>", "Number of leads to fetch", "10")
116
+ .option("-s, --status <status>", "Filter by lead status")
117
+ .option("-p, --pipeline <id>", "Filter by pipeline ID")
118
+ .option("-q, --search <query>", "Search by name or email")
119
+ .action(async (options, command) => {
120
+ const globalOptions = command.parent.parent.opts();
121
+ const ecod = getClient(globalOptions);
122
+
123
+ try {
124
+ const limit = parseInt(options.limit);
125
+ console.log(pc.cyan(`Fetching last ${limit} leads...`));
126
+
127
+ const queryParams: any = { limit };
128
+ if (options.status) queryParams.status = options.status;
129
+ if (options.pipeline) queryParams.pipelineId = options.pipeline;
130
+ if (options.search) queryParams.search = options.search;
131
+
132
+ const response: any = await ecod.crm.leads.list(queryParams);
133
+ const leads = Array.isArray(response.data)
134
+ ? response.data
135
+ : Array.isArray(response)
136
+ ? response
137
+ : [];
138
+
139
+ if (leads.length === 0) {
140
+ console.log(pc.yellow("No leads found."));
141
+ return;
142
+ }
143
+
144
+ console.table(
145
+ leads.map((l: any) => ({
146
+ ID: l.id || l._id,
147
+ Name: `${l.firstName} ${l.lastName || ""}`.trim(),
148
+ Phone: l.phone,
149
+ Status: l.status,
150
+ Score: l.score || 0,
151
+ Created: new Date(l.createdAt).toLocaleDateString(),
152
+ })),
153
+ );
154
+ } catch (error: any) {
155
+ console.error(pc.red("✖ Failed to fetch leads"));
156
+ console.error(pc.dim(error.message));
157
+ }
158
+ });
159
+
160
+ crm
161
+ .command("pipelines")
162
+ .description("List all CRM pipelines")
163
+ .action(async (options, command) => {
164
+ const globalOptions = command.parent.parent.opts();
165
+ const ecod = getClient(globalOptions);
166
+
167
+ try {
168
+ console.log(pc.cyan("Fetching pipelines..."));
169
+ const response: any = await ecod.crm.pipelines.list();
170
+ const pipelines = response.data || response || [];
171
+
172
+ if (pipelines.length === 0) {
173
+ console.log(pc.yellow("No pipelines found."));
174
+ return;
175
+ }
176
+
177
+ console.table(
178
+ pipelines.map((p: any) => ({
179
+ ID: p.id || p._id,
180
+ Name: p.name,
181
+ Default: p.isDefault ? "Yes" : "No",
182
+ Stages: p.stages?.length || 0
183
+ })),
184
+ );
185
+ } catch (error: any) {
186
+ console.error(pc.red("✖ Failed to fetch pipelines"));
187
+ console.error(pc.dim(error.message));
188
+ }
189
+ });
190
+
191
+ // --- ANALYTICS ---
192
+ const analytics = program.command("analytics").description("Business Intelligence Analytics");
193
+
194
+ analytics
195
+ .command("overview")
196
+ .description("Get high-level CRM KPIs")
197
+ .option("-r, --range <range>", "Date range (e.g., 24h, 7d, 30d, 365d)", "30d")
198
+ .action(async (options, command) => {
199
+ const globalOptions = command.parent.parent.opts();
200
+ const ecod = getClient(globalOptions);
201
+
202
+ try {
203
+ console.log(pc.cyan(`Fetching overview metrics for last ${options.range}...`));
204
+ const response: any = await ecod.crm.analytics.overview({ range: options.range });
205
+ const data = response.data || response;
206
+
207
+ console.log("\n" + pc.bold("OVERVIEW KPIs:"));
208
+ console.log(`Total Leads: ${pc.green(data.totalLeads || 0)}`);
209
+ console.log(`Open Value: ${pc.yellow("$" + (data.openValue || 0).toLocaleString())}`);
210
+ console.log(`Won Revenue: ${pc.green("$" + (data.wonRevenue || 0).toLocaleString())}`);
211
+ console.log(`Avg Score: ${pc.blue(data.avgScore?.toFixed(1) || 0)}`);
212
+ console.log(`Conversion: ${pc.magenta((data.conversionRate || 0).toFixed(2) + "%")}\n`);
213
+
214
+ } catch (error: any) {
215
+ console.error(pc.red("✖ Failed to fetch analytics overview"));
216
+ console.error(pc.dim(error.message));
217
+ }
218
+ });
219
+
220
+ // --- WEBHOOKS ---
221
+ const webhooks = program
222
+ .command("webhooks")
223
+ .description("Webhook utility tools");
224
+
225
+ webhooks
226
+ .command("verify")
227
+ .description("Verify a cryptographic webhook signature")
228
+ .argument("<payload>", "The raw request body string")
229
+ .argument("<signature>", "The 'x-ecodrix-signature' header value")
230
+ .argument("<secret>", "Your webhook signing secret")
231
+ .action(async (payload, signature, secret, options, command) => {
232
+ const globalOptions = command.parent.parent.opts();
233
+ const ecod = getClient(globalOptions);
234
+
235
+ try {
236
+ await ecod.webhooks.constructEvent(payload, signature, secret);
237
+ console.log(pc.green("✔ Signature is VALID"));
238
+ } catch (error: any) {
239
+ console.error(pc.red("✖ Error during verification"));
240
+ console.error(pc.dim(error.message));
241
+ }
242
+ });
243
+
244
+ // --- SHELL (REPL) ---
245
+ program
246
+ .command("shell")
247
+ .alias("repl")
248
+ .description("Start an interactive SDK shell")
249
+ .action(async (options, command) => {
250
+ const globalOptions = command.parent.opts();
251
+ const ecod = getClient(globalOptions);
252
+
253
+ console.log(pc.magenta(pc.bold("\nWelcome to the Erix Interactive Shell")));
254
+ console.log(pc.dim(`SDK Version: ${VERSION}`));
255
+ console.log(pc.dim("The 'ecod' client is pre-initialized and ready.\n"));
256
+
257
+ const r = repl.start({
258
+ prompt: pc.cyan("erix > "),
259
+ useColors: true,
260
+ });
261
+
262
+ // Load resources into REPL context for immediate access
263
+ r.context.ecod = ecod;
264
+ r.context.whatsapp = ecod.whatsapp;
265
+ r.context.crm = ecod.crm;
266
+ r.context.meet = ecod.meet;
267
+ r.context.media = ecod.media;
268
+
269
+ r.on("exit", () => {
270
+ console.log(pc.yellow("\nGoodbye!"));
271
+ process.exit(0);
272
+ });
273
+ });
274
+
275
+ // --- COMPLETION ---
276
+ program
277
+ .command("completion")
278
+ .description("Generate Bash auto-completion script")
279
+ .action(() => {
280
+ const script = `
281
+ # Erix Bash Completion
282
+ _erix_completions() {
283
+ local cur opts
284
+ COMPREPLY=()
285
+ cur="\${COMP_WORDS[COMP_CWORD]}"
286
+ opts="whoami whatsapp crm analytics webhooks shell completion"
287
+
288
+ if [[ \${COMP_CWORD} -eq 1 ]] ; then
289
+ COMPREPLY=( \$(compgen -W "\${opts}" -- \${cur}) )
290
+ return 0
291
+ fi
292
+
293
+ # Simple sub-command completion
294
+ case "\${COMP_WORDS[1]}" in
295
+ whatsapp)
296
+ COMPREPLY=( \$(compgen -W "send-template" -- \${cur}) )
297
+ ;;
298
+ crm)
299
+ COMPREPLY=( \$(compgen -W "leads pipelines" -- \${cur}) )
300
+ ;;
301
+ analytics)
302
+ COMPREPLY=( \$(compgen -W "overview" -- \${cur}) )
303
+ ;;
304
+ webhooks)
305
+ COMPREPLY=( \$(compgen -W "verify" -- \${cur}) )
306
+ ;;
307
+ esac
308
+ }
309
+ complete -F _erix_completions erix
310
+ `;
311
+ console.log(script.trim());
312
+ console.error(pc.yellow('\n# To enable, run: eval "$(erix completion)"'));
313
+ console.error(
314
+ pc.dim("# Or add it to your ~/.bashrc: erix completion >> ~/.bashrc"),
315
+ );
316
+ });
317
+
318
+ program.parse();
package/src/core.ts CHANGED
@@ -9,6 +9,10 @@ import { Notifications } from "./resources/notifications";
9
9
  import { EmailResource } from "./resources/email";
10
10
  import { EventsResource } from "./resources/events";
11
11
  import { Webhooks } from "./resources/webhooks";
12
+ import { Storage } from "./resources/storage";
13
+ import { Marketing } from "./resources/marketing";
14
+ import { Health } from "./resources/health";
15
+ import { Queue } from "./resources/queue";
12
16
  import { io, type Socket } from "socket.io-client";
13
17
 
14
18
  declare const process: any;
@@ -94,6 +98,18 @@ export class Ecodrix {
94
98
  /** Cryptographic webhook signature verification. */
95
99
  public readonly webhooks: Webhooks;
96
100
 
101
+ /** Tenant Cloud Storage mapping. */
102
+ public readonly storage: Storage;
103
+
104
+ /** Email and SMS Marketing Campaigns. */
105
+ public readonly marketing: Marketing;
106
+
107
+ /** Platform and tenant health diagnostics. */
108
+ public readonly health: Health;
109
+
110
+ /** Background job queue management. */
111
+ public readonly queue: Queue;
112
+
97
113
  constructor(options: EcodrixOptions) {
98
114
  if (!options.apiKey) {
99
115
  throw new AuthenticationError("API Key is required");
@@ -151,6 +167,10 @@ export class Ecodrix {
151
167
  this.email = new EmailResource(this.client);
152
168
  this.events = new EventsResource(this.client);
153
169
  this.webhooks = new Webhooks();
170
+ this.storage = new Storage(this.client);
171
+ this.marketing = new Marketing(this.client);
172
+ this.health = new Health(this.client);
173
+ this.queue = new Queue(this.client);
154
174
 
155
175
  // Establish persistent Socket.io connection
156
176
  this.socket = io(socketUrl, {
package/src/index.ts CHANGED
@@ -2,16 +2,32 @@ export { Ecodrix, type EcodrixOptions } from "./core";
2
2
  export * from "./error";
3
3
 
4
4
  // Resource Type Exports
5
+ export * from "./resources/whatsapp/index";
5
6
  export * from "./resources/whatsapp/messages";
6
7
  export * from "./resources/whatsapp/conversations";
7
- export * from "./resources/whatsapp/index";
8
+ export * from "./resources/whatsapp/templates";
9
+ export * from "./resources/whatsapp/broadcasts";
10
+
11
+ export * from "./resources/crm/index";
8
12
  export * from "./resources/crm/leads";
13
+ export * from "./resources/crm/automations";
14
+ export * from "./resources/crm/pipelines";
15
+ export * from "./resources/crm/activities";
16
+ export * from "./resources/crm/analytics";
17
+ export * from "./resources/crm/sequences";
18
+ export * from "./resources/crm/scoring";
19
+ export * from "./resources/crm/payments";
20
+ export * from "./resources/crm/automationDashboard";
9
21
  export * from "./resources/meet";
10
22
  export * from "./resources/media";
11
23
  export * from "./resources/notifications";
12
24
  export * from "./resources/email";
13
25
  export * from "./resources/events";
14
26
  export * from "./resources/webhooks";
27
+ export * from "./resources/storage";
28
+ export * from "./resources/marketing";
29
+ export * from "./resources/health";
30
+ export * from "./resources/queue";
15
31
 
16
32
  // Export the main client also as default for better ergonomics
17
33
  import { Ecodrix } from "./core";
package/src/resource.ts CHANGED
@@ -17,7 +17,11 @@ export interface RequestOptions extends AxiosRequestConfig {
17
17
  export abstract class APIResource {
18
18
  public constructor(protected readonly client: AxiosInstance) {}
19
19
 
20
- protected async post<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
20
+ protected async post<T>(
21
+ url: string,
22
+ data?: any,
23
+ options?: RequestOptions,
24
+ ): Promise<T> {
21
25
  try {
22
26
  const config = this.buildConfig(options);
23
27
  const response = await this.client.post(url, data, config);
@@ -37,7 +41,38 @@ export abstract class APIResource {
37
41
  }
38
42
  }
39
43
 
40
- protected async deleteRequest<T>(url: string, options?: RequestOptions): Promise<T> {
44
+ protected async patch<T>(
45
+ url: string,
46
+ data?: any,
47
+ options?: RequestOptions,
48
+ ): Promise<T> {
49
+ try {
50
+ const config = this.buildConfig(options);
51
+ const response = await this.client.patch(url, data, config);
52
+ return response.data;
53
+ } catch (error: any) {
54
+ this.handleError(error);
55
+ }
56
+ }
57
+
58
+ protected async put<T>(
59
+ url: string,
60
+ data?: any,
61
+ options?: RequestOptions,
62
+ ): Promise<T> {
63
+ try {
64
+ const config = this.buildConfig(options);
65
+ const response = await this.client.put(url, data, config);
66
+ return response.data;
67
+ } catch (error: any) {
68
+ this.handleError(error);
69
+ }
70
+ }
71
+
72
+ protected async deleteRequest<T>(
73
+ url: string,
74
+ options?: RequestOptions,
75
+ ): Promise<T> {
41
76
  try {
42
77
  const config = this.buildConfig(options);
43
78
  const response = await this.client.delete(url, config);
@@ -47,7 +82,9 @@ export abstract class APIResource {
47
82
  }
48
83
  }
49
84
 
50
- private buildConfig(options?: RequestOptions): AxiosRequestConfig | undefined {
85
+ private buildConfig(
86
+ options?: RequestOptions,
87
+ ): AxiosRequestConfig | undefined {
51
88
  if (!options) return undefined;
52
89
 
53
90
  const config: AxiosRequestConfig = { ...options };
@@ -63,9 +100,11 @@ export abstract class APIResource {
63
100
  private handleError(error: any): never {
64
101
  if (error.response) {
65
102
  throw new APIError(
66
- error.response.data?.message || error.response.data?.error || "API Request Failed",
103
+ error.response.data?.message ||
104
+ error.response.data?.error ||
105
+ "API Request Failed",
67
106
  error.response.status,
68
- error.response.data?.code
107
+ error.response.data?.code,
69
108
  );
70
109
  }
71
110
  throw new APIError(error.message || "Network Error");
@@ -0,0 +1,89 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export interface LogActivityParams {
4
+ leadId: string;
5
+ type: "note" | "call" | "email" | "meeting" | "whatsapp" | "system";
6
+ title: string;
7
+ body?: string;
8
+ metadata?: Record<string, any>;
9
+ }
10
+
11
+ export interface LogCallParams {
12
+ durationMinutes: number;
13
+ summary: string;
14
+ outcome: "answered" | "no_answer" | "busy" | "voicemail" | "wrong_number";
15
+ }
16
+
17
+ export class Notes extends APIResource {
18
+ /**
19
+ * List all notes for a specific lead.
20
+ */
21
+ async list<T = any>(leadId: string) {
22
+ return this.get<T>(`/api/saas/crm/leads/${leadId}/notes`);
23
+ }
24
+
25
+ /**
26
+ * Add a note to a lead.
27
+ */
28
+ async create<T = any>(leadId: string, params: { content: string }) {
29
+ return this.post<T>(`/api/saas/crm/leads/${leadId}/notes`, params);
30
+ }
31
+
32
+ /**
33
+ * Update an existing note.
34
+ */
35
+ async update<T = any>(noteId: string, content: string) {
36
+ return this.patch<T>(`/api/saas/crm/notes/${noteId}`, { content });
37
+ }
38
+
39
+ /**
40
+ * Pin or unpin a note to the top of the feed.
41
+ */
42
+ async pin<T = any>(noteId: string, isPinned = true) {
43
+ return this.patch<T>(`/api/saas/crm/notes/${noteId}/pin`, { isPinned });
44
+ }
45
+
46
+ /**
47
+ * Delete a note.
48
+ */
49
+ async delete(noteId: string) {
50
+ return this.deleteRequest(`/api/saas/crm/notes/${noteId}`);
51
+ }
52
+ }
53
+
54
+ export class Activities extends APIResource {
55
+ public notes: Notes;
56
+
57
+ constructor(client: any) {
58
+ super(client);
59
+ this.notes = new Notes(client);
60
+ }
61
+
62
+ /**
63
+ * Retrieve the complete chronological timeline for a lead.
64
+ */
65
+ async timeline<T = any>(leadId: string, params?: { page?: number; limit?: number }) {
66
+ return this.get<T>(`/api/saas/crm/leads/${leadId}/timeline`, { params } as any);
67
+ }
68
+
69
+ /**
70
+ * List specific activities (filtered by type).
71
+ */
72
+ async list<T = any>(leadId: string, params?: { type?: string; page?: number; limit?: number }) {
73
+ return this.get<T>(`/api/saas/crm/activities`, { params: { leadId, ...params } } as any);
74
+ }
75
+
76
+ /**
77
+ * Generic method to log a business activity/event.
78
+ */
79
+ async log<T = any>(params: LogActivityParams) {
80
+ return this.post<T>("/api/saas/crm/activities", params);
81
+ }
82
+
83
+ /**
84
+ * Specific method to log communication outcomes.
85
+ */
86
+ async logCall<T = any>(leadId: string, params: LogCallParams) {
87
+ return this.post<T>(`/api/saas/crm/leads/${leadId}/calls`, params);
88
+ }
89
+ }
@@ -0,0 +1,89 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export type AnalyticsRange = "24h" | "7d" | "30d" | "60d" | "90d" | "365d";
4
+
5
+ export interface AnalyticsParams {
6
+ range?: AnalyticsRange;
7
+ from?: string;
8
+ to?: string;
9
+ pipelineId?: string;
10
+ }
11
+
12
+ export class Analytics extends APIResource {
13
+ /**
14
+ * KPIs: total leads, pipeline value, won revenue, avg score, conversion rate.
15
+ */
16
+ async overview<T = any>(params?: AnalyticsParams) {
17
+ return this.get<T>("/api/saas/crm/analytics/overview", { params } as any);
18
+ }
19
+
20
+ /**
21
+ * Stage-by-stage lead counts and conversion percentages.
22
+ */
23
+ async funnel<T = any>(pipelineId: string) {
24
+ return this.get<T>("/api/saas/crm/analytics/funnel", { params: { pipelineId } } as any);
25
+ }
26
+
27
+ /**
28
+ * Revenue forecast: deal value × stage probability.
29
+ */
30
+ async forecast<T = any>(pipelineId?: string) {
31
+ return this.get<T>("/api/saas/crm/analytics/forecast", { params: { pipelineId } } as any);
32
+ }
33
+
34
+ /**
35
+ * Lead source breakdown: count, conversion rate, total value per source.
36
+ */
37
+ async sources<T = any>(params?: AnalyticsParams) {
38
+ return this.get<T>("/api/saas/crm/analytics/sources", { params } as any);
39
+ }
40
+
41
+ /**
42
+ * Team leaderboard: won deals, revenue, activity count, conversion rate per member.
43
+ */
44
+ async team<T = any>(params?: AnalyticsParams) {
45
+ return this.get<T>("/api/saas/crm/analytics/team", { params } as any);
46
+ }
47
+
48
+ /**
49
+ * Daily activity counts by type. For activity calendar.
50
+ */
51
+ async heatmap<T = any>(params?: AnalyticsParams) {
52
+ return this.get<T>("/api/saas/crm/analytics/heatmap", { params } as any);
53
+ }
54
+
55
+ /**
56
+ * Score distribution: how many leads in each score bucket.
57
+ */
58
+ async scores<T = any>() {
59
+ return this.get<T>("/api/saas/crm/analytics/scores");
60
+ }
61
+
62
+ /**
63
+ * Avg time leads spend in each stage. Helps find bottlenecks.
64
+ */
65
+ async stageTime<T = any>(pipelineId: string) {
66
+ return this.get<T>("/api/saas/crm/analytics/stage-time", { params: { pipelineId } } as any);
67
+ }
68
+
69
+ /**
70
+ * Tiered Growth Report matching business sophistication.
71
+ */
72
+ async tiered<T = any>(params?: AnalyticsParams) {
73
+ return this.get<T>("/api/saas/crm/analytics/tiered", { params } as any);
74
+ }
75
+
76
+ /**
77
+ * Consolidated analytics including CRM overview and WhatsApp.
78
+ */
79
+ async summary<T = any>(params?: AnalyticsParams) {
80
+ return this.get<T>("/api/saas/crm/analytics/summary", { params } as any);
81
+ }
82
+
83
+ /**
84
+ * WhatsApp volume and delivery analytics.
85
+ */
86
+ async whatsapp<T = any>(params?: AnalyticsParams) {
87
+ return this.get<T>("/api/saas/crm/analytics/whatsapp", { params } as any);
88
+ }
89
+ }
@@ -0,0 +1,24 @@
1
+ import { APIResource } from "../../resource";
2
+
3
+ export class AutomationDashboard extends APIResource {
4
+ /**
5
+ * Retrieve summary statistics for automation health.
6
+ */
7
+ async stats<T = any>() {
8
+ return this.get<T>("/api/saas/crm/automation/stats");
9
+ }
10
+
11
+ /**
12
+ * List recent EventLog entries (automation logs).
13
+ */
14
+ async logs<T = any>(params?: { limit?: number; status?: string }) {
15
+ return this.get<T>("/api/saas/crm/automation/logs", { params } as any);
16
+ }
17
+
18
+ /**
19
+ * Re-emit a failed event log to process its automations again.
20
+ */
21
+ async retryFailedEvent<T = any>(logId: string) {
22
+ return this.post<T>(`/api/saas/crm/automation/logs/${logId}/retry`, {});
23
+ }
24
+ }