concierge: lire airtria_ro depuis l'env/.env + alerte d'echec d'auth
Le mot de passe airtria_ro est desormais lu depuis AIRTRIA_RO_PASSWORD (variable d'environnement, sinon .env monte dans le conteneur), plus depuis .pg-airtria : EVCS renouvelle ce mot de passe, un fichier fige faisait echouer l'auth EN SILENCE. readPgPassword LEVE (rattrapable) au lieu de process.exit ; mot de passe resolu paresseusement dans makeClient. Nouveau module concierge-health.js (meme patron que le moniteur LLM) : battement de coeur horodate a CHAQUE cycle detect, statut live dans HA, et alerte WhatsApp UNIQUEMENT sur transition ok<->erreur (dedup, pas de rappel periodique). Chemin HA independant de PostgreSQL : l'alerte auth KO part meme quand c'est l'auth qui tombe. Best-effort : si les helpers HA manquent, le concierge n'echoue pas. - concierge-health.test.js : machine a etats (dedup + transitions) verifiee, sans reseau - concierge-health-ha-package.yaml.draft : helpers HA (a integrer cote proprietaire) - SPEC : source du secret corrigee + section supervision Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RZsbhyGmRwZogdoBwT6C6y
This commit is contained in:
@@ -17,6 +17,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { makeClient } = require('./concierge-detection.js');
|
||||
const { publishLabel } = require('./concierge-write.js');
|
||||
const health = require('./concierge-health.js');
|
||||
|
||||
const STATE = path.join(__dirname, 'concierge-state.json');
|
||||
const PENDING = path.join(__dirname, 'concierge-pending.json');
|
||||
@@ -91,7 +92,8 @@ async function loadWindow() {
|
||||
const hhmm = (epoch) => new Date(epoch * 1000)
|
||||
.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Paris' });
|
||||
|
||||
async function detect() {
|
||||
// Détection pure : PEUT LEVER (erreur PG/auth via loadWindow). Renvoie la question ou ''.
|
||||
async function runDetection() {
|
||||
const { plugins, selChanges } = await loadWindow();
|
||||
if (plugins.length === 0) return '';
|
||||
const latest = plugins[plugins.length - 1];
|
||||
@@ -112,6 +114,19 @@ async function detect() {
|
||||
`(VW / JEEP / invité) [${ref}]`;
|
||||
}
|
||||
|
||||
// Cycle detect : publie la santé À CHAQUE passage (battement de cœur HA) et n'alerte que
|
||||
// sur transition. Une panne d'auth PostgreSQL n'est donc PLUS silencieuse — elle devient un
|
||||
// statut HA + un WhatsApp unique. Sur reprise, le « de nouveau opérationnel » précède
|
||||
// l'éventuelle question véhicule (le branchement en attente n'est pas perdu).
|
||||
async function detect() {
|
||||
let question = '', ok = true, detail = null;
|
||||
try { question = await runDetection(); }
|
||||
catch (e) { ok = false; detail = e.message; }
|
||||
const transition = await health.publish({ ok, detail });
|
||||
if (ok) return [transition, question].filter(Boolean).join('\n\n');
|
||||
return transition; // échec : WhatsApp seulement à la bascule vers panne
|
||||
}
|
||||
|
||||
// Labels en MAJUSCULES sans accent (convention colonne : VW/JEEP/MEGANE). Le propriétaire
|
||||
// peut nommer l'invité (MEGANE) ; sinon INVITE. ZERO accepté (moto, si option ajoutée).
|
||||
function parseLabel(text, options) {
|
||||
|
||||
Reference in New Issue
Block a user