diff --git a/server/src/lib/score-import/framework/user-game-stats/classes.test.ts b/server/src/lib/score-import/framework/user-game-stats/classes.test.ts index d5d32a2a3..24943e0bc 100644 --- a/server/src/lib/score-import/framework/user-game-stats/classes.test.ts +++ b/server/src/lib/score-import/framework/user-game-stats/classes.test.ts @@ -2,7 +2,7 @@ import { UserGameStats } from "tachi-common"; import t from "tap"; import CreateLogCtx from "lib/logger/logger"; import ResetDBState from "test-utils/resets"; -import { CalculateClassDeltas, UpdateUGSClasses } from "./classes"; +import { ProcessClassDeltas, UpdateUGSClasses } from "./classes"; import { GitadoraColours } from "lib/constants/classes"; @@ -45,14 +45,15 @@ t.test("#UpdateUGSClasses", (t) => { t.end(); }); -t.test("#CalculateClassDeltas", (t) => { +t.test("#ProcessClassDeltas", (t) => { t.beforeEach(ResetDBState); - t.test("Should return improved classes from null", (t) => { - const res = CalculateClassDeltas("SP", { dan: 18 }, null, 1, logger); + t.test("Should return improved classes from null", async (t) => { + const res = await ProcessClassDeltas("iidx", "SP", { dan: 18 }, null, 1, logger); t.strictSame(res, [ { + game: "iidx", set: "dan", playtype: "SP", old: null, @@ -63,8 +64,9 @@ t.test("#CalculateClassDeltas", (t) => { t.end(); }); - t.test("Should return improved classes from null class", (t) => { - const res = CalculateClassDeltas( + t.test("Should return improved classes from null class", async (t) => { + const res = await ProcessClassDeltas( + "iidx", "SP", { dan: 18 }, { classes: {} } as UserGameStats, @@ -74,6 +76,7 @@ t.test("#CalculateClassDeltas", (t) => { t.strictSame(res, [ { + game: "iidx", set: "dan", playtype: "SP", old: null, @@ -84,8 +87,9 @@ t.test("#CalculateClassDeltas", (t) => { t.end(); }); - t.test("Should return improved classes", (t) => { - const res = CalculateClassDeltas( + t.test("Should return improved classes", async (t) => { + const res = await ProcessClassDeltas( + "iidx", "SP", { dan: 18 }, { classes: { dan: 17 } } as unknown as UserGameStats, @@ -95,6 +99,7 @@ t.test("#CalculateClassDeltas", (t) => { t.strictSame(res, [ { + game: "iidx", set: "dan", playtype: "SP", old: 17, @@ -105,8 +110,9 @@ t.test("#CalculateClassDeltas", (t) => { t.end(); }); - t.test("Should not return identical classes", (t) => { - const res = CalculateClassDeltas( + t.test("Should not return identical classes", async (t) => { + const res = await ProcessClassDeltas( + "iidx", "SP", { dan: 18 }, { classes: { dan: 18 } } as unknown as UserGameStats, @@ -119,8 +125,9 @@ t.test("#CalculateClassDeltas", (t) => { t.end(); }); - t.test("Should not return worse classes", (t) => { - const res = CalculateClassDeltas( + t.test("Should not return worse classes", async (t) => { + const res = await ProcessClassDeltas( + "iidx", "SP", { dan: 16 }, { classes: { dan: 18 } } as unknown as UserGameStats, diff --git a/server/src/lib/score-import/framework/user-game-stats/classes.ts b/server/src/lib/score-import/framework/user-game-stats/classes.ts index 8f1c41002..9ecdc3a2f 100644 --- a/server/src/lib/score-import/framework/user-game-stats/classes.ts +++ b/server/src/lib/score-import/framework/user-game-stats/classes.ts @@ -1,16 +1,16 @@ -import { Game, Playtypes, integer, UserGameStats, ClassDelta, IDStrings } from "tachi-common"; -import { GameClasses } from "tachi-common/js/game-classes"; import deepmerge from "deepmerge"; +import db from "external/mongo/db"; import { KtLogger } from "lib/logger/logger"; +import { EmitWebhookEvent } from "lib/webhooks/webhooks"; +import { ClassDelta, Game, IDStrings, integer, Playtypes, UserGameStats } from "tachi-common"; +import { GameClasses } from "tachi-common/js/game-classes"; +import { ReturnClassIfGreater } from "utils/class"; import { CalculateChunithmColour, CalculateGitadoraColour, CalculateSDVXClass, } from "./builtin-class-handlers"; -import { ReturnClassIfGreater } from "utils/class"; -import { RedisPub } from "external/redis/redis-IPC"; import { ClassHandler, ScoreClasses } from "./types"; -import { EmitWebhookEvent } from "lib/webhooks/webhooks"; type ClassHandlerMap = { [G in Game]: @@ -110,17 +110,20 @@ export async function UpdateUGSClasses( * This is for calculating scenarios where a users class has improved (i.e. they have gone from 9th dan to 10th dan). * * Knowing this information allows us to attach it onto the import, and also emit things on redis - * so that other services can listen for it. In the future we might allow webhooks, too. + * s**This function emits webhook events and inserts classachieved documents into the DB!** */ -export function CalculateClassDeltas( +export async function ProcessClassDeltas( + game: Game, playtype: Playtypes[Game], classes: ScoreClasses, userGameStats: UserGameStats | null, userID: integer, logger: KtLogger -): ClassDelta[] { +): Promise { const deltas: ClassDelta[] = []; + const updateOps = []; + for (const s in classes) { const classSet = s as keyof GameClasses; const classVal = classes[classSet]; @@ -139,6 +142,7 @@ export function CalculateClassDeltas( let delta: ClassDelta; if (isGreater === null) { delta = { + game, set: classSet, playtype, old: null, @@ -146,6 +150,7 @@ export function CalculateClassDeltas( }; } else { delta = { + game, set: classSet, playtype, old: userGameStats!.classes[classSet]!, @@ -155,6 +160,16 @@ export function CalculateClassDeltas( EmitWebhookEvent({ type: "class-update/v1", content: { userID, ...delta } }); + updateOps.push({ + userID, + classSet: delta.set, + classOldValue: delta.old, + classValue: delta.new, + game, + playtype, + timeAchieved: Date.now(), + }); + deltas.push(delta); } } catch (err) { @@ -162,5 +177,7 @@ export function CalculateClassDeltas( } } + await db["class-achievements"].insert(updateOps); + return deltas; }