fix(server): winner_id on completed games + stats idempotency latch
Two issues in the GAME_OVER broadcast path: 1. log_game_end called update_game_completed with winner_id=None default, so games_v2.winner_id was NULL on all 17 completed staging rows. The denormalized column existed but carried no information. Compute winner (lowest total; None on tie) in broadcast_game_state and thread through. 2. _process_stats_safe had no idempotency guard. log_game_end was already self-guarding via game_log_id=None after first fire, but nothing stopped repeated GAME_OVER broadcasts from re-firing stats and double-counting games_played/games_won. Add Room.stats_processed latch; reset it in handle_start_game so a re-used room still records. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -209,6 +209,8 @@ async def handle_start_game(data: dict, ctx: ConnectionContext, *, broadcast_gam
|
||||
|
||||
async with ctx.current_room.game_lock:
|
||||
ctx.current_room.game.start_game(num_decks, num_rounds, options)
|
||||
# Reset the per-game idempotency latch so this game's stats can fire.
|
||||
ctx.current_room.stats_processed = False
|
||||
|
||||
game_logger = get_logger()
|
||||
if game_logger:
|
||||
|
||||
Reference in New Issue
Block a user