Two super-admins approved and rejected the same payout — status race-guard (PR #548 PP H5)
Lena Berlin Mitte Synaltix EU office 32-yo EU affiliate payout lead ops engineer 8-yr operations 5-yr Delivery Hero finance ops + 3-yr Synaltix thMenu Phase 1-3 affiliate payout review + anomaly + Wise dispatch superadmin panel manual. Monday 09:00 47 pending payout requests KYC review complete + Wise quote pulled awaiting final sign-off. Senior colleague Kerem parallel-reviews. 09:14 Lena payout #47828 Approve clicks same moment Kerem Reject same row two requests parallel thMenu admin API. 5 seconds UI refresh status rejected but Lena approved Wise transfer dispatch log Lena approve dispatchWiseTransfer + Wise quote+create €310 affiliate bank money flowing thMenu DB status rejected audit chaos. Engineering reproduce two parallel curl PUT endpoint different status. 3 wrong theories (1) UI optimistic lock reviewing badge helpful UX race fix not two superadmins miss/ignore race still UI-only back-end correctness; (2) DB transaction isolation level Cloudflare D1 SQLite serialized exists each independent UPDATE own mini-transaction statement-level atomicity inline race-guard; (3) frontend debounce 1 sec single user race two different users. Correct fix race-guarded UPDATE WHERE status='requested' + meta.changes=0 detection 409 conflict + state machine PAYOUT_TRANSITIONS lookup. Forensic apps/web-superadmin/src/app/api/payouts/[id]/route.ts no SELECT no race-guard two parallel (1) Lena approve UPDATE WHERE id=47828 status=approved + dispatchWiseTransfer €310 wire fired; (2) Kerem reject UPDATE WHERE id=47828 status=rejected + Lena updated_at + status OVERWRITE no dispatchWiseTransfer call. Final state rejected reviewed_by=kerem Wise transfer ALREADY FIRED €310 audit chaos. Manual reconcile Wise cancelTransfer pending settlement window reversal success status requested KYC re-review docs OK approved + Wise re-fired 24 hours affiliate €310. Production audit 90-day race-pattern 3 incidents Lena + 2 others similar manual reconciles. PR #548 batch PP H5 3-layer fix Layer 1 race-guarded UPDATE WHERE status='requested' meta.changes=0 SELECT current 409 conflict current_status + current_reviewer UI 409 catch refresh-and-retry. Layer 2 side-effect dispatch ONLY after meta.changes>0 if approved + meta.changes>0 dispatchWiseTransfer status flip + Wise atomic spurious fires impossible. Layer 3 PAYOUT_TRANSITIONS const requested:[approved,rejected] approved:[processing,cancelled] rejected:[] processing:[paid,failed] paid:[] failed:[requested] retry cancelled:[requested] retry state machine 422 illegal_transition sibling PR #603 BBB F3 reservation. Bonus audit log per state transition INSERT payout_audit_log payout_id + prior_status + new_status + actor_id + transition_at + reason + dashboard widget. 3 affected manual reconcile (a) Lena/Kerem Monday Wise reverse + KYC re-review €310; (b) Aysu/Mehmet 2 months prior Wise IBAN invalid return cancel + reissue new IBAN; (c) Aysu/Mehmet 1 month prior double approve Wise idempotency-key single transfer manual reconcile. Post-deploy 30-day 0 race incidents 4 race-guard 409 triggers superadmins refresh-and-retry state-machine compliant 0 spurious Wise. Lena Synaltix internal Slack PR #548 PP H5 review queue safe parallel superadmins 409 coordinated SOC 2 finance audit transparent audit log Berlin coffee engineering. Tugrul Istanbul Maslak Synaltix HQ 29-yo TR/MENA affiliate payout lead ops ex-Hepsiburada finance ops 6-yr parallel #47811 TR queue same Monday after PR #548 deploy queue safe. Pattern financial state-change endpoints (payout approve/reject + refund + dispute + transfer + commission) MUST use UPDATE inline filter WHERE prior_status race-guard + side-effect dispatch ONLY after meta.changes>0 + state machine TRANSITIONS lookup. Sibling sweep /api/payouts/[id]/approve|reject PP H5 + affiliate_commissions PR #378 + /api/orders/[id]/refund PR #328 + /api/dispute/[id]/resolve PR #585 XX F1 + /api/wise/transfer-confirm PR #593 ZZ F1 + /api/orders/[id]/status PR #329. Implementation financial state-change identify + race-guarded UPDATE + meta.changes 409 + side-effect ONLY after success + TRANSITIONS state machine + audit log + UI 409 catch refresh-and-retry + PR template checkbox + quarterly financial endpoint audit. PR #548 reference.
thMenu Team
thmenu.com
Found this helpful? Share it.
Related articles
Why Digital Menus Increase Restaurant Revenue by Up to 30%
Studies show restaurants using digital QR menus see measurable increases in aver…
When a Customer Downgrades, What Happens to Old Features? — The Silent Feature-Drift Problem in SaaS
Most SaaS apps run a single line of code when a customer downgrades — but old fe…
JWT alg-confusion attack — why Supabase's HS256 → RS256/JWKS migration breaks legacy verifiers
Verifiers that never decode the JWT header are wide open to `alg=none` and alg-c…