handle personal leaderboards (pivotId)
Some checks failed
Build / build (22) (push) Has been cancelled
Build / build (18) (push) Successful in 45s
Build / build (20) (push) Has been cancelled
Build / build (18) (pull_request) Successful in 48s
Build / build (20) (pull_request) Successful in 1m13s
Build / build (22) (pull_request) Successful in 1m28s
Some checks failed
Build / build (22) (push) Has been cancelled
Build / build (18) (push) Successful in 45s
Build / build (20) (push) Has been cancelled
Build / build (18) (pull_request) Successful in 48s
Build / build (20) (pull_request) Successful in 1m13s
Build / build (22) (pull_request) Successful in 1m28s
This commit is contained in:
parent
ea201e3be8
commit
b8109d0bc4
@ -6,7 +6,7 @@ export const leaderboardController: RequestHandler = async (req, res) => {
|
|||||||
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
||||||
const payload = JSON.parse(String(req.body)) as ILeaderboardRequest;
|
const payload = JSON.parse(String(req.body)) as ILeaderboardRequest;
|
||||||
res.json({
|
res.json({
|
||||||
results: await getLeaderboard(payload.field, payload.before, payload.after)
|
results: await getLeaderboard(payload.field, payload.before, payload.after, payload.pivotId)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -14,4 +14,5 @@ interface ILeaderboardRequest {
|
|||||||
field: string;
|
field: string;
|
||||||
before: number;
|
before: number;
|
||||||
after: number;
|
after: number;
|
||||||
|
pivotId?: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { model, Schema } from "mongoose";
|
import { Document, model, Schema, Types } from "mongoose";
|
||||||
import { ILeaderboardEntryDatabase } from "../types/leaderboardTypes";
|
import { ILeaderboardEntryDatabase } from "../types/leaderboardTypes";
|
||||||
|
|
||||||
const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
|
const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
|
||||||
@ -16,3 +16,9 @@ leaderboardEntrySchema.index({ leaderboard: 1 });
|
|||||||
leaderboardEntrySchema.index({ expiry: 1 }, { expireAfterSeconds: 0 }); // With this, MongoDB will automatically delete expired entries.
|
leaderboardEntrySchema.index({ expiry: 1 }, { expireAfterSeconds: 0 }); // With this, MongoDB will automatically delete expired entries.
|
||||||
|
|
||||||
export const Leaderboard = model<ILeaderboardEntryDatabase>("Leaderboard", leaderboardEntrySchema);
|
export const Leaderboard = model<ILeaderboardEntryDatabase>("Leaderboard", leaderboardEntrySchema);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
export type TLeaderboardEntryDocument = Document<unknown, {}, ILeaderboardEntryDatabase> & {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
__v: number;
|
||||||
|
} & ILeaderboardEntryDatabase;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Leaderboard } from "../models/leaderboardModel";
|
import { Leaderboard, TLeaderboardEntryDocument } from "../models/leaderboardModel";
|
||||||
import { ILeaderboardEntryClient } from "../types/leaderboardTypes";
|
import { ILeaderboardEntryClient } from "../types/leaderboardTypes";
|
||||||
|
|
||||||
export const submitLeaderboardScore = async (
|
export const submitLeaderboardScore = async (
|
||||||
@ -29,14 +29,41 @@ export const submitLeaderboardScore = async (
|
|||||||
export const getLeaderboard = async (
|
export const getLeaderboard = async (
|
||||||
leaderboard: string,
|
leaderboard: string,
|
||||||
before: number,
|
before: number,
|
||||||
after: number
|
after: number,
|
||||||
|
pivotId: string | undefined = undefined
|
||||||
): Promise<ILeaderboardEntryClient[]> => {
|
): Promise<ILeaderboardEntryClient[]> => {
|
||||||
const entries = await Leaderboard.find({ leaderboard })
|
let entries: TLeaderboardEntryDocument[];
|
||||||
.sort({ score: -1 })
|
let r: number;
|
||||||
.skip(before)
|
if (pivotId) {
|
||||||
.limit(after - before);
|
const pivotDoc = await Leaderboard.findOne({ leaderboard, accountId: pivotId });
|
||||||
|
if (!pivotDoc) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const beforeDocs = await Leaderboard.find({
|
||||||
|
leaderboard,
|
||||||
|
score: { $gt: pivotDoc.score }
|
||||||
|
})
|
||||||
|
.sort({ score: 1 })
|
||||||
|
.limit(before);
|
||||||
|
const afterDocs = await Leaderboard.find({
|
||||||
|
leaderboard,
|
||||||
|
score: { $lt: pivotDoc.score }
|
||||||
|
})
|
||||||
|
.sort({ score: -1 })
|
||||||
|
.limit(after);
|
||||||
|
entries = [...beforeDocs.reverse(), pivotDoc, ...afterDocs];
|
||||||
|
r = await Leaderboard.countDocuments({
|
||||||
|
leaderboard,
|
||||||
|
score: { $gt: pivotDoc.score }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
entries = await Leaderboard.find({ leaderboard })
|
||||||
|
.sort({ score: -1 })
|
||||||
|
.skip(before)
|
||||||
|
.limit(after - before);
|
||||||
|
r = before;
|
||||||
|
}
|
||||||
const res: ILeaderboardEntryClient[] = [];
|
const res: ILeaderboardEntryClient[] = [];
|
||||||
let r = before;
|
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
res.push({
|
res.push({
|
||||||
_id: entry.accountId.toString(),
|
_id: entry.accountId.toString(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user