// ABOUTME: API route for editing and deleting individual period logs. // ABOUTME: PATCH updates startDate, DELETE removes period entry. import type { NextRequest } from "next/server"; import { NextResponse } from "next/server"; import type PocketBase from "pocketbase"; import { withAuth } from "@/lib/auth-middleware"; import type { PeriodLog, User } from "@/types"; // Date format regex: YYYY-MM-DD const DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/; interface RouteContext { params?: Promise<{ id: string }>; } // Helper to format date as YYYY-MM-DD function formatDateStr(date: Date): string { return date.toISOString().split("T")[0]; } // Helper to check if a period log is the most recent for a user async function isMostRecentPeriod( pb: PocketBase, userId: string, periodLogId: string, ): Promise { const result = await pb.collection("period_logs").getList(1, 1, { filter: `user="${userId}"`, sort: "-startDate", }); if (result.items.length === 0) { return false; } return result.items[0].id === periodLogId; } // Helper to get the most recent period after deletion async function getMostRecentPeriodAfterDeletion( pb: PocketBase, userId: string, ): Promise { const result = await pb.collection("period_logs").getList(1, 1, { filter: `user="${userId}"`, sort: "-startDate", }); return result.items[0] || null; } export const PATCH = withAuth( async ( request: NextRequest, user: User, pb: PocketBase, context?: RouteContext, ) => { // Get ID from route params const { id } = await (context?.params ?? Promise.resolve({ id: "" })); // Fetch the period log let periodLog: PeriodLog; try { periodLog = await pb.collection("period_logs").getOne(id); } catch (error) { // Handle PocketBase 404 errors (can be Error or plain object) const err = error as { status?: number }; if (err.status === 404) { return NextResponse.json( { error: "Period log not found" }, { status: 404 }, ); } throw error; } // Check ownership if (periodLog.user !== user.id) { return NextResponse.json({ error: "Access denied" }, { status: 403 }); } // Parse request body const body = await request.json(); // Validate startDate is present if (!body.startDate) { return NextResponse.json( { error: "startDate is required" }, { status: 400 }, ); } // Validate startDate format if (!DATE_REGEX.test(body.startDate)) { return NextResponse.json( { error: "startDate must be in YYYY-MM-DD format" }, { status: 400 }, ); } // Validate startDate is a valid date const parsedDate = new Date(body.startDate); if (Number.isNaN(parsedDate.getTime())) { return NextResponse.json( { error: "startDate is not a valid date" }, { status: 400 }, ); } // Validate startDate is not in the future const today = new Date(); today.setHours(23, 59, 59, 999); // End of today if (parsedDate > today) { return NextResponse.json( { error: "startDate cannot be in the future" }, { status: 400 }, ); } // Update the period log const updatedPeriodLog = await pb .collection("period_logs") .update(id, { startDate: body.startDate, }); // If this is the most recent period, update user.lastPeriodDate const isLatest = await isMostRecentPeriod(pb, user.id, id); if (isLatest) { await pb.collection("users").update(user.id, { lastPeriodDate: body.startDate, }); } return NextResponse.json(updatedPeriodLog, { status: 200 }); }, ); export const DELETE = withAuth( async ( _request: NextRequest, user: User, pb: PocketBase, context?: RouteContext, ) => { // Get ID from route params const { id } = await (context?.params ?? Promise.resolve({ id: "" })); // Fetch the period log let periodLog: PeriodLog; try { periodLog = await pb.collection("period_logs").getOne(id); } catch (error) { // Handle PocketBase 404 errors (can be Error or plain object) const err = error as { status?: number }; if (err.status === 404) { return NextResponse.json( { error: "Period log not found" }, { status: 404 }, ); } throw error; } // Check ownership if (periodLog.user !== user.id) { return NextResponse.json({ error: "Access denied" }, { status: 403 }); } // Delete the period log await pb.collection("period_logs").delete(id); // Update user.lastPeriodDate to the previous period (or null if no more periods) const previousPeriod = await getMostRecentPeriodAfterDeletion(pb, user.id); await pb.collection("users").update(user.id, { lastPeriodDate: previousPeriod ? formatDateStr(new Date(previousPeriod.startDate)) : null, }); return NextResponse.json({ success: true }, { status: 200 }); }, );