dashboard : écran Qualité — disponibilité par site et part de points imputés (#24) #156

Merged
gabriel merged 3 commits from marvin/24-ecran-qualite into develop 2026-09-07 14:05:54 +00:00
Member

Le troisième écran du ticket #24, celui qui manquait :

  • Écran qualité : disponibilité par site, part de points imputés, journal de collecte, alertes.

Les deux dernières cases — journal et alertes — sont sur la PR #155, empilée derrière celle-ci.

Empilée sur marvin/24-ecran-site (PR #140), à fusionner après elle.

L'API était déjà servie

/v1/qualite/synthese, /v1/qualite/collecte et /v1/alertes existaient depuis le lot L4 de #94, et le front n'en appelait aucune. Cette branche ne touche pas à l'API.

Un point qui a son test dédié : sur /qualite/collecte, site_id est un paramètre de requête, pas un segment de chemin comme sur toutes les autres routes du module. L'écrire comme les autres donnait un 404 sans rien dire de plus.

L'écran

/qualite, avec son onglet dans l'en-tête, et deux blocs :

La synthèse — disponibilité moyenne face à sa cible, part de points reconstitués, sites sous la cible. La disponibilité prend une couleur de statut parce qu'elle a une cible publiée par l'API ; la part de points reconstitués reste en encre neutre, faute de cible à laquelle la comparer. Les sites sous la cible sont nommés, pas comptés — « 1 site sous la cible » obligerait à chercher lequel dans le tableau juste en dessous.

Le tableau par site — trié du pire au meilleur, et il le dit dans sa légende : un écran de qualité montre d'abord ce qui ne va pas, et sans cette mention la première ligne passerait pour le premier site du référentiel. « Sous la cible » se lit en toutes lettres à côté de la puce, jamais par la couleur seule. Le seuil vient de l'API, il n'est pas recalculé côté front.

Aucune route supplémentaire pour ce tableau : disponibilite_pct et imputation_pct sont déjà dans SiteOut.

Un défaut corrigé au passage, hors périmètre du bloc Qualité

Derrière la modale de reprise de session, la page se couvrait de messages rouges — « indicateurs du parc indisponibles », « impossible de charger les sites » — alors que rien n'était en panne : les appels avaient reçu un 401, la session avait expiré. Ces messages proposaient de réessayer ce qui ne pouvait pas revenir avant une reconnexion, et faisaient passer une déconnexion pour une avarie.

estExpiration classe l'échec dans api/erreur.js, et chaque dépôt s'en sert pour se taire plutôt que marquer une erreur.

Second défaut, plus discret : une reconnexion réussie refermait la modale sur cette page vidée, sans rien recharger — écran mort, sans autre issue qu'un rechargement à la main. surRepriseDeSession recharge l'écran courant quand l'expiration est levée et qu'une identité est revenue. La seconde condition écarte « Retourner à la connexion », qui lève l'expiration sans session derrière : recharger là relancerait un appel, donc un 401, sur une page qu'on quitte.

Un test du dépôt du parc prenait un 401 comme exemple de panne — il encodait le bug. Passé à 503, et la règle nouvelle a le sien.

Vérification

npm run test:unit    30 fichiers, 268 tests
npm run build        passe
npm audit            0 vulnérabilité

+61 tests sur cette branche. Le correctif de la modale a été vérifié par retour en arrière : avec l'ancien v-else rétabli, le test échoue ; avec le correctif, il passe.

Ce que cette branche ne fait pas

  • dashboard/autorisation.py rend les sept sites à tout utilisateur authentifié (ENF-02 attend une table qui n'existe dans aucune migration) : le critère « seuls les sites autorisés apparaissent » de #24 n'est pas tenu, et ne se corrige pas côté front.
  • Les captures d'écran demandées en preuve et l'audit axe-core supposent des données à l'écran, donc une API jointe à une base.
Le troisième écran du ticket #24, celui qui manquait : > - [x] Écran qualité : **disponibilité par site**, **part de points imputés**, journal de collecte, alertes. Les deux dernières cases — journal et alertes — sont sur la PR #155, empilée derrière celle-ci. Empilée sur `marvin/24-ecran-site` (PR #140), à fusionner après elle. ## L'API était déjà servie `/v1/qualite/synthese`, `/v1/qualite/collecte` et `/v1/alertes` existaient depuis le lot L4 de #94, et le front n'en appelait aucune. Cette branche ne touche pas à l'API. Un point qui a son test dédié : sur `/qualite/collecte`, `site_id` est un **paramètre de requête**, pas un segment de chemin comme sur toutes les autres routes du module. L'écrire comme les autres donnait un 404 sans rien dire de plus. ## L'écran `/qualite`, avec son onglet dans l'en-tête, et deux blocs : **La synthèse** — disponibilité moyenne face à sa cible, part de points reconstitués, sites sous la cible. La disponibilité prend une couleur de statut parce qu'elle a une cible publiée par l'API ; la part de points reconstitués reste en encre neutre, faute de cible à laquelle la comparer. Les sites sous la cible sont **nommés**, pas comptés — « 1 site sous la cible » obligerait à chercher lequel dans le tableau juste en dessous. **Le tableau par site** — trié du pire au meilleur, et il le dit dans sa légende : un écran de qualité montre d'abord ce qui ne va pas, et sans cette mention la première ligne passerait pour le premier site du référentiel. « Sous la cible » se lit en toutes lettres à côté de la puce, jamais par la couleur seule. Le seuil vient de l'API, il n'est pas recalculé côté front. Aucune route supplémentaire pour ce tableau : `disponibilite_pct` et `imputation_pct` sont déjà dans `SiteOut`. ## Un défaut corrigé au passage, hors périmètre du bloc Qualité Derrière la modale de reprise de session, la page se couvrait de messages rouges — « indicateurs du parc indisponibles », « impossible de charger les sites » — alors que rien n'était en panne : les appels avaient reçu un 401, la session avait expiré. Ces messages proposaient de réessayer ce qui ne pouvait pas revenir avant une reconnexion, et faisaient passer une déconnexion pour une avarie. `estExpiration` classe l'échec dans `api/erreur.js`, et chaque dépôt s'en sert pour **se taire** plutôt que marquer une erreur. Second défaut, plus discret : une reconnexion réussie refermait la modale sur cette page vidée, sans rien recharger — écran mort, sans autre issue qu'un rechargement à la main. `surRepriseDeSession` recharge l'écran courant quand l'expiration est levée **et** qu'une identité est revenue. La seconde condition écarte « Retourner à la connexion », qui lève l'expiration sans session derrière : recharger là relancerait un appel, donc un 401, sur une page qu'on quitte. Un test du dépôt du parc prenait un 401 comme exemple de panne — il encodait le bug. Passé à 503, et la règle nouvelle a le sien. ## Vérification ``` npm run test:unit 30 fichiers, 268 tests npm run build passe npm audit 0 vulnérabilité ``` **+61 tests** sur cette branche. Le correctif de la modale a été vérifié par retour en arrière : avec l'ancien `v-else` rétabli, le test échoue ; avec le correctif, il passe. ## Ce que cette branche ne fait pas - `dashboard/autorisation.py` rend les sept sites à tout utilisateur authentifié (ENF-02 attend une table qui n'existe dans aucune migration) : le critère « seuls les sites autorisés apparaissent » de #24 n'est pas tenu, et ne se corrige pas côté front. - Les captures d'écran demandées en preuve et l'audit `axe-core` supposent des données à l'écran, donc une API jointe à une base.
Trois routes que le front n'appelait pas encore, et que l'API sert déjà :
la synthèse qualité, le journal de collecte d'un site et les alertes.

« site_id » est un paramètre de requête sur /qualite/collecte, pas un
segment de chemin comme sur toutes les autres routes de ce module. Le
commentaire le dit et un test l'ancre : écrit comme les autres, l'appel
rendrait 404 sans que rien ne l'explique.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VAFDyP1qfZvdwy8V9Vuz68
Les deux tables vivaient dans TracabiliteDetail. L'écran Qualité ventile
les relevés par la même énumération : les y laisser aurait donné deux
traductions du même mot, qui divergent au premier ajout.

Deux registres, une seule table : « libelleMethode » pour une colonne de
tableau, « descriptionMethode » pour la fiche de traçabilité, où l'on veut
savoir ce qui a été fait à la valeur qu'on regarde (EF-04). Un test tient
les deux registres alignés sur les mêmes clés.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VAFDyP1qfZvdwy8V9Vuz68
Quatre blocs, quatre statuts indépendants, comme les dépôts du parc et du
site : un écran qui parle de la qualité de la donnée ne peut pas mentir
sur la sienne quand une source ne répond pas.

Le référentiel vient de /v1/sites, appelé pour son propre compte plutôt
que lu dans le dépôt du graphique — celui-là charge les sept séries de
mesures au passage, dont cet écran n'a aucun besoin. « disponibilite_pct »
et « imputation_pct » sont déjà dans SiteOut : aucune route de plus pour
la colonne par site.

Les journaux de collecte se chargent à la demande, un site à la fois. La
garde « déjà chargé » exclut explicitement les entrées en erreur : traiter
une erreur comme un journal laisserait la ligne en panne jusqu'au
rechargement de la page. Un test le tient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VAFDyP1qfZvdwy8V9Vuz68
Les deux blocs qui portent le critère « disponibilité par site, part de
points imputés » du ticket. Aucune route de plus : disponibilite_pct et
imputation_pct sont déjà dans SiteOut.

Le tableau trie du pire au meilleur — un écran de qualité montre d'abord
ce qui ne va pas — et le dit dans sa légende, sinon la première ligne
passe pour le premier site du référentiel.

« Sous la cible » se lit en toutes lettres à côté de la puce, jamais par
la couleur seule (RGAA, critère du ticket). Le seuil vient de l'API, il
n'est pas recalculé ici.

La disponibilité prend une couleur de statut parce qu'elle a une cible
publiée ; la part de points reconstitués reste en encre neutre, faute de
cible à laquelle la comparer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
La vue, la route « /qualite » et son onglet dans l'en-tête.

Deux onglets désormais, Parc et Qualité. L'écran Site n'en a pas : on y
entre par un site nommé, jamais dans l'absolu, et un onglet qui
demanderait « lequel » n'aurait rien à ouvrir.

Le journal de collecte et les alertes viennent ensuite. Les deux blocs
livrés couvrent déjà « disponibilité par site, part de points imputés »
du ticket, et un écran atteignable vaut mieux qu'un écran complet mais
invisible.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dashboard : une session expirée n'affiche plus une page en panne (#24)
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 4s
Intégration / Aucun secret commité (pull_request) Successful in 3s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 34s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 2m6s
bf3402e36d
Derrière la modale de reprise, la page se couvrait de messages rouges —
« indicateurs du parc indisponibles », « impossible de charger les
sites » — alors que rien n'était en panne : les appels avaient reçu un
401, la session avait expiré. Ces messages proposaient de réessayer ce
qui ne pouvait pas revenir avant une reconnexion, et faisaient passer une
déconnexion pour une avarie.

« estExpiration » classe l'échec dans api/erreur.js, et chaque dépôt s'en
sert pour se taire plutôt que marquer une erreur : le bloc repart à
« attente », les séries et journaux concernés sont retirés. La page ne
rend plus rien derrière la modale.

Second défaut, plus discret : une reconnexion réussie refermait la modale
sur cette page vidée, sans rien recharger — écran mort, sans autre issue
qu'un rechargement à la main. « surRepriseDeSession » recharge l'écran
courant quand l'expiration est levée ET qu'une identité est revenue. La
seconde condition écarte « Retourner à la connexion », qui lève
l'expiration sans session derrière : recharger là relancerait un appel,
donc un 401, sur une page qu'on quitte.

Un test du dépôt du parc prenait un 401 comme exemple de panne : il passe
à 503, et la règle nouvelle a le sien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
marvin changed title from dashboard : �cran Qualit� � disponibilit� par site et part de points imput�s (#24) to dashboard : écran Qualité — disponibilité par site et part de points imputés (#24) 2026-09-04 14:27:23 +00:00
marvin changed target branch from marvin/24-ecran-site to develop 2026-09-07 07:37:30 +00:00
marvin requested review from florian 2026-09-07 07:49:32 +00:00
gabriel requested reviews from gabriel and removed review requests for florian 2026-09-07 13:17:43 +00:00
- api/glossaire.js, TracabiliteDetail.vue : develop avait fait le même
  déplacement de METHODE/QUALITE en parallèle, avec une seule fonction
  libelleMethode (pas de libellé court séparé). On garde sa forme, plus
  simple et sans consommateur du libellé court dans cette branche.
- stores/graphique.js, GraphiquesView.vue(.test.js) : develop a ajouté
  afficherTousLesSites() et un message distinct par type de panne
  (référentiel en panne + Réessayer, parc vide, session expirée). On
  garde ces ajouts et on conserve le silence sur 401 de cette branche
  (chargerSites ne pose plus jamais erreurSites sur une session expirée),
  ce qui rend l'ancien message « Session expirée » de develop inatteignable
  derrière la modale de reprise — retiré avec son test.
- graphiqueUtils.js(.test.js) : formaterPct (cette branche) et
  graduationsY (develop) cohabitent, ajouts indépendants.
dashboard : Réessayer sur l'écran Qualité ne recharge que son propre bloc
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 8s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 25s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 38s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m17s
a9bb05c75f
chargerSynthese, chargerSites et chargerAlertes deviennent publics dans
stores/qualite.js (au lieu d'être privés et appelés seulement via
Promise.all dans charger()). Les boutons « Réessayer » de SyntheseQualite
et TableauQualite ciblent maintenant leur bloc, comme le fait déjà
SyntheseParc. Avant ce correctif, cliquer Réessayer sur un bloc en échec
rappelait store.charger() en entier et faisait clignoter les autres blocs
— déjà affichés avec leurs données — retour à leur état « Chargement… ».
gabriel approved these changes 2026-09-07 13:50:58 +00:00
Dismissed
Fusionne develop : résout les conflits de la #156
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 8s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 39s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 33s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m10s
04a66e1303
Les huit fichiers en conflit avaient déjà leur version à jour côté
develop (méthode de reconstitution scindée libellé/description,
formaterJour, gestion de session expirée dans le store graphique,
tests d'alertes/glossaire) — cette branche avait simplement pris du
retard. Résolu en gardant la version develop partout, sauf le test
GraphiquesView.test.js où les deux mêmes cas existaient en double
(ordre différent) : gardée une seule fois, dans l'ordre de develop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKNWNe8igWLfyV6f9Zfnx3
gabriel dismissed gabriel's review 2026-09-07 13:57:45 +00:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

gabriel merged commit 2e56aaf6b2 into develop 2026-09-07 14:05:54 +00:00
gabriel deleted branch marvin/24-ecran-qualite 2026-09-07 14:05:55 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
g2/enervision!156
No description provided.