import { NextResponse } from "next/server"; import { getServiceSupabase } from "@/lib/supabase/client"; import { getAuthenticatedUser } from "@/lib/server/auth"; export const runtime = "nodejs"; // GET - fetch all sprints (optionally filtered by status) export async function GET(request: Request) { try { const user = await getAuthenticatedUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } // Parse query params const { searchParams } = new URL(request.url); const status = searchParams.get("status"); const supabase = getServiceSupabase(); let query = supabase .from("sprints") .select("*") .order("start_date", { ascending: true }); // Filter by status if provided if (status && ["planning", "active", "completed"].includes(status)) { query = query.eq("status", status); } const { data: sprints, error } = await query; if (error) throw error; return NextResponse.json({ sprints: sprints || [] }); } catch (error) { console.error(">>> API GET /sprints error:", error); return NextResponse.json({ error: "Failed to fetch sprints" }, { status: 500 }); } } // POST - create a new sprint export async function POST(request: Request) { try { const user = await getAuthenticatedUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const body = await request.json(); const { name, goal, startDate, endDate, status, projectId } = body; if (!name || typeof name !== "string") { return NextResponse.json({ error: "Missing sprint name" }, { status: 400 }); } const supabase = getServiceSupabase(); const now = new Date().toISOString(); const { data, error } = await supabase .from("sprints") .insert({ name, goal: goal || null, start_date: startDate || now, end_date: endDate || now, status: status || "planning", project_id: projectId || null, created_at: now, }) .select() .single(); if (error) throw error; return NextResponse.json({ success: true, sprint: data }); } catch (error) { console.error(">>> API POST /sprints error:", error); return NextResponse.json({ error: "Failed to create sprint" }, { status: 500 }); } } // PATCH - update a sprint export async function PATCH(request: Request) { try { const user = await getAuthenticatedUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const body = await request.json(); const { id, ...updates } = body; if (!id) { return NextResponse.json({ error: "Missing sprint id" }, { status: 400 }); } const supabase = getServiceSupabase(); const now = new Date().toISOString(); // Map camelCase to snake_case for database const dbUpdates: Record = {}; if (updates.name !== undefined) dbUpdates.name = updates.name; if (updates.goal !== undefined) dbUpdates.goal = updates.goal; if (updates.startDate !== undefined) dbUpdates.start_date = updates.startDate; if (updates.endDate !== undefined) dbUpdates.end_date = updates.endDate; if (updates.status !== undefined) dbUpdates.status = updates.status; if (updates.projectId !== undefined) dbUpdates.project_id = updates.projectId; dbUpdates.updated_at = now; const { data, error } = await supabase .from("sprints") .update(dbUpdates) .eq("id", id) .select() .single(); if (error) throw error; return NextResponse.json({ success: true, sprint: data }); } catch (error) { console.error(">>> API PATCH /sprints error:", error); return NextResponse.json({ error: "Failed to update sprint" }, { status: 500 }); } } // DELETE - delete a sprint export async function DELETE(request: Request) { try { const user = await getAuthenticatedUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const { id } = await request.json(); if (!id) { return NextResponse.json({ error: "Missing sprint id" }, { status: 400 }); } const supabase = getServiceSupabase(); const { error } = await supabase.from("sprints").delete().eq("id", id); if (error) throw error; return NextResponse.json({ success: true }); } catch (error) { console.error(">>> API DELETE /sprints error:", error); return NextResponse.json({ error: "Failed to delete sprint" }, { status: 500 }); } }