src/app/api/wishlist/route.ts
Annotation non disponible
Lance npm run annotate (nécessite ANTHROPIC_API_KEY dans .env.local) pour générer une annotation française par Claude Haiku 4.5.
Concepts détectés — comprends la théorie
ORM Prisma
6 occurrencesCe fichier accède à la base de données via Prisma. Prisma est l'ORM utilisé côté backend pour les requêtes typées sur PostgreSQL.
Voir l'article général
Route API Next.js
4 occurrencesCe fichier est une route API Next.js (App Router). Voir le contrat API complet pour les conventions de réponse et d'auth.
Voir l'article général
2 exports
GETPOST
Code source· typescript
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma/client";
import { getSession } from "@/lib/auth/session";
import { getTenant } from "@/lib/auth/get-tenant";
import { cookies } from "next/headers";
export async function GET(req: NextRequest) {
try {
const tenant = await getTenant();
if (!tenant) return NextResponse.json({ error: "Tenant introuvable" }, { status: 404 });
const session = await getSession();
const cookieStore = await cookies();
const sessionId = cookieStore.get("panier_session")?.value ?? null;
const where = session?.role === "CLIENT"
? { tenantId: tenant.id, clientId: session.userId }
: sessionId
? { tenantId: tenant.id, sessionId }
: null;
if (!where) return NextResponse.json({ produitIds: [] });
const items = await prisma.wishlist.findMany({ where });
return NextResponse.json({ produitIds: items.map((i) => i.produitId) });
} catch (error) {
console.error("wishlist GET error:", error);
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}
export async function POST(req: NextRequest) {
try {
const tenant = await getTenant();
if (!tenant) return NextResponse.json({ error: "Tenant introuvable" }, { status: 404 });
const { produitId } = await req.json();
if (!produitId) return NextResponse.json({ error: "produitId requis" }, { status: 400 });
const session = await getSession();
const cookieStore = await cookies();
let sessionId = cookieStore.get("panier_session")?.value ?? null;
// Créer sessionId anonyme si besoin (partage avec panier)
if (!session && !sessionId) {
sessionId = crypto.randomUUID();
}
const clientId = session?.role === "CLIENT" ? session.userId : null;
// Trouver via la bonne clé unique
const existing = clientId
? await prisma.wishlist.findUnique({
where: { tenantId_clientId_produitId: { tenantId: tenant.id, clientId, produitId } },
})
: sessionId
? await prisma.wishlist.findUnique({
where: { tenantId_sessionId_produitId: { tenantId: tenant.id, sessionId, produitId } },
})
: null;
const response = existing
? await prisma.wishlist.delete({
where: { id: existing.id },
}).then(() => NextResponse.json({ enWishlist: false }))
: await prisma.wishlist.create({
data: { tenantId: tenant.id, clientId, sessionId: clientId ? null : sessionId, produitId },
}).then(() => NextResponse.json({ enWishlist: true }));
if (!session && sessionId && !cookieStore.get("panier_session")?.value) {
response.cookies.set("panier_session", sessionId, {
httpOnly: true,
sameSite: "lax",
maxAge: 60 * 60 * 24 * 30,
path: "/",
});
}
return response;
} catch (error) {
console.error("wishlist POST error:", error);
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma/client";
import { getSession } from "@/lib/auth/session";
import { getTenant } from "@/lib/auth/get-tenant";
import { cookies } from "next/headers";
export async function GET(req: NextRequest) {
try {
const tenant = await getTenant();
if (!tenant) return NextResponse.json({ error: "Tenant introuvable" }, { status: 404 });
const session = await getSession();
const cookieStore = await cookies();
const sessionId = cookieStore.get("panier_session")?.value ?? null;
const where = session?.role === "CLIENT"
? { tenantId: tenant.id, clientId: session.userId }
: sessionId
? { tenantId: tenant.id, sessionId }
: null;
if (!where) return NextResponse.json({ produitIds: [] });
const items = await prisma.wishlist.findMany({ where });
return NextResponse.json({ produitIds: items.map((i) => i.produitId) });
} catch (error) {
console.error("wishlist GET error:", error);
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}
export async function POST(req: NextRequest) {
try {
const tenant = await getTenant();
if (!tenant) return NextResponse.json({ error: "Tenant introuvable" }, { status: 404 });
const { produitId } = await req.json();
if (!produitId) return NextResponse.json({ error: "produitId requis" }, { status: 400 });
const session = await getSession();
const cookieStore = await cookies();
let sessionId = cookieStore.get("panier_session")?.value ?? null;
// Créer sessionId anonyme si besoin (partage avec panier)
if (!session && !sessionId) {
sessionId = crypto.randomUUID();
}
const clientId = session?.role === "CLIENT" ? session.userId : null;
// Trouver via la bonne clé unique
const existing = clientId
? await prisma.wishlist.findUnique({
where: { tenantId_clientId_produitId: { tenantId: tenant.id, clientId, produitId } },
})
: sessionId
? await prisma.wishlist.findUnique({
where: { tenantId_sessionId_produitId: { tenantId: tenant.id, sessionId, produitId } },
})
: null;
const response = existing
? await prisma.wishlist.delete({
where: { id: existing.id },
}).then(() => NextResponse.json({ enWishlist: false }))
: await prisma.wishlist.create({
data: { tenantId: tenant.id, clientId, sessionId: clientId ? null : sessionId, produitId },
}).then(() => NextResponse.json({ enWishlist: true }));
if (!session && sessionId && !cookieStore.get("panier_session")?.value) {
response.cookies.set("panier_session", sessionId, {
httpOnly: true,
sameSite: "lax",
maxAge: 60 * 60 * 24 * 30,
path: "/",
});
}
return response;
} catch (error) {
console.error("wishlist POST error:", error);
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
}
}