// ABOUTME: API route for managing training overrides. // ABOUTME: Handles flare, stress, sleep, and PMS override toggles. import type { NextRequest } from "next/server"; import { NextResponse } from "next/server"; import { withAuth } from "@/lib/auth-middleware"; import { logger } from "@/lib/logger"; import type { OverrideType } from "@/types"; const VALID_OVERRIDE_TYPES: OverrideType[] = [ "flare", "stress", "sleep", "pms", ]; function isValidOverrideType(value: unknown): value is OverrideType { return ( typeof value === "string" && VALID_OVERRIDE_TYPES.includes(value as OverrideType) ); } /** * POST /api/overrides - Add an override to the user's active overrides. * Request body: { override: OverrideType } * Response: { activeOverrides: OverrideType[] } */ export const POST = withAuth(async (request: NextRequest, user, pb) => { const body = await request.json(); if (!body.override) { return NextResponse.json( { error: "Missing required field: override" }, { status: 400 }, ); } if (!isValidOverrideType(body.override)) { return NextResponse.json( { error: `Invalid override type: ${body.override}. Valid types: ${VALID_OVERRIDE_TYPES.join(", ")}`, }, { status: 400 }, ); } const overrideToAdd: OverrideType = body.override; // Build the new array, avoiding duplicates const currentOverrides = user.activeOverrides || []; const newOverrides = currentOverrides.includes(overrideToAdd) ? currentOverrides : [...currentOverrides, overrideToAdd]; // Update the user record in PocketBase await pb .collection("users") .update(user.id, { activeOverrides: newOverrides }); // Log override toggle per observability spec logger.info( { userId: user.id, override: overrideToAdd, enabled: true }, "Override toggled", ); return NextResponse.json({ activeOverrides: newOverrides }); }); /** * DELETE /api/overrides - Remove an override from the user's active overrides. * Request body: { override: OverrideType } * Response: { activeOverrides: OverrideType[] } */ export const DELETE = withAuth(async (request: NextRequest, user, pb) => { const body = await request.json(); if (!body.override) { return NextResponse.json( { error: "Missing required field: override" }, { status: 400 }, ); } if (!isValidOverrideType(body.override)) { return NextResponse.json( { error: `Invalid override type: ${body.override}. Valid types: ${VALID_OVERRIDE_TYPES.join(", ")}`, }, { status: 400 }, ); } const overrideToRemove: OverrideType = body.override; // Remove the override from the array const currentOverrides = user.activeOverrides || []; const newOverrides = currentOverrides.filter((o) => o !== overrideToRemove); // Update the user record in PocketBase await pb .collection("users") .update(user.id, { activeOverrides: newOverrides }); // Log override toggle per observability spec logger.info( { userId: user.id, override: overrideToRemove, enabled: false }, "Override toggled", ); return NextResponse.json({ activeOverrides: newOverrides }); });