Gestion-des-Marches-RLA/routes/matrice-risque.js

91 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* GET /api/matrice-risque
* Matrice de risque : probabilité × impact (délai × avancement)
*/
const express = require('express');
const router = express.Router();
const { getMarches } = require('../services/baserow');
const {
isCloture, normalizeMarche,
getDelaiRestant, niveauAlerte, niveauRisque,
parseNum, SEUIL_STANDARD, SEUIL_CRITIQUE_PCT,
DELAI_CRITIQUE, DELAI_ATTENTION,
} = require('../services/calc');
/**
* Score délai : 1 (ok) → 3 (critique)
*/
function scoreDelai(delai) {
if (delai === null) return 1; // inconnu → faible
if (delai <= DELAI_CRITIQUE) return 3;
if (delai <= DELAI_ATTENTION) return 2;
return 1;
}
/**
* Score avancement : 1 (ok) → 3 (dépassé)
*/
function scoreAvancement(tauxPhy) {
const t = parseNum(tauxPhy);
if (t >= SEUIL_CRITIQUE_PCT) return 3;
if (t >= SEUIL_STANDARD) return 2;
return 1;
}
router.get('/', async (req, res) => {
try {
const { region, entrepreneur, nature } = req.query;
const regionFilter = req.regionFilter;
let rows = await getMarches();
rows = rows.filter(r => !isCloture(r));
if (regionFilter) rows = rows.filter(r => r.region === regionFilter);
else if (region) rows = rows.filter(r => r.region === region);
if (entrepreneur) rows = rows.filter(r => String(r.entrepreneur || '').toLowerCase().includes(entrepreneur.toLowerCase()));
if (nature) rows = rows.filter(r => String(r.nature || '').toLowerCase().includes(nature.toLowerCase()));
// Matrice 3×3 : delai (1-3) × avancement (1-3)
const matrice = {};
for (let d = 1; d <= 3; d++) {
for (let a = 1; a <= 3; a++) {
matrice[`${d}_${a}`] = { score_delai: d, score_avancement: a, items: [] };
}
}
const items = rows.map(r => {
const delai = getDelaiRestant(r);
const sd = scoreDelai(delai);
const sa = scoreAvancement(r.taux_phy ?? r.avt_phy);
const risque = niveauRisque(r);
const m = normalizeMarche(r);
return { ...m, score_delai: sd, score_avancement: sa, niveau_risque: risque };
});
// Remplissage matrice
for (const item of items) {
const key = `${item.score_delai}_${item.score_avancement}`;
if (matrice[key]) matrice[key].items.push(item);
}
// Comptage par niveau de risque
const parNiveau = { critique: 0, élevé: 0, moyen: 0, faible: 0 };
for (const item of items) {
const n = item.niveau_risque;
if (parNiveau[n] !== undefined) parNiveau[n]++;
else parNiveau[n] = 1;
}
res.json({
total: items.length,
par_niveau: parNiveau,
matrice, // grille 3×3
items, // liste complète triée par risque décroissant
});
} catch (err) {
res.status(502).json({ error: 'Erreur Baserow', detail: err.message });
}
});
module.exports = router;