add guildId to optionally narrow results
All checks were successful
Build / build (22) (push) Successful in 38s
Build / build (20) (push) Successful in 1m11s
Build / build (18) (push) Successful in 1m18s
Build / build (18) (pull_request) Successful in 41s
Build / build (20) (pull_request) Successful in 1m8s
Build / build (22) (pull_request) Successful in 1m18s

This commit is contained in:
Sainan 2025-03-24 23:00:23 +01:00
parent 46cdb44f59
commit 942f062e90
5 changed files with 20 additions and 10 deletions

View File

@ -6,7 +6,7 @@ export const leaderboardController: RequestHandler = async (req, res) => {
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
const payload = JSON.parse(String(req.body)) as ILeaderboardRequest;
res.json({
results: await getLeaderboard(payload.field, payload.before, payload.after, payload.pivotId)
results: await getLeaderboard(payload.field, payload.before, payload.after, payload.guildId, payload.pivotId)
});
};
@ -14,5 +14,6 @@ interface ILeaderboardRequest {
field: string;
before: number;
after: number;
guildId?: string;
pivotId?: string;
}

View File

@ -4,15 +4,17 @@ import { ILeaderboardEntryDatabase } from "../types/leaderboardTypes";
const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
{
leaderboard: { type: String, required: true },
displayName: { type: String, required: true },
ownerId: { type: Schema.Types.ObjectId, required: true },
displayName: { type: String, required: true },
score: { type: Number, required: true },
guildId: Schema.Types.ObjectId,
expiry: { type: Date, required: true }
},
{ id: false }
);
leaderboardEntrySchema.index({ leaderboard: 1 });
leaderboardEntrySchema.index({ leaderboard: 1, ownerId: 1 }, { unique: true });
leaderboardEntrySchema.index({ expiry: 1 }, { expireAfterSeconds: 0 }); // With this, MongoDB will automatically delete expired entries.
export const Leaderboard = model<ILeaderboardEntryDatabase>("Leaderboard", leaderboardEntrySchema);

View File

@ -5,7 +5,8 @@ export const submitLeaderboardScore = async (
leaderboard: string,
ownerId: string,
displayName: string,
score: number
score: number,
guildId?: string
): Promise<void> => {
const schedule = leaderboard.split(".")[0] as "daily" | "weekly";
let expiry: Date;
@ -20,8 +21,8 @@ export const submitLeaderboardScore = async (
expiry = new Date(weekEnd);
}
await Leaderboard.findOneAndUpdate(
{ leaderboard, displayName },
{ $max: { score }, $set: { ownerId, expiry } },
{ leaderboard, ownerId },
{ $max: { score }, $set: { displayName, guildId, expiry } },
{ upsert: true }
);
};
@ -30,23 +31,26 @@ export const getLeaderboard = async (
leaderboard: string,
before: number,
after: number,
pivotId: string | undefined = undefined
guildId?: string,
pivotId?: string
): Promise<ILeaderboardEntryClient[]> => {
let entries: TLeaderboardEntryDocument[];
let r: number;
if (pivotId) {
const pivotDoc = await Leaderboard.findOne({ leaderboard, ownerId: pivotId });
const pivotDoc = await Leaderboard.findOne({ leaderboard, guildId, ownerId: pivotId });
if (!pivotDoc) {
return [];
}
const beforeDocs = await Leaderboard.find({
leaderboard,
guildId,
score: { $gt: pivotDoc.score }
})
.sort({ score: 1 })
.limit(before);
const afterDocs = await Leaderboard.find({
leaderboard,
guildId,
score: { $lt: pivotDoc.score }
})
.sort({ score: -1 })
@ -55,10 +59,11 @@ export const getLeaderboard = async (
r =
(await Leaderboard.countDocuments({
leaderboard,
guildId,
score: { $gt: pivotDoc.score }
})) - beforeDocs.length;
} else {
entries = await Leaderboard.find({ leaderboard })
entries = await Leaderboard.find({ leaderboard, guildId })
.sort({ score: -1 })
.skip(before)
.limit(after - before);

View File

@ -327,7 +327,8 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
"weekly.accounts." + category,
accountOwnerId,
payload.displayName,
data as number
data as number,
payload.guildId
);
break;

View File

@ -2,9 +2,10 @@ import { Types } from "mongoose";
export interface ILeaderboardEntryDatabase {
leaderboard: string;
displayName: string;
ownerId: Types.ObjectId;
displayName: string;
score: number;
guildId?: Types.ObjectId;
expiry: Date;
}