252 lines
7.1 KiB
TypeScript
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 }
|
|
);
|
|
}
|
|
}
|