@@ -22,51 +22,72 @@ class InhousesController < Api::V1::BaseController
2222 before_action :set_inhouse , only : %i[ join balance_teams start_draft captain_pick start_game record_game close ]
2323
2424 # GET /api/v1/inhouse/ladder
25- # Returns per-player win/loss/win-rate aggregated across all done sessions.
25+ # Returns per-player TrueSkill ratings sorted by MMR descending.
26+ # Optional query param: ?role=mid (filter by role)
2627 def ladder
2728 authorize Inhouse
2829
29- rows = InhouseParticipation
30- . joins ( :inhouse , :player )
31- . where ( inhouses : { organization_id : current_organization . id , status : 'done' } )
32- . where . not ( team : 'none' )
33- . group ( :player_id )
34- . select (
35- 'player_id' ,
36- 'SUM(wins) AS total_wins' ,
37- 'SUM(losses) AS total_losses'
38- )
39- . to_a
40-
41- player_ids = rows . map ( &:player_id )
42- players_by_id = current_organization . players
43- . where ( id : player_ids )
44- . index_by ( &:id )
45-
46- entries = rows . map do |row |
47- player = players_by_id [ row . player_id ]
48- next unless player
49-
50- total = row . total_wins . to_i + row . total_losses . to_i
51- win_rate = total . zero? ? 0.0 : ( row . total_wins . to_f / total * 100 ) . round ( 1 )
30+ scope = PlayerInhouseRating
31+ . joins ( :player )
32+ . where ( organization_id : current_organization . id )
5233
34+ scope = scope . where ( role : params [ :role ] . downcase ) if params [ :role ] . present?
35+
36+ ratings = scope . includes ( :player ) . to_a
37+
38+ entries = ratings . map do |r |
5339 {
54- player_id : row . player_id ,
55- player_name : player . summoner_name ,
56- role : player . role ,
57- wins : row . total_wins . to_i ,
58- losses : row . total_losses . to_i ,
59- total_games : total ,
60- win_rate : win_rate
40+ player_id : r . player_id ,
41+ player_name : r . player &.summoner_name ,
42+ role : r . role ,
43+ mu : r . mu . round ( 3 ) ,
44+ sigma : r . sigma . round ( 3 ) ,
45+ mmr : r . mmr ,
46+ games_played : r . games_played ,
47+ wins : r . wins ,
48+ losses : r . losses ,
49+ win_rate : r . win_rate
6150 }
62- end . compact
51+ end
6352
64- entries . sort_by! { |e | [ -e [ :wins ] , e [ :losses ] ] }
53+ entries . sort_by! { |e | -e [ :mmr ] }
6554 entries . each_with_index { |e , i | e [ :rank ] = i + 1 }
6655
6756 render_success ( { entries : entries , total : entries . size } )
6857 end
6958
59+ # GET /api/v1/inhouse/ladder/:player_id
60+ # Returns all role ratings for a single player.
61+ def player_ratings
62+ authorize Inhouse
63+
64+ player = current_organization . players . find_by ( id : params [ :player_id ] )
65+ return render_not_found unless player
66+
67+ ratings = PlayerInhouseRating
68+ . where ( player : player , organization : current_organization )
69+ . order ( :role )
70+
71+ entries = ratings . map do |r |
72+ {
73+ role : r . role ,
74+ mu : r . mu . round ( 3 ) ,
75+ sigma : r . sigma . round ( 3 ) ,
76+ mmr : r . mmr ,
77+ games_played : r . games_played ,
78+ wins : r . wins ,
79+ losses : r . losses ,
80+ win_rate : r . win_rate
81+ }
82+ end
83+
84+ render_success ( {
85+ player_id : player . id ,
86+ player_name : player . summoner_name ,
87+ ratings : entries
88+ } )
89+ end
90+
7091 # GET /api/v1/inhouse/sessions
7192 # Returns paginated history of completed inhouse sessions with summary.
7293 def sessions
@@ -208,10 +229,15 @@ def join
208229 )
209230 end
210231
232+ role = params [ :role ] . to_s . downcase . presence
233+ role = nil unless InhouseParticipation ::ROLES . include? ( role )
234+ role ||= player . role . presence
235+
211236 participation = @inhouse . inhouse_participations . new (
212237 player : player ,
213238 team : 'none' ,
214- tier_snapshot : player . solo_queue_tier . presence
239+ tier_snapshot : player . solo_queue_tier . presence ,
240+ role : role
215241 )
216242
217243 if participation . save
@@ -455,7 +481,7 @@ def record_game
455481 @inhouse . increment! ( :red_wins )
456482 end
457483
458- # Update per-player wins/losses
484+ # Update per-player wins/losses and TrueSkill ratings
459485 @inhouse . inhouse_participations . each do |p |
460486 next if p . team == 'none'
461487
@@ -466,6 +492,8 @@ def record_game
466492 end
467493 end
468494
495+ TrueSkillService . update_ratings ( @inhouse , winner )
496+
469497 render_success (
470498 { inhouse : serialize_inhouse ( @inhouse . reload ) } ,
471499 message : "Game recorded — #{ winner . capitalize } team wins"
@@ -574,7 +602,11 @@ def serialize_inhouse(inhouse, detailed: false)
574602 player_id : p . player_id ,
575603 player_name : p . player &.summoner_name ,
576604 team : p . team ,
605+ role : p . role ,
577606 tier_snapshot : p . tier_snapshot ,
607+ mu_snapshot : p . mu_snapshot ,
608+ sigma_snapshot : p . sigma_snapshot ,
609+ mmr_delta : p . mmr_delta ,
578610 is_captain : p . is_captain ,
579611 wins : p . wins ,
580612 losses : p . losses
0 commit comments