package store // ResultReceiptInsertSQL intentionally uses DO NOTHING. The adapter must // select the existing receipt afterward and compare its digest; an identical // retry is acknowledged, while a different payload is a conflict with no // update side effect. const ResultReceiptInsertSQL = `INSERT INTO result_receipts (result_id, match_id, result_nonce, payload_digest, integrity_state, received_at) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT DO NOTHING` const ResultReceiptSelectSQL = `SELECT result_id, match_id, result_nonce, payload_digest, integrity_state, received_at, committed_at FROM result_receipts WHERE match_id = $1 FOR UPDATE` // ResultCommitLockSQL establishes the match lock before participant/rating // locks. Rating rows are then locked in lexical player-ID order by the // adapter, ensuring every concurrent result computes from one snapshot. const ResultCommitLockSQL = `SELECT match_id, playlist, state FROM matches WHERE match_id = $1 AND server_id = $2 FOR UPDATE` const ResultMatchCompleteSQL = `UPDATE matches SET state = 'COMPLETED', revision = revision + 1, completed_at = $2 WHERE match_id = $1 AND state = 'RESULT_PENDING'` const ResultOutboxSQL = `INSERT INTO outbox (event_id, aggregate_type, aggregate_id, revision, event_type, payload) VALUES ($1, 'match', $2, $3, 'match_completed', $4)` const RatingLockSQL = `SELECT player_id, rating, deviation, volatility, ranked_games, revision FROM ratings WHERE player_id = ANY($1) ORDER BY player_id FOR UPDATE`