espace-paie-odentas/app/api/staff/productions/[id]/route.ts

252 lines
7.1 KiB
TypeScript

// app/api/staff/productions/[id]/route.ts
import { NextResponse, NextRequest } from "next/server";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
export const dynamic = "force-dynamic";
export const revalidate = 0;
export const runtime = "nodejs";
// Fonction helper pour vérifier si l'utilisateur est staff
async function isStaffUser(supabase: any, userId: string): Promise<boolean> {
try {
const { data: staffRow } = await supabase
.from("staff_users")
.select("is_staff")
.eq("user_id", userId)
.maybeSingle();
return !!staffRow?.is_staff;
} catch {
return false;
}
}
// GET - Récupérer une production spécifique
export async function GET(
req: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const supabase = createRouteHandlerClient({ cookies });
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
return NextResponse.json({ error: "unauthorized" }, { status: 401 });
}
// Vérifier que l'utilisateur est staff
const isStaff = await isStaffUser(supabase, session.user.id);
if (!isStaff) {
return NextResponse.json(
{ error: "forbidden", message: "Staff access required" },
{ status: 403 }
);
}
const { data: production, error } = await supabase
.from("productions")
.select("*")
.eq("id", params.id)
.single();
if (error || !production) {
return NextResponse.json(
{ error: "Production introuvable" },
{ status: 404 }
);
}
return NextResponse.json({ production });
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
return NextResponse.json(
{ error: "internal_server_error", message },
{ status: 500 }
);
}
}
// PATCH - Mettre à jour une production
export async function PATCH(
req: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const supabase = createRouteHandlerClient({ cookies });
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
return NextResponse.json({ error: "unauthorized" }, { status: 401 });
}
// Vérifier que l'utilisateur est staff
const isStaff = await isStaffUser(supabase, session.user.id);
if (!isStaff) {
return NextResponse.json(
{ error: "forbidden", message: "Staff access required" },
{ status: 403 }
);
}
// Vérifier que la production existe
const { data: existing, error: existingError } = await supabase
.from("productions")
.select("id")
.eq("id", params.id)
.single();
if (existingError || !existing) {
return NextResponse.json(
{ error: "Production introuvable" },
{ status: 404 }
);
}
// Récupérer les données du body
const body = await req.json();
const { name, reference, declaration_date, org_id } = body;
// Validation
if (name !== undefined && (!name || !name.trim())) {
return NextResponse.json(
{ error: "Le nom ne peut pas être vide" },
{ status: 400 }
);
}
if (org_id !== undefined && !org_id) {
return NextResponse.json(
{ error: "L'organisation est requise" },
{ status: 400 }
);
}
// Si org_id est modifié, vérifier qu'il existe
if (org_id !== undefined) {
const { data: orgExists, error: orgError } = await supabase
.from("organizations")
.select("id")
.eq("id", org_id)
.single();
if (orgError || !orgExists) {
return NextResponse.json(
{ error: "Organisation introuvable" },
{ status: 400 }
);
}
}
// Préparer les données à mettre à jour
const updateData: any = {};
if (name !== undefined) updateData.name = name.trim();
if (reference !== undefined) updateData.reference = reference?.trim() || null;
if (declaration_date !== undefined) updateData.declaration_date = declaration_date || null;
if (org_id !== undefined) updateData.org_id = org_id;
// Mettre à jour la production
const { data: production, error } = await supabase
.from("productions")
.update(updateData)
.eq("id", params.id)
.select()
.single();
if (error) {
console.error("[api/staff/productions] Update error:", error.message);
return NextResponse.json(
{ error: "Erreur lors de la mise à jour", detail: error.message },
{ status: 500 }
);
}
return NextResponse.json({ production });
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
return NextResponse.json(
{ error: "internal_server_error", message },
{ status: 500 }
);
}
}
// DELETE - Supprimer une production
export async function DELETE(
req: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const supabase = createRouteHandlerClient({ cookies });
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
return NextResponse.json({ error: "unauthorized" }, { status: 401 });
}
// Vérifier que l'utilisateur est staff
const isStaff = await isStaffUser(supabase, session.user.id);
if (!isStaff) {
return NextResponse.json(
{ error: "forbidden", message: "Staff access required" },
{ status: 403 }
);
}
// Vérifier que la production existe
const { data: existing, error: existingError } = await supabase
.from("productions")
.select("id, name")
.eq("id", params.id)
.single();
if (existingError || !existing) {
return NextResponse.json(
{ error: "Production introuvable" },
{ status: 404 }
);
}
// Vérifier si la production est utilisée dans des contrats
const { data: contractsUsing, error: contractsError } = await supabase
.from("cddu_contracts")
.select("id")
.eq("production_id", params.id)
.limit(1);
if (contractsError) {
console.error("[api/staff/productions] Check contracts error:", contractsError.message);
}
if (contractsUsing && contractsUsing.length > 0) {
return NextResponse.json(
{ error: "Cette production est utilisée dans des contrats et ne peut pas être supprimée" },
{ status: 400 }
);
}
// Supprimer la production
const { error } = await supabase
.from("productions")
.delete()
.eq("id", params.id);
if (error) {
console.error("[api/staff/productions] Delete error:", error.message);
return NextResponse.json(
{ error: "Erreur lors de la suppression", detail: error.message },
{ status: 500 }
);
}
return NextResponse.json({
message: "Production supprimée avec succès",
deleted_id: params.id
});
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
return NextResponse.json(
{ error: "internal_server_error", message },
{ status: 500 }
);
}
}