149 lines
4.4 KiB
TypeScript
149 lines
4.4 KiB
TypeScript
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<string, unknown> = {};
|
|
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 });
|
|
}
|
|
}
|