From ef0d3a4b243d2c77c60a4ef312da489514a32454 Mon Sep 17 00:00:00 2001 From: Cody <36463298+ugcodrr@users.noreply.github.com> Date: Fri, 30 Oct 2026 15:18:25 -0400 Subject: [PATCH 1/4] perf(api): skip removing leaderboard scores that were already 0 --- apps/api/src/leaderboards/leaderboard.service.ts | 12 ++++++++++-- apps/api/src/player/player.service.ts | 12 +++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/api/src/leaderboards/leaderboard.service.ts b/apps/api/src/leaderboards/leaderboard.service.ts index 58a15af98..5a324e601 100644 --- a/apps/api/src/leaderboards/leaderboard.service.ts +++ b/apps/api/src/leaderboards/leaderboard.service.ts @@ -27,6 +27,10 @@ const DAYS_IN_WEEK = { export type LeaderboardAdditionalStats = Record & { name: string }; +// Leaderboards leave out 0, NaN and anything that isn't a number +const isScore = (value: unknown): value is number => + typeof value === "number" && value !== 0 && !Number.isNaN(value); + @Injectable() export abstract class LeaderboardService { public constructor(@InjectRedis() protected readonly redis: Redis) {} @@ -35,7 +39,8 @@ export abstract class LeaderboardService { constructor: Constructor, instance: Flatten, idField: keyof T, - remove = false + remove = false, + previous?: Flatten | null ) { const fields = getLeaderboardFields(constructor); const transaction = Sentry.getCurrentHub().getScope()?.getTransaction(); @@ -54,7 +59,10 @@ export abstract class LeaderboardService { const value = instance[field] as unknown as number; const key = `${name}.${String(field)}`; - if (remove || value === 0 || Number.isNaN(value) || typeof value !== "number") { + if (remove || !isScore(value)) { + // Redis only has a score for the player if their stored document did + if (previous && !isScore(previous[field] ?? metadata.store.default)) continue; + pipeline.zrem(key, id); continue; } diff --git a/apps/api/src/player/player.service.ts b/apps/api/src/player/player.service.ts index 0d5ad6218..e1be3eaef 100644 --- a/apps/api/src/player/player.service.ts +++ b/apps/api/src/player/player.service.ts @@ -73,7 +73,8 @@ export class PlayerService { if (mongoPlayer && mongoPlayer.username !== player.username) await this.playerSearchService.delete(mongoPlayer.username); - const flatPlayer = await this.saveOne(player, true); + // A selector only loads part of the stored document + const flatPlayer = await this.saveOne(player, true, selector ? undefined : mongoPlayer); flatPlayer.isNew = !mongoPlayer; @@ -161,7 +162,11 @@ export class PlayerService { return true; } - public async saveOne(player: Player, registerAutocomplete: boolean) { + public async saveOne( + player: Player, + registerAutocomplete: boolean, + previous?: Flatten | null + ) { // Serialize and flatten the player const flatPlayer = flatten(player); const serializedPlayer = serialize(Player, flatPlayer); @@ -174,7 +179,8 @@ export class PlayerService { Player, flatPlayer, "uuid", - false + false, + previous ), ]; From cb4895727888e46c63f7be91add81f9014b6b299 Mon Sep 17 00:00:00 2001 From: Cody <36463298+ugcodrr@users.noreply.github.com> Date: Fri, 30 Oct 2026 15:41:27 -0400 Subject: [PATCH 2/4] refactor(api): drop the comment restating isScore --- apps/api/src/leaderboards/leaderboard.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/api/src/leaderboards/leaderboard.service.ts b/apps/api/src/leaderboards/leaderboard.service.ts index 5a324e601..eb7632c2f 100644 --- a/apps/api/src/leaderboards/leaderboard.service.ts +++ b/apps/api/src/leaderboards/leaderboard.service.ts @@ -27,7 +27,6 @@ const DAYS_IN_WEEK = { export type LeaderboardAdditionalStats = Record & { name: string }; -// Leaderboards leave out 0, NaN and anything that isn't a number const isScore = (value: unknown): value is number => typeof value === "number" && value !== 0 && !Number.isNaN(value); From 0e2a4a4c2d047d23e4cce658c6cfe0077feeb510 Mon Sep 17 00:00:00 2001 From: Cody <36463298+ugcodrr@users.noreply.github.com> Date: Thu, 5 Nov 2026 00:10:47 -0500 Subject: [PATCH 3/4] refactor(api): drop the number cast that isScore now narrows --- apps/api/src/leaderboards/leaderboard.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/leaderboards/leaderboard.service.ts b/apps/api/src/leaderboards/leaderboard.service.ts index eb7632c2f..892510fce 100644 --- a/apps/api/src/leaderboards/leaderboard.service.ts +++ b/apps/api/src/leaderboards/leaderboard.service.ts @@ -55,7 +55,7 @@ export abstract class LeaderboardService { const id = instance[idField] as unknown as string; for (const [field, metadata] of fields) { - const value = instance[field] as unknown as number; + const value = instance[field]; const key = `${name}.${String(field)}`; if (remove || !isScore(value)) { From 6983fe9cb66f25d02249ce67f546577ae4eaa9d1 Mon Sep 17 00:00:00 2001 From: Cody <36463298+ugcodrr@users.noreply.github.com> Date: Thu, 5 Nov 2026 00:10:50 -0500 Subject: [PATCH 4/4] refactor(api): drop the comment explaining the skipped zrem --- apps/api/src/leaderboards/leaderboard.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/api/src/leaderboards/leaderboard.service.ts b/apps/api/src/leaderboards/leaderboard.service.ts index 892510fce..06598a862 100644 --- a/apps/api/src/leaderboards/leaderboard.service.ts +++ b/apps/api/src/leaderboards/leaderboard.service.ts @@ -59,7 +59,6 @@ export abstract class LeaderboardService { const key = `${name}.${String(field)}`; if (remove || !isScore(value)) { - // Redis only has a score for the player if their stored document did if (previous && !isScore(previous[field] ?? metadata.store.default)) continue; pipeline.zrem(key, id);