@@ -8,26 +8,55 @@ WITH challenge_context AS (
88 ON ct .id = c." typeId"
99 WHERE c .id = ANY($1 ::text [])
1010),
11+ -- Automated review types that must never contribute a leaderboard score.
12+ scan_review_types AS (
13+ SELECT rt .id
14+ FROM reviews." reviewType" AS rt
15+ WHERE LOWER (rt .name ) IN (' av scan' , ' sonarqube review' , ' virus scan' )
16+ ),
1117submission_metrics AS (
1218 SELECT
1319 cc .challenge_id ,
20+ cc .challenge_name ,
21+ cc .is_marathon_match ,
1422 s .id AS submission_id,
1523 s." memberId" AS user_id,
1624 COALESCE(
1725 NULLIF(TRIM (u .handle ), ' ' ),
1826 NULLIF(TRIM (mem .handle ), ' ' ),
1927 fallback .member_handle
2028 ) AS handle,
21- COALESCE(final_review." aggregateScore" , s." finalScore" ::double precision ) AS standard_score,
22- provisional_review .provisional_score ,
23- COALESCE(final_review." aggregateScore" , s." finalScore" ::double precision ) AS final_score_raw,
24- COALESCE(s." submittedDate" , s." createdAt" ) AS submitted_date
29+ COALESCE(NULLIF(TRIM (mem." firstName" ), ' ' ), NULLIF(TRIM (u .handle ), ' ' ), NULLIF(TRIM (mem .handle ), ' ' )) AS name,
30+ COALESCE(
31+ NULLIF(TRIM (mem." competitionCountryCode" ), ' ' ),
32+ NULLIF(TRIM (mem." homeCountryCode" ), ' ' )
33+ ) AS country_code,
34+ mem." photoURL" AS photo_url,
35+ mmr .rating AS rating,
36+ mmr." ratingColor" AS rating_color,
37+ -- Final score comes ONLY from a non-provisional reviewSummation. submission."finalScore"
38+ -- is a denormalized column that is written during provisional MM reviews too, so using it
39+ -- here would surface a "final" score for matches that are still running.
40+ final_review." aggregateScore" AS final_score,
41+ final_review .is_strict_final ,
42+ -- Provisional score: latest non-scan review row first, provisional summation second.
43+ -- NULLIF(..., 0) reproduces the old `||` chain, where a 0 review score fell through to
44+ -- the provisional summation before ending up back at 0.
45+ COALESCE(
46+ NULLIF(latest_review .review_score , 0 ),
47+ provisional_review .provisional_score ,
48+ latest_review .review_score
49+ ) AS provisional_score,
50+ COALESCE(s." submittedDate" , s." createdAt" ) AS submitted_date,
51+ COALESCE(s." updatedAt" , s." submittedDate" , s." createdAt" ) AS updated_date
2552 FROM challenge_context AS cc
2653 JOIN reviews." submission" AS s
2754 ON s." challengeId" = cc .challenge_id
2855 AND s." memberId" IS NOT NULL
2956 LEFT JOIN LATERAL (
30- SELECT rs." aggregateScore"
57+ SELECT
58+ rs." aggregateScore" ,
59+ rs." isFinal" IS TRUE AS is_strict_final
3160 FROM reviews." reviewSummation" AS rs
3261 WHERE rs." submissionId" = s .id
3362 AND COALESCE(rs." isFinal" , TRUE) = TRUE
@@ -43,8 +72,25 @@ submission_metrics AS (
4372 ORDER BY COALESCE(rs." reviewedDate" , rs." createdAt" ) DESC NULLS LAST, rs .id DESC
4473 LIMIT 1
4574 ) AS provisional_review ON TRUE
75+ LEFT JOIN LATERAL (
76+ SELECT COALESCE(r." finalScore" , r." initialScore" ) AS review_score
77+ FROM reviews .review AS r
78+ WHERE r." submissionId" = s .id
79+ AND (r." typeId" IS NULL OR r." typeId" NOT IN (SELECT id FROM scan_review_types))
80+ AND COALESCE(r." finalScore" , r." initialScore" ) IS NOT NULL
81+ ORDER BY COALESCE(r." reviewDate" , r." updatedAt" , r." createdAt" ) DESC NULLS LAST, r .id DESC
82+ LIMIT 1
83+ ) AS latest_review ON TRUE
4684 LEFT JOIN members." member" AS mem
4785 ON mem." userId" = s." memberId" ::bigint
86+ LEFT JOIN LATERAL (
87+ SELECT DISTINCT ON (mmr." userId" )
88+ mmr .rating ,
89+ mmr." ratingColor"
90+ FROM members." memberMaxRating" AS mmr
91+ WHERE mmr." userId" = s." memberId" ::bigint
92+ ORDER BY mmr." userId" , mmr .rating DESC
93+ ) AS mmr ON TRUE
4894 LEFT JOIN identity." user" AS u
4995 ON s." memberId" ~ ' ^[0-9]+$'
5096 AND u .user_id = s." memberId" ::numeric
@@ -54,44 +100,111 @@ submission_metrics AS (
54100 WHERE r." challengeId" = cc .challenge_id
55101 AND r." memberId" = s." memberId"
56102 ) AS fallback ON TRUE
57- WHERE COALESCE(final_review." aggregateScore" , s." finalScore" ::double precision , s." initialScore" ::double precision ) IS NOT NULL
103+ ),
104+ scored_submissions AS (
105+ SELECT sm.*
106+ FROM submission_metrics AS sm
107+ WHERE sm .handle IS NOT NULL
108+ AND (sm .final_score IS NOT NULL OR sm .provisional_score IS NOT NULL )
58109),
59110unique_member_submissions AS (
60111 SELECT DISTINCT ON (challenge_id, user_id)
61- sm .*
62- FROM submission_metrics AS sm
112+ ss .*
113+ FROM scored_submissions AS ss
63114 ORDER BY
64- sm .challenge_id ,
65- sm .user_id ,
66- sm .submitted_date DESC NULLS LAST,
67- sm .submission_id DESC
115+ ss .challenge_id ,
116+ ss .user_id ,
117+ ss .submitted_date DESC NULLS LAST,
118+ ss .updated_date DESC NULLS LAST,
119+ ss .submission_id DESC
120+ ),
121+ -- A match is "complete" only when at least one submission carries an isFinal summation.
122+ -- Until then the leaderboard is ranked on the provisional/standard score.
123+ challenge_progress AS (
124+ SELECT
125+ challenge_id,
126+ BOOL_OR(is_strict_final AND final_score IS NOT NULL ) AS has_final_results
127+ FROM unique_member_submissions
128+ GROUP BY challenge_id
68129),
69130ranked_submissions AS (
70131 SELECT
71132 ums .challenge_id ,
72- ums .user_id AS " userId" ,
73- ums .submission_id AS " submissionId" ,
74- ums .handle AS handle,
133+ ums .challenge_name ,
134+ ums .is_marathon_match ,
135+ ums .user_id ,
136+ ums .submission_id ,
137+ ums .handle ,
138+ ums .name ,
139+ ums .country_code ,
140+ ums .photo_url ,
141+ ums .rating ,
142+ ums .rating_color ,
143+ ums .final_score ,
144+ ums .provisional_score ,
145+ COALESCE(ums .final_score , ums .provisional_score ) AS standard_score,
146+ ums .submitted_date ,
75147 ROW_NUMBER() OVER (
76148 PARTITION BY ums .challenge_id
77- ORDER BY ums .final_score_raw DESC NULLS LAST, ums .submitted_date ASC NULLS LAST, ums .user_id ASC
149+ ORDER BY
150+ CASE
151+ WHEN cp .has_final_results THEN ums .final_score
152+ ELSE COALESCE(ums .final_score , ums .provisional_score )
153+ END DESC NULLS LAST,
154+ ums .submitted_date ASC NULLS LAST,
155+ ums .user_id ASC
78156 ) AS placement,
79- ums .provisional_score AS " provisionalScore" ,
80- ums .final_score_raw AS " finalScore" ,
81- ums .standard_score AS score
157+ ROW_NUMBER() OVER (
158+ PARTITION BY ums .challenge_id
159+ ORDER BY
160+ ums .provisional_score DESC NULLS LAST,
161+ ums .submitted_date ASC NULLS LAST,
162+ ums .user_id ASC
163+ ) AS provisional_rank
82164 FROM unique_member_submissions AS ums
165+ JOIN challenge_progress AS cp
166+ ON cp .challenge_id = ums .challenge_id
83167)
84168SELECT
85- cc .challenge_id AS " challengeId" ,
86- cc .challenge_name AS " challengeName" ,
87- rs." userId" ,
88- rs." submissionId" ,
169+ rs .challenge_id AS " challengeId" ,
170+ rs .challenge_name AS " challengeName" ,
171+ rs .is_marathon_match AS " isMarathonMatch" ,
172+ rs .user_id AS " userId" ,
173+ rs .submission_id AS " submissionId" ,
89174 rs .handle ,
175+ rs .name ,
176+ COALESCE(
177+ comp_code .name ,
178+ comp_id .name ,
179+ NULLIF(TRIM (rs .country_code ), ' ' )
180+ ) AS country,
181+ NULLIF(TRIM (rs .country_code ), ' ' ) AS " countryCode" ,
182+ rs .photo_url AS " photoURL" ,
183+ rs .rating AS rating,
184+ rs .rating_color AS " ratingColor" ,
90185 rs .placement ,
91- rs." provisionalScore" ,
92- rs." finalScore" ,
93- rs .score
186+ rs .provisional_rank AS " provisionalRank" ,
187+ -- Match the legacy formatting: 2 decimals, with anything in (0, 0.01) pinned to 0.01
188+ -- so a non-zero score never renders as 0.
189+ CASE
190+ WHEN rs .provisional_score IS NULL THEN NULL
191+ WHEN rs .provisional_score > 0 AND rs .provisional_score < 0 .01 THEN 0 .01
192+ ELSE ROUND(rs .provisional_score ::numeric , 2 )::double precision
193+ END AS " provisionalScore" ,
194+ CASE
195+ WHEN rs .final_score IS NULL THEN NULL
196+ WHEN rs .final_score > 0 AND rs .final_score < 0 .01 THEN 0 .01
197+ ELSE ROUND(rs .final_score ::numeric , 2 )::double precision
198+ END AS " finalScore" ,
199+ CASE
200+ WHEN rs .standard_score IS NULL THEN NULL
201+ WHEN rs .standard_score > 0 AND rs .standard_score < 0 .01 THEN 0 .01
202+ ELSE ROUND(rs .standard_score ::numeric , 2 )::double precision
203+ END AS score,
204+ rs .submitted_date AS " submittedDate"
94205FROM ranked_submissions AS rs
95- JOIN challenge_context AS cc
96- ON cc .challenge_id = rs .challenge_id
206+ LEFT JOIN lookups." Country" AS comp_code
207+ ON UPPER (comp_code." countryCode" ) = UPPER (rs .country_code )
208+ LEFT JOIN lookups." Country" AS comp_id
209+ ON UPPER (comp_id .id ) = UPPER (rs .country_code )
97210ORDER BY rs .challenge_id , rs .placement ;
0 commit comments