src/app/api/admin/auth/code/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
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
ORM Prisma
2 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
2 exports
POSTdynamic
Code source· typescript
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma/client";
import { isValidCodeFormat, normalizeCode } from "@/lib/admin/code-acces";
export const dynamic = "force-dynamic";
// POST /api/admin/auth/code
// Body: { code: "WARI-XXXX-XXXX" }
// Vérifie le code, retourne tenant + onboardingStep + données déjà saisies pour reprise.
export async function POST(req: NextRequest) {
let body: { code?: string };
try {
body = await req.json();
} catch {
return NextResponse.json({ error: "Body invalide" }, { status: 400 });
}
const code = normalizeCode(body.code ?? "");
if (!isValidCodeFormat(code)) {
return NextResponse.json(
{ error: "Format de code invalide. Format attendu : WARI-XXXX-XXXX" },
{ status: 400 }
);
}
const tenant = await prisma.tenant.findUnique({
where: { codeAcces: code },
select: {
id: true,
nom: true,
onboardingStep: true,
modulesPrevus: true,
actif: true,
users: {
where: { isPrimary: true },
select: {
id: true,
email: true,
username: true,
emailVerifiedAt: true,
},
take: 1,
},
},
});
if (!tenant) {
return NextResponse.json(
{ error: "Code invalide. Vérifie le code reçu par ton accompagnant wari.pro." },
{ status: 404 }
);
}
if (!tenant.actif) {
return NextResponse.json(
{ error: "Ce tenant est suspendu. Contacte ton accompagnant wari.pro." },
{ status: 403 }
);
}
if (tenant.onboardingStep === "DONE") {
return NextResponse.json(
{ error: "Setup déjà terminé. Connecte-toi via l'onglet Connexion." },
{ status: 422 }
);
}
const primary = tenant.users[0] ?? null;
return NextResponse.json({
tenantId: tenant.id,
tenantNom: tenant.nom,
modulesPrevus: tenant.modulesPrevus,
onboardingStep: tenant.onboardingStep ?? "CODE",
// Données existantes pour reprise (si user en cours de wizard) :
primaryUser: primary
? {
email: primary.email,
username: primary.username,
emailVerified: !!primary.emailVerifiedAt,
}
: null,
});
}
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma/client";
import { isValidCodeFormat, normalizeCode } from "@/lib/admin/code-acces";
export const dynamic = "force-dynamic";
// POST /api/admin/auth/code
// Body: { code: "WARI-XXXX-XXXX" }
// Vérifie le code, retourne tenant + onboardingStep + données déjà saisies pour reprise.
export async function POST(req: NextRequest) {
let body: { code?: string };
try {
body = await req.json();
} catch {
return NextResponse.json({ error: "Body invalide" }, { status: 400 });
}
const code = normalizeCode(body.code ?? "");
if (!isValidCodeFormat(code)) {
return NextResponse.json(
{ error: "Format de code invalide. Format attendu : WARI-XXXX-XXXX" },
{ status: 400 }
);
}
const tenant = await prisma.tenant.findUnique({
where: { codeAcces: code },
select: {
id: true,
nom: true,
onboardingStep: true,
modulesPrevus: true,
actif: true,
users: {
where: { isPrimary: true },
select: {
id: true,
email: true,
username: true,
emailVerifiedAt: true,
},
take: 1,
},
},
});
if (!tenant) {
return NextResponse.json(
{ error: "Code invalide. Vérifie le code reçu par ton accompagnant wari.pro." },
{ status: 404 }
);
}
if (!tenant.actif) {
return NextResponse.json(
{ error: "Ce tenant est suspendu. Contacte ton accompagnant wari.pro." },
{ status: 403 }
);
}
if (tenant.onboardingStep === "DONE") {
return NextResponse.json(
{ error: "Setup déjà terminé. Connecte-toi via l'onglet Connexion." },
{ status: 422 }
);
}
const primary = tenant.users[0] ?? null;
return NextResponse.json({
tenantId: tenant.id,
tenantNom: tenant.nom,
modulesPrevus: tenant.modulesPrevus,
onboardingStep: tenant.onboardingStep ?? "CODE",
// Données existantes pour reprise (si user en cours de wizard) :
primaryUser: primary
? {
email: primary.email,
username: primary.username,
emailVerified: !!primary.emailVerifiedAt,
}
: null,
});
}