Implement POST/DELETE /api/overrides endpoints (P1.5)
Add override management API for the training decision system: - POST /api/overrides adds an override (flare, stress, sleep, pms) - DELETE /api/overrides removes an override - Both endpoints use withAuth middleware - Validation for override types, idempotent operations - 14 tests covering auth, validation, and persistence Also fix type error in today/route.ts where DailyLog body battery fields could be null but biometrics object expected numbers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,102 @@
|
||||
// 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";
|
||||
|
||||
export async function POST() {
|
||||
// TODO: Implement override setting
|
||||
return NextResponse.json({ message: "Not implemented" }, { status: 501 });
|
||||
import { withAuth } from "@/lib/auth-middleware";
|
||||
import { createPocketBaseClient } from "@/lib/pocketbase";
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
export async function DELETE() {
|
||||
// TODO: Implement override removal
|
||||
return NextResponse.json({ message: "Not implemented" }, { status: 501 });
|
||||
}
|
||||
/**
|
||||
* 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) => {
|
||||
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
|
||||
const pb = createPocketBaseClient();
|
||||
await pb
|
||||
.collection("users")
|
||||
.update(user.id, { activeOverrides: newOverrides });
|
||||
|
||||
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) => {
|
||||
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
|
||||
const pb = createPocketBaseClient();
|
||||
await pb
|
||||
.collection("users")
|
||||
.update(user.id, { activeOverrides: newOverrides });
|
||||
|
||||
return NextResponse.json({ activeOverrides: newOverrides });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user