Refactor a lot of endpoints to use GetUGPT

This commit is contained in:
zkldi
2022-04-01 13:47:57 +01:00
parent 4cfdecfded
commit 74a0b2e04f
16 changed files with 237 additions and 114 deletions
+1 -1
View File
@@ -84,7 +84,7 @@
"rimraf": "3.0.2",
"safe-json-stringify": "1.2.0",
"seq-logging": "1.1.1",
"tachi-common": "0.7.8",
"tachi-common": "0.7.9",
"ts-node": "10.4.0",
"tsconfig-paths": "3.12.0",
"typescript": "4.5.5",
+4 -4
View File
@@ -65,7 +65,7 @@ specifiers:
safe-json-stringify: 1.2.0
seq-logging: 1.1.1
supertest: 6.2.2
tachi-common: 0.7.8
tachi-common: 0.7.9
tap: 15.1.6
ts-node: 10.4.0
tsconfig-paths: 3.12.0
@@ -112,7 +112,7 @@ dependencies:
rimraf: 3.0.2
safe-json-stringify: 1.2.0
seq-logging: 1.1.1
tachi-common: 0.7.8
tachi-common: 0.7.9
ts-node: 10.4.0_2615db9039ce432b4abf2fc39ef336ec
tsconfig-paths: 3.12.0
typescript: 4.5.5
@@ -5363,8 +5363,8 @@ packages:
engines: {node: '>= 0.4'}
dev: true
/tachi-common/0.7.8:
resolution: {integrity: sha512-rDT+scIl1WQacdPrEIvM7fenRvkdjEQwMJMBDz1Pf/VQoYvyBeRL0rxjHrd26L8qkg1yPhwVKhs9DZUMnt4QzA==}
/tachi-common/0.7.9:
resolution: {integrity: sha512-q6JMyACbHb7rDSGPv+cZZHZP1XxyQIvuhnQU5jRKYQfn4LkMm6ticHUN7gjSNAVHnwR05VQnulrkc+SOcnn3nQ==}
dependencies:
'@types/mongodb': 3.6.18
dev: false
@@ -26,9 +26,7 @@ router.get("/recently-achieved", async (req, res) => {
game,
playtype,
achieved: true,
// exclude stuff where timeAchieved == timeSet, as they're not really
// goals but rather consequences of milestone assignment.
$expr: { $ne: ["$timeAchieved", "$timeSet"] },
wasInstantlyAchieved: false,
},
{
sort: {
@@ -4,6 +4,7 @@ import { SYMBOL_TachiData } from "lib/constants/tachi";
import { FilterQuery } from "mongodb";
import { GetGamePTConfig, ScoreDocument } from "tachi-common";
import { GetFolderCharts, GetGradeLampDistributionForFolder, GetPBsOnFolder } from "utils/folder";
import { GetUGPT } from "utils/req-tachi-data";
import { ParseStrPositiveInt } from "utils/string-checks";
import { GetFolderFromParam } from "../../../../../../../games/_game/_playtype/folders/middleware";
import { RequireSelfRequestFromUser } from "../../../../../middleware";
@@ -18,7 +19,8 @@ router.use(GetFolderFromParam);
* @name GET /api/v1/users/:userID/games/:game/:playtype/folders/:folderID
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { user } = GetUGPT(req);
const folder = req[SYMBOL_TachiData]!.folderDoc!;
const { songs, charts, pbs } = await GetPBsOnFolder(user.id, folder);
@@ -41,8 +43,9 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/folders/:folderID/stats
*/
router.get("/stats", async (req, res) => {
const { user } = GetUGPT(req);
const folder = req[SYMBOL_TachiData]!.folderDoc!;
const user = req[SYMBOL_TachiData]!.requestedUser!;
const stats = await GetGradeLampDistributionForFolder(user.id, folder);
@@ -64,7 +67,8 @@ router.get("/stats", async (req, res) => {
* @name POST /api/v1/users/:userID/games/:game/:playtype/folders/:folderID/viewed
*/
router.post("/viewed", RequireSelfRequestFromUser, async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { user } = GetUGPT(req);
const folder = req[SYMBOL_TachiData]!.folderDoc!;
await db["recent-folder-views"].update(
@@ -101,10 +105,9 @@ router.post("/viewed", RequireSelfRequestFromUser, async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/folders/:folderID/timeline
*/
router.get("/timeline", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { user, game, playtype } = GetUGPT(req);
const folder = req[SYMBOL_TachiData]!.folderDoc!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const gptConfig = GetGamePTConfig(game, playtype);
const intIndex = ParseStrPositiveInt(req.query.criteriaValue);
@@ -4,6 +4,7 @@ import { SYMBOL_TachiData } from "lib/constants/tachi";
import { SearchCollection } from "lib/search/search";
import { GetGradeLampDistributionForFolders, GetRecentlyViewedFolders } from "utils/folder";
import { IsString } from "utils/misc";
import { GetUGPT } from "utils/req-tachi-data";
import folderIDRouter from "./_folderID/router";
const router: Router = Router({ mergeParams: true });
@@ -21,9 +22,7 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/folders
*/
router.get("/", async (req, res) => {
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { game, playtype, user } = GetUGPT(req);
if (!IsString(req.query.search)) {
return res.status(400).json({
@@ -60,9 +59,7 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/folders/recent
*/
router.get("/recent", async (req, res) => {
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { game, playtype, user } = GetUGPT(req);
const { views, folders } = await GetRecentlyViewedFolders(user.id, game, playtype);
@@ -6,6 +6,7 @@ import { GetGamePTConfig } from "tachi-common";
import { GetRelevantSongsAndCharts } from "utils/db";
import { IsValidScoreAlg } from "utils/misc";
import { GetAdjacentAbove, GetAdjacentBelow } from "utils/queries/pbs";
import { GetUGPT } from "utils/req-tachi-data";
import { FilterChartsAndSongs, GetScoreIDsFromComposed } from "utils/scores";
import { GetUsersWithIDs } from "utils/user";
@@ -19,9 +20,7 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/pbs
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
if (typeof req.query.search !== "string") {
return res.status(400).json({
@@ -71,9 +70,7 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/pbs/all
*/
router.get("/all", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const pbs = await db["personal-bests"].find({
userID: user.id,
@@ -99,9 +96,8 @@ router.get("/all", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/pbs/best
*/
router.get("/best", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const gptConfig = GetGamePTConfig(game, playtype);
if (req.query.alg && !IsValidScoreAlg(gptConfig, req.query.alg)) {
@@ -152,9 +148,7 @@ router.get("/best", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/pbs/:chartID
*/
router.get("/:chartID", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const chart = await db.charts[game].findOne({
chartID: req.params.chartID,
@@ -215,9 +209,7 @@ router.get("/:chartID", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/pbs/:chartID/leaderboard-adjacent
*/
router.get("/:chartID/leaderboard-adjacent", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const chart = await db.charts[game].findOne({
chartID: req.params.chartID,
@@ -3,6 +3,7 @@ import db from "external/mongo/db";
import { SYMBOL_TachiData } from "lib/constants/tachi";
import { GetGamePTConfig, integer, PBScoreDocument, UserGameStatsSnapshot } from "tachi-common";
import { IsString } from "utils/misc";
import { GetUGPT } from "utils/req-tachi-data";
import { CheckStrProfileAlg } from "utils/string-checks";
import {
GetAllRankings,
@@ -29,10 +30,9 @@ router.use(CheckUserPlayedGamePlaytype);
* @name GET /api/v1/users/:userID/games/:game/:playtype
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { game, playtype, user } = GetUGPT(req);
const stats = req[SYMBOL_TachiData]!.requestedUserGameStats!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const [totalScores, firstScore, mostRecentScore, rankingData] = await Promise.all([
db.scores.count({
@@ -87,10 +87,9 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/history
*/
router.get("/history", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { game, playtype, user } = GetUGPT(req);
const stats = req[SYMBOL_TachiData]!.requestedUserGameStats!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const snapshots = (await db["game-stats-snapshots"].find(
{
@@ -133,9 +132,7 @@ router.get("/history", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/most-played
*/
router.get("/most-played", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { game, playtype, user } = GetUGPT(req);
const mostPlayed: { playcount: integer; songID: integer; _id: string }[] =
await db.scores.aggregate([
@@ -208,10 +205,9 @@ router.get("/most-played", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/leaderboard-adjacent
*/
router.get("/leaderboard-adjacent", async (req, res) => {
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { game, playtype, user } = GetUGPT(req);
const gptConfig = GetGamePTConfig(game, playtype);
const user = req[SYMBOL_TachiData]!.requestedUser!;
let alg = gptConfig.defaultProfileRatingAlg;
if (IsString(req.query.alg)) {
@@ -3,6 +3,7 @@ import db from "external/mongo/db";
import { SYMBOL_TachiData } from "lib/constants/tachi";
import { SearchGameSongsAndCharts } from "lib/search/search";
import { GetRelevantSongsAndCharts } from "utils/db";
import { GetUGPT } from "utils/req-tachi-data";
import { FilterChartsAndSongs } from "utils/scores";
const router: Router = Router({ mergeParams: true });
@@ -13,9 +14,7 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/scores
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
if (typeof req.query.search !== "string") {
return res.status(400).json({
@@ -62,9 +61,7 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/scores/recent
*/
router.get("/recent", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const recentScores = await db.scores.find(
{
@@ -99,9 +96,7 @@ router.get("/recent", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/scores/:chartID
*/
router.get("/:chartID", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const chart = await db.charts[game].findOne({
chartID: req.params.chartID,
@@ -13,9 +13,8 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/sessions
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
if (typeof req.query.search !== "string") {
return res.status(400).json({
@@ -41,9 +40,8 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/sessions/best
*/
router.get("/best", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const gptConfig = GetGamePTConfig(game, playtype);
let alg = gptConfig.defaultSessionRatingAlg;
@@ -89,9 +87,8 @@ router.get("/best", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/sessions/highlighted
*/
router.get("/highlighted", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const sessions = await db.sessions.find(
{ userID: user.id, game, playtype, highlight: true },
@@ -111,9 +108,8 @@ router.get("/highlighted", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/sessions/recent
*/
router.get("/recent", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const sessions = await db.sessions.find(
{ userID: user.id, game, playtype },
@@ -133,9 +129,8 @@ router.get("/recent", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/sessions/last
*/
router.get("/last", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const session = await db.sessions.findOne(
{ userID: user.id, game, playtype },
@@ -6,6 +6,7 @@ import p from "prudence";
import { RequirePermissions } from "server/middleware/auth";
import { GetGamePTConfig } from "tachi-common";
import { FormatPrError, optNull } from "utils/prudence";
import { GetUGPT } from "utils/req-tachi-data";
import { FormatUserDoc } from "utils/user";
import { RequireAuthedAsUser } from "../../../../middleware";
@@ -25,9 +26,7 @@ router.patch(
RequireAuthedAsUser,
RequirePermissions("customise_profile"),
async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const gptConfig = GetGamePTConfig(game, playtype);
@@ -170,9 +169,7 @@ router.patch(
* @name GET /api/v1/users/:userID/games/:game/:playtype/settings
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const settings = await db["game-settings"].findOne({
userID: user.id,
@@ -9,6 +9,7 @@ import { RequirePermissions } from "server/middleware/auth";
import { RequireAuthedAsUser } from "server/router/api/v1/users/_userID/middleware";
import { GetGamePTConfig, ShowcaseStatDetails } from "tachi-common";
import { FormatPrError } from "utils/prudence";
import { GetUGPT } from "utils/req-tachi-data";
import { ResolveUser } from "utils/user";
const router: Router = Router({ mergeParams: true });
@@ -20,9 +21,7 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/showcase
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
let projectUser;
@@ -60,9 +59,7 @@ router.get("/", async (req, res) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/showcase/custom
*/
router.get("/custom", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
let stat: ShowcaseStatDetails;
@@ -164,9 +161,7 @@ router.get("/custom", async (req, res) => {
* @name PUT /api/v1/users/:userID/games/:game/:playtype/showcase
*/
router.put("/", RequireAuthedAsUser, RequirePermissions("customise_profile"), async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const gptConfig = GetGamePTConfig(game, playtype);
@@ -1,6 +1,7 @@
import { Router } from "express";
import { SYMBOL_TachiData } from "lib/constants/tachi";
import { GetFoldersFromTable, GetGradeLampDistributionForFolders } from "utils/folder";
import { GetUGPT } from "utils/req-tachi-data";
// @todo maybe refactor where middleware is stored to avoid paths this ugly.
import { GetTableFromParam } from "../../../../../../games/_game/_playtype/tables/middleware";
@@ -12,8 +13,9 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/tables/:tableID
*/
router.get("/:tableID", GetTableFromParam, async (req, res) => {
const { user } = GetUGPT(req);
const table = req[SYMBOL_TachiData]!.tableDoc!;
const user = req[SYMBOL_TachiData]!.requestedUser!;
const folders = await GetFoldersFromTable(table);
@@ -7,7 +7,7 @@ import { GoalDocument, MilestoneDocument } from "tachi-common";
import { ConstructGoal, SubscribeToGoal } from "lib/targets/goals";
import CreateLogCtx from "lib/logger/logger";
import { RequirePermissions } from "server/middleware/auth";
import { AssignToReqTachiData } from "utils/req-tachi-data";
import { AssignToReqTachiData, GetUGPT } from "utils/req-tachi-data";
import { GetGoalForIDGuaranteed, GetMilestoneForIDGuaranteed } from "utils/db";
import { RequireAuthedAsUser } from "../../../../../middleware";
import { SubscribeFailReasons } from "lib/constants/err-codes";
@@ -23,9 +23,7 @@ const logger = CreateLogCtx(__filename);
* @name GET /api/v1/users/:userID/games/:game/:playtype/targets/goals
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const goalSubs = await db["goal-subs"].find({
userID: user.id,
@@ -127,9 +125,7 @@ router.post(
},
}),
async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const existingGoalsCount = await db["goal-subs"].count({
userID: user.id,
@@ -188,9 +184,7 @@ router.post(
);
const GetGoalSubscription: RequestHandler = async (req, res, next) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const goalSub = await db["goal-subs"].findOne({
userID: user.id,
@@ -217,7 +211,8 @@ const GetGoalSubscription: RequestHandler = async (req, res, next) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/targets/goals/:goalID
*/
router.get("/:goalID", GetGoalSubscription, async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { user } = GetUGPT(req);
const goalSub = req[SYMBOL_TachiData]!.goalSubDoc!;
let milestones: MilestoneDocument[] = [];
@@ -255,9 +250,7 @@ router.delete(
prValidate({ goalID: "string" }),
async (req, res) => {
const goalID = req.params.goalID;
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const goalSub = await db["goal-subs"].findOne({
goalID,
@@ -10,7 +10,7 @@ import {
UnsubscribeFromMilestone,
} from "lib/targets/milestones";
import { RequirePermissions } from "server/middleware/auth";
import { AssignToReqTachiData } from "utils/req-tachi-data";
import { AssignToReqTachiData, GetUGPT } from "utils/req-tachi-data";
import { FormatUserDoc } from "utils/user";
import { RequireAuthedAsUser } from "../../../../../middleware";
@@ -24,9 +24,7 @@ const router: Router = Router({ mergeParams: true });
* @name GET /api/v1/users/:userID/games/:game/:playtype/targets/milestones
*/
router.get("/", async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const milestoneSubs = await db["milestone-subs"].find({
userID: user.id,
@@ -49,9 +47,7 @@ router.get("/", async (req, res) => {
});
const GetMilestoneSubscription: RequestHandler = async (req, res, next) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const milestoneSub = await db["milestone-subs"].findOne({
userID: user.id,
@@ -101,7 +97,8 @@ const GetMilestone: RequestHandler = async (req, res, next) => {
* @name GET /api/v1/users/:userID/games/:game/:playtype/targets/milestones/:milestoneID
*/
router.get("/:milestoneID", GetMilestone, GetMilestoneSubscription, async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { user } = GetUGPT(req);
const milestoneSub = req[SYMBOL_TachiData]!.milestoneSubDoc!;
const milestone = req[SYMBOL_TachiData]!.milestoneDoc!;
@@ -134,9 +131,7 @@ router.put(
GetMilestone,
RequirePermissions("manage_targets"),
async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const game = req[SYMBOL_TachiData]!.game!;
const playtype = req[SYMBOL_TachiData]!.playtype!;
const { user, game, playtype } = GetUGPT(req);
const existingMilestonesCount = await db["milestone-subs"].count({
userID: user.id,
@@ -200,7 +195,7 @@ router.delete(
GetMilestone,
RequirePermissions("manage_targets"),
async (req, res) => {
const user = req[SYMBOL_TachiData]!.requestedUser!;
const { user } = GetUGPT(req);
const milestone = req[SYMBOL_TachiData]!.milestoneDoc!;
logger.info(
@@ -1,10 +1,137 @@
import { Router } from "express";
import db from "external/mongo/db";
import { SYMBOL_TachiData } from "lib/constants/tachi";
import { GetUGPT } from "utils/req-tachi-data";
import goalsRouter from "./goals/router";
import milestonesRouter from "./milestones/router";
const router: Router = Router({ mergeParams: true });
/**
* Return a user's recently achieved goals and milestones.
*
* @name GET /api/v1/users/:userID/games/:game/:playtype/targets/recently-achieved
*/
router.get("/recently-achieved", async (req, res) => {
const { game, playtype, user } = GetUGPT(req);
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) },
});
return res.status(200).json({
success: true,
description: `Returned ${user.username}'s recently achieved targets.`,
body: {
goals,
milestones,
goalSubs: recentlyAchievedGoalSubs,
milestoneSubs: recentlyAchievedMilestoneSubs,
user,
},
});
});
/**
* Returns a user's recently interacted with (raised, etc.) goals and milestones.
*
* @name GET /api/v1/users/:userID/games/:game/:playtype/targets/recently-interacted
*/
router.get("/recently-interacted", async (req, res) => {
const { game, playtype, user } = GetUGPT(req);
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,
},
{
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) },
});
return res.status(200).json({
success: true,
description: `Returned ${user.username}'s recently achieved targets.`,
body: {
goals,
milestones,
goalSubs: recentlyAchievedGoalSubs,
milestoneSubs: recentlyAchievedMilestoneSubs,
user,
},
});
});
router.use("/goals", goalsRouter);
router.use("/milestones", milestonesRouter);
export default router;
+38
View File
@@ -2,6 +2,7 @@ import { SYMBOL_TachiData } from "lib/constants/tachi";
import { Request } from "express";
import { TachiRequestData } from "./types";
import deepmerge from "deepmerge";
import CreateLogCtx from "lib/logger/logger";
export function AssignToReqTachiData(req: Request, data: Partial<TachiRequestData>) {
if (!req[SYMBOL_TachiData]) {
@@ -10,3 +11,40 @@ export function AssignToReqTachiData(req: Request, data: Partial<TachiRequestDat
req[SYMBOL_TachiData] = deepmerge(req[SYMBOL_TachiData]!, data);
}
}
const logger = CreateLogCtx(__filename);
export function GetUGPT(req: Request) {
if (!req[SYMBOL_TachiData]) {
logger.error(`Tried to get UGPT from a req that doesn't have SYMBOL_TachiData.`);
throw new Error("Failed to get UGPT.");
}
const user = req[SYMBOL_TachiData]!.requestedUser;
const game = req[SYMBOL_TachiData]!.game;
const playtype = req[SYMBOL_TachiData]!.playtype;
if (!user || !game || !playtype) {
logger.error(`Tried to get UGPT from a req that doesnt have U, G and PT.`);
throw new Error(`Failed to get UGPT.`);
}
return { user, game, playtype };
}
export function GetGPT(req: Request) {
if (!req[SYMBOL_TachiData]) {
logger.error(`Tried to get GPT from a req that doesn't have SYMBOL_TachiData.`);
throw new Error("Failed to get GPT.");
}
const game = req[SYMBOL_TachiData]!.game;
const playtype = req[SYMBOL_TachiData]!.playtype;
if (!game || !playtype) {
logger.error(`Tried to get GPT from a req that doesnt have a Game and Playtype.`);
throw new Error(`Failed to get GPT.`);
}
return { game, playtype };
}