Reconciliation
Quick summary
Reconciliation checks internal records for drift and produces findings; it does not automatically repair financial data or prove external PG settlement.
Read each check's scope and completeness. A failed database query or a partial scan must never be interpreted as a clean result.
The durable-authority consistency engine — admin-only, manually triggered, from be-cloudflare/src/reconciliation_impl.rs. It compares money, entitlement, and event states and stores drift as findings; money and entitlement findings are never auto-fixed.
Endpoints (admin)
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/admin/reconciliation/run | Run all checks; returns the run + findings immediately (auto-fixes apply in the same batch they are recorded). |
GET | /api/v1/admin/reconciliation/reports | List runs. |
GET | /api/v1/admin/reconciliation/report/:id | One run + its findings. |
The 7 checks
| Check | Detects | Auto-fix? |
|---|---|---|
paid_no_entitlement | paid order on a license-enabled product with no/missing license row (subscriptions also checked) | needs_review — money/entitlement |
unpaid_but_entitled | valid license attached to an unpaid order (manual issues excluded) | needs_review |
refunded_but_valid_entitlement | fully refunded order whose license was not revoked | needs_review |
subscription_expired_but_renewed | expired-processed subscription that has a renewal payment | needs_review |
duplicate_issuance_per_payment | multiple licenses on one order | needs_review |
unprocessed_inbox_events | processing >10 min (died mid-flight) → auto-marked failed; old received/failed → review (re-delivery may have money impact) | stale processing → auto_fixed; aged received/failed → needs_review |
failed_or_stuck_outbox | dead_letter rows; claimed lease expired; aged pending | stale claim re-queue → auto_fixed; dead_letter/aged → needs_review |
Finding states
auto_fixed— safe state-normalization only (stale leases). Applied in the same batch as the finding insert.needs_review— anything touching money or entitlements. Manual resolution, no SLA, no owner, and no sweeper job — see limitations §4.14–4.15.open— schema-valid informational state; this wave's checks do not emit it.
Each run writes an integrity-chained audit_events entry (reconciliation_run) recording {run, findings, auto_fixed}.
Seller-visible surface
Sellers do not see recon reports — they see their own consistent views: GET /orders, /orders/:id/refund-attempts, /settlements, /dashboard/stats. Recon is a platform-operator tool.
Runbook
Day-to-day monitoring (security events, outbox health) → Monitoring. Acting on findings (refund, revoke, redrive) → Incident Response.