import { NextResponse } from "next/server"; import { getServiceSupabase } from "@/lib/supabase/client"; import { getAuthenticatedUser } from "@/lib/server/auth"; export const runtime = "nodejs"; // GET - fetch all projects export async function GET() { try { const user = await getAuthenticatedUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const supabase = getServiceSupabase(); const { data: projects, error } = await supabase .from("projects") .select("*") .order("created_at", { ascending: true }); if (error) throw error; return NextResponse.json({ projects: projects || [] }); } catch (error) { console.error(">>> API GET /projects error:", error); return NextResponse.json({ error: "Failed to fetch projects" }, { status: 500 }); } } // POST - create a new project 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, description, color } = body; if (!name || typeof name !== "string") { return NextResponse.json({ error: "Missing project name" }, { status: 400 }); } const supabase = getServiceSupabase(); const now = new Date().toISOString(); const { data, error } = await supabase .from("projects") .insert({ name, description: description || null, color: color || "#3b82f6", created_at: now, }) .select() .single(); if (error) throw error; return NextResponse.json({ success: true, project: data }); } catch (error) { console.error(">>> API POST /projects error:", error); return NextResponse.json({ error: "Failed to create project" }, { status: 500 }); } } // PATCH - update a project 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, ...rawUpdates } = body; if (!id) { return NextResponse.json({ error: "Missing project id" }, { status: 400 }); } const updates: Record = {}; if (typeof rawUpdates.name === "string" && rawUpdates.name.trim().length > 0) { updates.name = rawUpdates.name.trim(); } if (Object.prototype.hasOwnProperty.call(rawUpdates, "description")) { updates.description = typeof rawUpdates.description === "string" && rawUpdates.description.trim().length > 0 ? rawUpdates.description : null; } if (typeof rawUpdates.color === "string" && rawUpdates.color.trim().length > 0) { updates.color = rawUpdates.color; } if (Object.keys(updates).length === 0) { return NextResponse.json({ error: "No valid project updates provided" }, { status: 400 }); } const supabase = getServiceSupabase(); const { data, error } = await supabase .from("projects") .update(updates) .eq("id", id) .select() .single(); if (error) throw error; return NextResponse.json({ success: true, project: data }); } catch (error) { console.error(">>> API PATCH /projects error:", error); return NextResponse.json({ error: "Failed to update project" }, { status: 500 }); } } // DELETE - delete a project 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 project id" }, { status: 400 }); } const supabase = getServiceSupabase(); const { error, count } = await supabase .from("projects") .delete({ count: "exact" }) .eq("id", id); if (error) throw error; if ((count ?? 0) === 0) { return NextResponse.json({ error: "Project not found" }, { status: 404 }); } return NextResponse.json({ success: true }); } catch (error) { console.error(">>> API DELETE /projects error:", error); return NextResponse.json({ error: "Failed to delete project" }, { status: 500 }); } }