diff --git a/backend/src/api/controllers/result.ts b/backend/src/api/controllers/result.ts index dba0dead7..df27cb765 100644 --- a/backend/src/api/controllers/result.ts +++ b/backend/src/api/controllers/result.ts @@ -329,7 +329,9 @@ export async function addResult( // ); // return res.status(400).json({ message: "Time traveler detected" }); - const { data: lastResult } = await tryCatch(ResultDAL.getLastResult(uid)); + const { data: lastResultTimestamp } = await tryCatch( + ResultDAL.getLastResultTimestamp(uid) + ); //convert result test duration to miliseconds completedEvent.timestamp = Math.floor(Date.now() / 1000) * 1000; @@ -338,16 +340,16 @@ export async function addResult( const testDurationMilis = completedEvent.testDuration * 1000; const incompleteTestsMilis = completedEvent.incompleteTestSeconds * 1000; const earliestPossible = - (lastResult?.timestamp ?? 0) + testDurationMilis + incompleteTestsMilis; + (lastResultTimestamp ?? 0) + testDurationMilis + incompleteTestsMilis; const nowNoMilis = Math.floor(Date.now() / 1000) * 1000; if ( - isSafeNumber(lastResult?.timestamp) && + isSafeNumber(lastResultTimestamp) && nowNoMilis < earliestPossible - 1000 ) { void addLog( "invalid_result_spacing", { - lastTimestamp: lastResult.timestamp, + lastTimestamp: lastResultTimestamp, earliestPossible, now: nowNoMilis, testDuration: testDurationMilis, @@ -590,7 +592,7 @@ export async function addResult( const xpGained = await calculateXp( completedEvent, req.ctx.configuration.users.xp, - uid, + lastResultTimestamp, user.xp ?? 0, streak ); @@ -689,7 +691,7 @@ type XpResult = { async function calculateXp( result: CompletedEvent, xpConfiguration: Configuration["users"]["xp"], - uid: string, + lastResultTimestamp: number | null, currentTotalXp: number, streak: number ): Promise { @@ -802,16 +804,8 @@ async function calculateXp( const accuracyModifier = (acc - 50) / 50; let dailyBonus = 0; - const { data: lastResult, error: getLastResultError } = await tryCatch( - ResultDAL.getLastResult(uid) - ); - - if (getLastResultError) { - Logger.error(`Could not fetch last result: ${getLastResultError}`); - } - - if (isSafeNumber(lastResult?.timestamp)) { - const lastResultDay = getStartOfDayTimestamp(lastResult.timestamp); + if (isSafeNumber(lastResultTimestamp)) { + const lastResultDay = getStartOfDayTimestamp(lastResultTimestamp); const today = getCurrentDayTimestamp(); if (lastResultDay !== today) { const proportionalXp = Math.round(currentTotalXp * 0.05); diff --git a/backend/src/dal/result.ts b/backend/src/dal/result.ts index 499734086..4ba066b32 100644 --- a/backend/src/dal/result.ts +++ b/backend/src/dal/result.ts @@ -75,10 +75,20 @@ export async function getLastResult(uid: string): Promise { .sort({ timestamp: -1 }) .limit(1) .toArray(); - if (!lastResult) throw new MonkeyError(404, "No results found"); + if (!lastResult) throw new MonkeyError(404, "No last result found"); return convert(lastResult); } +export async function getLastResultTimestamp(uid: string): Promise { + const [lastResult] = await getResultCollection() + .find({ uid }, { projection: { timestamp: 1, _id: 0 } }) + .sort({ timestamp: -1 }) + .limit(1) + .toArray(); + if (!lastResult) throw new MonkeyError(404, "No last result found"); + return lastResult.timestamp; +} + export async function getResultByTimestamp( uid: string, timestamp: number