+4
−0
+20
−5
Loading
fix(api): serialise RedeemPlayerBindCode — concurrent redeem 500s become clean 400s/idempotent converges 6-way concurrent redeem of one code 500'd on users_username_key (each request generated a fresh user id but the same uuid-derived username), plus the rarer two-codes-one-uuid race. Same drift family as VerifyLinkCode, which already locks its code row and handles the conflict. - SELECT ... FOR UPDATE the code row: same-code racers serialise; losers exit as ErrLinkCodeInvalid (400 invalid_code), no user row is attempted. - INSERT users ... ON CONFLICT (username) DO NOTHING + re-read by username: cross-code racers converge on the winner's row (role checked, staff still refused) instead of a unique-violation 500. - account_links ON CONFLICT (mc_uuid) DO NOTHING for the same race. Verified live: same-code x6 = 1x200 + 5x400; two-codes x2 = 2x200 same user; db clean; zero unmapped errors.