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

166 lines
4.6 KiB
TypeScript

// app/api/staff/productions/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 - Lister toutes les productions (avec filtres optionnels)
export async function GET(req: NextRequest) {
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 }
);
}
// Paramètres de filtrage
const url = new URL(req.url);
const orgId = url.searchParams.get("org_id");
const searchQuery = url.searchParams.get("q");
// Construire la requête
let query = supabase
.from("productions")
.select("*")
.order("name", { ascending: true });
// Filtrer par organisation si spécifié
if (orgId) {
query = query.eq("org_id", orgId);
}
// Filtrer par recherche si spécifié
if (searchQuery) {
query = query.or(
`name.ilike.%${searchQuery}%,reference.ilike.%${searchQuery}%`
);
}
const { data: productions, error } = await query;
if (error) {
console.error("[api/staff/productions] Supabase error:", error.message);
return NextResponse.json(
{ error: "supabase_error", detail: error.message },
{ status: 500 }
);
}
return NextResponse.json({ productions: productions || [] });
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
return NextResponse.json(
{ error: "internal_server_error", message },
{ status: 500 }
);
}
}
// POST - Créer une nouvelle production
export async function POST(req: NextRequest) {
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 }
);
}
// Récupérer les données du body
const body = await req.json();
const { name, reference, declaration_date, org_id } = body;
// Validation
if (!name || !name.trim()) {
return NextResponse.json(
{ error: "Le nom est requis" },
{ status: 400 }
);
}
if (!org_id) {
return NextResponse.json(
{ error: "L'organisation est requise" },
{ status: 400 }
);
}
// Vérifier que l'organisation existe
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 }
);
}
// Créer la production
const { data: production, error } = await supabase
.from("productions")
.insert({
name: name.trim(),
reference: reference?.trim() || null,
declaration_date: declaration_date || null,
org_id,
})
.select()
.single();
if (error) {
console.error("[api/staff/productions] Insert error:", error.message);
return NextResponse.json(
{ error: "Erreur lors de la création", detail: error.message },
{ status: 500 }
);
}
return NextResponse.json({ production }, { status: 201 });
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
return NextResponse.json(
{ error: "internal_server_error", message },
{ status: 500 }
);
}
}