Add Elo rating system with match entry and CSV upload

- Implement EloCalculator service for 2v2 Euchre matches
- Create background job processing with GoodJob
- Add single match entry form
- Add CSV upload for batch match entry
- Create player rankings view
- Add database schema for matches and elo snapshots
This commit is contained in:
2026-03-26 16:28:24 -07:00
parent 1a9b3496e1
commit 1268889a78
31 changed files with 865 additions and 2 deletions
+86
View File
@@ -0,0 +1,86 @@
# frozen_string_literal: true
module EuchreCamp
module Jobs
class CalculateEloJob
def self.perform_later(match_id)
# Enqueue job using GoodJob's database directly
rom = EuchreCamp::App["persistence.rom"]
job_params = {
queue_name: "default",
priority: 0,
serialized_params: { "match_id" => match_id }.to_json,
scheduled_at: Time.now,
created_at: Time.now,
updated_at: Time.now,
job_class: "EuchreCamp::Jobs::CalculateEloJob",
executions_count: 0
}
rom.relations[:good_jobs].insert(job_params)
end
def self.perform(match_id)
# This is the actual job execution
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)
end
private
def self.find_match(match_id)
rom = EuchreCamp::App["persistence.rom"]
rom.relations[:matches].by_pk(match_id).one
end
def self.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 self.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