src/app/api/admin/search/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
3 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
GETdynamic
Code source· typescript
import { NextRequest, NextResponse } from "next/server";
import { getSession } from "@/lib/auth/session";
import { prisma } from "@/lib/prisma/client";
export const dynamic = "force-dynamic";
export async function GET(req: NextRequest) {
const session = await getSession();
if (!session || session.role !== "TENANT_ADMIN" || !session.tenantId) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
const q = (req.nextUrl.searchParams.get("q") ?? "").trim();
if (q.length < 2) {
return NextResponse.json({ commandes: [], produits: [], clients: [], prestations: [] });
}
const tenantId = session.tenantId;
const tenant = await prisma.tenant.findUnique({
where: { id: tenantId },
select: { subdomain: true, modules: { where: { actif: true }, select: { nom: true } } },
});
if (!tenant) return NextResponse.json({ error: "Tenant introuvable" }, { status: 404 });
const modulesActifs = tenant.modules.map((m) => m.nom);
const hasCatalogue = modulesActifs.includes("catalogue");
const hasServices = modulesActifs.includes("services");
const [commandes, produits, clients, prestations] = await Promise.all([
prisma.commande.findMany({
where: {
tenantId,
OR: [
{ id: { contains: q, mode: "insensitive" } },
{ client: { nom: { contains: q, mode: "insensitive" } } },
{ client: { email: { contains: q, mode: "insensitive" } } },
{ client: { telephone: { contains: q, mode: "insensitive" } } },
],
},
orderBy: { createdAt: "desc" },
take: 5,
select: {
id: true,
statut: true,
total: true,
devise: true,
createdAt: true,
client: { select: { nom: true, email: true } },
},
}),
hasCatalogue
? prisma.produit.findMany({
where: { tenantId, nom: { contains: q, mode: "insensitive" } },
orderBy: { createdAt: "desc" },
take: 5,
select: { id: true, nom: true, prix: true, disponible: true, stock: true },
})
: Promise.resolve([]),
prisma.clientAccount.findMany({
where: {
originTenantId: tenant.subdomain,
OR: [
{ nom: { contains: q, mode: "insensitive" } },
{ prenom: { contains: q, mode: "insensitive" } },
{ email: { contains: q, mode: "insensitive" } },
{ phone: { contains: q, mode: "insensitive" } },
],
},
orderBy: { createdAt: "desc" },
take: 5,
select: { id: true, nom: true, prenom: true, email: true, phone: true },
}),
hasServices
? prisma.prestation.findMany({
where: { tenantId, nom: { contains: q, mode: "insensitive" } },
orderBy: { createdAt: "desc" },
take: 5,
select: { id: true, nom: true, prixMin: true, prixMax: true },
})
: Promise.resolve([]),
]);
return NextResponse.json({ commandes, produits, clients, prestations });
}
import { NextRequest, NextResponse } from "next/server";
import { getSession } from "@/lib/auth/session";
import { prisma } from "@/lib/prisma/client";
export const dynamic = "force-dynamic";
export async function GET(req: NextRequest) {
const session = await getSession();
if (!session || session.role !== "TENANT_ADMIN" || !session.tenantId) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
const q = (req.nextUrl.searchParams.get("q") ?? "").trim();
if (q.length < 2) {
return NextResponse.json({ commandes: [], produits: [], clients: [], prestations: [] });
}
const tenantId = session.tenantId;
const tenant = await prisma.tenant.findUnique({
where: { id: tenantId },
select: { subdomain: true, modules: { where: { actif: true }, select: { nom: true } } },
});
if (!tenant) return NextResponse.json({ error: "Tenant introuvable" }, { status: 404 });
const modulesActifs = tenant.modules.map((m) => m.nom);
const hasCatalogue = modulesActifs.includes("catalogue");
const hasServices = modulesActifs.includes("services");
const [commandes, produits, clients, prestations] = await Promise.all([
prisma.commande.findMany({
where: {
tenantId,
OR: [
{ id: { contains: q, mode: "insensitive" } },
{ client: { nom: { contains: q, mode: "insensitive" } } },
{ client: { email: { contains: q, mode: "insensitive" } } },
{ client: { telephone: { contains: q, mode: "insensitive" } } },
],
},
orderBy: { createdAt: "desc" },
take: 5,
select: {
id: true,
statut: true,
total: true,
devise: true,
createdAt: true,
client: { select: { nom: true, email: true } },
},
}),
hasCatalogue
? prisma.produit.findMany({
where: { tenantId, nom: { contains: q, mode: "insensitive" } },
orderBy: { createdAt: "desc" },
take: 5,
select: { id: true, nom: true, prix: true, disponible: true, stock: true },
})
: Promise.resolve([]),
prisma.clientAccount.findMany({
where: {
originTenantId: tenant.subdomain,
OR: [
{ nom: { contains: q, mode: "insensitive" } },
{ prenom: { contains: q, mode: "insensitive" } },
{ email: { contains: q, mode: "insensitive" } },
{ phone: { contains: q, mode: "insensitive" } },
],
},
orderBy: { createdAt: "desc" },
take: 5,
select: { id: true, nom: true, prenom: true, email: true, phone: true },
}),
hasServices
? prisma.prestation.findMany({
where: { tenantId, nom: { contains: q, mode: "insensitive" } },
orderBy: { createdAt: "desc" },
take: 5,
select: { id: true, nom: true, prixMin: true, prixMax: true },
})
: Promise.resolve([]),
]);
return NextResponse.json({ commandes, produits, clients, prestations });
}