move score page fetching to the backend
This commit is contained in:
13
projects/common/src/model/beatsaver/beatsaver-author.ts
Normal file
13
projects/common/src/model/beatsaver/beatsaver-author.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { prop } from "@typegoose/typegoose";
|
||||
|
||||
export default class BeatsaverAuthor {
|
||||
/**
|
||||
* The id of the author.
|
||||
*/
|
||||
@prop({ required: true })
|
||||
id: number;
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
51
projects/common/src/model/beatsaver/beatsaver-map.ts
Normal file
51
projects/common/src/model/beatsaver/beatsaver-map.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { getModelForClass, modelOptions, prop, ReturnModelType, Severity } from "@typegoose/typegoose";
|
||||
import { Document } from "mongoose";
|
||||
import BeatsaverAuthor from "./beatsaver-author";
|
||||
|
||||
/**
|
||||
* The model for a BeatSaver map.
|
||||
*/
|
||||
@modelOptions({
|
||||
options: { allowMixed: Severity.ALLOW },
|
||||
schemaOptions: {
|
||||
toObject: {
|
||||
virtuals: true,
|
||||
transform: function (_, ret) {
|
||||
ret.id = ret._id;
|
||||
delete ret._id;
|
||||
delete ret.__v;
|
||||
return ret;
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
export class BeatSaverMap {
|
||||
/**
|
||||
* The internal MongoDB ID (_id).
|
||||
*/
|
||||
@prop({ required: true })
|
||||
private _id!: string;
|
||||
|
||||
/**
|
||||
* The bsr code for the map.
|
||||
* @private
|
||||
*/
|
||||
@prop({ required: true })
|
||||
public bsr!: string;
|
||||
|
||||
/**
|
||||
* The author of the map.
|
||||
*/
|
||||
@prop({ required: true, _id: false, type: () => BeatsaverAuthor })
|
||||
public author!: BeatsaverAuthor;
|
||||
|
||||
/**
|
||||
* Exposes `id` as a virtual field mapped from `_id`.
|
||||
*/
|
||||
public get id(): string {
|
||||
return this._id;
|
||||
}
|
||||
}
|
||||
|
||||
export type BeatSaverMapDocument = BeatSaverMap & Document;
|
||||
export const BeatSaverMapModel: ReturnModelType<typeof BeatSaverMap> = getModelForClass(BeatSaverMap);
|
113
projects/common/src/model/player.ts
Normal file
113
projects/common/src/model/player.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import { getModelForClass, modelOptions, prop, ReturnModelType, Severity } from "@typegoose/typegoose";
|
||||
import { Document } from "mongoose";
|
||||
import { PlayerHistory } from "../player/player-history";
|
||||
import { formatDateMinimal, getDaysAgoDate, getMidnightAlignedDate } from "../utils/time-utils";
|
||||
|
||||
/**
|
||||
* The model for a player.
|
||||
*/
|
||||
@modelOptions({ options: { allowMixed: Severity.ALLOW } })
|
||||
export class Player {
|
||||
/**
|
||||
* The id of the player.
|
||||
*/
|
||||
@prop()
|
||||
public _id!: string;
|
||||
|
||||
/**
|
||||
* The player's statistic history.
|
||||
*/
|
||||
@prop()
|
||||
private statisticHistory?: Record<string, PlayerHistory>;
|
||||
|
||||
/**
|
||||
* The date the player was last tracked.
|
||||
*/
|
||||
@prop()
|
||||
public lastTracked?: Date;
|
||||
|
||||
/**
|
||||
* The date the player was first tracked.
|
||||
*/
|
||||
@prop()
|
||||
public trackedSince?: Date;
|
||||
|
||||
/**
|
||||
* Gets the player's statistic history.
|
||||
*/
|
||||
public getStatisticHistory(): Record<string, PlayerHistory> {
|
||||
if (this.statisticHistory === undefined) {
|
||||
this.statisticHistory = {};
|
||||
}
|
||||
return this.statisticHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's history for a specific date.
|
||||
*
|
||||
* @param date the date to get the history for.
|
||||
*/
|
||||
public getHistoryByDate(date: Date): PlayerHistory {
|
||||
if (this.statisticHistory === undefined) {
|
||||
this.statisticHistory = {};
|
||||
}
|
||||
return this.getStatisticHistory()[formatDateMinimal(getMidnightAlignedDate(date))] || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's history for the previous X days.
|
||||
*
|
||||
* @param days the number of days to get the history for.
|
||||
*/
|
||||
public getHistoryPreviousDays(days: number): Record<string, PlayerHistory> {
|
||||
const statisticHistory = this.getStatisticHistory();
|
||||
const history: Record<string, PlayerHistory> = {};
|
||||
|
||||
for (let i = 0; i < days; i++) {
|
||||
const date = formatDateMinimal(getMidnightAlignedDate(getDaysAgoDate(i)));
|
||||
const playerHistory = statisticHistory[date];
|
||||
if (playerHistory !== undefined && Object.keys(playerHistory).length > 0) {
|
||||
history[date] = playerHistory;
|
||||
}
|
||||
}
|
||||
return history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player's statistic history.
|
||||
*
|
||||
* @param date the date to set it for.
|
||||
* @param history the history to set.
|
||||
*/
|
||||
public setStatisticHistory(date: Date, history: PlayerHistory) {
|
||||
if (this.statisticHistory === undefined) {
|
||||
this.statisticHistory = {};
|
||||
}
|
||||
this.statisticHistory[formatDateMinimal(getMidnightAlignedDate(date))] = history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the player's statistic history by
|
||||
* date in descending order. (oldest to newest)
|
||||
*/
|
||||
public sortStatisticHistory() {
|
||||
if (this.statisticHistory === undefined) {
|
||||
this.statisticHistory = {};
|
||||
}
|
||||
this.statisticHistory = Object.fromEntries(
|
||||
Object.entries(this.statisticHistory).sort((a, b) => new Date(b[0]).getTime() - new Date(a[0]).getTime())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of days tracked.
|
||||
*
|
||||
* @returns the number of days tracked.
|
||||
*/
|
||||
public getDaysTracked(): number {
|
||||
return Object.keys(this.getStatisticHistory()).length;
|
||||
}
|
||||
}
|
||||
|
||||
export type PlayerDocument = Player & Document;
|
||||
export const PlayerModel: ReturnModelType<typeof Player> = getModelForClass(Player);
|
Reference in New Issue
Block a user