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:
2026-01-10 19:09:08 +00:00
parent 949cb1671a
commit e4d123704d
4 changed files with 433 additions and 18 deletions

View File

@@ -13,11 +13,16 @@ import {
import { getDecisionWithOverrides } from "@/lib/decision-engine";
import { getNutritionGuidance } from "@/lib/nutrition";
import { createPocketBaseClient } from "@/lib/pocketbase";
import type { DailyData, DailyLog } from "@/types";
import type { DailyData, DailyLog, HrvStatus } from "@/types";
// Default biometrics when no Garmin data is available
const DEFAULT_BIOMETRICS = {
hrvStatus: "Unknown" as const,
const DEFAULT_BIOMETRICS: {
hrvStatus: HrvStatus;
bodyBatteryCurrent: number;
bodyBatteryYesterdayLow: number;
weekIntensityMinutes: number;
} = {
hrvStatus: "Unknown",
bodyBatteryCurrent: 100,
bodyBatteryYesterdayLow: 100,
weekIntensityMinutes: 0,
@@ -69,8 +74,11 @@ export const GET = withAuth(async (_request, user) => {
biometrics = {
hrvStatus: dailyLog.hrvStatus,
bodyBatteryCurrent: dailyLog.bodyBatteryCurrent,
bodyBatteryYesterdayLow: dailyLog.bodyBatteryYesterdayLow,
bodyBatteryCurrent:
dailyLog.bodyBatteryCurrent ?? DEFAULT_BIOMETRICS.bodyBatteryCurrent,
bodyBatteryYesterdayLow:
dailyLog.bodyBatteryYesterdayLow ??
DEFAULT_BIOMETRICS.bodyBatteryYesterdayLow,
weekIntensityMinutes: dailyLog.weekIntensityMinutes,
phaseLimit: dailyLog.phaseLimit,
};