@happyvertical/smrt-sales 0.55.0 → 0.55.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/AGENTS.md +1 -1
- package/README.md +6 -3
- package/agents/crm.md +9 -2
- package/dist/agreements.js +1 -1
- package/dist/chunks/{__smrt-register__-B51ohBYo.js → __smrt-register__-CJ2_r5s0.js} +2 -2
- package/dist/chunks/{__smrt-register__-B51ohBYo.js.map → __smrt-register__-CJ2_r5s0.js.map} +1 -1
- package/dist/chunks/{crm-DfRKKvWV.js → crm-B-irXbbr.js} +55 -1
- package/dist/chunks/crm-B-irXbbr.js.map +1 -0
- package/dist/commissions.js +1 -1
- package/dist/crm/index.d.ts +1 -1
- package/dist/crm/index.d.ts.map +1 -1
- package/dist/crm/services/LeadWorkflowService.d.ts +18 -1
- package/dist/crm/services/LeadWorkflowService.d.ts.map +1 -1
- package/dist/crm.js +2 -2
- package/dist/index.js +2 -2
- package/dist/manifest.json +1 -1
- package/dist/referrals.js +1 -1
- package/dist/smrt-knowledge.json +7 -7
- package/package.json +6 -6
- package/dist/chunks/crm-DfRKKvWV.js.map +0 -1
|
@@ -1888,6 +1888,7 @@ var LeadWorkflowService = class LeadWorkflowService {
|
|
|
1888
1888
|
contactName: normalized.contactName,
|
|
1889
1889
|
phone: normalized.phone,
|
|
1890
1890
|
organizationName: normalized.organizationName,
|
|
1891
|
+
...normalized.profileId ? { profileId: normalized.profileId } : {},
|
|
1891
1892
|
sourceKind: normalized.sourceKind,
|
|
1892
1893
|
sourceId: normalized.sourceId,
|
|
1893
1894
|
acquisitionContext: stableStringify(normalized.acquisitionContext),
|
|
@@ -1967,6 +1968,44 @@ var LeadWorkflowService = class LeadWorkflowService {
|
|
|
1967
1968
|
created: result.created
|
|
1968
1969
|
};
|
|
1969
1970
|
}
|
|
1971
|
+
/** Move an open Opportunity between nonterminal stages in one transaction. */
|
|
1972
|
+
async moveOpportunityToStage(input) {
|
|
1973
|
+
const actorProfileId = this.requireIdentifier(input.actorProfileId, "actorProfileId");
|
|
1974
|
+
if (!UUID_RE.test(input.opportunityId)) throw this.refusal("opportunity_unavailable", "Opportunity is unavailable in the active tenant");
|
|
1975
|
+
if (!UUID_RE.test(input.stageId)) throw this.refusal("stage_unavailable", "Opportunity stage is unavailable in the active tenant");
|
|
1976
|
+
if (input.probabilityOverride !== void 0 && (!Number.isFinite(input.probabilityOverride) || input.probabilityOverride < 0 || input.probabilityOverride > 1)) throw this.refusal("invalid_value", "Opportunity probability must be between 0 and 1");
|
|
1977
|
+
const tenantId = this.requireActiveTenant();
|
|
1978
|
+
const result = await this.runMutation(async (deps, activeTenantId) => {
|
|
1979
|
+
const opportunity = await this.lockOpportunity(deps, input.opportunityId, activeTenantId);
|
|
1980
|
+
if (opportunity.status !== "open") throw this.refusal("invalid_transition", `Opportunity cannot move stages while '${opportunity.status}'`);
|
|
1981
|
+
const stage = await this.lockPipelineStage(deps, input.stageId, activeTenantId);
|
|
1982
|
+
if (!stage || stage.tenantId !== activeTenantId || stage.pipelineId !== opportunity.pipelineId) throw this.refusal("stage_unavailable", "Opportunity stage is unavailable in the active tenant and pipeline");
|
|
1983
|
+
if (stage.isWon || stage.isLost) throw this.refusal("invalid_transition", "Terminal Opportunity stages must use closeOpportunity()");
|
|
1984
|
+
const probability = input.probabilityOverride ?? stage.probability;
|
|
1985
|
+
if (opportunity.stageId === input.stageId) {
|
|
1986
|
+
if (opportunity.probability !== probability) throw this.refusal("opportunity_replay_conflict", "Opportunity is already at this stage with a different probability");
|
|
1987
|
+
return {
|
|
1988
|
+
opportunityId: input.opportunityId,
|
|
1989
|
+
changed: false
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
await deps.opportunities.moveToStage({
|
|
1993
|
+
opportunityId: input.opportunityId,
|
|
1994
|
+
stageId: input.stageId,
|
|
1995
|
+
actorProfileId,
|
|
1996
|
+
probabilityOverride: input.probabilityOverride,
|
|
1997
|
+
now: input.now
|
|
1998
|
+
});
|
|
1999
|
+
return {
|
|
2000
|
+
opportunityId: input.opportunityId,
|
|
2001
|
+
changed: true
|
|
2002
|
+
};
|
|
2003
|
+
});
|
|
2004
|
+
return {
|
|
2005
|
+
opportunity: await this.readOpportunity(result.opportunityId, tenantId),
|
|
2006
|
+
changed: result.changed
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
1970
2009
|
/** Close an opportunity at its configured terminal stage and optionally link conversion. */
|
|
1971
2010
|
async closeOpportunity(input) {
|
|
1972
2011
|
const actorProfileId = this.requireIdentifier(input.actorProfileId, "actorProfileId");
|
|
@@ -2308,6 +2347,18 @@ var LeadWorkflowService = class LeadWorkflowService {
|
|
|
2308
2347
|
}
|
|
2309
2348
|
return await this.readOpportunityFrom(deps.opportunities, opportunityId, tenantId);
|
|
2310
2349
|
}
|
|
2350
|
+
async lockPipelineStage(deps, stageId, tenantId) {
|
|
2351
|
+
if (deps.supportsRowLocks) {
|
|
2352
|
+
const stage2 = (await deps.stages.query(`SELECT * FROM ${deps.stages.tableName}
|
|
2353
|
+
WHERE id = $1 AND tenant_id = $2
|
|
2354
|
+
FOR UPDATE`, [stageId, tenantId], { allowRawOnTenantScoped: true }))[0];
|
|
2355
|
+
if (stage2 && stage2.tenantId === tenantId) return stage2;
|
|
2356
|
+
throw this.refusal("stage_unavailable", "Opportunity stage is unavailable in the active tenant and pipeline");
|
|
2357
|
+
}
|
|
2358
|
+
const stage = await deps.stages.get({ id: stageId }, { cache: false });
|
|
2359
|
+
if (stage && stage.tenantId === tenantId) return stage;
|
|
2360
|
+
throw this.refusal("stage_unavailable", "Opportunity stage is unavailable in the active tenant and pipeline");
|
|
2361
|
+
}
|
|
2311
2362
|
async lockOperationFence(deps, key) {
|
|
2312
2363
|
if (!deps.supportsRowLocks) return;
|
|
2313
2364
|
await deps.leads.db.query("SELECT pg_advisory_xact_lock(hashtext($1))", key);
|
|
@@ -2368,6 +2419,7 @@ var LeadWorkflowService = class LeadWorkflowService {
|
|
|
2368
2419
|
const acquisitionContext = input.acquisitionContext ?? {};
|
|
2369
2420
|
if (!isPlainJsonObject(acquisitionContext) || !isJsonValue(acquisitionContext, /* @__PURE__ */ new Set())) throw this.refusal("invalid_metadata", "Lead acquisitionContext must be a plain JSON object with JSON values");
|
|
2370
2421
|
const ownerRepId = input.ownerRepId ? this.requireIdentifier(input.ownerRepId, "ownerRepId") : "";
|
|
2422
|
+
const profileId = input.profileId !== void 0 ? this.requireIdentifier(input.profileId, "profileId") : "";
|
|
2371
2423
|
const actorProfileId = input.actorProfileId ? this.requireIdentifier(input.actorProfileId, "actorProfileId") : "";
|
|
2372
2424
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
2373
2425
|
if (!Number.isFinite(now.getTime())) throw this.refusal("invalid_due_at", "Lead intake now must be valid");
|
|
@@ -2377,6 +2429,7 @@ var LeadWorkflowService = class LeadWorkflowService {
|
|
|
2377
2429
|
contactName: input.contactName?.trim() ?? "",
|
|
2378
2430
|
phone,
|
|
2379
2431
|
organizationName: input.organizationName?.trim() ?? "",
|
|
2432
|
+
profileId,
|
|
2380
2433
|
sourceKind,
|
|
2381
2434
|
sourceId: input.sourceId?.trim() ?? "",
|
|
2382
2435
|
acquisitionContext,
|
|
@@ -2394,6 +2447,7 @@ var LeadWorkflowService = class LeadWorkflowService {
|
|
|
2394
2447
|
contactName: normalized.contactName,
|
|
2395
2448
|
phone: normalized.phone,
|
|
2396
2449
|
organizationName: normalized.organizationName,
|
|
2450
|
+
...normalized.profileId ? { profileId: normalized.profileId } : {},
|
|
2397
2451
|
sourceKind: normalized.sourceKind,
|
|
2398
2452
|
sourceId: normalized.sourceId,
|
|
2399
2453
|
acquisitionContext: normalized.acquisitionContext,
|
|
@@ -2555,4 +2609,4 @@ function uuidFromHash(hash) {
|
|
|
2555
2609
|
//#endregion
|
|
2556
2610
|
export { PIPELINE_STATUSES as C, Lead as D, SALES_REPRESENTATIVE_STATUSES as E, OPPORTUNITY_STATUSES as S, SALES_ACTIVITY_SUBJECT_KINDS as T, PipelineStage as _, projectLeadWorkQueue as a, DEFAULT_PIPELINE_STAGES as b, LeadCollection as c, PipelineDefinitionCollection as d, PipelineDefinition as f, PipelineStageCollection as g, SalesActivity as h, MAX_LEAD_WORKFLOW_TEXT_LENGTH as i, SalesRepresentativeCollection as l, SalesActivityCollection as m, LeadWorkflowService as n, OpportunityConversionCollection as o, OpportunityCollection as p, LeadWorkflowValidationError as r, OpportunityConversion as s, LEAD_HUMAN_ACTIVITY_KINDS as t, SalesRepresentative as u, Opportunity as v, SALES_ACTIVITY_KINDS as w, LEAD_STATUSES as x, DEFAULT_PIPELINE_KEY as y };
|
|
2557
2611
|
|
|
2558
|
-
//# sourceMappingURL=crm-
|
|
2612
|
+
//# sourceMappingURL=crm-B-irXbbr.js.map
|