dashboard : les ecrans de surveillance se rafraichissent seuls (#196) #209

Merged
olivier merged 3 commits from marvin/196-rafraichissement-tableau-de-bord into develop 2026-09-08 14:48:12 +00:00
Member

Ce que la PR fait

Les ecrans de surveillance du tableau de bord ne se rafraichissaient jamais
seuls : ils chargeaient a l'ouverture et rien ne repartait. Un ecran laisse
ouvert affichait un etat perime sans le dire — et d'abord sur l'heure, puisque
derniere_releve porte l'heure reelle depuis le #179 : sur un ecran ouvert
depuis une heure, elle donnait a croire que la collecte s'etait arretee.

Le battement

surRafraichissement(recharger) rejoue les appels de l'ecran toutes les
minutes
, et une fois de plus au retour de l'onglet au premier plan. Rien ne
part quand l'onglet est en arriere-plan (document.visibilityState) : sept
sites n'interrogent pas l'API toute la nuit pour un ecran que personne ne
regarde. La minuterie suit le cycle de vie de la vue.

Rejouer sans vider

Parc, Site, Qualite et Alertes gagnent un rafraichir() : un bloc deja rempli
ne repasse pas par « chargement », et s'il echoue il garde sa derniere valeur.
EtatRafraichissement, sous le titre, dit l'heure du dernier cycle reussi, ou
« Actualisation impossible — donnees de 14:03 » quand le dernier a echoue.

Periode ecrite une seule fois

Les profondeurs d'affichage (24 h / 7 j / 30 j), recopiees dans GraphiquesView
et ComparaisonView, passent dans src/periodes.js.

Verification

  • npm run test:unit : 438 tests, tous verts (dont 14 propres au rafraichissement).
  • npm run build : ok.

Hors perimetre (le ticket le pose)

  • L'ecran Comparer : sept ou trente jours de journees closes, rien qui bouge a la minute.
  • Le temps reel pousse par le serveur (websocket / SSE).

Base

Empilee sur marvin/184-refonte-tableau-de-bord (PR #207), dont elle depend
(elle retouche les vues et les depots que #184 refond). A recibler sur develop
une fois #207 fusionnee.

## Ce que la PR fait Les ecrans de surveillance du tableau de bord ne se rafraichissaient jamais seuls : ils chargeaient a l'ouverture et rien ne repartait. Un ecran laisse ouvert affichait un etat perime sans le dire — et d'abord sur l'heure, puisque `derniere_releve` porte l'heure reelle depuis le #179 : sur un ecran ouvert depuis une heure, elle donnait a croire que la collecte s'etait arretee. ### Le battement `surRafraichissement(recharger)` rejoue les appels de l'ecran **toutes les minutes**, et une fois de plus au retour de l'onglet au premier plan. Rien ne part quand l'onglet est en arriere-plan (`document.visibilityState`) : sept sites n'interrogent pas l'API toute la nuit pour un ecran que personne ne regarde. La minuterie suit le cycle de vie de la vue. ### Rejouer sans vider Parc, Site, Qualite et Alertes gagnent un `rafraichir()` : un bloc deja rempli ne repasse pas par « chargement », et s'il echoue il garde sa derniere valeur. `EtatRafraichissement`, sous le titre, dit l'heure du dernier cycle reussi, ou « Actualisation impossible — donnees de 14:03 » quand le dernier a echoue. ### Periode ecrite une seule fois Les profondeurs d'affichage (24 h / 7 j / 30 j), recopiees dans `GraphiquesView` et `ComparaisonView`, passent dans `src/periodes.js`. ## Verification - `npm run test:unit` : 438 tests, tous verts (dont 14 propres au rafraichissement). - `npm run build` : ok. ## Hors perimetre (le ticket le pose) - L'ecran Comparer : sept ou trente jours de journees closes, rien qui bouge a la minute. - Le temps reel pousse par le serveur (websocket / SSE). ## Base Empilee sur `marvin/184-refonte-tableau-de-bord` (PR #207), dont elle depend (elle retouche les vues et les depots que #184 refond). A recibler sur `develop` une fois #207 fusionnee.
dashboard: les écrans de surveillance se rafraîchissent seuls (#196)
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 9s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 23s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 42s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m27s
a4f9655dc0
Les vues chargeaient sur `onMounted` et rien ne repartait : un écran
laissé ouvert affichait l'état de l'instant où on l'avait ouvert, sans
le dire — et d'abord sur l'heure, `derniere_releve` portant l'heure
réelle depuis le #179.

`surRafraichissement` rejoue les appels de l'écran toutes les minutes,
tant que l'onglet est au premier plan (`document.visibilityState`), et
une fois de plus dès qu'il y revient. Parc, Site, Qualité et Alertes
gagnent chacun un `rafraichir()` qui rejoue sans vider : un bloc déjà
rempli garde sa valeur si l'appel échoue, et `EtatRafraichissement`
dit l'heure du dernier cycle réussi, ou que la donnée a vieilli.

Les profondeurs d'affichage, recopiées dans deux vues, passent dans
`src/periodes.js` — une seule liste.

Hors périmètre (le ticket le pose) : l'écran Comparer, qui porte des
journées closes, et le temps réel poussé par le serveur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EL8Yw5fQMitWWyKR4FugX3
marvin requested review from olivier 2026-09-08 14:20:33 +00:00
marvin self-assigned this 2026-09-08 14:20:34 +00:00
marvin changed target branch from marvin/184-refonte-tableau-de-bord to develop 2026-09-08 14:20:55 +00:00
olivier left a comment

Relecture ciblée « bloquant seulement » (J-1)

J'ai regardé le commit propre à cette demande (a4f9655, 21 fichiers) et laissé de côté ce qui vient de la #207.

Aucun défaut critique dans le code du #196. Rien qui casse la construction, la chaîne ou la mise en production.

Ce que j'ai vérifié

  • CI verte sur a4f9655 : les quatre jobs de l'exécution 586 sont au vert, Python compris.
  • Rejoué en local sur un arbre neuf (npm ci, node 24.14) : npm run test:unit438 tests, 41 fichiers, tous verts ; npm run build avec VITE_API_BASE → ok.
  • La minuterie ne fuit pas. setInterval posé sur onMounted, retiré sur onUnmounted avec l'écouteur visibilitychange. Vue démonte l'ancienne vue avant de monter la nouvelle, donc pas deux battements simultanés en changeant d'écran.
  • Le mode doux ne peut pas vider un écran qui allait bien. Les quatre dépôts (graphique, qualite, site) gardent la valeur affichée quand le statut est déjà pret, et rendent false — le verdict remonte bien jusqu'à EtatRafraichissement.
  • Pas de martèlement de /auth. Un 401 sur une route de données appelle seulement signalerExpiration() : il ne déclenche aucun POST /auth/refresh. Le limiteur 429 du routeur d'authentification n'est donc pas exposé au battement à la minute.
  • Les jetons CSS existent (--ev-erreur-600, --ev-mention-taille, --ev-ink-500, --ev-espace-08 dans jetons.css).
  • Tout le diff reste sous services/dashboard/ : aucun impact chaîne, API, infra ou déploiement.

Le seul point bloquant, et il n'est pas dans le code

La base de la demande est develop, mais la branche porte encore les cinq commits de la #207. git log develop..marvin/196 en rend six : les cinq du #184 puis celui du #196. Fusionner cette demande telle quelle fait donc entrer la #207 dans develop en même temps, sans qu'elle ait été relue — ce que la description elle-même veut éviter (« À recibler sur develop une fois #207 fusionnée »).

Rien à corriger sur la branche : c'est un ordre de fusion, pas un correctif. #207 d'abord, cette demande ensuite. Une fois la #207 fusionnée, le diff de celle-ci retombe à ses 21 fichiers et elle part telle quelle.

Deux remarques non bloquantes, pour après la soutenance

  1. Statut coincé sur chargement derrière la modale de reprise. Si la session expire pendant le chargement initial (statut attente), le battement suivant passe le bloc à chargement puis, l'appel échouant en 401, _echec(..., doux) sort sans reposer attente : le bloc reste sur son squelette. C'est couvert par la modale de reprise, et la reconnexion recharge en mode non-doux, donc ça se répare tout seul — mais la garde doux && statut === 'pret' gagnerait à traiter attente comme un cas à part.
  2. estExpiration compte comme un succès dans les valeurs de retour doux : EtatRafraichissement affiche « Actualisé à HH:MM » alors que rien n'est revenu. Là encore invisible sous la modale, mais l'horodatage ment le temps qu'elle est là.

Rien de tout cela ne justifie de retenir la fusion.

## Relecture ciblée « bloquant seulement » (J-1) J'ai regardé le commit propre à cette demande (`a4f9655`, 21 fichiers) et laissé de côté ce qui vient de la #207. **Aucun défaut critique dans le code du #196.** Rien qui casse la construction, la chaîne ou la mise en production. ### Ce que j'ai vérifié - **CI verte sur `a4f9655`** : les quatre jobs de l'exécution 586 sont au vert, Python compris. - **Rejoué en local** sur un arbre neuf (`npm ci`, node 24.14) : `npm run test:unit` → **438 tests, 41 fichiers, tous verts** ; `npm run build` avec `VITE_API_BASE` → ok. - **La minuterie ne fuit pas.** `setInterval` posé sur `onMounted`, retiré sur `onUnmounted` avec l'écouteur `visibilitychange`. Vue démonte l'ancienne vue avant de monter la nouvelle, donc pas deux battements simultanés en changeant d'écran. - **Le mode `doux` ne peut pas vider un écran qui allait bien.** Les quatre dépôts (`graphique`, `qualite`, `site`) gardent la valeur affichée quand le statut est déjà `pret`, et rendent `false` — le verdict remonte bien jusqu'à `EtatRafraichissement`. - **Pas de martèlement de `/auth`.** Un 401 sur une route de données appelle seulement `signalerExpiration()` : il ne déclenche aucun `POST /auth/refresh`. Le limiteur 429 du routeur d'authentification n'est donc pas exposé au battement à la minute. - **Les jetons CSS existent** (`--ev-erreur-600`, `--ev-mention-taille`, `--ev-ink-500`, `--ev-espace-08` dans `jetons.css`). - **Tout le diff reste sous `services/dashboard/`** : aucun impact chaîne, API, infra ou déploiement. ### Le seul point bloquant, et il n'est pas dans le code **La base de la demande est `develop`, mais la branche porte encore les cinq commits de la #207.** `git log develop..marvin/196` en rend six : les cinq du #184 puis celui du #196. Fusionner cette demande telle quelle fait donc entrer la #207 dans `develop` en même temps, sans qu'elle ait été relue — ce que la description elle-même veut éviter (« À recibler sur `develop` une fois #207 fusionnée »). Rien à corriger sur la branche : c'est un ordre de fusion, pas un correctif. **#207 d'abord, cette demande ensuite.** Une fois la #207 fusionnée, le diff de celle-ci retombe à ses 21 fichiers et elle part telle quelle. ### Deux remarques non bloquantes, pour après la soutenance 1. **Statut coincé sur `chargement` derrière la modale de reprise.** Si la session expire pendant le chargement initial (statut `attente`), le battement suivant passe le bloc à `chargement` puis, l'appel échouant en 401, `_echec(..., doux)` sort sans reposer `attente` : le bloc reste sur son squelette. C'est couvert par la modale de reprise, et la reconnexion recharge en mode non-doux, donc ça se répare tout seul — mais la garde `doux && statut === 'pret'` gagnerait à traiter `attente` comme un cas à part. 2. **`estExpiration` compte comme un succès** dans les valeurs de retour `doux` : `EtatRafraichissement` affiche « Actualisé à HH:MM » alors que rien n'est revenu. Là encore invisible sous la modale, mais l'horodatage ment le temps qu'elle est là. Rien de tout cela ne justifie de retenir la fusion.
olivier approved these changes 2026-09-08 14:29:42 +00:00
Dismissed
olivier left a comment

Approuvé.

Portée de cette approbation : le commit a4f9655 seul — le rafraîchissement périodique, les 21 fichiers du #196. Les cinq commits du #184 que la branche porte encore relèvent de la #207 et sont relus là-bas ; je ne les couvre pas ici.

Le détail de la relecture est dans mon commentaire précédent. En bref : CI verte sur les quatre jobs, 438 tests unitaires rejoués en local sur un arbre neuf, construction ok, minuterie et écouteur visibilitychange retirés au démontage, mode doux incapable de vider un écran qui répond, et aucun appel supplémentaire vers /auth (donc le limiteur 429 n'est pas exposé au battement à la minute). Rien de bloquant.

À fusionner après la #207, sans quoi celle-ci entre dans develop par la bande.

Approuvé. **Portée de cette approbation : le commit `a4f9655` seul** — le rafraîchissement périodique, les 21 fichiers du #196. Les cinq commits du #184 que la branche porte encore relèvent de la #207 et sont relus là-bas ; je ne les couvre pas ici. Le détail de la relecture est dans mon commentaire précédent. En bref : CI verte sur les quatre jobs, 438 tests unitaires rejoués en local sur un arbre neuf, construction ok, minuterie et écouteur `visibilitychange` retirés au démontage, mode `doux` incapable de vider un écran qui répond, et aucun appel supplémentaire vers `/auth` (donc le limiteur 429 n'est pas exposé au battement à la minute). Rien de bloquant. **À fusionner après la #207**, sans quoi celle-ci entre dans `develop` par la bande.
Fusionne develop : la refonte du tableau de bord rencontre les correctifs #199, #179 et #37
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 10s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 41s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 20s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m55s
0b6628449f
La branche datait du 58f4c70 et develop avait quatre-vingt-dix commits
d'avance. Cinq fichiers du tableau de bord se sont croisés : le #184 les a
reformatés et renommés, develop y a ajouté du comportement. La règle tenue
partout est la même — aucun comportement présent sur develop ne disparaît,
la forme est celle de la refonte.

- `api/glossaire.js` : la table des méthodes est celle de develop, à quatre
  régimes. `measured` est la mesure et `none` le trou assumé depuis la
  migration 0010 ; la forme à trois entrées de la branche les confondait, et
  l'écran Qualité affichait « measured » en anglais. La branche n'y ajoute
  que `capitaliser`.

- `components/FicheSite.vue` : listes d'imports réunies, et les trois
  mentions du #199 et du #179 conservées — la dernière valeur connue à côté
  du tiret, l'état de la valeur reconstituée, « rien mesuré à cette minute ».
  La marge garde son `kW` conditionnel : « — kW » se lit comme zéro.

- `components/TableauSites.vue` : imports réunis. `libellePalier` ne sert
  nulle part dans ce fichier, il ne rentre pas.

- `components/GraphiqueSite.vue` : la structure de develop — un site sans
  prévision le dit, au lieu d'afficher « 0 kW » — avec le `formaterPct` du
  #184 à la place de `toFixed(1)`, qui rendait le point décimal anglais.

- `components/SyntheseParc.vue` : le bandeau du #184 accueille les trois
  cas de develop (écart servi, aucune prévision servie, prévision sans
  référence), l'unité conditionnelle de la prévision, et la mention de
  total partiel du #199, renommée `mesure__second--partiel` avec le reste
  du bandeau. Elle reste sous le total qu'elle qualifie : la disponibilité
  dit déjà « x/y mesurés », mais c'est le nombre de kilowatts qu'on risque
  de lire comme une baisse.

Vérifié sur l'arbre fusionné : `npm run test:unit` → 448 tests, 41 fichiers,
tous verts ; `npm run build` avec `VITE_API_BASE` → ok. Aucun fichier de test
de develop n'a été perdu.
olivier dismissed olivier's review 2026-09-08 14:38:19 +00:00
Reason:

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

Fusionne develop : la #207 est passée, la branche se réduit à ses 21 fichiers
Some checks failed
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 45s
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 7s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 17s
Intégration / Python — qualité, tests et dépendances (pull_request) Has been cancelled
77642ed021
La #207 fusionnée, `develop` porte désormais la refonte du #184 — et sa
propre résolution des conflits avec la zone or (de29d55), faite en parallèle
de la mienne du 0b66284. Là où les deux disent la même chose autrement, c'est
`develop` qui est repris mot pour mot : deux rédactions du même arbitrage ne
valent pas un conflit de plus au prochain tour.

- `api/glossaire.js`, `components/FicheSite.vue`, `components/SyntheseParc.vue` :
  identiques à `develop`, à la ligne près. Le #196 ne touche aucun de ces
  fichiers ; il n'avait pas à y laisser de trace.

- `stores/graphique.js` : le seul arbitrage réel. Le #184 fait porter à chaque
  entrée de série la fenêtre pour laquelle elle a été demandée (`_serieAJour`),
  le #196 ajoute le rafraîchissement doux. Les deux se composent :
  `_chargerSerie(siteId, { doux })` pose `fenetre: demandee` comme sur
  `develop`, et `garderAffiche` exige maintenant la fenêtre courante en plus du
  statut « pret ». Sans cette condition, un rafraîchissement en 24 h aurait
  gardé à l'écran une courbe 7 j — le défaut même que le #184 vient de
  corriger.

Vérifié sur l'arbre fusionné : `npm run test:unit` → 455 tests, 41 fichiers,
tous verts ; `npm run build` avec `VITE_API_BASE` → ok. Le diff avec `develop`
est exactement les 21 fichiers du #196, plus rien.
olivier approved these changes 2026-09-08 14:45:50 +00:00
olivier merged commit 7b8e914982 into develop 2026-09-08 14:48:12 +00:00
olivier deleted branch marvin/196-rafraichissement-tableau-de-bord 2026-09-08 14:48:12 +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!209
No description provided.