fix: update team shouldnot create new user

This commit is contained in:
Julien Froidefond
2025-08-22 12:15:36 +02:00
parent 76015510f3
commit 90c2f25ec7
3 changed files with 186 additions and 30 deletions

View File

@@ -53,7 +53,21 @@ export async function POST(request: NextRequest) {
} }
const evaluationService = new EvaluationService(); const evaluationService = new EvaluationService();
const userUuid = await evaluationService.upsertUserUuid(profile);
// Vérifier s'il y a déjà un cookie d'authentification
const cookieStore = await cookies();
const existingUserUuid = cookieStore.get(COOKIE_NAME)?.value;
let userUuid: string;
if (existingUserUuid) {
// Mettre à jour l'utilisateur existant
await evaluationService.updateUserByUuid(existingUserUuid, profile);
userUuid = existingUserUuid;
} else {
// Créer un nouvel utilisateur
userUuid = await evaluationService.upsertUserUuid(profile);
}
// Créer la réponse avec le cookie // Créer la réponse avec le cookie
const response = NextResponse.json( const response = NextResponse.json(

View File

@@ -48,16 +48,9 @@ export async function getServerUserEvaluation() {
try { try {
const evaluationService = new EvaluationService(); const evaluationService = new EvaluationService();
// Récupérer d'abord le profil utilisateur via UUID // Charger directement l'évaluation par UUID
const userProfile = await evaluationService.getUserByUuid(userUuid); const userEvaluation = await evaluationService.loadUserEvaluationByUuid(
userUuid
if (!userProfile) {
return null;
}
// Puis charger l'évaluation avec le profil
const userEvaluation = await evaluationService.loadUserEvaluation(
userProfile
); );
return userEvaluation; return userEvaluation;

View File

@@ -16,37 +16,89 @@ export class EvaluationService {
const client = await pool.connect(); const client = await pool.connect();
try { try {
// Vérifier si l'utilisateur existe déjà (par firstName + lastName + teamId) // Créer un nouvel utilisateur avec UUID auto-généré
const existingUserQuery = ` const insertQuery = `
SELECT uuid_id FROM users INSERT INTO users (first_name, last_name, team_id, uuid_id)
WHERE first_name = $1 AND last_name = $2 AND team_id = $3 VALUES ($1, $2, $3, uuid_generate_v4())
RETURNING uuid_id
`; `;
const existingUser = await client.query(existingUserQuery, [ const result = await client.query(insertQuery, [
profile.firstName, profile.firstName,
profile.lastName, profile.lastName,
profile.teamId, profile.teamId,
]); ]);
if (existingUser.rows.length > 0) { return result.rows[0].uuid_id;
// Retourner l'UUID de l'utilisateur existant } catch (error: any) {
return existingUser.rows[0].uuid_id; // Si erreur de contrainte unique, l'utilisateur existe déjà
} else { if (
// Créer un nouvel utilisateur avec UUID auto-généré error.code === "23505" &&
const insertQuery = ` error.constraint === "users_first_name_last_name_team_id_key"
INSERT INTO users (first_name, last_name, team_id, uuid_id) ) {
VALUES ($1, $2, $3, uuid_generate_v4()) // Récupérer l'utilisateur existant
RETURNING uuid_id const existingUserQuery = `
SELECT uuid_id FROM users
WHERE first_name = $1 AND last_name = $2 AND team_id = $3
`; `;
const result = await client.query(insertQuery, [ const existingUser = await client.query(existingUserQuery, [
profile.firstName, profile.firstName,
profile.lastName, profile.lastName,
profile.teamId, profile.teamId,
]); ]);
return result.rows[0].uuid_id; return existingUser.rows[0].uuid_id;
} }
throw error;
} finally {
client.release();
}
}
/**
* Met à jour un utilisateur existant par son UUID
*/
async updateUserByUuid(
userUuid: string,
profile: UserProfile
): Promise<void> {
const pool = getPool();
const client = await pool.connect();
try {
// Vérifier s'il existe déjà un utilisateur avec ce nom/prénom dans la nouvelle équipe
const conflictCheckQuery = `
SELECT uuid_id FROM users
WHERE first_name = $1 AND last_name = $2 AND team_id = $3 AND uuid_id != $4
`;
const conflictResult = await client.query(conflictCheckQuery, [
profile.firstName,
profile.lastName,
profile.teamId,
userUuid,
]);
if (conflictResult.rows.length > 0) {
throw new Error(
"Un utilisateur avec ce nom et prénom existe déjà dans cette équipe"
);
}
// Mettre à jour l'utilisateur existant
const updateQuery = `
UPDATE users
SET first_name = $1, last_name = $2, team_id = $3, updated_at = CURRENT_TIMESTAMP
WHERE uuid_id = $4
`;
await client.query(updateQuery, [
profile.firstName,
profile.lastName,
profile.teamId,
userUuid,
]);
} finally { } finally {
client.release(); client.release();
} }
@@ -83,6 +135,104 @@ export class EvaluationService {
} }
} }
/**
* Charge une évaluation utilisateur directement par UUID
*/
async loadUserEvaluationByUuid(
userUuid: string
): Promise<UserEvaluation | null> {
const pool = getPool();
const client = await pool.connect();
try {
// Trouver l'utilisateur et son évaluation par UUID
const userQuery = `
SELECT u.*, ue.id as user_evaluation_id, ue.last_updated
FROM users u
LEFT JOIN user_evaluations ue ON u.uuid_id = ue.user_uuid
WHERE u.uuid_id = $1
`;
const userResult = await client.query(userQuery, [userUuid]);
if (
userResult.rows.length === 0 ||
!userResult.rows[0].user_evaluation_id
) {
return null;
}
const userData = userResult.rows[0];
const userEvaluationId = userData.user_evaluation_id;
// Charger directement les skills évaluées avec leurs catégories
const skillsQuery = `
SELECT
sc.name as category_name,
se.skill_id,
se.level,
se.can_mentor,
se.wants_to_learn,
se.is_selected
FROM skill_evaluations se
JOIN skills s ON se.skill_id = s.id
JOIN skill_categories sc ON s.category_id = sc.id
WHERE se.user_evaluation_id = $1
ORDER BY sc.name, s.name
`;
const skillsResult = await client.query(skillsQuery, [userEvaluationId]);
// Grouper par catégorie
const categoriesMap = new Map<string, CategoryEvaluation>();
for (const row of skillsResult.rows) {
const categoryName = row.category_name;
if (!categoriesMap.has(categoryName)) {
categoriesMap.set(categoryName, {
category: categoryName,
selectedSkillIds: [],
skills: [],
});
}
const catEval = categoriesMap.get(categoryName)!;
// Ajouter aux skills sélectionnées si is_selected = true
if (row.is_selected) {
catEval.selectedSkillIds.push(row.skill_id);
}
// Ajouter aux évaluations si elle est sélectionnée (donc évaluée)
if (row.is_selected) {
catEval.skills.push({
skillId: row.skill_id,
level: row.level,
canMentor: row.can_mentor,
wantsToLearn: row.wants_to_learn,
});
}
}
const evaluations: CategoryEvaluation[] = Array.from(
categoriesMap.values()
);
return {
profile: {
firstName: userData.first_name,
lastName: userData.last_name,
teamId: userData.team_id,
},
evaluations,
lastUpdated: userData.last_updated.toISOString(),
};
} finally {
client.release();
}
}
/** /**
* Crée ou met à jour un utilisateur (legacy - retourne l'ID numérique) * Crée ou met à jour un utilisateur (legacy - retourne l'ID numérique)
*/ */
@@ -318,18 +468,17 @@ export class EvaluationService {
const client = await pool.connect(); const client = await pool.connect();
try { try {
// Trouver l'utilisateur // Trouver l'utilisateur par firstName + lastName (équipe peut avoir changé)
const userQuery = ` const userQuery = `
SELECT u.*, ue.id as user_evaluation_id, ue.last_updated SELECT u.*, ue.id as user_evaluation_id, ue.last_updated
FROM users u FROM users u
LEFT JOIN user_evaluations ue ON u.uuid_id = ue.user_uuid LEFT JOIN user_evaluations ue ON u.uuid_id = ue.user_uuid
WHERE u.first_name = $1 AND u.last_name = $2 AND u.team_id = $3 WHERE u.first_name = $1 AND u.last_name = $2
`; `;
const userResult = await client.query(userQuery, [ const userResult = await client.query(userQuery, [
profile.firstName, profile.firstName,
profile.lastName, profile.lastName,
profile.teamId,
]); ]);
if ( if (