@happyvertical/smrt-sales 0.40.42 → 0.40.43
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 +2 -1
- package/README.md +27 -0
- package/agents/crm.md +3 -0
- package/agents/svelte.md +3 -1
- package/dist/agreements.js +1 -1
- package/dist/chunks/{__smrt-register__-DJEOUcaR.js → __smrt-register__-CSOh6enh.js} +2 -2
- package/dist/chunks/{__smrt-register__-DJEOUcaR.js.map → __smrt-register__-CSOh6enh.js.map} +1 -1
- package/dist/chunks/{crm-DwEz7E2r.js → crm-B8XqwUBg.js} +472 -7
- package/dist/chunks/crm-B8XqwUBg.js.map +1 -0
- package/dist/commissions.js +1 -1
- package/dist/crm/collections/SalesActivityCollection.d.ts +2 -2
- package/dist/crm/collections/SalesActivityCollection.d.ts.map +1 -1
- package/dist/crm/index.d.ts +2 -0
- package/dist/crm/index.d.ts.map +1 -1
- package/dist/crm/models/SalesActivity.d.ts +17 -0
- package/dist/crm/models/SalesActivity.d.ts.map +1 -1
- package/dist/crm/services/LeadWorkflowService.d.ts +164 -0
- package/dist/crm/services/LeadWorkflowService.d.ts.map +1 -0
- package/dist/crm.js +3 -3
- package/dist/index.js +3 -3
- package/dist/manifest.json +1671 -1663
- package/dist/referrals.js +1 -1
- package/dist/smrt-knowledge.json +157 -156
- package/dist/svelte/__tests__/types.test.js +30 -1
- package/dist/svelte/components/LeadDetail.svelte +512 -0
- package/dist/svelte/components/LeadDetail.svelte.d.ts +31 -0
- package/dist/svelte/components/LeadDetail.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +5 -3
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +3 -2
- package/dist/svelte/types.d.ts +44 -1
- package/dist/svelte/types.d.ts.map +1 -1
- package/dist/svelte/types.js +17 -0
- package/package.json +6 -6
- package/dist/chunks/crm-DwEz7E2r.js.map +0 -1
package/AGENTS.md
CHANGED
|
@@ -30,7 +30,7 @@ you are editing. This file keeps what holds in every module.
|
|
|
30
30
|
|---|---|---|
|
|
31
31
|
| `agreements` | verified execution evidence — private orchestration state, append-only provider events, immutable executed agreements, and the provider-neutral execution service | [agents/agreements.md](agents/agreements.md) |
|
|
32
32
|
| `commissions` | the neutral financial core — earners, versioned plans, earning events, commissions, adjustments, balances, and payout settlement | [agents/commissions.md](agents/commissions.md) |
|
|
33
|
-
| `crm` | leads, configurable pipelines, opportunities, activity trail, and idempotent conversion links | [agents/crm.md](agents/crm.md) |
|
|
33
|
+
| `crm` | leads, configurable pipelines, opportunities, tenant-safe Lead follow-up, activity trail, and idempotent conversion links | [agents/crm.md](agents/crm.md) |
|
|
34
34
|
| `referrals` | referrers, programs, versioned attribution policies, links/touches, referrals, exception review, and term snapshots | [agents/referrals.md](agents/referrals.md) |
|
|
35
35
|
| `svelte` | props-driven presentational surfaces for CRM, the referrer portal, and operator review | [agents/svelte.md](agents/svelte.md) |
|
|
36
36
|
|
|
@@ -61,6 +61,7 @@ Business/domain models are generally `@TenantScoped({ mode: 'optional' })` with
|
|
|
61
61
|
- **CommissionPayout, not Payout**: avoids the pre-existing global table-name collision between commerce `Payout` and legacy affiliates `Payout` (`payouts`).
|
|
62
62
|
- **Table names are global**: new models were named to avoid collisions across packages (`commission_payouts`, `sales_activities`, `attribution_policies`, …).
|
|
63
63
|
- **Svelte module is svelte-check-gated**: no runtime component tests; `typecheck` runs `svelte-check` via `scripts/svelte-check-a11y.mjs`. Ship raw `.svelte` via `svelte-package`.
|
|
64
|
+
- **Lead follow-up stays generic**: call `LeadWorkflowService` for audited Lead assignment/status/activity/task mutations under ambient tenancy; it locks rows, rejects cross-tenant identifiers, and has no authorization, SLA, automatic-owner, reminder, website-contact, or conversion policy. `LeadDetail` is props/callback only; host applications map state and call the service.
|
|
64
65
|
- **Model transition methods don't save**: `markEarned()/approve()/markPayable()/markPaid()` (Commission) and the payout transitions mutate + stamp timestamps only — callers save; the settlement/payout services do both.
|
|
65
66
|
- **`reject()` alone strands rows**: the model method only flips status — always reject through `transitionPayoutForSource`, which releases the batch's membership in the same transaction; stamped rows on a rejected payout would be unsettleable forever.
|
|
66
67
|
- **The payout source stamp is derived data, never authorization**: `sourceKind`/`sourceId` on CommissionPayout index the history listing; both the listing and the lifecycle service re-verify actual membership and fail closed when the stamp cannot be proven.
|
package/README.md
CHANGED
|
@@ -86,6 +86,33 @@ decimals from `0` to `1`; rounding occurs through the exported money helpers.
|
|
|
86
86
|
agreement execution, and attribution have service-owned invariants that raw
|
|
87
87
|
generated CRUD must not bypass.
|
|
88
88
|
|
|
89
|
+
## Lead follow-up workflow
|
|
90
|
+
|
|
91
|
+
`LeadWorkflowService` is the tenant-safe, application-facing seam for generic
|
|
92
|
+
pre-qualification follow-up. Construct it with the host database inside an
|
|
93
|
+
active `withTenant()` context; the host supplies authorization, actor/profile
|
|
94
|
+
ids, and view-model mapping.
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { LeadWorkflowService } from '@happyvertical/smrt-sales/crm';
|
|
98
|
+
|
|
99
|
+
const workflow = await LeadWorkflowService.create({ db });
|
|
100
|
+
await workflow.startWorking({ leadId, actorProfileId });
|
|
101
|
+
await workflow.scheduleNextAction({
|
|
102
|
+
leadId,
|
|
103
|
+
actorProfileId,
|
|
104
|
+
summary: 'Call after product review',
|
|
105
|
+
dueAt: new Date('2026-10-01T16:00:00Z'),
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The service atomically records assignment and status audit events, human
|
|
110
|
+
activities, scheduled next actions, and monotonic task completion. Qualification
|
|
111
|
+
and duplicate merge ownership remain respectively with `LeadCollection.qualify()`
|
|
112
|
+
and `LeadCollection.mergeLeads()`. `LeadDetail` from the `/svelte` subpath is
|
|
113
|
+
props- and callback-driven; it never fetches data or applies authorization/SLA
|
|
114
|
+
policy.
|
|
115
|
+
|
|
89
116
|
## Agreement boundary
|
|
90
117
|
|
|
91
118
|
The agreements module accepts the provider-neutral
|
package/agents/crm.md
CHANGED
|
@@ -10,4 +10,7 @@ money), and the Gotchas that apply before editing anything live in
|
|
|
10
10
|
- **PipelineDefinition / PipelineStage**: configurable ordered stages with default `new → qualified → discovery → proposal → negotiation → closed_won | closed_lost` (seeded via `ensureDefaultPipeline()`); stages carry `probability` and `isWon`/`isLost` terminal flags.
|
|
11
11
|
- **Opportunity**: qualified engagement — owner, pipeline + stage, `expectedValueCents`, `probability`, `expectedCloseAt`, outcome. Stage movement validated against the pipeline; terminal stages set `won|lost` status.
|
|
12
12
|
- **SalesActivity**: activity/next-action trail for Leads and Opportunities (`subjectKind`/`subjectId`), also the audit trail for assignment, qualification, merges, and stage movement.
|
|
13
|
+
- **LeadWorkflowService**: the required tenant-safe pre-qualification mutation seam. It transactionally locks the Lead (and completion task on PostgreSQL), accepts only active same-tenant representatives, writes assignment/status/completion audits alongside their mutations, and returns merge-aware timeline/work-state reads. It owns `new | disqualified → working`, `new | working → disqualified`, human follow-up (`note | call | email | meeting`), and task scheduling/completion; qualification and merging remain collection lifecycles.
|
|
13
14
|
- **OpportunityConversion**: idempotent conversion links (`targetKind`/`targetId` — client, project, contract, subscription, …) with a composite natural key. CRM never creates downstream records itself and never mutates referral or commission state.
|
|
15
|
+
|
|
16
|
+
Workflow calls require ambient tenant context and an actor profile id. Fail closed for foreign/missing Lead, representative, and task ids without revealing their existence. Human metadata is plain JSON-object data; framework audit metadata is generated separately. Keep queue projection pure (`now`/optional timezone are injected) and do not add assignment, reminder, SLA, authorization, or conversion policy.
|
package/agents/svelte.md
CHANGED
|
@@ -5,4 +5,6 @@ cross-module invariants (currency, tenancy, cross-package refs, roles vs.
|
|
|
5
5
|
money), and the Gotchas that apply before editing anything live in
|
|
6
6
|
[../AGENTS.md](../AGENTS.md) — read that first.
|
|
7
7
|
|
|
8
|
-
Props-driven presentational components (no data fetching, no model-class imports, Provider-free smrt-ui primitives, `--smrt-*` tokens only): CRM — `SalesDashboard`, `LeadList`, `OpportunityBoard`, `OpportunityDetail`; referrer portal — `ReferralLinkManager`, `ReferralStatusList`, `ReferrerEarningsSummary`, `CommissionBreakdown` (trace-explained amounts), `PayoutHistoryList`, `ExecutedAgreementsList`; operator — `AttributionConflictQueue` (award editor + required resolution reason), `PayoutBatchReview`, `CommissionExpenseSummary` (explicitly distinct from client invoices). Monetary props stay integer cents; `format.ts` converts at render. View-model prop types are exported interfaces (never inline intersected generics in `$props()`); pure helpers (dashboard math, award validation mirroring the service, payout action gating) are unit-tested while components are svelte-check-gated.
|
|
8
|
+
Props-driven presentational components (no data fetching, no model-class imports, Provider-free smrt-ui primitives, `--smrt-*` tokens only): CRM — `SalesDashboard`, `LeadList`, `LeadDetail`, `OpportunityBoard`, `OpportunityDetail`; referrer portal — `ReferralLinkManager`, `ReferralStatusList`, `ReferrerEarningsSummary`, `CommissionBreakdown` (trace-explained amounts), `PayoutHistoryList`, `ExecutedAgreementsList`; operator — `AttributionConflictQueue` (award editor + required resolution reason), `PayoutBatchReview`, `CommissionExpenseSummary` (explicitly distinct from client invoices). Monetary props stay integer cents; `format.ts` converts at render. View-model prop types are exported interfaces (never inline intersected generics in `$props()`); pure helpers (dashboard math, Lead workflow action gating, award validation mirroring the service, payout action gating) are unit-tested while components are svelte-check-gated.
|
|
9
|
+
|
|
10
|
+
`LeadDetail` renders a complete host-supplied timeline and callback-only assignment, start/reopen, disqualification, human-activity, next-action, completion, and optional qualification controls. Its `busy` prop disables every mutation affordance; the host owns tenancy, authorization, service invocation, refresh, and any policy around due dates or reminders.
|
package/dist/agreements.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./chunks/__smrt-register__-
|
|
1
|
+
import "./chunks/__smrt-register__-CSOh6enh.js";
|
|
2
2
|
import { a as AgreementExecutionEvent, c as AGREEMENT_EXECUTION_STATUSES, d as sanitizeSignerIntent, i as AgreementExecutionEventCollection, l as coerceAgreementDate, n as ExecutedAgreementCollection, o as AgreementExecutionCollection, r as ExecutedAgreement, s as AgreementExecution, t as AgreementExecutionService, u as sanitizeSignerEvidence } from "./chunks/agreements-DbzW1Pcq.js";
|
|
3
3
|
export { AGREEMENT_EXECUTION_STATUSES, AgreementExecution, AgreementExecutionCollection, AgreementExecutionEvent, AgreementExecutionEventCollection, AgreementExecutionService, ExecutedAgreement, ExecutedAgreementCollection, coerceAgreementDate, sanitizeSignerEvidence, sanitizeSignerIntent };
|