feat: update evaluation schema and refactor skill evaluations
- Added unique constraint on users table for first_name, last_name, and team_id. - Removed category_evaluations and selected_skills tables, simplifying the schema. - Updated skill_evaluations to directly reference user_evaluations and include is_selected flag. - Refactored EvaluationService to handle skill evaluations directly, improving data integrity and performance. - Introduced new queries for loading skills and evaluations, enhancing data retrieval efficiency. - Added views for user skills summary and category skills count for easier querying.
This commit is contained in:
@@ -45,10 +45,15 @@ CREATE TABLE users (
|
|||||||
last_name VARCHAR(100) NOT NULL,
|
last_name VARCHAR(100) NOT NULL,
|
||||||
team_id VARCHAR(50) REFERENCES teams(id),
|
team_id VARCHAR(50) REFERENCES teams(id),
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(first_name, last_name, team_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- User evaluations table
|
-- ========================================
|
||||||
|
-- SIMPLIFIED EVALUATION SCHEMA
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
-- User evaluations - metadata about user's evaluation session
|
||||||
CREATE TABLE user_evaluations (
|
CREATE TABLE user_evaluations (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||||
@@ -57,35 +62,18 @@ CREATE TABLE user_evaluations (
|
|||||||
UNIQUE(user_id)
|
UNIQUE(user_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Category evaluations table
|
-- Skill evaluations - direct relationship between user and skill
|
||||||
CREATE TABLE category_evaluations (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
user_evaluation_id INTEGER REFERENCES user_evaluations(id) ON DELETE CASCADE,
|
|
||||||
category VARCHAR(100) NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
UNIQUE(user_evaluation_id, category)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Selected skills table (skills the user wants to evaluate)
|
|
||||||
CREATE TABLE selected_skills (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
category_evaluation_id INTEGER REFERENCES category_evaluations(id) ON DELETE CASCADE,
|
|
||||||
skill_id VARCHAR(100) NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
UNIQUE(category_evaluation_id, skill_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Skill evaluations table
|
|
||||||
CREATE TABLE skill_evaluations (
|
CREATE TABLE skill_evaluations (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
category_evaluation_id INTEGER REFERENCES category_evaluations(id) ON DELETE CASCADE,
|
user_evaluation_id INTEGER REFERENCES user_evaluations(id) ON DELETE CASCADE,
|
||||||
skill_id VARCHAR(100) NOT NULL,
|
skill_id VARCHAR(100) REFERENCES skills(id) ON DELETE CASCADE,
|
||||||
level skill_level_enum NOT NULL,
|
level skill_level_enum NOT NULL,
|
||||||
can_mentor BOOLEAN DEFAULT FALSE,
|
can_mentor BOOLEAN DEFAULT FALSE,
|
||||||
wants_to_learn BOOLEAN DEFAULT FALSE,
|
wants_to_learn BOOLEAN DEFAULT FALSE,
|
||||||
|
is_selected BOOLEAN DEFAULT TRUE, -- Replaces selected_skills table
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
UNIQUE(category_evaluation_id, skill_id)
|
UNIQUE(user_evaluation_id, skill_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Insert initial teams data
|
-- Insert initial teams data
|
||||||
@@ -104,11 +92,11 @@ CREATE INDEX idx_teams_direction ON teams(direction);
|
|||||||
CREATE INDEX idx_skills_category_id ON skills(category_id);
|
CREATE INDEX idx_skills_category_id ON skills(category_id);
|
||||||
CREATE INDEX idx_skill_links_skill_id ON skill_links(skill_id);
|
CREATE INDEX idx_skill_links_skill_id ON skill_links(skill_id);
|
||||||
CREATE INDEX idx_users_team_id ON users(team_id);
|
CREATE INDEX idx_users_team_id ON users(team_id);
|
||||||
|
CREATE INDEX idx_users_unique_person ON users(first_name, last_name, team_id);
|
||||||
CREATE INDEX idx_user_evaluations_user_id ON user_evaluations(user_id);
|
CREATE INDEX idx_user_evaluations_user_id ON user_evaluations(user_id);
|
||||||
CREATE INDEX idx_category_evaluations_user_evaluation_id ON category_evaluations(user_evaluation_id);
|
CREATE INDEX idx_skill_evaluations_user_evaluation_id ON skill_evaluations(user_evaluation_id);
|
||||||
CREATE INDEX idx_selected_skills_category_evaluation_id ON selected_skills(category_evaluation_id);
|
|
||||||
CREATE INDEX idx_skill_evaluations_category_evaluation_id ON skill_evaluations(category_evaluation_id);
|
|
||||||
CREATE INDEX idx_skill_evaluations_skill_id ON skill_evaluations(skill_id);
|
CREATE INDEX idx_skill_evaluations_skill_id ON skill_evaluations(skill_id);
|
||||||
|
CREATE INDEX idx_skill_evaluations_is_selected ON skill_evaluations(is_selected);
|
||||||
|
|
||||||
-- Update trigger for users table
|
-- Update trigger for users table
|
||||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||||
@@ -133,3 +121,33 @@ CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users
|
|||||||
|
|
||||||
CREATE TRIGGER update_skill_evaluations_updated_at BEFORE UPDATE ON skill_evaluations
|
CREATE TRIGGER update_skill_evaluations_updated_at BEFORE UPDATE ON skill_evaluations
|
||||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||||
|
|
||||||
|
-- Views for easy querying
|
||||||
|
CREATE VIEW user_skills_summary AS
|
||||||
|
SELECT
|
||||||
|
u.first_name,
|
||||||
|
u.last_name,
|
||||||
|
t.name as team_name,
|
||||||
|
t.direction,
|
||||||
|
sc.name as category_name,
|
||||||
|
s.name as skill_name,
|
||||||
|
se.level,
|
||||||
|
se.can_mentor,
|
||||||
|
se.wants_to_learn,
|
||||||
|
se.is_selected,
|
||||||
|
se.updated_at
|
||||||
|
FROM users u
|
||||||
|
JOIN teams t ON u.team_id = t.id
|
||||||
|
JOIN user_evaluations ue ON u.id = ue.user_id
|
||||||
|
JOIN skill_evaluations se ON ue.id = se.user_evaluation_id
|
||||||
|
JOIN skills s ON se.skill_id = s.id
|
||||||
|
JOIN skill_categories sc ON s.category_id = sc.id;
|
||||||
|
|
||||||
|
CREATE VIEW category_skills_count AS
|
||||||
|
SELECT
|
||||||
|
sc.id as category_id,
|
||||||
|
sc.name as category_name,
|
||||||
|
COUNT(s.id) as total_skills
|
||||||
|
FROM skill_categories sc
|
||||||
|
LEFT JOIN skills s ON sc.id = s.category_id
|
||||||
|
GROUP BY sc.id, sc.name;
|
||||||
|
|||||||
@@ -95,15 +95,15 @@ export class EvaluationService {
|
|||||||
|
|
||||||
const userEvaluationId = userEvalResult.rows[0].id;
|
const userEvaluationId = userEvalResult.rows[0].id;
|
||||||
|
|
||||||
// 3. Supprimer les anciennes évaluations de catégories
|
// 3. Supprimer les anciennes évaluations de skills
|
||||||
await client.query(
|
await client.query(
|
||||||
"DELETE FROM category_evaluations WHERE user_evaluation_id = $1",
|
"DELETE FROM skill_evaluations WHERE user_evaluation_id = $1",
|
||||||
[userEvaluationId]
|
[userEvaluationId]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 4. Sauvegarder les nouvelles évaluations
|
// 4. Sauvegarder les nouvelles évaluations directement
|
||||||
for (const catEval of evaluation.evaluations) {
|
for (const catEval of evaluation.evaluations) {
|
||||||
await this.saveCategoryEvaluation(client, userEvaluationId, catEval);
|
await this.saveSkillEvaluations(client, userEvaluationId, catEval);
|
||||||
}
|
}
|
||||||
|
|
||||||
await client.query("COMMIT");
|
await client.query("COMMIT");
|
||||||
@@ -116,33 +116,30 @@ export class EvaluationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sauvegarde une évaluation de catégorie
|
* Sauvegarde les évaluations de skills directement
|
||||||
*/
|
*/
|
||||||
private async saveCategoryEvaluation(
|
private async saveSkillEvaluations(
|
||||||
client: any,
|
client: any,
|
||||||
userEvaluationId: number,
|
userEvaluationId: number,
|
||||||
catEval: CategoryEvaluation
|
catEval: CategoryEvaluation
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Insérer la catégorie d'évaluation
|
// Insérer les skills sélectionnées (sans évaluation)
|
||||||
const catEvalQuery = `
|
|
||||||
INSERT INTO category_evaluations (user_evaluation_id, category)
|
|
||||||
VALUES ($1, $2)
|
|
||||||
RETURNING id
|
|
||||||
`;
|
|
||||||
|
|
||||||
const catEvalResult = await client.query(catEvalQuery, [
|
|
||||||
userEvaluationId,
|
|
||||||
catEval.category,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const categoryEvaluationId = catEvalResult.rows[0].id;
|
|
||||||
|
|
||||||
// Insérer les skills sélectionnées
|
|
||||||
for (const skillId of catEval.selectedSkillIds) {
|
for (const skillId of catEval.selectedSkillIds) {
|
||||||
await client.query(
|
const isEvaluated = catEval.skills.some(
|
||||||
"INSERT INTO selected_skills (category_evaluation_id, skill_id) VALUES ($1, $2)",
|
(se) => se.skillId === skillId && se.level !== null
|
||||||
[categoryEvaluationId, skillId]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!isEvaluated) {
|
||||||
|
// Skill sélectionnée mais pas encore évaluée
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
INSERT INTO skill_evaluations
|
||||||
|
(user_evaluation_id, skill_id, level, is_selected, can_mentor, wants_to_learn)
|
||||||
|
VALUES ($1, $2, 'never'::skill_level_enum, true, false, false)
|
||||||
|
`,
|
||||||
|
[userEvaluationId, skillId]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insérer les évaluations de skills
|
// Insérer les évaluations de skills
|
||||||
@@ -151,11 +148,11 @@ export class EvaluationService {
|
|||||||
await client.query(
|
await client.query(
|
||||||
`
|
`
|
||||||
INSERT INTO skill_evaluations
|
INSERT INTO skill_evaluations
|
||||||
(category_evaluation_id, skill_id, level, can_mentor, wants_to_learn)
|
(user_evaluation_id, skill_id, level, is_selected, can_mentor, wants_to_learn)
|
||||||
VALUES ($1, $2, $3, $4, $5)
|
VALUES ($1, $2, $3, true, $4, $5)
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
categoryEvaluationId,
|
userEvaluationId,
|
||||||
skillEval.skillId,
|
skillEval.skillId,
|
||||||
skillEval.level,
|
skillEval.level,
|
||||||
skillEval.canMentor || false,
|
skillEval.canMentor || false,
|
||||||
@@ -200,38 +197,58 @@ export class EvaluationService {
|
|||||||
const userData = userResult.rows[0];
|
const userData = userResult.rows[0];
|
||||||
const userEvaluationId = userData.user_evaluation_id;
|
const userEvaluationId = userData.user_evaluation_id;
|
||||||
|
|
||||||
// Charger les évaluations de catégories
|
// Charger directement les skills évaluées avec leurs catégories
|
||||||
const categoriesQuery = `
|
const skillsQuery = `
|
||||||
SELECT ce.*,
|
SELECT
|
||||||
array_agg(DISTINCT ss.skill_id) FILTER (WHERE ss.skill_id IS NOT NULL) as selected_skill_ids,
|
sc.name as category_name,
|
||||||
array_agg(
|
se.skill_id,
|
||||||
json_build_object(
|
se.level,
|
||||||
'skillId', se.skill_id,
|
se.can_mentor,
|
||||||
'level', se.level,
|
se.wants_to_learn,
|
||||||
'canMentor', se.can_mentor,
|
se.is_selected
|
||||||
'wantsToLearn', se.wants_to_learn
|
FROM skill_evaluations se
|
||||||
)
|
JOIN skills s ON se.skill_id = s.id
|
||||||
) FILTER (WHERE se.skill_id IS NOT NULL) as skill_evaluations
|
JOIN skill_categories sc ON s.category_id = sc.id
|
||||||
FROM category_evaluations ce
|
WHERE se.user_evaluation_id = $1
|
||||||
LEFT JOIN selected_skills ss ON ce.id = ss.category_evaluation_id
|
ORDER BY sc.name, s.name
|
||||||
LEFT JOIN skill_evaluations se ON ce.id = se.category_evaluation_id
|
|
||||||
WHERE ce.user_evaluation_id = $1
|
|
||||||
GROUP BY ce.id, ce.category
|
|
||||||
ORDER BY ce.category
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const categoriesResult = await client.query(categoriesQuery, [
|
const skillsResult = await client.query(skillsQuery, [userEvaluationId]);
|
||||||
userEvaluationId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const evaluations: CategoryEvaluation[] = categoriesResult.rows.map(
|
// Grouper par catégorie
|
||||||
(row) => ({
|
const categoriesMap = new Map<string, CategoryEvaluation>();
|
||||||
category: row.category,
|
|
||||||
selectedSkillIds: row.selected_skill_ids || [],
|
for (const row of skillsResult.rows) {
|
||||||
skills: (row.skill_evaluations || []).filter(
|
const categoryName = row.category_name;
|
||||||
(se: any) => se.skillId !== null
|
|
||||||
),
|
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 {
|
return {
|
||||||
@@ -253,60 +270,7 @@ export class EvaluationService {
|
|||||||
skillId: string,
|
skillId: string,
|
||||||
level: SkillLevel
|
level: SkillLevel
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const pool = getPool();
|
await this.upsertSkillEvaluation(profile, skillId, { level });
|
||||||
const client = await pool.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
await client.query("BEGIN");
|
|
||||||
|
|
||||||
const userId = await this.upsertUser(profile);
|
|
||||||
|
|
||||||
// Obtenir ou créer user_evaluation
|
|
||||||
const userEvalResult = await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO user_evaluations (user_id, last_updated)
|
|
||||||
VALUES ($1, CURRENT_TIMESTAMP)
|
|
||||||
ON CONFLICT (user_id)
|
|
||||||
DO UPDATE SET last_updated = CURRENT_TIMESTAMP
|
|
||||||
RETURNING id
|
|
||||||
`,
|
|
||||||
[userId]
|
|
||||||
);
|
|
||||||
|
|
||||||
const userEvaluationId = userEvalResult.rows[0].id;
|
|
||||||
|
|
||||||
// Obtenir ou créer category_evaluation
|
|
||||||
const catEvalResult = await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO category_evaluations (user_evaluation_id, category)
|
|
||||||
VALUES ($1, $2)
|
|
||||||
ON CONFLICT (user_evaluation_id, category)
|
|
||||||
DO UPDATE SET category = $2
|
|
||||||
RETURNING id
|
|
||||||
`,
|
|
||||||
[userEvaluationId, category]
|
|
||||||
);
|
|
||||||
|
|
||||||
const categoryEvaluationId = catEvalResult.rows[0].id;
|
|
||||||
|
|
||||||
// Upsert skill evaluation
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO skill_evaluations (category_evaluation_id, skill_id, level)
|
|
||||||
VALUES ($1, $2, $3)
|
|
||||||
ON CONFLICT (category_evaluation_id, skill_id)
|
|
||||||
DO UPDATE SET level = $3, updated_at = CURRENT_TIMESTAMP
|
|
||||||
`,
|
|
||||||
[categoryEvaluationId, skillId, level]
|
|
||||||
);
|
|
||||||
|
|
||||||
await client.query("COMMIT");
|
|
||||||
} catch (error) {
|
|
||||||
await client.query("ROLLBACK");
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
client.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,13 +282,7 @@ export class EvaluationService {
|
|||||||
skillId: string,
|
skillId: string,
|
||||||
canMentor: boolean
|
canMentor: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await this.updateSkillProperty(
|
await this.upsertSkillEvaluation(profile, skillId, { canMentor });
|
||||||
profile,
|
|
||||||
category,
|
|
||||||
skillId,
|
|
||||||
"can_mentor",
|
|
||||||
canMentor
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,24 +294,21 @@ export class EvaluationService {
|
|||||||
skillId: string,
|
skillId: string,
|
||||||
wantsToLearn: boolean
|
wantsToLearn: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await this.updateSkillProperty(
|
await this.upsertSkillEvaluation(profile, skillId, { wantsToLearn });
|
||||||
profile,
|
|
||||||
category,
|
|
||||||
skillId,
|
|
||||||
"wants_to_learn",
|
|
||||||
wantsToLearn
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Méthode utilitaire pour mettre à jour une propriété de skill
|
* Méthode utilitaire pour mettre à jour ou créer une évaluation de skill
|
||||||
*/
|
*/
|
||||||
private async updateSkillProperty(
|
private async upsertSkillEvaluation(
|
||||||
profile: UserProfile,
|
profile: UserProfile,
|
||||||
category: string,
|
|
||||||
skillId: string,
|
skillId: string,
|
||||||
property: "can_mentor" | "wants_to_learn",
|
updates: {
|
||||||
value: boolean
|
level?: SkillLevel;
|
||||||
|
canMentor?: boolean;
|
||||||
|
wantsToLearn?: boolean;
|
||||||
|
isSelected?: boolean;
|
||||||
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const pool = getPool();
|
const pool = getPool();
|
||||||
const client = await pool.connect();
|
const client = await pool.connect();
|
||||||
@@ -363,6 +318,7 @@ export class EvaluationService {
|
|||||||
|
|
||||||
const userId = await this.upsertUser(profile);
|
const userId = await this.upsertUser(profile);
|
||||||
|
|
||||||
|
// Upsert user_evaluation
|
||||||
const userEvalResult = await client.query(
|
const userEvalResult = await client.query(
|
||||||
`
|
`
|
||||||
INSERT INTO user_evaluations (user_id, last_updated)
|
INSERT INTO user_evaluations (user_id, last_updated)
|
||||||
@@ -376,27 +332,39 @@ export class EvaluationService {
|
|||||||
|
|
||||||
const userEvaluationId = userEvalResult.rows[0].id;
|
const userEvaluationId = userEvalResult.rows[0].id;
|
||||||
|
|
||||||
const catEvalResult = await client.query(
|
// Upsert skill evaluation avec valeurs par défaut
|
||||||
`
|
const query = `
|
||||||
INSERT INTO category_evaluations (user_evaluation_id, category)
|
INSERT INTO skill_evaluations (
|
||||||
VALUES ($1, $2)
|
user_evaluation_id,
|
||||||
ON CONFLICT (user_evaluation_id, category)
|
skill_id,
|
||||||
DO UPDATE SET category = $2
|
level,
|
||||||
RETURNING id
|
can_mentor,
|
||||||
`,
|
wants_to_learn,
|
||||||
[userEvaluationId, category]
|
is_selected
|
||||||
);
|
)
|
||||||
|
VALUES ($1, $2,
|
||||||
const categoryEvaluationId = catEvalResult.rows[0].id;
|
COALESCE($3::skill_level_enum, 'never'::skill_level_enum),
|
||||||
|
COALESCE($4, false),
|
||||||
// Update the specific property
|
COALESCE($5, false),
|
||||||
const updateQuery = `
|
COALESCE($6, true)
|
||||||
UPDATE skill_evaluations
|
)
|
||||||
SET ${property} = $3, updated_at = CURRENT_TIMESTAMP
|
ON CONFLICT (user_evaluation_id, skill_id)
|
||||||
WHERE category_evaluation_id = $1 AND skill_id = $2
|
DO UPDATE SET
|
||||||
|
level = CASE WHEN $3 IS NOT NULL THEN $3::skill_level_enum ELSE skill_evaluations.level END,
|
||||||
|
can_mentor = CASE WHEN $4 IS NOT NULL THEN $4 ELSE skill_evaluations.can_mentor END,
|
||||||
|
wants_to_learn = CASE WHEN $5 IS NOT NULL THEN $5 ELSE skill_evaluations.wants_to_learn END,
|
||||||
|
is_selected = CASE WHEN $6 IS NOT NULL THEN $6 ELSE skill_evaluations.is_selected END,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
`;
|
`;
|
||||||
|
|
||||||
await client.query(updateQuery, [categoryEvaluationId, skillId, value]);
|
await client.query(query, [
|
||||||
|
userEvaluationId,
|
||||||
|
skillId,
|
||||||
|
updates.level || null,
|
||||||
|
updates.canMentor !== undefined ? updates.canMentor : null,
|
||||||
|
updates.wantsToLearn !== undefined ? updates.wantsToLearn : null,
|
||||||
|
updates.isSelected !== undefined ? updates.isSelected : null,
|
||||||
|
]);
|
||||||
|
|
||||||
await client.query("COMMIT");
|
await client.query("COMMIT");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -415,57 +383,10 @@ export class EvaluationService {
|
|||||||
category: string,
|
category: string,
|
||||||
skillId: string
|
skillId: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const pool = getPool();
|
await this.upsertSkillEvaluation(profile, skillId, {
|
||||||
const client = await pool.connect();
|
isSelected: true,
|
||||||
|
level: "never" as SkillLevel, // Valeur par défaut pour une skill nouvellement sélectionnée
|
||||||
try {
|
});
|
||||||
await client.query("BEGIN");
|
|
||||||
|
|
||||||
const userId = await this.upsertUser(profile);
|
|
||||||
|
|
||||||
const userEvalResult = await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO user_evaluations (user_id, last_updated)
|
|
||||||
VALUES ($1, CURRENT_TIMESTAMP)
|
|
||||||
ON CONFLICT (user_id)
|
|
||||||
DO UPDATE SET last_updated = CURRENT_TIMESTAMP
|
|
||||||
RETURNING id
|
|
||||||
`,
|
|
||||||
[userId]
|
|
||||||
);
|
|
||||||
|
|
||||||
const userEvaluationId = userEvalResult.rows[0].id;
|
|
||||||
|
|
||||||
const catEvalResult = await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO category_evaluations (user_evaluation_id, category)
|
|
||||||
VALUES ($1, $2)
|
|
||||||
ON CONFLICT (user_evaluation_id, category)
|
|
||||||
DO UPDATE SET category = $2
|
|
||||||
RETURNING id
|
|
||||||
`,
|
|
||||||
[userEvaluationId, category]
|
|
||||||
);
|
|
||||||
|
|
||||||
const categoryEvaluationId = catEvalResult.rows[0].id;
|
|
||||||
|
|
||||||
// Ajouter à selected_skills
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO selected_skills (category_evaluation_id, skill_id)
|
|
||||||
VALUES ($1, $2)
|
|
||||||
ON CONFLICT DO NOTHING
|
|
||||||
`,
|
|
||||||
[categoryEvaluationId, skillId]
|
|
||||||
);
|
|
||||||
|
|
||||||
await client.query("COMMIT");
|
|
||||||
} catch (error) {
|
|
||||||
await client.query("ROLLBACK");
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
client.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -482,36 +403,18 @@ export class EvaluationService {
|
|||||||
try {
|
try {
|
||||||
await client.query("BEGIN");
|
await client.query("BEGIN");
|
||||||
|
|
||||||
// Trouver les IDs nécessaires
|
const userId = await this.upsertUser(profile);
|
||||||
const findQuery = `
|
|
||||||
SELECT ce.id as category_evaluation_id
|
// Supprimer directement la skill evaluation
|
||||||
FROM users u
|
const deleteQuery = `
|
||||||
JOIN user_evaluations ue ON u.id = ue.user_id
|
DELETE FROM skill_evaluations
|
||||||
JOIN category_evaluations ce ON ue.id = ce.user_evaluation_id
|
WHERE user_evaluation_id = (
|
||||||
WHERE u.first_name = $1 AND u.last_name = $2 AND u.team_id = $3 AND ce.category = $4
|
SELECT id FROM user_evaluations WHERE user_id = $1
|
||||||
|
)
|
||||||
|
AND skill_id = $2
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await client.query(findQuery, [
|
await client.query(deleteQuery, [userId, skillId]);
|
||||||
profile.firstName,
|
|
||||||
profile.lastName,
|
|
||||||
profile.teamId,
|
|
||||||
category,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (result.rows.length > 0) {
|
|
||||||
const categoryEvaluationId = result.rows[0].category_evaluation_id;
|
|
||||||
|
|
||||||
// Supprimer de selected_skills et skill_evaluations
|
|
||||||
await client.query(
|
|
||||||
"DELETE FROM selected_skills WHERE category_evaluation_id = $1 AND skill_id = $2",
|
|
||||||
[categoryEvaluationId, skillId]
|
|
||||||
);
|
|
||||||
|
|
||||||
await client.query(
|
|
||||||
"DELETE FROM skill_evaluations WHERE category_evaluation_id = $1 AND skill_id = $2",
|
|
||||||
[categoryEvaluationId, skillId]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await client.query("COMMIT");
|
await client.query("COMMIT");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user