From 377b8b133bec96293af02d44b0a111c632bb492c Mon Sep 17 00:00:00 2001 From: HutchyBen <38333275+HutchyBen@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:57:06 +0000 Subject: [PATCH 1/3] Set a default of 0 when a rating value is null when calculating rank --- typescript/server/src/utils/user.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/server/src/utils/user.ts b/typescript/server/src/utils/user.ts index 581abb093d..0e38d385b8 100644 --- a/typescript/server/src/utils/user.ts +++ b/typescript/server/src/utils/user.ts @@ -199,7 +199,7 @@ export async function GetUsersRankingAndOutOf( const result = await DB.selectFrom("game_profile") .select([ (eb) => eb.fn.countAll().as("out_of"), - sql`COUNT(*) FILTER (WHERE (ratings->>${ratingAlg})::numeric > ${userRating})`.as( + sql`COUNT(*) FILTER (WHERE (ratings->>${ratingAlg})::numeric > ${userRating ?? 0})`.as( "ranking_count", ), ]) From 209107f40b48015c2484d46672031b94e382f6b0 Mon Sep 17 00:00:00 2001 From: HutchyBen <38333275+HutchyBen@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:50:51 +0000 Subject: [PATCH 2/3] make null values be last place --- typescript/server/src/utils/user.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/typescript/server/src/utils/user.ts b/typescript/server/src/utils/user.ts index 0e38d385b8..194c6425a3 100644 --- a/typescript/server/src/utils/user.ts +++ b/typescript/server/src/utils/user.ts @@ -199,9 +199,13 @@ export async function GetUsersRankingAndOutOf( const result = await DB.selectFrom("game_profile") .select([ (eb) => eb.fn.countAll().as("out_of"), - sql`COUNT(*) FILTER (WHERE (ratings->>${ratingAlg})::numeric > ${userRating ?? 0})`.as( - "ranking_count", - ), + sql`COUNT(*) FILTER ( + WHERE user_id != ${stats.userID} -- itll include self when null, doesnt affect normal ranking + AND ( + (ratings->>${ratingAlg})::numeric > ${userRating}::numeric + OR ${userRating}::numeric IS NULL + ) + )`.as("ranking_count"), ]) .where("game", "=", stats.game) .executeTakeFirstOrThrow(); From e3f2233e615573cc1072820a5306fc2b840d4af2 Mon Sep 17 00:00:00 2001 From: HutchyBen <38333275+HutchyBen@users.noreply.github.com> Date: Tue, 16 Jun 2026 19:55:59 +0000 Subject: [PATCH 3/3] adjust test for new null rating case --- typescript/server/src/utils/user.test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/typescript/server/src/utils/user.test.ts b/typescript/server/src/utils/user.test.ts index 5005e863bd..396f6cc3bf 100644 --- a/typescript/server/src/utils/user.test.ts +++ b/typescript/server/src/utils/user.test.ts @@ -131,15 +131,17 @@ describe("GetUsersRankingAndOutOf", () => { expect(result).toEqual({ ranking: 1, outOf: 2 }); }); - it("returns ranking 1 when user rating is null (no one can be strictly greater than null)", async () => { + it("returns worst ranking when user rating is null", async () => { const user1 = await seedUser({ username: "null_rater" }); const user2 = await seedUser({ username: "other_player" }); + const user3 = await seedUser({ username: "other_better_player" }); await seedGameStats(user1.id, null); - await seedGameStats(user2.id, 10); + await seedGameStats(user2.id, 0); + await seedGameStats(user3.id, 10); const result = await GetUsersRankingAndOutOf(makeStats(user1.id, null)); - expect(result).toEqual({ ranking: 1, outOf: 2 }); + expect(result).toEqual({ ranking: 3, outOf: 3 }); }); it("does not include rows from different games in the count", async () => {