-- Defense-in-depth: prevent concurrent in-flight payout rows for the same user.
-- Combined with the FOR UPDATE lock in withdraw.ts, this makes a second simultaneous
-- withdrawal attempt fail with a constraint violation even if the lock is somehow bypassed.
-- The index covers only active states; completed/rejected payouts do not block new requests.
CREATE UNIQUE INDEX affiliate_payouts_one_active_idx
  ON affiliate_payouts (user_id)
  WHERE status IN ('requested', 'approved', 'processing');
