@happyvertical/smrt-commerce 0.55.13 → 0.55.15

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 (55) hide show
  1. package/AGENTS.md +8 -0
  2. package/README.md +36 -0
  3. package/agents/cost-billing.md +41 -0
  4. package/agents/payment-allocations.md +45 -0
  5. package/agents/purchasing-ui.md +27 -0
  6. package/dist/allocation-integrity.d.ts +13 -0
  7. package/dist/allocation-integrity.d.ts.map +1 -0
  8. package/dist/billing/payment-attempts.d.ts.map +1 -1
  9. package/dist/chunks/money-DfrRxrel.js +50 -0
  10. package/dist/chunks/money-DfrRxrel.js.map +1 -0
  11. package/dist/chunks/{types-CRnln577.js → types-zVnIjSOk.js} +29 -2
  12. package/dist/chunks/{types-CRnln577.js.map → types-zVnIjSOk.js.map} +1 -1
  13. package/dist/collections/PaymentAllocationCollection.d.ts +14 -0
  14. package/dist/collections/PaymentAllocationCollection.d.ts.map +1 -1
  15. package/dist/cost-billing.d.ts +58 -0
  16. package/dist/cost-billing.d.ts.map +1 -0
  17. package/dist/cost-billing.js +126 -0
  18. package/dist/cost-billing.js.map +1 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +175 -93
  22. package/dist/index.js.map +1 -1
  23. package/dist/manifest.json +43 -2
  24. package/dist/models/Contract.d.ts +7 -1
  25. package/dist/models/Contract.d.ts.map +1 -1
  26. package/dist/models/Invoice.d.ts.map +1 -1
  27. package/dist/models/Payment.d.ts +2 -0
  28. package/dist/models/Payment.d.ts.map +1 -1
  29. package/dist/models/PaymentAllocation.d.ts +7 -33
  30. package/dist/models/PaymentAllocation.d.ts.map +1 -1
  31. package/dist/playground.js +23 -0
  32. package/dist/playground.js.map +1 -1
  33. package/dist/smrt-knowledge.json +86 -8
  34. package/dist/svelte/components/PurchaseOrderHeaderForm.svelte +106 -0
  35. package/dist/svelte/components/PurchaseOrderHeaderForm.svelte.d.ts +49 -0
  36. package/dist/svelte/components/PurchaseOrderHeaderForm.svelte.d.ts.map +1 -0
  37. package/dist/svelte/index.d.ts +4 -0
  38. package/dist/svelte/index.d.ts.map +1 -1
  39. package/dist/svelte/index.js +3 -0
  40. package/dist/svelte/playground.d.ts +93 -0
  41. package/dist/svelte/playground.d.ts.map +1 -1
  42. package/dist/svelte/playground.js +20 -0
  43. package/dist/svelte/purchasing-i18n.d.ts +9 -0
  44. package/dist/svelte/purchasing-i18n.d.ts.map +1 -1
  45. package/dist/svelte/purchasing-i18n.js +9 -0
  46. package/dist/svelte/purchasing-types.d.ts +13 -0
  47. package/dist/svelte/purchasing-types.d.ts.map +1 -1
  48. package/dist/types/index.d.ts +7 -0
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/ui.d.ts.map +1 -1
  51. package/dist/ui.js +9 -0
  52. package/dist/ui.js.map +1 -1
  53. package/package.json +16 -12
  54. package/dist/chunks/money-WSMvSgWq.js +0 -8
  55. package/dist/chunks/money-WSMvSgWq.js.map +0 -1
package/AGENTS.md CHANGED
@@ -31,6 +31,9 @@ recipes show carry `@field({ description })` text; keep both in plain
31
31
  language for end users and update them when a recipe's fields change. See
32
32
  [core recipes](../core/agents/recipes.md).
33
33
 
34
+ See [payment allocation integrity](agents/payment-allocations.md) for atomic splits,
35
+ retry identity, parent corrections and supported dialects.
36
+
34
37
  ## Ledger Integration
35
38
 
36
39
  `@happyvertical/smrt-ledgers` is a regular dependency, loaded lazily via dynamic `import()` so the coupling stays runtime-only (no hard static import; the package graph stays a DAG — see #1582). Invoice stores `arJournalId` and `revenueJournalId` as string references. `recognizeRevenue()` creates a balanced AR journal entry; `getArJournal()` returns null when no journal has been recognized yet.
@@ -193,3 +196,8 @@ extension conventions are documented in [agents/quote-ui.md](agents/quote-ui.md)
193
196
  `PurchaseOrderEditor` preserves allocation IDs and explicit zeroes, including
194
197
  retained reduction rows; the server validates review fingerprints before recording.
195
198
  See [agents/purchasing-ui.md](agents/purchasing-ui.md) for caller responsibilities.
199
+
200
+ ## Exact cost billing
201
+
202
+ Pure signed cost billing and explicit tax rounding are available through the
203
+ independent `cost-billing` subpath; see [contract](agents/cost-billing.md).
package/README.md CHANGED
@@ -107,6 +107,13 @@ await payment.recordPayment({
107
107
 
108
108
  `CustomerCollection`, `VendorCollection`, `ContractCollection`, `InvoiceCollection`, `InvoiceLineItemCollection`, `PaymentCollection`, `PaymentAllocationCollection`, `FulfillmentCollection`
109
109
 
110
+ `PaymentAllocationCollection.allocatePayment()` splits a payment across invoices
111
+ in one transaction using stable allocation IDs for retries. Direct allocation
112
+ saves also enforce matching owners, customers and currencies and both balance
113
+ caps. Read [payment allocation integrity](agents/payment-allocations.md) for
114
+ replay, parent revision refresh and compatibility requirements.
115
+
116
+
110
117
  ### Enums
111
118
 
112
119
  | Export | Values |
@@ -137,6 +144,18 @@ await payment.recordPayment({
137
144
 
138
145
  Invoice and Payment integrate with `@happyvertical/smrt-ledgers` via dynamic import (optional dependency). Invoice stores `arJournalId` and `revenueJournalId` as plain string references to ledger journals. `recognizeRevenue()` creates a balanced AR entry (DR: Accounts Receivable, CR: Revenue, CR: Tax Payable). `recordPayment()` creates a balanced cash receipt entry (DR: Cash, CR: Accounts Receivable). Both methods return null or throw if the ledgers package is not installed.
139
146
 
147
+ `Payment.recordPayment()` claims the payment revision and commits the journal,
148
+ entries, and completed payment in one database transaction. A failed completion
149
+ rolls back the posting and restores the instance's settlement fields for retry.
150
+ The claimed persisted status is authoritative even if a caller locally resets
151
+ status or marks the instance failed without saving. Concurrent or stale instances
152
+ fail instead of posting twice; reload the payment
153
+ and retry only if it is still pending. An already completed payment retains the
154
+ `Payment already recorded` error. A caller's enclosing transaction remains the
155
+ owner: if it rolls back after settlement returns, reload the payment before retry.
156
+ These guarantees cover new postings, not orphaned journals written by older
157
+ versions. The returned journal uses the caller's database executor.
158
+
140
159
  ### Cross-Package References
141
160
 
142
161
  Customer and Vendor link to `@happyvertical/smrt-profiles` via plain `profileId` string. Invoice and Payment reference `@happyvertical/smrt-ledgers` journals via plain string IDs (`arJournalId`, `revenueJournalId`, `journalId`). All models use `@TenantScoped({ mode: 'optional' })` with nullable `tenantId`.
@@ -576,3 +595,20 @@ for server handlers from `@happyvertical/smrt-commerce/invoices`.
576
595
  caller-owned sources and approvals. See [the editor contract](agents/invoice-preparation.md),
577
596
  [calculation rules](agents/invoice-calculations.md), and the required
578
597
  [existing-database storage migration](agents/invoice-quantity.md).
598
+
599
+ ## Exact cost billing
600
+
601
+ The independent `@happyvertical/smrt-commerce/cost-billing` entry point provides
602
+ exact signed reimbursement/fee calculations, ordered generic markup provenance,
603
+ and explicit line or invoice tax rounding. See [the cost billing contract](agents/cost-billing.md).
604
+ It does not alter Invoice persistence, editor defaults or settlement behavior.
605
+
606
+ ### Purchase-order header editing
607
+
608
+ Import `PurchaseOrderHeaderForm` from `@happyvertical/smrt-commerce/svelte` for a
609
+ native POST of vendor, reference, notes, expected date and ship-to fields. Pass
610
+ `action`, `vendors` and raw `values`; return canonical field `errors` and the same
611
+ `hiddenFields` after server validation. This header-only form leaves purchase
612
+ allocations and totals unchanged. `PurchaseOrder` stores `expectedDate` and
613
+ `shipTo` in existing STI metadata. See [the purchasing contract](agents/purchasing-ui.md#purchase-order-header)
614
+ for validation, retained values and transport details.
@@ -0,0 +1,41 @@
1
+ # Exact cost billing
2
+
3
+ `@happyvertical/smrt-commerce/cost-billing` is an independent, transport-neutral
4
+ entry point without model, server or Svelte dependencies. It does not persist,
5
+ post, authorize, select a currency/jurisdiction, or implement credit-note lifecycle.
6
+ Existing Invoice calculations and editor defaults are unchanged. In particular,
7
+ `calculateInvoiceMinorLine` retains negative ties toward positive infinity; the
8
+ new opt-in helpers use symmetric half-away-from-zero ties. Positive-only invoice
9
+ editor validation remains distinct from these generic signed calculations.
10
+
11
+ Call `resolveCostMarkup(overrides)` with caller-approved precedence, most specific
12
+ first. Each item has `source`, optional `policy` and `version`, and optional
13
+ `percent`. The first defined percent wins, including `"0"`. At least one is
14
+ required; even shadowed inputs are validated. The result contains the percent,
15
+ selected index, and detached ordered provenance. Persist accepted snapshots in
16
+ the owning application; these helpers never reprice them automatically.
17
+
18
+ Call `calculateCostBilling({ basisMinor, mode, markup })` with that result. Money
19
+ is signed safe-integer minor units in a single caller-selected currency. The
20
+ basis is explicitly chosen by the caller (for example excluding recoverable tax).
21
+ `reimbursement-plus-fee` returns principal once plus rounded fee; `fee-only`
22
+ returns only the fee; `nonbillable` and `fixed-contract` return zero charge.
23
+ The result includes `principalMinor`, `feeMinor`, `totalMinor`, and provenance.
24
+ Percent strings use plain nonnegative decimal notation, range 0–100000 percent,
25
+ at most six fractional places, without whitespace, exponent or leading zeroes.
26
+ The finite range and scale bound input parsing and arithmetic resource use; they
27
+ are API limits, not tax or industry policy. Arithmetic uses BigInt intermediates and half-away-from-zero rounding. Invalid
28
+ inputs, unknown modes, inconsistent provenance and unsafe outputs throw.
29
+
30
+ `calculateCostBillingTax({ lines, rules, roundingScope })` accepts line
31
+ `id`, signed `amountMinor`, and `category`; rules explicitly map every used
32
+ category to `{ id, percent }` components. An empty component array explicitly
33
+ means exempt. Components are additive, never compounded. Shared component IDs
34
+ must use equal rates across categories; distinct rate regimes need distinct IDs.
35
+ The caller owns taxable basis and jurisdiction mapping. Duplicate category,
36
+ component-within-category or line IDs fail closed. `line` scope rounds each
37
+ line/component pair; `invoice` scope aggregates exact amounts per component and
38
+ rounds once. Two 10-unit lines at 5 percent yield tax 2 versus 1 respectively.
39
+ Returns `taxMinor` and component totals, deliberately without allocating rounded
40
+ invoice tax back to lines. Signed reversals use symmetric rounding, but mixed
41
+ positive/negative lines may differ between rounding scopes.
@@ -0,0 +1,45 @@
1
+ # Payment allocation integrity
2
+
3
+ `PaymentAllocation.save()` owns the financial boundary for every direct or
4
+ collection write. Both payment and invoice must exist, belong to the same
5
+ exact tenant (global is distinct), have the same customer and currency, and
6
+ have room for the positive safe-integer minor-unit amount. Zero-total invoices
7
+ have no room. Missing or zero-total invoice fixtures no longer bypass the cap.
8
+ Pending payments remain allocatable; this command does not establish settlement
9
+ proof. Generated REST/MCP/CLI allocation writes remain closed. Applications
10
+ must authorize the actor before invoking these backend commands.
11
+
12
+ Use `PaymentAllocationCollection.allocatePayment({ paymentId, allocations,
13
+ allocatedBy })` for a split. Each allocation is `{ id, invoiceId, amount }`, with
14
+ a caller-generated stable UUID retained across retries. Exact replay
15
+ reuses the existing rows without applying money again; an existing id with
16
+ different parents or amount fails. Replay preserves an already-paid invoice's
17
+ recorded payment date. Reversing
18
+ payment clears that date; reaching full payment again records the new date.
19
+ The complete batch and invoice payment-status refresh share one transaction. Invoices must
20
+ already be in a status that permits payment (normally SENT); WRITTEN_OFF retains
21
+ its terminal status. A failed leg rolls back every leg and parent revision.
22
+ Direct allocation saves continue to leave status refresh to the caller. Allocation
23
+ writes advance both parent revisions: reload a previously held parent with
24
+ `await parent.loadFromId()` before applying later edits or status refresh.
25
+ Stale parent saves continue to fail the core revision guard; no implicit
26
+ revision refresh bypasses another editor. In-package billing follows this rule.
27
+
28
+ Once inserted, allocation tenant/payment/invoice identity is immutable. Amount
29
+ corrections are capped against the other allocations. Parent saves reject
30
+ changes to tenant, customer, currency or amount that would invalidate committed
31
+ allocations. A payment may be increased or reduced to its allocated total;
32
+ invoice totals continue to derive from persisted invoice lines where present.
33
+ Standalone payments remain saveable when allocation storage has not been
34
+ provisioned. An existing allocation table always participates in validation;
35
+ storage probes and permission errors propagate instead of disabling the guard.
36
+
37
+ All participating writes bind collections to the owning transaction executor.
38
+ They claim parent revisions before reading balances. Concurrent writers can
39
+ receive a revision conflict or database serialization failure; reload and retry
40
+ the complete transaction with the same allocation ids. Never retry only the
41
+ last leg inside an already failed transaction. PostgreSQL Repeatable Read
42
+ snapshots fail closed through the same revision writes. SQLite serializes the
43
+ owning write transaction. DuckDB is not a supported commerce allocation store:
44
+ the existing declared foreign keys require ON UPDATE CASCADE, which its DDL
45
+ boundary explicitly refuses; no weaker schema is substituted.
@@ -80,3 +80,30 @@ Composition regression: run the quote SSR lane, then the maintained quote browse
80
80
  host with `QUOTE_BROWSER_EXTENSION=packages/commerce/test-support/quote-attachments-browser.mjs`.
81
81
  It submits actual Assets upload bytes and the separate editor action with and
82
82
  without JavaScript at 390px.
83
+
84
+ ## Purchase-order header
85
+
86
+ `PurchaseOrderHeaderForm` (`purchase-order-header-form` registry slot) edits only
87
+ `vendorId`, `reference`, `notes`, `expectedDate` and `shipTo`. It does not amend
88
+ awards, allocations, totals or status. Supply `action`, caller-authorized `vendors`,
89
+ raw `values`, canonical-key `errors`, optional `message`, `hiddenFields` and
90
+ `names` for an existing endpoint. The native POST submitter defaults to
91
+ `intent=saveHeader`; `intent`, `onsubmit` and `formAttributes` adapt transport.
92
+ Readonly/busy are presentation controls, never authorization. The server must
93
+ check active authority, vendor eligibility and any order-status edit policy.
94
+
95
+ All header input remains text: even rejected calendar dates survive a rerender.
96
+ The server validates `expectedDate` as YYYY-MM-DD or empty before saving. An
97
+ unknown retained vendor appears explicitly unavailable but retains its ID on POST
98
+ so a rejected submission cannot silently clear it. The caller must reject an
99
+ unavailable vendor or explicitly permit keeping the existing relationship.
100
+ `shipTo` is a delivery address/instructions snapshot, not a Profile reference.
101
+ `PurchaseOrder.expectedDate` and `.shipTo` use existing STI metadata, default to
102
+ empty strings, and accept `PurchaseOrderOptions`; no table migration is needed.
103
+ Existing Contract fields own the other three values. Header persistence uses the
104
+ existing SQLite/PostgreSQL Contract schema; DuckDB rejects its existing
105
+ ON UPDATE CASCADE foreign keys and is not a supported Contract storage lane. Caller retry identities
106
+ are rendered unchanged; the form itself never persists or retries a mutation.
107
+
108
+ Header regression evidence uses the purchasing SSR suite and the shared quote
109
+ browser host with `QUOTE_BROWSER_EXTENSION=packages/commerce/test-support/purchasing-header-browser.mjs`.
@@ -0,0 +1,13 @@
1
+ import type { Invoice } from './models/Invoice.js';
2
+ import type { Payment } from './models/Payment.js';
3
+ export declare function allocationOwner(value: string | null): string | null;
4
+ /** Claim the persisted parent before reading dependants, including at repeatable read. */
5
+ export declare function claimAllocationParent(parent: Payment | Invoice, kind: 'payment' | 'invoice'): Promise<void>;
6
+ /** Exact totals must never silently exceed JavaScript's integer range. */
7
+ export declare function allocationTotal(rows: {
8
+ amount: number;
9
+ id?: string | null;
10
+ }[], excluding?: string | null): bigint;
11
+ /** Parent corrections cannot invalidate an already committed allocation. */
12
+ export declare function assertAllocationParent(parent: Payment | Invoice, kind: 'payment' | 'invoice'): Promise<void>;
13
+ //# sourceMappingURL=allocation-integrity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allocation-integrity.d.ts","sourceRoot":"","sources":["../src/allocation-integrity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,0FAA0F;AAC1F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,EAC9C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAQR;AAED,4EAA4E;AAC5E,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,OAAO,CAAC,IAAI,CAAC,CAyDf"}
@@ -1 +1 @@
1
- {"version":3,"file":"payment-attempts.d.ts","sourceRoot":"","sources":["../../src/billing/payment-attempts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"payment-attempts.d.ts","sourceRoot":"","sources":["../../src/billing/payment-attempts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { isPostgresDatabase } from "@happyvertical/smrt-core";
2
+ import { getTenantId } from "@happyvertical/smrt-tenancy";
3
+ //#region src/allocation-integrity.ts
4
+ function allocationOwner(value) {
5
+ return value || getTenantId() || null;
6
+ }
7
+ async function claimAllocationParent(parent, kind) {
8
+ if (!parent.id) return;
9
+ const { PaymentCollection } = await import("../index.js").then((n) => n.r);
10
+ const { InvoiceCollection } = await import("../index.js").then((n) => n.t);
11
+ const persisted = await (kind === "payment" ? await PaymentCollection.create({ db: parent.db }) : await InvoiceCollection.create({ db: parent.db })).get({ id: parent.id }, { cache: false });
12
+ if (!persisted) return;
13
+ const expected = parent.isPersisted ? parent.updated_at : persisted.updated_at;
14
+ if (!expected) throw new Error("Allocation parent has no persisted revision");
15
+ await persisted.claimRevision(expected);
16
+ parent.updated_at = persisted.updated_at;
17
+ }
18
+ function allocationTotal(rows, excluding) {
19
+ return rows.reduce((total, row) => {
20
+ if (row.id === excluding) return total;
21
+ if (!Number.isSafeInteger(row.amount) || row.amount <= 0) throw new Error("Invalid persisted payment allocation amount");
22
+ return total + BigInt(row.amount);
23
+ }, 0n);
24
+ }
25
+ async function assertAllocationParent(parent, kind) {
26
+ if (!parent.id) return;
27
+ const { PaymentAllocationCollection } = await import("../index.js").then((n) => n.n);
28
+ const allocations = await PaymentAllocationCollection.create({ db: parent.db });
29
+ if (!(isPostgresDatabase(parent.db) ? (await parent.db.query("SELECT to_regclass(?) AS relation", [allocations.tableName])).rows[0]?.relation != null : await parent.db.tableExists(allocations.tableName))) return;
30
+ const rows = kind === "payment" ? await allocations.findByPayment(parent.id) : await allocations.findByInvoice(parent.id);
31
+ if (!rows.length) return;
32
+ const { PaymentCollection } = await import("../index.js").then((n) => n.r);
33
+ const { InvoiceCollection } = await import("../index.js").then((n) => n.t);
34
+ const opposite = kind === "payment" ? await InvoiceCollection.create({ db: parent.db }) : await PaymentCollection.create({ db: parent.db });
35
+ const cap = kind === "payment" ? parent.amount : parent.totalAmount;
36
+ if (allocationTotal(rows) > BigInt(cap)) throw new Error("Parent amount cannot be less than committed allocations");
37
+ for (const row of rows) {
38
+ const other = await opposite.get({ id: kind === "payment" ? row.invoiceId : row.paymentId }, { cache: false });
39
+ if (!other || row.tenantId !== allocationOwner(parent.tenantId) || other.tenantId !== row.tenantId || (other.customerId || null) !== (parent.customerId || null) || other.currency !== parent.currency) throw new Error("Parent correction would invalidate payment allocation tenant, customer or currency");
40
+ }
41
+ }
42
+ //#endregion
43
+ //#region src/money.ts
44
+ function assertIntegerMinorUnits(context, label, entries) {
45
+ for (const [field, value] of entries) if (!Number.isFinite(value) || !Number.isInteger(value)) throw new Error(`${context} ${label}: ${field} must be an integer number of minor units (cents, satoshis) \u2014 got ${value}. Money is exact: $19.99 is 1999, not 19.99.`);
46
+ }
47
+ //#endregion
48
+ export { claimAllocationParent as a, assertAllocationParent as i, allocationOwner as n, allocationTotal as r, assertIntegerMinorUnits as t };
49
+
50
+ //# sourceMappingURL=money-DfrRxrel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-DfrRxrel.js","names":[],"sources":["../../src/allocation-integrity.ts","../../src/money.ts"],"sourcesContent":["/** Transactional allocation invariants shared by the owning models. */\nimport { isPostgresDatabase } from '@happyvertical/smrt-core';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport type { Invoice } from './models/Invoice.js';\nimport type { Payment } from './models/Payment.js';\n\nexport function allocationOwner(value: string | null): string | null {\n return value || getTenantId() || null;\n}\n\n/** Claim the persisted parent before reading dependants, including at repeatable read. */\nexport async function claimAllocationParent(\n parent: Payment | Invoice,\n kind: 'payment' | 'invoice',\n): Promise<void> {\n if (!parent.id) return;\n const { PaymentCollection } = await import(\n './collections/PaymentCollection.js'\n );\n const { InvoiceCollection } = await import(\n './collections/InvoiceCollection.js'\n );\n const collection =\n kind === 'payment'\n ? await PaymentCollection.create({ db: parent.db })\n : await InvoiceCollection.create({ db: parent.db });\n const persisted = await collection.get({ id: parent.id }, { cache: false });\n if (!persisted) return;\n const expected = parent.isPersisted\n ? parent.updated_at\n : persisted.updated_at;\n if (!expected) throw new Error('Allocation parent has no persisted revision');\n await persisted.claimRevision(expected);\n parent.updated_at = persisted.updated_at;\n}\n\n/** Exact totals must never silently exceed JavaScript's integer range. */\nexport function allocationTotal(\n rows: { amount: number; id?: string | null }[],\n excluding?: string | null,\n): bigint {\n return rows.reduce((total, row) => {\n if (row.id === excluding) return total;\n if (!Number.isSafeInteger(row.amount) || row.amount <= 0) {\n throw new Error('Invalid persisted payment allocation amount');\n }\n return total + BigInt(row.amount);\n }, 0n);\n}\n\n/** Parent corrections cannot invalidate an already committed allocation. */\nexport async function assertAllocationParent(\n parent: Payment | Invoice,\n kind: 'payment' | 'invoice',\n): Promise<void> {\n if (!parent.id) return;\n const { PaymentAllocationCollection } = await import(\n './collections/PaymentAllocationCollection.js'\n );\n const allocations = await PaymentAllocationCollection.create({\n db: parent.db,\n });\n // Payment-only deployments need not provision allocation storage. PostgreSQL's\n // information_schema hides inaccessible tables, so use its catalog lookup and\n // let the subsequent read report permission errors for an existing table.\n const exists = isPostgresDatabase(parent.db)\n ? (\n await parent.db.query('SELECT to_regclass(?) AS relation', [\n allocations.tableName,\n ])\n ).rows[0]?.relation != null\n : await parent.db.tableExists(allocations.tableName);\n if (!exists) return;\n const rows =\n kind === 'payment'\n ? await allocations.findByPayment(parent.id)\n : await allocations.findByInvoice(parent.id);\n if (!rows.length) return;\n const { PaymentCollection } = await import(\n './collections/PaymentCollection.js'\n );\n const { InvoiceCollection } = await import(\n './collections/InvoiceCollection.js'\n );\n const opposite =\n kind === 'payment'\n ? await InvoiceCollection.create({ db: parent.db })\n : await PaymentCollection.create({ db: parent.db });\n const cap =\n kind === 'payment'\n ? (parent as Payment).amount\n : (parent as Invoice).totalAmount;\n if (allocationTotal(rows) > BigInt(cap))\n throw new Error('Parent amount cannot be less than committed allocations');\n for (const row of rows) {\n const other = await opposite.get(\n { id: kind === 'payment' ? row.invoiceId : row.paymentId },\n { cache: false },\n );\n if (\n !other ||\n row.tenantId !== allocationOwner(parent.tenantId) ||\n other.tenantId !== row.tenantId ||\n (other.customerId || null) !== (parent.customerId || null) ||\n other.currency !== parent.currency\n ) {\n throw new Error(\n 'Parent correction would invalidate payment allocation tenant, customer or currency',\n );\n }\n }\n}\n","/**\n * Money is exact: integer minor units, checked at the model boundary (#2401).\n *\n * Every money column in this package is INTEGER minor units — cents,\n * satoshis — so `$19.99` is `1999`. Before #2401 the models carried\n * `EPSILON = 0.01` tolerances on every comparison, because the values really\n * were floats and `0.1 * 3` really is `0.30000000000000004`. With exact\n * integers those tolerances are not merely unnecessary, they are wrong: a\n * one-cent discrepancy is a one-cent discrepancy, not rounding fuzz.\n *\n * Dropping the tolerances is only safe if the values are *actually* integers,\n * which is what this guard establishes. A fractional major-unit write (`19.99`\n * into a cents column) is the bug the whole convention exists to prevent;\n * PostgreSQL catches it with a `22P02` and SQLite's type affinity does not\n * catch it at all, so the model catches it first, on every engine and every\n * write surface.\n */\n\n/**\n * Throw unless every named value is a finite integer.\n *\n * @param context - Model name for the error message, e.g. `Invoice`.\n * @param label - Row identifier used in the error, e.g. an invoice number.\n * @param entries - `[fieldName, value]` pairs to check.\n * @throws When any value is non-finite or has a fractional part.\n */\nexport function assertIntegerMinorUnits(\n context: string,\n label: string,\n entries: ReadonlyArray<readonly [string, number]>,\n): void {\n for (const [field, value] of entries) {\n if (!Number.isFinite(value) || !Number.isInteger(value)) {\n throw new Error(\n `${context} ${label}: ${field} must be an integer number of minor ` +\n `units (cents, satoshis) — got ${value}. Money is exact: $19.99 is ` +\n '1999, not 19.99.',\n );\n }\n }\n}\n"],"mappings":";;;AAMO,SAAS,gBAAgB,OAAqC;CACnE,OAAO,SAAS,YAAY,KAAK;AACnC;AAGA,eAAsB,sBACpB,QACA,MACe;CACf,IAAI,CAAC,OAAO,IAAI;CAChB,MAAM,EAAE,sBAAsB,MAAM,OAClC,cAAA,CAAA,MAAA,MAAA,EAAA,CAAA;CAEF,MAAM,EAAE,sBAAsB,MAAM,OAClC,cAAA,CAAA,MAAA,MAAA,EAAA,CAAA;CAMF,MAAM,YAAY,OAHhB,SAAS,YACL,MAAM,kBAAkB,OAAO,EAAE,IAAI,OAAO,GAAG,CAAC,IAChD,MAAM,kBAAkB,OAAO,EAAE,IAAI,OAAO,GAAG,CAAC,EAAA,CACnB,IAAI,EAAE,IAAI,OAAO,GAAG,GAAG,EAAE,OAAO,MAAM,CAAC;CAC1E,IAAI,CAAC,WAAW;CAChB,MAAM,WAAW,OAAO,cACpB,OAAO,aACP,UAAU;CACd,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,6CAA6C;CAC5E,MAAM,UAAU,cAAc,QAAQ;CACtC,OAAO,aAAa,UAAU;AAChC;AAGO,SAAS,gBACd,MACA,WACQ;CACR,OAAO,KAAK,QAAQ,OAAO,QAAQ;EACjC,IAAI,IAAI,OAAO,WAAW,OAAO;EACjC,IAAI,CAAC,OAAO,cAAc,IAAI,MAAM,KAAK,IAAI,UAAU,GACrD,MAAM,IAAI,MAAM,6CAA6C;EAE/D,OAAO,QAAQ,OAAO,IAAI,MAAM;CAClC,GAAG,EAAE;AACP;AAGA,eAAsB,uBACpB,QACA,MACe;CACf,IAAI,CAAC,OAAO,IAAI;CAChB,MAAM,EAAE,gCAAgC,MAAM,OAC5C,cAAA,CAAA,MAAA,MAAA,EAAA,CAAA;CAEF,MAAM,cAAc,MAAM,4BAA4B,OAAO,EAC3D,IAAI,OAAO,GACb,CAAC;CAWD,IAAI,EAPW,mBAAmB,OAAO,EAAE,KAErC,MAAM,OAAO,GAAG,MAAM,qCAAqC,CACzD,YAAY,SACd,CAAC,EAAA,CACD,KAAK,EAAC,EAAG,YAAY,OACvB,MAAM,OAAO,GAAG,YAAY,YAAY,SAAS,IACxC;CACb,MAAM,OACJ,SAAS,YACL,MAAM,YAAY,cAAc,OAAO,EAAE,IACzC,MAAM,YAAY,cAAc,OAAO,EAAE;CAC/C,IAAI,CAAC,KAAK,QAAQ;CAClB,MAAM,EAAE,sBAAsB,MAAM,OAClC,cAAA,CAAA,MAAA,MAAA,EAAA,CAAA;CAEF,MAAM,EAAE,sBAAsB,MAAM,OAClC,cAAA,CAAA,MAAA,MAAA,EAAA,CAAA;CAEF,MAAM,WACJ,SAAS,YACL,MAAM,kBAAkB,OAAO,EAAE,IAAI,OAAO,GAAG,CAAC,IAChD,MAAM,kBAAkB,OAAO,EAAE,IAAI,OAAO,GAAG,CAAC;CACtD,MAAM,MACJ,SAAS,YACJ,OAAmB,SACnB,OAAmB;CAC1B,IAAI,gBAAgB,IAAI,IAAI,OAAO,GAAG,GACpC,MAAM,IAAI,MAAM,yDAAyD;CAC3E,KAAA,MAAW,OAAO,MAAM;EACtB,MAAM,QAAQ,MAAM,SAAS,IAC3B,EAAE,IAAI,SAAS,YAAY,IAAI,YAAY,IAAI,UAAU,GACzD,EAAE,OAAO,MAAM,CACjB;EACA,IACE,CAAC,SACD,IAAI,aAAa,gBAAgB,OAAO,QAAQ,KAChD,MAAM,aAAa,IAAI,aACtB,MAAM,cAAc,WAAW,OAAO,cAAc,SACrD,MAAM,aAAa,OAAO,UAE1B,MAAM,IAAI,MACR,oFACF;CAEJ;AACF;;;ACrFO,SAAS,wBACd,SACA,OACA,SACM;CACN,KAAA,MAAW,CAAC,OAAO,UAAU,SAC3B,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,UAAU,KAAK,GACpD,MAAM,IAAI,MACR,GAAG,QAAO,GAAI,MAAK,IAAK,MAAK,yEACM,MAAK,6CAE1C;AAGN"}
@@ -1,4 +1,31 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
1
13
  //#region src/types/index.ts
14
+ var types_exports = /* @__PURE__ */ __exportAll({
15
+ ContractStatus: () => ContractStatus,
16
+ ContractType: () => ContractType,
17
+ CustomerStatus: () => CustomerStatus,
18
+ CustomerType: () => CustomerType,
19
+ FulfillmentStatus: () => FulfillmentStatus,
20
+ FulfillmentType: () => FulfillmentType,
21
+ InvoiceStatus: () => InvoiceStatus,
22
+ PaymentInstrumentStatus: () => PaymentInstrumentStatus,
23
+ PaymentIntentStatus: () => PaymentIntentStatus,
24
+ PaymentMethod: () => PaymentMethod,
25
+ PaymentStatus: () => PaymentStatus,
26
+ PayoutStatus: () => PayoutStatus,
27
+ VendorStatus: () => VendorStatus
28
+ });
2
29
  var CustomerStatus = /* @__PURE__ */ ((CustomerStatus2) => {
3
30
  CustomerStatus2["ACTIVE"] = "active";
4
31
  CustomerStatus2["INACTIVE"] = "inactive";
@@ -105,6 +132,6 @@ var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus2) => {
105
132
  return InvoiceStatus2;
106
133
  })(InvoiceStatus || {});
107
134
  //#endregion
108
- export { FulfillmentStatus as a, PaymentInstrumentStatus as c, PaymentStatus as d, PayoutStatus as f, CustomerType as i, PaymentIntentStatus as l, ContractType as n, FulfillmentType as o, VendorStatus as p, CustomerStatus as r, InvoiceStatus as s, ContractStatus as t, PaymentMethod as u };
135
+ export { FulfillmentStatus as a, PaymentInstrumentStatus as c, PaymentStatus as d, PayoutStatus as f, __exportAll as h, CustomerType as i, PaymentIntentStatus as l, types_exports as m, ContractType as n, FulfillmentType as o, VendorStatus as p, CustomerStatus as r, InvoiceStatus as s, ContractStatus as t, PaymentMethod as u };
109
136
 
110
- //# sourceMappingURL=types-CRnln577.js.map
137
+ //# sourceMappingURL=types-zVnIjSOk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-CRnln577.js","names":["CustomerStatus","CustomerType","VendorStatus","ContractType","ContractStatus","FulfillmentType","FulfillmentStatus","PaymentMethod","PaymentStatus","PaymentInstrumentStatus","PayoutStatus","PaymentIntentStatus","InvoiceStatus"],"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Commerce package type definitions\n * @packageDocumentation\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport type {\n InvoiceCalculationContext,\n InvoiceLineDraft,\n} from '../svelte/invoices/calculations.js';\n\n// ============================================================================\n// Customer/Vendor Types\n// ============================================================================\n\nexport enum CustomerStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n/**\n * Customer classification — drives channel access, pricing tier, and credit terms.\n *\n * - DTC: direct-to-consumer (end shopper). Pays via storefront checkout.\n * - WHOLESALE: B2B buyer with negotiated terms (NET-30, line sheets, etc.).\n * - RETAIL: in-store walk-in / point-of-sale customer.\n */\nexport enum CustomerType {\n DTC = 'dtc',\n WHOLESALE = 'wholesale',\n RETAIL = 'retail',\n}\n\nexport enum VendorStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n// ============================================================================\n// Contract Types\n// ============================================================================\n\nexport enum ContractType {\n ESTIMATE = 'estimate',\n ORDER = 'order',\n LEASE = 'lease',\n AGREEMENT = 'agreement',\n PURCHASE_ORDER = 'purchase_order',\n WHOLESALE_ORDER = 'wholesale_order',\n PRODUCTION_ORDER = 'production_order',\n CART = 'cart',\n /**\n * Industry-neutral licensing primitive. The `LicenseSale` STI subtype\n * carries an immutable rights snapshot, a licensee email, optional\n * legal-entity / jurisdiction fields, and a signed-PDF reference.\n * Any application that sells rights for a fee (stock media,\n * music licensing, code-asset marketplace, license keys, etc.)\n * uses this subtype.\n */\n LICENSE_SALE = 'license_sale',\n}\n\nexport enum ContractStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n ACCEPTED = 'accepted',\n DECLINED = 'declined',\n COMPLETED = 'completed',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Fulfillment Types\n// ============================================================================\n\nexport enum FulfillmentType {\n SHIPMENT = 'shipment',\n DELIVERY = 'delivery',\n PICKUP = 'pickup',\n DIGITAL = 'digital',\n SERVICE = 'service',\n}\n\nexport enum FulfillmentStatus {\n PENDING = 'pending',\n PROCESSING = 'processing',\n SHIPPED = 'shipped',\n DELIVERED = 'delivered',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\nexport enum PaymentMethod {\n CASH = 'cash',\n CHECK = 'check',\n CREDIT_CARD = 'credit_card',\n BANK_TRANSFER = 'bank_transfer',\n CRYPTO = 'crypto',\n OTHER = 'other',\n}\n\nexport enum PaymentStatus {\n PENDING = 'pending',\n COMPLETED = 'completed',\n FAILED = 'failed',\n REFUNDED = 'refunded',\n CANCELLED = 'cancelled',\n}\n\n/**\n * Lifecycle status for a saved {@link PaymentInstrument} (card on file).\n * `active` while chargeable, `expired` once the card lapses, `removed` when the\n * customer detaches it.\n */\nexport enum PaymentInstrumentStatus {\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REMOVED = 'removed',\n}\n\n// ============================================================================\n// Payout Types\n// ============================================================================\n\n/**\n * Status machine for {@link Payout}.\n *\n * `pending → sent → confirmed → failed`. `failed` is terminal but the\n * model exposes a dedicated `resetFromFailed()` so an operator can\n * deliberately requeue a payout after fixing the underlying problem;\n * the reset moves the row back to `pending` and clears the failure\n * metadata.\n *\n * Skipping intermediate states is rejected — a `pending` payout cannot\n * jump straight to `confirmed`, and a `sent` payout cannot regress to\n * `pending` without going through `resetFromFailed()` first.\n */\nexport enum PayoutStatus {\n PENDING = 'pending',\n SENT = 'sent',\n CONFIRMED = 'confirmed',\n FAILED = 'failed',\n}\n\n// ============================================================================\n// PaymentIntent Types\n// ============================================================================\n\n/**\n * Status machine for {@link PaymentIntent}.\n *\n * `awaiting_payment → paid → (issued | retired)`, with `expired` and\n * `cancelled` as alternate terminal states reachable from\n * `awaiting_payment`.\n *\n * - `AWAITING_PAYMENT` — open quote, accepting any of the listed\n * payment options.\n * - `PAID` — one option was satisfied by an incoming payment. The\n * other options are implicitly retired; later inbound funds to a\n * retired option must be flagged for refund by the consumer.\n * - `ISSUED` — downstream rights / contract / fulfillment have been\n * created and linked. Terminal happy-path state.\n * - `RETIRED` — paid but the satisfaction was reversed (refund,\n * chargeback, etc.). Terminal.\n * - `EXPIRED` — the USD-price-lock window passed without payment.\n * Terminal.\n * - `CANCELLED` — the buyer or the system explicitly cancelled the\n * intent before it was paid. Terminal.\n */\nexport enum PaymentIntentStatus {\n AWAITING_PAYMENT = 'awaiting_payment',\n PAID = 'paid',\n ISSUED = 'issued',\n RETIRED = 'retired',\n EXPIRED = 'expired',\n CANCELLED = 'cancelled',\n}\n\n/**\n * One way for a {@link PaymentIntent} to be satisfied. The intent lists\n * an array of these; satisfying any one of them transitions the intent\n * to `PAID` and implicitly retires the rest.\n *\n * Industry-neutral: a marketplace that accepts USDC-on-Base and BTC\n * lists two options; a SaaS billing flow that accepts Stripe and\n * PayPal lists two; a kiosk that accepts only one rail lists one.\n */\nexport interface PaymentOption {\n /**\n * Stable id of the `PaymentBackend` adapter that fulfills this\n * option — must match a `backendId` the consumer's payment-routing\n * layer recognises. Examples: `base-usdc`, `solana-usdc`, `btc`,\n * `stripe`, `paypal`.\n */\n backendId: string;\n /**\n * Payout-rail-qualified currency code, e.g. `USDC-base`, `BTC`,\n * `USD-stripe`. The same convention used by\n * `Vendor.payoutAddresses` and `Payment.nativeCurrency`.\n */\n currency: string;\n /**\n * Optional chain identifier for blockchain-backed options (`base`,\n * `ethereum`, `solana`, ...). Pure-fiat options leave this empty.\n */\n chain?: string;\n /**\n * Destination address / account id the buyer should send funds to\n * for this option (EVM address, BTC address, Stripe payment-intent\n * id, etc.).\n */\n payTo: string;\n /**\n * Amount denominated in `currency`. Stored at decimal precision —\n * a USDC option might be `199.0`, a BTC option `0.00713`.\n */\n nativeAmount: number;\n /**\n * Optional on-chain memo / payment reference (Solana memo, BTC OP_RETURN\n * tag, Stripe metadata key). Some backends use this to disambiguate\n * which intent an inbound payment satisfies.\n */\n memo?: string;\n /**\n * Whether this option supports the x402 HTTP-402 payment-required\n * flow. Consumers that build agent-driven flows use this flag to\n * filter the offered options.\n */\n x402Capable?: boolean;\n /**\n * Optional per-option expiry — when a single rail's quote becomes\n * stale earlier than the intent-wide price-lock window (e.g. a\n * volatile-currency option that re-quotes more aggressively). ISO\n * 8601 string. Empty / missing means \"inherit the intent's\n * `priceLockExpiresAt`\".\n */\n expiresAt?: string;\n}\n\n// ============================================================================\n// Invoice Types\n// ============================================================================\n\nexport enum InvoiceStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n VIEWED = 'viewed',\n PARTIAL = 'partial',\n PAID = 'paid',\n OVERDUE = 'overdue',\n CANCELLED = 'cancelled',\n WRITTEN_OFF = 'written_off',\n}\n\n// ============================================================================\n// Common Interfaces\n// ============================================================================\n\n/**\n * Address structure used for billing and shipping\n */\nexport interface Address {\n street1?: string;\n street2?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}\n\n/**\n * Options for recording a payment with ledger integration\n */\nexport interface RecordPaymentOptions {\n /** The ledger to record the journal entry in */\n ledgerId: string;\n /** Account ID for receivables (credit side) */\n receivablesAccountId: string;\n /** Account ID for cash/bank (debit side) */\n cashAccountId: string;\n}\n\n/**\n * Options for recognizing revenue on an invoice\n */\nexport interface RecognizeRevenueOptions {\n /** Account ID for accounts receivable (debit side) */\n arAccountId: string;\n /** Account ID for revenue (credit side) */\n revenueAccountId: string;\n /** Account ID for tax payable (credit side, optional) */\n taxAccountId?: string;\n}\n\n// ============================================================================\n// Accounting-provider sync shapes\n// ============================================================================\n\n/**\n * A single line item in the format expected by `@happyvertical/accounting`\n * providers (QBO, Stripe, …). Mirrors the object built by\n * {@link InvoiceLineItem.toAccountingLineItem}. The SDK isn't a dependency of\n * this package, so the shape is declared locally rather than imported.\n */\nexport interface AccountingLineItemInput {\n description: string;\n sku?: string;\n quantity: number;\n unitPrice: number;\n discount?: number;\n taxRate?: number;\n amount: number;\n periodStart?: Date;\n periodEnd?: Date;\n}\n\n/**\n * An invoice in the format expected by `@happyvertical/accounting` providers.\n * Mirrors the object built by {@link Invoice.toAccountingInput}; money is in\n * currency **major** units, as the SDK expects.\n */\nexport interface AccountingInvoiceInput {\n id: string;\n externalId?: string;\n invoiceNumber: string;\n customerId: string;\n customerExternalId?: string;\n issueDate: Date;\n dueDate: Date;\n lineItems: AccountingLineItemInput[];\n subtotal: number;\n taxAmount: number;\n totalAmount: number;\n currency: string;\n reference?: string;\n memo?: string;\n}\n\n// ============================================================================\n// Model constructor option interfaces\n//\n// Each model's `constructor(options)` accepts a partial bag of its own fields.\n// Declaring a dedicated `XxxOptions extends SmrtObjectOptions` interface keeps\n// the constructors strongly typed (no `any`) while still allowing the\n// framework's base options (db, ai, fs, _className, …) through.\n// ============================================================================\n\n/**\n * Constructor options for {@link Customer}.\n */\nexport interface CustomerOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n creditLimit?: number;\n paymentTerms?: string;\n taxExempt?: boolean;\n taxId?: string;\n defaultShippingAddress?: Address;\n defaultBillingAddress?: Address;\n status?: CustomerStatus;\n customerType?: CustomerType | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Vendor}.\n */\nexport interface VendorOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n leadTimeDays?: number;\n minimumOrderAmount?: number;\n paymentTerms?: string;\n currency?: string;\n defaultContactEmail?: string;\n defaultContactPhone?: string;\n status?: VendorStatus;\n notes?: string;\n payoutAddresses?: Record<string, string> | string | null;\n}\n\n/**\n * Constructor options for {@link Contract} and its STI subtypes.\n */\nexport interface ContractOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractType?: ContractType;\n status?: ContractStatus;\n customerId?: string | null;\n vendorId?: string | null;\n subtotal?: number;\n taxAmount?: number;\n totalAmount?: number;\n currency?: string;\n issueDate?: Date;\n dueDate?: Date | null;\n expiryDate?: Date | null;\n reference?: string;\n notes?: string;\n terms?: string;\n channelId?: string;\n}\n\n/**\n * Constructor options for {@link LicenseSale} (Contract STI subtype). Extends\n * {@link ContractOptions} with the licensing-specific meta fields.\n */\nexport interface LicenseSaleOptions extends ContractOptions {\n skuId?: string;\n paymentId?: string;\n licenseeEmail?: string;\n licenseeLegalEntity?: string;\n licenseeJurisdiction?: string;\n rightsMedium?: string;\n rightsDistributionScope?: string;\n rightsExclusivity?: string;\n rightsDuration?: string;\n rightsTerritory?: string;\n rightsSublicensing?: boolean;\n rightsDerivatives?: boolean;\n pdfUrl?: string;\n pdfHash?: string;\n onChainHashRegistryRef?: string;\n}\n\n/**\n * Constructor options for {@link ContractLineItem}.\n */\nexport interface ContractLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n description?: string;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n taxRate?: number;\n amount?: number;\n productId?: string;\n sku?: string;\n startDate?: Date | null;\n endDate?: Date | null;\n billingPeriod?: string;\n sortOrder?: number;\n}\n\n/**\n * How the provider collects an invoice (#3190): `charge_automatically`\n * charges the payer's saved card; `send_invoice` asks the payer to pay. Empty\n * for an invoice never pushed to a provider, or pushed before it was recorded.\n */\nexport type InvoiceCollectionMethod =\n | ''\n | 'send_invoice'\n | 'charge_automatically';\n\n/**\n * Constructor options for {@link Invoice}.\n */\nexport interface InvoiceOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n customerId?: string;\n contractId?: string;\n invoiceNumber?: string;\n reference?: string;\n issueDate?: Date;\n dueDate?: Date;\n paidDate?: Date | null;\n subtotal?: number;\n taxAmount?: number;\n providerTaxAmount?: number;\n totalAmount?: number;\n amountPaid?: number;\n currency?: string;\n status?: InvoiceStatus;\n arJournalId?: string;\n revenueJournalId?: string;\n externalId?: string;\n customerExternalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n collectionMethod?: InvoiceCollectionMethod;\n sentAt?: Date | null;\n viewedAt?: Date | null;\n remindersSent?: number;\n lastReminderAt?: Date | null;\n notes?: string;\n customerNotes?: string;\n terms?: string;\n}\n\n/** Retained editing modes, validated against resolved model fields before reuse. */\nexport interface InvoiceLineEditorState {\n /** Lossless editor draft; never authoritative for ordinary model saves. */\n draft: InvoiceLineDraft;\n /** Context used to resolve that draft; caller authority must still match on reload. */\n context: InvoiceCalculationContext;\n}\n\n/** Constructor options for {@link InvoiceLineItem}. */\nexport interface InvoiceLineItemOptions extends SmrtObjectOptions {\n /** Optional retained editor modes and their original calculation context. */\n invoiceEditorState?: InvoiceLineEditorState | null;\n /** Serialized editor state loaded from persistence; malformed JSON is ignored. */\n invoiceEditorStateJson?: string;\n tenantId?: string | null;\n invoiceId?: string;\n description?: string;\n sku?: string;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n taxRate?: number;\n amount?: number;\n sourceType?: string;\n sourceId?: string;\n periodStart?: Date | null;\n periodEnd?: Date | null;\n revenueAccountId?: string;\n sortOrder?: number;\n}\n\n/**\n * Constructor options for {@link Fulfillment}.\n */\nexport interface FulfillmentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n fulfillmentType?: FulfillmentType;\n status?: FulfillmentStatus;\n trackingNumber?: string;\n carrier?: string;\n shippingAddress?: Address;\n shippedAt?: Date | null;\n deliveredAt?: Date | null;\n estimatedDelivery?: Date | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link FulfillmentLineItem}.\n */\nexport interface FulfillmentLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n fulfillmentId?: string;\n contractLineItemId?: string;\n quantityFulfilled?: number;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payment}.\n */\nexport interface PaymentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string | null;\n customerId?: string | null;\n amount?: number;\n currency?: string;\n method?: PaymentMethod;\n status?: PaymentStatus;\n transactionId?: string;\n reference?: string;\n journalId?: string;\n paidAt?: Date | null;\n notes?: string;\n externalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n backendId?: string;\n backendTxRef?: string;\n nativeAmount?: number;\n nativeCurrency?: string;\n usdAtQuote?: number;\n usdAtConfirmation?: number;\n}\n\n/**\n * Constructor options for {@link PaymentInstrument}.\n */\nexport interface PaymentInstrumentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n customerId?: string;\n backendId?: string;\n providerCustomerId?: string;\n providerPaymentMethodId?: string;\n type?: string;\n brand?: string;\n last4?: string;\n expMonth?: number;\n expYear?: number;\n isDefault?: boolean;\n status?: PaymentInstrumentStatus;\n}\n\n/**\n * Constructor options for {@link PaymentAllocation}.\n */\nexport interface PaymentAllocationOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n invoiceId?: string;\n amount?: number;\n allocatedAt?: Date;\n allocatedBy?: string;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link PaymentIntent}.\n */\nexport interface PaymentIntentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n skuId?: string;\n offeringRef?: string;\n licenseeEmail?: string;\n customerId?: string;\n paymentOptions?: PaymentOption[] | string;\n usdPriceLocked?: number;\n priceLockWindowMs?: number;\n priceLockExpiresAt?: Date | number | string | null;\n status?: PaymentIntentStatus;\n idempotencyKey?: string;\n paidOptionBackendId?: string;\n paymentId?: string;\n paidAt?: Date | number | string | null;\n issuedAt?: Date | number | string | null;\n expiredAt?: Date | number | string | null;\n cancelledAt?: Date | number | string | null;\n retiredAt?: Date | number | string | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payout}.\n */\nexport interface PayoutOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n vendorId?: string;\n grossAmount?: number;\n operatorFee?: number;\n supplierNet?: number;\n currency?: string;\n backendId?: string;\n backendTxRef?: string;\n status?: PayoutStatus;\n sentAt?: Date | number | string | null;\n confirmedAt?: Date | number | string | null;\n failedAt?: Date | number | string | null;\n failureReason?: string;\n notes?: string;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"types-zVnIjSOk.js","names":["CustomerStatus","CustomerType","VendorStatus","ContractType","ContractStatus","FulfillmentType","FulfillmentStatus","PaymentMethod","PaymentStatus","PaymentInstrumentStatus","PayoutStatus","PaymentIntentStatus","InvoiceStatus"],"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Commerce package type definitions\n * @packageDocumentation\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport type {\n InvoiceCalculationContext,\n InvoiceLineDraft,\n} from '../svelte/invoices/calculations.js';\n\n// ============================================================================\n// Customer/Vendor Types\n// ============================================================================\n\nexport enum CustomerStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n/**\n * Customer classification — drives channel access, pricing tier, and credit terms.\n *\n * - DTC: direct-to-consumer (end shopper). Pays via storefront checkout.\n * - WHOLESALE: B2B buyer with negotiated terms (NET-30, line sheets, etc.).\n * - RETAIL: in-store walk-in / point-of-sale customer.\n */\nexport enum CustomerType {\n DTC = 'dtc',\n WHOLESALE = 'wholesale',\n RETAIL = 'retail',\n}\n\nexport enum VendorStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n// ============================================================================\n// Contract Types\n// ============================================================================\n\nexport enum ContractType {\n ESTIMATE = 'estimate',\n ORDER = 'order',\n LEASE = 'lease',\n AGREEMENT = 'agreement',\n PURCHASE_ORDER = 'purchase_order',\n WHOLESALE_ORDER = 'wholesale_order',\n PRODUCTION_ORDER = 'production_order',\n CART = 'cart',\n /**\n * Industry-neutral licensing primitive. The `LicenseSale` STI subtype\n * carries an immutable rights snapshot, a licensee email, optional\n * legal-entity / jurisdiction fields, and a signed-PDF reference.\n * Any application that sells rights for a fee (stock media,\n * music licensing, code-asset marketplace, license keys, etc.)\n * uses this subtype.\n */\n LICENSE_SALE = 'license_sale',\n}\n\nexport enum ContractStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n ACCEPTED = 'accepted',\n DECLINED = 'declined',\n COMPLETED = 'completed',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Fulfillment Types\n// ============================================================================\n\nexport enum FulfillmentType {\n SHIPMENT = 'shipment',\n DELIVERY = 'delivery',\n PICKUP = 'pickup',\n DIGITAL = 'digital',\n SERVICE = 'service',\n}\n\nexport enum FulfillmentStatus {\n PENDING = 'pending',\n PROCESSING = 'processing',\n SHIPPED = 'shipped',\n DELIVERED = 'delivered',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\nexport enum PaymentMethod {\n CASH = 'cash',\n CHECK = 'check',\n CREDIT_CARD = 'credit_card',\n BANK_TRANSFER = 'bank_transfer',\n CRYPTO = 'crypto',\n OTHER = 'other',\n}\n\nexport enum PaymentStatus {\n PENDING = 'pending',\n COMPLETED = 'completed',\n FAILED = 'failed',\n REFUNDED = 'refunded',\n CANCELLED = 'cancelled',\n}\n\n/**\n * Lifecycle status for a saved {@link PaymentInstrument} (card on file).\n * `active` while chargeable, `expired` once the card lapses, `removed` when the\n * customer detaches it.\n */\nexport enum PaymentInstrumentStatus {\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REMOVED = 'removed',\n}\n\n// ============================================================================\n// Payout Types\n// ============================================================================\n\n/**\n * Status machine for {@link Payout}.\n *\n * `pending → sent → confirmed → failed`. `failed` is terminal but the\n * model exposes a dedicated `resetFromFailed()` so an operator can\n * deliberately requeue a payout after fixing the underlying problem;\n * the reset moves the row back to `pending` and clears the failure\n * metadata.\n *\n * Skipping intermediate states is rejected — a `pending` payout cannot\n * jump straight to `confirmed`, and a `sent` payout cannot regress to\n * `pending` without going through `resetFromFailed()` first.\n */\nexport enum PayoutStatus {\n PENDING = 'pending',\n SENT = 'sent',\n CONFIRMED = 'confirmed',\n FAILED = 'failed',\n}\n\n// ============================================================================\n// PaymentIntent Types\n// ============================================================================\n\n/**\n * Status machine for {@link PaymentIntent}.\n *\n * `awaiting_payment → paid → (issued | retired)`, with `expired` and\n * `cancelled` as alternate terminal states reachable from\n * `awaiting_payment`.\n *\n * - `AWAITING_PAYMENT` — open quote, accepting any of the listed\n * payment options.\n * - `PAID` — one option was satisfied by an incoming payment. The\n * other options are implicitly retired; later inbound funds to a\n * retired option must be flagged for refund by the consumer.\n * - `ISSUED` — downstream rights / contract / fulfillment have been\n * created and linked. Terminal happy-path state.\n * - `RETIRED` — paid but the satisfaction was reversed (refund,\n * chargeback, etc.). Terminal.\n * - `EXPIRED` — the USD-price-lock window passed without payment.\n * Terminal.\n * - `CANCELLED` — the buyer or the system explicitly cancelled the\n * intent before it was paid. Terminal.\n */\nexport enum PaymentIntentStatus {\n AWAITING_PAYMENT = 'awaiting_payment',\n PAID = 'paid',\n ISSUED = 'issued',\n RETIRED = 'retired',\n EXPIRED = 'expired',\n CANCELLED = 'cancelled',\n}\n\n/**\n * One way for a {@link PaymentIntent} to be satisfied. The intent lists\n * an array of these; satisfying any one of them transitions the intent\n * to `PAID` and implicitly retires the rest.\n *\n * Industry-neutral: a marketplace that accepts USDC-on-Base and BTC\n * lists two options; a SaaS billing flow that accepts Stripe and\n * PayPal lists two; a kiosk that accepts only one rail lists one.\n */\nexport interface PaymentOption {\n /**\n * Stable id of the `PaymentBackend` adapter that fulfills this\n * option — must match a `backendId` the consumer's payment-routing\n * layer recognises. Examples: `base-usdc`, `solana-usdc`, `btc`,\n * `stripe`, `paypal`.\n */\n backendId: string;\n /**\n * Payout-rail-qualified currency code, e.g. `USDC-base`, `BTC`,\n * `USD-stripe`. The same convention used by\n * `Vendor.payoutAddresses` and `Payment.nativeCurrency`.\n */\n currency: string;\n /**\n * Optional chain identifier for blockchain-backed options (`base`,\n * `ethereum`, `solana`, ...). Pure-fiat options leave this empty.\n */\n chain?: string;\n /**\n * Destination address / account id the buyer should send funds to\n * for this option (EVM address, BTC address, Stripe payment-intent\n * id, etc.).\n */\n payTo: string;\n /**\n * Amount denominated in `currency`. Stored at decimal precision —\n * a USDC option might be `199.0`, a BTC option `0.00713`.\n */\n nativeAmount: number;\n /**\n * Optional on-chain memo / payment reference (Solana memo, BTC OP_RETURN\n * tag, Stripe metadata key). Some backends use this to disambiguate\n * which intent an inbound payment satisfies.\n */\n memo?: string;\n /**\n * Whether this option supports the x402 HTTP-402 payment-required\n * flow. Consumers that build agent-driven flows use this flag to\n * filter the offered options.\n */\n x402Capable?: boolean;\n /**\n * Optional per-option expiry — when a single rail's quote becomes\n * stale earlier than the intent-wide price-lock window (e.g. a\n * volatile-currency option that re-quotes more aggressively). ISO\n * 8601 string. Empty / missing means \"inherit the intent's\n * `priceLockExpiresAt`\".\n */\n expiresAt?: string;\n}\n\n// ============================================================================\n// Invoice Types\n// ============================================================================\n\nexport enum InvoiceStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n VIEWED = 'viewed',\n PARTIAL = 'partial',\n PAID = 'paid',\n OVERDUE = 'overdue',\n CANCELLED = 'cancelled',\n WRITTEN_OFF = 'written_off',\n}\n\n// ============================================================================\n// Common Interfaces\n// ============================================================================\n\n/**\n * Address structure used for billing and shipping\n */\nexport interface Address {\n street1?: string;\n street2?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}\n\n/**\n * Options for recording a payment with ledger integration\n */\nexport interface RecordPaymentOptions {\n /** The ledger to record the journal entry in */\n ledgerId: string;\n /** Account ID for receivables (credit side) */\n receivablesAccountId: string;\n /** Account ID for cash/bank (debit side) */\n cashAccountId: string;\n}\n\n/**\n * Options for recognizing revenue on an invoice\n */\nexport interface RecognizeRevenueOptions {\n /** Account ID for accounts receivable (debit side) */\n arAccountId: string;\n /** Account ID for revenue (credit side) */\n revenueAccountId: string;\n /** Account ID for tax payable (credit side, optional) */\n taxAccountId?: string;\n}\n\n// ============================================================================\n// Accounting-provider sync shapes\n// ============================================================================\n\n/**\n * A single line item in the format expected by `@happyvertical/accounting`\n * providers (QBO, Stripe, …). Mirrors the object built by\n * {@link InvoiceLineItem.toAccountingLineItem}. The SDK isn't a dependency of\n * this package, so the shape is declared locally rather than imported.\n */\nexport interface AccountingLineItemInput {\n description: string;\n sku?: string;\n quantity: number;\n unitPrice: number;\n discount?: number;\n taxRate?: number;\n amount: number;\n periodStart?: Date;\n periodEnd?: Date;\n}\n\n/**\n * An invoice in the format expected by `@happyvertical/accounting` providers.\n * Mirrors the object built by {@link Invoice.toAccountingInput}; money is in\n * currency **major** units, as the SDK expects.\n */\nexport interface AccountingInvoiceInput {\n id: string;\n externalId?: string;\n invoiceNumber: string;\n customerId: string;\n customerExternalId?: string;\n issueDate: Date;\n dueDate: Date;\n lineItems: AccountingLineItemInput[];\n subtotal: number;\n taxAmount: number;\n totalAmount: number;\n currency: string;\n reference?: string;\n memo?: string;\n}\n\n// ============================================================================\n// Model constructor option interfaces\n//\n// Each model's `constructor(options)` accepts a partial bag of its own fields.\n// Declaring a dedicated `XxxOptions extends SmrtObjectOptions` interface keeps\n// the constructors strongly typed (no `any`) while still allowing the\n// framework's base options (db, ai, fs, _className, …) through.\n// ============================================================================\n\n/**\n * Constructor options for {@link Customer}.\n */\nexport interface CustomerOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n creditLimit?: number;\n paymentTerms?: string;\n taxExempt?: boolean;\n taxId?: string;\n defaultShippingAddress?: Address;\n defaultBillingAddress?: Address;\n status?: CustomerStatus;\n customerType?: CustomerType | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Vendor}.\n */\nexport interface VendorOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n leadTimeDays?: number;\n minimumOrderAmount?: number;\n paymentTerms?: string;\n currency?: string;\n defaultContactEmail?: string;\n defaultContactPhone?: string;\n status?: VendorStatus;\n notes?: string;\n payoutAddresses?: Record<string, string> | string | null;\n}\n\n/**\n * Constructor options for {@link Contract} and its STI subtypes.\n */\nexport interface ContractOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractType?: ContractType;\n status?: ContractStatus;\n customerId?: string | null;\n vendorId?: string | null;\n subtotal?: number;\n taxAmount?: number;\n totalAmount?: number;\n currency?: string;\n issueDate?: Date;\n dueDate?: Date | null;\n expiryDate?: Date | null;\n reference?: string;\n notes?: string;\n terms?: string;\n channelId?: string;\n}\n\n/** Purchase-order header options stored in the existing STI metadata. */\nexport interface PurchaseOrderOptions extends ContractOptions {\n /** Expected delivery calendar date (YYYY-MM-DD); empty means unspecified. */\n expectedDate?: string;\n /** Delivery address/instructions snapshot. */\n shipTo?: string;\n}\n\n/**\n * Constructor options for {@link LicenseSale} (Contract STI subtype). Extends\n * {@link ContractOptions} with the licensing-specific meta fields.\n */\nexport interface LicenseSaleOptions extends ContractOptions {\n skuId?: string;\n paymentId?: string;\n licenseeEmail?: string;\n licenseeLegalEntity?: string;\n licenseeJurisdiction?: string;\n rightsMedium?: string;\n rightsDistributionScope?: string;\n rightsExclusivity?: string;\n rightsDuration?: string;\n rightsTerritory?: string;\n rightsSublicensing?: boolean;\n rightsDerivatives?: boolean;\n pdfUrl?: string;\n pdfHash?: string;\n onChainHashRegistryRef?: string;\n}\n\n/**\n * Constructor options for {@link ContractLineItem}.\n */\nexport interface ContractLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n description?: string;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n taxRate?: number;\n amount?: number;\n productId?: string;\n sku?: string;\n startDate?: Date | null;\n endDate?: Date | null;\n billingPeriod?: string;\n sortOrder?: number;\n}\n\n/**\n * How the provider collects an invoice (#3190): `charge_automatically`\n * charges the payer's saved card; `send_invoice` asks the payer to pay. Empty\n * for an invoice never pushed to a provider, or pushed before it was recorded.\n */\nexport type InvoiceCollectionMethod =\n | ''\n | 'send_invoice'\n | 'charge_automatically';\n\n/**\n * Constructor options for {@link Invoice}.\n */\nexport interface InvoiceOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n customerId?: string;\n contractId?: string;\n invoiceNumber?: string;\n reference?: string;\n issueDate?: Date;\n dueDate?: Date;\n paidDate?: Date | null;\n subtotal?: number;\n taxAmount?: number;\n providerTaxAmount?: number;\n totalAmount?: number;\n amountPaid?: number;\n currency?: string;\n status?: InvoiceStatus;\n arJournalId?: string;\n revenueJournalId?: string;\n externalId?: string;\n customerExternalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n collectionMethod?: InvoiceCollectionMethod;\n sentAt?: Date | null;\n viewedAt?: Date | null;\n remindersSent?: number;\n lastReminderAt?: Date | null;\n notes?: string;\n customerNotes?: string;\n terms?: string;\n}\n\n/** Retained editing modes, validated against resolved model fields before reuse. */\nexport interface InvoiceLineEditorState {\n /** Lossless editor draft; never authoritative for ordinary model saves. */\n draft: InvoiceLineDraft;\n /** Context used to resolve that draft; caller authority must still match on reload. */\n context: InvoiceCalculationContext;\n}\n\n/** Constructor options for {@link InvoiceLineItem}. */\nexport interface InvoiceLineItemOptions extends SmrtObjectOptions {\n /** Optional retained editor modes and their original calculation context. */\n invoiceEditorState?: InvoiceLineEditorState | null;\n /** Serialized editor state loaded from persistence; malformed JSON is ignored. */\n invoiceEditorStateJson?: string;\n tenantId?: string | null;\n invoiceId?: string;\n description?: string;\n sku?: string;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n taxRate?: number;\n amount?: number;\n sourceType?: string;\n sourceId?: string;\n periodStart?: Date | null;\n periodEnd?: Date | null;\n revenueAccountId?: string;\n sortOrder?: number;\n}\n\n/**\n * Constructor options for {@link Fulfillment}.\n */\nexport interface FulfillmentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n fulfillmentType?: FulfillmentType;\n status?: FulfillmentStatus;\n trackingNumber?: string;\n carrier?: string;\n shippingAddress?: Address;\n shippedAt?: Date | null;\n deliveredAt?: Date | null;\n estimatedDelivery?: Date | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link FulfillmentLineItem}.\n */\nexport interface FulfillmentLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n fulfillmentId?: string;\n contractLineItemId?: string;\n quantityFulfilled?: number;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payment}.\n */\nexport interface PaymentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string | null;\n customerId?: string | null;\n amount?: number;\n currency?: string;\n method?: PaymentMethod;\n status?: PaymentStatus;\n transactionId?: string;\n reference?: string;\n journalId?: string;\n paidAt?: Date | null;\n notes?: string;\n externalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n backendId?: string;\n backendTxRef?: string;\n nativeAmount?: number;\n nativeCurrency?: string;\n usdAtQuote?: number;\n usdAtConfirmation?: number;\n}\n\n/**\n * Constructor options for {@link PaymentInstrument}.\n */\nexport interface PaymentInstrumentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n customerId?: string;\n backendId?: string;\n providerCustomerId?: string;\n providerPaymentMethodId?: string;\n type?: string;\n brand?: string;\n last4?: string;\n expMonth?: number;\n expYear?: number;\n isDefault?: boolean;\n status?: PaymentInstrumentStatus;\n}\n\n/**\n * Constructor options for {@link PaymentAllocation}.\n */\nexport interface PaymentAllocationOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n invoiceId?: string;\n amount?: number;\n allocatedAt?: Date;\n allocatedBy?: string;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link PaymentIntent}.\n */\nexport interface PaymentIntentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n skuId?: string;\n offeringRef?: string;\n licenseeEmail?: string;\n customerId?: string;\n paymentOptions?: PaymentOption[] | string;\n usdPriceLocked?: number;\n priceLockWindowMs?: number;\n priceLockExpiresAt?: Date | number | string | null;\n status?: PaymentIntentStatus;\n idempotencyKey?: string;\n paidOptionBackendId?: string;\n paymentId?: string;\n paidAt?: Date | number | string | null;\n issuedAt?: Date | number | string | null;\n expiredAt?: Date | number | string | null;\n cancelledAt?: Date | number | string | null;\n retiredAt?: Date | number | string | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payout}.\n */\nexport interface PayoutOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n vendorId?: string;\n grossAmount?: number;\n operatorFee?: number;\n supplierNet?: number;\n currency?: string;\n backendId?: string;\n backendTxRef?: string;\n status?: PayoutStatus;\n sentAt?: Date | number | string | null;\n confirmedAt?: Date | number | string | null;\n failedAt?: Date | number | string | null;\n failureReason?: string;\n notes?: string;\n}\n"],"mappings":"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"}
@@ -6,6 +6,20 @@ import { SmrtCollection } from '@happyvertical/smrt-core';
6
6
  import { PaymentAllocation } from '../models/PaymentAllocation.js';
7
7
  export declare class PaymentAllocationCollection extends SmrtCollection<PaymentAllocation> {
8
8
  static readonly _itemClass: typeof PaymentAllocation;
9
+ /**
10
+ * Apply a payment to several invoices atomically. Callers supply stable UUID
11
+ * allocation ids: exact replays reuse rows; reusing an id with other money
12
+ * or parents fails. Actor authorization remains the application's job.
13
+ */
14
+ allocatePayment(input: {
15
+ paymentId: string;
16
+ allocations: {
17
+ id: string;
18
+ invoiceId: string;
19
+ amount: number;
20
+ }[];
21
+ allocatedBy?: string;
22
+ }): Promise<PaymentAllocation[]>;
9
23
  /**
10
24
  * Find allocations by payment
11
25
  *
@@ -1 +1 @@
1
- {"version":3,"file":"PaymentAllocationCollection.d.ts","sourceRoot":"","sources":["../../src/collections/PaymentAllocationCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,qBAAa,2BAA4B,SAAQ,cAAc,CAAC,iBAAiB,CAAC;IAChF,MAAM,CAAC,QAAQ,CAAC,UAAU,2BAAqB;IAE/C;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOpE;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOpE;;;;;OAKG;IACG,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpE;;;;;OAKG;IACG,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKtE;;;;;;;OAOG;IACG,yBAAyB,CAC7B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IAclB;;;;;;OAMG;IACG,uBAAuB,CAC3B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAQpC;;;;;OAKG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOxE;;;;;;OAMG;IACG,eAAe,CACnB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAc/B;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIlE;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIhD;;;;;;;;OAQG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAOtE"}
1
+ {"version":3,"file":"PaymentAllocationCollection.d.ts","sourceRoot":"","sources":["../../src/collections/PaymentAllocationCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,qBAAa,2BAA4B,SAAQ,cAAc,CAAC,iBAAiB,CAAC;IAChF,MAAM,CAAC,QAAQ,CAAC,UAAU,2BAAqB;IAE/C;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE;QAC3B,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACjE,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAsFhC;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOpE;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOpE;;;;;OAKG;IACG,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpE;;;;;OAKG;IACG,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKtE;;;;;;;OAOG;IACG,yBAAyB,CAC7B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IAclB;;;;;;OAMG;IACG,uBAAuB,CAC3B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAQpC;;;;;OAKG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOxE;;;;;;OAMG;IACG,eAAe,CACnB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAc/B;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIlE;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIhD;;;;;;;;OAQG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAOtE"}
@@ -0,0 +1,58 @@
1
+ /** Exact, transport-neutral cost pricing. All money is signed integer minor units. */
2
+ export type CostBillingMode = 'reimbursement-plus-fee' | 'fee-only' | 'nonbillable' | 'fixed-contract';
3
+ /** Caller-defined precedence, most specific first. No industry hierarchy is assumed. */
4
+ export interface CostMarkupOverride {
5
+ source: string;
6
+ policy?: string;
7
+ version?: string;
8
+ /** Exact percent in [0, 100000], with at most six decimal places. */
9
+ percent?: string;
10
+ }
11
+ /** Detached provenance suitable for the caller's accepted pricing snapshot. */
12
+ export interface ResolvedCostMarkup {
13
+ percent: string;
14
+ selectedIndex: number;
15
+ overrides: CostMarkupOverride[];
16
+ }
17
+ /** Select the first supplied percent, validating even shadowed overrides. */
18
+ export declare function resolveCostMarkup(overrides: readonly CostMarkupOverride[]): ResolvedCostMarkup;
19
+ /** Calculate an explicitly supplied basis; this never reprices persisted snapshots. */
20
+ export declare function calculateCostBilling(input: {
21
+ basisMinor: number;
22
+ mode: CostBillingMode;
23
+ markup: ResolvedCostMarkup;
24
+ }): {
25
+ principalMinor: number;
26
+ feeMinor: number;
27
+ totalMinor: number;
28
+ markup: ResolvedCostMarkup;
29
+ };
30
+ /** Explicit noncompounding tax components; an empty array means tax exempt. */
31
+ export interface CostBillingTaxRule {
32
+ category: string;
33
+ components: readonly {
34
+ id: string;
35
+ percent: string;
36
+ }[];
37
+ }
38
+ /**
39
+ * Tax signed amounts with half-away-from-zero rounding. Invoice scope rounds each
40
+ * component once after aggregation; line scope rounds each line/component pair.
41
+ * A shared component ID must have the same exact rate across categories.
42
+ */
43
+ export declare function calculateCostBillingTax(input: {
44
+ lines: readonly {
45
+ id: string;
46
+ amountMinor: number;
47
+ category: string;
48
+ }[];
49
+ rules: readonly CostBillingTaxRule[];
50
+ roundingScope: 'line' | 'invoice';
51
+ }): {
52
+ taxMinor: number;
53
+ components: {
54
+ id: string;
55
+ taxMinor: number;
56
+ }[];
57
+ };
58
+ //# sourceMappingURL=cost-billing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-billing.d.ts","sourceRoot":"","sources":["../src/cost-billing.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,MAAM,MAAM,eAAe,GACvB,wBAAwB,GACxB,UAAU,GACV,aAAa,GACb,gBAAgB,CAAC;AAErB,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+EAA+E;AAC/E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,kBAAkB,EAAE,CAAC;CACjC;AA4CD,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,kBAAkB,EAAE,GACvC,kBAAkB,CAmBpB;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,kBAAkB,CAAC;CAC5B,GAAG;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CA+BA;AAED,+EAA+E;AAC/E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,KAAK,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxE,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACrC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAiDvE"}