This repository has been archived on 2024-10-29. You can view files and clone it, but cannot push or open issues or pull requests.
scoresaber-reloadedv3/projects/backend/src/model/player.ts

117 lines
3.3 KiB
TypeScript
Raw Normal View History

2024-10-09 00:58:42 +00:00
import { getModelForClass, modelOptions, prop, ReturnModelType, Severity } from "@typegoose/typegoose";
2024-10-09 00:17:00 +00:00
import { Document } from "mongoose";
import { PlayerHistory } from "@ssr/common/types/player/player-history";
import { formatDateMinimal, getDaysAgoDate, getMidnightAlignedDate } from "@ssr/common/utils/time-utils";
/**
* The model for a player.
*/
2024-10-09 00:58:42 +00:00
@modelOptions({ options: { allowMixed: Severity.ALLOW } })
2024-10-09 00:17:00 +00:00
export class Player {
/**
* The id of the player.
*/
@prop()
public _id!: string;
/**
* The player's statistic history.
*/
@prop()
private statisticHistory?: Record<string, PlayerHistory>;
2024-10-09 14:25:21 +00:00
/**
* The date the player was last tracked.
*/
2024-10-09 00:17:00 +00:00
@prop()
public lastTracked?: Date;
2024-10-09 14:25:21 +00:00
/**
* The date the player was first tracked.
*/
@prop()
public trackedSince?: Date;
2024-10-09 00:17:00 +00:00
/**
* 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> {
2024-10-10 00:40:21 +00:00
const statisticHistory = this.getStatisticHistory();
2024-10-09 00:17:00 +00:00
const history: Record<string, PlayerHistory> = {};
for (let i = 0; i < days; i++) {
const date = formatDateMinimal(getMidnightAlignedDate(getDaysAgoDate(i)));
2024-10-10 00:40:21 +00:00
const playerHistory = statisticHistory[date];
2024-10-09 00:17:00 +00:00
if (playerHistory === undefined || Object.keys(playerHistory).length === 0) {
continue;
}
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 = {};
}
2024-10-10 00:40:21 +00:00
this.statisticHistory[formatDateMinimal(getMidnightAlignedDate(date))] = history;
2024-10-09 00:17:00 +00:00
}
/**
* Sorts the player's statistic history by
* date in descending order. (oldest to newest)
*/
public sortStatisticHistory() {
if (this.statisticHistory === undefined) {
this.statisticHistory = {};
}
2024-10-10 00:40:21 +00:00
this.statisticHistory = Object.fromEntries(
Object.entries(this.statisticHistory).sort((a, b) => new Date(b[0]).getTime() - new Date(a[0]).getTime())
);
2024-10-09 00:17:00 +00:00
}
/**
* Gets the number of days tracked.
*
* @returns the number of days tracked.
*/
public getDaysTracked(): number {
return Object.keys(this.getStatisticHistory()).length;
}
}
// This type defines a Mongoose document based on Player.
export type PlayerDocument = Player & Document;
// This type ensures that PlayerModel returns Mongoose documents (PlayerDocument) that have Mongoose methods (save, remove, etc.)
export const PlayerModel: ReturnModelType<typeof Player> = getModelForClass(Player);