Mise en production : une valeur nulle ne devient plus un chiffre plausible #202

Merged
lenaic merged 4 commits from develop into main 2026-09-08 12:50:09 +00:00
Owner

Mise en production. Deux correctifs de la même famille : une valeur nulle ne doit jamais devenir un chiffre plausible à l'écran.

Ce que ça change en prod

#199, les nuls du tableau de bord. SQL_SITES portait and valeur_kw is not null : un site dont la minute courante est une panne remontait sa dernière minute valide, estampillée comme la relève du moment. Mesuré sur enervision_prod, trois heures, par site : environ quarante minutes nulles sur cent six, une trentaine de suspect, une vingtaine d'imputed. La panne était invisible sur le seul écran fait pour la voir, et cinq sites sur sept affichaient une valeur suspect sans que rien ne le dise.

Trois jointures latérales au lieu de deux. La dernière minute, nulle comprise, avec sa qualité et sa méthode. La dernière valeur non nulle, à côté et jamais à la place. L'écran affiche « — » puis, sous le tiret, « dernière connue 412 kW à 10:58 ».

#200, la couverture de la veille. count(moyenne_kw) et non count(*) : une ligne présente dont la moyenne est nulle n'est pas une couverture. Une veille partielle rend maintenant « pas de comparaison » plutôt qu'un écart entre deux parcs différents.

La synthèse du parc annonce « sur 5 sites mesurés sur 7 » quand le parc est incomplet. Sans ça, un total qui baisse parce qu'un capteur est tombé se lit comme une baisse de consommation.

Vérifications

Chaîne verte sur les deux demandes, front compris. ruff, mypy --strict, tests unitaires complets. Les chiffres cités viennent de requêtes passées à la main sur enervision_prod, pas d'une estimation. La couverture de la veille a été vérifiée sur 30 heures : pleine partout sauf à 08:00 aujourd'hui, l'épisode des 416 relevés critical.

Après le déploiement

Rien à jouer manuellement. Le déploiement recrée api et supervision.

Mise en production. Deux correctifs de la même famille : une valeur nulle ne doit jamais devenir un chiffre plausible à l'écran. ### Ce que ça change en prod **#199, les nuls du tableau de bord.** `SQL_SITES` portait `and valeur_kw is not null` : un site dont la minute courante est une panne remontait sa dernière minute valide, estampillée comme la relève du moment. Mesuré sur `enervision_prod`, trois heures, par site : environ quarante minutes nulles sur cent six, une trentaine de `suspect`, une vingtaine d'`imputed`. La panne était invisible sur le seul écran fait pour la voir, et cinq sites sur sept affichaient une valeur `suspect` sans que rien ne le dise. Trois jointures latérales au lieu de deux. La dernière minute, nulle comprise, avec sa qualité et sa méthode. La dernière valeur non nulle, à côté et jamais à la place. L'écran affiche « — » puis, sous le tiret, « dernière connue 412 kW à 10:58 ». **#200, la couverture de la veille.** `count(moyenne_kw)` et non `count(*)` : une ligne présente dont la moyenne est nulle n'est pas une couverture. Une veille partielle rend maintenant « pas de comparaison » plutôt qu'un écart entre deux parcs différents. **La synthèse du parc** annonce « sur 5 sites mesurés sur 7 » quand le parc est incomplet. Sans ça, un total qui baisse parce qu'un capteur est tombé se lit comme une baisse de consommation. ### Vérifications Chaîne verte sur les deux demandes, front compris. `ruff`, `mypy --strict`, tests unitaires complets. Les chiffres cités viennent de requêtes passées à la main sur `enervision_prod`, pas d'une estimation. La couverture de la veille a été vérifiée sur 30 heures : pleine partout sauf à 08:00 aujourd'hui, l'épisode des 416 relevés `critical`. ### Après le déploiement Rien à jouer manuellement. Le déploiement recrée `api` et `supervision`.
lenaic self-assigned this 2026-09-08 12:42:23 +00:00
api : l'écart à la veille exige la même couverture des deux côtés (#179)
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 22s
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 5m38s
0666526590
Le périmètre de la requête était bien restreint aux sites mesurés du jour,
mais rien ne vérifiait que la veille les portait tous. `moyenne_kw` vaut
`avg(...) filter (where indicateur_qualite <> 'critical')` dans la 0016 :
un site dont le seau de la veille est vide ou entièrement dégradé rend
`null`, `sum()` l'ignore, et six sites d'aujourd'hui se comparaient à trois
d'hier. Le même faux delta que le périmètre corrigeait, retourné — une
perte de couverture lue comme une baisse de consommation. Le 08/09 à 08 h
la source marquait 416 relevés sur 420 en `critical` (#112).

`count(moyenne_kw)` et non `count(*)` : une ligne présente dont la moyenne
est nulle n'est pas une couverture. La colonne était déjà sélectionnée et
jamais lue ; elle décide maintenant, et une veille partielle rend `None` —
l'écran dit « pas de comparaison » plutôt qu'un chiffre plausible et faux.

Le double de la veille répondait « sites: 7 » à une requête qui en demandait
six : il décrivait une base impossible, celle-là même dont la couverture
partielle passait inaperçue. Il suit maintenant ce qu'on lui demande.
Merge pull request 'L'écart à la veille exige la même couverture des deux côtés (#179)' (#200) from gabriel/179-couverture-veille into develop
All checks were successful
Intégration / Tableau de bord — dépendances, tests et construction (push) Successful in 41s
Intégration / Contrôles statiques du dépôt (push) Successful in 7s
Intégration / Workflows — lint et audit de sécurité (push) Successful in 19s
Intégration / Python — qualité, tests et dépendances (push) Successful in 5m54s
9863205e6e
api: le tableau de bord n'ecrase plus les valeurs nulles (#199)
All checks were successful
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 38s
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 18s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 6m0s
622d2ec4d6
La jointure laterale de SQL_SITES portait "and valeur_kw is not null". Un site
dont la minute courante est une panne remontait donc sa derniere minute valide,
estampillee comme la releve du moment : la panne devenait invisible sur le seul
ecran fait pour la voir.

Mesure sur enervision_prod, trois dernieres heures, par site : environ 40
minutes nulles sur 106, autant de lignes critical, une trentaine de suspect,
une vingtaine d'imputed. Il restait une vingtaine de minutes reellement propres
par site, et l'ecran n'en disait rien. L'API amont produit ces nuls expres,
pour simuler la panne d'un capteur.

Trois jointures au lieu de deux. La premiere prend la derniere minute, nulle
comprise, avec son indicateur_qualite et sa methode_imputation. La seconde
prend la derniere valeur non nulle et son heure. Les deux traversent jusqu'au
contrat et jamais l'une a la place de l'autre : l'ecran affiche un tiret, et
sous le tiret la derniere valeur connue avec son heure.

La synthese du parc continue d'exclure les sites muets, ce que le contrat dit
depuis toujours, mais elle annonce maintenant sur combien de sites elle porte
quand le parc est incomplet. Sans ca, un total qui baisse parce qu'un capteur
est tombe se lit comme une baisse de consommation.

C'est l'EF-04 : la valeur brute et la methode restent lisibles a cote. Elles
l'etaient de bronze a la zone or, et se perdaient au dernier metre.
Merge pull request 'api : le tableau de bord n'écrase plus les valeurs nulles' (#201) from lenaic/199-nuls-non-ecrases into develop
All checks were successful
Intégration / Contrôles statiques du dépôt (push) Successful in 8s
Intégration / Workflows — lint et audit de sécurité (push) Successful in 24s
Intégration / Tableau de bord — dépendances, tests et construction (push) Successful in 38s
Intégration / Python — qualité, tests et dépendances (push) Successful in 6m6s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 39s
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 18s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m50s
c28c282672
lenaic requested review from gabriel 2026-09-08 12:42:24 +00:00
gabriel approved these changes 2026-09-08 12:45:49 +00:00
lenaic merged commit 1e676d47e1 into main 2026-09-08 12:50:09 +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!202
No description provided.