refactor: Userservice
This commit is contained in:
192
services/user-service.ts
Normal file
192
services/user-service.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
import { getPool } from "./database";
|
||||
import { UserProfile } from "../lib/types";
|
||||
|
||||
export class UserService {
|
||||
/**
|
||||
* Crée ou met à jour un utilisateur et retourne son UUID
|
||||
*/
|
||||
async upsertUserUuid(profile: UserProfile): Promise<string> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
// Créer un nouvel utilisateur avec UUID auto-généré
|
||||
const insertQuery = `
|
||||
INSERT INTO users (first_name, last_name, team_id, uuid_id)
|
||||
VALUES ($1, $2, $3, uuid_generate_v4())
|
||||
RETURNING uuid_id
|
||||
`;
|
||||
|
||||
const result = await client.query(insertQuery, [
|
||||
profile.firstName,
|
||||
profile.lastName,
|
||||
profile.teamId,
|
||||
]);
|
||||
|
||||
return result.rows[0].uuid_id;
|
||||
} catch (error: any) {
|
||||
// Si erreur de contrainte unique, l'utilisateur existe déjà
|
||||
if (
|
||||
error.code === "23505" &&
|
||||
error.constraint === "users_first_name_last_name_team_id_key"
|
||||
) {
|
||||
// Récupérer l'utilisateur existant
|
||||
const existingUserQuery = `
|
||||
SELECT uuid_id FROM users
|
||||
WHERE first_name = $1 AND last_name = $2 AND team_id = $3
|
||||
`;
|
||||
|
||||
const existingUser = await client.query(existingUserQuery, [
|
||||
profile.firstName,
|
||||
profile.lastName,
|
||||
profile.teamId,
|
||||
]);
|
||||
|
||||
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 {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère un utilisateur par son UUID
|
||||
*/
|
||||
async getUserByUuid(userUuid: string): Promise<UserProfile | null> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
const query = `
|
||||
SELECT u.first_name, u.last_name, u.team_id
|
||||
FROM users u
|
||||
WHERE u.uuid_id = $1
|
||||
`;
|
||||
|
||||
const result = await client.query(query, [userUuid]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const user = result.rows[0];
|
||||
return {
|
||||
firstName: user.first_name,
|
||||
lastName: user.last_name,
|
||||
teamId: user.team_id,
|
||||
};
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée ou met à jour un utilisateur (legacy - retourne l'ID numérique)
|
||||
*/
|
||||
async upsertUser(profile: UserProfile): Promise<number> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
// Vérifier si l'utilisateur existe déjà (par firstName + lastName + teamId)
|
||||
const existingUserQuery = `
|
||||
SELECT id FROM users
|
||||
WHERE first_name = $1 AND last_name = $2 AND team_id = $3
|
||||
`;
|
||||
|
||||
const existingUser = await client.query(existingUserQuery, [
|
||||
profile.firstName,
|
||||
profile.lastName,
|
||||
profile.teamId,
|
||||
]);
|
||||
|
||||
if (existingUser.rows.length > 0) {
|
||||
// Mettre à jour l'utilisateur existant
|
||||
const updateQuery = `
|
||||
UPDATE users
|
||||
SET first_name = $1, last_name = $2, team_id = $3, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $4
|
||||
RETURNING id
|
||||
`;
|
||||
|
||||
const result = await client.query(updateQuery, [
|
||||
profile.firstName,
|
||||
profile.lastName,
|
||||
profile.teamId,
|
||||
existingUser.rows[0].id,
|
||||
]);
|
||||
|
||||
return result.rows[0].id;
|
||||
} else {
|
||||
// Créer un nouvel utilisateur
|
||||
const insertQuery = `
|
||||
INSERT INTO users (first_name, last_name, team_id)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id
|
||||
`;
|
||||
|
||||
const result = await client.query(insertQuery, [
|
||||
profile.firstName,
|
||||
profile.lastName,
|
||||
profile.teamId,
|
||||
]);
|
||||
|
||||
return result.rows[0].id;
|
||||
}
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Instance singleton
|
||||
export const userService = new UserService();
|
||||
Reference in New Issue
Block a user