2026-06-16 09:43:48 +02:00
|
|
|
import { ObjectId } from "mongodb";
|
|
|
|
|
import { z } from "zod";
|
|
|
|
|
import { getDb } from "@/lib/db";
|
|
|
|
|
|
|
|
|
|
export const strengthSetSchema = z.object({
|
|
|
|
|
order: z.number().int().positive(),
|
|
|
|
|
weightKg: z.number().positive().optional(),
|
|
|
|
|
reps: z.number().int().positive().optional(),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const strengthExerciseSchema = z.object({
|
|
|
|
|
name: z.string().min(1),
|
|
|
|
|
notes: z.string().optional(),
|
|
|
|
|
sets: z.array(strengthSetSchema),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const strengthWorkoutSchema = z.object({
|
|
|
|
|
date: z.date(),
|
|
|
|
|
name: z.string().min(1),
|
|
|
|
|
notes: z.string().optional(),
|
|
|
|
|
exercises: z.array(strengthExerciseSchema),
|
|
|
|
|
sourceUrl: z.string().optional(),
|
|
|
|
|
sourceKey: z.string().min(1),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export type StrengthSet = z.infer<typeof strengthSetSchema>;
|
|
|
|
|
export type StrengthExercise = z.infer<typeof strengthExerciseSchema>;
|
|
|
|
|
export type StrengthWorkoutInput = z.infer<typeof strengthWorkoutSchema>;
|
|
|
|
|
|
|
|
|
|
export type StrengthWorkout = StrengthWorkoutInput & {
|
|
|
|
|
_id: ObjectId;
|
2026-06-18 11:02:31 +02:00
|
|
|
userId: string;
|
2026-06-16 09:43:48 +02:00
|
|
|
createdAt: Date;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const COLLECTION = "strength_workouts";
|
|
|
|
|
|
|
|
|
|
async function getCollection() {
|
|
|
|
|
const db = await getDb();
|
|
|
|
|
const collection = db.collection<StrengthWorkout>(COLLECTION);
|
2026-06-18 11:02:31 +02:00
|
|
|
await collection.createIndex({ userId: 1, sourceKey: 1 }, { unique: true });
|
2026-06-16 09:43:48 +02:00
|
|
|
return collection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function upsertStrengthWorkout(
|
2026-06-18 11:02:31 +02:00
|
|
|
userId: string,
|
2026-06-16 09:43:48 +02:00
|
|
|
workout: StrengthWorkoutInput
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
const collection = await getCollection();
|
|
|
|
|
await collection.updateOne(
|
2026-06-18 11:02:31 +02:00
|
|
|
{ userId, sourceKey: workout.sourceKey },
|
2026-06-16 09:43:48 +02:00
|
|
|
{
|
2026-06-18 11:02:31 +02:00
|
|
|
$set: { ...workout, userId },
|
2026-06-16 09:43:48 +02:00
|
|
|
$setOnInsert: { createdAt: new Date() },
|
|
|
|
|
},
|
|
|
|
|
{ upsert: true }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function listStrengthWorkouts(userId: string): Promise<StrengthWorkout[]> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const collection = await getCollection();
|
2026-06-18 11:02:31 +02:00
|
|
|
return collection.find({ userId }).sort({ date: -1 }).toArray();
|
2026-06-16 09:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
2026-06-18 11:02:31 +02:00
|
|
|
export async function getStrengthWorkout(
|
|
|
|
|
userId: string,
|
|
|
|
|
id: string
|
|
|
|
|
): Promise<StrengthWorkout | null> {
|
2026-06-16 09:43:48 +02:00
|
|
|
const collection = await getCollection();
|
2026-06-18 11:02:31 +02:00
|
|
|
return collection.findOne({ _id: new ObjectId(id), userId });
|
2026-06-16 09:43:48 +02:00
|
|
|
}
|