@startanaicompany/crm 2.11.1 → 2.13.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/index.js +96 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -411,6 +411,22 @@ keysCmd
|
|
|
411
411
|
}
|
|
412
412
|
});
|
|
413
413
|
|
|
414
|
+
keysCmd
|
|
415
|
+
.command('set-scope <key-id>')
|
|
416
|
+
.description('Set the scope of an API key (admin only, feature 98b01015)')
|
|
417
|
+
.requiredOption('--scope <scope>', 'Scope: admin, standard, or agent')
|
|
418
|
+
.action(async (keyId, opts) => {
|
|
419
|
+
const globalOpts = program.opts();
|
|
420
|
+
const client = getClient(globalOpts);
|
|
421
|
+
try {
|
|
422
|
+
const res = await client.patch(`/keys/${keyId}/scope`, { scope: opts.scope });
|
|
423
|
+
console.log(`Key scope updated to: ${opts.scope}`);
|
|
424
|
+
printJSON(res.data);
|
|
425
|
+
} catch (err) {
|
|
426
|
+
handleError(err);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
414
430
|
// ============================================================
|
|
415
431
|
// LEADS COMMANDS
|
|
416
432
|
// ============================================================
|
|
@@ -2217,6 +2233,22 @@ contractsCmd
|
|
|
2217
2233
|
}
|
|
2218
2234
|
});
|
|
2219
2235
|
|
|
2236
|
+
contractsCmd
|
|
2237
|
+
.command('export-pdf <id>')
|
|
2238
|
+
.description('Export a contract as PDF blob and save to disk (Sprint 50 T1)')
|
|
2239
|
+
.requiredOption('--output <file>', 'Output file path (e.g. contract.pdf)')
|
|
2240
|
+
.action(async (id, opts) => {
|
|
2241
|
+
const globalOpts = program.opts();
|
|
2242
|
+
const client = getClient(globalOpts);
|
|
2243
|
+
try {
|
|
2244
|
+
const res = await client.post(`/contracts/${id}/export-pdf`, {}, { responseType: 'arraybuffer' });
|
|
2245
|
+
fs.writeFileSync(opts.output, Buffer.from(res.data));
|
|
2246
|
+
console.log(`PDF saved to ${opts.output} (${res.data.byteLength} bytes)`);
|
|
2247
|
+
} catch (err) {
|
|
2248
|
+
handleError(err);
|
|
2249
|
+
}
|
|
2250
|
+
});
|
|
2251
|
+
|
|
2220
2252
|
// ============================================================
|
|
2221
2253
|
// BUDGETS commands — Sprint 5
|
|
2222
2254
|
// ============================================================
|
|
@@ -2776,6 +2808,9 @@ analyticsCmd
|
|
|
2776
2808
|
console.log('\nStage Conversion Rates:');
|
|
2777
2809
|
Object.entries(d.stage_conversion_rates).forEach(([k, v]) => console.log(` ${k}: ${v}%`));
|
|
2778
2810
|
}
|
|
2811
|
+
// Sprint 50 T3: win rate (closed_won / (closed_won + closed_lost))
|
|
2812
|
+
if (d.win_rate != null) console.log(`\nWin Rate: ${d.win_rate}%`);
|
|
2813
|
+
else console.log('\nWin Rate: N/A (no closed deals yet)');
|
|
2779
2814
|
} catch (err) {
|
|
2780
2815
|
handleError(err);
|
|
2781
2816
|
}
|
|
@@ -3190,4 +3225,65 @@ sequencesCmd
|
|
|
3190
3225
|
} catch (err) { handleError(err); }
|
|
3191
3226
|
});
|
|
3192
3227
|
|
|
3228
|
+
// ============================================================
|
|
3229
|
+
// GDPR COMMANDS — Sprint 50 T2
|
|
3230
|
+
// ============================================================
|
|
3231
|
+
const gdprCmd = program.command('gdpr').description('GDPR data management — erase, export, and consent');
|
|
3232
|
+
|
|
3233
|
+
gdprCmd
|
|
3234
|
+
.command('erase <lead-id>')
|
|
3235
|
+
.description('Permanently erase a lead and all associated data (GDPR right to erasure). Requires admin scope key. IRREVERSIBLE.')
|
|
3236
|
+
.action(async (leadId) => {
|
|
3237
|
+
const globalOpts = program.opts();
|
|
3238
|
+
const client = getClient(globalOpts);
|
|
3239
|
+
try {
|
|
3240
|
+
const res = await client.delete(`/leads/${leadId}/erase`);
|
|
3241
|
+
console.log('Lead permanently erased.');
|
|
3242
|
+
printJSON(res.data);
|
|
3243
|
+
} catch (err) {
|
|
3244
|
+
handleError(err);
|
|
3245
|
+
}
|
|
3246
|
+
});
|
|
3247
|
+
|
|
3248
|
+
gdprCmd
|
|
3249
|
+
.command('export <lead-id>')
|
|
3250
|
+
.description('Export all personal data for a lead as JSON (GDPR data portability)')
|
|
3251
|
+
.option('--output <file>', 'Save JSON to this file path (default: gdpr-export-<id>.json)')
|
|
3252
|
+
.action(async (leadId, opts) => {
|
|
3253
|
+
const globalOpts = program.opts();
|
|
3254
|
+
const client = getClient(globalOpts);
|
|
3255
|
+
try {
|
|
3256
|
+
const res = await client.get(`/leads/${leadId}/gdpr-export`);
|
|
3257
|
+
const outFile = opts.output || `gdpr-export-${leadId}.json`;
|
|
3258
|
+
fs.writeFileSync(outFile, JSON.stringify(res.data, null, 2));
|
|
3259
|
+
console.log(`GDPR export saved to ${outFile}`);
|
|
3260
|
+
} catch (err) {
|
|
3261
|
+
handleError(err);
|
|
3262
|
+
}
|
|
3263
|
+
});
|
|
3264
|
+
|
|
3265
|
+
gdprCmd
|
|
3266
|
+
.command('consent <lead-id>')
|
|
3267
|
+
.description('Update consent settings for a lead')
|
|
3268
|
+
.option('--marketing <bool>', 'Marketing consent (true/false)')
|
|
3269
|
+
.option('--contacted <bool>', 'Contacted consent (true/false)')
|
|
3270
|
+
.action(async (leadId, opts) => {
|
|
3271
|
+
const globalOpts = program.opts();
|
|
3272
|
+
const client = getClient(globalOpts);
|
|
3273
|
+
try {
|
|
3274
|
+
const body = {};
|
|
3275
|
+
if (opts.marketing !== undefined) body.marketing = opts.marketing === 'true' || opts.marketing === true;
|
|
3276
|
+
if (opts.contacted !== undefined) body.contacted = opts.contacted === 'true' || opts.contacted === true;
|
|
3277
|
+
if (Object.keys(body).length === 0) {
|
|
3278
|
+
console.error('Error: at least one of --marketing or --contacted is required');
|
|
3279
|
+
process.exit(1);
|
|
3280
|
+
}
|
|
3281
|
+
const res = await client.patch(`/leads/${leadId}/consent`, body);
|
|
3282
|
+
console.log('Consent updated.');
|
|
3283
|
+
printJSON(res.data);
|
|
3284
|
+
} catch (err) {
|
|
3285
|
+
handleError(err);
|
|
3286
|
+
}
|
|
3287
|
+
});
|
|
3288
|
+
|
|
3193
3289
|
program.parse(process.argv);
|