Implement GET /api/cycle/current endpoint (P1.3)
Add endpoint returning current cycle day, phase, phase configuration, and days until next phase. Uses withAuth middleware for authentication. Response shape: - cycleDay: current day in menstrual cycle (1-31) - phase: current phase (MENSTRUAL, FOLLICULAR, OVULATION, EARLY_LUTEAL, LATE_LUTEAL) - phaseConfig: full configuration including weeklyLimit, trainingType - daysUntilNextPhase: days remaining in current phase - cycleLength: user's configured cycle length Includes 10 tests covering: - Authentication (401 when not authenticated) - Validation (400 when no lastPeriodDate) - All five cycle phases - Cycle rollover handling - Custom cycle lengths 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,66 @@
|
||||
// ABOUTME: Returns current cycle day, phase, and phase limits.
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function GET() {
|
||||
// TODO: Implement current cycle info
|
||||
return NextResponse.json({ message: "Not implemented" }, { status: 501 });
|
||||
import { withAuth } from "@/lib/auth-middleware";
|
||||
import {
|
||||
getCycleDay,
|
||||
getPhase,
|
||||
getPhaseConfig,
|
||||
PHASE_CONFIGS,
|
||||
} from "@/lib/cycle";
|
||||
|
||||
/**
|
||||
* 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);
|
||||
const currentConfig = getPhaseConfig(currentPhase);
|
||||
|
||||
// For LATE_LUTEAL, calculate days until new cycle
|
||||
if (currentPhase === "LATE_LUTEAL") {
|
||||
return cycleLength - cycleDay + 1;
|
||||
}
|
||||
|
||||
// Find next phase start day
|
||||
const currentIndex = PHASE_CONFIGS.findIndex((c) => c.name === currentPhase);
|
||||
const nextConfig = PHASE_CONFIGS[currentIndex + 1];
|
||||
|
||||
if (nextConfig) {
|
||||
return nextConfig.days[0] - cycleDay;
|
||||
}
|
||||
|
||||
// Fallback: days until end of current phase + 1
|
||||
return currentConfig.days[1] - cycleDay + 1;
|
||||
}
|
||||
|
||||
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);
|
||||
const phaseConfig = getPhaseConfig(phase);
|
||||
const daysUntilNextPhase = getDaysUntilNextPhase(cycleDay, user.cycleLength);
|
||||
|
||||
return NextResponse.json({
|
||||
cycleDay,
|
||||
phase,
|
||||
phaseConfig,
|
||||
daysUntilNextPhase,
|
||||
cycleLength: user.cycleLength,
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user