From 149f23c5bdbf9c2a65e9874bdc287b931ec39a46 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 13 Aug 2026 13:44:22 +0300 Subject: [PATCH 1/4] PM-5834 - use submissions count --- sql/reports/topcoder/leaderboard-generic.sql | 3 ++- src/reports/topcoder/topcoder-reports.service.spec.ts | 2 ++ src/reports/topcoder/topcoder-reports.service.ts | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sql/reports/topcoder/leaderboard-generic.sql b/sql/reports/topcoder/leaderboard-generic.sql index ae2cbcc..c61b517 100644 --- a/sql/reports/topcoder/leaderboard-generic.sql +++ b/sql/reports/topcoder/leaderboard-generic.sql @@ -63,7 +63,8 @@ member_submissions AS ( s."initialScore"::double precision ) AS score, COALESCE(s."submittedDate", s."createdAt") AS submitted_date, - cc.duration_days + cc.duration_days, + COUNT(*) OVER (PARTITION BY s."challengeId", s."memberId") AS "userSubmissionsCount" FROM challenge_context AS cc JOIN reviews."submission" AS s ON s."challengeId" = cc.challenge_id diff --git a/src/reports/topcoder/topcoder-reports.service.spec.ts b/src/reports/topcoder/topcoder-reports.service.spec.ts index 04cea85..24a4a36 100644 --- a/src/reports/topcoder/topcoder-reports.service.spec.ts +++ b/src/reports/topcoder/topcoder-reports.service.spec.ts @@ -197,6 +197,7 @@ describe("TopcoderReportsService", () => { ratingColor: "#000000", score: 123, submittedDate: "2026-08-13T00:00:00Z", + submissionCount: 1, placement: 1, challengeStatus: "ACTIVE", isAiOnlyChallenge: true, @@ -223,6 +224,7 @@ describe("TopcoderReportsService", () => { score: 123, isProvisional: true, }); + expect(resultWithRealtime.placementData[0].submissionCount).toBe(1); db.query.mockResolvedValueOnce([genericRow]); diff --git a/src/reports/topcoder/topcoder-reports.service.ts b/src/reports/topcoder/topcoder-reports.service.ts index f6e3114..f30f149 100644 --- a/src/reports/topcoder/topcoder-reports.service.ts +++ b/src/reports/topcoder/topcoder-reports.service.ts @@ -120,6 +120,7 @@ type LeaderboardGenericRow = { placement: number; challengeStatus: string; isAiOnlyChallenge: boolean; + userSubmissionsCount: number; }; type LeaderboardMmRow = { @@ -1068,6 +1069,7 @@ export class TopcoderReportsService implements OnModuleDestroy { wins: {}, points: 0, prizes: 0, + submissionCount: 0, rating: row.rating as number, ratingColor: row.ratingColor, challengeScores: {}, @@ -1082,6 +1084,7 @@ export class TopcoderReportsService implements OnModuleDestroy { const pointsByWin = log / sqrt; entriesByUser[row.userId].points += pointsByWin; + entriesByUser[row.userId].submissionCount += Number(row.userSubmissionsCount ?? 0); entriesByUser[row.userId].wins[row.challengeId] = pointsByWin; entriesByUser[row.userId].challengeScores[row.challengeId] = { score: row.score, @@ -1116,6 +1119,7 @@ export class TopcoderReportsService implements OnModuleDestroy { prizes: useCmsPlacementPrizes ? (cmsPlacementPrizeAmounts[index] ?? 0) : entry.prizes, + submissionCount: entry.submissionCount, })); return { From 88e8b66ce48663e603e6f848b23f4903dec27c9e Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 13 Aug 2026 13:56:37 +0300 Subject: [PATCH 2/4] lint --- src/reports/topcoder/topcoder-reports.service.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/reports/topcoder/topcoder-reports.service.ts b/src/reports/topcoder/topcoder-reports.service.ts index f30f149..cb9cc54 100644 --- a/src/reports/topcoder/topcoder-reports.service.ts +++ b/src/reports/topcoder/topcoder-reports.service.ts @@ -1047,6 +1047,7 @@ export class TopcoderReportsService implements OnModuleDestroy { string, { score: number; isProvisional: boolean } >; + submissionCount: number; } > = {}; @@ -1084,7 +1085,9 @@ export class TopcoderReportsService implements OnModuleDestroy { const pointsByWin = log / sqrt; entriesByUser[row.userId].points += pointsByWin; - entriesByUser[row.userId].submissionCount += Number(row.userSubmissionsCount ?? 0); + entriesByUser[row.userId].submissionCount += Number( + row.userSubmissionsCount ?? 0, + ); entriesByUser[row.userId].wins[row.challengeId] = pointsByWin; entriesByUser[row.userId].challengeScores[row.challengeId] = { score: row.score, From 181b538b57d05028f0aae1ba524daab006ce5544 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 13 Aug 2026 15:25:16 +0300 Subject: [PATCH 3/4] Submissions count for generic leaderboard --- sql/reports/topcoder/leaderboard-generic.sql | 15 +++++++++++++++ src/reports/topcoder/topcoder-reports.service.ts | 12 ++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sql/reports/topcoder/leaderboard-generic.sql b/sql/reports/topcoder/leaderboard-generic.sql index c61b517..57a0aee 100644 --- a/sql/reports/topcoder/leaderboard-generic.sql +++ b/sql/reports/topcoder/leaderboard-generic.sql @@ -159,6 +159,17 @@ unique_member_submissions AS ( ms.submitted_date DESC NULLS LAST, ms.submission_id DESC ), +member_submission_counts AS ( + SELECT + cc.challenge_id, + s."memberId" AS user_id, + COUNT(*) AS submission_count + FROM challenge_context AS cc + JOIN reviews."submission" AS s + ON s."challengeId" = cc.challenge_id + AND s."memberId" IS NOT NULL + GROUP BY cc.challenge_id, s."memberId" +), challenge_prizes AS ( SELECT cps."challengeId" AS challenge_id, @@ -216,6 +227,7 @@ SELECT ums.ratingColor AS "ratingColor", ums.score AS score, ums.submitted_date AS submitted_date, + COALESCE(msc.submission_count, 1) AS "submissionCount", ROW_NUMBER() OVER ( PARTITION BY ums.challenge_id ORDER BY ums.score DESC NULLS LAST, ums.submitted_date ASC NULLS LAST, ums.user_id ASC @@ -229,6 +241,9 @@ LEFT JOIN lookups."Country" AS comp_code ON UPPER(comp_code."countryCode") = UPPER(ums.country_code) LEFT JOIN lookups."Country" AS comp_id ON UPPER(comp_id.id) = UPPER(ums.country_code) +LEFT JOIN member_submission_counts AS msc + ON msc.challenge_id = ums.challenge_id + AND msc.user_id = ums.user_id JOIN challenge_summary AS cs ON cs.challenge_id = ums.challenge_id ORDER BY ums.challenge_id, ums.score DESC NULLS LAST, ums.submitted_date ASC NULLS LAST, ums.user_id ASC; diff --git a/src/reports/topcoder/topcoder-reports.service.ts b/src/reports/topcoder/topcoder-reports.service.ts index cb9cc54..0db30b8 100644 --- a/src/reports/topcoder/topcoder-reports.service.ts +++ b/src/reports/topcoder/topcoder-reports.service.ts @@ -117,6 +117,7 @@ type LeaderboardGenericRow = { ratingColor: string | null; score: number; submittedDate: string; + submissionCount: string | number | null; placement: number; challengeStatus: string; isAiOnlyChallenge: boolean; @@ -1040,6 +1041,7 @@ export class TopcoderReportsService implements OnModuleDestroy { wins: Record; points: number; prizes: number; + submissionCount: number; photoURL: string | null; rating: number; ratingColor: string | null; @@ -1047,7 +1049,6 @@ export class TopcoderReportsService implements OnModuleDestroy { string, { score: number; isProvisional: boolean } >; - submissionCount: number; } > = {}; @@ -1077,6 +1078,13 @@ export class TopcoderReportsService implements OnModuleDestroy { }; } + const memberSubmissions = Number(row.submissionCount ?? 0); + entriesByUser[row.userId].submissionCount += Number.isFinite( + memberSubmissions, + ) + ? memberSubmissions + : 0; + const log = Math.log10(Math.max(1, row.prizePool)) + row.durationDays * (filters.pointsPerDay ?? 0); @@ -1117,12 +1125,12 @@ export class TopcoderReportsService implements OnModuleDestroy { points: entry.points, wins: entry.wins, challengeScores: entry.challengeScores, + submissionCount: entry.submissionCount, rating: entry.rating, ratingColor: entry.ratingColor, prizes: useCmsPlacementPrizes ? (cmsPlacementPrizeAmounts[index] ?? 0) : entry.prizes, - submissionCount: entry.submissionCount, })); return { From f09b029dc363661ed91c2ff42ee0395d39aa4107 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 13 Aug 2026 15:37:16 +0300 Subject: [PATCH 4/4] clean --- sql/reports/topcoder/leaderboard-generic.sql | 3 +-- src/reports/topcoder/topcoder-reports.service.ts | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sql/reports/topcoder/leaderboard-generic.sql b/sql/reports/topcoder/leaderboard-generic.sql index 57a0aee..8983523 100644 --- a/sql/reports/topcoder/leaderboard-generic.sql +++ b/sql/reports/topcoder/leaderboard-generic.sql @@ -63,8 +63,7 @@ member_submissions AS ( s."initialScore"::double precision ) AS score, COALESCE(s."submittedDate", s."createdAt") AS submitted_date, - cc.duration_days, - COUNT(*) OVER (PARTITION BY s."challengeId", s."memberId") AS "userSubmissionsCount" + cc.duration_days FROM challenge_context AS cc JOIN reviews."submission" AS s ON s."challengeId" = cc.challenge_id diff --git a/src/reports/topcoder/topcoder-reports.service.ts b/src/reports/topcoder/topcoder-reports.service.ts index 0db30b8..fffe496 100644 --- a/src/reports/topcoder/topcoder-reports.service.ts +++ b/src/reports/topcoder/topcoder-reports.service.ts @@ -1093,9 +1093,6 @@ export class TopcoderReportsService implements OnModuleDestroy { const pointsByWin = log / sqrt; entriesByUser[row.userId].points += pointsByWin; - entriesByUser[row.userId].submissionCount += Number( - row.userSubmissionsCount ?? 0, - ); entriesByUser[row.userId].wins[row.challengeId] = pointsByWin; entriesByUser[row.userId].challengeScores[row.challengeId] = { score: row.score,