diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/router.ts index 9ba386131..f1b8a0471 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/router.ts @@ -1,9 +1,70 @@ import { Router } from "express"; +import { FormatGame } from "tachi-common"; +import { + GetRecentlyAchievedGoals, + GetRecentlyAchievedMilestones, + GetRecentlyInteractedGoals, + GetRecentlyInteractedMilestones, +} from "utils/db"; +import { GetGPT } from "utils/req-tachi-data"; import goalsRouter from "./goals/router"; import milestonesRouter from "./milestones/router"; const router: Router = Router({ mergeParams: true }); +/** + * Retrieve all of this game's recently achieved goals and milestones. + * + * @name GET /api/v1/games/:game/:playtype/targets/recently-achieved + */ +router.get("/recently-achieved", async (req, res) => { + const { game, playtype } = GetGPT(req); + + const [{ goals, goalSubs }, { milestones, milestoneSubs }] = await Promise.all([ + GetRecentlyAchievedGoals({ game, playtype }), + GetRecentlyAchievedMilestones({ game, playtype }), + ]); + + return res.status(200).json({ + success: true, + description: `Retrieved some recently achieved goals for ${FormatGame(game, playtype)}`, + body: { + goals, + goalSubs, + milestones, + milestoneSubs, + }, + }); +}); + +/** + * Retrieve all of this game's recently interacted-with goals and milestones. + * + * @name GET /api/v1/games/:game/:playtype/targets/recently-interacted + */ +router.get("/recently-interacted", async (req, res) => { + const { game, playtype } = GetGPT(req); + + const [{ goals, goalSubs }, { milestones, milestoneSubs }] = await Promise.all([ + GetRecentlyInteractedGoals({ game, playtype }), + GetRecentlyInteractedMilestones({ game, playtype }), + ]); + + return res.status(200).json({ + success: true, + description: `Retrieved some recently interacted-with goals for ${FormatGame( + game, + playtype + )}`, + body: { + goals, + goalSubs, + milestones, + milestoneSubs, + }, + }); +}); + router.use("/goals", goalsRouter); router.use("/milestones", milestonesRouter); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts index 320785fb6..df1ef4c1f 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts @@ -1,5 +1,10 @@ import { Router } from "express"; -import db from "external/mongo/db"; +import { + GetRecentlyAchievedGoals, + GetRecentlyAchievedMilestones, + GetRecentlyInteractedGoals, + GetRecentlyInteractedMilestones, +} from "utils/db"; import { GetUGPT } from "utils/req-tachi-data"; import goalsRouter from "./goals/router"; import milestonesRouter from "./milestones/router"; @@ -16,45 +21,10 @@ router.get("/recently-achieved", async (req, res) => { const userID = user.id; - const recentlyAchievedGoalSubs = await db["goal-subs"].find( - { - game, - playtype, - achieved: true, - wasInstantlyAchieved: false, - userID, - }, - { - sort: { - timeAchieved: -1, - }, - limit: 50, - } - ); - - const recentlyAchievedMilestoneSubs = await db["milestone-subs"].find( - { - game, - playtype, - achieved: true, - wasInstantlyAchieved: false, - userID, - }, - { - sort: { - timeAchieved: -1, - }, - limit: 10, - } - ); - - const goals = await db.goals.find({ - goalID: { $in: recentlyAchievedGoalSubs.map((e) => e.goalID) }, - }); - - const milestones = await db.milestones.find({ - milestoneID: { $in: recentlyAchievedMilestoneSubs.map((e) => e.milestoneID) }, - }); + const [{ goals, goalSubs }, { milestones, milestoneSubs }] = await Promise.all([ + GetRecentlyAchievedGoals({ userID, game, playtype }), + GetRecentlyAchievedMilestones({ userID, game, playtype }), + ]); return res.status(200).json({ success: true, @@ -62,8 +32,8 @@ router.get("/recently-achieved", async (req, res) => { body: { goals, milestones, - goalSubs: recentlyAchievedGoalSubs, - milestoneSubs: recentlyAchievedMilestoneSubs, + goalSubs, + milestoneSubs, user, }, }); @@ -79,45 +49,10 @@ router.get("/recently-interacted", async (req, res) => { const userID = user.id; - const recentlyAchievedGoalSubs = await db["goal-subs"].find( - { - game, - playtype, - wasInstantlyAchieved: false, - userID, - lastInteraction: { $ne: null }, - }, - { - sort: { - lastInteraction: -1, - }, - limit: 50, - } - ); - - const recentlyAchievedMilestoneSubs = await db["milestone-subs"].find( - { - game, - playtype, - wasInstantlyAchieved: false, - userID, - lastInteraction: { $ne: null }, - }, - { - sort: { - lastInteraction: -1, - }, - limit: 10, - } - ); - - const goals = await db.goals.find({ - goalID: { $in: recentlyAchievedGoalSubs.map((e) => e.goalID) }, - }); - - const milestones = await db.milestones.find({ - milestoneID: { $in: recentlyAchievedMilestoneSubs.map((e) => e.milestoneID) }, - }); + const [{ goals, goalSubs }, { milestones, milestoneSubs }] = await Promise.all([ + GetRecentlyInteractedGoals({ userID, game, playtype }), + GetRecentlyInteractedMilestones({ userID, game, playtype }), + ]); return res.status(200).json({ success: true, @@ -125,8 +60,8 @@ router.get("/recently-interacted", async (req, res) => { body: { goals, milestones, - goalSubs: recentlyAchievedGoalSubs, - milestoneSubs: recentlyAchievedMilestoneSubs, + goalSubs, + milestoneSubs, user, }, }); diff --git a/server/src/utils/db.ts b/server/src/utils/db.ts index 38aefab15..8f915205e 100644 --- a/server/src/utils/db.ts +++ b/server/src/utils/db.ts @@ -1,6 +1,15 @@ import db from "external/mongo/db"; import CreateLogCtx from "lib/logger/logger"; -import { FormatChart, Game, integer, PBScoreDocument, ScoreDocument } from "tachi-common"; +import { FilterQuery } from "mongodb"; +import { + FormatChart, + Game, + GoalSubscriptionDocument, + integer, + MilestoneSubscriptionDocument, + PBScoreDocument, + ScoreDocument, +} from "tachi-common"; const logger = CreateLogCtx(__filename); export async function GetNextCounterValue(counterName: string): Promise { @@ -153,3 +162,133 @@ export async function HumaniseChartID(game: Game, chartID: string) { return FormatChart(game, song, chart); } + +/** + * Get recently achieved goals for this query. + * + * @param baseQuery - A base query, used to limit results on GPTs or UGPTs. + * @param limit - How many recently achieved goals to search for. + * @returns - The goals and their subs. + */ +export async function GetRecentlyAchievedGoals( + baseQuery: FilterQuery, + limit = 50 +) { + const query = Object.assign( + { + wasInstantlyAchieved: false, + achieved: true, + }, + baseQuery + ); + + const goalSubs = await db["goal-subs"].find(query, { + sort: { + timeAchieved: -1, + }, + limit, + }); + + const goals = await db.goals.find({ + goalID: { $in: goalSubs.map((e) => e.goalID) }, + }); + + return { goals, goalSubs }; +} + +/** + * Get recently interacted-with goals for this query. + * + * @param baseQuery - A base query, used to limit results on GPTs or UGPTs. + * @param limit - How many recently achieved goals to search for. + * @returns - The goals and their subs. + */ +export async function GetRecentlyInteractedGoals( + baseQuery: FilterQuery, + limit = 50 +) { + const query = Object.assign( + { + lastInteraction: { $ne: null }, + }, + baseQuery + ); + + const goalSubs = await db["goal-subs"].find(query, { + sort: { + lastInteraction: -1, + }, + limit, + }); + + const goals = await db.goals.find({ + goalID: { $in: goalSubs.map((e) => e.goalID) }, + }); + + return { goals, goalSubs }; +} + +/** + * Get recently achieved goals for this query. + * + * @param baseQuery - A base query, used to limit results on GPTs or UGPTs. + * @param limit - How many recently achieved goals to search for. + * @returns - The goals and their subs. + */ +export async function GetRecentlyAchievedMilestones( + baseQuery: FilterQuery, + limit = 50 +) { + const query = Object.assign( + { + wasInstantlyAchieved: false, + achieved: true, + }, + baseQuery + ); + + const milestoneSubs = await db["milestone-subs"].find(query, { + sort: { + timeAchieved: -1, + }, + limit, + }); + + const milestones = await db.goals.find({ + goalID: { $in: milestoneSubs.map((e) => e.milestoneID) }, + }); + + return { milestones, milestoneSubs }; +} + +/** + * Get recently interacted-with milestones for this query. + * + * @param baseQuery - A base query, used to limit results on GPTs or UGPTs. + * @param limit - How many recently achieved milestones to search for. + * @returns - The milestones and their subs. + */ +export async function GetRecentlyInteractedMilestones( + baseQuery: FilterQuery, + limit = 50 +) { + const query = Object.assign( + { + lastInteraction: { $ne: null }, + }, + baseQuery + ); + + const milestoneSubs = await db["milestone-subs"].find(query, { + sort: { + lastInteraction: -1, + }, + limit, + }); + + const milestones = await db.goals.find({ + milestoneID: { $in: milestoneSubs.map((e) => e.milestoneID) }, + }); + + return { milestones, milestoneSubs }; +}