Transtypage des parametres : aucun UPDATE de session n'aboutissait

`operator is not unique: unknown * unknown`. node-postgres envoie ses
parametres SANS type ; multiplier deux d'entre eux ne permet pas a PostgreSQL
de choisir un operateur.

Et contrairement a ce que j'ai d'abord annonce, ce n'est pas l'ajout de la part
reseau qui a casse la ligne : les DEUX lignes en souffraient. La premiere
version du detecteur de session n'a jamais reussi un seul UPDATE — la session
enregistree a 02:56 affichait 0,000 kWh avec fin = debut, seul l'INSERT avait
abouti. Verifie en rejouant les trois formes contre la vraie base : l'ancienne
echoue, la nouvelle passe.

Lecon consignee dans le README : l'essai a blanc remplace l'envoi a la base par
un compteur, donc il valide la logique et JAMAIS le SQL. Une erreur de typage y
est invisible par construction. D'ou la regle — tout parametre entrant dans un
calcul porte son ::float8 — et l'obligation de lire le journal du conteneur
apres chaque deploiement du service.

Tableaux : 53/53 depuis que la colonne existe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
Tallagrand Thierry
2026-09-05 03:15:15 +02:00
parent c00a2107b3
commit 22927a2930
2 changed files with 34 additions and 2 deletions

View File

@@ -279,3 +279,26 @@ quel tableau de bord en crée une copie personnelle et modifiable.
Il ne **stocke** rien : il interroge les deux bases à la demande. Le perdre ne
perd aucune mesure. Il n'écrit rien non plus — sa connexion PostgreSQL utilise
le rôle `evcs_lecture`, en lecture seule.
### ⚠️ Ce que `--dry-run` ne peut pas vérifier
L'essai à blanc remplace l'envoi à la base par un compteur : il valide la
logique, jamais le SQL. Une erreur de typage passe donc inaperçue.
C'est arrivé le 05/09 : `energie_kwh + $3 * $4 / 3600000.0` échouait sur
`operator is not unique: unknown * unknown`, parce que node-postgres envoie ses
paramètres **sans type** et que PostgreSQL ne sait alors pas quel opérateur `*`
choisir. Aucun `UPDATE` de session n'a abouti pendant vingt minutes, et cela ne
s'est vu qu'au journal du conteneur.
**Règle : tout paramètre entrant dans un calcul porte son `::float8`.**
**Et après tout déploiement du service :**
```bash
sudo docker compose restart historisation
sudo docker compose logs --tail=5 historisation
```
Une ligne `cycle en echec` vaut arrêt immédiat. Une ligne
`mesures=… session=…` vaut confirmation.

View File

@@ -418,8 +418,17 @@ async function ecrireSession(sql, client, st) {
await sql(
`UPDATE session_charge SET
fin = $2,
energie_kwh = energie_kwh + $3 * $4 / 3600000.0,
energie_reseau_kwh = energie_reseau_kwh + $8 * $3 * $4 / 3600000.0,
-- Transtypages EXPLICITES, sur TOUS les parametres.
-- node-postgres envoie ses parametres sans type ; multiplier deux
-- d'entre eux fait echouer PostgreSQL sur « operator is not unique:
-- unknown * unknown ». Les DEUX lignes en souffraient — la premiere
-- version de ce code n'a jamais reussi un seul UPDATE, ce qui ne
-- s'est vu qu'au journal du conteneur : l'essai a blanc court-circuite
-- l'envoi a la base et ne peut donc rien valider de ce genre.
-- REGLE : tout parametre entrant dans un calcul porte son ::float8.
energie_kwh = energie_kwh + $3::float8 * $4::float8 / 3600000.0,
energie_reseau_kwh = energie_reseau_kwh
+ $8::float8 * $3::float8 * $4::float8 / 3600000.0,
p_max_w = GREATEST(coalesce(p_max_w, 0), $3),
courant_max_a = GREATEST(coalesce(courant_max_a, 0), coalesce($5, 0)),
consigne_max_a = GREATEST(coalesce(consigne_max_a, 0), coalesce($6, 0)),