@happyvertical/smrt-commerce 0.58.0 → 0.59.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.
- package/agents/accounting-snapshot-mapper.md +3 -0
- package/agents/quickbooks-pilot.md +56 -0
- package/dist/chunks/{ContractLineItemCollection-D74LbDOI.js → ContractLineItemCollection-BFWJ2e6a.js} +4 -4
- package/dist/chunks/{ContractLineItemCollection-D74LbDOI.js.map → ContractLineItemCollection-BFWJ2e6a.js.map} +1 -1
- package/dist/chunks/{DocumentTaxCollection-BmKyJGZi.js → DocumentTaxCollection-MFfprLH-.js} +9 -9
- package/dist/chunks/{DocumentTaxCollection-BmKyJGZi.js.map → DocumentTaxCollection-MFfprLH-.js.map} +1 -1
- package/dist/chunks/{InvoiceCollection-BPEzXaKm.js → InvoiceCollection-D_8NXuaw.js} +9 -9
- package/dist/chunks/{InvoiceCollection-BPEzXaKm.js.map → InvoiceCollection-D_8NXuaw.js.map} +1 -1
- package/dist/chunks/{TaxCodeCollection-DpQeIqP4.js → TaxCodeCollection-Bc-Z8alx.js} +2 -2
- package/dist/chunks/{TaxCodeCollection-DpQeIqP4.js.map → TaxCodeCollection-Bc-Z8alx.js.map} +1 -1
- package/dist/chunks/{TaxComponentCollection-wFGWOaxy.js → TaxComponentCollection-DUY7A2sU.js} +3 -3
- package/dist/chunks/{TaxComponentCollection-wFGWOaxy.js.map → TaxComponentCollection-DUY7A2sU.js.map} +1 -1
- package/dist/chunks/{allocation-integrity-DgnPec2a.js → allocation-integrity-ri5cUYXB.js} +6 -6
- package/dist/chunks/{allocation-integrity-DgnPec2a.js.map → allocation-integrity-ri5cUYXB.js.map} +1 -1
- package/dist/chunks/{contract-money-BxvY2Kcp.js → contract-money-By1XIzp_.js} +6 -6
- package/dist/chunks/{contract-money-BxvY2Kcp.js.map → contract-money-By1XIzp_.js.map} +1 -1
- package/dist/chunks/{invoice-posting-C1q3CIYz.js → invoice-posting-BfnOyqBR.js} +3 -3
- package/dist/chunks/{invoice-posting-C1q3CIYz.js.map → invoice-posting-BfnOyqBR.js.map} +1 -1
- package/dist/chunks/{retention-accounting-BAKsmbwJ.js → retention-accounting-CASwH8OH.js} +239 -74
- package/dist/chunks/retention-accounting-CASwH8OH.js.map +1 -0
- package/dist/chunks/{tenant-money-barrier-j1m0r6pe.js → tenant-money-barrier-BbbInDGP.js} +3 -3
- package/dist/chunks/{tenant-money-barrier-j1m0r6pe.js.map → tenant-money-barrier-BbbInDGP.js.map} +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/invoice-accounting-sync.d.ts +33 -1
- package/dist/invoice-accounting-sync.d.ts.map +1 -1
- package/dist/invoices.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/quickbooks-pilot-evidence.d.ts +47 -0
- package/dist/quickbooks-pilot-evidence.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +3 -3
- package/package.json +13 -13
- package/dist/chunks/retention-accounting-BAKsmbwJ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention-accounting-CASwH8OH.js","names":["field","request","projection","step"],"sources":["../../src/connected-payments-internal.ts","../../src/models/Payment.ts","../../src/collections/PaymentCollection.ts","../../src/historical-funds-internal.ts","../../src/models/PaymentAllocation.ts","../../src/collections/PaymentAllocationCollection.ts","../../src/accounting-snapshot.ts","../../src/quickbooks-pilot-evidence.ts","../../src/invoice-accounting-sync.ts","../../src/svelte/invoices/calculations.ts","../../src/accounting-steps-internal.ts","../../src/ordinary-accounting.ts","../../src/retention-accounting.ts"],"sourcesContent":["/**\n * Internal write authority for the connected-payments commands (#3831); not a\n * public bypass. Connected `Payment` rows, connected `PaymentIntent` creation\n * and option writes are refused unless they run inside a command for the\n * row's tenant, so no generated REST, MCP or CLI surface can forge them.\n */\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nconst authority = new AsyncLocalStorage<{ tenantId: string }>();\n\n/** @internal Run a connected-payments command write for one tenant. */\nexport function withConnectedPaymentAuthority<T>(\n tenantId: string,\n operation: () => Promise<T>,\n): Promise<T> {\n return authority.run({ tenantId: tenantId.toLowerCase() }, operation);\n}\n\n/** @internal Whether a connected-payments command for this tenant is running. */\nexport function hasConnectedPaymentAuthority(\n tenantId: string | null | undefined,\n): boolean {\n const current = authority.getStore();\n return (\n !!current &&\n typeof tenantId === 'string' &&\n current.tenantId === tenantId.toLowerCase()\n );\n}\n","import { hasConnectedPaymentAuthority } from '../connected-payments-internal.js';\nimport { hasOrdinaryAccountingAuthority } from '../ordinary-accounting-internal.js';\nimport { hasRetentionAccountingAuthority } from '../retention-accounting-internal.js';\n/**\n * Payment model - tracks payments with ledger integration\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n type SmrtDeleteOptions,\n SmrtObject,\n type SmrtSaveOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { Journal } from '@happyvertical/smrt-ledgers';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n assertAllocationParent,\n claimAllocationParent,\n} from '../allocation-integrity.js';\nimport {\n assertCustomerFundsWrite,\n customerFundsState,\n} from '../customer-funds-internal.js';\nimport { assertIntegerMinorUnits } from '../money.js';\nimport {\n type PaymentKind,\n PaymentMethod,\n type PaymentOptions,\n PaymentStatus,\n type RecordPaymentOptions,\n} from '../types/index.js';\n\n/**\n * Legal status transitions for a Payment, keyed by the prior persisted status.\n * A status mapping to itself (no-op re-save) is always permitted and handled\n * separately. Transitioning *into* COMPLETED is additionally gated on the\n * verified `recordPayment()` settlement path (see {@link Payment.save}) — it is\n * never reachable by raw mass-assignment even though it appears here as a\n * structurally legal edge out of PENDING.\n *\n * Forward path: PENDING → COMPLETED, with FAILED / CANCELLED as alternate\n * terminal exits from PENDING and REFUNDED reachable from COMPLETED.\n */\nconst PAYMENT_STATUS_TRANSITIONS: Record<PaymentStatus, PaymentStatus[]> = {\n [PaymentStatus.PENDING]: [\n PaymentStatus.COMPLETED,\n PaymentStatus.FAILED,\n PaymentStatus.CANCELLED,\n ],\n // A completed payment can only be reversed via refund.\n [PaymentStatus.COMPLETED]: [PaymentStatus.REFUNDED],\n // Terminal states.\n [PaymentStatus.FAILED]: [],\n [PaymentStatus.REFUNDED]: [],\n [PaymentStatus.CANCELLED]: [],\n};\n\n/**\n * Module-scoped record of the status each Payment instance was loaded with,\n * so the save-time transition guard can compare the prior persisted status\n * against the one being written without adding a persisted column. WeakMap\n * keeps it out of the schema and GCs with the instance — same pattern as the\n * other commerce models.\n */\nconst loadedPaymentStatus = new WeakMap<Payment, PaymentStatus>();\n\n/**\n * Marks instances whose transition into COMPLETED is being driven by the\n * verified `recordPayment()` settlement path (which posts a balanced journal\n * before flipping the status). The save-time guard consults this set so that\n * COMPLETED can only be reached through that path, never via raw\n * mass-assignment on the generated update route. Cleared after the save runs.\n */\nconst settlementInProgress = new WeakSet<Payment>();\n\n/** Prevent concurrent temporary executor bindings on the same instance. */\nconst recordingInProgress = new WeakSet<Payment>();\n\n/**\n * Payment represents a financial transaction against a contract.\n *\n * Payments can be integrated with smrt-ledgers to automatically\n * create balanced journal entries for proper accounting.\n *\n * @example\n * ```typescript\n * // Create a payment\n * const payment = await payments.create({\n * contractId: order.id,\n * customerId: customer.id,\n * amount: 1500.00,\n * method: PaymentMethod.CREDIT_CARD,\n * transactionId: 'stripe_pi_123456'\n * });\n *\n * // Record with ledger integration\n * await payment.recordPayment({\n * ledgerId: ledger.id,\n * receivablesAccountId: arAccount.id,\n * cashAccountId: bankAccount.id\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n // ROOT FIX (S5 audit #1390 round 4): restrict the generated create/update\n // write surface so privileged / settlement-derived fields can NEVER be set\n // by a generated REST/MCP route — closing the status-mass-assignment vector\n // at the surface rather than relying solely on the save()-time guard.\n //\n // `writable` is an allowlist: only these fields survive applyWritablePolicy()\n // on BOTH create and update (#1540). Deliberately EXCLUDED:\n // - `status` — a COMPLETED Payment is settlement proof downstream\n // (PaymentIntent's PAID verification trusts it). It is only ever set by\n // the verified `recordPayment()` settlement path, never by a caller. This\n // closes the \"forged COMPLETED Payment via api.create\" vector (codex HIGH#1).\n // - `journalId` / `paidAt` — settlement-derived, written by recordPayment().\n // - `syncedAt` — provider-sync bookkeeping, written by the sync path.\n api: {\n include: ['list', 'get', 'create', 'update'],\n writable: [\n 'kind',\n 'contractId',\n 'customerId',\n 'amount',\n 'currency',\n 'method',\n 'transactionId',\n 'reference',\n 'notes',\n 'externalId',\n 'externalProvider',\n 'backendId',\n 'backendTxRef',\n 'nativeAmount',\n 'nativeCurrency',\n 'usdAtQuote',\n 'usdAtConfirmation',\n ],\n },\n // NOTE: `recordPayment` is intentionally NOT exposed over MCP. It posts a\n // balanced journal into smrt-ledgers (moves money in the books) and flips\n // the payment to COMPLETED — not safe as an unguarded MCP tool that carries\n // no authz. Financial mutations must go through application code that\n // enforces permissions. The MCP create/update tools honor the same\n // `api.writable` allowlist above, so `status` is unsettable over MCP too.\n // See S5 audit #1390.\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class Payment extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n /** Incoming settlement or outgoing customer refund. Amount stays positive. */\n kind: PaymentKind = 'payment';\n\n /** Command-owned customer advance policy, source lineage and append-only application evidence. */\n @field({ type: 'text' })\n customerFundsJson = '';\n\n /** Immutable provider-refund source binding owned by retention commands. */\n @field({ sensitive: true })\n retentionAccountingBindingJson = '';\n\n /** Immutable ordinary-provider refund reservation; command-owned. */\n @field({ sensitive: true })\n ordinaryAccountingBindingJson = '';\n\n /**\n * Tenant ID for multi-tenant isolation\n * Nullable to support both tenant-scoped and global payments\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Contract this payment is for\n */\n @field({ description: 'The order or agreement this payment is for, if any.' })\n @foreignKey('SalesContract', { validateSubtype: true })\n contractId: string | null = null;\n\n /**\n * Customer who made the payment\n */\n @field({ description: 'The customer who paid.' })\n @foreignKey('Customer')\n customerId: string | null = null;\n\n /**\n * Payment amount, in **integer minor units** (cents, satoshis).\n *\n * The `= 0` initializer is load-bearing: SMRT maps an integer literal to\n * INTEGER and a decimal literal to DECIMAL. This is the figure\n * `PaymentAllocation.save()` caps allocations against and `Invoice.amountPaid`\n * is summed from, so it must be in the same exact units as both (#2401).\n */\n @field({ description: 'How much was paid.', ui: { format: 'money' } })\n amount: number = 0;\n\n /**\n * Currency code (ISO 4217)\n */\n @field({\n description: 'The currency of the payment.',\n ui: { widget: 'currency' },\n })\n currency: string = 'USD';\n\n /**\n * Payment method used\n */\n @field({\n description: 'How it was paid: cash, check, card, bank transfer or other.',\n })\n method: PaymentMethod = PaymentMethod.BANK_TRANSFER;\n\n /**\n * Current payment status\n */\n @field({\n description:\n 'Whether the payment is pending, completed, failed or refunded.',\n })\n status: PaymentStatus = PaymentStatus.PENDING;\n\n /**\n * External transaction ID (from payment processor)\n */\n transactionId: string = '';\n\n /**\n * Internal reference number\n */\n @field({ description: 'A reference note, such as a check number.' })\n reference: string = '';\n\n /**\n * Link to smrt-ledgers Journal (created by recordPayment)\n */\n @crossPackageRef('@happyvertical/smrt-ledgers:Journal')\n journalId: string = '';\n\n /**\n * When the payment was completed\n */\n @field({ description: 'When the money was received.' })\n paidAt: Date | null = null;\n\n /**\n * Notes about the payment\n */\n @field({\n description: 'Anything worth remembering about this payment.',\n ui: { widget: 'textarea' },\n })\n notes: string = '';\n\n // ============================================================================\n // Provider Sync\n // ============================================================================\n\n /**\n * External ID in accounting provider (e.g., QBO payment ID)\n */\n externalId: string = '';\n\n /**\n * Accounting provider name ('quickbooks' | 'stripe' | 'paypal' | etc.)\n */\n externalProvider: string = '';\n\n /**\n * When payment was last synced to provider\n */\n syncedAt: Date | null = null;\n\n // ============================================================================\n // Payment Backend Identity\n // ============================================================================\n //\n // When a `PaymentBackend` adapter (Stripe, x402, BTC RPC, etc.) brokers the\n // payment rather than a human recording it manually, we capture the\n // backend identity, its native-currency amount, and the USD valuation at\n // both quote and confirmation time. The classic `amount` / `currency`\n // pair stays as the canonical settlement number; the backend fields\n // describe *how* the funds arrived and let downstream accounting close\n // the loop on volatile-currency drift.\n //\n // All fields default to empty / zero so existing Payment consumers that\n // pre-date the marketplace adapter machinery are unaffected.\n\n /**\n * Stable identifier of the `PaymentBackend` adapter that served this\n * payment — e.g. `base-usdc`, `solana-usdc`, `btc`, `stripe`, `paypal`.\n *\n * Distinct from {@link externalProvider}: `backendId` names the SMRT\n * payment-rail adapter, while `externalProvider` names a downstream\n * accounting destination (QuickBooks, Stripe-the-accounting-source).\n * The same Stripe payment will have `backendId: 'stripe'` AND\n * `externalProvider: 'stripe'`; a crypto payment synced to QBO will\n * have `backendId: 'base-usdc'` and `externalProvider: 'quickbooks'`.\n */\n backendId: string = '';\n\n /**\n * Chain transaction hash or backend aggregator's reference id. For\n * on-chain payments this is the tx hash (`0x...` on EVM, base58 sig on\n * Solana, txid on Bitcoin); for fiat-rail backends it's the gateway's\n * own reference. Kept distinct from {@link transactionId} so consumers\n * that already populate `transactionId` with a provider-internal id\n * don't have to overload it.\n */\n backendTxRef: string = '';\n\n /**\n * The amount the backend actually moved, in the native currency's own\n * **integer minor units** — satoshis for BTC, cents for a fiat rail. For\n * stablecoin rails this typically equals `amount`; for volatile-currency\n * rails it's the satoshi/wei figure the chain recorded, independent of any\n * USD valuation.\n *\n * Fresh PostgreSQL and DuckDB INTEGER columns materialize as BIGINT. SMRT\n * rejects values outside JavaScript's safe-integer range during hydration;\n * existing PostgreSQL `int4` columns require the explicit widening in #2424.\n */\n nativeAmount: number = 0;\n\n /**\n * Code identifying the native currency `nativeAmount` is denominated\n * in. Mirrors the `backendId` namespacing convention — `USDC-base`,\n * `BTC`, `ETH`, `USD-stripe`. Empty string means \"use {@link currency}\"\n * (i.e. the payment was already quoted and settled in the same\n * currency).\n */\n nativeCurrency: string = '';\n\n /**\n * USD valuation of the payment at the moment the price was quoted to\n * the buyer (typically the moment a `PaymentIntent` was issued), in\n * **integer minor units** (US cents). A default of `0` means no USD-quote\n * snapshot was taken (the payment was already USD-denominated or the\n * backend doesn't require drift accounting).\n *\n * This is money describing the same funds as {@link Payment.amount}, so it\n * converts with it — a dollars-here / cents-there split would make\n * {@link Payment.usdDrift} meaningless (#2401).\n */\n usdAtQuote: number = 0;\n\n /**\n * USD valuation of the payment at the moment it was confirmed on the\n * backend (chain confirmation, gateway settlement, etc.), in integer minor\n * units (US cents). The delta between {@link usdAtQuote} and\n * `usdAtConfirmation` is the USD drift the operator absorbs (positive or\n * negative) when accepting payment in a volatile native currency (#2401).\n */\n usdAtConfirmation: number = 0;\n\n /**\n * Connected provider account (for example a Stripe `acct_...`) a direct\n * charge was made on, so the funds landed with the tenant rather than the\n * platform (#3831). Empty for platform-account and non-Connect payments.\n * Server-managed: written only by the connected-payments commands.\n */\n connectedAccountId: string = '';\n\n /** Immutable host-supplied agreement/fee-policy version at checkout pricing. */\n connectedFeePolicyRef: string = '';\n\n /**\n * Platform application fee the provider withheld from this direct charge,\n * in integer minor units of {@link currency} (#3831). Settled at source, so\n * {@link recordPayment} books it as a fee expense, never as a payable.\n * Server-managed.\n */\n applicationFeeCents: number = 0;\n\n /**\n * For a `refund` of a connected charge, the `Payment` it refunds (#3831).\n * Server-managed.\n */\n refundOfPaymentId: string = '';\n\n /**\n * For a `refund` of a connected charge, the provider's refund state:\n * `requested` (recorded before the provider is asked), `pending` until the\n * provider confirms it, then `succeeded` (journaled) or `failed` (#3831).\n * Server-managed.\n */\n connectedRefundState: '' | 'requested' | 'pending' | 'succeeded' | 'failed' =\n '';\n\n /**\n * For a `refund` of a connected charge, whether the platform's application\n * fee was refunded with it (#3831). Server-managed and frozen.\n */\n applicationFeeRefunded: boolean = false;\n\n constructor(options: PaymentOptions = {}) {\n super(options);\n if (options.kind !== undefined) this.kind = options.kind;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.contractId !== undefined) this.contractId = options.contractId;\n if (options.customerId !== undefined) this.customerId = options.customerId;\n if (options.amount !== undefined) this.amount = options.amount;\n if (options.currency !== undefined) this.currency = options.currency;\n if (options.method !== undefined) this.method = options.method;\n if (options.status !== undefined) this.status = options.status;\n if (options.transactionId !== undefined)\n this.transactionId = options.transactionId;\n if (options.reference !== undefined) this.reference = options.reference;\n if (options.customerFundsJson !== undefined)\n this.customerFundsJson = options.customerFundsJson;\n if (options.journalId !== undefined) this.journalId = options.journalId;\n if (options.paidAt !== undefined) this.paidAt = options.paidAt;\n if (options.notes !== undefined) this.notes = options.notes;\n if (options.externalId !== undefined) this.externalId = options.externalId;\n if (options.externalProvider !== undefined)\n this.externalProvider = options.externalProvider;\n if (options.syncedAt !== undefined) this.syncedAt = options.syncedAt;\n if (options.backendId !== undefined) this.backendId = options.backendId;\n if (options.backendTxRef !== undefined)\n this.backendTxRef = options.backendTxRef;\n if (options.nativeAmount !== undefined)\n this.nativeAmount = options.nativeAmount;\n if (options.nativeCurrency !== undefined)\n this.nativeCurrency = options.nativeCurrency;\n if (options.usdAtQuote !== undefined) this.usdAtQuote = options.usdAtQuote;\n if (options.usdAtConfirmation !== undefined)\n this.usdAtConfirmation = options.usdAtConfirmation;\n if (options.connectedAccountId !== undefined)\n this.connectedAccountId = options.connectedAccountId;\n if (options.connectedFeePolicyRef !== undefined)\n this.connectedFeePolicyRef = options.connectedFeePolicyRef;\n if (options.applicationFeeCents !== undefined)\n this.applicationFeeCents = options.applicationFeeCents;\n if (options.refundOfPaymentId !== undefined)\n this.refundOfPaymentId = options.refundOfPaymentId;\n if (options.connectedRefundState !== undefined)\n this.connectedRefundState = options.connectedRefundState;\n if (options.applicationFeeRefunded !== undefined)\n this.applicationFeeRefunded = options.applicationFeeRefunded;\n }\n\n /**\n * Capture the persisted status the row was loaded with, so the save-time\n * transition guard can reject illegal status flips made via raw field\n * assignment (mass-assignment on the generated update route, a stale caller,\n * etc.). Freshly-constructed (not-yet-saved) payments have no prior status.\n */\n override async initialize(): Promise<this> {\n await super.initialize();\n if (await this.isSaved()) {\n loadedPaymentStatus.set(this, this.status);\n }\n return this;\n }\n\n /**\n * Save-time state-machine guard (S5 audit #1390).\n *\n * `status` is mass-assignable on the generated update/create routes, and a\n * COMPLETED Payment is treated as settlement proof downstream — e.g.\n * {@link PaymentIntent}'s PAID verification trusts a COMPLETED Payment row.\n * A forged `status: 'completed'` (with arbitrary amounts and no journal)\n * would therefore satisfy that check without any money having moved.\n *\n * This guard enforces two things:\n * - **Transitions must be legal** per {@link PAYMENT_STATUS_TRANSITIONS}.\n * - **Reaching COMPLETED requires the verified settlement path — on\n * creation AND on update.** Only `recordPayment()` (which posts a\n * balanced journal and links `journalId`) may write a Payment into\n * COMPLETED; it announces itself via {@link settlementInProgress}. A raw\n * `status: 'completed'` is rejected whether the row is brand-new (a\n * GENESIS `create({ status: 'completed' })`) or already persisted — that\n * is the exact path a forged COMPLETED would take to satisfy\n * PaymentIntent's PAID verification without any money having moved (codex\n * HIGH#1, #1390 round 5). There is deliberately NO import/fixture\n * carve-out: a COMPLETED Payment is settlement proof downstream, so it is\n * only ever reachable through `recordPayment()`, on every surface\n * (REST/MCP/CLI/direct). Fixtures/migrations that need a completed payment\n * must drive it through `recordPayment()` (or start non-COMPLETED).\n */\n override async save(options?: SmrtSaveOptions): Promise<this> {\n return this.withTransaction(async () => {\n if (this.kind !== 'payment' && this.kind !== 'refund')\n throw new Error('Payment kind must be payment or refund');\n // The claim is the compare-and-swap against the caller's revision (it\n // advances the stored revision), so the guarded save below must expect\n // the revision the claim just wrote, not the caller's pre-claim one.\n const callerRevision = options?.expectedUpdatedAt;\n await claimAllocationParent(this, 'payment', callerRevision);\n if (callerRevision !== undefined && this.updated_at)\n options = { ...options, expectedUpdatedAt: this.updated_at };\n // Whole minor units on every surface (#2401). `amount` is what\n // `PaymentAllocation.save()` and `Payout.assertCappedBySourcePayment()` cap\n // against with exact integer comparisons, so a fractional major-unit write\n // here would silently break both.\n assertIntegerMinorUnits('Payment', this.id || '<new>', [\n ['amount', this.amount],\n ['nativeAmount', this.nativeAmount],\n ['usdAtQuote', this.usdAtQuote],\n ['usdAtConfirmation', this.usdAtConfirmation],\n ['applicationFeeCents', this.applicationFeeCents],\n ]);\n if (\n this.applicationFeeCents < 0 ||\n this.applicationFeeCents > this.amount\n )\n throw new Error(\n 'Payment applicationFeeCents must be between 0 and the payment amount',\n );\n if (this.applicationFeeCents > 0 && !this.connectedAccountId)\n throw new Error(\n 'Payment applicationFeeCents requires a connectedAccountId',\n );\n\n const priorRow = await this.loadPersistedRow();\n if (this.customerFundsJson || priorRow?.customer_funds_json)\n assertCustomerFundsWrite(this);\n const ordinaryBinding =\n this.ordinaryAccountingBindingJson ||\n String(priorRow?.ordinary_accounting_binding_json ?? '');\n if (\n ordinaryBinding &&\n !hasOrdinaryAccountingAuthority(\n this.tenantId,\n JSON.parse(ordinaryBinding).invoiceId,\n )\n )\n throw new Error(\n 'Provider-recorded refund is immutable; use an explicit reversal workflow',\n );\n const retainedBinding =\n this.retentionAccountingBindingJson ||\n String(priorRow?.retention_accounting_binding_json ?? '');\n if (\n retainedBinding &&\n !hasRetentionAccountingAuthority(\n this.tenantId,\n JSON.parse(retainedBinding).invoiceId,\n )\n )\n throw new Error(\n 'Provider-recorded refund is immutable; use an explicit reversal workflow',\n );\n // A connected charge or refund (#3831) is written only by the\n // connected-payments commands: its identity and amounts never change\n // after the first write, even while PENDING (a pending refund can wait\n // days for the provider), so a generated update cannot repoint it.\n // Every write of a connected row (creation, refund state, provider\n // reference, status) must come from a connected-payments command for\n // its tenant: generated surfaces (including CLI `--from-file`) cannot\n // forge or advance one.\n if (\n (this.connectedAccountId ||\n String(priorRow?.connected_account_id ?? '')) &&\n !hasConnectedPaymentAuthority(this.tenantId)\n )\n throw new Error(\n 'Connected payments and refunds are written only by the connected-payments commands',\n );\n if (priorRow && String(priorRow.connected_account_id ?? ''))\n this.assertConnectedIdentityUnchanged(priorRow);\n const prior =\n priorRow && priorRow.status != null\n ? (priorRow.status as PaymentStatus)\n : loadedPaymentStatus.get(this);\n this.assertStatusTransition(prior);\n\n // Reaching COMPLETED is only legal via the verified settlement path,\n // regardless of whether this is a create (no persisted prior) or an\n // update of an existing row. A GENESIS create with status: COMPLETED would\n // otherwise forge settlement proof, so we close it here at the model level\n // — this covers EVERY surface (REST/MCP/CLI/direct), independent of any\n // writable-allowlist gap on a given surface.\n const reachingCompleted =\n this.status === PaymentStatus.COMPLETED &&\n prior !== PaymentStatus.COMPLETED;\n if (reachingCompleted && !settlementInProgress.has(this)) {\n throw new Error(\n `Payment ${this.id || '<new>'}: cannot set status to COMPLETED via ` +\n 'raw assignment — a Payment is only completed through ' +\n 'recordPayment(), which posts a balanced settlement journal. Use ' +\n 'recordPayment() instead of setting status directly.',\n );\n }\n\n // Freeze the settled monetary fields once the row is already COMPLETED in\n // the database (S5 audit #1390 round 6 — codex ROOT INSIGHT; mirrors the\n // PaymentIntent PAID backing-field freeze). A COMPLETED Payment is\n // settlement proof: its amount was reconciled against a balanced journal\n // and is trusted downstream — PaymentIntent's PAID verification binds the\n // winning option's `nativeAmount` to `Payment.amount` / `nativeAmount`. The\n // only legal exit from COMPLETED is COMPLETED → REFUNDED, and a refund must\n // NOT alter the settled figures. Closing this at the model level covers\n // EVERY surface (REST/MCP/CLI/direct), independent of the per-surface\n // writable allowlist (`amount`/`currency`/`nativeAmount`/... are writable\n // on a *new* PENDING payment, but must be immutable once settled).\n if (\n priorRow &&\n (priorRow.status === PaymentStatus.COMPLETED ||\n priorRow.status === PaymentStatus.REFUNDED)\n ) {\n this.assertSettledAmountsUnchanged(priorRow);\n }\n\n try {\n await assertAllocationParent(this, 'payment');\n const result = (await super.save(options)) as this;\n loadedPaymentStatus.set(this, this.status);\n return result;\n } finally {\n settlementInProgress.delete(this);\n }\n });\n }\n\n /** Managed receipts and refunds retain immutable cash provenance. */\n override async delete(options: SmrtDeleteOptions = {}): Promise<void> {\n const persisted = await this.loadPersistedRow();\n if (\n this.retentionAccountingBindingJson ||\n persisted?.retention_accounting_binding_json ||\n this.ordinaryAccountingBindingJson ||\n persisted?.ordinary_accounting_binding_json\n )\n throw new Error('Provider-recorded refund history cannot be deleted');\n if (this.customerFundsJson || persisted?.customer_funds_json)\n throw new Error('Customer funds cash history cannot be deleted');\n if (this.connectedAccountId || persisted?.connected_account_id)\n throw new Error('Connected payment and refund history cannot be deleted');\n return super.delete(options);\n }\n\n /** See the connected-row guard in {@link save}. */\n private assertConnectedIdentityUnchanged(\n priorRow: Record<string, unknown>,\n ): void {\n const frozen: Array<[string, unknown, unknown]> = [\n ['kind', String(priorRow.kind ?? 'payment'), this.kind],\n [\n 'connectedFeePolicyRef',\n String(priorRow.connected_fee_policy_ref ?? ''),\n this.connectedFeePolicyRef,\n ],\n ['amount', Number(priorRow.amount ?? 0), Number(this.amount ?? 0)],\n ['currency', String(priorRow.currency ?? ''), this.currency],\n ['backendId', String(priorRow.backend_id ?? ''), this.backendId],\n [\n // A refund's provider reference is set once, in the same write that\n // records the provider's answer (connectedRefundState leaves\n // `requested`, which no generated surface can write).\n 'backendTxRef',\n !priorRow.backend_tx_ref &&\n priorRow.connected_refund_state === 'requested' &&\n this.connectedRefundState !== 'requested'\n ? this.backendTxRef\n : String(priorRow.backend_tx_ref ?? ''),\n this.backendTxRef,\n ],\n [\n 'transactionId',\n String(priorRow.transaction_id ?? ''),\n this.transactionId,\n ],\n [\n 'connectedAccountId',\n String(priorRow.connected_account_id ?? ''),\n this.connectedAccountId,\n ],\n [\n 'applicationFeeCents',\n Number(priorRow.application_fee_cents ?? 0),\n Number(this.applicationFeeCents ?? 0),\n ],\n [\n 'refundOfPaymentId',\n String(priorRow.refund_of_payment_id ?? ''),\n this.refundOfPaymentId,\n ],\n [\n 'applicationFeeRefunded',\n Boolean(priorRow.application_fee_refunded),\n Boolean(this.applicationFeeRefunded),\n ],\n ];\n for (const [field, prior, next] of frozen)\n if (prior !== next)\n throw new Error(\n `Payment ${this.id}: '${field}' of a connected payment or refund cannot change`,\n );\n }\n\n /**\n * Reject an illegal status flip. Compares the about-to-be-written status\n * against the status the row was loaded with. No-op transitions (status\n * unchanged) and brand-new rows (no prior) are always allowed — the\n * COMPLETED-specific settlement requirement is enforced separately in\n * {@link save}.\n */\n private assertStatusTransition(prior: PaymentStatus | undefined): void {\n if (prior === undefined) return; // new row — any starting status (subject to the COMPLETED gate)\n if (prior === this.status) return; // no-op re-save\n const allowed = PAYMENT_STATUS_TRANSITIONS[prior] ?? [];\n if (!allowed.includes(this.status)) {\n throw new Error(\n `Payment ${this.id}: illegal status transition '${prior}' → '${this.status}'. ` +\n 'Use the guarded helpers (recordPayment / markFailed / cancel).',\n );\n }\n }\n\n /**\n * Load the AUTHORITATIVE persisted row (S5 audit #1390 round 4, codex HIGH#1;\n * extended round 6 to carry the full row, not just `status`). The WeakMap is\n * only populated when {@link initialize} loaded the row from the DB; it is\n * empty for an instance built via\n * `collection.create({ id: <existing>, _skipLoad: true })` — the upsert path\n * that lets a caller write onto an existing row without hydrating it. Trusting\n * an empty WeakMap there would treat the write as a brand-new row and skip the\n * transition guard entirely (a poisonable prior-state).\n *\n * So when this instance carries an `id`, read the persisted row straight from\n * the database and use it as the prior — a create-onto-existing is an update.\n * Returns `undefined` when no row exists (truly new), so callers fall back to\n * the WeakMap (which is also empty then). Settled-amount columns are\n * snake_case (`native_amount`, etc.); the `status` column is single-word.\n */\n private async loadPersistedRow(): Promise<\n Record<string, unknown> | undefined\n > {\n if (!this.id) return undefined;\n try {\n const row = await this.getCanonicalPersistedRow({ id: this.id });\n return row ?? undefined;\n } catch {\n // DB not ready / table absent — treat as new (in-memory fallback in save).\n return undefined;\n }\n }\n\n /**\n * Reject any change to the settled monetary fields of an already-COMPLETED\n * Payment (S5 audit #1390 round 6 — codex ROOT INSIGHT). Mirrors the\n * PaymentIntent PAID backing-field freeze. A COMPLETED Payment's economic\n * identity is settled: the `amount` was posted into a balanced journal and is\n * the figure PaymentIntent's PAID verification reconciles against, so it (and\n * the native/USD valuation fields that describe the same money) must not\n * drift. The only legal status move out of COMPLETED is REFUNDED, which\n * reverses the funds without rewriting how much they were. Compared against\n * the AUTHORITATIVE persisted row so the freeze holds on every surface, even\n * for an un-hydrated create-onto-existing upsert.\n */\n private assertSettledAmountsUnchanged(\n priorRow: Record<string, unknown>,\n ): void {\n const frozen: Array<[string, number | string, number | string]> = [\n ['journalId', String(priorRow.journal_id ?? ''), this.journalId ?? ''],\n [\n 'paidAt',\n priorRow.paid_at == null\n ? ''\n : new Date(priorRow.paid_at as string | number).getTime(),\n this.paidAt == null ? '' : new Date(this.paidAt).getTime(),\n ],\n ['kind', String(priorRow.kind ?? 'payment'), this.kind],\n [\n 'connectedFeePolicyRef',\n String(priorRow.connected_fee_policy_ref ?? ''),\n this.connectedFeePolicyRef,\n ],\n ['amount', Number(priorRow.amount ?? 0), Number(this.amount ?? 0)],\n [\n 'currency',\n String(priorRow.currency ?? ''),\n String(this.currency ?? ''),\n ],\n [\n 'nativeAmount',\n Number(priorRow.native_amount ?? 0),\n Number(this.nativeAmount ?? 0),\n ],\n [\n 'nativeCurrency',\n String(priorRow.native_currency ?? ''),\n String(this.nativeCurrency ?? ''),\n ],\n [\n 'usdAtQuote',\n Number(priorRow.usd_at_quote ?? 0),\n Number(this.usdAtQuote ?? 0),\n ],\n [\n 'usdAtConfirmation',\n Number(priorRow.usd_at_confirmation ?? 0),\n Number(this.usdAtConfirmation ?? 0),\n ],\n [\n 'connectedAccountId',\n String(priorRow.connected_account_id ?? ''),\n String(this.connectedAccountId ?? ''),\n ],\n [\n 'applicationFeeCents',\n Number(priorRow.application_fee_cents ?? 0),\n Number(this.applicationFeeCents ?? 0),\n ],\n [\n 'refundOfPaymentId',\n String(priorRow.refund_of_payment_id ?? ''),\n String(this.refundOfPaymentId ?? ''),\n ],\n [\n 'connectedRefundState',\n String(priorRow.connected_refund_state ?? ''),\n String(this.connectedRefundState ?? ''),\n ],\n ];\n for (const [field, prior, next] of frozen) {\n if (prior !== next) {\n throw new Error(\n `Payment ${this.id}: '${field}' is frozen once the payment is ` +\n `COMPLETED (was '${prior}', got '${next}'). A settled payment's ` +\n 'monetary fields cannot be mutated — issue a refund instead.',\n );\n }\n }\n }\n\n /**\n * USD drift between quote time and confirmation time — what the\n * operator gained (positive) or lost (negative) by accepting a\n * volatile-currency payment. Returns `0` when either side of the\n * comparison is missing or zero, so callers don't have to special-case\n * fiat-rail / stablecoin payments.\n */\n usdDrift(): number {\n if (!this.usdAtQuote || !this.usdAtConfirmation) return 0;\n return this.usdAtConfirmation - this.usdAtQuote;\n }\n\n /**\n * Check if payment is pending\n */\n isPending(): boolean {\n return this.status === PaymentStatus.PENDING;\n }\n\n /**\n * Check if payment is completed\n */\n isCompleted(): boolean {\n return this.status === PaymentStatus.COMPLETED;\n }\n\n /**\n * Check if payment is refunded\n */\n isRefunded(): boolean {\n return this.status === PaymentStatus.REFUNDED;\n }\n\n /**\n * Record the payment and create a balanced journal entry.\n *\n * Creates a journal entry in smrt-ledgers:\n * - Debit: Cash/Bank account (assets increase)\n * - Credit: Accounts Receivable (receivables decrease)\n *\n * Both sides carry `this.amount`, so the journal posted from commerce is\n * denominated in **integer minor units** like the rest of this package\n * (#2401). smrt-ledgers is unit-agnostic — its `BALANCE_EPSILON` only checks\n * that debits equal credits — and integer entries balance exactly, so this is\n * strictly tighter than the major-unit journals commerce used to post.\n *\n * @param options - Ledger and account configuration\n * @returns The created journal\n *\n * @example\n * ```typescript\n * const journal = await payment.recordPayment({\n * ledgerId: ledger.id,\n * receivablesAccountId: arAccount.id,\n * cashAccountId: bankAccount.id\n * });\n * console.log(`Created journal: ${journal.number}`);\n * ```\n */\n async recordPayment(options: RecordPaymentOptions): Promise<Journal> {\n if (recordingInProgress.has(this)) {\n throw new Error('Payment recording is already in progress');\n }\n if (this.status === PaymentStatus.COMPLETED) {\n throw new Error('Payment already recorded');\n }\n const previous = {\n status: this.status,\n journalId: this.journalId,\n paidAt: this.paidAt,\n loadedStatus: loadedPaymentStatus.get(this),\n };\n recordingInProgress.add(this);\n try {\n await this.withTransaction(async () => {\n if (!this.isPersisted) await this.save();\n // The revision claim is a write fence, including under PostgreSQL\n // repeatable-read snapshots. A stale contender must reload and retry\n // instead of posting from an earlier pending-payment snapshot.\n if (!this.updated_at) {\n throw new Error(\n 'Payment revision is missing; reload before recording',\n );\n }\n await this.claimRevision(this.updated_at);\n // In-memory status can be edited without saving (including markFailed).\n // Only the claimed persisted row decides whether settlement happened.\n const persisted = await this.getCanonicalPersistedRow({ id: this.id });\n if (!persisted) throw new Error('Claimed payment could not be loaded');\n if (persisted.status === PaymentStatus.COMPLETED) {\n throw new Error('Payment already recorded');\n }\n await this.postPaymentInTransaction(options);\n });\n } catch (error) {\n this.status = previous.status;\n this.journalId = previous.journalId;\n this.paidAt = previous.paidAt;\n if (previous.loadedStatus === undefined) loadedPaymentStatus.delete(this);\n else loadedPaymentStatus.set(this, previous.loadedStatus);\n throw error;\n } finally {\n recordingInProgress.delete(this);\n settlementInProgress.delete(this);\n }\n\n // Return a journal on the caller's executor, not the now-closed transaction.\n const { JournalCollection } = await import('@happyvertical/smrt-ledgers');\n const journals = await JournalCollection.create({\n ...this.options,\n db: this.db,\n });\n const journal = await journals.get({ id: this.journalId });\n if (!journal)\n throw new Error('Recorded payment journal could not be loaded');\n return journal;\n }\n\n /** Settle an outgoing refund through the same guarded journal transaction. */\n async recordRefund(options: RecordPaymentOptions): Promise<Journal> {\n if (this.kind !== 'refund')\n throw new Error('recordRefund requires Payment.kind=refund');\n return this.recordPayment(options);\n }\n\n /** Post and complete only inside recordPayment's claimed transaction. */\n private async postPaymentInTransaction(\n options: RecordPaymentOptions,\n ): Promise<Journal> {\n if (this.status === PaymentStatus.COMPLETED) {\n throw new Error('Payment already recorded');\n }\n\n if (this.amount <= 0) {\n throw new Error('Payment amount must be positive');\n }\n\n // A connected direct charge arrives net of the platform's application\n // fee (#3831): the provider withheld it at source, so it is an expense\n // already paid, never a payable to the platform.\n const applicationFee =\n this.kind === 'payment' ? this.applicationFeeCents : 0;\n if (applicationFee > 0 && !options.applicationFeeAccountId)\n throw new Error(\n 'Payment carries an application fee; recordPayment requires applicationFeeAccountId',\n );\n\n const funds = customerFundsState(this.customerFundsJson);\n const explicitDate = options.effectiveOn;\n if (\n explicitDate !== undefined &&\n (typeof explicitDate !== 'string' ||\n !/^\\d{4}-\\d{2}-\\d{2}$/.test(explicitDate) ||\n !Number.isFinite(Date.parse(explicitDate)) ||\n new Date(explicitDate).toISOString().slice(0, 10) !== explicitDate)\n )\n throw new Error('Settlement effectiveOn must be a calendar date');\n if (funds) {\n if (explicitDate !== undefined && explicitDate !== funds.effectiveOn)\n throw new Error('Settlement date differs from reviewed customer funds');\n assertCustomerFundsWrite(this);\n if (\n options.cashAccountId !== funds.policy.cashAccountId ||\n options.receivablesAccountId !== funds.policy.receivablesAccountId\n )\n throw new Error(\n 'Customer funds settlement accounts differ from reviewed policy',\n );\n }\n const creditAccountId =\n funds?.policy.mode === 'deposit-liability'\n ? funds.policy.liabilityAccountId!\n : options.receivablesAccountId;\n const effectiveOn = funds?.effectiveOn ?? explicitDate;\n const effectiveDate = effectiveOn\n ? new Date(`${effectiveOn}T12:00:00Z`)\n : new Date();\n // Dynamic import to avoid hard dependency on smrt-ledgers\n const { JournalCollection } = await import('@happyvertical/smrt-ledgers');\n\n // Create the journal collection\n const journalCollection = await JournalCollection.create(this.options);\n\n // Create a new journal for this payment\n const journal = await journalCollection.create({\n date: effectiveDate,\n description:\n this.kind === 'refund'\n ? `Customer refund for contract ${this.contractId}`\n : `Payment received for contract ${this.contractId}`,\n sourceModule: 'smrt-commerce',\n sourceRef: this.id,\n });\n await journal.save();\n\n // Incoming payments debit cash/credit AR; refunds reverse that movement.\n await journal.addEntry({\n accountId: options.cashAccountId,\n currency: this.currency,\n debit: this.kind === 'payment' ? this.amount - applicationFee : 0,\n credit: this.kind === 'refund' ? this.amount : 0,\n memo: `${this.kind === 'refund' ? 'Refund' : 'Payment'} ${this.reference || this.id}`,\n });\n if (applicationFee > 0)\n await journal.addEntry({\n accountId: options.applicationFeeAccountId!,\n currency: this.currency,\n debit: applicationFee,\n credit: 0,\n memo: `Application fee ${this.reference || this.id}`,\n });\n\n // Credit Accounts Receivable (receivables decrease)\n await journal.addEntry({\n accountId: creditAccountId,\n currency: this.currency,\n debit: this.kind === 'refund' ? this.amount : 0,\n credit: this.kind === 'payment' ? this.amount : 0,\n memo: `${this.kind === 'refund' ? 'Refund' : 'Payment'} ${this.reference || this.id}`,\n });\n\n // Post the journal (validates balance and finalizes)\n await journal.post();\n\n // Update payment record. Announce the verified settlement to the save-time\n // guard so the COMPLETED transition is accepted (the guard rejects any\n // other route into COMPLETED). A posted journal always carries an id;\n // fail fast rather than persist an empty-string FK if that invariant breaks.\n if (!journal.id) {\n throw new Error(\n 'Payment.recordPayment: journal was posted but has no id',\n );\n }\n this.journalId = journal.id;\n this.status = PaymentStatus.COMPLETED;\n this.paidAt = effectiveDate;\n settlementInProgress.add(this);\n await this.save();\n\n return journal;\n }\n\n /**\n * Get the linked journal entry (if recorded)\n */\n async getJournal(): Promise<Journal | null> {\n if (!this.journalId) return null;\n\n try {\n const { JournalCollection } = await import('@happyvertical/smrt-ledgers');\n const collection = await JournalCollection.create(this.options);\n return await collection.get({ id: this.journalId });\n } catch {\n // smrt-ledgers not available\n return null;\n }\n }\n\n /**\n * Mark payment as failed\n */\n markFailed(reason?: string): void {\n this.status = PaymentStatus.FAILED;\n if (reason) {\n this.notes = `${this.notes ? `${this.notes}\\n` : ''}Failed: ${reason}`;\n }\n }\n\n /**\n * Cancel the payment\n */\n cancel(): void {\n if (this.status === PaymentStatus.COMPLETED) {\n throw new Error('Cannot cancel a completed payment. Use refund instead.');\n }\n this.status = PaymentStatus.CANCELLED;\n }\n}\n\nexport default Payment;\n","/**\n * PaymentCollection - Collection manager for Payment objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { Payment } from '../models/Payment.js';\nimport { type PaymentMethod, PaymentStatus } from '../types/index.js';\n\nexport class PaymentCollection extends SmrtCollection<Payment> {\n static readonly _itemClass = Payment;\n\n /**\n * Find payments by contract\n *\n * @param contractId - Contract ID\n * @returns Array of payments\n */\n async findByContract(contractId: string): Promise<Payment[]> {\n return await this.list({\n where: { contractId },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find payments by customer\n *\n * @param customerId - Customer ID\n * @returns Array of payments\n */\n async findByCustomer(customerId: string): Promise<Payment[]> {\n return await this.list({\n where: { customerId },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find payments by status\n *\n * @param status - Payment status\n * @returns Array of payments\n */\n async findByStatus(status: PaymentStatus): Promise<Payment[]> {\n return await this.list({\n where: { status },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find payments by method\n *\n * @param method - Payment method\n * @returns Array of payments\n */\n async findByMethod(method: PaymentMethod): Promise<Payment[]> {\n return await this.list({\n where: { method },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find all pending payments\n *\n * @returns Array of pending payments\n */\n async findPending(): Promise<Payment[]> {\n return await this.findByStatus(PaymentStatus.PENDING);\n }\n\n /**\n * Find all completed payments\n *\n * @returns Array of completed payments\n */\n async findCompleted(): Promise<Payment[]> {\n return await this.findByStatus(PaymentStatus.COMPLETED);\n }\n\n /**\n * Find payment by transaction ID\n *\n * @param transactionId - External transaction ID\n * @returns Payment or null\n */\n async findByTransactionId(transactionId: string): Promise<Payment | null> {\n const results = await this.list({\n where: { transactionId },\n limit: 1,\n });\n return results[0] || null;\n }\n\n /**\n * Find payments in date range\n *\n * @param startDate - Start date\n * @param endDate - End date\n * @returns Array of payments\n */\n async findByDateRange(startDate: Date, endDate: Date): Promise<Payment[]> {\n return await this.list({\n where: {\n 'paidAt >=': startDate.toISOString(),\n 'paidAt <=': endDate.toISOString(),\n },\n orderBy: 'paidAt DESC',\n });\n }\n\n /**\n * Calculate total payments for a contract\n *\n * @param contractId - Contract ID\n * @returns Total amount paid\n */\n async getTotalForContract(contractId: string): Promise<number> {\n const payments = await this.list({\n where: {\n contractId,\n status: PaymentStatus.COMPLETED,\n },\n });\n\n return payments.reduce((sum, payment) => sum + payment.amount, 0);\n }\n\n /**\n * Find payments linked to a ledger journal\n *\n * @param journalId - Journal ID from smrt-ledgers\n * @returns Payment or null\n */\n async findByJournal(journalId: string): Promise<Payment | null> {\n const results = await this.list({\n where: { journalId },\n limit: 1,\n });\n return results[0] || null;\n }\n\n // ============================================================================\n // Tenant Helper Methods\n // ============================================================================\n\n /**\n * Find all payments belonging to a specific tenant\n *\n * @param tenantId - Tenant ID\n * @returns Array of payments for the tenant\n */\n async findByTenant(tenantId: string): Promise<Payment[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find all global payments (not associated with any tenant).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global payments\n */\n async findGlobal(): Promise<Payment[]> {\n return queryGlobal<Payment>(this);\n }\n\n /**\n * Find payments for a tenant including global payments.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID\n * @returns Array of tenant-specific and global payments\n */\n async findWithGlobals(tenantId: string): Promise<Payment[]> {\n return queryWithGlobals<Payment>(this, tenantId, 'Payment.findWithGlobals');\n }\n}\n","/** Shared historical/live invoice capacity. This module is private to the owning package. */\nimport { isPostgresDatabase } from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport { HistoricalCustomerFundsAllocationCollection } from './collections/HistoricalCustomerFundsCollections.js';\n\nasync function exists(db: DatabaseInterface) {\n return isPostgresDatabase(db)\n ? (\n await db.query('SELECT to_regclass(?) AS relation', [\n 'historical_customer_funds_allocations',\n ])\n ).rows[0]?.relation != null\n : db.tableExists('historical_customer_funds_allocations');\n}\nexport async function historicalInvoiceAllocationTotal(\n db: DatabaseInterface,\n invoiceId: string,\n effect?: 'payment' | 'refund',\n): Promise<number> {\n if (effect === 'refund')\n return historicalCreditRefundCommittedTotal(db, invoiceId);\n if (!(await exists(db)))\n return historicalCreditRefundCommittedTotal(db, invoiceId);\n const tenantId = getTenantId();\n if (!tenantId) {\n if (\n (\n await db.query(\n 'SELECT id FROM historical_customer_funds_allocations WHERE invoice_id=? LIMIT 1',\n invoiceId,\n )\n ).rows.length\n )\n throw new Error(\n 'Historical allocation capacity requires the explicit active tenant',\n );\n return historicalCreditRefundCommittedTotal(db, invoiceId);\n }\n const rows = await (\n await HistoricalCustomerFundsAllocationCollection.create({ db })\n ).list({\n where: { tenantId, invoiceId, effect: 'payment' },\n limit: 100001,\n });\n if (rows.length > 100000)\n throw new Error(\n 'Historical allocation capacity exceeds the bounded source scope',\n );\n const total = rows\n .filter((row) => row.effect === 'payment')\n .reduce((sum, row) => sum + BigInt(row.amountMinor), 0n);\n if (total > BigInt(Number.MAX_SAFE_INTEGER))\n throw new Error('Historical allocation capacity is unsafe');\n const combined =\n total +\n BigInt(\n effect === 'payment'\n ? 0\n : await historicalCreditRefundCommittedTotal(db, invoiceId),\n );\n if (combined > BigInt(Number.MAX_SAFE_INTEGER))\n throw new Error('Historical combined capacity is unsafe');\n return Number(combined);\n}\n\n/** Original cash refunds reserve capacity before their separately preserved allocation arrives. */\nexport async function historicalCreditRefundCommittedTotal(\n db: DatabaseInterface,\n creditNoteId: string,\n): Promise<number> {\n const available = isPostgresDatabase(db)\n ? (\n await db.query('SELECT to_regclass(?) AS relation', [\n 'historical_customer_funds',\n ])\n ).rows[0]?.relation != null\n : await db.tableExists('historical_customer_funds');\n if (!available) return 0;\n const tenantId = getTenantId();\n if (!tenantId) {\n if (\n (\n await db.query(\n 'SELECT id FROM historical_customer_funds WHERE source_credit_note_id=? LIMIT 1',\n creditNoteId,\n )\n ).rows.length\n )\n throw new Error(\n 'Historical refund capacity requires the explicit active tenant',\n );\n return 0;\n }\n const { HistoricalCustomerFundsCollection } = await import(\n './collections/HistoricalCustomerFundsCollections.js'\n );\n const rows = await (\n await HistoricalCustomerFundsCollection.create({ db })\n ).list({\n where: { tenantId, sourceCreditNoteId: creditNoteId, kind: 'refund' },\n limit: 100001,\n });\n if (rows.length > 100000)\n throw new Error(\n 'Historical credit refund source scope exceeds its bounded limit',\n );\n const total = rows.reduce((sum, row) => sum + BigInt(row.amountMinor), 0n);\n if (total > BigInt(Number.MAX_SAFE_INTEGER))\n throw new Error('Historical refund source total is unsafe');\n return Number(total);\n}\n","/**\n * PaymentAllocation model - maps payments to invoices\n * @packageDocumentation\n */\n\nimport {\n field,\n foreignKey,\n type SmrtDeleteOptions,\n SmrtObject,\n type SmrtSaveOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { allocationOwner, allocationTotal } from '../allocation-integrity.js';\nimport { calculateAvailableRefund } from '../credit-allocation.js';\nimport {\n assertCustomerFundsWrite,\n customerFundsState,\n} from '../customer-funds-internal.js';\nimport {\n historicalCreditRefundCommittedTotal,\n historicalInvoiceAllocationTotal,\n} from '../historical-funds-internal.js';\nimport { assertIntegerMinorUnits } from '../money.js';\nimport type { PaymentAllocationOptions } from '../types/index.js';\n\n/*\n * There is deliberately no `ALLOCATION_EPSILON` here any more (#2401).\n *\n * `Payment.amount`, `Invoice.totalAmount` and this row's `amount` are all\n * integer minor units, so \"does this allocation over-apply the payment\" is an\n * exact integer question. The old `0.01` tolerance let an allocation exceed its\n * payment by up to a cent — real money, not rounding fuzz — and only existed\n * because the payment side was a float.\n */\n\n/**\n * PaymentAllocation tracks how payments are applied to invoices.\n *\n * This enables:\n * - Partial payments (one payment partially covering an invoice)\n * - Split payments (one payment split across multiple invoices)\n * - Payment history per invoice\n *\n * Saves atomically enforce parent existence, matching tenant/customer/currency,\n * positive safe-integer amounts and both balance caps. Use\n * `PaymentAllocationCollection.allocatePayment()` for atomic splits and replay.\n * Direct saves retain caller-owned invoice status refresh.\n *\n * @example\n * ```typescript\n * import { PaymentAllocationCollection } from '@happyvertical/smrt-commerce';\n *\n * // Get the collection\n * const allocations = await PaymentAllocationCollection.create(options);\n *\n * // Check available funds before allocating (all amounts are minor units)\n * const available = await allocations.getUnallocatedFromPayment(\n * payment.id,\n * payment.amount\n * );\n *\n * if (available >= amountToAllocate) {\n * const allocation = await allocations.create({\n * paymentId: payment.id,\n * invoiceId: invoice.id,\n * amount: amountToAllocate,\n * allocatedBy: 'user-uuid'\n * });\n *\n * // Reload the revision advanced by the allocation, then update status.\n * await invoice.loadFromId();\n * const totalAllocated = await allocations.getTotalAllocatedToInvoice(invoice.id);\n * invoice.updatePaymentStatus(totalAllocated);\n * await invoice.save();\n * }\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n // NOTE: `create` and `delete` are intentionally NOT exposed over the\n // generated REST/MCP surface (S5 audit #1390). Allocation rows directly\n // determine an invoice's amountPaid/status and a payment's remaining funds;\n // a generated `create` lets a caller forge an allocation that over-applies a\n // payment, and a generated `delete` lets a caller silently un-apply funds —\n // both falsify balances with no authz. Allocations must be created/removed\n // through application code that re-derives invoice status and respects the\n // payment-amount cap (the cap is also enforced in `save()` as defence in\n // depth).\n //\n // CLI parity (round 6, codex ROOT INSIGHT): the CLI is an independently\n // configured write surface. `cli: true` would still generate create/update/\n // delete commands that forge or un-apply allocations, re-opening the exact\n // vector closed on api/mcp. The CLI is locked to the same read-only surface.\n api: { include: ['list', 'get'] },\n mcp: { include: ['list', 'get'] },\n cli: { include: ['list', 'get'] },\n})\nexport class PaymentAllocation extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n /**\n * Tenant ID for multi-tenant isolation\n * Nullable to support both tenant-scoped and global payment allocations\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Payment being allocated\n */\n @field({ description: 'The payment being applied.' })\n @foreignKey('Payment')\n paymentId: string = '';\n\n /**\n * Invoice receiving the allocation\n */\n @field({ description: 'The invoice it settles.' })\n @foreignKey('Invoice')\n invoiceId: string = '';\n\n /**\n * Amount allocated from payment to invoice, in **integer minor units**\n * (cents, satoshis).\n *\n * Matches `Invoice.amountPaid` (derived by summing these rows) and\n * `Payment.amount` (which `save()` caps against). All three converted\n * together in #2401 — the cap is a subtraction across the pair, so a\n * dollars-vs-cents split there would reject every allocation as\n * over-applying.\n */\n @field({\n description: 'How much of the payment goes to this invoice.',\n ui: { format: 'money' },\n })\n amount: number = 0;\n\n /**\n * When the allocation was made\n */\n @field({ description: 'When it was applied.' })\n allocatedAt: Date = new Date();\n\n /**\n * User/agent who made the allocation\n */\n allocatedBy: string = '';\n\n /**\n * Notes about the allocation\n */\n @field({ description: 'Anything worth remembering about this allocation.' })\n notes: string = '';\n\n constructor(options: PaymentAllocationOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.paymentId !== undefined) this.paymentId = options.paymentId;\n if (options.invoiceId !== undefined) this.invoiceId = options.invoiceId;\n if (options.amount !== undefined) this.amount = options.amount;\n if (options.allocatedAt !== undefined)\n this.allocatedAt = options.allocatedAt;\n if (options.allocatedBy !== undefined)\n this.allocatedBy = options.allocatedBy;\n if (options.notes !== undefined) this.notes = options.notes;\n }\n\n /** Save and validate against both claimed parent rows in one transaction. */\n override async save(options?: SmrtSaveOptions): Promise<this> {\n assertIntegerMinorUnits('PaymentAllocation', this.id ?? '<new>', [\n ['amount', this.amount],\n ]);\n if (this.amount <= 0)\n throw new Error('PaymentAllocation amount must be a positive number');\n if (!this.paymentId || !this.invoiceId)\n throw new Error('PaymentAllocation requires payment and invoice');\n return this.withTransaction(async () => {\n const { PaymentCollection } = await import(\n '../collections/PaymentCollection.js'\n );\n const { InvoiceCollection } = await import(\n '../collections/InvoiceCollection.js'\n );\n const { PaymentAllocationCollection } = await import(\n '../collections/PaymentAllocationCollection.js'\n );\n const payments = await PaymentCollection.create({ db: this.db });\n const invoices = await InvoiceCollection.create({ db: this.db });\n const allocations = await PaymentAllocationCollection.create({\n db: this.db,\n });\n const prior = this.id\n ? await allocations.get({ id: this.id }, { cache: false })\n : null;\n if (\n prior &&\n (prior.paymentId !== this.paymentId ||\n prior.invoiceId !== this.invoiceId ||\n prior.tenantId !== allocationOwner(this.tenantId))\n ) {\n throw new Error('PaymentAllocation parent identity is immutable');\n }\n const payment = await payments.get(\n { id: this.paymentId },\n { cache: false },\n );\n if (!payment)\n throw new Error('PaymentAllocation referenced Payment does not exist');\n if (\n payment.retentionAccountingBindingJson ||\n payment.ordinaryAccountingBindingJson\n )\n throw new Error('Provider-recorded refund allocation is immutable');\n if (customerFundsState(payment.customerFundsJson))\n assertCustomerFundsWrite(this);\n if (!payment.updated_at)\n throw new Error('Allocation parent has no persisted revision');\n await payment.claimRevision(payment.updated_at);\n const invoice = await invoices.get(\n { id: this.invoiceId },\n { cache: false },\n );\n if (!invoice)\n throw new Error('PaymentAllocation referenced Invoice does not exist');\n if (!invoice.updated_at)\n throw new Error('Allocation parent has no persisted revision');\n await invoice.claimRevision(invoice.updated_at);\n const owner = allocationOwner(this.tenantId);\n if (\n payment.tenantId !== owner ||\n invoice.tenantId !== owner ||\n (payment.customerId || null) !== (invoice.customerId || null) ||\n payment.currency !== invoice.currency\n ) {\n throw new Error(\n 'PaymentAllocation requires matching tenant, customer and currency',\n );\n }\n if (\n (payment.kind === 'refund' && invoice.kind !== 'credit_note') ||\n (payment.kind === 'payment' && invoice.kind !== 'invoice')\n )\n throw new Error(\n 'PaymentAllocation requires payments on invoices and refunds on credit notes',\n );\n const paymentTotal =\n allocationTotal(\n await allocations.findByPayment(this.paymentId),\n this.id,\n ) + BigInt(this.amount);\n const invoiceTotal =\n allocationTotal(\n await allocations.findByInvoice(this.invoiceId),\n this.id,\n ) +\n BigInt(this.amount) +\n BigInt(await historicalInvoiceAllocationTotal(this.db, this.invoiceId));\n if (paymentTotal > BigInt(payment.amount))\n throw new Error('PaymentAllocation would over-apply payment');\n const invoiceCap =\n invoice.kind === 'invoice'\n ? invoice.getPayableFacts().allocationCapMinor\n : invoice.totalAmount;\n if (invoiceTotal > BigInt(Math.max(0, invoiceCap)))\n throw new Error('PaymentAllocation would over-pay invoice');\n if (payment.kind === 'refund') {\n if (payment.status !== 'completed')\n throw new Error('A refund must be settled before it is allocated');\n if (!invoice.creditedInvoiceId)\n throw new Error('Refund credit note has no credited invoice');\n const source = await invoices.get(\n { id: invoice.creditedInvoiceId },\n { cache: false },\n );\n if (!source || source.tenantId !== owner)\n throw new Error('Refund source invoice does not exist in its tenant');\n if (!source.updated_at)\n throw new Error('Refund source invoice has no persisted revision');\n await source.claimRevision(source.updated_at);\n const creditRows = await invoices.list({\n where: { tenantId: owner, creditedInvoiceId: source.id },\n limit: 100001,\n });\n if (creditRows.length > 100000)\n throw new Error(\n 'Refund credit scope exceeds its bounded source limit',\n );\n const credits = creditRows.filter(\n (credit) =>\n credit.kind === 'credit_note' &&\n credit.status !== 'draft' &&\n credit.status !== 'cancelled',\n );\n const issuedCredits = credits.reduce(\n (sum, credit) => sum + credit.totalAmount,\n 0,\n );\n let settledRefunds = 0;\n for (const credit of credits) {\n if (!credit.id) continue;\n settledRefunds += await historicalCreditRefundCommittedTotal(\n this.db,\n credit.id,\n );\n for (const allocation of await allocations.findByInvoice(credit.id)) {\n if (allocation.id === this.id) continue;\n const refund = await payments.get(\n { id: allocation.paymentId },\n { cache: false },\n );\n if (refund?.kind === 'refund' && refund.status === 'completed')\n settledRefunds += allocation.amount;\n }\n }\n const availableRefund = calculateAvailableRefund({\n sourceTotalMinor: source.totalAmount,\n sourcePaidMinor: source.amountPaid,\n issuedCreditMinor: issuedCredits,\n settledRefundMinor: settledRefunds,\n });\n if (this.amount > availableRefund)\n throw new Error(\n `Refund allocation exceeds available unapplied credit (${availableRefund})`,\n );\n }\n return (await super.save(options)) as this;\n });\n }\n /** Managed application reversal must also post its inverse journal and retain evidence. */\n override async delete(options: SmrtDeleteOptions = {}): Promise<void> {\n return this.withTransaction(async () => {\n const persisted = this.id\n ? await this.db.get(this.tableName, { id: this.id })\n : null;\n const { PaymentCollection } = await import(\n '../collections/PaymentCollection.js'\n );\n const payment = await (\n await PaymentCollection.create({ db: this.db })\n ).get(\n { id: String(persisted?.payment_id ?? this.paymentId) },\n { cache: false },\n );\n // Share the Payment revision boundary with provider refund reservation.\n // A stale unbound read must fail before deleting its settlement evidence.\n if (payment) {\n if (!payment.updated_at)\n throw new Error('Allocation parent has no persisted revision');\n await payment.claimRevision(payment.updated_at);\n }\n if (\n payment?.retentionAccountingBindingJson ||\n payment?.ordinaryAccountingBindingJson\n )\n throw new Error(\n 'Provider-recorded refund allocation cannot be deleted',\n );\n if (payment?.customerFundsJson) assertCustomerFundsWrite(this);\n return super.delete(options);\n });\n }\n}\n\nexport default PaymentAllocation;\n","/**\n * PaymentAllocationCollection - Collection manager for PaymentAllocation objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { customerFundsState } from '../customer-funds-internal.js';\nimport { historicalInvoiceAllocationTotal } from '../historical-funds-internal.js';\nimport { PaymentAllocation } from '../models/PaymentAllocation.js';\n\nexport class PaymentAllocationCollection extends SmrtCollection<PaymentAllocation> {\n static readonly _itemClass = PaymentAllocation;\n\n /**\n * Apply a payment to several invoices atomically. Callers supply stable UUID\n * allocation ids: exact replays reuse rows; reusing an id with other money\n * or parents fails. Actor authorization remains the application's job.\n */\n async allocatePayment(input: {\n paymentId: string;\n allocations: { id: string; invoiceId: string; amount: number }[];\n allocatedBy?: string;\n }): Promise<PaymentAllocation[]> {\n if (\n !input.allocations.length ||\n new Set(input.allocations.map((item) => item.id)).size !==\n input.allocations.length\n ) {\n throw new Error(\n 'Allocation batch requires distinct stable allocation ids',\n );\n }\n const { PaymentCollection } = await import('./PaymentCollection.js');\n const { InvoiceCollection } = await import('./InvoiceCollection.js');\n const { InvoiceStatus } = await import('../types/index.js');\n const payments = await PaymentCollection.create({ db: this.db });\n const payment = await payments.get(\n { id: input.paymentId },\n { cache: false },\n );\n if (!payment) throw new Error('Payment does not exist');\n const committed = await payment.withTransaction(async () => {\n if (!payment.updated_at)\n throw new Error('Allocation parent has no persisted revision');\n await payment.claimRevision(payment.updated_at);\n const allocations = await PaymentAllocationCollection.create({\n db: payment.db,\n });\n const invoices = await InvoiceCollection.create({ db: payment.db });\n const result: PaymentAllocation[] = [];\n for (const item of [...input.allocations].sort(\n (a, b) =>\n a.invoiceId.localeCompare(b.invoiceId) || a.id.localeCompare(b.id),\n )) {\n if (!item.id) throw new Error('Allocation requires a stable id');\n const existing = await allocations.get(\n { id: item.id },\n { cache: false },\n );\n if (existing) {\n if (\n existing.paymentId !== input.paymentId ||\n existing.invoiceId !== item.invoiceId ||\n existing.amount !== item.amount ||\n existing.tenantId !== payment.tenantId\n ) {\n throw new Error(\n 'Allocation replay does not match existing allocation',\n );\n }\n result.push(existing);\n } else {\n result.push(\n await allocations.create({\n ...item,\n paymentId: input.paymentId,\n tenantId: payment.tenantId,\n allocatedBy: input.allocatedBy ?? '',\n _insertOnly: true,\n }),\n );\n }\n }\n for (const invoiceId of [\n ...new Set(input.allocations.map((item) => item.invoiceId)),\n ].sort()) {\n const invoice = await invoices.get({ id: invoiceId }, { cache: false });\n if (!invoice) throw new Error('Invoice does not exist');\n if (invoice.status !== InvoiceStatus.WRITTEN_OFF)\n invoice.updatePaymentStatus(\n await allocations.getTotalAllocatedToInvoice(invoiceId),\n );\n await invoice.save();\n }\n return result;\n });\n // Child objects created on the transaction cannot escape with its closed\n // executor. Hydrate results on the caller's executor (possibly an outer tx).\n return Promise.all(\n committed.map(async ({ id }) => {\n const allocation = await this.get({ id: String(id) }, { cache: false });\n if (!allocation)\n throw new Error('Committed allocation no longer exists');\n return allocation;\n }),\n );\n }\n\n /** Remove one allocation atomically and rederive its invoice/credit status. */\n async removeAllocation(id: string): Promise<void> {\n const allocation = await this.get({ id }, { cache: false });\n if (!allocation) return;\n const { PaymentCollection } = await import('./PaymentCollection.js');\n const { InvoiceCollection } = await import('./InvoiceCollection.js');\n const payment = await (await PaymentCollection.create({ db: this.db })).get(\n { id: allocation.paymentId },\n { cache: false },\n );\n if (!payment) throw new Error('Allocation payment does not exist');\n await payment.withTransaction(async () => {\n const rows = await PaymentAllocationCollection.create({ db: payment.db });\n const current = await rows.get({ id }, { cache: false });\n if (!current) return;\n const invoices = await InvoiceCollection.create({ db: payment.db });\n const invoice = await invoices.get(\n { id: current.invoiceId },\n { cache: false },\n );\n if (!invoice) throw new Error('Allocation invoice does not exist');\n await current.delete();\n invoice.updatePaymentStatus(\n await rows.getTotalAllocatedToInvoice(current.invoiceId),\n );\n await invoice.save();\n });\n }\n\n /**\n * Find allocations by payment\n *\n * @param paymentId - Payment ID\n * @returns Array of allocations\n */\n private async allFor(\n field: 'paymentId' | 'invoiceId',\n id: string,\n ): Promise<PaymentAllocation[]> {\n const rows: PaymentAllocation[] = [];\n for (let offset = 0; ; offset += 1000) {\n const page = await this.list({\n where: { [field]: id },\n orderBy: ['allocatedAt DESC', 'id ASC'],\n offset,\n limit: 1000,\n });\n rows.push(...page);\n if (page.length < 1000) return rows;\n }\n }\n async findByPayment(paymentId: string): Promise<PaymentAllocation[]> {\n return this.allFor('paymentId', paymentId);\n }\n /** Every committed row participates in payment and historical combined capacity. */\n async findByInvoice(invoiceId: string): Promise<PaymentAllocation[]> {\n return this.allFor('invoiceId', invoiceId);\n }\n\n /**\n * Get total amount allocated to an invoice\n *\n * @param invoiceId - Invoice ID\n * @returns Total allocated amount\n */\n async getTotalAllocatedToInvoice(invoiceId: string): Promise<number> {\n const allocations = await this.findByInvoice(invoiceId);\n const total = allocations.reduce(\n (sum, alloc) => sum + BigInt(alloc.amount),\n BigInt(await historicalInvoiceAllocationTotal(this.db, invoiceId)),\n );\n if (total > BigInt(Number.MAX_SAFE_INTEGER))\n throw new Error('Combined invoice allocation total is unsafe');\n return Number(total);\n }\n\n /**\n * Get total amount allocated from a payment\n *\n * @param paymentId - Payment ID\n * @returns Total allocated amount\n */\n async getTotalAllocatedFromPayment(paymentId: string): Promise<number> {\n const allocations = await this.findByPayment(paymentId);\n return allocations.reduce((sum, alloc) => sum + alloc.amount, 0);\n }\n\n /**\n * Get remaining unallocated amount from a payment.\n *\n * @param paymentId - Payment ID\n * @param paymentAmount - Total payment amount\n * @returns Unallocated amount\n * @throws Error if payment is over-allocated (indicates data integrity issue)\n */\n async getUnallocatedFromPayment(\n paymentId: string,\n paymentAmount: number,\n ): Promise<number> {\n const allocated = await this.getTotalAllocatedFromPayment(paymentId);\n const { PaymentCollection } = await import('./PaymentCollection.js');\n const payment = await (await PaymentCollection.create({ db: this.db })).get(\n { id: paymentId },\n { cache: false },\n );\n const managed = customerFundsState(payment?.customerFundsJson);\n if (\n managed &&\n (managed.kind !== 'receipt' || payment?.amount !== paymentAmount)\n )\n throw new Error(\n 'Customer funds require their authoritative receipt amount',\n );\n const refunded =\n managed?.operations\n .filter((op) => op.kind === 'refund')\n .reduce((sum, op) => sum + BigInt(op.amountMinor), 0n) ?? 0n;\n const remaining = Number(\n BigInt(paymentAmount) - BigInt(allocated) - refunded,\n );\n\n if (remaining < 0) {\n throw new Error(\n `Over-allocated payment detected for paymentId=${paymentId}: ` +\n `allocated amount (${allocated}) exceeds payment amount (${paymentAmount})`,\n );\n }\n\n return remaining;\n }\n\n /**\n * Find allocation by payment and invoice\n *\n * @param paymentId - Payment ID\n * @param invoiceId - Invoice ID\n * @returns Allocation or null\n */\n async findByPaymentAndInvoice(\n paymentId: string,\n invoiceId: string,\n ): Promise<PaymentAllocation | null> {\n const results = await this.list({\n where: { paymentId, invoiceId },\n limit: 1,\n });\n return results[0] || null;\n }\n\n /**\n * Find allocations by allocator\n *\n * @param allocatedBy - User/agent ID who made the allocation\n * @returns Array of allocations\n */\n async findByAllocator(allocatedBy: string): Promise<PaymentAllocation[]> {\n return await this.list({\n where: { allocatedBy },\n orderBy: 'allocatedAt DESC',\n });\n }\n\n /**\n * Find allocations in date range\n *\n * @param startDate - Start date\n * @param endDate - End date\n * @returns Array of allocations\n */\n async findByDateRange(\n startDate: Date,\n endDate: Date,\n ): Promise<PaymentAllocation[]> {\n return await this.list({\n where: {\n 'allocatedAt >=': startDate.toISOString(),\n 'allocatedAt <=': endDate.toISOString(),\n },\n orderBy: 'allocatedAt DESC',\n });\n }\n\n // ============================================================================\n // Tenant Helper Methods\n // ============================================================================\n\n /**\n * Find all payment allocations belonging to a specific tenant\n *\n * @param tenantId - Tenant ID\n * @returns Array of payment allocations for the tenant\n */\n async findByTenant(tenantId: string): Promise<PaymentAllocation[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find all global payment allocations (not associated with any tenant).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global payment allocations\n */\n async findGlobal(): Promise<PaymentAllocation[]> {\n return queryGlobal<PaymentAllocation>(this);\n }\n\n /**\n * Find payment allocations for a tenant including global allocations.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID\n * @returns Array of tenant-specific and global payment allocations\n */\n async findWithGlobals(tenantId: string): Promise<PaymentAllocation[]> {\n return queryWithGlobals<PaymentAllocation>(\n this,\n tenantId,\n 'PaymentAllocation.findWithGlobals',\n );\n }\n}\n","/** Pure projection of frozen commerce money snapshots into accounting SDK inputs. */\n\nimport {\n type AccountingProvider,\n type CreditMemoInput,\n type InvoiceInput,\n type InvoiceLineItemInput,\n requireCreditMemoOperations,\n type SyncResult,\n type TaxComponentSnapshot,\n} from '@happyvertical/accounting';\n\nimport { minorToMajorUnits } from './billing/units.js';\nimport {\n type LineAmountType,\n MoneyValidationError,\n type TaxRoundingScope,\n} from './money.js';\n\nexport type FrozenAccountingDocumentKind = 'invoice' | 'creditMemo';\n\n/** Realm-specific references are configuration, never inferred from a tax name or rate. */\nexport interface FrozenQuickBooksTaxMapping {\n readonly lines: Readonly<\n Record<\n string,\n {\n readonly itemRef: string;\n readonly taxCodeRef: string;\n /** Caller-verified configuration of the referenced realm TaxCode. */\n readonly taxComponents?: readonly {\n readonly taxRateRef: string;\n readonly compound: boolean;\n }[];\n }\n >\n >;\n readonly components: Readonly<\n Record<string, { readonly quickbooksTaxRateRef: string }>\n >;\n}\n\n/** Frozen component fact persisted with a line; all values are minor units except percent. */\nexport interface FrozenAccountingTaxComponent {\n readonly taxComponentId: string;\n readonly name: string;\n /** Exact percent text: `5` means 5 percent. */\n readonly percent: string;\n readonly taxMinor: number;\n readonly compound?: boolean;\n readonly taxableMinor?: number;\n}\n\n/** A frozen commerce line. `unitPriceMinor` and `discountMinor` are pre-discount document-mode values. */\nexport interface FrozenAccountingLineSnapshot {\n readonly id: string;\n readonly description: string;\n readonly sku?: string;\n readonly quantity: number;\n /** Pre-discount unit price: net for exclusive, gross for inclusive. */\n readonly unitPriceMinor: number;\n /** Pre-discount reduction: net for exclusive, gross for inclusive. */\n readonly discountMinor: number;\n /** Persisted post-discount net amount. */\n readonly amountMinor: number;\n readonly taxMinor: number;\n readonly taxComponents: readonly FrozenAccountingTaxComponent[];\n}\n\n/** Immutable facts required to project one approved document. */\nexport interface FrozenAccountingDocumentSnapshot {\n readonly kind: FrozenAccountingDocumentKind;\n readonly id: string;\n readonly number: string;\n readonly customerId: string;\n readonly customerExternalId?: string;\n readonly issueDate: Date;\n readonly dueDate?: Date;\n readonly currency: string;\n readonly lineAmountType: LineAmountType;\n readonly taxRoundingScope: TaxRoundingScope;\n readonly subtotalMinor: number;\n readonly taxAmountMinor: number;\n /** Header-only provider tax has no frozen component and cannot be sent to QBO. */\n readonly providerTaxMinor: number;\n readonly totalAmountMinor: number;\n readonly lineItems: readonly FrozenAccountingLineSnapshot[];\n /** Required only for a positive credit memo. */\n readonly creditedInvoiceExternalId?: string;\n readonly externalId?: string;\n readonly reference?: string;\n readonly memo?: string;\n}\n\n/** Public SDK types retained as named aliases for commerce callers. */\nexport type AccountingTaxComponentInput = TaxComponentSnapshot;\nexport type AccountingSnapshotLineInput = InvoiceLineItemInput;\nexport type AccountingSnapshotInvoiceInput = InvoiceInput;\nexport type AccountingSnapshotCreditMemoInput = CreditMemoInput;\nexport type AccountingSnapshotInput = InvoiceInput | CreditMemoInput;\n\n/**\n * Map and submit a positive credit memo only when the provider exposes that\n * capability. Mapping runs before the provider is touched, so a malformed\n * frozen snapshot cannot trigger a network write.\n */\nexport async function pushFrozenCreditMemo(\n provider: Pick<AccountingProvider, 'type' | 'creditMemos'>,\n snapshot: FrozenAccountingDocumentSnapshot,\n mapping: FrozenQuickBooksTaxMapping,\n): Promise<SyncResult> {\n if (snapshot.kind !== 'creditMemo') {\n throw new Error('Credit-memo submission requires a creditMemo snapshot');\n }\n const input = mapFrozenAccountingSnapshot(snapshot, mapping);\n if (!('creditMemoNumber' in input)) {\n throw new Error('Credit-memo submission did not produce a credit memo');\n }\n return requireCreditMemoOperations(provider).push(input);\n}\n\nfunction requireText(value: string | undefined, label: string): string {\n if (!value || value.trim() !== value) {\n throw new Error(`${label} must be a nonempty trimmed string`);\n }\n return value;\n}\n\nfunction requireSafeMinor(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error(`${label} must be a nonnegative safe integer minor amount`);\n }\n return value;\n}\n\nfunction requirePositiveQuantity(quantity: number, lineId: string): number {\n if (!Number.isFinite(quantity) || quantity <= 0) {\n throw new Error(\n `Line '${lineId}' quantity must be a positive finite number`,\n );\n }\n return quantity;\n}\n\n/** Convert exact percent text to the SDK's fraction text without float arithmetic. */\nfunction percentToFraction(percent: string, componentId: string): string {\n if (!/^(?:0|[1-9]\\d{0,2})(?:\\.\\d{1,6})?$/.test(percent)) {\n throw new Error(\n `Tax component '${componentId}' percent must be exact decimal text from 0 through 100`,\n );\n }\n const [whole, fraction = ''] = percent.split('.');\n const scale = 10n ** BigInt(fraction.length);\n const numerator = BigInt(whole) * scale + BigInt(fraction || '0');\n const denominator = 100n * scale;\n if (numerator > denominator) {\n throw new Error(`Tax component '${componentId}' percent exceeds 100`);\n }\n if (numerator === 0n) return '0';\n if (numerator === denominator) return '1';\n const padded = numerator\n .toString()\n .padStart(denominator.toString().length - 1, '0');\n return `0.${padded}`.replace(/0+$/, '');\n}\n\nfunction globalTaxCalculation(\n lineAmountType: LineAmountType,\n): NonNullable<InvoiceInput['quickbooksMapping']>['globalTaxCalculation'] {\n switch (lineAmountType) {\n case 'exclusive':\n return 'TaxExcluded';\n case 'inclusive':\n return 'TaxInclusive';\n case 'none':\n return 'NotApplicable';\n }\n}\n\nfunction mapLine(\n line: FrozenAccountingLineSnapshot,\n currency: string,\n lineAmountType: LineAmountType,\n mapping: FrozenQuickBooksTaxMapping,\n): AccountingSnapshotLineInput {\n requireText(line.id, 'Line ID');\n const lineMapping = mapping.lines[line.id];\n if (!lineMapping) {\n throw new Error(\n `Missing explicit QuickBooks mapping for line '${line.id}'`,\n );\n }\n requireText(\n lineMapping.itemRef,\n `QuickBooks item reference for line '${line.id}'`,\n );\n requireText(\n lineMapping.taxCodeRef,\n `QuickBooks tax-code reference for line '${line.id}'`,\n );\n\n const amountMinor = requireSafeMinor(\n line.amountMinor,\n `Line '${line.id}' amount`,\n );\n const taxMinor = requireSafeMinor(line.taxMinor, `Line '${line.id}' tax`);\n const componentIds = new Set<string>();\n let componentTotalMinor = 0;\n const taxComponents = line.taxComponents.map((component) => {\n if (\n component.compound !== undefined &&\n typeof component.compound !== 'boolean'\n )\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen component compound flag must be boolean',\n );\n if (component.compound && !lineMapping.taxComponents)\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_UNSUPPORTED',\n 'Compound accounting sync requires caller-verified ordered realm tax-code mapping',\n );\n if (component.compound && component.taxableMinor === undefined)\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_UNSUPPORTED',\n 'Compound accounting sync requires the frozen component taxable basis',\n );\n const basisMinor =\n component.taxableMinor === undefined\n ? undefined\n : requireSafeMinor(\n component.taxableMinor,\n `Line '${line.id}' component taxable basis`,\n );\n if (\n basisMinor !== undefined &&\n basisMinor !==\n amountMinor + (component.compound ? componentTotalMinor : 0)\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_UNSUPPORTED',\n 'Frozen component taxable basis does not match ordered source facts',\n );\n requireText(component.taxComponentId, `Line '${line.id}' tax component ID`);\n if (componentIds.has(component.taxComponentId)) {\n throw new Error(\n `Line '${line.id}' repeats tax component '${component.taxComponentId}'`,\n );\n }\n componentIds.add(component.taxComponentId);\n const taxAmountMinor = requireSafeMinor(\n component.taxMinor,\n `Line '${line.id}' component '${component.taxComponentId}' tax`,\n );\n componentTotalMinor += taxAmountMinor;\n const componentMapping = mapping.components[component.taxComponentId];\n if (!componentMapping) {\n throw new Error(\n `Missing explicit QuickBooks tax-rate reference for component '${component.taxComponentId}'`,\n );\n }\n requireText(\n componentMapping.quickbooksTaxRateRef,\n `QuickBooks tax-rate reference for component '${component.taxComponentId}'`,\n );\n return {\n taxCode: component.taxComponentId,\n rate: percentToFraction(component.percent, component.taxComponentId),\n quickbooksTaxRateRef: componentMapping.quickbooksTaxRateRef,\n taxAmount: minorToMajorUnits(taxAmountMinor, currency),\n ...(component.compound ? { compound: true } : {}),\n ...(basisMinor !== undefined\n ? { taxableAmount: minorToMajorUnits(basisMinor, currency) }\n : {}),\n };\n });\n if (\n lineMapping.taxComponents &&\n (lineMapping.taxComponents.length !== taxComponents.length ||\n lineMapping.taxComponents.some(\n (part, index) =>\n part.taxRateRef !== taxComponents[index].quickbooksTaxRateRef ||\n typeof part.compound !== 'boolean' ||\n part.compound !== (taxComponents[index].compound ?? false),\n ))\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_UNSUPPORTED',\n 'Ordered realm tax-code mapping does not match frozen components',\n );\n if (componentTotalMinor !== taxMinor) {\n throw new Error(\n `Line '${line.id}' frozen component tax ${componentTotalMinor} does not equal line tax ${taxMinor}`,\n );\n }\n if (taxMinor > 0 && taxComponents.length === 0) {\n throw new Error(`Line '${line.id}' tax requires frozen tax components`);\n }\n\n const discountMinor = requireSafeMinor(\n line.discountMinor,\n `Line '${line.id}' discount`,\n );\n const unitPriceMinor = requireSafeMinor(\n line.unitPriceMinor,\n `Line '${line.id}' unit price`,\n );\n const result = {\n description: requireText(line.description, `Line '${line.id}' description`),\n sku: line.sku || undefined,\n quantity: requirePositiveQuantity(line.quantity, line.id),\n unitPrice: minorToMajorUnits(unitPriceMinor, currency),\n ...(discountMinor === 0\n ? {}\n : { discount: minorToMajorUnits(discountMinor, currency) }),\n amount: minorToMajorUnits(amountMinor, currency),\n taxAmount: minorToMajorUnits(taxMinor, currency),\n taxComponents,\n quickbooksMapping: {\n itemRef: lineMapping.itemRef,\n taxCodeRef: lineMapping.taxCodeRef,\n ...(lineMapping.taxComponents\n ? {\n taxComponents: lineMapping.taxComponents.map((part) => ({\n ...part,\n })),\n }\n : {}),\n },\n };\n if (lineAmountType === 'inclusive') {\n // This is an exact representation of two stored facts, never a tax calculation.\n return {\n ...result,\n taxInclusiveAmount: minorToMajorUnits(amountMinor + taxMinor, currency),\n };\n }\n return result;\n}\n\n/**\n * Project an approved frozen snapshot into the companion SDK's request shape.\n * It does not calculate discounts, taxes, rates, or document allocation.\n */\nexport function mapFrozenAccountingSnapshot(\n snapshot: FrozenAccountingDocumentSnapshot,\n mapping: FrozenQuickBooksTaxMapping,\n): AccountingSnapshotInput {\n const currency = requireText(snapshot.currency, 'Currency');\n requireText(snapshot.id, 'Document ID');\n requireText(snapshot.number, 'Document number');\n requireText(snapshot.customerId, 'Customer ID');\n if (\n !(snapshot.issueDate instanceof Date) ||\n Number.isNaN(snapshot.issueDate.valueOf())\n ) {\n throw new Error('Issue date must be a valid Date');\n }\n if (!Array.isArray(snapshot.lineItems) || snapshot.lineItems.length === 0) {\n throw new Error('Frozen document requires at least one line item');\n }\n const subtotalMinor = requireSafeMinor(snapshot.subtotalMinor, 'Subtotal');\n const taxAmountMinor = requireSafeMinor(\n snapshot.taxAmountMinor,\n 'Tax amount',\n );\n const providerTaxMinor = requireSafeMinor(\n snapshot.providerTaxMinor,\n 'Provider tax',\n );\n const totalAmountMinor = requireSafeMinor(snapshot.totalAmountMinor, 'Total');\n if (providerTaxMinor !== 0) {\n throw new Error(\n 'Frozen provider tax cannot be mapped to QuickBooks without a stored component snapshot and explicit tax-rate reference',\n );\n }\n if (subtotalMinor + taxAmountMinor !== totalAmountMinor) {\n throw new Error('Frozen subtotal plus tax must equal frozen total');\n }\n\n const lineItems = snapshot.lineItems.map((line) =>\n mapLine(line, currency, snapshot.lineAmountType, mapping),\n );\n const linesSubtotalMinor = snapshot.lineItems.reduce(\n (sum, line) => sum + line.amountMinor,\n 0,\n );\n const linesTaxMinor = snapshot.lineItems.reduce(\n (sum, line) => sum + line.taxMinor,\n 0,\n );\n if (linesSubtotalMinor !== subtotalMinor) {\n throw new Error('Frozen line net amounts do not equal frozen subtotal');\n }\n if (linesTaxMinor !== taxAmountMinor) {\n throw new Error('Frozen line tax amounts do not equal frozen tax total');\n }\n\n const base = {\n id: snapshot.id,\n externalId: snapshot.externalId,\n customerId: snapshot.customerId,\n customerExternalId: snapshot.customerExternalId,\n issueDate: snapshot.issueDate,\n currency,\n subtotal: minorToMajorUnits(subtotalMinor, currency),\n taxAmount: minorToMajorUnits(taxAmountMinor, currency),\n totalAmount: minorToMajorUnits(totalAmountMinor, currency),\n lineItems,\n quickbooksMapping: {\n globalTaxCalculation: globalTaxCalculation(snapshot.lineAmountType),\n },\n reference: snapshot.reference,\n memo: snapshot.memo,\n } as const;\n\n if (snapshot.kind === 'invoice') {\n if (\n !(snapshot.dueDate instanceof Date) ||\n Number.isNaN(snapshot.dueDate.valueOf())\n ) {\n throw new Error('Invoice due date must be a valid Date');\n }\n return {\n ...base,\n invoiceNumber: snapshot.number,\n dueDate: snapshot.dueDate,\n };\n }\n const creditedInvoiceExternalId = requireText(\n snapshot.creditedInvoiceExternalId,\n 'Credited invoice external ID',\n );\n if (subtotalMinor === 0 || totalAmountMinor === 0) {\n throw new Error('Credit memo amounts must be positive');\n }\n return {\n ...base,\n creditMemoNumber: snapshot.number,\n creditedInvoiceExternalId,\n };\n}\n","import { deterministicId } from './billing/units.js';\nimport { MoneyValidationError } from './money.js';\n\n/** Host-authorized acceptance of a specific frozen local invoice snapshot. */\nexport interface QuickBooksPilotAcceptance {\n readonly obligationId: string;\n readonly quoteVersionId: string;\n readonly moneySnapshotId: string;\n}\n\nexport interface QuickBooksPilotScope {\n readonly tenantId: string;\n readonly realmId: string;\n readonly environment: 'sandbox';\n}\n\nexport interface QuickBooksPilotInvoiceEvidence extends QuickBooksPilotScope {\n readonly externalId: string;\n readonly customerExternalId: string;\n readonly currency: string;\n readonly subtotalMinor: number;\n readonly discountMinor: number;\n readonly taxMinor: number;\n readonly totalMinor: number;\n /** Provider calendar date, YYYY-MM-DD. */\n readonly dueDate: string | null;\n readonly balanceMinor: number;\n readonly voided: boolean;\n /** True only after the adapter has read all relevant linked transaction facts. */\n readonly complete: true;\n readonly transactions: readonly QuickBooksPilotTransaction[];\n}\n\nexport interface QuickBooksPilotTransaction {\n readonly id: string;\n readonly kind: 'payment' | 'credit' | 'refund';\n /** Exact amount attributable to this invoice, not the entire transaction. */\n readonly amountMinor: number;\n}\n\nexport interface QuickBooksPilotProjection {\n readonly balanceMinor: number;\n readonly paidMinor: number;\n readonly creditedMinor: number;\n readonly refundedMinor: number;\n readonly state:\n | 'unpaid'\n | 'partial'\n | 'paid'\n | 'credited'\n | 'refunded'\n | 'voided';\n readonly transactions: readonly QuickBooksPilotTransaction[];\n readonly observedAt: string;\n}\n\nexport function pilotDisagreement(message: string): never {\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n message,\n );\n}\n\n/** Use this ID when preparing the one canonical local invoice for the obligation. */\nexport function quickBooksPilotInvoiceId(\n tenantId: string,\n obligationId: string,\n): Promise<string> {\n return deterministicId(['quickbooks-pilot-invoice', tenantId, obligationId]);\n}\n\nexport function projectQuickBooksPilotEvidence(\n evidence: QuickBooksPilotInvoiceEvidence,\n): QuickBooksPilotProjection {\n const { balanceMinor, totalMinor, voided, transactions } = evidence;\n if (\n evidence.complete !== true ||\n typeof voided !== 'boolean' ||\n !Number.isSafeInteger(balanceMinor) ||\n balanceMinor < 0 ||\n balanceMinor > totalMinor ||\n !Array.isArray(transactions)\n )\n pilotDisagreement('QuickBooks invoice readback is incomplete or invalid');\n\n const seen = new Set<string>();\n const facts: QuickBooksPilotTransaction[] = [];\n const sums = { payment: 0, credit: 0, refund: 0 };\n for (const entry of evidence.transactions) {\n if (!entry || typeof entry !== 'object')\n pilotDisagreement('QuickBooks linked transaction evidence is invalid');\n const { id, kind, amountMinor } = entry;\n if (\n !['payment', 'credit', 'refund'].includes(kind) ||\n typeof id !== 'string' ||\n !id ||\n id.trim() !== id ||\n !Number.isSafeInteger(amountMinor) ||\n amountMinor <= 0 ||\n seen.has(JSON.stringify([kind, id]))\n )\n pilotDisagreement(\n 'QuickBooks linked transaction evidence is invalid or duplicated',\n );\n seen.add(JSON.stringify([kind, id]));\n facts.push({ id, kind, amountMinor });\n sums[kind] += amountMinor;\n if (!Number.isSafeInteger(sums[kind]))\n pilotDisagreement(\n 'QuickBooks linked transaction totals exceed safe minor units',\n );\n }\n\n const paidMinor = sums.payment - sums.refund;\n if (\n paidMinor < 0 ||\n (voided\n ? balanceMinor !== 0 || paidMinor !== 0 || sums.credit !== 0\n : BigInt(paidMinor) + BigInt(sums.credit) + BigInt(balanceMinor) !==\n BigInt(totalMinor))\n )\n pilotDisagreement(\n 'QuickBooks balance disagrees with linked transaction evidence',\n );\n\n let state: QuickBooksPilotProjection['state'] = 'unpaid';\n if (voided) state = 'voided';\n else if (sums.refund > 0) state = 'refunded';\n else if (balanceMinor === 0 && sums.credit > 0) state = 'credited';\n else if (balanceMinor === 0) state = 'paid';\n else if (paidMinor > 0 || sums.credit > 0) state = 'partial';\n\n return {\n balanceMinor,\n paidMinor,\n creditedMinor: sums.credit,\n refundedMinor: sums.refund,\n state,\n transactions: facts,\n observedAt: new Date().toISOString(),\n };\n}\n","import { hasOrdinaryAccountingAuthority } from './ordinary-accounting-internal.js';\nimport { hasRetentionAccountingAuthority } from './retention-accounting-internal.js';\n/** Frozen Invoice projection and guarded accounting-provider synchronization. */\n\nimport { createHash, randomUUID } from 'node:crypto';\nimport type {\n AccountingProvider,\n InvoiceInput,\n QuickBooksCreditMemoRequest,\n QuickBooksInvoiceRequest,\n SyncResult,\n} from '@happyvertical/accounting';\nimport {\n prepareQuickBooksCreditMemoRequest,\n prepareQuickBooksInvoiceRequest,\n requireCreditMemoOperations,\n} from '@happyvertical/accounting';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport {\n type AccountingSnapshotInput,\n type FrozenAccountingDocumentSnapshot,\n type FrozenQuickBooksTaxMapping,\n mapFrozenAccountingSnapshot,\n} from './accounting-snapshot.js';\nimport { DocumentTaxCollection } from './collections/DocumentTaxCollection.js';\nimport { InvoiceCollection } from './collections/InvoiceCollection.js';\nimport { InvoiceLineItemCollection } from './collections/InvoiceLineItemCollection.js';\nimport { lockAndReloadInvoice } from './document-money.js';\nimport {\n DOCUMENT_MONEY_WRITE,\n withDocumentMoneyTransaction,\n} from './document-money-internal.js';\nimport type { Invoice } from './models/Invoice.js';\nimport type { InvoiceLineItem } from './models/InvoiceLineItem.js';\nimport { MoneyValidationError } from './money.js';\nimport {\n pilotDisagreement,\n projectQuickBooksPilotEvidence,\n type QuickBooksPilotAcceptance,\n type QuickBooksPilotInvoiceEvidence,\n type QuickBooksPilotProjection,\n type QuickBooksPilotScope,\n quickBooksPilotInvoiceId,\n} from './quickbooks-pilot-evidence.js';\nimport { lockTenantMoneyRuntime } from './tenant-money-barrier.js';\nimport { type AccountingInvoiceInput, InvoiceStatus } from './types/index.js';\n\nexport interface QuickBooksFrozenInvoiceMapping\n extends FrozenQuickBooksTaxMapping {\n readonly realmId: string;\n readonly environment: 'sandbox' | 'production';\n}\n\nexport interface FrozenInvoiceAccountingOptions {\n readonly mapping: QuickBooksFrozenInvoiceMapping;\n}\n\nexport interface FrozenInvoiceAccountingInput\n extends FrozenInvoiceAccountingOptions {\n readonly db: DatabaseInterface;\n readonly tenantId: string;\n readonly invoiceId: string;\n}\n\nexport interface FrozenInvoiceAccountingSnapshot {\n readonly document: FrozenAccountingDocumentSnapshot;\n readonly moneySnapshotId: string;\n readonly creditedInvoiceScope?: Readonly<{\n provider: 'quickbooks';\n realmId: string;\n environment: 'sandbox' | 'production';\n }>;\n}\n\ntype FrozenSyncStatus = 'in_flight' | 'unknown' | 'rejected' | 'synced';\n\ninterface FrozenSyncIdentity {\n provider: 'quickbooks';\n documentKind: 'invoice' | 'creditMemo';\n realmId: string;\n environment: 'sandbox' | 'production';\n invoiceId: string;\n moneySnapshotId: string;\n requestId: string;\n payloadHash: string;\n creditedInvoiceExternalId?: string;\n}\n\ninterface FrozenSyncState {\n version: 1;\n status: FrozenSyncStatus;\n identity: FrozenSyncIdentity;\n attemptId: string;\n startedAt: string;\n externalId?: string;\n syncedAt?: string;\n pilot?: QuickBooksPilotAcceptance;\n pilotProjection?: QuickBooksPilotProjection;\n}\n\nexport interface FrozenAccountingSyncResult {\n readonly status: 'synced' | 'unchanged';\n readonly externalId: string;\n readonly syncedAt: Date;\n readonly moneySnapshotId: string;\n}\n\nexport interface SyncFrozenInvoiceToAccountingInput\n extends FrozenInvoiceAccountingInput {\n readonly provider: Pick<\n AccountingProvider,\n 'type' | 'invoices' | 'creditMemos'\n >;\n}\n\nexport interface ReconcileFrozenInvoiceAccountingInput\n extends FrozenInvoiceAccountingInput {\n /** The request descriptor observed before checking QuickBooks. */\n readonly requestId: string;\n /** The unresolved local owner observed with that request descriptor. */\n readonly attemptId: string;\n /**\n * Required only for an interrupted `in_flight` record. The trusted server\n * caller must first establish that the original process/request owner can no\n * longer complete. A provider lookup reporting absence is not sufficient.\n */\n readonly confirmInterruptedOwnerStopped?: true;\n /**\n * The authoritative result of looking up that request in QuickBooks.\n * `absent` means QuickBooks confirmed that no document was created.\n */\n readonly outcome:\n | {\n readonly status: 'found';\n readonly externalId: string;\n readonly syncedAt: Date;\n }\n | { readonly status: 'absent' };\n}\n\nexport interface FrozenAccountingReconciliationReady {\n readonly status: 'ready';\n readonly moneySnapshotId: string;\n readonly requestId: string;\n}\n\ntype FrozenInvoicePushInput = Omit<\n SyncFrozenInvoiceToAccountingInput,\n 'provider'\n> & {\n readonly provider: Omit<\n SyncFrozenInvoiceToAccountingInput['provider'],\n 'invoices'\n > & {\n readonly invoices: Pick<AccountingProvider['invoices'], 'push'>;\n };\n};\n\ninterface PreparedSync {\n kind: 'push';\n documentKind: 'invoice' | 'creditMemo';\n accountingInput: AccountingSnapshotInput;\n invoice: Invoice;\n identity: FrozenSyncIdentity;\n attemptId: string;\n}\n\ninterface UnchangedSync {\n kind: 'unchanged';\n result: FrozenAccountingSyncResult;\n}\n\nfunction requiredText(value: string, label: string): string {\n if (!value || value.trim() !== value)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n `${label} must be a nonempty trimmed string`,\n );\n return value;\n}\n\nfunction assertPrincipalTenant(tenantId: string): void {\n requiredText(tenantId, 'Accounting tenant');\n if (getTenantId() !== tenantId)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Accounting sync requires its active principal tenant',\n );\n}\n\nfunction unsupported(message: string): never {\n throw new MoneyValidationError('ACCOUNTING_SYNC_UNSUPPORTED', message);\n}\n\nfunction parseSyncState(value: string): FrozenSyncState | null {\n if (!value) return null;\n try {\n const parsed: unknown = JSON.parse(value);\n if (!parsed || typeof parsed !== 'object') throw new Error('not object');\n const state = parsed as Partial<FrozenSyncState>;\n const identity = state.identity as Partial<FrozenSyncIdentity> | undefined;\n if (\n state.version !== 1 ||\n !['in_flight', 'unknown', 'rejected', 'synced'].includes(\n String(state.status),\n ) ||\n !identity ||\n identity.provider !== 'quickbooks' ||\n typeof identity.realmId !== 'string' ||\n (identity.environment !== 'sandbox' &&\n identity.environment !== 'production') ||\n typeof identity.invoiceId !== 'string' ||\n typeof identity.moneySnapshotId !== 'string' ||\n typeof identity.requestId !== 'string' ||\n typeof identity.payloadHash !== 'string' ||\n (identity.documentKind !== undefined &&\n identity.documentKind !== 'invoice' &&\n identity.documentKind !== 'creditMemo') ||\n (identity.creditedInvoiceExternalId !== undefined &&\n typeof identity.creditedInvoiceExternalId !== 'string') ||\n typeof state.attemptId !== 'string' ||\n typeof state.startedAt !== 'string'\n )\n throw new Error('invalid shape');\n return {\n ...(state as FrozenSyncState),\n identity: {\n ...(identity as FrozenSyncIdentity),\n documentKind: identity.documentKind ?? 'invoice',\n },\n };\n } catch {\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Stored accounting sync state is malformed and requires reconciliation',\n );\n }\n}\n\nfunction sameIdentity(\n left: FrozenSyncIdentity,\n right: FrozenSyncIdentity,\n): boolean {\n return (\n left.provider === right.provider &&\n left.documentKind === right.documentKind &&\n left.realmId === right.realmId &&\n left.environment === right.environment &&\n left.invoiceId === right.invoiceId &&\n left.moneySnapshotId === right.moneySnapshotId &&\n left.requestId === right.requestId &&\n left.payloadHash === right.payloadHash &&\n left.creditedInvoiceExternalId === right.creditedInvoiceExternalId\n );\n}\n\nfunction sameSyncScope(\n identity: FrozenSyncIdentity,\n snapshot: FrozenInvoiceAccountingSnapshot,\n mapping: QuickBooksFrozenInvoiceMapping,\n): boolean {\n return (\n identity.provider === 'quickbooks' &&\n identity.documentKind === snapshot.document.kind &&\n identity.realmId === mapping.realmId &&\n identity.environment === mapping.environment &&\n identity.invoiceId === snapshot.document.id &&\n identity.moneySnapshotId === snapshot.moneySnapshotId\n );\n}\n\nfunction sum(values: readonly number[]): number {\n let result = 0n;\n for (const value of values) {\n if (!Number.isSafeInteger(value))\n throw new MoneyValidationError(\n 'UNSAFE_MONEY',\n 'Frozen accounting facts require safe integer minor units',\n );\n result += BigInt(value);\n }\n if (\n result > BigInt(Number.MAX_SAFE_INTEGER) ||\n result < BigInt(Number.MIN_SAFE_INTEGER)\n )\n throw new MoneyValidationError(\n 'UNSAFE_MONEY',\n 'Frozen accounting totals exceed safe integer minor units',\n );\n return Number(result);\n}\n\nfunction componentTotals(\n lines: readonly InvoiceLineItem[],\n): Map<string, number> {\n const totals = new Map<string, number>();\n for (const line of lines) {\n for (const component of line.taxComponents) {\n totals.set(\n component.taxComponentId,\n sum([totals.get(component.taxComponentId) ?? 0, component.taxMinor]),\n );\n }\n }\n return totals;\n}\n\nasync function loadSnapshot(\n db: DatabaseInterface,\n tenantId: string,\n invoice: Invoice,\n): Promise<FrozenInvoiceAccountingSnapshot> {\n if (invoice.moneyAuthority === 'historical')\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_UNSUPPORTED',\n 'Historical sales source money requires an explicit reviewed provider representation; no quantities or tax breakdown will be invented',\n );\n\n if (invoice.tenantId !== tenantId)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Accounting invoice cannot cross tenant boundaries',\n );\n if (invoice.status === InvoiceStatus.DRAFT || !invoice.moneySnapshotId)\n throw new MoneyValidationError(\n 'FROZEN_DOCUMENT',\n 'Accounting sync requires an issued frozen invoice',\n );\n if (\n (invoice.getPayableFacts().retainedRemainingMinor > 0 ||\n invoice.retentionAccountingStateJson) &&\n !hasRetentionAccountingAuthority(invoice.tenantId, invoice.id)\n )\n unsupported(\n 'Unreleased retention requires a provider payable representation',\n );\n if (invoice.status === InvoiceStatus.CANCELLED)\n unsupported('Cancelled documents cannot be created by accounting sync');\n\n const lines = await (\n await InvoiceLineItemCollection.create({ db })\n ).findByInvoice(requiredText(invoice.id ?? '', 'Accounting invoice ID'));\n if (lines.length === 0)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen accounting invoice requires at least one line',\n );\n for (const line of lines) {\n if (\n line.tenantId !== tenantId ||\n line.moneySnapshotId !== invoice.moneySnapshotId\n )\n throw new MoneyValidationError(\n 'FROZEN_DOCUMENT',\n 'Accounting line snapshot does not match its frozen invoice',\n );\n }\n const taxes = await (\n await DocumentTaxCollection.create({ db })\n ).findByDocument(tenantId, invoice.kind, invoice.id ?? '');\n const lineTax = sum(lines.map((line) => line.taxAmount));\n const storedTax = sum(taxes.map((row) => row.taxMinor));\n if (\n lineTax + invoice.providerTaxAmount !== invoice.taxAmount ||\n storedTax !== lineTax\n )\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen line, DocumentTax, and invoice tax totals do not reconcile',\n );\n const lineComponents = componentTotals(lines);\n const storedComponents = new Map<string, number>();\n for (const row of taxes) {\n if (!row.taxComponentId) continue;\n storedComponents.set(\n row.taxComponentId,\n sum([storedComponents.get(row.taxComponentId) ?? 0, row.taxMinor]),\n );\n }\n if (\n [...new Set([...lineComponents.keys(), ...storedComponents.keys()])].some(\n (id) => (lineComponents.get(id) ?? 0) !== (storedComponents.get(id) ?? 0),\n )\n )\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen line components do not reconcile to DocumentTax',\n );\n\n let creditedInvoiceExternalId: string | undefined;\n let creditedInvoiceScope:\n | FrozenInvoiceAccountingSnapshot['creditedInvoiceScope']\n | undefined;\n if (invoice.kind === 'credit_note') {\n if (!invoice.creditedInvoiceId)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen credit note requires its credited invoice',\n );\n const source = await (await InvoiceCollection.create({ db })).get(\n { id: invoice.creditedInvoiceId },\n { cache: false },\n );\n if (!source || source.tenantId !== tenantId || !source.externalId)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen credit note requires the source invoice external ID',\n );\n if (\n source.retentionAccountingStateJson &&\n !hasRetentionAccountingAuthority(source.tenantId, source.id)\n )\n unsupported(\n 'Provider-retained credit requires the retained-first accounting adjustment command',\n );\n if (\n source.ordinaryAccountingStateJson &&\n !hasOrdinaryAccountingAuthority(source.tenantId, source.id)\n )\n unsupported(\n 'Provider ordinary credit requires its owning accounting adjustment command',\n );\n const sourceState = parseSyncState(source.accountingSyncStateJson);\n if (\n sourceState?.status !== 'synced' ||\n sourceState.externalId !== source.externalId\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Frozen credit note requires a reconciled source invoice accounting identity',\n );\n creditedInvoiceExternalId = source.externalId;\n creditedInvoiceScope = {\n provider: sourceState.identity.provider,\n realmId: sourceState.identity.realmId,\n environment: sourceState.identity.environment,\n };\n }\n\n return {\n moneySnapshotId: invoice.moneySnapshotId,\n creditedInvoiceScope,\n document: {\n kind: invoice.kind === 'invoice' ? 'invoice' : 'creditMemo',\n id: invoice.id ?? '',\n number: invoice.invoiceNumber,\n customerId: invoice.customerId,\n customerExternalId: invoice.customerExternalId || undefined,\n issueDate: invoice.issueDate,\n dueDate: invoice.dueDate ?? undefined,\n currency: invoice.currency,\n lineAmountType: invoice.lineAmountType,\n taxRoundingScope: invoice.taxRoundingScope,\n subtotalMinor: invoice.subtotal,\n taxAmountMinor: invoice.taxAmount,\n providerTaxMinor: invoice.providerTaxAmount,\n totalAmountMinor: invoice.totalAmount,\n lineItems: lines.map((line) => ({\n id: requiredText(line.id ?? '', 'Accounting line ID'),\n description: line.description,\n sku: line.sku || undefined,\n quantity: line.quantity,\n unitPriceMinor: line.unitPrice,\n discountMinor: line.discount,\n amountMinor:\n invoice.lineAmountType === 'inclusive'\n ? line.amount - line.taxAmount\n : line.amount,\n taxMinor: line.taxAmount,\n taxComponents: structuredClone(line.taxComponents),\n })),\n creditedInvoiceExternalId,\n externalId: invoice.externalId || undefined,\n reference: invoice.reference || undefined,\n memo: invoice.customerNotes || undefined,\n },\n };\n}\n\nfunction validateMapping(mapping: QuickBooksFrozenInvoiceMapping): void {\n requiredText(mapping.realmId, 'QuickBooks realm ID');\n if (mapping.environment !== 'sandbox' && mapping.environment !== 'production')\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'QuickBooks environment must be sandbox or production',\n );\n if (!mapping.lines || typeof mapping.lines !== 'object')\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'QuickBooks line mapping is required',\n );\n if (!mapping.components || typeof mapping.components !== 'object')\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'QuickBooks component mapping is required',\n );\n}\n\nfunction toSdkInput(\n snapshot: FrozenInvoiceAccountingSnapshot,\n mapping: QuickBooksFrozenInvoiceMapping,\n): AccountingSnapshotInput {\n validateMapping(mapping);\n if (\n snapshot.document.kind === 'creditMemo' &&\n (snapshot.creditedInvoiceScope?.provider !== 'quickbooks' ||\n snapshot.creditedInvoiceScope.realmId !== mapping.realmId ||\n snapshot.creditedInvoiceScope.environment !== mapping.environment)\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Credit note and credited invoice must use the same accounting provider, realm, and environment',\n );\n if (\n snapshot.document.lineItems.some(\n (line) =>\n line.quantity < 0 || line.amountMinor < 0 || line.unitPriceMinor < 0,\n )\n )\n unsupported(\n 'Signed-line accounting sync requires a public accounting SDK signed-line representation',\n );\n return mapFrozenAccountingSnapshot(snapshot.document, mapping);\n}\n\n/** Load and validate one authoritative issued snapshot without provider I/O. */\nexport async function loadFrozenInvoiceAccountingSnapshot(\n input: Omit<FrozenInvoiceAccountingInput, 'mapping'>,\n): Promise<FrozenInvoiceAccountingSnapshot> {\n assertPrincipalTenant(input.tenantId);\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n return loadSnapshot(tx, input.tenantId, invoice);\n });\n}\n\n/** Convert authoritative persisted facts into the released SDK invoice shape. */\nexport async function toFrozenInvoiceAccountingInput(\n input: FrozenInvoiceAccountingInput,\n): Promise<AccountingInvoiceInput> {\n const snapshot = await loadFrozenInvoiceAccountingSnapshot(input);\n return toSdkInput(snapshot, input.mapping) as AccountingInvoiceInput;\n}\n\nfunction prepareRequest(\n snapshot: FrozenInvoiceAccountingSnapshot,\n mapping: QuickBooksFrozenInvoiceMapping,\n sdkInput: AccountingSnapshotInput,\n): {\n accountingInput: AccountingSnapshotInput;\n request: QuickBooksInvoiceRequest | QuickBooksCreditMemoRequest;\n} {\n const identity = {\n requestId: requestIdFor(snapshot, mapping),\n realmId: mapping.realmId,\n environment: mapping.environment,\n } as const;\n if (snapshot.document.kind === 'invoice') {\n if (!('invoiceNumber' in sdkInput))\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen invoice mapping produced the wrong accounting document kind',\n );\n const request = prepareQuickBooksInvoiceRequest(sdkInput, identity);\n return {\n request,\n accountingInput: {\n ...sdkInput,\n idempotencyKey: request.requestId,\n quickbooksRequest: request,\n },\n };\n }\n if (!('creditMemoNumber' in sdkInput))\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Frozen credit-note mapping produced the wrong accounting document kind',\n );\n const request = prepareQuickBooksCreditMemoRequest(sdkInput, identity);\n return {\n request,\n accountingInput: {\n ...sdkInput,\n quickbooksCreditMemoRequest: request,\n },\n };\n}\n\nfunction requestIdFor(\n snapshot: FrozenInvoiceAccountingSnapshot,\n mapping: QuickBooksFrozenInvoiceMapping,\n): string {\n const digest = createHash('sha256')\n .update(\n JSON.stringify([\n 'quickbooks',\n mapping.realmId,\n mapping.environment,\n snapshot.document.id,\n snapshot.moneySnapshotId,\n ]),\n )\n .digest('hex');\n return `smrt_${digest.slice(0, 40)}`;\n}\n\nasync function prepareSync(\n input: FrozenInvoicePushInput,\n pilot?: QuickBooksPilotAcceptance,\n): Promise<PreparedSync | UnchangedSync> {\n if (input.provider.type !== 'quickbooks')\n unsupported(\n `Frozen accounting sync does not support provider '${input.provider.type}'`,\n );\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n if (\n invoice.ordinaryAccountingStateJson &&\n !hasOrdinaryAccountingAuthority(invoice.tenantId, invoice.id)\n )\n unsupported(\n 'Provider ordinary invoice requires its owning accounting command',\n );\n const snapshot = await loadSnapshot(tx, input.tenantId, invoice);\n const sdkInput = toSdkInput(snapshot, input.mapping);\n const prior = parseSyncState(invoice.accountingSyncStateJson);\n checkPilotAcceptance(invoice, prior, pilot);\n if (pilot) assertPilotInvoice(invoice);\n if (\n prior?.status === 'synced' &&\n sameSyncScope(prior.identity, snapshot, input.mapping)\n ) {\n if (!prior.externalId || !prior.syncedAt)\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Completed accounting sync state is incomplete',\n );\n return {\n kind: 'unchanged',\n result: {\n status: 'unchanged',\n externalId: prior.externalId,\n syncedAt: new Date(prior.syncedAt),\n moneySnapshotId: prior.identity.moneySnapshotId,\n },\n };\n }\n if (prior?.status === 'in_flight')\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_IN_PROGRESS',\n 'Another accounting sync owns this invoice',\n );\n if (prior?.status === 'unknown')\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'The prior accounting write outcome is unknown and must be reconciled',\n );\n if (prior?.status === 'synced' || invoice.externalId)\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Invoice accounting identity changed across provider, realm, environment, or snapshot',\n );\n if (snapshot.document.kind === 'creditMemo') {\n try {\n requireCreditMemoOperations(input.provider);\n } catch (error) {\n unsupported(error instanceof Error ? error.message : String(error));\n }\n }\n const { accountingInput, request } = prepareRequest(\n snapshot,\n input.mapping,\n sdkInput,\n );\n const identity = frozenIdentity(snapshot, request);\n if (prior && !sameIdentity(prior.identity, identity))\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Invoice accounting identity changed across provider, realm, environment, or snapshot',\n );\n\n const attemptId = randomUUID();\n invoice.accountingSyncStateJson = JSON.stringify({\n version: 1,\n status: 'in_flight',\n identity,\n attemptId,\n startedAt: new Date().toISOString(),\n pilot,\n } satisfies FrozenSyncState);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n return {\n kind: 'push',\n documentKind: snapshot.document.kind,\n accountingInput,\n invoice,\n identity,\n attemptId,\n };\n });\n}\n\nasync function recordFailure(\n input: FrozenInvoicePushInput,\n prepared: PreparedSync,\n error: unknown,\n pushReturned: boolean,\n): Promise<void> {\n const rejected =\n !pushReturned &&\n !!error &&\n typeof error === 'object' &&\n (error as { code?: unknown }).code === 'QBO_WRITE_ERROR' &&\n (error as { outcome?: unknown }).outcome === 'rejected';\n await withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n const state = parseSyncState(invoice.accountingSyncStateJson);\n if (\n !state ||\n state.attemptId !== prepared.attemptId ||\n !sameIdentity(state.identity, prepared.identity)\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Accounting sync ownership changed after provider failure',\n );\n invoice.accountingSyncStateJson = JSON.stringify({\n ...state,\n status: rejected ? 'rejected' : 'unknown',\n } satisfies FrozenSyncState);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n });\n}\n\nasync function saveSyncedInvoice(\n invoice: Invoice,\n state: FrozenSyncState,\n externalId: string,\n syncedAt: Date,\n): Promise<FrozenAccountingSyncResult> {\n invoice.externalId = externalId;\n invoice.externalProvider = state.identity.provider;\n invoice.syncedAt = syncedAt;\n invoice.accountingSyncStateJson = JSON.stringify({\n ...state,\n status: 'synced',\n externalId,\n syncedAt: syncedAt.toISOString(),\n } satisfies FrozenSyncState);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n return {\n status: 'synced',\n externalId,\n syncedAt,\n moneySnapshotId: state.identity.moneySnapshotId,\n };\n}\n\nasync function recordSuccess(\n input: FrozenInvoicePushInput,\n prepared: PreparedSync,\n result: SyncResult,\n pilotProjection?: QuickBooksPilotProjection,\n): Promise<FrozenAccountingSyncResult> {\n requiredText(result.externalId, 'Accounting external ID');\n if (\n !(result.syncedAt instanceof Date) ||\n Number.isNaN(result.syncedAt.valueOf())\n )\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Accounting provider returned an invalid sync timestamp',\n );\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n const state = parseSyncState(invoice.accountingSyncStateJson);\n if (\n state?.status !== 'in_flight' ||\n state.attemptId !== prepared.attemptId ||\n !sameIdentity(state.identity, prepared.identity) ||\n invoice.moneySnapshotId !== prepared.identity.moneySnapshotId ||\n (state.pilot &&\n invoice.customerExternalId !== prepared.invoice.customerExternalId)\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Accounting sync ownership or frozen snapshot changed after provider write',\n );\n if (state.pilot)\n await assertUnusedPilotExternalId(\n tx,\n invoice,\n state.identity,\n result.externalId,\n );\n return saveSyncedInvoice(\n invoice,\n { ...state, pilotProjection },\n result.externalId,\n result.syncedAt,\n );\n });\n}\n\n/**\n * Push one frozen invoice exactly once per provider/realm/environment/snapshot.\n * Local and remote writes are intentionally separate phases. An unknown remote\n * outcome is persisted and requires reconciliation instead of a blind replay.\n */\nexport async function syncFrozenInvoiceToAccounting(\n input: SyncFrozenInvoiceToAccountingInput,\n): Promise<FrozenAccountingSyncResult> {\n return syncFrozenInvoice(input);\n}\n\nasync function syncFrozenInvoice(\n input: FrozenInvoicePushInput,\n pilot?: {\n acceptance: QuickBooksPilotAcceptance;\n verify(\n invoice: Invoice,\n result: SyncResult,\n ): Promise<QuickBooksPilotProjection>;\n },\n): Promise<FrozenAccountingSyncResult> {\n assertPrincipalTenant(input.tenantId);\n const prepared = await prepareSync(input, pilot?.acceptance);\n if (prepared.kind === 'unchanged') return prepared.result;\n let result: SyncResult;\n let pushReturned = false;\n let projection: QuickBooksPilotProjection | undefined;\n try {\n if (prepared.documentKind === 'invoice') {\n if (!('invoiceNumber' in prepared.accountingInput))\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Prepared invoice has the wrong accounting document kind',\n );\n result = await input.provider.invoices.push(prepared.accountingInput);\n } else {\n if (!('creditMemoNumber' in prepared.accountingInput))\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Prepared credit note has the wrong accounting document kind',\n );\n result = await requireCreditMemoOperations(input.provider).push(\n prepared.accountingInput,\n );\n }\n pushReturned = true;\n projection = await pilot?.verify(prepared.invoice, result);\n } catch (error) {\n await recordFailure(input, prepared, error, pushReturned);\n throw error;\n }\n return recordSuccess(input, prepared, result, projection);\n}\n\n/**\n * Record an authoritative QuickBooks lookup after an unknown/interrupted push.\n * The caller must first query the exact persisted request descriptor and must\n * only report `absent` when the provider confirms that no document exists.\n */\nexport async function reconcileFrozenInvoiceAccountingSync(\n input: ReconcileFrozenInvoiceAccountingInput,\n): Promise<FrozenAccountingSyncResult | FrozenAccountingReconciliationReady> {\n assertPrincipalTenant(input.tenantId);\n requiredText(input.requestId, 'Accounting request ID');\n requiredText(input.attemptId, 'Accounting attempt ID');\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n const snapshot = await loadSnapshot(tx, input.tenantId, invoice);\n const sdkInput = toSdkInput(snapshot, input.mapping);\n const { request } = prepareRequest(snapshot, input.mapping, sdkInput);\n const identity = frozenIdentity(snapshot, request);\n const state = parseSyncState(invoice.accountingSyncStateJson);\n checkPilotAcceptance(invoice, state);\n if (\n !state ||\n (state.status !== 'unknown' && state.status !== 'in_flight') ||\n state.identity.requestId !== input.requestId ||\n state.attemptId !== input.attemptId ||\n !sameIdentity(state.identity, identity)\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n 'Accounting reconciliation does not match the unresolved frozen request',\n );\n if (\n state.status === 'in_flight' &&\n input.confirmInterruptedOwnerStopped !== true\n )\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_IN_PROGRESS',\n 'Accounting reconciliation cannot release a live sync owner',\n );\n\n if (input.outcome.status === 'absent') {\n invoice.accountingSyncStateJson = JSON.stringify({\n ...state,\n status: 'rejected',\n } satisfies FrozenSyncState);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n return {\n status: 'ready',\n moneySnapshotId: identity.moneySnapshotId,\n requestId: identity.requestId,\n };\n }\n\n const externalId = requiredText(\n input.outcome.externalId,\n 'Accounting external ID',\n );\n if (\n !(input.outcome.syncedAt instanceof Date) ||\n Number.isNaN(input.outcome.syncedAt.valueOf())\n )\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Accounting reconciliation requires a valid sync timestamp',\n );\n return saveSyncedInvoice(\n invoice,\n state,\n externalId,\n input.outcome.syncedAt,\n );\n });\n}\n\n/** Read the persisted coordination state for diagnostics/reconciliation. */\nexport function readFrozenAccountingSyncState(invoice: Invoice): Readonly<{\n status: FrozenSyncStatus;\n provider: string;\n realmId: string;\n environment: string;\n moneySnapshotId: string;\n requestId: string;\n attemptId: string;\n startedAt: string;\n documentKind: 'invoice' | 'creditMemo';\n request: QuickBooksInvoiceRequest | QuickBooksCreditMemoRequest;\n pilotProjection?: QuickBooksPilotProjection;\n}> | null {\n const state = parseSyncState(invoice.accountingSyncStateJson);\n if (!state) return null;\n return {\n status: state.status,\n provider: state.identity.provider,\n realmId: state.identity.realmId,\n environment: state.identity.environment,\n documentKind: state.identity.documentKind,\n moneySnapshotId: state.identity.moneySnapshotId,\n requestId: state.identity.requestId,\n attemptId: state.attemptId,\n startedAt: state.startedAt,\n ...(state.pilotProjection\n ? { pilotProjection: state.pilotProjection }\n : {}),\n request: {\n requestId: state.identity.requestId,\n realmId: state.identity.realmId,\n environment: state.identity.environment,\n payloadHash: state.identity.payloadHash,\n ...(state.identity.documentKind === 'creditMemo'\n ? {\n creditedInvoiceExternalId: requiredText(\n state.identity.creditedInvoiceExternalId ?? '',\n 'Credited invoice external ID',\n ),\n }\n : {}),\n },\n };\n}\n\nfunction frozenIdentity(\n snapshot: FrozenInvoiceAccountingSnapshot,\n request: QuickBooksInvoiceRequest | QuickBooksCreditMemoRequest,\n): FrozenSyncIdentity {\n return {\n provider: 'quickbooks',\n documentKind: snapshot.document.kind,\n realmId: request.realmId,\n environment: request.environment,\n invoiceId: snapshot.document.id,\n moneySnapshotId: snapshot.moneySnapshotId,\n requestId: request.requestId,\n payloadHash: request.payloadHash,\n creditedInvoiceExternalId:\n 'creditedInvoiceExternalId' in request\n ? request.creditedInvoiceExternalId\n : undefined,\n };\n}\n\nfunction checkPilotAcceptance(\n invoice: Invoice,\n state: FrozenSyncState | null,\n acceptance?: QuickBooksPilotAcceptance,\n): void {\n if (acceptance && acceptance.moneySnapshotId !== invoice.moneySnapshotId)\n pilotDisagreement(\n 'QuickBooks pilot acceptance does not match the frozen invoice',\n );\n if (\n state &&\n (state.pilot?.obligationId !== acceptance?.obligationId ||\n state.pilot?.quoteVersionId !== acceptance?.quoteVersionId ||\n state.pilot?.moneySnapshotId !== acceptance?.moneySnapshotId)\n )\n pilotDisagreement(\n 'QuickBooks pilot acceptance differs from the existing reservation',\n );\n}\n\nasync function assertUnusedPilotExternalId(\n db: DatabaseInterface,\n invoice: Invoice,\n identity: FrozenSyncIdentity,\n externalId: string,\n): Promise<void> {\n const invoices = await InvoiceCollection.create({ db });\n const matches = await invoices.list({\n where: { externalId, tenantId: invoice.tenantId },\n });\n for (const other of matches) {\n if (other.id === invoice.id) continue;\n const binding = parseSyncState(other.accountingSyncStateJson);\n if (\n !binding ||\n (binding.identity.realmId === identity.realmId &&\n binding.identity.environment === identity.environment)\n )\n pilotDisagreement(\n 'QuickBooks invoice is already bound to another local invoice',\n );\n }\n}\n\n/** The pilot has a fixture transport only. No credential or SDK factory is accepted. */\nexport interface QuickBooksPilotFixture {\n readonly mode: 'fixture';\n readonly scope: QuickBooksPilotScope;\n pushInvoice(input: InvoiceInput): Promise<SyncResult>;\n readInvoice(externalId: string): Promise<QuickBooksPilotInvoiceEvidence>;\n findInvoiceForRequest?(request: QuickBooksInvoiceRequest): Promise<{\n readonly requestId: string;\n readonly payloadHash: string;\n readonly invoice: QuickBooksPilotInvoiceEvidence;\n } | null>;\n}\n\nexport type QuickBooksPilotCommand = FrozenInvoiceAccountingInput & {\n readonly acceptance: QuickBooksPilotAcceptance;\n readonly fixture: QuickBooksPilotFixture;\n} & (\n | { readonly action: 'issue' | 'poll' }\n | { readonly action: 'link'; readonly externalId: string }\n | {\n readonly action: 'recover';\n readonly confirmInterruptedOwnerStopped?: true;\n }\n );\n\nfunction assertPilotInvoice(invoice: Invoice): void {\n if (\n invoice.kind !== 'invoice' ||\n invoice.totalAmount <= 0 ||\n !invoice.customerExternalId ||\n invoice.ordinaryAccountingStateJson ||\n invoice.retentionAccountingStateJson\n )\n unsupported(\n 'QuickBooks pilot requires an ordinary positive invoice and a mapped customer',\n );\n}\n\nfunction checkPilotEvidence(\n evidence: QuickBooksPilotInvoiceEvidence,\n scope: QuickBooksPilotScope,\n externalId: string,\n invoice: Pick<\n Invoice,\n | 'customerExternalId'\n | 'currency'\n | 'subtotal'\n | 'discountTotal'\n | 'taxAmount'\n | 'totalAmount'\n | 'dueDate'\n >,\n): QuickBooksPilotProjection {\n if (\n !evidence ||\n evidence.tenantId !== scope.tenantId ||\n evidence.realmId !== scope.realmId ||\n evidence.environment !== scope.environment ||\n evidence.externalId !== externalId ||\n !invoice.customerExternalId ||\n evidence.customerExternalId !== invoice.customerExternalId ||\n evidence.currency !== invoice.currency ||\n evidence.subtotalMinor !== invoice.subtotal ||\n evidence.discountMinor !== invoice.discountTotal ||\n evidence.taxMinor !== invoice.taxAmount ||\n evidence.totalMinor !== invoice.totalAmount ||\n evidence.dueDate !== (invoice.dueDate?.toISOString().slice(0, 10) ?? null)\n )\n pilotDisagreement('QuickBooks invoice identity or frozen money differs');\n return projectQuickBooksPilotEvidence(evidence);\n}\n\n/**\n * Issue, link, recover or poll one accepted invoice using deterministic fixture\n * evidence. The trusted host authorizes the quote acceptance and manual link.\n * Every invocation revalidates the active tenant and fixture scope.\n */\nexport async function runQuickBooksPilot(\n input: QuickBooksPilotCommand,\n): Promise<QuickBooksPilotProjection> {\n assertPrincipalTenant(input.tenantId);\n const { acceptance, fixture, mapping } = input;\n if (!['issue', 'poll', 'link', 'recover'].includes(input.action))\n unsupported('Unsupported QuickBooks pilot action');\n if (\n fixture?.mode !== 'fixture' ||\n fixture.scope?.environment !== 'sandbox' ||\n mapping.environment !== 'sandbox' ||\n fixture.scope.tenantId !== input.tenantId ||\n fixture.scope.realmId !== mapping.realmId\n )\n unsupported(\n 'QuickBooks pilot requires an explicitly scoped sandbox fixture',\n );\n requiredText(mapping.realmId, 'QuickBooks realm');\n requiredText(acceptance.quoteVersionId, 'Accepted quote version');\n requiredText(acceptance.moneySnapshotId, 'Accepted money snapshot');\n const obligationId = requiredText(\n acceptance.obligationId,\n 'Accepted obligation',\n );\n if (\n input.invoiceId !==\n (await quickBooksPilotInvoiceId(input.tenantId, obligationId))\n )\n pilotDisagreement(\n 'QuickBooks pilot requires the canonical obligation invoice',\n );\n const scope = { ...fixture.scope };\n\n if (input.action === 'issue') {\n // The existing owner persists the descriptor before push and records any\n // unverifiable readback after push as an unresolved create.\n let projection: QuickBooksPilotProjection | undefined;\n await syncFrozenInvoice(\n {\n ...input,\n provider: {\n type: 'quickbooks',\n invoices: { push: (invoice) => fixture.pushInvoice(invoice) },\n },\n },\n {\n acceptance,\n async verify(invoice, result) {\n if (result.action !== 'created')\n pilotDisagreement('QuickBooks pilot did not return a new invoice');\n const id = requiredText(result.externalId, 'QuickBooks invoice ID');\n projection = checkPilotEvidence(\n await fixture.readInvoice(id),\n scope,\n id,\n invoice,\n );\n return projection;\n },\n },\n );\n if (projection) return projection;\n }\n\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n const state = parseSyncState(invoice.accountingSyncStateJson);\n checkPilotAcceptance(invoice, state, acceptance);\n assertPilotInvoice(invoice);\n const snapshot = await loadSnapshot(tx, input.tenantId, invoice);\n // Validate the original create descriptor even after a binding exists.\n const sdkInput = toSdkInput(\n {\n ...snapshot,\n document: { ...snapshot.document, externalId: undefined },\n },\n mapping,\n );\n const { request } = prepareRequest(snapshot, mapping, sdkInput);\n const identity = frozenIdentity(snapshot, request);\n if (state && !sameIdentity(state.identity, identity))\n pilotDisagreement('QuickBooks pilot binding or frozen request changed');\n\n if (state?.status === 'synced') {\n const id = requiredText(state.externalId ?? '', 'QuickBooks invoice ID');\n if (\n invoice.externalId !== id ||\n invoice.externalProvider !== 'quickbooks'\n )\n pilotDisagreement('QuickBooks pilot provider binding changed');\n if (input.action === 'link' && input.externalId !== id)\n pilotDisagreement('QuickBooks invoice already has a different binding');\n const projection = checkPilotEvidence(\n await fixture.readInvoice(id),\n scope,\n id,\n invoice,\n );\n invoice.accountingSyncStateJson = JSON.stringify({\n ...state,\n pilotProjection: projection,\n } satisfies FrozenSyncState);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n return projection;\n }\n\n let externalId: string;\n let evidence: QuickBooksPilotInvoiceEvidence;\n if (\n input.action === 'link' &&\n (!state || state.status === 'rejected') &&\n !invoice.externalId\n ) {\n externalId = requiredText(input.externalId, 'QuickBooks invoice ID');\n evidence = await fixture.readInvoice(externalId);\n } else if (\n input.action === 'recover' &&\n (state?.status === 'unknown' ||\n (state?.status === 'in_flight' &&\n input.confirmInterruptedOwnerStopped === true))\n ) {\n const match = await fixture.findInvoiceForRequest?.(request);\n if (\n !match ||\n match.requestId !== identity.requestId ||\n match.payloadHash !== identity.payloadHash\n )\n pilotDisagreement(\n 'QuickBooks create remains unresolved without verified request identity',\n );\n evidence = match.invoice;\n externalId = requiredText(evidence.externalId, 'QuickBooks invoice ID');\n } else {\n pilotDisagreement(\n 'QuickBooks pilot has no verified invoice binding for this action',\n );\n }\n\n const projection = checkPilotEvidence(evidence, scope, externalId, invoice);\n await assertUnusedPilotExternalId(tx, invoice, identity, externalId);\n await saveSyncedInvoice(\n invoice,\n {\n version: 1,\n status: 'synced',\n identity,\n attemptId: state?.attemptId ?? randomUUID(),\n startedAt: state?.startedAt ?? projection.observedAt,\n pilot: acceptance,\n pilotProjection: projection,\n },\n externalId,\n new Date(projection.observedAt),\n );\n return projection;\n });\n}\n","/** Exact, transport-neutral invoice line calculation shared by browser and server. */\nimport {\n calculateMoneyDocument,\n type MoneyLineResult,\n type MoneyTaxCodeInput,\n MoneyValidationError,\n} from '../../money.js';\n\n/** All monetary outputs are safe integer minor units. */\nexport interface InvoiceCalculatedAmounts {\n /** Rounded quantity times unit price before discounts. */\n grossMinor: number;\n /** Discount in minor units before tax; it carries the gross sign. */\n discountMinor: number;\n /** Gross less discount. */\n subtotalMinor: number;\n /** Rounded tax on the discounted subtotal. */\n taxMinor: number;\n /** Subtotal plus tax. */\n totalMinor: number;\n}\n\ninterface Decimal {\n coefficient: bigint;\n scale: bigint;\n}\n\n/** Existing model monetary inputs, independent of currency display precision. */\nexport interface InvoiceMinorLineInput {\n /** Nonnegative quantity with at most six fractional digits. */\n quantity: number;\n /** Signed integer minor units; negative prices support existing credit lines. */\n unitPrice: number;\n /** Flat discount in signed integer minor units; it carries the gross sign. */\n discount: number;\n /** Resolved tax fraction, at most eight fractional digits, in [0, 1]. */\n taxRate: number;\n}\n\nfunction numberDecimal(value: number, precision: number): Decimal {\n if (!Number.isFinite(value) || value < 0 || value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n 'Invoice rate or quantity is outside the supported range.',\n );\n // The shortest canonical decimal preserves the caller's Number. toFixed can\n // invent different decimal digits that round back to that same binary value.\n const [mantissa, exponent = '0'] = value.toString().split('e');\n const [whole, fraction = ''] = mantissa.split('.');\n const places = fraction.length - Number(exponent);\n if (places > precision)\n throw new RangeError(\n 'Invoice rate or quantity exceeds the supported decimal precision.',\n );\n const coefficient = BigInt(whole + fraction);\n return places < 0\n ? { coefficient: coefficient * 10n ** BigInt(-places), scale: 1n }\n : { coefficient, scale: 10n ** BigInt(places) };\n}\n\nfunction decimalText(value: Decimal): string {\n if (value.scale === 1n) return value.coefficient.toString();\n const places = value.scale.toString().length - 1;\n const digits = value.coefficient.toString().padStart(places + 1, '0');\n const split = digits.length - places;\n return `${digits.slice(0, split)}.${digits.slice(split)}`\n .replace(/0+$/, '')\n .replace(/\\.$/, '');\n}\n\n/** An in-memory single-rate tax code for editor previews of a percent rate. */\nfunction rateTaxCode(percent: string): MoneyTaxCodeInput {\n const normalized =\n percent\n .replace(/^0+(?=\\d)/, '')\n .replace(/(\\.\\d*?)0+$/, '$1')\n .replace(/\\.$/, '') || '0';\n return normalized === '0'\n ? { id: 'rate-zero', kind: 'zero-rated', components: [] }\n : {\n id: `rate-${normalized}`,\n kind: 'taxable',\n components: [\n {\n taxComponentId: `rate-${normalized}`,\n percent: normalized,\n compound: false,\n },\n ],\n };\n}\n\n/**\n * Exact model calculation, including existing negative-price credit lines.\n * Throws before persistence for unsafe money, invalid quantity, or invalid tax.\n */\nexport function calculateInvoiceMinorLine(\n input: InvoiceMinorLineInput,\n): InvoiceCalculatedAmounts {\n for (const amount of [input.unitPrice, input.discount])\n if (!Number.isSafeInteger(amount))\n throw new RangeError('Invoice money must be safe integer minor units.');\n if (input.taxRate > 1)\n throw new RangeError('Invoice tax rate is outside the supported range.');\n numberDecimal(input.quantity, 6);\n const tax = numberDecimal(input.taxRate, 8);\n const percent = decimalText({\n coefficient: tax.coefficient * 100n,\n scale: tax.scale,\n });\n let result: MoneyLineResult;\n try {\n result = calculateMoneyDocument({\n currency: 'USD',\n lineAmountType: 'exclusive',\n roundingScope: 'line',\n lines: [\n {\n id: 'line',\n quantity: input.quantity,\n unitPrice: input.unitPrice,\n discount:\n input.discount === 0\n ? { kind: 'none' }\n : { kind: 'amount', minor: input.discount },\n taxCode: rateTaxCode(percent),\n },\n ],\n }).lines[0];\n } catch (cause) {\n if (cause instanceof MoneyValidationError)\n throw new RangeError(cause.message, { cause });\n throw cause;\n }\n return {\n grossMinor: result.grossMinor,\n discountMinor: result.discountMinor,\n subtotalMinor: result.netMinor,\n taxMinor: result.taxMinor,\n totalMinor: result.netMinor + result.taxMinor,\n };\n}\n","/** Shared durable provider step owner; internal, never a caller-writable state API. */\nimport { randomUUID } from 'node:crypto';\nimport type {\n AccountingProvider,\n QuickBooksReceivableReadback,\n QuickBooksReceivableRequest,\n} from '@happyvertical/accounting';\nimport type { Invoice } from './models/Invoice.js';\nimport { MoneyValidationError } from './money.js';\n\ninterface ReconciliationEvidence {\n outcome: 'found' | 'absent';\n evidenceRef?: string;\n externalId?: string;\n recordedAt: string;\n interruptedOwnerStopped: boolean;\n}\nexport interface AccountingStep {\n key: string;\n status: 'in_flight' | 'unknown' | 'rejected' | 'confirmed';\n attemptId: string;\n request: QuickBooksReceivableRequest;\n startedAt: string;\n result?: QuickBooksReceivableReadback;\n reconciliation?: ReconciliationEvidence;\n priorAttempts?: {\n attemptId: string;\n status: string;\n startedAt: string;\n reconciliation?: ReconciliationEvidence;\n }[];\n}\n\nexport interface AccountingStepState {\n steps: AccountingStep[];\n}\nexport interface AccountingStepEngine<S extends AccountingStepState> {\n locked<T>(\n operation: (invoice: Invoice, state: S | null) => Promise<T>,\n ): Promise<T>;\n save(invoice: Invoice, state: S): Promise<void>;\n provider: NonNullable<AccountingProvider['receivableTransfers']>;\n}\nexport interface AccountingStepReconciliation {\n stepKey: string;\n requestId: string;\n attemptId: string;\n confirmInterruptedOwnerStopped?: true;\n outcome:\n | { status: 'found'; externalId: string }\n | { status: 'absent'; evidenceRef: string };\n}\nfunction reject(message: string): never {\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n message,\n );\n}\nfunction text(value: string, label: string) {\n if (typeof value !== 'string' || !value || value.trim() !== value)\n reject(`${label} is required`);\n}\nexport async function executeAccountingStep<S extends AccountingStepState>(\n engine: AccountingStepEngine<S>,\n key: string,\n make: (invoice: Invoice, state: S) => QuickBooksReceivableRequest,\n): Promise<QuickBooksReceivableReadback> {\n const prepared = await engine.locked(async (invoice, state) => {\n if (!state) reject('Retention provider contract is missing');\n const expected = make(invoice, state),\n prior = state.steps.find((s) => s.key === key);\n if (prior && prior.request.payloadHash !== expected.payloadHash)\n reject('Retention operation identity reused with changed facts');\n if (prior?.status === 'confirmed') {\n if (!prior.result) reject('Confirmed retention step has no readback');\n return { complete: prior.result } as const;\n }\n if (prior && prior.status !== 'rejected')\n reject('Retention operation has an unresolved remote owner');\n if (state.steps.some((s) => s.key !== key && s.status !== 'confirmed'))\n reject('Another retention operation requires reconciliation');\n const step: AccountingStep = {\n key,\n status: 'in_flight',\n attemptId: randomUUID(),\n request: expected,\n startedAt: new Date().toISOString(),\n priorAttempts: prior\n ? [\n ...(prior.priorAttempts ?? []),\n {\n attemptId: prior.attemptId,\n status: prior.status,\n startedAt: prior.startedAt,\n reconciliation: prior.reconciliation,\n },\n ]\n : [],\n };\n if (prior) state.steps[state.steps.indexOf(prior)] = step;\n else state.steps.push(step);\n await engine.save(invoice, state);\n return { step } as const;\n });\n if ('complete' in prepared && prepared.complete) return prepared.complete;\n if (!prepared.step) reject('Prepared retention step is missing');\n const step = prepared.step;\n let result: QuickBooksReceivableReadback;\n try {\n result = await engine.provider.execute(step.request);\n } catch (error) {\n await engine.locked(async (invoice, state) => {\n const current = state?.steps.find((s) => s.key === key);\n if (\n !state ||\n current?.attemptId !== step.attemptId ||\n current.status !== 'in_flight'\n )\n reject('Retention step ownership changed after remote failure');\n current.status =\n (error as { outcome?: string })?.outcome === 'rejected'\n ? 'rejected'\n : 'unknown';\n await engine.save(invoice, state);\n });\n throw error;\n }\n return engine.locked(async (invoice, state) => {\n const current = state?.steps.find((s) => s.key === key);\n if (\n !state ||\n current?.attemptId !== step.attemptId ||\n current.status !== 'in_flight' ||\n result.payloadHash !== step.request.payloadHash\n )\n reject('Retention step ownership or readback changed after write');\n current.status = 'confirmed';\n current.result = structuredClone(result);\n await engine.save(invoice, state);\n return result;\n });\n}\nexport async function reconcileAccountingStep<S extends AccountingStepState>(\n engine: AccountingStepEngine<S>,\n input: AccountingStepReconciliation,\n): Promise<S> {\n const step = await engine.locked(async (_invoice, state) => {\n const found = state?.steps.find((s) => s.key === input.stepKey);\n if (\n !found ||\n found.request.requestId !== input.requestId ||\n found.attemptId !== input.attemptId ||\n !['in_flight', 'unknown'].includes(found.status)\n )\n reject('Observed retention reconciliation owner differs');\n if (found.status === 'in_flight' && !input.confirmInterruptedOwnerStopped)\n reject('Interrupted retention owner must be proven stopped');\n return structuredClone(found);\n });\n const result =\n input.outcome.status === 'found'\n ? await engine.provider.read(step.request, input.outcome.externalId)\n : null;\n if (input.outcome.status === 'absent')\n text(input.outcome.evidenceRef, 'Authoritative provider absence evidence');\n return engine.locked(async (invoice, state) => {\n const current = state?.steps.find((s) => s.key === input.stepKey);\n if (\n !state ||\n current?.attemptId !== step.attemptId ||\n current.status !== step.status\n )\n reject('Retention reconciliation owner changed');\n current.reconciliation = {\n outcome: input.outcome.status,\n recordedAt: new Date().toISOString(),\n interruptedOwnerStopped: input.confirmInterruptedOwnerStopped === true,\n ...(input.outcome.status === 'found'\n ? { externalId: input.outcome.externalId }\n : { evidenceRef: input.outcome.evidenceRef }),\n };\n if (result) {\n if (result.payloadHash !== step.request.payloadHash)\n reject('Retention reconciliation readback differs');\n current.result = result;\n current.status = 'confirmed';\n } else current.status = 'rejected';\n await engine.save(invoice, state);\n return state;\n });\n}\n","/** Ordinary canonical receivables: exact provider credit application and already-settled refund recording. */\nimport { createHash } from 'node:crypto';\nimport {\n type AccountingProvider,\n type CreditMemoInput,\n prepareQuickBooksInvoiceRequest,\n prepareQuickBooksReceivableRequest,\n type QuickBooksOrdinaryReceivableMapping,\n type QuickBooksReceivableRequest,\n} from '@happyvertical/accounting';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport {\n type AccountingStep,\n type AccountingStepReconciliation,\n executeAccountingStep,\n reconcileAccountingStep,\n} from './accounting-steps-internal.js';\nimport { InvoiceCollection } from './collections/InvoiceCollection.js';\nimport { PaymentAllocationCollection } from './collections/PaymentAllocationCollection.js';\nimport { PaymentCollection } from './collections/PaymentCollection.js';\nimport { lockAndReloadInvoice } from './document-money.js';\nimport {\n DOCUMENT_MONEY_WRITE,\n isMoneyTransaction,\n withDocumentMoneyTransaction,\n} from './document-money-internal.js';\nimport {\n loadFrozenInvoiceAccountingSnapshot,\n type QuickBooksFrozenInvoiceMapping,\n type ReconcileFrozenInvoiceAccountingInput,\n readFrozenAccountingSyncState,\n reconcileFrozenInvoiceAccountingSync,\n syncFrozenInvoiceToAccounting,\n toFrozenInvoiceAccountingInput,\n} from './invoice-accounting-sync.js';\nimport type { Invoice } from './models/Invoice.js';\nimport { MoneyValidationError } from './money.js';\nimport { withOrdinaryAccountingAuthority } from './ordinary-accounting-internal.js';\nimport { lockTenantMoneyRuntime } from './tenant-money-barrier.js';\nimport { InvoiceStatus } from './types/index.js';\n\ntype Provider = Pick<\n AccountingProvider,\n 'type' | 'invoices' | 'creditMemos' | 'receivableTransfers'\n>;\ninterface Scope {\n db: DatabaseInterface;\n tenantId: string;\n invoiceId: string;\n provider: Provider;\n}\ninterface RefundRecording {\n paymentId: string;\n creditId: string;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n amountMinor: number;\n paymentFingerprint: string;\n committed: boolean;\n}\ninterface CreditAdjustment {\n creditId: string;\n moneySnapshotId: string;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n grossMinor: number;\n appliedMinor: number;\n mapping: QuickBooksFrozenInvoiceMapping;\n committed: boolean;\n}\n\nexport interface OrdinaryInvoiceAccountingState {\n version: 1;\n kind: 'ordinary';\n invoiceId: string;\n moneySnapshotId: string;\n externalInvoiceId: string | null;\n invoiceMapping: QuickBooksFrozenInvoiceMapping;\n requestId: string;\n evidenceRef: string;\n currency: string;\n grossMinor: number;\n mapping: QuickBooksOrdinaryReceivableMapping;\n status: 'pending' | 'ready';\n steps: AccountingStep[];\n credits: CreditAdjustment[];\n refunds: RefundRecording[];\n}\nconst hash = (value: unknown) =>\n createHash('sha256').update(JSON.stringify(value)).digest('hex');\nfunction reject(message: string): never {\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n message,\n );\n}\nfunction text(value: string, label: string) {\n if (typeof value !== 'string' || !value || value.trim() !== value)\n reject(`${label} is required`);\n}\nfunction date(value: string, label: string) {\n if (\n !/^\\d{4}-\\d{2}-\\d{2}$/.test(value) ||\n !Number.isFinite(Date.parse(value)) ||\n new Date(value).toISOString().slice(0, 10) !== value\n )\n reject(`${label} is invalid`);\n}\nfunction principal(input: Scope) {\n if (!input.tenantId || getTenantId() !== input.tenantId)\n reject('Ordinary accounting requires its active tenant');\n if (isMoneyTransaction(input.db))\n reject(\n 'Provider writes cannot run inside a caller-owned money transaction',\n );\n if (\n input.provider.type !== 'quickbooks' ||\n !input.provider.receivableTransfers\n )\n reject('Provider lacks reviewed receivable operations');\n}\nfunction syncedIdentity(\n invoice: Invoice,\n mapping: QuickBooksOrdinaryReceivableMapping,\n) {\n const sync = readFrozenAccountingSyncState(invoice);\n if (\n !sync ||\n sync.status !== 'synced' ||\n sync.documentKind !== 'invoice' ||\n sync.provider !== 'quickbooks' ||\n sync.moneySnapshotId !== invoice.moneySnapshotId ||\n sync.realmId !== mapping.realmId ||\n sync.environment !== mapping.environment ||\n invoice.externalProvider !== 'quickbooks' ||\n !invoice.externalId\n )\n reject(\n 'Ordinary accounting requires its reconciled frozen invoice export identity',\n );\n}\nexport function readOrdinaryInvoiceAccountingState(\n invoice: Invoice,\n): OrdinaryInvoiceAccountingState | null {\n if (!invoice.ordinaryAccountingStateJson) return null;\n let state: OrdinaryInvoiceAccountingState;\n try {\n state = JSON.parse(invoice.ordinaryAccountingStateJson);\n } catch {\n return reject('Malformed ordinary accounting state');\n }\n if (\n !state ||\n !state.mapping ||\n state.version !== 1 ||\n state.kind !== 'ordinary' ||\n state.mapping.kind !== 'ordinary' ||\n state.invoiceId !== invoice.id ||\n state.moneySnapshotId !== invoice.moneySnapshotId ||\n (state.externalInvoiceId !== null &&\n state.externalInvoiceId !== invoice.externalId) ||\n state.currency !== invoice.currency ||\n state.grossMinor !== invoice.totalAmount ||\n state.mapping.customerRef !== invoice.customerExternalId ||\n !Array.isArray(state.steps) ||\n !Array.isArray(state.credits) ||\n !Array.isArray(state.refunds) ||\n invoice.retentionStateJson ||\n invoice.retentionAccountingStateJson ||\n invoice.moneyAuthority !== 'calculated'\n )\n reject('Ordinary provider source identity changed');\n if (state.externalInvoiceId !== null) syncedIdentity(invoice, state.mapping);\n return state;\n}\nasync function locked<T>(\n input: Scope,\n operation: (\n invoice: Invoice,\n state: OrdinaryInvoiceAccountingState | null,\n ) => Promise<T>,\n): Promise<T> {\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n return operation(invoice, readOrdinaryInvoiceAccountingState(invoice));\n });\n}\nasync function save(invoice: Invoice, state: OrdinaryInvoiceAccountingState) {\n invoice.ordinaryAccountingStateJson = JSON.stringify(state);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n}\nfunction refreshStatus(state: OrdinaryInvoiceAccountingState) {\n state.status =\n state.steps.every((s) => s.status === 'confirmed') &&\n state.credits.every((c) => c.committed) &&\n state.refunds.every((r) => r.committed)\n ? 'ready'\n : 'pending';\n}\nfunction requireReady(\n state: OrdinaryInvoiceAccountingState | null,\n): OrdinaryInvoiceAccountingState {\n if (\n !state ||\n state.status !== 'ready' ||\n state.steps.some((s) => s.status !== 'confirmed')\n )\n reject('Ordinary provider operations require reconciliation');\n return state;\n}\nfunction requestId(state: OrdinaryInvoiceAccountingState, key: string) {\n return `smrt_ord_${hash([state.invoiceId, state.moneySnapshotId, state.mapping.realmId, state.mapping.environment, key]).slice(0, 40)}`;\n}\nfunction executeStep(\n input: Scope,\n key: string,\n make: (\n invoice: Invoice,\n state: OrdinaryInvoiceAccountingState,\n ) => QuickBooksReceivableRequest,\n) {\n return executeAccountingStep(\n {\n locked: (operation) => locked(input, operation),\n save,\n provider: input.provider.receivableTransfers!,\n },\n key,\n make,\n );\n}\nexport interface SyncOrdinaryInvoiceToAccountingInput extends Scope {\n requestId: string;\n evidenceRef: string;\n mapping: QuickBooksOrdinaryReceivableMapping;\n invoiceMapping: QuickBooksFrozenInvoiceMapping;\n}\nfunction validateOrdinarySource(\n invoice: Invoice,\n input: SyncOrdinaryInvoiceToAccountingInput,\n) {\n if (\n invoice.kind !== 'invoice' ||\n !invoice.moneySnapshotId ||\n invoice.retentionStateJson ||\n invoice.retentionAccountingStateJson ||\n invoice.moneyAuthority !== 'calculated' ||\n [\n InvoiceStatus.DRAFT,\n InvoiceStatus.CANCELLED,\n InvoiceStatus.WRITTEN_OFF,\n ].includes(invoice.status) ||\n invoice.collectionMethod ||\n invoice.providerTaxAmount ||\n invoice.currency !== input.mapping.currency ||\n invoice.customerExternalId !== input.mapping.customerRef ||\n input.invoiceMapping.realmId !== input.mapping.realmId ||\n input.invoiceMapping.environment !== input.mapping.environment\n )\n reject(\n 'Ordinary accounting requires its issued, nonretained canonical frozen source',\n );\n}\n/** Retain exact reviewed mapping before the first possible remote invoice write. */\nexport async function syncOrdinaryInvoiceToAccounting(\n input: SyncOrdinaryInvoiceToAccountingInput,\n): Promise<OrdinaryInvoiceAccountingState> {\n principal(input);\n text(input.requestId, 'Ordinary request');\n text(input.evidenceRef, 'Ordinary evidence');\n if (input.mapping.kind !== 'ordinary') reject('Ordinary mapping is required');\n await locked(input, async (invoice) => {\n validateOrdinarySource(invoice, input);\n await toFrozenInvoiceAccountingInput({\n db: invoice.db,\n tenantId: input.tenantId,\n invoiceId: input.invoiceId,\n mapping: input.invoiceMapping,\n });\n });\n await input.provider.receivableTransfers!.verifyMapping(input.mapping);\n await locked(input, async (invoice, state) => {\n validateOrdinarySource(invoice, input);\n // A generic exporter may already own this document. Compare its exact\n // prepared request while holding the same lock before retaining a mapping.\n const prior = readFrozenAccountingSyncState(invoice);\n if (prior) {\n const sdkInput = await toFrozenInvoiceAccountingInput({\n db: invoice.db,\n tenantId: input.tenantId,\n invoiceId: input.invoiceId,\n mapping: input.invoiceMapping,\n });\n // Reconstruct the original creation payload, not an update to its result.\n const request = prepareQuickBooksInvoiceRequest(\n { ...sdkInput, externalId: undefined },\n {\n requestId: prior.requestId,\n realmId: input.invoiceMapping.realmId,\n environment: input.invoiceMapping.environment,\n },\n );\n if (\n prior.provider !== 'quickbooks' ||\n prior.documentKind !== 'invoice' ||\n prior.moneySnapshotId !== invoice.moneySnapshotId ||\n prior.realmId !== request.realmId ||\n prior.environment !== request.environment ||\n prior.request.payloadHash !== request.payloadHash\n )\n reject(\n 'Ordinary invoice mapping differs from its frozen export request',\n );\n }\n if (state) {\n if (\n hash([\n state.requestId,\n state.evidenceRef,\n state.mapping,\n state.invoiceMapping,\n ]) !==\n hash([\n input.requestId,\n input.evidenceRef,\n input.mapping,\n input.invoiceMapping,\n ])\n )\n reject('Ordinary accounting initialization changed');\n return;\n }\n const next: OrdinaryInvoiceAccountingState = {\n version: 1,\n kind: 'ordinary',\n invoiceId: input.invoiceId,\n moneySnapshotId: invoice.moneySnapshotId,\n externalInvoiceId: null,\n invoiceMapping: structuredClone(input.invoiceMapping),\n requestId: input.requestId,\n evidenceRef: input.evidenceRef,\n currency: invoice.currency,\n grossMinor: invoice.totalAmount,\n mapping: structuredClone(input.mapping),\n status: 'pending',\n steps: [],\n credits: [],\n refunds: [],\n };\n await save(invoice, next);\n });\n const result = await withOrdinaryAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () =>\n syncFrozenInvoiceToAccounting({\n ...input,\n mapping: input.invoiceMapping,\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Ordinary provider reservation disappeared');\n syncedIdentity(invoice, state.mapping);\n state.externalInvoiceId = result.externalId;\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\nexport async function reconcileOrdinaryBaseInvoice(\n input: ReconcileFrozenInvoiceAccountingInput & { provider: Provider },\n) {\n principal(input);\n await locked(input, async (_invoice, state) => {\n if (!state || hash(state.invoiceMapping) !== hash(input.mapping))\n reject('Ordinary base mapping differs');\n });\n return reconcileFrozenInvoiceAccountingSync(input);\n}\nexport interface ReconcileOrdinaryAccountingStepInput\n extends Scope,\n AccountingStepReconciliation {}\nexport async function reconcileOrdinaryAccountingStep(\n input: ReconcileOrdinaryAccountingStepInput,\n): Promise<OrdinaryInvoiceAccountingState> {\n principal(input);\n return reconcileAccountingStep(\n {\n locked: (operation) => locked(input, operation),\n save,\n provider: input.provider.receivableTransfers!,\n },\n input,\n );\n}\nexport interface SyncOrdinaryCreditToAccountingInput extends Scope {\n creditInvoiceId: string;\n creditMapping: QuickBooksFrozenInvoiceMapping;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n}\n/** Apply the reserved ordinary credit amount to its original due balance. */\nexport async function syncOrdinaryCreditToAccounting(\n input: SyncOrdinaryCreditToAccountingInput,\n): Promise<OrdinaryInvoiceAccountingState> {\n principal(input);\n text(input.requestId, 'Credit adjustment request');\n text(input.evidenceRef, 'Credit adjustment evidence');\n date(input.effectiveOn, 'Credit adjustment date');\n const reserved = await locked(input, async (invoice, state) => {\n if (!state) reject('Ordinary provider contract is missing');\n const credit = await (\n await InvoiceCollection.create({ db: invoice.db })\n ).get({ id: input.creditInvoiceId }, { cache: false });\n if (\n !credit ||\n credit.tenantId !== input.tenantId ||\n credit.customerId !== invoice.customerId ||\n credit.creditedInvoiceId !== invoice.id ||\n credit.kind !== 'credit_note' ||\n !credit.moneySnapshotId ||\n [InvoiceStatus.DRAFT, InvoiceStatus.CANCELLED].includes(credit.status) ||\n credit.currency !== state.currency ||\n credit.customerExternalId !== state.mapping.customerRef\n )\n reject(\n 'Credit adjustment requires its issued same-customer source credit',\n );\n if (\n input.creditMapping.realmId !== state.mapping.realmId ||\n input.creditMapping.environment !== state.mapping.environment\n )\n reject('Credit adjustment provider scope differs');\n const prior = state.credits.find(\n (c) =>\n c.creditId === input.creditInvoiceId || c.requestId === input.requestId,\n );\n if (prior) {\n if (\n prior.creditId !== input.creditInvoiceId ||\n prior.requestId !== input.requestId ||\n prior.moneySnapshotId !== credit.moneySnapshotId ||\n prior.grossMinor !== credit.totalAmount ||\n prior.evidenceRef !== input.evidenceRef ||\n prior.effectiveOn !== input.effectiveOn ||\n hash(prior.mapping) !== hash(input.creditMapping)\n )\n reject('Credit adjustment identity reused with changed facts');\n return structuredClone(prior);\n }\n requireReady(state);\n const previousGross = state.credits.reduce(\n (sum, c) => sum + c.grossMinor,\n 0,\n );\n if (previousGross + credit.totalAmount > invoice.creditedAmount)\n reject('Provider credit exceeds issued source credit capacity');\n const next: CreditAdjustment = {\n creditId: input.creditInvoiceId,\n moneySnapshotId: credit.moneySnapshotId,\n requestId: input.requestId,\n evidenceRef: input.evidenceRef,\n effectiveOn: input.effectiveOn,\n grossMinor: credit.totalAmount,\n appliedMinor: credit.creditedAmount,\n mapping: structuredClone(input.creditMapping),\n committed: false,\n };\n state.credits.push(next);\n state.status = 'pending';\n await save(invoice, state);\n return next;\n });\n const creditResult = await withOrdinaryAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () =>\n syncFrozenInvoiceToAccounting({\n db: input.db,\n tenantId: input.tenantId,\n invoiceId: input.creditInvoiceId,\n provider: input.provider,\n mapping: input.creditMapping,\n }),\n );\n const prefix = `credit:${input.requestId}`;\n const creditSource = (state: OrdinaryInvoiceAccountingState) => ({\n type: 'CreditMemo' as const,\n id: creditResult.externalId,\n customerRef: state.mapping.customerRef,\n evidenceRef: reserved.moneySnapshotId,\n });\n if (reserved.appliedMinor > 0)\n await executeStep(input, `${prefix}:due-application`, (invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'application',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, `${prefix}:due-application`),\n effectiveOn: reserved.effectiveOn,\n evidenceRef: reserved.evidenceRef,\n amountMinor: reserved.appliedMinor,\n debit: { type: 'Invoice', id: invoice.externalId },\n credit: { type: 'CreditMemo', id: creditResult.externalId },\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Ordinary provider state is missing');\n const credit = state.credits.find(\n (c) => c.creditId === input.creditInvoiceId,\n );\n if (!credit) reject('Credit reservation disappeared');\n credit.committed = true;\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\n\nexport interface SyncOrdinaryRefundToAccountingInput extends Scope {\n paymentId: string;\n creditInvoiceId: string;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n}\n/** Record an already settled local refund and consume its existing remote credit. No bank I/O. */\nexport async function syncOrdinaryRefundToAccounting(\n input: SyncOrdinaryRefundToAccountingInput,\n): Promise<OrdinaryInvoiceAccountingState> {\n principal(input);\n text(input.requestId, 'Refund recording request');\n text(input.evidenceRef, 'Refund settlement evidence');\n date(input.effectiveOn, 'Refund effective date');\n const reservation = await locked(input, async (invoice, state) => {\n if (!state) reject('Ordinary provider contract is missing');\n const credit = state.credits.find(\n (c) => c.creditId === input.creditInvoiceId && c.committed,\n );\n if (!credit) reject('Refund requires its reconciled provider credit');\n const payments = await PaymentCollection.create({ db: invoice.db }),\n payment = await payments.get({ id: input.paymentId }, { cache: false });\n const creditInvoice = await (\n await InvoiceCollection.create({ db: invoice.db })\n ).get({ id: input.creditInvoiceId }, { cache: false });\n if (\n !payment ||\n !creditInvoice ||\n payment.tenantId !== input.tenantId ||\n creditInvoice.tenantId !== input.tenantId ||\n creditInvoice.customerId !== invoice.customerId ||\n creditInvoice.currency !== state.currency ||\n creditInvoice.creditedInvoiceId !== invoice.id ||\n payment.customerId !== invoice.customerId ||\n payment.currency !== state.currency ||\n payment.kind !== 'refund' ||\n payment.status !== 'completed' ||\n !payment.journalId ||\n !payment.paidAt ||\n new Date(payment.paidAt).toISOString().slice(0, 10) !==\n input.effectiveOn ||\n !creditInvoice.externalId ||\n creditInvoice.moneySnapshotId !== credit.moneySnapshotId\n )\n reject(\n 'Provider refund requires its completed same-customer local cash journal and source credit',\n );\n const allocations = await (\n await PaymentAllocationCollection.create({ db: invoice.db })\n ).findByPayment(input.paymentId);\n if (\n allocations.length !== 1 ||\n allocations[0].invoiceId !== input.creditInvoiceId ||\n allocations[0].amount !== payment.amount\n )\n reject(\n 'Refund recording requires one exact full source-credit allocation',\n );\n const fingerprint = hash([\n payment.id,\n payment.customerId,\n payment.currency,\n payment.amount,\n payment.journalId,\n new Date(payment.paidAt).toISOString(),\n allocations[0].id,\n allocations[0].amount,\n credit.moneySnapshotId,\n ]);\n const next: RefundRecording = {\n paymentId: input.paymentId,\n creditId: input.creditInvoiceId,\n requestId: input.requestId,\n evidenceRef: input.evidenceRef,\n effectiveOn: input.effectiveOn,\n amountMinor: payment.amount,\n paymentFingerprint: fingerprint,\n committed: false,\n };\n const prior = state.refunds.find(\n (r) => r.paymentId === input.paymentId || r.requestId === input.requestId,\n );\n if (prior) {\n if (hash({ ...prior, committed: false }) !== hash(next))\n reject('Refund recording identity reused with changed facts');\n return { ...prior, externalCreditId: creditInvoice.externalId };\n }\n requireReady(state);\n if (!state.mapping.cashAccountRef)\n reject('Refund provider bank account must be explicitly reviewed');\n const already = state.refunds\n .filter((r) => r.creditId === input.creditInvoiceId)\n .reduce((sum, r) => sum + r.amountMinor, 0);\n if (already + payment.amount > credit.grossMinor - credit.appliedMinor)\n reject('Refund exceeds unapplied provider credit capacity');\n if (\n payment.ordinaryAccountingBindingJson ||\n payment.retentionAccountingBindingJson\n )\n reject('Refund is already bound to a provider operation');\n payment.ordinaryAccountingBindingJson = JSON.stringify({\n invoiceId: input.invoiceId,\n tenantId: input.tenantId,\n requestId: input.requestId,\n paymentFingerprint: fingerprint,\n });\n await withOrdinaryAccountingAuthority(input.tenantId, input.invoiceId, () =>\n payment.save(),\n );\n state.refunds.push(next);\n state.status = 'pending';\n await save(invoice, state);\n return { ...next, externalCreditId: creditInvoice.externalId };\n });\n const prefix = `refund:${input.requestId}`;\n const creditSource = (state: OrdinaryInvoiceAccountingState) => ({\n type: 'CreditMemo' as const,\n id: reservation.externalCreditId,\n customerRef: state.mapping.customerRef,\n evidenceRef: reservation.paymentFingerprint,\n });\n const journal = await executeStep(input, prefix, (_invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'cash-refund',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, prefix),\n effectiveOn: reservation.effectiveOn,\n evidenceRef: reservation.evidenceRef,\n amountMinor: reservation.amountMinor,\n }),\n );\n await executeStep(input, `${prefix}:application`, (_invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'application',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, `${prefix}:application`),\n effectiveOn: reservation.effectiveOn,\n evidenceRef: reservation.evidenceRef,\n amountMinor: reservation.amountMinor,\n debit: { type: 'JournalEntry', id: journal.externalId },\n credit: { type: 'CreditMemo', id: reservation.externalCreditId },\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Ordinary provider state disappeared');\n const refund = state.refunds.find((r) => r.requestId === input.requestId);\n if (!refund) reject('Refund reservation disappeared');\n refund.committed = true;\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\n\nexport interface ReconcileOrdinaryCreditAccountingInput extends Scope {\n creditInvoiceId: string;\n requestId: string;\n attemptId: string;\n confirmInterruptedOwnerStopped?: true;\n outcome: ReconcileFrozenInvoiceAccountingInput['outcome'];\n}\n/** Resolve an interrupted credit-memo export before its ordinary applications resume. */\nexport async function reconcileOrdinaryCreditAccounting(\n input: ReconcileOrdinaryCreditAccountingInput,\n) {\n principal(input);\n const mapping = await locked(input, async (_invoice, state) => {\n const reserved = state?.credits.find(\n (credit) => credit.creditId === input.creditInvoiceId,\n );\n if (!reserved)\n reject('Ordinary credit has no approved provider reservation');\n return structuredClone(reserved.mapping);\n });\n return withOrdinaryAccountingAuthority(input.tenantId, input.invoiceId, () =>\n reconcileFrozenInvoiceAccountingSync({\n ...input,\n invoiceId: input.creditInvoiceId,\n mapping,\n }),\n );\n}\n\nexport interface OrdinaryCreditReviewScope {\n db: DatabaseInterface;\n tenantId: string;\n invoiceId: string;\n creditInvoiceId: string;\n}\nasync function reviewOrdinaryCredit<T>(\n input: OrdinaryCreditReviewScope,\n read: (scope: {\n db: DatabaseInterface;\n tenantId: string;\n invoiceId: string;\n }) => Promise<T>,\n): Promise<T> {\n if (getTenantId() !== input.tenantId)\n reject('Ordinary review requires its active tenant');\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n if (!readOrdinaryInvoiceAccountingState(invoice))\n reject('Ordinary provider contract is missing');\n const credit = await (await InvoiceCollection.create({ db: tx })).get(\n { id: input.creditInvoiceId },\n { cache: false },\n );\n if (\n !credit ||\n credit.tenantId !== input.tenantId ||\n credit.creditedInvoiceId !== invoice.id ||\n credit.kind !== 'credit_note' ||\n credit.customerId !== invoice.customerId ||\n credit.currency !== invoice.currency ||\n credit.moneyAuthority !== 'calculated'\n )\n reject('Ordinary credit review requires exact source lineage');\n return withOrdinaryAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () =>\n read({\n db: tx,\n tenantId: input.tenantId,\n invoiceId: input.creditInvoiceId,\n }),\n );\n });\n}\nexport function loadOrdinaryCreditAccountingSnapshot(\n input: OrdinaryCreditReviewScope,\n) {\n return reviewOrdinaryCredit(input, loadFrozenInvoiceAccountingSnapshot);\n}\nexport function toOrdinaryCreditAccountingInput(\n input: OrdinaryCreditReviewScope & {\n mapping: QuickBooksFrozenInvoiceMapping;\n },\n): Promise<CreditMemoInput> {\n return reviewOrdinaryCredit(\n input,\n async (scope) =>\n (await toFrozenInvoiceAccountingInput({\n ...scope,\n mapping: input.mapping,\n })) as unknown as CreditMemoInput,\n );\n}\n","/** Durable retained-invoice provider orchestration. Every remote write is a separate recoverable step. */\nimport { createHash } from 'node:crypto';\nimport {\n type AccountingProvider,\n type CreditMemoInput,\n prepareQuickBooksReceivableRequest,\n type QuickBooksReceivableMapping,\n type QuickBooksReceivableReadback,\n type QuickBooksReceivableRequest,\n} from '@happyvertical/accounting';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport { mapFrozenAccountingSnapshot } from './accounting-snapshot.js';\nimport {\n type AccountingStep,\n executeAccountingStep,\n reconcileAccountingStep,\n} from './accounting-steps-internal.js';\nimport { InvoiceCollection } from './collections/InvoiceCollection.js';\nimport { PaymentAllocationCollection } from './collections/PaymentAllocationCollection.js';\nimport { PaymentCollection } from './collections/PaymentCollection.js';\nimport { lockAndReloadInvoice } from './document-money.js';\nimport {\n DOCUMENT_MONEY_WRITE,\n isMoneyTransaction,\n withDocumentMoneyTransaction,\n} from './document-money-internal.js';\nimport {\n type FrozenInvoiceAccountingInput,\n loadFrozenInvoiceAccountingSnapshot,\n type QuickBooksFrozenInvoiceMapping,\n type ReconcileFrozenInvoiceAccountingInput,\n reconcileFrozenInvoiceAccountingSync,\n syncFrozenInvoiceToAccounting,\n toFrozenInvoiceAccountingInput,\n} from './invoice-accounting-sync.js';\nimport type { Invoice } from './models/Invoice.js';\nimport { MoneyValidationError } from './money.js';\nimport { withRetentionAccountingAuthority } from './retention-accounting-internal.js';\nimport {\n calculateInvoicePayable,\n type InvoiceRetentionEvidence,\n parseInvoiceRetention,\n validateRetentionEvidence,\n} from './retention-money.js';\nimport { lockTenantMoneyRuntime } from './tenant-money-barrier.js';\nimport { type AccountingInvoiceInput, InvoiceStatus } from './types/index.js';\n\ntype Provider = Pick<\n AccountingProvider,\n 'type' | 'invoices' | 'creditMemos' | 'receivableTransfers'\n>;\ninterface Scope {\n db: DatabaseInterface;\n tenantId: string;\n invoiceId: string;\n provider: Provider;\n}\ninterface RefundRecording {\n paymentId: string;\n creditId: string;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n amountMinor: number;\n paymentFingerprint: string;\n committed: boolean;\n}\ninterface CreditAdjustment {\n creditId: string;\n moneySnapshotId: string;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n grossMinor: number;\n retainedMinor: number;\n appliedMinor: number;\n mapping: QuickBooksFrozenInvoiceMapping;\n committed: boolean;\n}\ninterface Release extends InvoiceRetentionEvidence {\n amountMinor: number;\n effectiveOn: string;\n dueOn: string;\n stepKey: string;\n committed: boolean;\n}\nexport interface RetainedInvoiceAccountingState {\n version: 1;\n invoiceId: string;\n moneySnapshotId: string;\n requestId: string;\n evidenceRef: string;\n currency: string;\n grossMinor: number;\n retainedMinor: number;\n retentionAgreementHash: string;\n effectiveOn: string;\n mapping: QuickBooksReceivableMapping;\n invoiceMapping: QuickBooksFrozenInvoiceMapping;\n status: 'pending' | 'ready';\n steps: AccountingStep[];\n releases: Release[];\n credits: CreditAdjustment[];\n refunds: RefundRecording[];\n}\nexport interface SyncRetainedInvoiceToAccountingInput extends Scope {\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n mapping: QuickBooksReceivableMapping;\n invoiceMapping: QuickBooksFrozenInvoiceMapping;\n}\nexport interface ReleaseRetainedInvoiceToAccountingInput\n extends Scope,\n InvoiceRetentionEvidence {\n amountMinor: number;\n effectiveOn: string;\n dueOn: string;\n expectedUpdatedAt: string;\n}\nconst hash = (value: unknown) =>\n createHash('sha256').update(JSON.stringify(value)).digest('hex');\nfunction reject(message: string): never {\n throw new MoneyValidationError(\n 'ACCOUNTING_SYNC_RECONCILIATION_REQUIRED',\n message,\n );\n}\nfunction text(value: string, label: string) {\n if (typeof value !== 'string' || !value || value.trim() !== value)\n reject(`${label} is required`);\n}\nfunction date(value: string, label: string) {\n if (\n !/^\\d{4}-\\d{2}-\\d{2}$/.test(value) ||\n !Number.isFinite(Date.parse(value)) ||\n new Date(value).toISOString().slice(0, 10) !== value\n )\n reject(`${label} is invalid`);\n}\nfunction principal(input: Scope) {\n if (!input.tenantId || getTenantId() !== input.tenantId)\n reject('Retention accounting requires its active tenant');\n if (isMoneyTransaction(input.db))\n reject(\n 'Provider writes cannot run inside a caller-owned money transaction',\n );\n if (\n input.provider.type !== 'quickbooks' ||\n !input.provider.receivableTransfers\n )\n reject('Provider lacks the reviewed receivable transfer capability');\n}\nexport function readRetainedInvoiceAccountingState(\n invoice: Invoice,\n): RetainedInvoiceAccountingState | null {\n if (!invoice.retentionAccountingStateJson) return null;\n let state: RetainedInvoiceAccountingState;\n try {\n state = JSON.parse(invoice.retentionAccountingStateJson);\n } catch {\n return reject('Malformed retained accounting state');\n }\n if (\n state.version !== 1 ||\n state.invoiceId !== invoice.id ||\n state.moneySnapshotId !== invoice.moneySnapshotId ||\n state.currency !== invoice.currency ||\n state.grossMinor !== invoice.totalAmount ||\n state.mapping.customerRef !== invoice.customerExternalId ||\n !Array.isArray(state.steps) ||\n !Array.isArray(state.releases) ||\n !Array.isArray(state.credits) ||\n !Array.isArray(state.refunds)\n )\n reject('Retention provider source identity changed');\n const retention = parseInvoiceRetention(invoice.retentionStateJson);\n if (!retention) reject('Provider retention agreement is missing');\n const { releases: _releases, ...agreement } = retention;\n if (state.retentionAgreementHash !== hash(agreement))\n reject('Provider retention agreement changed');\n return state;\n}\n/** Read-only review of the exact retained document; generic export stays blocked.\n * The host supplies authorization, and every read stays on the caller's executor.\n */\nexport async function loadRetainedInvoiceAccountingSnapshot(\n input: Omit<FrozenInvoiceAccountingInput, 'mapping'>,\n) {\n if (!input.tenantId || getTenantId() !== input.tenantId)\n reject('Retained accounting review requires its active tenant');\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n const retention = parseInvoiceRetention(invoice.retentionStateJson);\n if (\n !retention ||\n retention.retainedMinor <= 0 ||\n invoice.kind !== 'invoice' ||\n invoice.moneyAuthority === 'historical'\n )\n reject(\n 'Retained accounting review requires a calculated retained invoice',\n );\n readRetainedInvoiceAccountingState(invoice);\n return withRetentionAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () => loadFrozenInvoiceAccountingSnapshot({ ...input, db: tx }),\n );\n });\n}\n/** Validate reviewed realm item/tax mapping without creating a provider operation. */\nexport async function toRetainedInvoiceAccountingInput(\n input: FrozenInvoiceAccountingInput,\n) {\n const snapshot = await loadRetainedInvoiceAccountingSnapshot(input);\n return mapFrozenAccountingSnapshot(\n snapshot.document,\n input.mapping,\n ) as AccountingInvoiceInput;\n}\ntype RetainedCreditReviewScope = Omit<\n FrozenInvoiceAccountingInput,\n 'mapping'\n> & {\n creditInvoiceId: string;\n};\nasync function reviewRetainedCredit<T>(\n input: RetainedCreditReviewScope,\n read: (scope: Omit<FrozenInvoiceAccountingInput, 'mapping'>) => Promise<T>,\n): Promise<T> {\n if (!input.tenantId || getTenantId() !== input.tenantId)\n reject('Retained credit review requires its active tenant');\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n // The existing owning reader proves the original calculated retained invoice.\n const original = await loadRetainedInvoiceAccountingSnapshot({\n ...input,\n db: tx,\n });\n const { invoice: credit } = await lockAndReloadInvoice(\n tx,\n input.creditInvoiceId,\n input.tenantId,\n );\n if (\n credit.kind !== 'credit_note' ||\n credit.creditedInvoiceId !== input.invoiceId ||\n credit.customerId !== original.document.customerId ||\n credit.currency !== original.document.currency ||\n credit.moneyAuthority === 'historical'\n )\n reject(\n 'Retained credit review requires its exact calculated source lineage',\n );\n return withRetentionAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () =>\n read({\n db: tx,\n tenantId: input.tenantId,\n invoiceId: input.creditInvoiceId,\n }),\n );\n });\n}\n/** Read an issued retained-first credit without permitting generic credit export. */\nexport function loadRetainedCreditAccountingSnapshot(\n input: RetainedCreditReviewScope,\n) {\n return reviewRetainedCredit(input, loadFrozenInvoiceAccountingSnapshot);\n}\n/** Map a retained-first credit using the existing frozen reader's realm/lineage checks. */\nexport function toRetainedCreditAccountingInput(\n input: RetainedCreditReviewScope & {\n mapping: QuickBooksFrozenInvoiceMapping;\n },\n): Promise<CreditMemoInput> {\n return reviewRetainedCredit(input, async (scope) => {\n // The owning review above proves credit_note; the legacy generic converter's\n // return declaration names InvoiceInput for both runtime document variants.\n return (await toFrozenInvoiceAccountingInput({\n ...scope,\n mapping: input.mapping,\n })) as unknown as CreditMemoInput;\n });\n}\n\nasync function locked<T>(\n input: Scope,\n operation: (\n invoice: Invoice,\n state: RetainedInvoiceAccountingState | null,\n ) => Promise<T>,\n): Promise<T> {\n return withDocumentMoneyTransaction(input.db, async (tx) => {\n await lockTenantMoneyRuntime(tx, input.tenantId);\n const { invoice } = await lockAndReloadInvoice(\n tx,\n input.invoiceId,\n input.tenantId,\n );\n return operation(invoice, readRetainedInvoiceAccountingState(invoice));\n });\n}\nasync function save(invoice: Invoice, state: RetainedInvoiceAccountingState) {\n invoice.retentionAccountingStateJson = JSON.stringify(state);\n await invoice.saveDerived(DOCUMENT_MONEY_WRITE);\n}\nfunction refreshStatus(state: RetainedInvoiceAccountingState) {\n state.status =\n state.steps.every((step) => step.status === 'confirmed') &&\n state.releases.every((event) => event.committed) &&\n state.credits.every((event) => event.committed) &&\n state.refunds.every((event) => event.committed)\n ? 'ready'\n : 'pending';\n}\nfunction requireReady(\n state: RetainedInvoiceAccountingState | null,\n): RetainedInvoiceAccountingState {\n if (\n !state ||\n state.status !== 'ready' ||\n state.steps.some((s) => s.status !== 'confirmed')\n )\n reject(\n 'Retention provider bundle requires reconciliation before a new operation',\n );\n return state;\n}\nfunction requestId(state: RetainedInvoiceAccountingState, key: string) {\n return `smrt_ret_${hash([state.invoiceId, state.moneySnapshotId, state.mapping.realmId, state.mapping.environment, key]).slice(0, 40)}`;\n}\nfunction source(invoice: Invoice, state: RetainedInvoiceAccountingState) {\n if (!invoice.externalId || invoice.externalProvider !== 'quickbooks')\n reject('Retention needs a reconciled provider invoice');\n return {\n type: 'Invoice' as const,\n id: invoice.externalId,\n customerRef: state.mapping.customerRef,\n evidenceRef: state.moneySnapshotId,\n };\n}\nasync function executeStep(\n input: Scope,\n key: string,\n make: (\n invoice: Invoice,\n state: RetainedInvoiceAccountingState,\n ) => QuickBooksReceivableRequest,\n) {\n return executeAccountingStep(\n {\n locked: (operation) => locked(input, operation),\n save,\n provider: input.provider.receivableTransfers!,\n },\n key,\n make,\n );\n}\n/** Export unchanged gross/tax, then reclassify and apply its exact retained amount. */\nexport async function syncRetainedInvoiceToAccounting(\n input: SyncRetainedInvoiceToAccountingInput,\n): Promise<RetainedInvoiceAccountingState> {\n principal(input);\n text(input.requestId, 'Retention request');\n text(input.evidenceRef, 'Retention evidence');\n date(input.effectiveOn, 'Retention effective date');\n await input.provider.receivableTransfers!.verifyMapping(input.mapping);\n await locked(input, async (invoice, state) => {\n if (\n input.mapping.realmId !== input.invoiceMapping.realmId ||\n input.mapping.environment !== input.invoiceMapping.environment ||\n input.mapping.currency !== invoice.currency ||\n input.mapping.customerRef !== invoice.customerExternalId\n )\n reject(\n 'Retention mapping differs from frozen invoice provider authority',\n );\n if (state) {\n if (\n hash([\n state.requestId,\n state.evidenceRef,\n state.effectiveOn,\n state.mapping,\n state.invoiceMapping,\n ]) !==\n hash([\n input.requestId,\n input.evidenceRef,\n input.effectiveOn,\n input.mapping,\n input.invoiceMapping,\n ])\n )\n reject('Retention provider contract is immutable');\n return;\n }\n if ('moneyAuthority' in invoice && invoice.moneyAuthority === 'historical')\n reject(\n 'Historical source-owned invoices require an explicit reconciled provider authority contract; original journals cannot be duplicated',\n );\n const retention = parseInvoiceRetention(invoice.retentionStateJson);\n if (\n !retention ||\n retention.retainedMinor <= 0 ||\n retention.releases.length ||\n invoice.creditedAmount ||\n invoice.amountPaid ||\n !invoice.moneySnapshotId ||\n invoice.kind !== 'invoice' ||\n [\n InvoiceStatus.DRAFT,\n InvoiceStatus.CANCELLED,\n InvoiceStatus.WRITTEN_OFF,\n ].includes(invoice.status) ||\n invoice.externalId ||\n invoice.externalProvider ||\n invoice.accountingSyncStateJson ||\n invoice.collectionMethod ||\n invoice.providerTaxAmount\n )\n reject(\n 'Initial provider retention requires an issued, uncredited, unpaid, unreleased host-owned retained invoice',\n );\n const { releases: _releases, ...agreement } = retention;\n state = {\n version: 1,\n invoiceId: input.invoiceId,\n moneySnapshotId: invoice.moneySnapshotId,\n requestId: input.requestId,\n evidenceRef: input.evidenceRef,\n effectiveOn: input.effectiveOn,\n currency: invoice.currency,\n grossMinor: invoice.totalAmount,\n retainedMinor: retention.retainedMinor,\n retentionAgreementHash: hash(agreement),\n mapping: structuredClone(input.mapping),\n invoiceMapping: structuredClone(input.invoiceMapping),\n status: 'pending',\n steps: [],\n releases: [],\n credits: [],\n refunds: [],\n };\n await save(invoice, state);\n });\n await withRetentionAccountingAuthority(input.tenantId, input.invoiceId, () =>\n syncFrozenInvoiceToAccounting({ ...input, mapping: input.invoiceMapping }),\n );\n const withheld = await executeStep(input, 'withhold', (invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'withhold',\n mapping: state.mapping,\n source: source(invoice, state),\n requestId: requestId(state, 'withhold'),\n effectiveOn: state.effectiveOn,\n evidenceRef: state.evidenceRef,\n amountMinor: state.retainedMinor,\n }),\n );\n await executeStep(input, 'withhold-application', (invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'application',\n mapping: state.mapping,\n source: source(invoice, state),\n requestId: requestId(state, 'withhold-application'),\n effectiveOn: state.effectiveOn,\n evidenceRef: state.evidenceRef,\n amountMinor: state.retainedMinor,\n debit: { type: 'Invoice', id: invoice.externalId },\n credit: { type: 'JournalEntry', id: withheld.externalId },\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Missing retained provider state');\n if (\n state.steps.some((step) => step.status !== 'confirmed') ||\n state.releases.some((release) => !release.committed)\n )\n reject('Another retention operation is unfinished');\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\n/** Release date is provider TxnDate; dueOn remains explicit host collection policy. */\nexport async function releaseRetainedInvoiceToAccounting(\n input: ReleaseRetainedInvoiceToAccountingInput,\n): Promise<RetainedInvoiceAccountingState> {\n principal(input);\n validateRetentionEvidence(input);\n date(input.effectiveOn, 'Release effective date');\n date(input.dueOn, 'Release due date');\n if (!Number.isSafeInteger(input.amountMinor) || input.amountMinor <= 0)\n reject('Release amount or due date is invalid');\n const key = `release:${input.requestId}`;\n await locked(input, async (invoice, state) => {\n if (!state) reject('Retention provider contract is missing');\n const prior = state.releases.find((r) => r.requestId === input.requestId);\n const release: Release = {\n requestId: input.requestId,\n policyVersion: input.policyVersion,\n evidenceRef: input.evidenceRef,\n actorId: input.actorId,\n reason: input.reason,\n amountMinor: input.amountMinor,\n effectiveOn: input.effectiveOn,\n dueOn: input.dueOn,\n stepKey: key,\n committed: false,\n };\n if (prior) {\n if (hash({ ...prior, committed: false }) !== hash(release))\n reject('Release request identity reused with changed facts');\n return;\n }\n requireReady(state);\n if (\n !invoice.updated_at ||\n new Date(invoice.updated_at).toISOString() !==\n new Date(input.expectedUpdatedAt).toISOString()\n )\n reject('Stale retention release revision');\n if (\n invoice.creditedAmount !==\n state.credits\n .filter((c) => c.committed)\n .reduce((sum, c) => sum + c.grossMinor, 0)\n )\n reject(\n 'Provider retention credit adjustment must reconcile before release',\n );\n if (\n input.amountMinor >\n calculateInvoicePayable(invoice).retainedRemainingMinor\n )\n reject('Release exceeds retained capacity');\n state.releases.push(release);\n state.status = 'pending';\n await save(invoice, state);\n });\n await executeStep(input, key, (invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'release',\n mapping: state.mapping,\n source: source(invoice, state),\n requestId: requestId(state, key),\n effectiveOn: input.effectiveOn,\n evidenceRef: input.evidenceRef,\n amountMinor: input.amountMinor,\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Retention provider contract is missing');\n const release = state.releases.find((r) => r.requestId === input.requestId);\n if (!release) reject('Release reservation disappeared');\n if (!release.committed) {\n if (\n invoice.creditedAmount !==\n state.credits\n .filter((c) => c.committed)\n .reduce((sum, c) => sum + c.grossMinor, 0) ||\n input.amountMinor >\n calculateInvoicePayable(invoice).retainedRemainingMinor\n )\n reject(\n 'Source capacity changed after provider release; reconciliation required',\n );\n const retention = parseInvoiceRetention(invoice.retentionStateJson)!;\n retention.releases.push({\n requestId: release.requestId,\n policyVersion: release.policyVersion,\n evidenceRef: release.evidenceRef,\n actorId: release.actorId,\n reason: release.reason,\n amountMinor: release.amountMinor,\n effectiveOn: release.effectiveOn,\n recordedAt: new Date().toISOString(),\n });\n invoice.retentionStateJson = JSON.stringify(retention);\n release.committed = true;\n }\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\nexport interface ReconcileRetainedAccountingStepInput extends Scope {\n stepKey: string;\n requestId: string;\n attemptId: string;\n confirmInterruptedOwnerStopped?: true;\n outcome:\n | { status: 'found'; externalId: string }\n | { status: 'absent'; evidenceRef: string };\n}\n/** Unknown remote outcomes never reset on a guessed absence or an unobserved owner. */\nexport async function reconcileRetainedAccountingStep(\n input: ReconcileRetainedAccountingStepInput,\n): Promise<RetainedInvoiceAccountingState> {\n principal(input);\n return reconcileAccountingStep(\n {\n locked: (operation) => locked(input, operation),\n save,\n provider: input.provider.receivableTransfers!,\n },\n input,\n );\n}\n/** Reconcile the existing frozen invoice step using its established owner proof. */\nexport async function reconcileRetainedBaseInvoice(\n input: ReconcileFrozenInvoiceAccountingInput & { provider: Provider },\n) {\n principal(input);\n await locked(input, async (_invoice, state) => {\n if (!state || hash(state.invoiceMapping) !== hash(input.mapping))\n reject('Retention base mapping differs');\n });\n return withRetentionAccountingAuthority(input.tenantId, input.invoiceId, () =>\n reconcileFrozenInvoiceAccountingSync(input),\n );\n}\n\nexport interface SyncRetainedCreditToAccountingInput extends Scope {\n creditInvoiceId: string;\n creditMapping: QuickBooksFrozenInvoiceMapping;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n}\n/** Apply retained-first credit to the retained asset, then to the original due balance. */\nexport async function syncRetainedCreditToAccounting(\n input: SyncRetainedCreditToAccountingInput,\n): Promise<RetainedInvoiceAccountingState> {\n principal(input);\n text(input.requestId, 'Credit adjustment request');\n text(input.evidenceRef, 'Credit adjustment evidence');\n date(input.effectiveOn, 'Credit adjustment date');\n const reserved = await locked(input, async (invoice, state) => {\n if (!state) reject('Retention provider contract is missing');\n const credit = await (\n await InvoiceCollection.create({ db: invoice.db })\n ).get({ id: input.creditInvoiceId }, { cache: false });\n if (\n !credit ||\n credit.tenantId !== input.tenantId ||\n credit.creditedInvoiceId !== invoice.id ||\n credit.kind !== 'credit_note' ||\n !credit.moneySnapshotId ||\n [InvoiceStatus.DRAFT, InvoiceStatus.CANCELLED].includes(credit.status) ||\n credit.currency !== state.currency ||\n credit.customerExternalId !== state.mapping.customerRef\n )\n reject(\n 'Credit adjustment requires its issued same-customer source credit',\n );\n if (\n input.creditMapping.realmId !== state.mapping.realmId ||\n input.creditMapping.environment !== state.mapping.environment\n )\n reject('Credit adjustment provider scope differs');\n const prior = state.credits.find(\n (c) =>\n c.creditId === input.creditInvoiceId || c.requestId === input.requestId,\n );\n if (prior) {\n if (\n prior.creditId !== input.creditInvoiceId ||\n prior.requestId !== input.requestId ||\n prior.moneySnapshotId !== credit.moneySnapshotId ||\n prior.grossMinor !== credit.totalAmount ||\n prior.evidenceRef !== input.evidenceRef ||\n prior.effectiveOn !== input.effectiveOn ||\n hash(prior.mapping) !== hash(input.creditMapping)\n )\n reject('Credit adjustment identity reused with changed facts');\n return structuredClone(prior);\n }\n requireReady(state);\n const previousGross = state.credits.reduce(\n (sum, c) => sum + c.grossMinor,\n 0,\n );\n if (previousGross + credit.totalAmount > invoice.creditedAmount)\n reject('Provider credit exceeds issued source credit capacity');\n const remainingRetained =\n state.retainedMinor -\n state.releases\n .filter((r) => r.committed)\n .reduce((sum, r) => sum + r.amountMinor, 0) -\n state.credits.reduce((sum, c) => sum + c.retainedMinor, 0);\n const retainedMinor = Math.min(remainingRetained, credit.totalAmount);\n if (retainedMinor < 0 || retainedMinor > credit.creditedAmount)\n reject('Retained-first credit exceeds its approved source allocation');\n const next: CreditAdjustment = {\n creditId: input.creditInvoiceId,\n moneySnapshotId: credit.moneySnapshotId,\n requestId: input.requestId,\n evidenceRef: input.evidenceRef,\n effectiveOn: input.effectiveOn,\n grossMinor: credit.totalAmount,\n retainedMinor,\n appliedMinor: credit.creditedAmount - retainedMinor,\n mapping: structuredClone(input.creditMapping),\n committed: false,\n };\n state.credits.push(next);\n state.status = 'pending';\n await save(invoice, state);\n return next;\n });\n const creditResult = await withRetentionAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () =>\n syncFrozenInvoiceToAccounting({\n db: input.db,\n tenantId: input.tenantId,\n invoiceId: input.creditInvoiceId,\n provider: input.provider,\n mapping: input.creditMapping,\n }),\n );\n const prefix = `credit:${input.requestId}`;\n const creditSource = (state: RetainedInvoiceAccountingState) => ({\n type: 'CreditMemo' as const,\n id: creditResult.externalId,\n customerRef: state.mapping.customerRef,\n evidenceRef: reserved.moneySnapshotId,\n });\n if (reserved.retainedMinor > 0) {\n const cancelled = await executeStep(\n input,\n `${prefix}:retention`,\n (_invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'release',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, `${prefix}:retention`),\n effectiveOn: reserved.effectiveOn,\n evidenceRef: reserved.evidenceRef,\n amountMinor: reserved.retainedMinor,\n }),\n );\n await executeStep(\n input,\n `${prefix}:retention-application`,\n (_invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'application',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, `${prefix}:retention-application`),\n effectiveOn: reserved.effectiveOn,\n evidenceRef: reserved.evidenceRef,\n amountMinor: reserved.retainedMinor,\n debit: { type: 'JournalEntry', id: cancelled.externalId },\n credit: { type: 'CreditMemo', id: creditResult.externalId },\n }),\n );\n }\n if (reserved.appliedMinor > 0)\n await executeStep(input, `${prefix}:due-application`, (invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'application',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, `${prefix}:due-application`),\n effectiveOn: reserved.effectiveOn,\n evidenceRef: reserved.evidenceRef,\n amountMinor: reserved.appliedMinor,\n debit: { type: 'Invoice', id: invoice.externalId },\n credit: { type: 'CreditMemo', id: creditResult.externalId },\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Retention provider state is missing');\n const credit = state.credits.find(\n (c) => c.creditId === input.creditInvoiceId,\n );\n if (!credit) reject('Credit reservation disappeared');\n credit.committed = true;\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\n\nexport interface SyncRetainedRefundToAccountingInput extends Scope {\n paymentId: string;\n creditInvoiceId: string;\n requestId: string;\n evidenceRef: string;\n effectiveOn: string;\n}\n/** Record an already settled local refund and consume its existing remote credit. No bank I/O. */\nexport async function syncRetainedRefundToAccounting(\n input: SyncRetainedRefundToAccountingInput,\n): Promise<RetainedInvoiceAccountingState> {\n principal(input);\n text(input.requestId, 'Refund recording request');\n text(input.evidenceRef, 'Refund settlement evidence');\n date(input.effectiveOn, 'Refund effective date');\n const reservation = await locked(input, async (invoice, state) => {\n if (!state) reject('Retention provider contract is missing');\n const credit = state.credits.find(\n (c) => c.creditId === input.creditInvoiceId && c.committed,\n );\n if (!credit) reject('Refund requires its reconciled provider credit');\n const payments = await PaymentCollection.create({ db: invoice.db }),\n payment = await payments.get({ id: input.paymentId }, { cache: false });\n const creditInvoice = await (\n await InvoiceCollection.create({ db: invoice.db })\n ).get({ id: input.creditInvoiceId }, { cache: false });\n if (\n !payment ||\n !creditInvoice ||\n payment.tenantId !== input.tenantId ||\n payment.customerId !== invoice.customerId ||\n payment.currency !== state.currency ||\n payment.kind !== 'refund' ||\n payment.status !== 'completed' ||\n !payment.journalId ||\n !payment.paidAt ||\n !creditInvoice.externalId ||\n creditInvoice.moneySnapshotId !== credit.moneySnapshotId\n )\n reject(\n 'Provider refund requires its completed same-customer local cash journal and source credit',\n );\n const allocations = await (\n await PaymentAllocationCollection.create({ db: invoice.db })\n ).findByPayment(input.paymentId);\n if (\n allocations.length !== 1 ||\n allocations[0].invoiceId !== input.creditInvoiceId ||\n allocations[0].amount !== payment.amount\n )\n reject(\n 'Refund recording requires one exact full source-credit allocation',\n );\n const fingerprint = hash([\n payment.id,\n payment.customerId,\n payment.currency,\n payment.amount,\n payment.journalId,\n new Date(payment.paidAt).toISOString(),\n allocations[0].id,\n allocations[0].amount,\n credit.moneySnapshotId,\n ]);\n const next: RefundRecording = {\n paymentId: input.paymentId,\n creditId: input.creditInvoiceId,\n requestId: input.requestId,\n evidenceRef: input.evidenceRef,\n effectiveOn: input.effectiveOn,\n amountMinor: payment.amount,\n paymentFingerprint: fingerprint,\n committed: false,\n };\n const prior = state.refunds.find(\n (r) => r.paymentId === input.paymentId || r.requestId === input.requestId,\n );\n if (prior) {\n if (hash({ ...prior, committed: false }) !== hash(next))\n reject('Refund recording identity reused with changed facts');\n return { ...prior, externalCreditId: creditInvoice.externalId };\n }\n requireReady(state);\n if (!state.mapping.cashAccountRef)\n reject('Refund provider bank account must be explicitly reviewed');\n const already = state.refunds\n .filter((r) => r.creditId === input.creditInvoiceId)\n .reduce((sum, r) => sum + r.amountMinor, 0);\n if (\n already + payment.amount >\n credit.grossMinor - credit.retainedMinor - credit.appliedMinor\n )\n reject('Refund exceeds unapplied provider credit capacity');\n if (payment.retentionAccountingBindingJson)\n reject('Refund is already bound to a provider operation');\n payment.retentionAccountingBindingJson = JSON.stringify({\n invoiceId: input.invoiceId,\n tenantId: input.tenantId,\n requestId: input.requestId,\n paymentFingerprint: fingerprint,\n });\n await withRetentionAccountingAuthority(\n input.tenantId,\n input.invoiceId,\n () => payment.save(),\n );\n state.refunds.push(next);\n state.status = 'pending';\n await save(invoice, state);\n return { ...next, externalCreditId: creditInvoice.externalId };\n });\n const prefix = `refund:${input.requestId}`;\n const creditSource = (state: RetainedInvoiceAccountingState) => ({\n type: 'CreditMemo' as const,\n id: reservation.externalCreditId,\n customerRef: state.mapping.customerRef,\n evidenceRef: reservation.paymentFingerprint,\n });\n const journal = await executeStep(input, prefix, (_invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'cash-refund',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, prefix),\n effectiveOn: reservation.effectiveOn,\n evidenceRef: reservation.evidenceRef,\n amountMinor: reservation.amountMinor,\n }),\n );\n await executeStep(input, `${prefix}:application`, (_invoice, state) =>\n prepareQuickBooksReceivableRequest({\n kind: 'application',\n mapping: state.mapping,\n source: creditSource(state),\n requestId: requestId(state, `${prefix}:application`),\n effectiveOn: reservation.effectiveOn,\n evidenceRef: reservation.evidenceRef,\n amountMinor: reservation.amountMinor,\n debit: { type: 'JournalEntry', id: journal.externalId },\n credit: { type: 'CreditMemo', id: reservation.externalCreditId },\n }),\n );\n return locked(input, async (invoice, state) => {\n if (!state) reject('Retention provider state disappeared');\n const refund = state.refunds.find((r) => r.requestId === input.requestId);\n if (!refund) reject('Refund reservation disappeared');\n refund.committed = true;\n refreshStatus(state);\n await save(invoice, state);\n return state;\n });\n}\n\nexport interface ReconcileRetainedCreditAccountingInput extends Scope {\n creditInvoiceId: string;\n requestId: string;\n attemptId: string;\n confirmInterruptedOwnerStopped?: true;\n outcome: ReconcileFrozenInvoiceAccountingInput['outcome'];\n}\n/** Resolve an interrupted credit-memo export before its retained-first applications resume. */\nexport async function reconcileRetainedCreditAccounting(\n input: ReconcileRetainedCreditAccountingInput,\n) {\n principal(input);\n const mapping = await locked(input, async (_invoice, state) => {\n const reserved = state?.credits.find(\n (credit) => credit.creditId === input.creditInvoiceId,\n );\n if (!reserved)\n reject('Retained credit has no approved provider reservation');\n return structuredClone(reserved.mapping);\n });\n return withRetentionAccountingAuthority(input.tenantId, input.invoiceId, () =>\n reconcileFrozenInvoiceAccountingSync({\n ...input,\n invoiceId: input.creditInvoiceId,\n mapping,\n }),\n );\n}\n"],"mappings":"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"}
|