97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import { revalidatePath } from "next/cache";
|
||
import { NextResponse } from "next/server";
|
||
import { WAFFLE_CATEGORIES } from "@/lib/constants";
|
||
import { normalizeImageUrl } from "@/lib/image-url";
|
||
import { parseStrictBoolean } from "@/lib/json-fields";
|
||
import { prisma } from "@/lib/prisma";
|
||
import { getSessionUserId } from "@/lib/session";
|
||
import {
|
||
parseIngredientIds,
|
||
validateIngredientIds,
|
||
waffleIngredientInclude,
|
||
} from "@/lib/waffle-ingredients";
|
||
|
||
const CATEGORIES: Set<string> = new Set(Object.values(WAFFLE_CATEGORIES));
|
||
|
||
export async function GET() {
|
||
const userId = await getSessionUserId();
|
||
if (!userId) {
|
||
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
|
||
}
|
||
|
||
const waffles = await prisma.waffle.findMany({
|
||
orderBy: [{ category: "asc" }, { name: "asc" }],
|
||
include: waffleIngredientInclude,
|
||
});
|
||
return NextResponse.json(waffles);
|
||
}
|
||
|
||
export async function POST(request: Request) {
|
||
const userId = await getSessionUserId();
|
||
if (!userId) {
|
||
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
|
||
}
|
||
|
||
let body: {
|
||
name?: string;
|
||
ingredients?: string;
|
||
price?: number;
|
||
isNew?: boolean;
|
||
category?: string;
|
||
imageUrl?: string | null;
|
||
ingredientIds?: unknown;
|
||
};
|
||
try {
|
||
body = await request.json();
|
||
} catch {
|
||
return NextResponse.json({ error: "Corps invalide" }, { status: 400 });
|
||
}
|
||
|
||
const name = String(body.name ?? "").trim();
|
||
const ingredients = String(body.ingredients ?? "").trim();
|
||
const price = Number(body.price);
|
||
const isNewParsed = parseStrictBoolean(body.isNew, "isNew", false);
|
||
if (!isNewParsed.ok) {
|
||
return NextResponse.json({ error: isNewParsed.error }, { status: 400 });
|
||
}
|
||
const isNew = isNewParsed.value;
|
||
const category = String(body.category ?? "").trim();
|
||
const imageUrl = normalizeImageUrl(body.imageUrl);
|
||
|
||
if (!name || !ingredients || Number.isNaN(price) || price < 0) {
|
||
return NextResponse.json({ error: "Données invalides" }, { status: 400 });
|
||
}
|
||
if (!CATEGORIES.has(category)) {
|
||
return NextResponse.json({ error: "Catégorie invalide" }, { status: 400 });
|
||
}
|
||
if (
|
||
body.imageUrl != null &&
|
||
String(body.imageUrl).trim() !== "" &&
|
||
imageUrl === null
|
||
) {
|
||
return NextResponse.json({ error: "URL d’image invalide" }, { status: 400 });
|
||
}
|
||
|
||
const ingredientIds = parseIngredientIds(body.ingredientIds) ?? [];
|
||
if (!(await validateIngredientIds(ingredientIds))) {
|
||
return NextResponse.json({ error: "Ingrédient inconnu" }, { status: 400 });
|
||
}
|
||
|
||
const waffle = await prisma.waffle.create({
|
||
data: {
|
||
name,
|
||
ingredients,
|
||
price,
|
||
isNew,
|
||
category,
|
||
imageUrl,
|
||
...(ingredientIds.length > 0
|
||
? { ingredientItems: { connect: ingredientIds.map((id) => ({ id })) } }
|
||
: {}),
|
||
},
|
||
include: waffleIngredientInclude,
|
||
});
|
||
revalidatePath("/");
|
||
return NextResponse.json(waffle);
|
||
}
|