fix(contracts,billing): close financial-integrity gaps #213

Merged
David merged 2 commits from fix/pms-194-contracts-billing-financial-integrity into main 2026-06-14 00:06:42 +02:00
Owner

Write audit rows for every contract financial mutation, paginate the contract-expiry sweep, reject invoice overpayment, consolidate invoice-number seeding, and drop a dead balance field.

  • update_rate_card now wraps its UPDATE in a tx and writes an Update audit row with before/after JSONB snapshots; the handler threads an AuditCtx.
  • delete_rate_card_item snapshots the row (joined through its parent rate_cards for tenant scope) and writes a Delete audit row in the tx; the handler threads an AuditCtx.
  • expire_due_contracts resolves the tenants with due contracts up front, then drains each tenant in EXPIRE_BATCH-sized transactions (committing per batch) so the sweep never holds one table-wide lock, and writes a per-contract audit row for each renew/expire via audit_write(AuditCtx::system).
  • create_payment rejects a payment larger than the invoice's remaining balance, so balance_due can never go negative.
  • The three identical invoice-sequence seed-or-bump blocks collapse into a shared BillingService::next_invoice_number helper.
  • BalanceMutRow.rollover_hours (allow(dead_code), fetched but never read) is removed from the struct and dropped from the two SELECTs that fetched it.

#PMS-194

Write audit rows for every contract financial mutation, paginate the contract-expiry sweep, reject invoice overpayment, consolidate invoice-number seeding, and drop a dead balance field. - update_rate_card now wraps its UPDATE in a tx and writes an Update audit row with before/after JSONB snapshots; the handler threads an AuditCtx. - delete_rate_card_item snapshots the row (joined through its parent rate_cards for tenant scope) and writes a Delete audit row in the tx; the handler threads an AuditCtx. - expire_due_contracts resolves the tenants with due contracts up front, then drains each tenant in EXPIRE_BATCH-sized transactions (committing per batch) so the sweep never holds one table-wide lock, and writes a per-contract audit row for each renew/expire via audit_write(AuditCtx::system). - create_payment rejects a payment larger than the invoice's remaining balance, so balance_due can never go negative. - The three identical invoice-sequence seed-or-bump blocks collapse into a shared BillingService::next_invoice_number helper. - BalanceMutRow.rollover_hours (allow(dead_code), fetched but never read) is removed from the struct and dropped from the two SELECTs that fetched it. #PMS-194
fix(contracts,billing): close financial-integrity gaps
Some checks failed
E2E / Playwright against staging (pull_request) Failing after 43s
Check / fmt + clippy + compile + tests (pull_request) Failing after 5m9s
9579f2b43e
Write audit rows for every contract financial mutation, paginate the contract-expiry sweep, reject invoice overpayment, consolidate invoice-number seeding, and drop a dead balance field.

- update_rate_card now wraps its UPDATE in a tx and writes an Update audit row with before/after JSONB snapshots; the handler threads an AuditCtx.
- delete_rate_card_item snapshots the row (joined through its parent rate_cards for tenant scope) and writes a Delete audit row in the tx; the handler threads an AuditCtx.
- expire_due_contracts resolves the tenants with due contracts up front, then drains each tenant in EXPIRE_BATCH-sized transactions (committing per batch) so the sweep never holds one table-wide lock, and writes a per-contract audit row for each renew/expire via audit_write(AuditCtx::system).
- create_payment rejects a payment larger than the invoice's remaining balance, so balance_due can never go negative.
- The three identical invoice-sequence seed-or-bump blocks collapse into a shared BillingService::next_invoice_number helper.
- BalanceMutRow.rollover_hours (allow(dead_code), fetched but never read) is removed from the struct and dropped from the two SELECTs that fetched it.

#PMS-194
Merge origin/main into fix/pms-194-contracts-billing-financial-integrity
Some checks failed
E2E / Playwright against staging (pull_request) Failing after 32s
Check / fmt + clippy + compile + tests (pull_request) Successful in 3m46s
Create release / Create release from merged PR (pull_request) Has been skipped
6d079547dd
#PMS-194
David merged commit 2e34ede280 into main 2026-06-14 00:06:42 +02:00
David deleted branch fix/pms-194-contracts-billing-financial-integrity 2026-06-14 00:06:42 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!213
No description provided.