100 lines
3.6 KiB
TypeScript
100 lines
3.6 KiB
TypeScript
import { Activity, Gender } from "@blade-and-brawn/domain";
|
|
import { db } from "../database/db";
|
|
import type { CalculatorService } from "./calculator";
|
|
import { Value } from "@sinclair/typebox/value";
|
|
import { t } from "elysia";
|
|
|
|
export type AccountRole = "user" | "admin";
|
|
|
|
export class AccountsService {
|
|
constructor(private Calculator: CalculatorService) { }
|
|
|
|
private static idComparison(id: string): ["accounts.id" | "accounts.discord_id", "=", string] {
|
|
return id.startsWith("@")
|
|
? ["accounts.discord_id", "=", id.slice(1)]
|
|
: ["accounts.id", "=", id];
|
|
}
|
|
|
|
async create(discordId: string, email?: string, name?: string) {
|
|
return await db.insertInto("accounts")
|
|
.values({
|
|
discord_id: discordId,
|
|
name: name ?? "",
|
|
email: email ?? null
|
|
})
|
|
.returning("id")
|
|
.executeTakeFirstOrThrow();
|
|
}
|
|
|
|
async get(id: string) {
|
|
return await (db).selectFrom("accounts")
|
|
.select(["id", "discord_id", "name", "email", "gender", "role"])
|
|
.where(...AccountsService.idComparison(id))
|
|
.executeTakeFirst();
|
|
}
|
|
|
|
async getByEmail(email: string) {
|
|
return await (db).selectFrom("accounts")
|
|
.select(["id", "discord_id", "name", "email", "gender", "password_hash", "role"])
|
|
.where("email", "=", email)
|
|
.executeTakeFirst();
|
|
}
|
|
|
|
async stats(id: string) {
|
|
const latestAssessment = await db.selectFrom("accounts")
|
|
.innerJoin("assessments", "assessments.account_id", "accounts.id")
|
|
.select([
|
|
"assessments.age", "assessments.gender", "assessments.weight", "assessments.name",
|
|
"assessments.perf_back_squat", "assessments.perf_bench_press", "assessments.perf_broad_jump",
|
|
"assessments.perf_cone_drill", "assessments.perf_deadlift", "assessments.perf_run"
|
|
])
|
|
.where(...AccountsService.idComparison(id))
|
|
.orderBy("assessments.created_at", "desc")
|
|
.limit(1)
|
|
.executeTakeFirst();
|
|
if (!latestAssessment) return;
|
|
Value.Assert(t.Enum(Gender), latestAssessment.gender);
|
|
|
|
return this.Calculator.calculate(
|
|
{
|
|
name: latestAssessment.name,
|
|
metrics: {
|
|
age: latestAssessment.age,
|
|
weight: latestAssessment.weight,
|
|
gender: latestAssessment.gender
|
|
}
|
|
},
|
|
[
|
|
// Strength
|
|
{
|
|
activity: Activity.BenchPress,
|
|
performance: latestAssessment.perf_bench_press ?? 0
|
|
},
|
|
{
|
|
activity: Activity.Deadlift,
|
|
performance: latestAssessment.perf_deadlift ?? 0
|
|
},
|
|
{
|
|
activity: Activity.BackSquat,
|
|
performance: latestAssessment.perf_back_squat ?? 0
|
|
},
|
|
// Power
|
|
{
|
|
activity: Activity.BroadJump,
|
|
performance: latestAssessment.perf_broad_jump ?? 0
|
|
},
|
|
// Endurance
|
|
{
|
|
activity: Activity.Run,
|
|
performance: latestAssessment.perf_run ?? 0
|
|
},
|
|
// Agility
|
|
{
|
|
activity: Activity.ConeDrill,
|
|
performance: latestAssessment.perf_cone_drill ?? 0
|
|
},
|
|
]
|
|
);
|
|
}
|
|
}
|