The claim lifecycle in five states.
Robnu's return_claims table walks five states. Each transition is an append-only row. Each evidence is an S3-backed StorageObject. Each win writes a recovery Adjustment back to reconciliation.
- Pending → filed → acknowledged → resolved-won | resolved-lost. Five states. Append-only events.
- The daily claim sweeper (BullMQ, 0 2 * * *) promotes overdue OrderReturn rows to claim_pending.
- Won claims write a recovery Adjustment of type=chargeback against the source MarketplacePayout.
What you get.
States are explicit
No 'in_progress' soup. Each state is a typed transition with a typed event in return_claim_events. Build dashboards on this; they stay accurate as the schema evolves.
Sweeper is idempotent
The sweeper promotes overdue returns once. A second sweep on the same hour is a no-op. The kill switch WORKER_ENABLE_CLAIM_SWEEPER governs whether it runs at all.
Won and lost are equal citizens
Lost claims are not failures, they're feedback. The lost reason is logged so the discrepancy taxonomy can shift its default posture if a reason is consistently un-disputable.
Public claim API surface.
- GET /v1/claims, list with filters (status, marketplace, period).
- GET /v1/claims/:id, single claim with events + evidences.
- GET /v1/claims/stats, counts by state for dashboards.
- POST /v1/claims/:id/file, transition pending → filed.
- POST /v1/claims/:id/acknowledge, transition filed → acknowledged.
- POST /v1/claims/:id/resolve-won, transition → resolved-won, write recovery Adjustment.
- POST /v1/claims/:id/resolve-lost, transition → resolved-lost with lost_reason.
- POST /v1/claims/:id/evidence, attach a StorageObject as evidence.
Practical answers.
Yes. Reopening writes a new event with a reopen reason and transitions the claim back to filed. The audit log preserves the full history.
RBAC controls the resolve transitions. By default OWNER/ADMIN/FINANCE roles can resolve; OPERATOR can file but not resolve. SuperAdmins act through ImpersonationSession with full audit.
Try it inside your own dashboard.
Free during early access. No card. Forever free under 25 orders/day.

