refactor: rule of coverage are in one place
This commit is contained in:
@@ -2,6 +2,10 @@ import { getPool } from "./database";
|
||||
import { Team, SkillCategory } from "@/lib/types";
|
||||
import { TeamMember, TeamStats, DirectionStats } from "@/lib/admin-types";
|
||||
import { SkillsService } from "./skills-service";
|
||||
import {
|
||||
COVERAGE_OBJECTIVES,
|
||||
generateSkillCoverageSQL,
|
||||
} from "@/lib/evaluation-utils";
|
||||
|
||||
export class AdminService {
|
||||
/**
|
||||
@@ -9,8 +13,11 @@ export class AdminService {
|
||||
*/
|
||||
static async getTeamsStats(): Promise<TeamStats[]> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
await client.query("BEGIN");
|
||||
|
||||
// Récupérer toutes les équipes avec leurs membres et évaluations
|
||||
const query = `
|
||||
WITH team_members AS (
|
||||
@@ -56,14 +63,7 @@ export class AdminService {
|
||||
s.icon as skill_icon,
|
||||
s.importance,
|
||||
AVG(ss.level_numeric) as avg_level,
|
||||
COALESCE(
|
||||
SUM(CASE
|
||||
WHEN ss.level_numeric >= 2 THEN 100.0 -- autonomous ou expert
|
||||
WHEN ss.level_numeric = 1 THEN 50.0 -- not-autonomous
|
||||
ELSE 0.0 -- never
|
||||
END) / NULLIF(COUNT(*), 0),
|
||||
0
|
||||
) as coverage
|
||||
${generateSkillCoverageSQL("ss.level_numeric")} as coverage
|
||||
FROM skill_stats ss
|
||||
JOIN skills s ON ss.skill_id = s.id
|
||||
WHERE ss.skill_name IS NOT NULL
|
||||
@@ -73,11 +73,17 @@ export class AdminService {
|
||||
SELECT
|
||||
team_id,
|
||||
COALESCE(
|
||||
AVG(CASE WHEN importance = 'incontournable' THEN coverage ELSE NULL END),
|
||||
AVG(CASE
|
||||
WHEN importance = 'incontournable' THEN coverage
|
||||
ELSE NULL
|
||||
END),
|
||||
0
|
||||
) as incontournable_coverage,
|
||||
COALESCE(
|
||||
AVG(CASE WHEN importance = 'majeure' THEN coverage ELSE NULL END),
|
||||
AVG(CASE
|
||||
WHEN importance = 'majeure' THEN coverage
|
||||
ELSE NULL
|
||||
END),
|
||||
0
|
||||
) as majeure_coverage
|
||||
FROM team_skill_averages
|
||||
@@ -149,7 +155,8 @@ export class AdminService {
|
||||
ORDER BY tm.direction, tm.team_name
|
||||
`;
|
||||
|
||||
const result = await pool.query(query);
|
||||
const result = await client.query(query);
|
||||
await client.query("COMMIT");
|
||||
|
||||
return result.rows.map((row) => ({
|
||||
teamId: row.team_id,
|
||||
@@ -168,8 +175,11 @@ export class AdminService {
|
||||
),
|
||||
}));
|
||||
} catch (error) {
|
||||
await client.query("ROLLBACK");
|
||||
console.error("Error fetching teams stats:", error);
|
||||
throw new Error("Failed to fetch teams statistics");
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,10 +251,15 @@ export class AdminService {
|
||||
skills: any[];
|
||||
}> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
await client.query("BEGIN");
|
||||
|
||||
const [categoriesResult, skills] = await Promise.all([
|
||||
pool.query("SELECT id, name, icon FROM skill_categories ORDER BY name"),
|
||||
client.query(
|
||||
"SELECT id, name, icon FROM skill_categories ORDER BY name"
|
||||
),
|
||||
SkillsService.getAllSkillsWithUsage(),
|
||||
]);
|
||||
|
||||
@@ -254,13 +269,18 @@ export class AdminService {
|
||||
skills: [],
|
||||
}));
|
||||
|
||||
await client.query("COMMIT");
|
||||
|
||||
return {
|
||||
skillCategories,
|
||||
skills,
|
||||
};
|
||||
} catch (error) {
|
||||
await client.query("ROLLBACK");
|
||||
console.error("Error fetching skills page data:", error);
|
||||
throw new Error("Failed to fetch skills page data");
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,13 +328,16 @@ export class AdminService {
|
||||
users: any[];
|
||||
}> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
await client.query("BEGIN");
|
||||
|
||||
const [teamsResult, usersResult] = await Promise.all([
|
||||
pool.query(
|
||||
client.query(
|
||||
"SELECT id, name, direction FROM teams ORDER BY direction, name"
|
||||
),
|
||||
pool.query(`
|
||||
client.query(`
|
||||
SELECT
|
||||
u.uuid_id as uuid,
|
||||
u.first_name as "firstName",
|
||||
@@ -330,13 +353,18 @@ export class AdminService {
|
||||
`),
|
||||
]);
|
||||
|
||||
await client.query("COMMIT");
|
||||
|
||||
return {
|
||||
teams: teamsResult.rows,
|
||||
users: usersResult.rows,
|
||||
};
|
||||
} catch (error) {
|
||||
await client.query("ROLLBACK");
|
||||
console.error("Error fetching users page data:", error);
|
||||
throw new Error("Failed to fetch users page data");
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,10 +377,13 @@ export class AdminService {
|
||||
directionStats: DirectionStats[];
|
||||
}> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
await client.query("BEGIN");
|
||||
|
||||
const [teamsResult, teamStats] = await Promise.all([
|
||||
pool.query(
|
||||
client.query(
|
||||
"SELECT id, name, direction FROM teams ORDER BY direction, name"
|
||||
),
|
||||
AdminService.getTeamsStats(),
|
||||
@@ -360,14 +391,19 @@ export class AdminService {
|
||||
|
||||
const directionStats = AdminService.generateDirectionStats(teamStats);
|
||||
|
||||
await client.query("COMMIT");
|
||||
|
||||
return {
|
||||
teams: teamsResult.rows,
|
||||
teamStats,
|
||||
directionStats,
|
||||
};
|
||||
} catch (error) {
|
||||
await client.query("ROLLBACK");
|
||||
console.error("Error fetching teams page data:", error);
|
||||
throw new Error("Failed to fetch teams page data");
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,13 +417,18 @@ export class AdminService {
|
||||
directionStats: DirectionStats[];
|
||||
}> {
|
||||
const pool = getPool();
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
await client.query("BEGIN");
|
||||
|
||||
const [teamsResult, categoriesResult, teamStats] = await Promise.all([
|
||||
pool.query(
|
||||
client.query(
|
||||
"SELECT id, name, direction FROM teams ORDER BY direction, name"
|
||||
),
|
||||
pool.query("SELECT id, name, icon FROM skill_categories ORDER BY name"),
|
||||
client.query(
|
||||
"SELECT id, name, icon FROM skill_categories ORDER BY name"
|
||||
),
|
||||
AdminService.getTeamsStats(),
|
||||
]);
|
||||
|
||||
@@ -400,6 +441,8 @@ export class AdminService {
|
||||
|
||||
const directionStats = AdminService.generateDirectionStats(teamStats);
|
||||
|
||||
await client.query("COMMIT");
|
||||
|
||||
return {
|
||||
teams,
|
||||
skillCategories,
|
||||
@@ -407,8 +450,11 @@ export class AdminService {
|
||||
directionStats,
|
||||
};
|
||||
} catch (error) {
|
||||
await client.query("ROLLBACK");
|
||||
console.error("Error fetching overview page data:", error);
|
||||
throw new Error("Failed to fetch overview page data");
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user