diff --git a/typescript/server/src/lib/folders/folders.ts b/typescript/server/src/lib/folders/folders.ts index 3986a23e4..faa52ccf3 100644 --- a/typescript/server/src/lib/folders/folders.ts +++ b/typescript/server/src/lib/folders/folders.ts @@ -285,9 +285,7 @@ export async function GetEnumDistForFolderAsOf( .where("score.user_id", "=", userID) .where("score.game", "=", v3Game) .where("score.chart_id", "in", chartIDs) - .where((eb) => - eb.or([eb("score.time_added", "is", null), eb("score.time_added", "<", beforeIso)]), - ) + .where("score.time_achieved", "<", beforeIso) .execute(); const maxByChart = new Map>(); diff --git a/typescript/server/src/lib/game-specific/custom-bms-tables.ts b/typescript/server/src/lib/game-specific/custom-bms-tables.ts index e8695feb6..43e7a9016 100644 --- a/typescript/server/src/lib/game-specific/custom-bms-tables.ts +++ b/typescript/server/src/lib/game-specific/custom-bms-tables.ts @@ -11,7 +11,7 @@ import { GetFoldersFromTable, GetTableForIDGuaranteed, } from "#utils/folder"; -import { GetRecentUGScores } from "#utils/queries/scores"; +import { GetRecentUGPTScores } from "#utils/queries/scores"; import { REQ_GetGame, REQ_GetUser } from "#utils/req-tachi-data"; import path from "path"; import { @@ -320,7 +320,7 @@ export const CUSTOM_TACHI_BMS_TABLES: Array = [ for (const rival of rivals) { promises.push( (async () => { - const scores = await GetRecentUGScores(rival.id, game); + const scores = await GetRecentUGPTScores(rival.id, game); const data = await GetRelevantSongsAndCharts(scores); const charts = data.charts as unknown as Array< @@ -340,7 +340,7 @@ export const CUSTOM_TACHI_BMS_TABLES: Array = [ promises.push( (async () => { - const scores = await GetRecentUGScores(rival.id, game); + const scores = await GetRecentUGPTScores(rival.id, game); const data = await GetRelevantSongsAndCharts(scores); const charts = data.charts as unknown as Array< diff --git a/typescript/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts b/typescript/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts index 37c1f3b3b..43bfcfda9 100644 --- a/typescript/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts +++ b/typescript/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts @@ -17,6 +17,7 @@ import { } from "#utils/queries/scores"; import { FilterChartsAndSongs } from "#utils/scores"; import { ExpectedErr } from "bliss"; +import { sql } from "kysely"; /** * Searches a user's individual scores. @@ -107,7 +108,7 @@ API_V1_ROUTER.add( .select(SELECT_SCORE_DOCUMENT) .where("score.user_id", "=", user.id) .where("chart.id", "=", chart.chartID) - .orderBy("score.time_added", "desc") + .orderBy(sql`score.time_achieved desc nulls last`) .execute(); return success( diff --git a/typescript/server/src/utils/queries/scores.test.ts b/typescript/server/src/utils/queries/scores.test.ts index b76a6d852..f60aba331 100644 --- a/typescript/server/src/utils/queries/scores.test.ts +++ b/typescript/server/src/utils/queries/scores.test.ts @@ -3,7 +3,7 @@ import { seedUser } from "#test-utils/pg-fixtures"; import { UnixMillisecondsToISO8601 } from "#utils/time"; import { describe, expect, it } from "vitest"; -import { GetRecentUGPTHighlights, GetRecentUGScores } from "./scores"; +import { GetRecentUGPTHighlights, GetRecentUGPTScores } from "./scores"; describe("GetRecentUGPTScores / GetRecentUGPTHighlights (Postgres)", () => { let counter = 0; @@ -11,7 +11,7 @@ describe("GetRecentUGPTScores / GetRecentUGPTHighlights (Postgres)", () => { async function seedIidxScore(opts: { highlight: boolean; scoreId: string; - timeAddedMs: number; + timeAchievedMs: number | null; userId: number; }) { const n = ++counter; @@ -60,32 +60,44 @@ describe("GetRecentUGPTScores / GetRecentUGPTHighlights (Postgres)", () => { judgements: JSON.stringify({}), calculated_data: JSON.stringify({}), meta: JSON.stringify({}), - time_achieved: null, - time_added: UnixMillisecondsToISO8601(opts.timeAddedMs), + time_achieved: + opts.timeAchievedMs !== null + ? UnixMillisecondsToISO8601(opts.timeAchievedMs) + : null, + time_added: new Date().toISOString(), highlight: opts.highlight, comment: null, }) .execute(); } - it("GetRecentUGPTScores orders by time_added desc", async () => { + it("GetRecentUGPTScores orders by time_achieved desc, nulls last", async () => { const { id: userId } = await seedUser(); await seedIidxScore({ userId, scoreId: `sc-old-${Date.now()}`, highlight: false, - timeAddedMs: 1_000_000, + timeAchievedMs: 1_000_000, }); await seedIidxScore({ userId, scoreId: `sc-new-${Date.now()}`, highlight: false, - timeAddedMs: 9_000_000, + timeAchievedMs: 9_000_000, + }); + await seedIidxScore({ + userId, + scoreId: `sc-null-${Date.now()}`, + highlight: false, + timeAchievedMs: null, }); - const scores = await GetRecentUGScores(userId, "iidx-sp", 10); - expect(scores.length).toBeGreaterThanOrEqual(2); - expect(scores[0]?.timeAdded).toBeGreaterThanOrEqual(scores[1]?.timeAdded ?? 0); + const scores = await GetRecentUGPTScores(userId, "iidx-sp", 10); + expect(scores.length).toBeGreaterThanOrEqual(3); + // newest play time first + expect(scores[0]?.timeAchieved).toBeGreaterThanOrEqual(scores[1]?.timeAchieved ?? 0); + // null time_achieved sorts last + expect(scores[scores.length - 1]?.timeAchieved).toBeNull(); }); it("GetRecentUGPTHighlights only returns highlight scores", async () => { @@ -95,13 +107,13 @@ describe("GetRecentUGPTScores / GetRecentUGPTHighlights (Postgres)", () => { userId, scoreId: `sc-hl-no-${base}`, highlight: false, - timeAddedMs: base + 1000, + timeAchievedMs: base + 1000, }); await seedIidxScore({ userId, scoreId: `sc-hl-yes-${base}`, highlight: true, - timeAddedMs: base + 2000, + timeAchievedMs: base + 2000, }); const highlights = await GetRecentUGPTHighlights(userId, "iidx-sp", 50); diff --git a/typescript/server/src/utils/queries/scores.ts b/typescript/server/src/utils/queries/scores.ts index 6476de0a0..7782e928e 100644 --- a/typescript/server/src/utils/queries/scores.ts +++ b/typescript/server/src/utils/queries/scores.ts @@ -18,11 +18,11 @@ export function scoreDocumentJoin() { .select(SELECT_SCORE_DOCUMENT); } -export async function GetRecentUGScores(userID: integer, game: V3Game, limit = 100) { +export async function GetRecentUGPTScores(userID: integer, game: V3Game, limit = 100) { const rows = await scoreDocumentJoin() .where("score.user_id", "=", userID) .where("score.game", "=", game) - .orderBy("score.time_added", "desc") + .orderBy(sql`score.time_achieved desc nulls last`) .limit(limit) .execute(); @@ -86,7 +86,7 @@ export async function GetRecentUGPTHighlights(userID: integer, game: V3Game, lim .where("score.user_id", "=", userID) .where("score.game", "=", game) .where("score.highlight", "=", true) - .orderBy("score.time_added", "desc") + .orderBy(sql`score.time_achieved desc nulls last`) .limit(limit) .execute();