Planificateur « Suggérer » : 4 stratégies (smart / meilleurs d'abord / équilibré / juste ce qu'il faut), compétences+niveaux par tech (édition inline), niveau requis par compétence + par job, carte des tournées (1 couleur/tech, domicile→arrêts, sélecteur de jour), fenêtre de dispatch auj.+demain (dates sélectionnées), règle week-end + placeholder « en attente du quart », clustering + lasso + filtre-date sur la carte, accès rapide « À assigner » (badge). Boîte : liste /conversations allégée (45 Mo → ~1 Mo, 17×) + messages chargés à l'ouverture. Rapports : cache SWR sur revenue-explorer (22×). Session : keep-alive + timeout fetch global + authFetch durci → fin des rechargements manuels. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
42 lines
2.3 KiB
JavaScript
42 lines
2.3 KiB
JavaScript
'use strict'
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Politiques SLA ÉDITABLES (par FILE + PRIORITÉ) — cibles de réponse/résolution en
|
|
// MINUTES. Modifiables depuis Ops > Paramètres. Le CALCUL (échéances, dépassement,
|
|
// à-risque) se fait côté Ops (composable useSla) à partir de ces politiques + la
|
|
// date d'ouverture / 1ʳᵉ réponse du ticket. Ici on ne fait que stocker/servir la config.
|
|
// GET /sla/policies → { policies, defaults }
|
|
// PUT /sla/policies { policies } → remplace (état complet)
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
const { json, parseBody, readJsonFile, writeJsonFile } = require('./helpers')
|
|
|
|
const FILE = '/app/data/sla_policies.json'
|
|
|
|
// Cibles de départ raisonnables (MINUTES). Clé = file (issue_type) → priorité → { response, resolution }.
|
|
// `_default` = repli pour toute file sans politique propre. Modifiables dans Settings.
|
|
const DEFAULTS = {
|
|
_default: {
|
|
Urgent: { response: 30, resolution: 240 }, // 30 min / 4 h
|
|
High: { response: 60, resolution: 480 }, // 1 h / 8 h
|
|
Medium: { response: 240, resolution: 1440 }, // 4 h / 1 j
|
|
Low: { response: 480, resolution: 2880 }, // 8 h / 2 j
|
|
},
|
|
}
|
|
|
|
async function handle (req, res, method, path) {
|
|
if (path !== '/sla/policies') return json(res, 404, { error: 'not found' })
|
|
if (method === 'GET') {
|
|
const p = readJsonFile(FILE, null)
|
|
return json(res, 200, { policies: (p && typeof p === 'object') ? p : DEFAULTS, defaults: DEFAULTS })
|
|
}
|
|
if (method === 'PUT') {
|
|
const b = await parseBody(req)
|
|
const pol = (b && b.policies && typeof b.policies === 'object' && !Array.isArray(b.policies)) ? b.policies : null
|
|
if (!pol) return json(res, 400, { error: 'policies requis (objet file→priorité→{response,resolution})' })
|
|
writeJsonFile(FILE, pol)
|
|
return json(res, 200, { ok: true, policies: pol })
|
|
}
|
|
return json(res, 405, { error: 'method not allowed' })
|
|
}
|
|
|
|
module.exports = { handle, DEFAULTS }
|