@@ -7,17 +7,71 @@ defmodule Codebattle.User.PointsAndRankUpdate do
77 """
88
99 alias Codebattle.Repo
10+ alias Codebattle.Season
1011 alias Ecto.Adapters.SQL
1112
1213 @ doc """
1314 Updates user points and rankings based on tournament performance in current season.
1415
15- Points are already calculated in tournament_user_results table based on tournament grade and place.
16- This function aggregates those points for the current season and updates user rankings.
17-
18- Updates the current season points in points field and rank.
16+ Points and places are calculated in season_results based on current season tournaments.
17+ This function aligns user points and rank with the current season standings.
1918 """
20- def update do
19+ def update ( season \\ nil ) do
20+ case season || Season . get_current_season ( ) do
21+ % Season { id: season_id } ->
22+ update_from_season_results ( season_id )
23+
24+ nil ->
25+ update_from_date_ranges ( )
26+ end
27+ end
28+
29+ defp update_from_season_results ( season_id ) do
30+ sql = """
31+ WITH season_results_data AS (
32+ SELECT
33+ sr.user_id,
34+ sr.total_points,
35+ sr.place
36+ FROM season_results sr
37+ WHERE sr.season_id = $1
38+ ),
39+ max_place AS (
40+ SELECT COALESCE(MAX(place), 0) AS max_place
41+ FROM season_results
42+ WHERE season_id = $1
43+ ),
44+ fallback_rankings AS (
45+ SELECT
46+ u.id AS user_id,
47+ (SELECT max_place FROM max_place)
48+ + DENSE_RANK() OVER (ORDER BY u.rating DESC, u.id ASC) AS fallback_rank
49+ FROM users u
50+ LEFT JOIN season_results_data sr ON sr.user_id = u.id
51+ WHERE u.is_bot = false AND sr.user_id IS NULL
52+ ),
53+ user_rankings AS (
54+ SELECT
55+ u.id AS user_id,
56+ COALESCE(sr.total_points, 0) AS season_points,
57+ COALESCE(sr.place, fr.fallback_rank) AS new_rank
58+ FROM users u
59+ LEFT JOIN season_results_data sr ON sr.user_id = u.id
60+ LEFT JOIN fallback_rankings fr ON fr.user_id = u.id
61+ WHERE u.is_bot = false
62+ )
63+ UPDATE users
64+ SET
65+ points = ur.season_points,
66+ rank = ur.new_rank
67+ FROM user_rankings ur
68+ WHERE users.id = ur.user_id;
69+ """
70+
71+ SQL . query! ( Repo , sql , [ season_id ] )
72+ end
73+
74+ defp update_from_date_ranges do
2175 { current_season , season_start , season_end } = get_current_season_info ( )
2276
2377 sql = """
0 commit comments