// ABOUTME: API route for current cycle phase information. // ABOUTME: Returns current cycle day, phase, and phase limits. import { NextResponse } from "next/server"; import { withAuth } from "@/lib/auth-middleware"; import { getCycleDay, getPhase, getPhaseConfig } from "@/lib/cycle"; // Phase boundaries per spec: MENSTRUAL 1-3, FOLLICULAR 4-(cl-16), OVULATION (cl-15)-(cl-14), // EARLY_LUTEAL (cl-13)-(cl-7), LATE_LUTEAL (cl-6)-cl function getNextPhaseStart(currentPhase: string, cycleLength: number): number { switch (currentPhase) { case "MENSTRUAL": return 4; // FOLLICULAR starts at 4 case "FOLLICULAR": return cycleLength - 15; // OVULATION starts at (cycleLength - 15) case "OVULATION": return cycleLength - 13; // EARLY_LUTEAL starts at (cycleLength - 13) case "EARLY_LUTEAL": return cycleLength - 6; // LATE_LUTEAL starts at (cycleLength - 6) case "LATE_LUTEAL": return 1; // New cycle starts default: return 1; } } /** * Calculates the number of days until the next phase begins. * For LATE_LUTEAL, calculates days until new cycle starts (MENSTRUAL). */ function getDaysUntilNextPhase(cycleDay: number, cycleLength: number): number { const currentPhase = getPhase(cycleDay, cycleLength); // For LATE_LUTEAL, calculate days until new cycle if (currentPhase === "LATE_LUTEAL") { return cycleLength - cycleDay + 1; } const nextPhaseStart = getNextPhaseStart(currentPhase, cycleLength); return nextPhaseStart - cycleDay; } export const GET = withAuth(async (_request, user) => { // Validate user has required cycle data if (!user.lastPeriodDate) { return NextResponse.json( { error: "User has no lastPeriodDate set. Please log your period start date first.", }, { status: 400 }, ); } // Calculate current cycle position const cycleDay = getCycleDay( user.lastPeriodDate, user.cycleLength, new Date(), ); const phase = getPhase(cycleDay, user.cycleLength); const phaseConfig = getPhaseConfig(phase); const daysUntilNextPhase = getDaysUntilNextPhase(cycleDay, user.cycleLength); return NextResponse.json({ cycleDay, phase, phaseConfig, daysUntilNextPhase, cycleLength: user.cycleLength, }); });