Skip to content

Commit aad1528

Browse files
committed
feat: add matches and info from riot api
1 parent 9ec1115 commit aad1528

File tree

2 files changed

+101
-21
lines changed

2 files changed

+101
-21
lines changed
Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,54 @@
11
class Api::V1::Analytics::ChampionsController < Api::V1::BaseController
22
def show
33
player = organization_scoped(Player).find(params[:player_id])
4-
champion_pools = player.champion_pools.order(games_played: :desc)
4+
5+
stats = PlayerMatchStat.where(player: player)
6+
.group(:champion)
7+
.select(
8+
'champion',
9+
'COUNT(*) as games_played',
10+
'SUM(CASE WHEN matches.victory THEN 1 ELSE 0 END) as wins',
11+
'AVG((kills + assists)::float / NULLIF(deaths, 0)) as avg_kda'
12+
)
13+
.joins(:match)
14+
.order('games_played DESC')
15+
16+
champion_stats = stats.map do |stat|
17+
win_rate = stat.games_played.zero? ? 0 : (stat.wins.to_f / stat.games_played)
18+
{
19+
champion: stat.champion,
20+
games_played: stat.games_played,
21+
win_rate: win_rate,
22+
avg_kda: stat.avg_kda&.round(2) || 0,
23+
mastery_grade: calculate_mastery_grade(win_rate, stat.avg_kda)
24+
}
25+
end
526

627
champion_data = {
728
player: PlayerSerializer.render_as_hash(player),
8-
champion_pool: ChampionPoolSerializer.render_as_hash(champion_pools),
9-
top_champions: champion_pools.limit(5).map do |pool|
10-
{
11-
champion: pool.champion,
12-
games: pool.games_played,
13-
win_rate: pool.wins.to_f / pool.games_played * 100,
14-
avg_kda: pool.average_kda,
15-
mastery: pool.mastery_level
16-
}
17-
end,
29+
champion_stats: champion_stats,
30+
top_champions: champion_stats.take(5),
1831
champion_diversity: {
19-
total_champions: champion_pools.count,
20-
highly_played: champion_pools.where('games_played >= ?', 10).count,
21-
mastery_points: champion_pools.sum(:mastery_points)
32+
total_champions: champion_stats.count,
33+
highly_played: champion_stats.count { |c| c[:games_played] >= 10 },
34+
average_games: champion_stats.empty? ? 0 : (champion_stats.sum { |c| c[:games_played] } / champion_stats.count.to_f).round(1)
2235
}
2336
}
2437

2538
render_success(champion_data)
2639
end
40+
41+
private
42+
43+
def calculate_mastery_grade(win_rate, avg_kda)
44+
score = (win_rate * 100 * 0.6) + ((avg_kda || 0) * 10 * 0.4)
45+
46+
case score
47+
when 80..Float::INFINITY then 'S'
48+
when 70...80 then 'A'
49+
when 60...70 then 'B'
50+
when 50...60 then 'C'
51+
else 'D'
52+
end
53+
end
2754
end

app/controllers/api/v1/matches_controller.rb

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,66 @@ def stats
146146
end
147147

148148
def import
149-
# This will import match data from Riot API
150-
# Will be implemented when Riot API service is ready
151-
render_error(
152-
message: 'Import functionality not yet implemented',
153-
code: 'NOT_IMPLEMENTED',
154-
status: :not_implemented
155-
)
149+
player_id = params[:player_id]
150+
count = params[:count]&.to_i || 20
151+
152+
unless player_id.present?
153+
return render_error(
154+
message: 'player_id is required',
155+
code: 'VALIDATION_ERROR',
156+
status: :unprocessable_entity
157+
)
158+
end
159+
160+
player = organization_scoped(Player).find(player_id)
161+
162+
unless player.riot_puuid.present?
163+
return render_error(
164+
message: 'Player does not have a Riot PUUID. Please sync player from Riot first.',
165+
code: 'VALIDATION_ERROR',
166+
status: :unprocessable_entity
167+
)
168+
end
169+
170+
begin
171+
riot_service = RiotApiService.new
172+
region = player.region || 'BR'
173+
174+
match_ids = riot_service.get_match_history(
175+
puuid: player.riot_puuid,
176+
region: region,
177+
count: count
178+
)
179+
180+
imported_count = 0
181+
match_ids.each do |match_id|
182+
# Check if match already exists
183+
next if Match.exists?(riot_match_id: match_id)
184+
185+
SyncMatchJob.perform_later(match_id, current_organization.id, region)
186+
imported_count += 1
187+
end
188+
189+
render_success({
190+
message: "Queued #{imported_count} matches for import",
191+
total_matches_found: match_ids.count,
192+
already_imported: match_ids.count - imported_count,
193+
player: PlayerSerializer.render_as_hash(player)
194+
})
195+
196+
rescue RiotApiService::RiotApiError => e
197+
render_error(
198+
message: "Failed to fetch matches from Riot API: #{e.message}",
199+
code: 'RIOT_API_ERROR',
200+
status: :bad_gateway
201+
)
202+
rescue StandardError => e
203+
render_error(
204+
message: "Failed to import matches: #{e.message}",
205+
code: 'IMPORT_ERROR',
206+
status: :internal_server_error
207+
)
208+
end
156209
end
157210

158211
private

0 commit comments

Comments
 (0)