← All tests

Loyalty earn-retry sweep STAGING

Robustness follow-up to the POS×loyalty integration. Points are earned after a POS order commits, in a fire-and-forget call that must never fail the sale — but the loyalty backend is scale-to-zero on Fly, so a cold start can time out and the order is left at loyalty_earn_status = 'pending'/'failed' with the points simply missing. Nothing read those columns. Now a sweep does.

The fix: a secret-gated cron route /api/cafe/cron/loyalty-earn-retry finds orders stuck at pending/failed (with a member, aged 2 min–7 days) and re-calls /pos/earn. That endpoint is idempotent on posOrderId (points-ledger unique index + spin chances keyed on the order), so an order that actually earned just returns its prior result — no double-award. Fired every minute by the cron-trigger; it no-ops (no backend call) when nothing is stuck, so it only wakes the scale-to-zero backend when there's real work. No migration.

Verified end-to-end on get-coffee.staging

CheckResult
Flip a real order earned → failed (ledger = 1 row)seeded
POST the sweep route200 · {pending:1, earned:1, failed:0}
Order status afterearned
Points ledger before / after1 / 1 — no duplicate points
Second POST (nothing stuck){pending:0, earned:0} — no backend call
?dry=1reports backlog, writes nothing
POST without the cron secret401
DAO query (nix_db_staging)picks up the stuck order + its line items
Staging smoke5/5
order e6ee38a4… flipped earned->failed; ledger rows before: 1
route: 200 {"ok":true,"dry":false,"pending":1,"earned":1,"failed":0,"errors":[]}
order status after: earned | ledger before/after: 1 1
EARN-RETRY OK (picked up, earned, no duplicate points)

nix-cafe 00f652d (nix-cafe-staging Worker). The cron-trigger worker redeploy (so it fires on schedule) + prod CAFE_CRON_SECRET ride along at the scheduled prod promote.