ac858f1e6d
Implement comprehensive partnership tracking system and tournament management features including round-robin, single/double elimination, and Swiss system pairings. Changes: - Add partnership_games and partnership_stats tables - Implement PartnershipTracker service for recording partnership data - Add tournament generator with multiple formats - Create tournament management actions and views - Add acceptance tests for partnership tracking - Fix PartnershipTracker to use single snapshot per player per match - Fix round-robin test to query by round_number instead of hardcoded ID Note: All 8 acceptance tests now passing
127 lines
4.5 KiB
Ruby
127 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module EuchreCamp
|
|
module Actions
|
|
module Admin
|
|
module Tournaments
|
|
class Schedule < EuchreCamp::Action
|
|
include Deps[
|
|
events_repo: 'repositories.events',
|
|
teams_repo: 'repositories.teams',
|
|
rounds_repo: 'repositories.tournament_rounds',
|
|
matchups_repo: 'repositories.bracket_matchups'
|
|
]
|
|
|
|
def handle(request, response)
|
|
tournament_id = request.params[:id]
|
|
tournament = events_repo.by_id(tournament_id)
|
|
teams = teams_repo.by_event(tournament_id)
|
|
|
|
if teams.empty?
|
|
response.flash[:error] = "No teams to schedule. Add teams first."
|
|
response.redirect_to("/admin/tournaments/#{tournament_id}")
|
|
return
|
|
end
|
|
|
|
# Generate matchups based on format
|
|
teams_data = teams.map { |t| { id: t[:id], seed: t[:id] } }
|
|
format = tournament[:format]
|
|
|
|
begin
|
|
case format
|
|
when 'round_robin'
|
|
rounds = EuchreCamp::Services::TournamentGenerator.round_robin(teams_data)
|
|
create_round_robin_schedule(tournament_id, rounds)
|
|
when 'single_elim'
|
|
bracket = EuchreCamp::Services::TournamentGenerator.single_elimination(teams_data)
|
|
create_single_elim_schedule(tournament_id, bracket, teams)
|
|
when 'swiss'
|
|
# For Swiss, create first round
|
|
rounds = EuchreCamp::Services::TournamentGenerator.swiss(teams_data, 1)
|
|
create_swiss_schedule(tournament_id, rounds, 1)
|
|
else
|
|
response.flash[:error] = "Format '#{format}' not yet implemented"
|
|
response.redirect_to("/admin/tournaments/#{tournament_id}")
|
|
return
|
|
end
|
|
|
|
# Update tournament status
|
|
events_repo.update(tournament_id, status: 'active')
|
|
|
|
response.flash[:message] = "Schedule generated successfully"
|
|
response.redirect_to("/admin/tournaments/#{tournament_id}")
|
|
rescue StandardError => e
|
|
response.flash[:error] = "Failed to generate schedule: #{e.message}"
|
|
response.redirect_to("/admin/tournaments/#{tournament_id}")
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def create_round_robin_schedule(tournament_id, rounds)
|
|
rounds.each do |round_data|
|
|
round = rounds_repo.create(
|
|
event_id: tournament_id,
|
|
round_number: round_data[:round_number],
|
|
status: round_data[:round_number] == 1 ? 'active' : 'pending'
|
|
)
|
|
|
|
round_data[:matchups].each_with_index do |matchup, index|
|
|
matchups_repo.create(
|
|
event_id: tournament_id,
|
|
round_id: round[:id],
|
|
team_1_id: matchup[:team_1_id],
|
|
team_2_id: matchup[:team_2_id],
|
|
bracket_position: index + 1
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_single_elim_schedule(tournament_id, bracket, teams)
|
|
# Create first round
|
|
round = rounds_repo.create(
|
|
event_id: tournament_id,
|
|
round_number: 1,
|
|
status: 'active'
|
|
)
|
|
|
|
bracket[:first_round_matchups].each do |matchup|
|
|
# Skip if team is nil (BYE)
|
|
next if matchup[:team_1_id].nil? && matchup[:team_2_id].nil?
|
|
|
|
matchups_repo.create(
|
|
event_id: tournament_id,
|
|
round_id: round[:id],
|
|
team_1_id: matchup[:team_1_id],
|
|
team_2_id: matchup[:team_2_id],
|
|
bracket_position: matchup[:bracket_position]
|
|
)
|
|
end
|
|
end
|
|
|
|
def create_swiss_schedule(tournament_id, rounds, round_number)
|
|
round = rounds_repo.create(
|
|
event_id: tournament_id,
|
|
round_number: round_number,
|
|
status: 'active'
|
|
)
|
|
|
|
rounds.each do |round_data|
|
|
round_data[:matchups].each_with_index do |matchup, index|
|
|
matchups_repo.create(
|
|
event_id: tournament_id,
|
|
round_id: round[:id],
|
|
team_1_id: matchup[:team_1_id],
|
|
team_2_id: matchup[:team_2_id],
|
|
bracket_position: index + 1
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|