@happyvertical/smrt-sales 0.39.2

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 (201) hide show
  1. package/AGENTS.md +87 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/chunks/__smrt-register__-kWdT7LOt.js +6 -0
  8. package/dist/chunks/__smrt-register__-kWdT7LOt.js.map +1 -0
  9. package/dist/chunks/commissions-BCxqOKVM.js +2181 -0
  10. package/dist/chunks/commissions-BCxqOKVM.js.map +1 -0
  11. package/dist/chunks/crm-DwEz7E2r.js +1428 -0
  12. package/dist/chunks/crm-DwEz7E2r.js.map +1 -0
  13. package/dist/chunks/referrals-BY47p70T.js +2880 -0
  14. package/dist/chunks/referrals-BY47p70T.js.map +1 -0
  15. package/dist/commissions/collections/CommissionAdjustmentCollection.d.ts +26 -0
  16. package/dist/commissions/collections/CommissionAdjustmentCollection.d.ts.map +1 -0
  17. package/dist/commissions/collections/CommissionCollection.d.ts +43 -0
  18. package/dist/commissions/collections/CommissionCollection.d.ts.map +1 -0
  19. package/dist/commissions/collections/CommissionPayoutCollection.d.ts +19 -0
  20. package/dist/commissions/collections/CommissionPayoutCollection.d.ts.map +1 -0
  21. package/dist/commissions/collections/CommissionPlanCollection.d.ts +46 -0
  22. package/dist/commissions/collections/CommissionPlanCollection.d.ts.map +1 -0
  23. package/dist/commissions/collections/EarnerCollection.d.ts +14 -0
  24. package/dist/commissions/collections/EarnerCollection.d.ts.map +1 -0
  25. package/dist/commissions/collections/EarningEventCollection.d.ts +27 -0
  26. package/dist/commissions/collections/EarningEventCollection.d.ts.map +1 -0
  27. package/dist/commissions/collections/index.d.ts +11 -0
  28. package/dist/commissions/collections/index.d.ts.map +1 -0
  29. package/dist/commissions/index.d.ts +20 -0
  30. package/dist/commissions/index.d.ts.map +1 -0
  31. package/dist/commissions/models/Commission.d.ts +150 -0
  32. package/dist/commissions/models/Commission.d.ts.map +1 -0
  33. package/dist/commissions/models/CommissionAdjustment.d.ts +62 -0
  34. package/dist/commissions/models/CommissionAdjustment.d.ts.map +1 -0
  35. package/dist/commissions/models/CommissionPayout.d.ts +119 -0
  36. package/dist/commissions/models/CommissionPayout.d.ts.map +1 -0
  37. package/dist/commissions/models/CommissionPlan.d.ts +117 -0
  38. package/dist/commissions/models/CommissionPlan.d.ts.map +1 -0
  39. package/dist/commissions/models/Earner.d.ts +49 -0
  40. package/dist/commissions/models/Earner.d.ts.map +1 -0
  41. package/dist/commissions/models/EarningEvent.d.ts +89 -0
  42. package/dist/commissions/models/EarningEvent.d.ts.map +1 -0
  43. package/dist/commissions/models/index.d.ts +11 -0
  44. package/dist/commissions/models/index.d.ts.map +1 -0
  45. package/dist/commissions/money.d.ts +42 -0
  46. package/dist/commissions/money.d.ts.map +1 -0
  47. package/dist/commissions/services/CommissionBalanceService.d.ts +14 -0
  48. package/dist/commissions/services/CommissionBalanceService.d.ts.map +1 -0
  49. package/dist/commissions/services/CommissionCalculationService.d.ts +142 -0
  50. package/dist/commissions/services/CommissionCalculationService.d.ts.map +1 -0
  51. package/dist/commissions/services/CommissionPayoutService.d.ts +134 -0
  52. package/dist/commissions/services/CommissionPayoutService.d.ts.map +1 -0
  53. package/dist/commissions/services/CommissionSettlementService.d.ts +42 -0
  54. package/dist/commissions/services/CommissionSettlementService.d.ts.map +1 -0
  55. package/dist/commissions/services/index.d.ts +9 -0
  56. package/dist/commissions/services/index.d.ts.map +1 -0
  57. package/dist/commissions/types.d.ts +243 -0
  58. package/dist/commissions/types.d.ts.map +1 -0
  59. package/dist/commissions.d.ts +2 -0
  60. package/dist/commissions.d.ts.map +1 -0
  61. package/dist/commissions.js +3 -0
  62. package/dist/crm/collections/LeadCollection.d.ts +79 -0
  63. package/dist/crm/collections/LeadCollection.d.ts.map +1 -0
  64. package/dist/crm/collections/OpportunityCollection.d.ts +42 -0
  65. package/dist/crm/collections/OpportunityCollection.d.ts.map +1 -0
  66. package/dist/crm/collections/OpportunityConversionCollection.d.ts +26 -0
  67. package/dist/crm/collections/OpportunityConversionCollection.d.ts.map +1 -0
  68. package/dist/crm/collections/PipelineDefinitionCollection.d.ts +46 -0
  69. package/dist/crm/collections/PipelineDefinitionCollection.d.ts.map +1 -0
  70. package/dist/crm/collections/PipelineStageCollection.d.ts +22 -0
  71. package/dist/crm/collections/PipelineStageCollection.d.ts.map +1 -0
  72. package/dist/crm/collections/SalesActivityCollection.d.ts +24 -0
  73. package/dist/crm/collections/SalesActivityCollection.d.ts.map +1 -0
  74. package/dist/crm/collections/SalesRepresentativeCollection.d.ts +19 -0
  75. package/dist/crm/collections/SalesRepresentativeCollection.d.ts.map +1 -0
  76. package/dist/crm/index.d.ts +27 -0
  77. package/dist/crm/index.d.ts.map +1 -0
  78. package/dist/crm/models/Lead.d.ts +135 -0
  79. package/dist/crm/models/Lead.d.ts.map +1 -0
  80. package/dist/crm/models/Opportunity.d.ts +111 -0
  81. package/dist/crm/models/Opportunity.d.ts.map +1 -0
  82. package/dist/crm/models/OpportunityConversion.d.ts +66 -0
  83. package/dist/crm/models/OpportunityConversion.d.ts.map +1 -0
  84. package/dist/crm/models/PipelineDefinition.d.ts +58 -0
  85. package/dist/crm/models/PipelineDefinition.d.ts.map +1 -0
  86. package/dist/crm/models/PipelineStage.d.ts +66 -0
  87. package/dist/crm/models/PipelineStage.d.ts.map +1 -0
  88. package/dist/crm/models/SalesActivity.d.ts +76 -0
  89. package/dist/crm/models/SalesActivity.d.ts.map +1 -0
  90. package/dist/crm/models/SalesRepresentative.d.ts +60 -0
  91. package/dist/crm/models/SalesRepresentative.d.ts.map +1 -0
  92. package/dist/crm/types.d.ts +228 -0
  93. package/dist/crm/types.d.ts.map +1 -0
  94. package/dist/crm.d.ts +2 -0
  95. package/dist/crm.d.ts.map +1 -0
  96. package/dist/crm.js +3 -0
  97. package/dist/index.d.ts +4 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +5 -0
  100. package/dist/manifest.json +9340 -0
  101. package/dist/referrals/collections/AttributionExceptionCollection.d.ts +17 -0
  102. package/dist/referrals/collections/AttributionExceptionCollection.d.ts.map +1 -0
  103. package/dist/referrals/collections/AttributionPolicyCollection.d.ts +50 -0
  104. package/dist/referrals/collections/AttributionPolicyCollection.d.ts.map +1 -0
  105. package/dist/referrals/collections/ReferralAgreementCollection.d.ts +48 -0
  106. package/dist/referrals/collections/ReferralAgreementCollection.d.ts.map +1 -0
  107. package/dist/referrals/collections/ReferralCollection.d.ts +25 -0
  108. package/dist/referrals/collections/ReferralCollection.d.ts.map +1 -0
  109. package/dist/referrals/collections/ReferralLinkCollection.d.ts +96 -0
  110. package/dist/referrals/collections/ReferralLinkCollection.d.ts.map +1 -0
  111. package/dist/referrals/collections/ReferralProgramCollection.d.ts +18 -0
  112. package/dist/referrals/collections/ReferralProgramCollection.d.ts.map +1 -0
  113. package/dist/referrals/collections/ReferralTermSnapshotCollection.d.ts +13 -0
  114. package/dist/referrals/collections/ReferralTermSnapshotCollection.d.ts.map +1 -0
  115. package/dist/referrals/collections/ReferralTouchCollection.d.ts +30 -0
  116. package/dist/referrals/collections/ReferralTouchCollection.d.ts.map +1 -0
  117. package/dist/referrals/collections/ReferrerCollection.d.ts +17 -0
  118. package/dist/referrals/collections/ReferrerCollection.d.ts.map +1 -0
  119. package/dist/referrals/index.d.ts +38 -0
  120. package/dist/referrals/index.d.ts.map +1 -0
  121. package/dist/referrals/models/AttributionException.d.ts +85 -0
  122. package/dist/referrals/models/AttributionException.d.ts.map +1 -0
  123. package/dist/referrals/models/AttributionPolicy.d.ts +128 -0
  124. package/dist/referrals/models/AttributionPolicy.d.ts.map +1 -0
  125. package/dist/referrals/models/Referral.d.ts +112 -0
  126. package/dist/referrals/models/Referral.d.ts.map +1 -0
  127. package/dist/referrals/models/ReferralAgreement.d.ts +125 -0
  128. package/dist/referrals/models/ReferralAgreement.d.ts.map +1 -0
  129. package/dist/referrals/models/ReferralLink.d.ts +71 -0
  130. package/dist/referrals/models/ReferralLink.d.ts.map +1 -0
  131. package/dist/referrals/models/ReferralProgram.d.ts +57 -0
  132. package/dist/referrals/models/ReferralProgram.d.ts.map +1 -0
  133. package/dist/referrals/models/ReferralTermSnapshot.d.ts +61 -0
  134. package/dist/referrals/models/ReferralTermSnapshot.d.ts.map +1 -0
  135. package/dist/referrals/models/ReferralTouch.d.ts +55 -0
  136. package/dist/referrals/models/ReferralTouch.d.ts.map +1 -0
  137. package/dist/referrals/models/Referrer.d.ts +69 -0
  138. package/dist/referrals/models/Referrer.d.ts.map +1 -0
  139. package/dist/referrals/services/AttributionService.d.ts +248 -0
  140. package/dist/referrals/services/AttributionService.d.ts.map +1 -0
  141. package/dist/referrals/services/ReferralCommissionService.d.ts +91 -0
  142. package/dist/referrals/services/ReferralCommissionService.d.ts.map +1 -0
  143. package/dist/referrals/services/ReferralQualificationService.d.ts +135 -0
  144. package/dist/referrals/services/ReferralQualificationService.d.ts.map +1 -0
  145. package/dist/referrals/types.d.ts +226 -0
  146. package/dist/referrals/types.d.ts.map +1 -0
  147. package/dist/referrals.d.ts +2 -0
  148. package/dist/referrals.d.ts.map +1 -0
  149. package/dist/referrals.js +3 -0
  150. package/dist/smrt-knowledge.json +5501 -0
  151. package/dist/svelte/__tests__/format.test.js +68 -0
  152. package/dist/svelte/__tests__/types.test.js +349 -0
  153. package/dist/svelte/components/AttributionConflictQueue.svelte +361 -0
  154. package/dist/svelte/components/AttributionConflictQueue.svelte.d.ts +15 -0
  155. package/dist/svelte/components/AttributionConflictQueue.svelte.d.ts.map +1 -0
  156. package/dist/svelte/components/CommissionBreakdown.svelte +251 -0
  157. package/dist/svelte/components/CommissionBreakdown.svelte.d.ts +11 -0
  158. package/dist/svelte/components/CommissionBreakdown.svelte.d.ts.map +1 -0
  159. package/dist/svelte/components/CommissionExpenseSummary.svelte +186 -0
  160. package/dist/svelte/components/CommissionExpenseSummary.svelte.d.ts +13 -0
  161. package/dist/svelte/components/CommissionExpenseSummary.svelte.d.ts.map +1 -0
  162. package/dist/svelte/components/ExecutedAgreementsList.svelte +136 -0
  163. package/dist/svelte/components/ExecutedAgreementsList.svelte.d.ts +11 -0
  164. package/dist/svelte/components/ExecutedAgreementsList.svelte.d.ts.map +1 -0
  165. package/dist/svelte/components/LeadList.svelte +224 -0
  166. package/dist/svelte/components/LeadList.svelte.d.ts +19 -0
  167. package/dist/svelte/components/LeadList.svelte.d.ts.map +1 -0
  168. package/dist/svelte/components/OpportunityBoard.svelte +230 -0
  169. package/dist/svelte/components/OpportunityBoard.svelte.d.ts +17 -0
  170. package/dist/svelte/components/OpportunityBoard.svelte.d.ts.map +1 -0
  171. package/dist/svelte/components/OpportunityDetail.svelte +472 -0
  172. package/dist/svelte/components/OpportunityDetail.svelte.d.ts +27 -0
  173. package/dist/svelte/components/OpportunityDetail.svelte.d.ts.map +1 -0
  174. package/dist/svelte/components/PayoutBatchReview.svelte +285 -0
  175. package/dist/svelte/components/PayoutBatchReview.svelte.d.ts +21 -0
  176. package/dist/svelte/components/PayoutBatchReview.svelte.d.ts.map +1 -0
  177. package/dist/svelte/components/PayoutHistoryList.svelte +245 -0
  178. package/dist/svelte/components/PayoutHistoryList.svelte.d.ts +11 -0
  179. package/dist/svelte/components/PayoutHistoryList.svelte.d.ts.map +1 -0
  180. package/dist/svelte/components/ReferralLinkManager.svelte +216 -0
  181. package/dist/svelte/components/ReferralLinkManager.svelte.d.ts +17 -0
  182. package/dist/svelte/components/ReferralLinkManager.svelte.d.ts.map +1 -0
  183. package/dist/svelte/components/ReferralStatusList.svelte +118 -0
  184. package/dist/svelte/components/ReferralStatusList.svelte.d.ts +11 -0
  185. package/dist/svelte/components/ReferralStatusList.svelte.d.ts.map +1 -0
  186. package/dist/svelte/components/ReferrerEarningsSummary.svelte +106 -0
  187. package/dist/svelte/components/ReferrerEarningsSummary.svelte.d.ts +11 -0
  188. package/dist/svelte/components/ReferrerEarningsSummary.svelte.d.ts.map +1 -0
  189. package/dist/svelte/components/SalesDashboard.svelte +192 -0
  190. package/dist/svelte/components/SalesDashboard.svelte.d.ts +29 -0
  191. package/dist/svelte/components/SalesDashboard.svelte.d.ts.map +1 -0
  192. package/dist/svelte/format.d.ts +46 -0
  193. package/dist/svelte/format.d.ts.map +1 -0
  194. package/dist/svelte/format.js +75 -0
  195. package/dist/svelte/index.d.ts +50 -0
  196. package/dist/svelte/index.d.ts.map +1 -0
  197. package/dist/svelte/index.js +37 -0
  198. package/dist/svelte/types.d.ts +422 -0
  199. package/dist/svelte/types.d.ts.map +1 -0
  200. package/dist/svelte/types.js +376 -0
  201. package/package.json +89 -0
@@ -0,0 +1,26 @@
1
+ import { SmrtCollection } from '@happyvertical/smrt-core';
2
+ import { CommissionAdjustment } from '../models/CommissionAdjustment.js';
3
+ export declare class CommissionAdjustmentCollection extends SmrtCollection<CommissionAdjustment> {
4
+ static readonly _itemClass: typeof CommissionAdjustment;
5
+ /** All adjustments appended to one commission, oldest first. */
6
+ findByCommission(commissionId: string): Promise<CommissionAdjustment[]>;
7
+ /** Unsettled adjustments for an earner+currency, oldest first. */
8
+ findUnsettledByEarner(earnerId: string, currency: string): Promise<CommissionAdjustment[]>;
9
+ /**
10
+ * Σ signed amountCents of {@link findUnsettledByEarner} rows (integer
11
+ * cents; clawbacks make it negative).
12
+ */
13
+ sumUnsettledByEarner(earnerId: string, currency: string): Promise<number>;
14
+ /** Adjustments settled by one payout batch. */
15
+ findByPayout(payoutId: string): Promise<CommissionAdjustment[]>;
16
+ /**
17
+ * Conditionally claim adjustment rows for a payout batch — the
18
+ * adjustment twin of `CommissionCollection.claimForPayout`. Rows already
19
+ * claimed by a DIFFERENT payout are skipped; rows already claimed by THIS
20
+ * payout pass through (idempotent retry / repair); every claim is
21
+ * verified by a post-save re-read. Returns the claimed rows.
22
+ */
23
+ claimForPayout(adjustmentIds: string[], payoutId: string): Promise<CommissionAdjustment[]>;
24
+ }
25
+ export default CommissionAdjustmentCollection;
26
+ //# sourceMappingURL=CommissionAdjustmentCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionAdjustmentCollection.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/CommissionAdjustmentCollection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,qBAAa,8BAA+B,SAAQ,cAAc,CAAC,oBAAoB,CAAC;IACtF,MAAM,CAAC,QAAQ,CAAC,UAAU,8BAAwB;IAElD,gEAAgE;IAC1D,gBAAgB,CACpB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAOlC,kEAAkE;IAC5D,qBAAqB,CACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAQlC;;;OAGG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAKlB,+CAA+C;IACzC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAOrE;;;;;;OAMG;IACG,cAAc,CAClB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,EAAE,CAAC;CAiBnC;AAED,eAAe,8BAA8B,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { SmrtCollection } from '@happyvertical/smrt-core';
2
+ import { Commission } from '../models/Commission.js';
3
+ import { CommissionStatus } from '../types.js';
4
+ export declare class CommissionCollection extends SmrtCollection<Commission> {
5
+ static readonly _itemClass: typeof Commission;
6
+ /** All commissions for an earner, newest first. */
7
+ findByEarner(earnerId: string): Promise<Commission[]>;
8
+ /** All commissions derived from one earning event. */
9
+ findByEvent(earningEventId: string): Promise<Commission[]>;
10
+ /** Commissions by lifecycle status, newest first. */
11
+ findByStatus(status: CommissionStatus): Promise<Commission[]>;
12
+ /** Look up a commission by its idempotency natural key. */
13
+ findByDedupeKey(dedupeKey: string): Promise<Commission | null>;
14
+ /**
15
+ * Payable commissions for an earner+currency that no payout batch has
16
+ * settled yet — the rows `CommissionPayoutService.createPayoutBatch`
17
+ * gathers.
18
+ */
19
+ findPayableUnsettled(earnerId: string, currency: string): Promise<Commission[]>;
20
+ /** Σ amountCents of {@link findPayableUnsettled} rows (integer cents). */
21
+ sumPayableByEarner(earnerId: string, currency: string): Promise<number>;
22
+ /** Commissions settled by one payout batch. */
23
+ findByPayout(payoutId: string): Promise<Commission[]>;
24
+ /**
25
+ * Conditionally claim rows for a payout batch: each row is re-loaded
26
+ * fresh and stamped with `payoutId` only when it is still payable and
27
+ * unclaimed (or already claimed by THIS payout — the idempotent-retry /
28
+ * repair case). Rows claimed by a DIFFERENT payout are skipped, and every
29
+ * claim is verified by a post-save re-read so a lost race never counts
30
+ * toward the caller's totals.
31
+ *
32
+ * This is the single place claim semantics live. It narrows the
33
+ * concurrent-batch window to the re-read granularity; true compare-and-set
34
+ * needs DB transactions the collection layer doesn't expose (settlement
35
+ * runs are expected to be single-writer per earner — see
36
+ * `CommissionPayoutService`).
37
+ *
38
+ * Returns the claimed rows (freshly loaded, `payoutId` verified).
39
+ */
40
+ claimForPayout(commissionIds: string[], payoutId: string): Promise<Commission[]>;
41
+ }
42
+ export default CommissionCollection;
43
+ //# sourceMappingURL=CommissionCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionCollection.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/CommissionCollection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,qBAAa,oBAAqB,SAAQ,cAAc,CAAC,UAAU,CAAC;IAClE,MAAM,CAAC,QAAQ,CAAC,UAAU,oBAAc;IAExC,mDAAmD;IAC7C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAO3D,sDAAsD;IAChD,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAOhE,qDAAqD;IAC/C,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAOnE,2DAA2D;IACrD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAMpE;;;;OAIG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC;IAQxB,0EAA0E;IACpE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAKlB,+CAA+C;IACzC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAO3D;;;;;;;;;;;;;;;OAeG;IACG,cAAc,CAClB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC;CAkBzB;AAED,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { SmrtCollection } from '@happyvertical/smrt-core';
2
+ import { CommissionPayout } from '../models/CommissionPayout.js';
3
+ import { CommissionPayoutStatus } from '../types.js';
4
+ export declare class CommissionPayoutCollection extends SmrtCollection<CommissionPayout> {
5
+ static readonly _itemClass: typeof CommissionPayout;
6
+ /** All payout batches for an earner, newest first. */
7
+ findByEarner(earnerId: string): Promise<CommissionPayout[]>;
8
+ /** Payout batches by status, newest first. */
9
+ findByStatus(status: CommissionPayoutStatus): Promise<CommissionPayout[]>;
10
+ /** Look up a payout by its idempotency natural key. */
11
+ findByIdempotencyKey(idempotencyKey: string): Promise<CommissionPayout | null>;
12
+ /**
13
+ * Σ totalAmountCents of COMPLETED payouts for an earner+currency —
14
+ * lifetime settled earnings (integer cents).
15
+ */
16
+ sumPaidByEarner(earnerId: string, currency: string): Promise<number>;
17
+ }
18
+ export default CommissionPayoutCollection;
19
+ //# sourceMappingURL=CommissionPayoutCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionPayoutCollection.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/CommissionPayoutCollection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,qBAAa,0BAA2B,SAAQ,cAAc,CAAC,gBAAgB,CAAC;IAC9E,MAAM,CAAC,QAAQ,CAAC,UAAU,0BAAoB;IAE9C,sDAAsD;IAChD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAOjE,8CAA8C;IACxC,YAAY,CAChB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAO9B,uDAAuD;IACjD,oBAAoB,CACxB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAMnC;;;OAGG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAM3E;AAED,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { SmrtCollection } from '@happyvertical/smrt-core';
2
+ import { CommissionPlan } from '../models/CommissionPlan.js';
3
+ import { CommissionPlanComponent, CommissionPlanStatus } from '../types.js';
4
+ /**
5
+ * Fields an amendment may change relative to the version it copies.
6
+ * `planKey` is fixed (it identifies the plan), `version` is computed, and
7
+ * `status` is always `draft` — a caller cannot mint a pre-activated
8
+ * amendment.
9
+ */
10
+ export interface CommissionPlanAmendmentChanges {
11
+ name?: string;
12
+ description?: string;
13
+ components?: CommissionPlanComponent[];
14
+ currency?: string;
15
+ effectiveFrom?: Date | null;
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ export declare class CommissionPlanCollection extends SmrtCollection<CommissionPlan> {
19
+ static readonly _itemClass: typeof CommissionPlan;
20
+ /** Every version of a plan, newest version first. */
21
+ findByPlanKey(planKey: string): Promise<CommissionPlan[]>;
22
+ /** Plans by status. */
23
+ findByStatus(status: CommissionPlanStatus): Promise<CommissionPlan[]>;
24
+ /**
25
+ * The highest ACTIVE version of a plan already IN EFFECT at `at`, or
26
+ * `null` when none is. This is what calculation callers resolve terms
27
+ * from when no frozen snapshot pins a specific version. A future-dated
28
+ * amendment can be activated ahead of its effective date without
29
+ * governing earlier qualifications (`effectiveFrom: null` = effective
30
+ * immediately).
31
+ */
32
+ latestActiveByKey(planKey: string, at?: Date, tenantId?: string | null): Promise<CommissionPlan | null>;
33
+ /**
34
+ * Create an amendment: insert a new DRAFT row with
35
+ * `version = max(existing versions) + 1`, copying the latest existing
36
+ * version's fields and then applying `changes`. The source version is not
37
+ * touched — activate the draft (and supersede the prior active version)
38
+ * as a separate, explicit step.
39
+ *
40
+ * Throws when no version of `planKey` exists (nothing to amend — use
41
+ * `create` for a brand-new plan).
42
+ */
43
+ createAmendment(planKey: string, changes?: CommissionPlanAmendmentChanges): Promise<CommissionPlan>;
44
+ }
45
+ export default CommissionPlanCollection;
46
+ //# sourceMappingURL=CommissionPlanCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionPlanCollection.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/CommissionPlanCollection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EACL,cAAc,EAEf,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,MAAM,WAAW,8BAA8B;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qBAAa,wBAAyB,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC1E,MAAM,CAAC,QAAQ,CAAC,UAAU,wBAAkB;IAE5C,qDAAqD;IAC/C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAO/D,uBAAuB;IACjB,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAO3E;;;;;;;OAOG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,IAAiB,EACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsBjC;;;;;;;;;OASG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,cAAc,CAAC;CAqC3B;AAED,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { SmrtCollection } from '@happyvertical/smrt-core';
2
+ import { Earner } from '../models/Earner.js';
3
+ import { EarnerStatus } from '../types.js';
4
+ export declare class EarnerCollection extends SmrtCollection<Earner> {
5
+ static readonly _itemClass: typeof Earner;
6
+ /** Earners linked to a smrt-profiles Profile. */
7
+ findByProfile(profileId: string): Promise<Earner[]>;
8
+ /** Earners by status. */
9
+ findByStatus(status: EarnerStatus): Promise<Earner[]>;
10
+ /** All active earners. */
11
+ findActive(): Promise<Earner[]>;
12
+ }
13
+ export default EarnerCollection;
14
+ //# sourceMappingURL=EarnerCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EarnerCollection.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/EarnerCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,qBAAa,gBAAiB,SAAQ,cAAc,CAAC,MAAM,CAAC;IAC1D,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAU;IAEpC,iDAAiD;IAC3C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAOzD,yBAAyB;IACnB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAO3D,0BAA0B;IACpB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAGtC;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { SmrtCollection } from '@happyvertical/smrt-core';
2
+ import { EarningEvent } from '../models/EarningEvent.js';
3
+ import { EarningEventOptions } from '../types.js';
4
+ export declare class EarningEventCollection extends SmrtCollection<EarningEvent> {
5
+ static readonly _itemClass: typeof EarningEvent;
6
+ /** Look up an event by its idempotency natural key. */
7
+ findByDedupeKey(dedupeKey: string): Promise<EarningEvent | null>;
8
+ /**
9
+ * Idempotent ingestion: if an event with `options.dedupeKey` already
10
+ * exists, return it untouched (`created: false`) — evidence is immutable,
11
+ * so a replay never updates the stored row. Otherwise create the event.
12
+ *
13
+ * `dedupeKey` is required — callers embed tenant/source identity in it
14
+ * (e.g. `` `${tenantId}:${sourceKind}:${sourceId}:${eventKind}` ``);
15
+ * an empty key would silently disable idempotency, so it throws instead.
16
+ */
17
+ getOrCreateByDedupeKey(options: EarningEventOptions): Promise<{
18
+ event: EarningEvent;
19
+ created: boolean;
20
+ }>;
21
+ /** Events for one generic earning source, newest occurrence first. */
22
+ findBySource(sourceKind: string, sourceId: string): Promise<EarningEvent[]>;
23
+ /** Events by kind, newest occurrence first. */
24
+ findByKind(eventKind: string): Promise<EarningEvent[]>;
25
+ }
26
+ export default EarningEventCollection;
27
+ //# sourceMappingURL=EarningEventCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EarningEventCollection.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/EarningEventCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,qBAAa,sBAAuB,SAAQ,cAAc,CAAC,YAAY,CAAC;IACtE,MAAM,CAAC,QAAQ,CAAC,UAAU,sBAAgB;IAE1C,uDAAuD;IACjD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAMtE;;;;;;;;OAQG;IACG,sBAAsB,CAC1B,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAqBrD,sEAAsE;IAChE,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,EAAE,CAAC;IAO1B,+CAA+C;IACzC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAM7D;AAED,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Collection barrel for the commissions module.
3
+ * @packageDocumentation
4
+ */
5
+ export { CommissionAdjustmentCollection } from './CommissionAdjustmentCollection.js';
6
+ export { CommissionCollection } from './CommissionCollection.js';
7
+ export { CommissionPayoutCollection } from './CommissionPayoutCollection.js';
8
+ export { type CommissionPlanAmendmentChanges, CommissionPlanCollection, } from './CommissionPlanCollection.js';
9
+ export { EarnerCollection } from './EarnerCollection.js';
10
+ export { EarningEventCollection } from './EarningEventCollection.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commissions/collections/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EACL,KAAK,8BAA8B,EACnC,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `commissions` — the neutral financial core of `@happyvertical/smrt-sales`.
3
+ *
4
+ * Earners (payout accounts), versioned CommissionPlans, immutable
5
+ * EarningEvents, Commissions with a strict settlement chain, append-only
6
+ * CommissionAdjustments, computed balances, and CommissionPayout batches.
7
+ *
8
+ * This module never imports from the `crm` or `referrals` modules and never
9
+ * assumes advertising, Referral, Lead, or Opportunity semantics — earning
10
+ * sources are generic `(sourceKind, sourceId)` strings and terms snapshots
11
+ * are generic `(termsSnapshotKind, termsSnapshotId)` references.
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ export * from './collections/index.js';
16
+ export * from './models/index.js';
17
+ export * from './money.js';
18
+ export * from './services/index.js';
19
+ export * from './types.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commissions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,150 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { CommissionBasis, CommissionCalculationTrace, CommissionOptions, CommissionStatus } from '../types.js';
3
+ export declare class Commission extends SmrtObject {
4
+ /** Tenant ID for multi-tenant isolation (nullable → global rows). */
5
+ tenantId: string | null;
6
+ /** The {@link Earner} this commission belongs to. Required. */
7
+ earnerId: string;
8
+ /** The {@link EarningEvent} evidence row this commission derives from. */
9
+ earningEventId: string;
10
+ /** Snapshot reference: plan key at calculation time. */
11
+ planKey: string;
12
+ /** Snapshot reference: plan version at calculation time. */
13
+ planVersion: number;
14
+ /** Which plan component produced this commission. */
15
+ componentKey: string;
16
+ /**
17
+ * Generic polymorphic reference to the terms snapshot that governed the
18
+ * calculation (e.g. the referrals module sets
19
+ * `('referral_term_snapshot', <id>)`). Free-form; this module attaches no
20
+ * semantics beyond recording it in the dedupe key and trace.
21
+ */
22
+ termsSnapshotKind: string;
23
+ /** Id of the terms snapshot named by {@link termsSnapshotKind}. */
24
+ termsSnapshotId: string;
25
+ /** How {@link baseAmountCents} was resolved from the event. */
26
+ basis: CommissionBasis;
27
+ /** Base amount the rate was applied to, in integer cents. */
28
+ baseAmountCents: number;
29
+ /** Rate applied (0–1). Recorded as `0` for `fixed`-basis commissions. */
30
+ rate: number;
31
+ /** Split share applied (0–1). `1.0` for unsplit commissions. */
32
+ shareFraction: number;
33
+ /**
34
+ * Groups the sibling commissions of one split — every earner sharing an
35
+ * event/component carries the same `splitGroupId`. Empty for unsplit rows.
36
+ */
37
+ splitGroupId: string;
38
+ /** The earned amount in integer cents. */
39
+ amountCents: number;
40
+ /** ISO 4217 currency (copied from the earning event). */
41
+ currency: string;
42
+ /**
43
+ * Lifecycle status — strict chain `pending → earned → approved → payable
44
+ * → paid`. Mutate via the transition methods; the save-time guard rejects
45
+ * illegal edges.
46
+ */
47
+ status: CommissionStatus;
48
+ /**
49
+ * End of the clearing window (refund/chargeback holdback). `null` means
50
+ * no clearing applies — the commission is immediately sweepable to
51
+ * `earned` (see `CommissionSettlementService.sweepClearing`).
52
+ */
53
+ clearingEndsAt: Date | null;
54
+ /** When the commission transitioned to `earned`. */
55
+ earnedAt: Date | null;
56
+ /** When the commission transitioned to `approved`. */
57
+ approvedAt: Date | null;
58
+ /** When the commission transitioned to `payable`. */
59
+ payableAt: Date | null;
60
+ /** When the commission transitioned to `paid`. */
61
+ paidAt: Date | null;
62
+ /**
63
+ * The {@link CommissionPayout} batch that settled this commission. Empty
64
+ * until a payout batch stamps it.
65
+ */
66
+ payoutId: string;
67
+ /** Copied from the earning event for reporting (generic source pair). */
68
+ sourceKind: string;
69
+ /** Copied from the earning event for reporting. */
70
+ sourceId: string;
71
+ /**
72
+ * JSON-string {@link CommissionCalculationTrace} — everything needed to
73
+ * reproduce {@link amountCents}. Use {@link getCalculationTrace} /
74
+ * {@link setCalculationTrace}.
75
+ */
76
+ calculationTrace: string;
77
+ /**
78
+ * Idempotency natural key —
79
+ * `` `${event.dedupeKey}:${terms}:${componentKey}:${earnerId}:${occurrenceIndex}` ``
80
+ * (see `CommissionCalculationService`). Required.
81
+ */
82
+ dedupeKey: string;
83
+ /** Additional metadata as a JSON string. */
84
+ metadata: string;
85
+ constructor(options?: CommissionOptions);
86
+ /**
87
+ * Re-coerce timestamp fields after the framework reapplies raw option /
88
+ * hydrated row values, and record the loaded status for the save guard.
89
+ */
90
+ initialize(): Promise<this>;
91
+ isPending(): boolean;
92
+ isEarned(): boolean;
93
+ isApproved(): boolean;
94
+ isPayable(): boolean;
95
+ isPaid(): boolean;
96
+ /** `true` once a payout batch has stamped {@link payoutId}. */
97
+ isSettled(): boolean;
98
+ /**
99
+ * `pending → earned` (clearing window passed). Stamps {@link earnedAt}.
100
+ * Does NOT save — the caller saves.
101
+ */
102
+ markEarned(now?: Date): void;
103
+ /**
104
+ * `earned → approved` (operator/automation approved the earning).
105
+ * Stamps {@link approvedAt}. Does NOT save — the caller saves.
106
+ */
107
+ approve(now?: Date): void;
108
+ /**
109
+ * `approved → payable` (released for the next payout batch).
110
+ * Stamps {@link payableAt}. Does NOT save — the caller saves.
111
+ */
112
+ markPayable(now?: Date): void;
113
+ /**
114
+ * `payable → paid` (its payout batch completed). Stamps {@link paidAt}.
115
+ * Does NOT save — the caller saves.
116
+ */
117
+ markPaid(now?: Date): void;
118
+ private assertTransitionFrom;
119
+ /** Parse {@link calculationTrace}; returns `null` on empty/invalid JSON. */
120
+ getCalculationTrace(): CommissionCalculationTrace | null;
121
+ /** Serialize and store {@link calculationTrace}. */
122
+ setCalculationTrace(trace: CommissionCalculationTrace): void;
123
+ /** Parse {@link metadata}; returns `{}` on empty/invalid JSON. */
124
+ getMetadata(): Record<string, unknown>;
125
+ /** Serialize and store {@link metadata}. */
126
+ setMetadata(data: Record<string, unknown>): void;
127
+ /**
128
+ * Save-time state-machine guard (commerce pattern). Validates the status
129
+ * transition against the AUTHORITATIVE prior persisted status — re-read
130
+ * from the database so a `create({ id: <existing>, _skipLoad: true })`
131
+ * upsert is correctly treated as an update rather than a guard-free new
132
+ * row. Brand-new rows may start in any status (fixtures/imports); a
133
+ * persisted row may only advance one legal step.
134
+ */
135
+ save(): Promise<this>;
136
+ /**
137
+ * Refuse a save whose `dedupeKey` already belongs to a DIFFERENT row —
138
+ * commissions are audit rows, and the natural-key upsert would let a
139
+ * fresh instance (generated `create`, or the loser of a calculation
140
+ * race) overwrite the persisted amount/status and rotate the row id.
141
+ * `CommissionCalculationService` treats this refusal as "someone else
142
+ * already earned it" and returns the existing row.
143
+ */
144
+ private assertDedupeKeyNotTaken;
145
+ private resolvePriorStatus;
146
+ private assertStatusTransition;
147
+ private static coerceDate;
148
+ }
149
+ export default Commission;
150
+ //# sourceMappingURL=Commission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Commission.d.ts","sourceRoot":"","sources":["../../../src/commissions/models/Commission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAqB,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAE/E,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AA0BrB,qBAaa,UAAW,SAAQ,UAAU;IACxC,qEAAqE;IAErE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,+DAA+D;IAE/D,QAAQ,EAAE,MAAM,CAAM;IAEtB,0EAA0E;IAE1E,cAAc,EAAE,MAAM,CAAM;IAE5B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAM;IAErB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAK;IAExB,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAM;IAE1B;;;;;OAKG;IACH,iBAAiB,EAAE,MAAM,CAAM;IAE/B,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAM;IAE7B,+DAA+D;IAC/D,KAAK,EAAE,eAAe,CAAW;IAEjC,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAK;IAE5B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAO;IAEnB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAO;IAE5B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAK;IAExB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAS;IAEzB;;;;OAIG;IACH,MAAM,EAAE,gBAAgB,CAAa;IAErC;;;;OAIG;IACH,cAAc,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEnC,oDAAoD;IACpD,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE7B,sDAAsD;IACtD,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE/B,qDAAqD;IACrD,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B,kDAAkD;IAClD,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE3B;;;OAGG;IAEH,QAAQ,EAAE,MAAM,CAAM;IAEtB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAM;IAExB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAM;IAEtB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAQ;IAEhC;;;;OAIG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,iBAAsB;IA8C3C;;;OAGG;IACY,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAe1C,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,OAAO;IAInB,UAAU,IAAI,OAAO;IAIrB,SAAS,IAAI,OAAO;IAIpB,MAAM,IAAI,OAAO;IAIjB,+DAA+D;IAC/D,SAAS,IAAI,OAAO;IAMpB;;;OAGG;IACH,UAAU,CAAC,GAAG,GAAE,IAAiB,GAAG,IAAI;IAMxC;;;OAGG;IACH,OAAO,CAAC,GAAG,GAAE,IAAiB,GAAG,IAAI;IAMrC;;;OAGG;IACH,WAAW,CAAC,GAAG,GAAE,IAAiB,GAAG,IAAI;IAMzC;;;OAGG;IACH,QAAQ,CAAC,GAAG,GAAE,IAAiB,GAAG,IAAI;IAMtC,OAAO,CAAC,oBAAoB;IAe5B,4EAA4E;IAC5E,mBAAmB,IAAI,0BAA0B,GAAG,IAAI;IAiBxD,oDAAoD;IACpD,mBAAmB,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI;IAI5D,kEAAkE;IAClE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYtC,4CAA4C;IAC5C,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAMhD;;;;;;;OAOG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASpC;;;;;;;OAOG;YACW,uBAAuB;YA0BvB,kBAAkB;IAchC,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,MAAM,CAAC,UAAU;CAS1B;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { CommissionAdjustmentKind, CommissionAdjustmentOptions } from '../types.js';
3
+ export declare class CommissionAdjustment extends SmrtObject {
4
+ /** Tenant ID for multi-tenant isolation (nullable → global rows). */
5
+ tenantId: string | null;
6
+ /** The {@link Commission} this adjustment corrects. Required. */
7
+ commissionId: string;
8
+ /**
9
+ * The {@link Earner} the adjustment applies to — denormalized from the
10
+ * parent commission so balance queries never need a join. Required.
11
+ */
12
+ earnerId: string;
13
+ /** What kind of correction this is. */
14
+ adjustmentKind: CommissionAdjustmentKind;
15
+ /**
16
+ * SIGNED amount in integer cents. Negative claws earnings back (refund,
17
+ * chargeback); positive credits extra.
18
+ */
19
+ amountCents: number;
20
+ /** ISO 4217 currency — must match the parent commission's. */
21
+ currency: string;
22
+ /** Human-readable justification. Required — audit rows explain themselves. */
23
+ reason: string;
24
+ /**
25
+ * Profile of the operator/automation that created the adjustment
26
+ * (cross-package string reference to smrt-profiles).
27
+ */
28
+ createdByProfileId: string;
29
+ /**
30
+ * The {@link CommissionPayout} batch that settled this adjustment. Empty
31
+ * until stamped. This is the ONLY field mutable after creation.
32
+ */
33
+ payoutId: string;
34
+ /** Additional metadata as a JSON string. Frozen once persisted. */
35
+ metadata: string;
36
+ constructor(options?: CommissionAdjustmentOptions);
37
+ /**
38
+ * Capture the frozen-fields snapshot when the row was loaded from the
39
+ * database — from that moment on, only {@link payoutId} may change.
40
+ */
41
+ initialize(): Promise<this>;
42
+ /** `true` once a payout batch has stamped {@link payoutId}. */
43
+ isSettled(): boolean;
44
+ /** Parse {@link metadata}; returns `{}` on empty/invalid JSON. */
45
+ getMetadata(): Record<string, unknown>;
46
+ /** Serialize and store {@link metadata}. */
47
+ setMetadata(data: Record<string, unknown>): void;
48
+ /**
49
+ * Save with the append-only guard: once the row has been persisted, every
50
+ * field except `payoutId` must match the captured snapshot. Corrections
51
+ * to a wrong adjustment are new counter-adjustments, never edits.
52
+ */
53
+ save(): Promise<this>;
54
+ private assertImmutableOncePersisted;
55
+ /**
56
+ * Serialize every field EXCEPT `payoutId` (the sole post-create mutable
57
+ * field) with stable key ordering.
58
+ */
59
+ private serializeFrozenSnapshot;
60
+ }
61
+ export default CommissionAdjustment;
62
+ //# sourceMappingURL=CommissionAdjustment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionAdjustment.d.ts","sourceRoot":"","sources":["../../../src/commissions/models/CommissionAdjustment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAIL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,aAAa,CAAC;AASrB,qBAQa,oBAAqB,SAAQ,UAAU;IAClD,qEAAqE;IAErE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,iEAAiE;IAEjE,YAAY,EAAE,MAAM,CAAM;IAE1B;;;OAGG;IAEH,QAAQ,EAAE,MAAM,CAAM;IAEtB,uCAAuC;IACvC,cAAc,EAAE,wBAAwB,CAAgB;IAExD;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAK;IAExB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAS;IAEzB,8EAA8E;IAE9E,MAAM,EAAE,MAAM,CAAM;IAEpB;;;OAGG;IAEH,kBAAkB,EAAE,MAAM,CAAM;IAEhC;;;OAGG;IAEH,QAAQ,EAAE,MAAM,CAAM;IAEtB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,2BAAgC;IAkBrD;;;OAGG;IACY,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1C,+DAA+D;IAC/D,SAAS,IAAI,OAAO;IAIpB,kEAAkE;IAClE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYtC,4CAA4C;IAC5C,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhD;;;;OAIG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASpC,OAAO,CAAC,4BAA4B;IAapC;;;OAGG;IACH,OAAO,CAAC,uBAAuB;CAahC;AAED,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { CommissionPayoutOptions, CommissionPayoutStatus, PayoutMethod } from '../types.js';
3
+ export declare class CommissionPayout extends SmrtObject {
4
+ /** Tenant ID for multi-tenant isolation (nullable → global payouts). */
5
+ tenantId: string | null;
6
+ /** The {@link Earner} being paid. Required. */
7
+ earnerId: string;
8
+ /** Start of the settlement period this batch covers (informational). */
9
+ periodStart: Date | null;
10
+ /** End of the settlement period this batch covers (informational). */
11
+ periodEnd: Date | null;
12
+ /** Σ amountCents of the Commissions this batch settled (integer cents). */
13
+ commissionTotalCents: number;
14
+ /**
15
+ * Σ signed amountCents of the Adjustments this batch settled (integer
16
+ * cents; clawbacks make it negative).
17
+ */
18
+ adjustmentTotalCents: number;
19
+ /**
20
+ * Net amount remitted — must equal
21
+ * `commissionTotalCents + adjustmentTotalCents` (enforced on save).
22
+ */
23
+ totalAmountCents: number;
24
+ /** ISO 4217 currency of the batch. */
25
+ currency: string;
26
+ /** Delivery method for this batch (defaulted from the Earner). */
27
+ payoutMethod: PayoutMethod;
28
+ /**
29
+ * Lifecycle status — see the class doc. Mutate via {@link approve} /
30
+ * {@link markProcessing} / {@link complete} / {@link fail} /
31
+ * {@link resetFromFailed}.
32
+ */
33
+ status: CommissionPayoutStatus;
34
+ /**
35
+ * Payment reference recorded at completion (check number, transfer id,
36
+ * …). Cleared by {@link resetFromFailed}.
37
+ */
38
+ paymentReference: string;
39
+ /**
40
+ * Opaque payout-provider reference (processor batch id, remittance file
41
+ * id, …). Retained across failure/reset for audit.
42
+ */
43
+ providerRef: string;
44
+ /** When the payout completed. */
45
+ paidAt: Date | null;
46
+ /**
47
+ * Optional link to the commerce Invoice that papers this payout
48
+ * (cross-package string reference — never a DDL foreign key).
49
+ */
50
+ invoiceId: string;
51
+ /** Operator notes — approval memos, failure reasons (append-only). */
52
+ notes: string;
53
+ /**
54
+ * Idempotency natural key. Required. The payout service defaults it to
55
+ * `` `${earnerId}:${currency}:${periodEnd ISO date}` `` when the caller
56
+ * doesn't supply one.
57
+ */
58
+ idempotencyKey: string;
59
+ /** Additional metadata as a JSON string. */
60
+ metadata: string;
61
+ constructor(options?: CommissionPayoutOptions);
62
+ /**
63
+ * Re-coerce timestamp fields after the framework reapplies raw option /
64
+ * hydrated row values, and record the loaded status for the save guard.
65
+ */
66
+ initialize(): Promise<this>;
67
+ isPending(): boolean;
68
+ isApproved(): boolean;
69
+ isProcessing(): boolean;
70
+ isCompleted(): boolean;
71
+ isFailed(): boolean;
72
+ /** `pending → approved`. Does NOT save — the caller saves. */
73
+ approve(): void;
74
+ /** `approved → processing`. Does NOT save — the caller saves. */
75
+ markProcessing(): void;
76
+ /**
77
+ * `processing → completed`. Requires a payment reference — a completed
78
+ * payout with no reference is untraceable. Stamps {@link paidAt}.
79
+ * Does NOT save — the caller saves.
80
+ */
81
+ complete(paymentReference: string, now?: Date): void;
82
+ /**
83
+ * `approved | processing → failed`. Appends the reason to {@link notes}.
84
+ * Does NOT save — the caller saves.
85
+ */
86
+ fail(reason: string): void;
87
+ /**
88
+ * Operator-driven reset: `failed → pending` after fixing whatever broke.
89
+ * Clears {@link paymentReference} and {@link paidAt} (the next attempt
90
+ * gets fresh ones) but RETAINS {@link providerRef} and {@link notes} for
91
+ * audit. The only path out of `failed`. Does NOT save — the caller saves.
92
+ */
93
+ resetFromFailed(): void;
94
+ /** Parse {@link metadata}; returns `{}` on empty/invalid JSON. */
95
+ getMetadata(): Record<string, unknown>;
96
+ /** Serialize and store {@link metadata}. */
97
+ setMetadata(data: Record<string, unknown>): void;
98
+ /**
99
+ * Save with two guards (commerce pattern):
100
+ *
101
+ * 1. **Totals invariant** — `totalAmountCents` must equal
102
+ * `commissionTotalCents + adjustmentTotalCents` (exact integer
103
+ * arithmetic, no epsilon).
104
+ * 2. **Status transition** — validated against the AUTHORITATIVE prior
105
+ * persisted status (re-read from the database so a
106
+ * `create({ id, _skipLoad: true })` upsert can't sidestep the guard).
107
+ * A `completed` payout additionally requires a payment reference,
108
+ * matching {@link complete}'s invariant, regardless of how the status
109
+ * was set.
110
+ */
111
+ save(): Promise<this>;
112
+ /** Throws when the totals invariant doesn't hold. */
113
+ validateTotals(): void;
114
+ private resolvePriorStatus;
115
+ private assertStatusTransition;
116
+ private static coerceDate;
117
+ }
118
+ export default CommissionPayout;
119
+ //# sourceMappingURL=CommissionPayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionPayout.d.ts","sourceRoot":"","sources":["../../../src/commissions/models/CommissionPayout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAIL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,YAAY,EACb,MAAM,aAAa,CAAC;AA6BrB,qBAYa,gBAAiB,SAAQ,UAAU;IAC9C,wEAAwE;IAExE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,+CAA+C;IAE/C,QAAQ,EAAE,MAAM,CAAM;IAEtB,wEAAwE;IACxE,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEhC,sEAAsE;IACtE,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B,2EAA2E;IAC3E,oBAAoB,EAAE,MAAM,CAAK;IAEjC;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAK;IAEjC;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAK;IAE7B,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAS;IAEzB,kEAAkE;IAClE,YAAY,EAAE,YAAY,CAAmB;IAE7C;;;;OAIG;IACH,MAAM,EAAE,sBAAsB,CAAa;IAE3C;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB,iCAAiC;IACjC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE3B;;;OAGG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAM;IAEnB;;;;OAIG;IAEH,cAAc,EAAE,MAAM,CAAM;IAE5B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,uBAA4B;IA+BjD;;;OAGG;IACY,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAa1C,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,OAAO;IAIrB,YAAY,IAAI,OAAO;IAIvB,WAAW,IAAI,OAAO;IAItB,QAAQ,IAAI,OAAO;IAMnB,8DAA8D;IAC9D,OAAO,IAAI,IAAI;IAkBf,iEAAiE;IACjE,cAAc,IAAI,IAAI;IAStB;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,GAAG,GAAE,IAAiB,GAAG,IAAI;IAgBhE;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAW1B;;;;;OAKG;IACH,eAAe,IAAI,IAAI;IAavB,kEAAkE;IAClE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYtC,4CAA4C;IAC5C,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAMhD;;;;;;;;;;;;OAYG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAcpC,qDAAqD;IACrD,cAAc,IAAI,IAAI;YAsBR,kBAAkB;IAgBhC,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,MAAM,CAAC,UAAU;CAS1B;AAED,eAAe,gBAAgB,CAAC"}