# frozen_string_literal: true require "good_job" module EuchreCamp module Jobs class CalculateEloJob < ActiveJob::Base queue_as :default # This job calculates Elo ratings for a match and updates player records def perform(match_id) match = find_match(match_id) return unless match # Get current player ratings player_ratings = fetch_player_ratings(match) # Calculate new ratings calculation_results = EuchreCamp::Services::EloCalculator.calculate( player_ratings: player_ratings, team_1_players: [match[:team_1_p1_id], match[:team_1_p2_id]], team_2_players: [match[:team_2_p1_id], match[:team_2_p2_id]], team_1_score: match[:team_1_score], team_2_score: match[:team_2_score] ) # Update player ratings and create snapshots update_player_ratings(calculation_results, match_id) # Record partnerships (after Elo snapshots are created) EuchreCamp::Services::PartnershipTracker.record_match(match_id) end private def find_match(match_id) rom = EuchreCamp::App["persistence.rom"] rom.relations[:matches].by_pk(match_id).one end def fetch_player_ratings(match) rom = EuchreCamp::App["persistence.rom"] player_ids = [ match[:team_1_p1_id], match[:team_1_p2_id], match[:team_2_p1_id], match[:team_2_p2_id] ] players = rom.relations[:players].where(id: player_ids).to_a players.each_with_object({}) do |player, hash| hash[player[:id]] = player[:current_elo] || 1000 end end def update_player_ratings(results, match_id) rom = EuchreCamp::App["persistence.rom"] results.each do |player_id, data| # Update player's current Elo rom.relations[:players].where(id: player_id).update(current_elo: data[:rating_after]) # Create Elo snapshot record rom.relations[:elo_snapshots].insert( player_id: player_id, match_id: match_id, rating_before: data[:rating_before], rating_after: data[:rating_after], rating_change: data[:rating_change] ) end end end end end