Skip to content

Commit 5db6727

Browse files
committed
feat: implement multi roster
1 parent 386d619 commit 5db6727

13 files changed

Lines changed: 56 additions & 16 deletions

File tree

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ DEPENDENCIES
521521
webmock
522522

523523
RUBY VERSION
524-
ruby 3.4.5p51
524+
ruby 3.4.8p72
525525

526526
BUNDLED WITH
527527
2.3.27

app/controllers/api/v1/organizations_controller.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ def upload_logo
5555
)
5656
end
5757

58+
# PATCH /api/v1/organizations/:id/lines
59+
def update_lines
60+
lines = Array(params[:enabled_lines]).select { |l| l.in?(Constants::Player::LINES) }
61+
62+
if lines.empty?
63+
return render_error(message: 'At least one valid line is required', code: 'VALIDATION_ERROR',
64+
status: :unprocessable_entity)
65+
end
66+
67+
lines = (['main'] | lines).uniq
68+
@organization.update!(enabled_lines: lines)
69+
70+
render json: { message: 'Roster lines updated', enabled_lines: @organization.enabled_lines }, status: :ok
71+
end
72+
5873
private
5974

6075
def set_organization
@@ -63,10 +78,10 @@ def set_organization
6378
end
6479

6580
def require_admin_or_owner
66-
return if %w[admin owner].include?(@current_user.role)
81+
return if %w[admin owner coach].include?(@current_user.role)
6782

6883
render_error(
69-
message: 'Only admins and owners can update organization settings',
84+
message: 'Only coaches, admins and owners can update organization settings',
7085
code: 'FORBIDDEN',
7186
status: :forbidden
7287
)

app/models/concerns/constants.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Organization
3030

3131
SOURCE_APP_URLS = {
3232
'prostaff' => ENV.fetch('PROSTAFF_URL', 'https://prostaff.gg'),
33-
'scrims' => ENV.fetch('SCRIMS_URL', 'https://scrims.lol'),
33+
'scrims' => ENV.fetch('SCRIMS_URL', 'https://scrims.lol'),
3434
'arena_br' => ENV.fetch('ARENA_BR_URL', 'https://arena-br.vercel.app')
3535
}.freeze
3636

@@ -51,6 +51,7 @@ module User
5151
module Player
5252
ROLES = %w[top jungle mid adc support].freeze
5353
STATUSES = %w[active inactive benched trial removed].freeze
54+
LINES = %w[main academy farm female other].freeze
5455
QUEUE_RANKS = %w[I II III IV].freeze
5556
QUEUE_TIERS = %w[IRON BRONZE SILVER GOLD PLATINUM EMERALD DIAMOND MASTER GRANDMASTER CHALLENGER].freeze
5657

app/modules/core/serializers/organization_serializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class OrganizationSerializer < Blueprinter::Base
66
identifier :id
77

88
fields :name, :slug, :team_tag, :region, :tier, :subscription_plan, :subscription_status,
9-
:logo_url, :settings, :created_at, :updated_at,
9+
:logo_url, :settings, :enabled_lines, :created_at, :updated_at,
1010
:trial_expires_at, :trial_started_at
1111

1212
field :region_display do |org|

app/modules/players/controllers/players_controller.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def index
2020

2121
players = players.by_role(params[:role]) if params[:role].present?
2222
players = players.by_status(params[:status]) if params[:status].present?
23+
players = players.by_line(params[:line]) if params[:line].present?
2324

2425
if params[:search].present?
2526
search_term = "%#{params[:search]}%"
@@ -178,13 +179,14 @@ def import
178179
summoner_name = params[:summoner_name]&.strip
179180
role = params[:role]
180181
region = params[:region] || 'br1'
182+
line = params[:line].presence_in(Constants::Player::LINES) || 'main'
181183

182184
# Validations
183185
return unless validate_import_params(summoner_name, role)
184186
return unless validate_player_uniqueness(summoner_name)
185187

186188
# Import from Riot API
187-
result = import_player_from_riot(summoner_name, role, region)
189+
result = import_player_from_riot(summoner_name, role, region, line)
188190

189191
# Handle result
190192
result[:success] ? handle_import_success(result) : handle_import_error(result)
@@ -426,12 +428,13 @@ def validate_player_uniqueness(summoner_name)
426428
end
427429

428430
# Import player from Riot API
429-
def import_player_from_riot(summoner_name, role, region)
431+
def import_player_from_riot(summoner_name, role, region, line = 'main')
430432
RiotSyncService.import(
431433
summoner_name: summoner_name,
432434
role: role,
433435
region: region,
434-
organization: current_organization
436+
organization: current_organization,
437+
line: line
435438
)
436439
end
437440

app/modules/players/models/player.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class Player < ApplicationRecord # rubocop:disable Metrics/ClassLength
5656
validates :role, presence: true, inclusion: { in: Constants::Player::ROLES }
5757
validates :country, length: { maximum: 2 }
5858
validates :status, inclusion: { in: Constants::Player::STATUSES }
59+
validates :line, inclusion: { in: Constants::Player::LINES }
5960
validates :riot_puuid, uniqueness: true, allow_blank: true
6061
validates :riot_summoner_id, uniqueness: true, allow_blank: true
6162
validates :jersey_number, uniqueness: { scope: :organization_id }, allow_blank: true
@@ -75,6 +76,7 @@ class Player < ApplicationRecord # rubocop:disable Metrics/ClassLength
7576
# Scopes
7677
scope :by_role, ->(role) { where(role: role) }
7778
scope :by_status, ->(status) { where(status: status) }
79+
scope :by_line, ->(line) { where(line: line) }
7880
scope :active, -> { where(status: 'active') }
7981
scope :with_contracts, -> { where.not(contract_start_date: nil) }
8082
scope :contracts_expiring_soon, lambda { |days = 30|

app/modules/players/serializers/player_serializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
class PlayerSerializer < Blueprinter::Base
66
identifier :id
77

8-
fields :summoner_name, :real_name, :role, :status,
8+
fields :summoner_name, :real_name, :role, :status, :line,
99
:jersey_number, :birth_date, :country,
1010
:contract_start_date, :contract_end_date,
1111
:solo_queue_tier, :solo_queue_rank, :solo_queue_lp,

app/modules/players/services/riot_sync_service.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ def initialize(organization, region = nil)
5555
end
5656

5757
# Class method to import a new player from Riot API
58-
def self.import(summoner_name:, role:, region:, organization:)
58+
def self.import(summoner_name:, role:, region:, organization:, line: 'main')
5959
service = new(organization, region)
60-
service.import_player(summoner_name, role)
60+
service.import_player(summoner_name, role, line: line)
6161
end
6262

6363
# Import a new player from Riot API
64-
def import_player(summoner_name, role)
64+
def import_player(summoner_name, role, line: 'main')
6565
parsed_name = parse_summoner_name(summoner_name)
6666
return parsed_name unless parsed_name[:success]
6767

@@ -85,7 +85,8 @@ def import_player(summoner_name, role)
8585
solo_queue_losses: riot_data[:rank_data]['losses'] || 0,
8686
last_sync_at: Time.current,
8787
sync_status: 'success',
88-
region: @region
88+
region: @region,
89+
line: line
8990
)
9091

9192
{

app/modules/players/services/roster_management_service.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,14 @@ def remove_from_roster(reason:)
6262
# @param jersey_number [Integer] Jersey number (optional)
6363
# @return [Hash] Result with success status and player
6464
def self.hire_from_scouting(scouting_target:, organization:, contract_start:, contract_end:,
65-
salary: nil, jersey_number: nil, current_user: nil)
65+
salary: nil, jersey_number: nil, line: 'main', current_user: nil)
6666
ActiveRecord::Base.transaction do
67-
# Check if this is a free agent or needs to be restored
6867
player = find_or_restore_player(scouting_target, organization)
6968

70-
# Update player with new contract details
7169
player.update!(
7270
organization: organization,
7371
status: 'active',
72+
line: line.presence_in(Constants::Player::LINES) || 'main',
7473
contract_start_date: contract_start,
7574
contract_end_date: contract_end,
7675
salary: salary,

app/modules/scouting/controllers/players_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ def import_to_roster
115115
contract_end: params[:contract_end].present? ? Date.parse(params[:contract_end]) : nil,
116116
salary: params[:salary]&.to_d,
117117
jersey_number: params[:jersey_number]&.to_i,
118+
line: params[:line],
118119
current_user: current_user
119120
)
120121

0 commit comments

Comments
 (0)