Refactor event handling and user management: Replace direct database calls with service layer methods for events, user profiles, and preferences, enhancing code organization and maintainability. Update API routes to utilize new services for event registration, feedback, and user statistics, ensuring a consistent approach across the application.
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { CharacterClass } from "@/prisma/generated/prisma/enums";
|
||||
import { userService } from "@/services/users/user.service";
|
||||
import {
|
||||
ValidationError,
|
||||
NotFoundError,
|
||||
ConflictError,
|
||||
} from "@/services/errors";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
@@ -14,139 +18,10 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur existe et a été créé récemment (dans les 10 dernières minutes)
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json(
|
||||
{ error: "Utilisateur non trouvé" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
// Vérifier que le compte a été créé récemment (dans les 10 dernières minutes)
|
||||
const tenMinutesAgo = new Date(Date.now() - 10 * 60 * 1000);
|
||||
if (user.createdAt < tenMinutesAgo) {
|
||||
return NextResponse.json(
|
||||
{ error: "Temps écoulé pour finaliser l'inscription" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Validation username
|
||||
if (username !== undefined) {
|
||||
if (typeof username !== "string" || username.trim().length === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: "Le nom d'utilisateur ne peut pas être vide" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
if (username.length < 3 || username.length > 20) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error:
|
||||
"Le nom d'utilisateur doit contenir entre 3 et 20 caractères",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Vérifier si le username est déjà pris par un autre utilisateur
|
||||
const existingUser = await prisma.user.findFirst({
|
||||
where: {
|
||||
username: username.trim(),
|
||||
NOT: { id: userId },
|
||||
},
|
||||
});
|
||||
|
||||
if (existingUser) {
|
||||
return NextResponse.json(
|
||||
{ error: "Ce nom d'utilisateur est déjà pris" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Validation bio
|
||||
if (bio !== undefined && bio !== null) {
|
||||
if (typeof bio !== "string") {
|
||||
return NextResponse.json(
|
||||
{ error: "La bio doit être une chaîne de caractères" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
if (bio.length > 500) {
|
||||
return NextResponse.json(
|
||||
{ error: "La bio ne peut pas dépasser 500 caractères" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Validation characterClass
|
||||
const validClasses = [
|
||||
"WARRIOR",
|
||||
"MAGE",
|
||||
"ROGUE",
|
||||
"RANGER",
|
||||
"PALADIN",
|
||||
"ENGINEER",
|
||||
"MERCHANT",
|
||||
"SCHOLAR",
|
||||
"BERSERKER",
|
||||
"NECROMANCER",
|
||||
];
|
||||
if (characterClass !== undefined && characterClass !== null) {
|
||||
if (!validClasses.includes(characterClass)) {
|
||||
return NextResponse.json(
|
||||
{ error: "Classe de personnage invalide" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre à jour l'utilisateur
|
||||
const updateData: {
|
||||
username?: string;
|
||||
avatar?: string | null;
|
||||
bio?: string | null;
|
||||
characterClass?: CharacterClass | null;
|
||||
} = {};
|
||||
|
||||
if (username !== undefined) {
|
||||
updateData.username = username.trim();
|
||||
}
|
||||
if (avatar !== undefined) {
|
||||
updateData.avatar = avatar || null;
|
||||
}
|
||||
if (bio !== undefined) {
|
||||
if (bio === null || bio === "") {
|
||||
updateData.bio = null;
|
||||
} else if (typeof bio === "string") {
|
||||
updateData.bio = bio.trim() || null;
|
||||
} else {
|
||||
updateData.bio = null;
|
||||
}
|
||||
}
|
||||
if (characterClass !== undefined) {
|
||||
updateData.characterClass = (characterClass as CharacterClass) || null;
|
||||
}
|
||||
|
||||
// Si aucun champ à mettre à jour, retourner succès quand même
|
||||
if (Object.keys(updateData).length === 0) {
|
||||
return NextResponse.json({
|
||||
message: "Profil finalisé avec succès",
|
||||
userId: user.id,
|
||||
});
|
||||
}
|
||||
|
||||
const updatedUser = await prisma.user.update({
|
||||
where: { id: userId },
|
||||
data: updateData,
|
||||
});
|
||||
const updatedUser = await userService.validateAndCompleteRegistration(
|
||||
userId,
|
||||
{ username, avatar, bio, characterClass }
|
||||
);
|
||||
|
||||
return NextResponse.json({
|
||||
message: "Profil finalisé avec succès",
|
||||
@@ -154,11 +29,20 @@ export async function POST(request: Request) {
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error completing registration:", error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : "Erreur inconnue";
|
||||
|
||||
if (
|
||||
error instanceof ValidationError ||
|
||||
error instanceof ConflictError
|
||||
) {
|
||||
return NextResponse.json({ error: error.message }, { status: 400 });
|
||||
}
|
||||
if (error instanceof NotFoundError) {
|
||||
return NextResponse.json({ error: error.message }, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: `Erreur lors de la finalisation de l'inscription: ${errorMessage}`,
|
||||
error: `Erreur lors de la finalisation de l'inscription: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
|
||||
@@ -1,73 +1,19 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { userService } from "@/services/users/user.service";
|
||||
import { ValidationError, ConflictError } from "@/services/errors";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { email, username, password, bio, characterClass, avatar } = body;
|
||||
|
||||
if (!email || !username || !password) {
|
||||
return NextResponse.json(
|
||||
{ error: "Email, nom d'utilisateur et mot de passe sont requis" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
return NextResponse.json(
|
||||
{ error: "Le mot de passe doit contenir au moins 6 caractères" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Valider characterClass si fourni
|
||||
const validCharacterClasses = [
|
||||
"WARRIOR",
|
||||
"MAGE",
|
||||
"ROGUE",
|
||||
"RANGER",
|
||||
"PALADIN",
|
||||
"ENGINEER",
|
||||
"MERCHANT",
|
||||
"SCHOLAR",
|
||||
"BERSERKER",
|
||||
"NECROMANCER",
|
||||
];
|
||||
if (characterClass && !validCharacterClasses.includes(characterClass)) {
|
||||
return NextResponse.json(
|
||||
{ error: "Classe de personnage invalide" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Vérifier si l'email existe déjà
|
||||
const existingUser = await prisma.user.findFirst({
|
||||
where: {
|
||||
OR: [{ email }, { username }],
|
||||
},
|
||||
});
|
||||
|
||||
if (existingUser) {
|
||||
return NextResponse.json(
|
||||
{ error: "Cet email ou nom d'utilisateur est déjà utilisé" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Hasher le mot de passe
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
|
||||
// Créer l'utilisateur
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email,
|
||||
username,
|
||||
password: hashedPassword,
|
||||
bio: bio || null,
|
||||
characterClass: characterClass || null,
|
||||
avatar: avatar || null,
|
||||
},
|
||||
const user = await userService.validateAndCreateUser({
|
||||
email,
|
||||
username,
|
||||
password,
|
||||
bio,
|
||||
characterClass,
|
||||
avatar,
|
||||
});
|
||||
|
||||
return NextResponse.json(
|
||||
@@ -76,6 +22,11 @@ export async function POST(request: Request) {
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Registration error:", error);
|
||||
|
||||
if (error instanceof ValidationError || error instanceof ConflictError) {
|
||||
return NextResponse.json({ error: error.message }, { status: 400 });
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: "Une erreur est survenue lors de l'inscription" },
|
||||
{ status: 500 }
|
||||
|
||||
Reference in New Issue
Block a user