@happyvertical/smrt-commerce 0.40.70 → 0.41.0

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.
@@ -0,0 +1,86 @@
1
+ import { DatabaseInterface, MinorUnitsPreflightResult, MinorUnitsRescaleResult, MoneyColumnTarget } from '@happyvertical/smrt-core/migrations';
2
+ /** Marker recorded in `_smrt_backfills` once the column rescale has run. */
3
+ export declare const COMMERCE_MONEY_MINOR_UNITS_BACKFILL = "@happyvertical/smrt-commerce:money-minor-units:v1";
4
+ /**
5
+ * Every commerce money column denominated in the deployment's own currency,
6
+ * i.e. everything a single scale converts correctly.
7
+ *
8
+ * `invoices`, `invoice_line_items` and `payment_allocations` are absent on
9
+ * purpose: those were already INTEGER (#2361), so the preflight reports them as
10
+ * converted and there is nothing to rescale. Rate columns (`tax_rate`) are
11
+ * absent for the opposite reason — they are genuinely fractional and must stay
12
+ * DECIMAL. `payments.native_amount` is absent because its scale is per-asset;
13
+ * see {@link COMMERCE_NATIVE_UNIT_COLUMNS}.
14
+ */
15
+ export declare const COMMERCE_MONEY_COLUMNS: MoneyColumnTarget[];
16
+ /**
17
+ * Columns whose minor-unit scale is a property of the **row's** asset, not of
18
+ * the deployment — so no single `scale` converts them and they are excluded
19
+ * from {@link migrateCommerceMoneyToMinorUnits}.
20
+ *
21
+ * `payments.native_amount` holds "the amount the backend actually moved, in the
22
+ * native currency's own minor units": satoshis for `BTC` (×1e8), cents for
23
+ * `USDC-base` or `USD-stripe` (×1e2). A blanket ×100 would store 1 satoshi-ish
24
+ * nonsense for a 0.00713 BTC payment whose correct value is 713 000 sats, and
25
+ * a round amount like 0.01 BTC would even pass the preflight's integrality
26
+ * check while being wrong by six orders of magnitude.
27
+ *
28
+ * Convert it in two deliberate steps, from one deploy process, while the column
29
+ * is still floating-point:
30
+ *
31
+ * ```ts
32
+ * // 1. Normalise each row to its own asset's minor units, in the REAL column.
33
+ * for (const [currency, scale] of Object.entries({ BTC: 1e8, 'USDC-base': 100 })) {
34
+ * await db.query(
35
+ * 'UPDATE payments SET native_amount = round(native_amount * ?) WHERE native_currency = ?',
36
+ * scale,
37
+ * currency,
38
+ * );
39
+ * }
40
+ *
41
+ * // 2. Change the column type with no further scaling.
42
+ * await rescaleMoneyColumnsToMinorUnits(db, COMMERCE_NATIVE_UNIT_COLUMNS, {
43
+ * scale: 1,
44
+ * backfillName: '<your-app>:payments-native-amount-minor-units:v1',
45
+ * });
46
+ * ```
47
+ *
48
+ * Step 1 is deliberately yours to write: only the deployment knows which
49
+ * `native_currency` values it has used and what each one's exponent is.
50
+ */
51
+ export declare const COMMERCE_NATIVE_UNIT_COLUMNS: MoneyColumnTarget[];
52
+ /**
53
+ * Report what {@link migrateCommerceMoneyToMinorUnits} would do, without
54
+ * writing anything.
55
+ *
56
+ * @param db - Root database handle.
57
+ * @param options - `scale` (default 100) and `engineHint`.
58
+ * @returns Per-column state plus the rows that would lose information.
59
+ */
60
+ export declare function preflightCommerceMoneyMinorUnits(db: DatabaseInterface, options?: {
61
+ scale?: number;
62
+ engineHint?: string;
63
+ }): Promise<MinorUnitsPreflightResult>;
64
+ /**
65
+ * Convert every single-scale commerce money column from floating-point major
66
+ * units to integer minor units.
67
+ *
68
+ * Idempotent: guarded by a `_smrt_backfills` marker, so re-running can never
69
+ * multiply a table by the scale twice.
70
+ *
71
+ * Does **not** touch `payments.native_amount` or the `paymentOptions` JSON —
72
+ * see this module's header and {@link COMMERCE_NATIVE_UNIT_COLUMNS}.
73
+ *
74
+ * @param db - Root database handle.
75
+ * @param options - `scale` (default 100 — cents), `engineHint`, and `force` to
76
+ * convert despite rows the preflight flagged as lossy.
77
+ * @throws `MinorUnitsPreflightError` when a row would be rounded or would
78
+ * overflow `int4` and `force` was not set. Print
79
+ * {@link preflightCommerceMoneyMinorUnits}'s summary, fix the data, retry.
80
+ */
81
+ export declare function migrateCommerceMoneyToMinorUnits(db: DatabaseInterface, options?: {
82
+ scale?: number;
83
+ engineHint?: string;
84
+ force?: boolean;
85
+ }): Promise<MinorUnitsRescaleResult>;
86
+ //# sourceMappingURL=moneyMinorUnits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moneyMinorUnits.d.ts","sourceRoot":"","sources":["../../src/migrations/moneyMinorUnits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAEH,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EAGvB,MAAM,qCAAqC,CAAC;AAE7C,4EAA4E;AAC5E,eAAO,MAAM,mCAAmC,sDACK,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,EAAE,iBAAiB,EAiBrD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,EAE3D,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAC9C,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,OAAO,CAAC,yBAAyB,CAAC,CAEpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gCAAgC,CAC9C,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACrE,OAAO,CAAC,uBAAuB,CAAC,CAMlC"}
@@ -16,7 +16,7 @@ import { ContractOptions, ContractStatus, ContractType, LicenseSaleOptions } fro
16
16
  * const order = await contracts.create({
17
17
  * _meta_type: 'Order',
18
18
  * customerId: customer.id,
19
- * totalAmount: 1500.00,
19
+ * totalAmount: 150000, // $1,500.00 in cents
20
20
  * status: ContractStatus.DRAFT
21
21
  * });
22
22
  *
@@ -24,7 +24,7 @@ import { ContractOptions, ContractStatus, ContractType, LicenseSaleOptions } fro
24
24
  * const po = await contracts.create({
25
25
  * _meta_type: 'PurchaseOrder',
26
26
  * vendorId: vendor.id,
27
- * totalAmount: 5000.00,
27
+ * totalAmount: 500000, // $5,000.00 in cents
28
28
  * reference: 'PO-2024-001'
29
29
  * });
30
30
  * ```
@@ -52,15 +52,20 @@ export declare class Contract extends SmrtObject {
52
52
  */
53
53
  vendorId: string;
54
54
  /**
55
- * Subtotal before tax
55
+ * Subtotal before tax, in **integer minor units** (cents, satoshis).
56
+ *
57
+ * The `= 0` initializer is load-bearing: SMRT maps an integer literal to
58
+ * INTEGER and a decimal literal to DECIMAL. Money is exact, so it is stored
59
+ * as minor units and never as a float — `$19.99` is `1999`, not `19.99`
60
+ * (#2401).
56
61
  */
57
62
  subtotal: number;
58
63
  /**
59
- * Tax amount
64
+ * Tax amount, in integer minor units (#2401).
60
65
  */
61
66
  taxAmount: number;
62
67
  /**
63
- * Total amount including tax
68
+ * Total amount including tax, in integer minor units (#2401).
64
69
  */
65
70
  totalAmount: number;
66
71
  /**
@@ -136,10 +141,15 @@ export declare class Contract extends SmrtObject {
136
141
  */
137
142
  initialize(): Promise<this>;
138
143
  /**
139
- * Validate the status transition before persisting, then save. Inherited by
140
- * every STI subtype (Estimate/Order/Lease/.../LicenseSale), so a forged
141
- * `status` on any of them is caught here. LicenseSale layers its own
142
- * rights-immutability guard on top via `super.save()`. See S5 audit #1390.
144
+ * Validate the amounts and the status transition before persisting, then
145
+ * save. Inherited by every STI subtype (Estimate/Order/Lease/.../LicenseSale),
146
+ * so a forged `status` on any of them is caught here. LicenseSale layers its
147
+ * own rights-immutability guard on top via `super.save()`. See S5 audit
148
+ * #1390.
149
+ *
150
+ * `subtotal` / `taxAmount` / `totalAmount` are mass-assignable on the
151
+ * generated create/update routes, so the minor-units check runs on every
152
+ * write surface (#2401).
143
153
  */
144
154
  save(): Promise<this>;
145
155
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Contract.d.ts","sourceRoot":"","sources":["../../src/models/Contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Contract.d.ts","sourceRoot":"","sources":["../../src/models/Contract.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ import { ContractLineItemOptions } from '../types/index.js';
12
12
  * contractId: order.id,
13
13
  * description: 'Widget Pro',
14
14
  * quantity: 10,
15
- * unitPrice: 49.99,
15
+ * unitPrice: 4999, // $49.99 in cents
16
16
  * taxRate: 0.08
17
17
  * });
18
18
  * ```
@@ -32,23 +32,31 @@ export declare class ContractLineItem extends SmrtObject {
32
32
  */
33
33
  description: string;
34
34
  /**
35
- * Quantity ordered
35
+ * Quantity ordered. Decimal on purpose — contracts price fractional
36
+ * quantities (hours, weight, bandwidth), unlike `InvoiceLineItem.quantity`.
36
37
  */
37
38
  quantity: number;
38
39
  /**
39
- * Unit price before discount
40
+ * Unit price before discount, in **integer minor units** (cents, satoshis).
41
+ *
42
+ * The `= 0` initializer is load-bearing: SMRT maps an integer literal to
43
+ * INTEGER and a decimal literal to DECIMAL. Money is exact, so `$49.99` is
44
+ * `4999` (#2401).
40
45
  */
41
46
  unitPrice: number;
42
47
  /**
43
- * Discount amount (flat, not percentage)
48
+ * Discount amount (flat, not percentage), in integer minor units (#2401).
44
49
  */
45
50
  discount: number;
46
51
  /**
47
- * Tax rate as decimal (e.g., 0.08 for 8%)
52
+ * Tax rate as decimal (e.g., 0.08 for 8%). A rate is inherently fractional,
53
+ * so it stays DECIMAL — INTEGER would truncate every meaningful value.
48
54
  */
49
55
  taxRate: number;
50
56
  /**
51
- * Calculated line amount (qty * price - discount + tax)
57
+ * Calculated line amount (qty * price - discount + tax), in integer minor
58
+ * units. Derived by {@link ContractLineItem.calculateAmount}, which rounds
59
+ * the fractional tax to a whole minor unit (#2401).
52
60
  */
53
61
  amount: number;
54
62
  /**
@@ -77,7 +85,13 @@ export declare class ContractLineItem extends SmrtObject {
77
85
  sortOrder: number;
78
86
  constructor(options?: ContractLineItemOptions);
79
87
  /**
80
- * Calculate the line amount
88
+ * Calculate the line amount, in integer minor units.
89
+ *
90
+ * `quantity` is decimal and `taxRate` is a fraction, so the product is not
91
+ * generally a whole number of minor units. Rounding happens here — at the
92
+ * one boundary where a rate meets money — so that every value that reaches a
93
+ * money column is already exact and every downstream comparison can be a
94
+ * plain `===` instead of an epsilon tolerance (#2401).
81
95
  */
82
96
  calculateAmount(): number;
83
97
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ContractLineItem.d.ts","sourceRoot":"","sources":["../../src/models/ContractLineItem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAOa,gBAAiB,SAAQ,UAAU;IAC9C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAO;IAEvB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAO;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAO;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAO;IAEtB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAO;IAErB;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAM;IAEjB;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B;;OAEG;IACH,OAAO,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE5B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;gBAEV,OAAO,GAAE,uBAA4B;IAoBjD;;OAEG;IACH,eAAe,IAAI,MAAM;IAMzB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,oBAAoB,IAAI,OAAO;CAUhC;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"ContractLineItem.d.ts","sourceRoot":"","sources":["../../src/models/ContractLineItem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAOa,gBAAiB,SAAQ,UAAU;IAC9C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAO;IAEvB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAK;IAEtB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAO;IAEtB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAK;IAEnB;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAM;IAEjB;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B;;OAEG;IACH,OAAO,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE5B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;gBAEV,OAAO,GAAE,uBAA4B;IAoBjD;;;;;;;;OAQG;IACH,eAAe,IAAI,MAAM;IAMzB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,oBAAoB,IAAI,OAAO;CAUhC;AAED,eAAe,gBAAgB,CAAC"}
@@ -27,7 +27,13 @@ export declare class Customer extends SmrtObject {
27
27
  */
28
28
  profileId: string;
29
29
  /**
30
- * Maximum credit extended to this customer
30
+ * Maximum credit extended to this customer, in **integer minor units**
31
+ * (cents, satoshis).
32
+ *
33
+ * Converts with the rest of commerce because
34
+ * {@link Customer.hasAvailableCredit} compares it directly against a money
35
+ * amount; a dollars-vs-cents split there would approve every request off by
36
+ * a factor of 100 (#2401).
31
37
  */
32
38
  creditLimit: number;
33
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Customer.d.ts","sourceRoot":"","sources":["../../src/models/Customer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;GAcG;AACH,qBAMa,QAAS,SAAQ,UAAU;IACtC;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;OAGG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAO;IAE1B;;OAEG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAS;IAE3B;;;;;OAKG;IAEH,KAAK,EAAE,MAAM,CAAM;IAEnB;;OAEG;IACH,sBAAsB,EAAE,OAAO,CAAM;IAErC;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAM;IAEpC;;OAEG;IACH,MAAM,EAAE,cAAc,CAAyB;IAE/C;;;;;OAKG;IACH,YAAY,EAAE,YAAY,CAAoB;IAE9C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,eAAoB;IA4BzC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAK3C;;;;;;;;;;OAUG;IACH,YAAY,IAAI,MAAM;CAGvB;AAED,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Customer.d.ts","sourceRoot":"","sources":["../../src/models/Customer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;GAcG;AACH,qBAMa,QAAS,SAAQ,UAAU;IACtC;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;;OAGG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;;;;;;;OAQG;IACH,WAAW,EAAE,MAAM,CAAK;IAExB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAS;IAE3B;;;;;OAKG;IAEH,KAAK,EAAE,MAAM,CAAM;IAEnB;;OAEG;IACH,sBAAsB,EAAE,OAAO,CAAM;IAErC;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAM;IAEpC;;OAEG;IACH,MAAM,EAAE,cAAc,CAAyB;IAE/C;;;;;OAKG;IACH,YAAY,EAAE,YAAY,CAAoB;IAE9C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,eAAoB;IA4BzC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAK3C;;;;;;;;;;OAUG;IACH,YAAY,IAAI,MAAM;CAGvB;AAED,eAAe,QAAQ,CAAC"}
@@ -69,19 +69,25 @@ export declare class Invoice extends SmrtObject {
69
69
  */
70
70
  paidDate: Date | null;
71
71
  /**
72
- * Subtotal before tax
72
+ * Subtotal before tax, in **integer minor units** (cents, satoshis).
73
+ *
74
+ * The `= 0` initializer is load-bearing: SMRT maps an integer literal to
75
+ * INTEGER and a decimal literal to DECIMAL. Money is exact, so it is stored
76
+ * as minor units and never as a float — `$19.99` is `1999`, not `19.99`.
77
+ * Writing a fractional major-unit value here is the bug; PostgreSQL rejects
78
+ * it with `22P02` while SQLite's affinity silently stores it (#2361).
73
79
  */
74
80
  subtotal: number;
75
81
  /**
76
- * Tax amount
82
+ * Tax amount, in integer minor units (#2361).
77
83
  */
78
84
  taxAmount: number;
79
85
  /**
80
- * Total amount due (subtotal + tax)
86
+ * Total amount due (subtotal + tax), in integer minor units (#2361).
81
87
  */
82
88
  totalAmount: number;
83
89
  /**
84
- * Amount paid (sum of PaymentAllocations)
90
+ * Amount paid (sum of PaymentAllocations), in integer minor units (#2361).
85
91
  */
86
92
  amountPaid: number;
87
93
  /**
@@ -169,8 +175,12 @@ export declare class Invoice extends SmrtObject {
169
175
  * `totalAmount === subtotal + taxAmount` arithmetic invariant is enforced.
170
176
  * - **amountPaid is derived/validated.** When persisted, it is recomputed
171
177
  * from PaymentAllocations rather than trusted from the caller. It may
172
- * never exceed `totalAmount` (beyond rounding tolerance).
173
- * - **Non-negativity** is enforced on all four amounts.
178
+ * never exceed `totalAmount`.
179
+ * - **Whole minor units and non-negativity** are enforced on all four
180
+ * amounts. The integer check runs FIRST (#2401), before the
181
+ * `totalAmount === subtotal + taxAmount` invariant, so a caller who wrote
182
+ * major units gets "money is minor units" rather than a confusing
183
+ * arithmetic-mismatch error from float addition.
174
184
  * - **Status transitions** are validated against the prior persisted status.
175
185
  */
176
186
  save(): Promise<this>;
@@ -192,23 +202,21 @@ export declare class Invoice extends SmrtObject {
192
202
  */
193
203
  private recomputeAmountsForSave;
194
204
  /**
195
- * Whether `amountPaid` covers `totalAmount` within the sub-cent rounding
196
- * tolerance. This is the SINGLE source of truth for the **PAID** decision —
197
- * both {@link updatePaymentStatus} (which decides PAID) and
198
- * {@link assertPaymentStatusConsistent} (which validates PAID on save) call
199
- * it, so the PAID-deciding comparison and the PAID-validating comparison can
200
- * never drift apart. A strict `amountPaid >= totalAmount` here would diverge
201
- * from the epsilon-tolerant guard: a float-summed total paid exactly (e.g.
202
- * `0.1 × 3` line items paid `0.3`) reads as "not covered" by `>=` but
203
- * "covered" by the guard, so `updatePaymentStatus` would set PARTIAL and the
204
- * save-time guard would then reject it — leaving a genuinely-paid invoice
205
- * unsaveable (S5 audit #1390 follow-up).
205
+ * Whether `amountPaid` covers `totalAmount`. This is the SINGLE source of
206
+ * truth for the **PAID** decision — both {@link updatePaymentStatus} (which
207
+ * decides PAID) and {@link assertPaymentStatusConsistent} (which validates
208
+ * PAID on save) call it, so the PAID-deciding comparison and the
209
+ * PAID-validating comparison can never drift apart (S5 audit #1390
210
+ * follow-up).
206
211
  *
207
- * NOTE: the claim is scoped to PAID. The PARTIAL branch is NOT unified the
208
- * same way{@link updatePaymentStatus} treats any `amountPaid > 0` as
209
- * PARTIAL, whereas {@link isPartiallyPaid} (used by the save-time guard)
210
- * requires `amountPaid > INVOICE_EPSILON`. That pre-existing asymmetry only
211
- * matters for a sub-cent dust payment and is intentionally left as-is.
212
+ * With integer minor units this is a plain `>=` (#2401). The float-era
213
+ * hazard it used to guard against a total summed from `0.1 × 3` line items
214
+ * reading as "not covered" by `>=` but "covered" by an epsilon-tolerant
215
+ * guard, leaving a genuinely-paid invoice unsaveable cannot arise when both
216
+ * sides are exact integers. That also removes the documented PAID/PARTIAL
217
+ * asymmetry: {@link updatePaymentStatus} and {@link isPartiallyPaid} now
218
+ * agree that any `amountPaid > 0` is a partial payment, because there is no
219
+ * such thing as sub-cent dust.
212
220
  */
213
221
  private isFullyPaid;
214
222
  /**
@@ -231,26 +239,24 @@ export declare class Invoice extends SmrtObject {
231
239
  */
232
240
  private assertPaymentStatusConsistent;
233
241
  /**
234
- * Enforce `totalAmount === subtotal + taxAmount` (within rounding tolerance),
235
- * then SNAP `totalAmount` to the exact arithmetic. Used when the invoice has
236
- * no line items to recompute from.
242
+ * Enforce `totalAmount === subtotal + taxAmount` exactly. Used when the
243
+ * invoice has no line items to recompute from.
237
244
  *
238
- * The snap closes the invoice-vs-ledger epsilon gap (S5 audit #1390
239
- * follow-up): the invoice guard tolerates `INVOICE_EPSILON` (0.01) but the
240
- * smrt-ledgers balance check uses a tighter `BALANCE_EPSILON` (0.001). A
241
- * no-line-item invoice with, say, subtotal 100.00 / total 100.005 passes this
242
- * guard, yet `recognizeRevenue` would build DR 100.005 / CR 100.00 and
243
- * `journal.post()` would reject it as unbalanced voiding the journal and
244
- * permanently blocking revenue recognition. Snapping `totalAmount` to
245
- * `subtotal + taxAmount` here (after the tolerance check) means the persisted
246
- * total and every journal built from it are always ledger-consistent.
245
+ * Exact because every term is integer minor units (#2401). The float era
246
+ * needed a `0.01` tolerance here and then had to SNAP `totalAmount` to the
247
+ * recomputed value afterwards, because a total that passed the invoice's
248
+ * loose tolerance could still fail smrt-ledgers' tighter `BALANCE_EPSILON`
249
+ * and void the journal `recognizeRevenue` builds from it. Integer arithmetic
250
+ * removes both halves of that workaround: what the caller supplied either is
251
+ * the sum or is rejected, and any journal built from it balances exactly.
247
252
  */
248
253
  private assertTotalArithmetic;
249
254
  /**
250
- * Reject negative financial values and an amountPaid that exceeds the total
251
- * (beyond rounding tolerance overpayment is modelled elsewhere, not by
252
- * letting amountPaid float above the invoice total).
255
+ * Reject amounts that are not whole minor units, negative financial values,
256
+ * and an amountPaid that exceeds the total (overpayment is modelled
257
+ * elsewhere, not by letting amountPaid float above the invoice total).
253
258
  */
259
+ private assertAmountsAreMinorUnits;
254
260
  private assertNonNegativeAmounts;
255
261
  /**
256
262
  * Reject an illegal status flip done via raw field assignment. Compares the
@@ -1 +1 @@
1
- {"version":3,"file":"Invoice.d.ts","sourceRoot":"","sources":["../../src/models/Invoice.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Invoice.d.ts","sourceRoot":"","sources":["../../src/models/Invoice.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ import { AccountingLineItemInput, InvoiceLineItemOptions } from '../types/index.
12
12
  * invoiceId: invoice.id,
13
13
  * description: 'Display Advertising - Summer Campaign',
14
14
  * quantity: 50000, // impressions
15
- * unitPrice: 0.01, // per impression
15
+ * unitPrice: 1, // 1 cent per impression (minor units)
16
16
  * taxRate: 0.05,
17
17
  * sourceType: 'campaign',
18
18
  * sourceId: 'campaign-uuid',
@@ -40,23 +40,37 @@ export declare class InvoiceLineItem extends SmrtObject {
40
40
  */
41
41
  sku: string;
42
42
  /**
43
- * Quantity (e.g., impressions, hours, units)
43
+ * Quantity (e.g., impressions, hours, units).
44
+ *
45
+ * Left INTEGER: this package's own example is `quantity: 50000` impressions,
46
+ * and nothing in it writes a fractional quantity, so whether fractional
47
+ * quantities are intended here is unresolved. `ContractLineItem.quantity` is
48
+ * decimal, which is the inconsistency to settle deliberately rather than by
49
+ * changing a column type in passing (#2361).
44
50
  */
45
51
  quantity: number;
46
52
  /**
47
- * Unit price before discount
53
+ * Unit price before discount, in **integer minor units** (cents, satoshis).
54
+ *
55
+ * Money is exact, so it is stored as minor units and never as a float —
56
+ * `$19.99` is `1999`. An integer literal is what maps this to an INTEGER
57
+ * column (#2361).
48
58
  */
49
59
  unitPrice: number;
50
60
  /**
51
- * Discount amount (flat, not percentage)
61
+ * Discount amount (flat, not percentage), in integer minor units (#2361).
52
62
  */
53
63
  discount: number;
54
64
  /**
55
- * Tax rate as decimal (e.g., 0.05 for 5%)
65
+ * Tax rate as a decimal fraction (e.g., 0.05 for 5%).
66
+ *
67
+ * A genuine rate, not money: it is inherently fractional, so the `0.0`
68
+ * initializer is load-bearing and maps it to a DECIMAL column. INTEGER would
69
+ * truncate every rate to 0 (#2361).
56
70
  */
57
71
  taxRate: number;
58
72
  /**
59
- * Calculated line amount
73
+ * Calculated line amount, in integer minor units (#2361).
60
74
  */
61
75
  amount: number;
62
76
  /**
@@ -86,9 +100,10 @@ export declare class InvoiceLineItem extends SmrtObject {
86
100
  sortOrder: number;
87
101
  constructor(options?: InvoiceLineItemOptions);
88
102
  /**
89
- * Calculate the line amount.
103
+ * Calculate the line amount, in integer minor units.
90
104
  *
91
- * Formula: (quantity * unitPrice - discount) * (1 + taxRate)
105
+ * Formula: `getSubtotal() + getTaxAmount()`, i.e.
106
+ * `(quantity * unitPrice - discount) * (1 + taxRate)` with the tax rounded.
92
107
  *
93
108
  * Tax is calculated on the discounted subtotal. This follows the common
94
109
  * "discount before tax" approach used in most North American jurisdictions.
@@ -97,11 +112,20 @@ export declare class InvoiceLineItem extends SmrtObject {
97
112
  */
98
113
  calculateAmount(): number;
99
114
  /**
100
- * Get subtotal (before tax)
115
+ * Get subtotal (before tax), in integer minor units.
116
+ *
117
+ * `quantity` is an integer and `unitPrice` / `discount` are integer minor
118
+ * units, so this is exact with no rounding.
101
119
  */
102
120
  getSubtotal(): number;
103
121
  /**
104
- * Get tax amount
122
+ * Get tax amount, in integer minor units.
123
+ *
124
+ * `taxRate` is a genuine fraction, so this product is where a rate meets
125
+ * money and the only place rounding is needed. Rounding here — rather than
126
+ * letting a fractional tax leak into `Invoice.taxAmount` — is what lets the
127
+ * invoice's guards compare integers exactly instead of tolerating an epsilon
128
+ * (#2401).
105
129
  */
106
130
  getTaxAmount(): number;
107
131
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"InvoiceLineItem.d.ts","sourceRoot":"","sources":["../../src/models/InvoiceLineItem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAMa,eAAgB,SAAQ,UAAU;IAC7C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAM;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;IAEtB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAK;IAEpB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAK;IAMnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAM9B;;;OAGG;IAEH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;gBAEV,OAAO,GAAE,sBAA2B;IAsBhD;;;;;;;;;OASG;IACH,eAAe,IAAI,MAAM;IAMzB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,oBAAoB,IAAI,uBAAuB;CAahD;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"InvoiceLineItem.d.ts","sourceRoot":"","sources":["../../src/models/InvoiceLineItem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAMa,eAAgB,SAAQ,UAAU;IAC7C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAM;IAEjB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAK;IAEtB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAO;IAEtB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAK;IAMnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAM9B;;;OAGG;IAEH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;gBAEV,OAAO,GAAE,sBAA2B;IAsBhD;;;;;;;;;;OAUG;IACH,eAAe,IAAI,MAAM;IAIzB;;;;;OAKG;IACH,WAAW,IAAI,MAAM;IAIrB;;;;;;;;OAQG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,oBAAoB,IAAI,uBAAuB;CAahD;AAED,eAAe,eAAe,CAAC"}
@@ -41,7 +41,12 @@ export declare class Payment extends SmrtObject {
41
41
  */
42
42
  customerId: string;
43
43
  /**
44
- * Payment amount
44
+ * Payment amount, in **integer minor units** (cents, satoshis).
45
+ *
46
+ * The `= 0` initializer is load-bearing: SMRT maps an integer literal to
47
+ * INTEGER and a decimal literal to DECIMAL. This is the figure
48
+ * `PaymentAllocation.save()` caps allocations against and `Invoice.amountPaid`
49
+ * is summed from, so it must be in the same exact units as both (#2401).
45
50
  */
46
51
  amount: number;
47
52
  /**
@@ -110,10 +115,15 @@ export declare class Payment extends SmrtObject {
110
115
  */
111
116
  backendTxRef: string;
112
117
  /**
113
- * The amount the backend actually moved, in its own native currency.
114
- * For stablecoin rails this typically equals `amount`; for volatile-
115
- * currency rails (BTC, ETH) it's the satoshi/wei figure that the chain
116
- * recorded, independent of any USD valuation.
118
+ * The amount the backend actually moved, in the native currency's own
119
+ * **integer minor units** satoshis for BTC, cents for a fiat rail. For
120
+ * stablecoin rails this typically equals `amount`; for volatile-currency
121
+ * rails it's the satoshi/wei figure the chain recorded, independent of any
122
+ * USD valuation.
123
+ *
124
+ * Range note (#2401): INTEGER is `int4` on PostgreSQL, so this column tops
125
+ * out near 2.1e9 minor units — about 21 BTC in satoshis. Widening to BIGINT
126
+ * is the decision parked in #2373; INTEGER→BIGINT is a plain widening later.
117
127
  */
118
128
  nativeAmount: number;
119
129
  /**
@@ -126,18 +136,22 @@ export declare class Payment extends SmrtObject {
126
136
  nativeCurrency: string;
127
137
  /**
128
138
  * USD valuation of the payment at the moment the price was quoted to
129
- * the buyer (typically the moment a `PaymentIntent` was issued).
130
- * Stored at decimal precision; empty default `0.0` means no USD-quote
139
+ * the buyer (typically the moment a `PaymentIntent` was issued), in
140
+ * **integer minor units** (US cents). A default of `0` means no USD-quote
131
141
  * snapshot was taken (the payment was already USD-denominated or the
132
142
  * backend doesn't require drift accounting).
143
+ *
144
+ * This is money describing the same funds as {@link Payment.amount}, so it
145
+ * converts with it — a dollars-here / cents-there split would make
146
+ * {@link Payment.usdDrift} meaningless (#2401).
133
147
  */
134
148
  usdAtQuote: number;
135
149
  /**
136
150
  * USD valuation of the payment at the moment it was confirmed on the
137
- * backend (chain confirmation, gateway settlement, etc.). The delta
138
- * between {@link usdAtQuote} and `usdAtConfirmation` is the USD drift
139
- * the operator absorbs (positive or negative) when accepting payment
140
- * in a volatile native currency.
151
+ * backend (chain confirmation, gateway settlement, etc.), in integer minor
152
+ * units (US cents). The delta between {@link usdAtQuote} and
153
+ * `usdAtConfirmation` is the USD drift the operator absorbs (positive or
154
+ * negative) when accepting payment in a volatile native currency (#2401).
141
155
  */
142
156
  usdAtConfirmation: number;
143
157
  constructor(options?: PaymentOptions);
@@ -239,6 +253,12 @@ export declare class Payment extends SmrtObject {
239
253
  * - Debit: Cash/Bank account (assets increase)
240
254
  * - Credit: Accounts Receivable (receivables decrease)
241
255
  *
256
+ * Both sides carry `this.amount`, so the journal posted from commerce is
257
+ * denominated in **integer minor units** like the rest of this package
258
+ * (#2401). smrt-ledgers is unit-agnostic — its `BALANCE_EPSILON` only checks
259
+ * that debits equal credits — and integer entries balance exactly, so this is
260
+ * strictly tighter than the major-unit journals commerce used to post.
261
+ *
242
262
  * @param options - Ledger and account configuration
243
263
  * @returns The created journal
244
264
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Payment.d.ts","sourceRoot":"","sources":["../../src/models/Payment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EACL,aAAa,EACb,KAAK,cAAc,EACnB,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AA6C3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBA8Ca,OAAQ,SAAQ,UAAU;IACrC;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAO;IAErB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAS;IAEzB;;OAEG;IACH,MAAM,EAAE,aAAa,CAA+B;IAEpD;;OAEG;IACH,MAAM,EAAE,aAAa,CAAyB;IAE9C;;OAEG;IACH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;IAMnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;OAEG;IACH,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAQ;IAiB7B;;;;;;;;;;OAUG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAO;IAE3B;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAM;IAE5B;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAO;IAEzB;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,CAAO;gBAEpB,OAAO,GAAE,cAAmB;IA+BxC;;;;;OAKG;IACY,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDpC;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;;;;;;;;;;;;;;OAeG;YACW,gBAAgB;IAa9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,6BAA6B;IA0CrC;;;;;;OAMG;IACH,QAAQ,IAAI,MAAM;IAKlB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;;;;;;;;;;;;;;;;OAmBG;IACG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4DpE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAa3C;;OAEG;IACH,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAOjC;;OAEG;IACH,MAAM,IAAI,IAAI;CAMf;AAED,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Payment.d.ts","sourceRoot":"","sources":["../../src/models/Payment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAG3D,OAAO,EACL,aAAa,EACb,KAAK,cAAc,EACnB,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AA6C3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBA8Ca,OAAQ,SAAQ,UAAU;IACrC;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAK;IAEnB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAS;IAEzB;;OAEG;IACH,MAAM,EAAE,aAAa,CAA+B;IAEpD;;OAEG;IACH,MAAM,EAAE,aAAa,CAAyB;IAE9C;;OAEG;IACH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;IAMnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;OAEG;IACH,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAQ;IAiB7B;;;;;;;;;;OAUG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAM;IAE1B;;;;;;;;;;OAUG;IACH,YAAY,EAAE,MAAM,CAAK;IAEzB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAM;IAE5B;;;;;;;;;;OAUG;IACH,UAAU,EAAE,MAAM,CAAK;IAEvB;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,CAAK;gBAElB,OAAO,GAAE,cAAmB;IA+BxC;;;;;OAKG;IACY,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6DpC;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;;;;;;;;;;;;;;OAeG;YACW,gBAAgB;IAa9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,6BAA6B;IA0CrC;;;;;;OAMG;IACH,QAAQ,IAAI,MAAM;IAKlB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4DpE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAa3C;;OAEG;IACH,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAOjC;;OAEG;IACH,MAAM,IAAI,IAAI;CAMf;AAED,eAAe,OAAO,CAAC"}
@@ -20,7 +20,7 @@ import { PaymentAllocationOptions } from '../types/index.js';
20
20
  * // Get the collection
21
21
  * const allocations = await PaymentAllocationCollection.create(options);
22
22
  *
23
- * // Check available funds before allocating
23
+ * // Check available funds before allocating (all amounts are minor units)
24
24
  * const available = await allocations.getUnallocatedFromPayment(
25
25
  * payment.id,
26
26
  * payment.amount
@@ -56,7 +56,14 @@ export declare class PaymentAllocation extends SmrtObject {
56
56
  */
57
57
  invoiceId: string;
58
58
  /**
59
- * Amount allocated from payment to invoice
59
+ * Amount allocated from payment to invoice, in **integer minor units**
60
+ * (cents, satoshis).
61
+ *
62
+ * Matches `Invoice.amountPaid` (derived by summing these rows) and
63
+ * `Payment.amount` (which `save()` caps against). All three converted
64
+ * together in #2401 — the cap is a subtraction across the pair, so a
65
+ * dollars-vs-cents split there would reject every allocation as
66
+ * over-applying.
60
67
  */
61
68
  amount: number;
62
69
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"PaymentAllocation.d.ts","sourceRoot":"","sources":["../../src/models/PaymentAllocation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAQlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAoBa,iBAAkB,SAAQ,UAAU;IAC/C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAK;IAEnB;;OAEG;IACH,WAAW,EAAE,IAAI,CAAc;IAE/B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,wBAA6B;IAalD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAmFrC;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"PaymentAllocation.d.ts","sourceRoot":"","sources":["../../src/models/PaymentAllocation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAGxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAYlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAoBa,iBAAkB,SAAQ,UAAU;IAC/C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;;;;;;;;OASG;IACH,MAAM,EAAE,MAAM,CAAK;IAEnB;;OAEG;IACH,WAAW,EAAE,IAAI,CAAc;IAE/B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,wBAA6B;IAalD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAqFrC;AAED,eAAe,iBAAiB,CAAC"}