/** * 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;