Revue : pistes ecartees et source (local/OpenRouter) gardees, historisation pour rejeu, carte verbeuse du conseiller
This commit is contained in:
@@ -779,6 +779,36 @@ async function migrer(client) {
|
||||
// proprietaire. NULL pour les releves anterieurs dont le pack n'est pas sur.
|
||||
await client.query('ALTER TABLE cellule ADD COLUMN IF NOT EXISTS pack smallint');
|
||||
|
||||
// REVUE DE LA JOURNEE (08/10/2026) : constats calcules et pistes du
|
||||
// conseiller, gardes pour REJOUER le conseiller plus tard (regression) et
|
||||
// juger s'il merite un role actif. Les pistes ecartees le sont avec leur
|
||||
// motif ; `avis_proprietaire` recevra le verdict humain (utile / a cote).
|
||||
await client.query(`
|
||||
CREATE TABLE IF NOT EXISTS revue_constat (
|
||||
jour date NOT NULL,
|
||||
code text NOT NULL,
|
||||
gravite text,
|
||||
debut timestamptz,
|
||||
fin timestamptz,
|
||||
texte text,
|
||||
contexte text,
|
||||
chiffres jsonb,
|
||||
PRIMARY KEY (jour, code, debut)
|
||||
)`);
|
||||
await client.query(`
|
||||
CREATE TABLE IF NOT EXISTS revue_piste (
|
||||
jour date NOT NULL,
|
||||
code text NOT NULL,
|
||||
piste text NOT NULL,
|
||||
retenue boolean NOT NULL,
|
||||
motif text,
|
||||
modele text,
|
||||
source text,
|
||||
avis_proprietaire text,
|
||||
ts timestamptz DEFAULT now(),
|
||||
PRIMARY KEY (jour, code, piste)
|
||||
)`);
|
||||
|
||||
// Ce que le CONSEILLER a observe. Ses helpers sont ecrases toutes les
|
||||
// quinze minutes : sans cette table, un signalement grave emis a 3 h du
|
||||
// matin a disparu au reveil. C'est precisement la trace que le proprietaire
|
||||
@@ -1147,6 +1177,7 @@ async function dejaFait(client, genre, jour) {
|
||||
}
|
||||
async function revueDeLaJournee(sql, client, st) {
|
||||
if (!client) return 0;
|
||||
if (!revueHistoriquePubliee) await publierRevueHistorique(client);
|
||||
const { min, jour } = partsParis();
|
||||
if (min < REVUE_PUBLIEE || min > 10 * 60) return 0;
|
||||
const hc = (id) => (st.get(id)?.state || '').slice(0, 5);
|
||||
@@ -1166,9 +1197,36 @@ async function revueDeLaJournee(sql, client, st) {
|
||||
constats: r.constats.map((c) => ({ code: c.code, gravite: c.gravite, texte: c.texte, contexte: c.contexte })),
|
||||
texte: r.texte,
|
||||
});
|
||||
for (const c of r.constats) {
|
||||
await sql(`INSERT INTO revue_constat (jour, code, gravite, debut, fin, texte, contexte, chiffres)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT DO NOTHING`,
|
||||
[jour, c.code, c.gravite, new Date(c.debut), new Date(c.fin), c.texte, c.contexte, JSON.stringify(c.chiffres || {})]);
|
||||
}
|
||||
await journaliser(sql, 'revue', `Revue de la journee : ${aExaminer} point(s) a examiner`, { jour, texte: r.texte });
|
||||
await publierRevueHistorique(client);
|
||||
n++;
|
||||
}
|
||||
// Les pistes du conseiller (retenues ET ecartees) sont historisees des qu'il a
|
||||
// repondu, independamment du courriel.
|
||||
{
|
||||
const avis = st.get('sensor.evcs_advisor_revue');
|
||||
if (avis && avis.state === jour && !(await dejaFait(client, 'revue_pistes', jour))) {
|
||||
const at = avis.attributes || {};
|
||||
const lignes = [
|
||||
...(at.pistes || []).map((p) => ({ ...p, retenue: true, motif: null })),
|
||||
...(at.ecartees || []).map((p) => ({ ...p, retenue: false })),
|
||||
];
|
||||
for (const p of lignes) {
|
||||
await sql(`INSERT INTO revue_piste (jour, code, piste, retenue, motif, modele, source)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7) ON CONFLICT DO NOTHING`,
|
||||
[jour, p.code || '', p.piste || '', p.retenue, p.motif, at.modele || null, at.source || null]);
|
||||
}
|
||||
await journaliser(sql, 'revue_pistes', `Revue : ${(at.pistes || []).length} piste(s) du conseiller, ${(at.ecartees || []).length} ecartee(s)`,
|
||||
{ jour, source: at.source || null, modele: at.modele || null });
|
||||
await publierRevueHistorique(client);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if (min >= REVUE_COURRIEL && !(await dejaFait(client, 'revue_courriel', jour))) {
|
||||
const revue = st.get('sensor.evcs_revue_jour');
|
||||
const avis = st.get('sensor.evcs_advisor_revue');
|
||||
@@ -1176,6 +1234,7 @@ async function revueDeLaJournee(sql, client, st) {
|
||||
if (revue && revue.state === jour && (avisDuJour || min >= REVUE_COURRIEL_SANS_AVIS)) {
|
||||
const a = revue.attributes || {};
|
||||
const pistes = (avisDuJour?.pistes || []).map((p) => `- ${p.piste}`);
|
||||
const quiRepond = avisDuJour ? (avisDuJour.source_texte || '') : '';
|
||||
const texte = [
|
||||
`Revue de la journee (24 h jusqu'a la fin des heures creuses de ce matin)`,
|
||||
'',
|
||||
@@ -1183,17 +1242,41 @@ async function revueDeLaJournee(sql, client, st) {
|
||||
a.texte || '(aucun)',
|
||||
'',
|
||||
a.a_examiner > 0
|
||||
? (pistes.length ? ['PISTES DU CONSEILLER IA (avis a verifier, pas des faits) :', ...pistes].join('\n')
|
||||
? (pistes.length ? ['PISTES DU CONSEILLER IA (avis a verifier, pas des faits) :', ...pistes,
|
||||
`(${quiRepond}${avisDuJour.rejetees ? ` ${avisDuJour.rejetees} piste(s) ecartee(s).` : ''})`].join('\n')
|
||||
: `Pistes du conseiller IA : ${avisDuJour ? 'aucune' : 'pas de reponse ce matin'}.`)
|
||||
: '',
|
||||
].join('\n').trim();
|
||||
await envoyer(texte, `EVCS - revue de la journee${a.a_examiner > 0 ? ` (${a.a_examiner} point(s))` : ''}`);
|
||||
await journaliser(sql, 'revue_courriel', 'Revue de la journee envoyee par courriel', { jour, avis: !!avisDuJour });
|
||||
await publierRevueHistorique(client);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
// Historique des revues (7 derniers jours) pour la carte du conseiller :
|
||||
// combien de points par jour, et ce qu'il en a dit. Publie a chaque nouvelle
|
||||
// revue ou reponse, et au demarrage.
|
||||
let revueHistoriquePubliee = false;
|
||||
async function publierRevueHistorique(client) {
|
||||
const { rows: c } = await client.query(`SELECT to_char(jour,'YYYY-MM-DD') jour, code, gravite, texte
|
||||
FROM revue_constat WHERE jour > current_date - 7 ORDER BY jour DESC, debut`);
|
||||
const { rows: p } = await client.query(`SELECT to_char(jour,'YYYY-MM-DD') jour, code, piste, retenue, motif, source
|
||||
FROM revue_piste WHERE jour > current_date - 7 ORDER BY jour DESC, retenue DESC`);
|
||||
const jours = [...new Set(c.map((x) => x.jour))];
|
||||
await publierCapteur('sensor.evcs_revue_historique', jours.length, {
|
||||
friendly_name: 'Revues des 7 derniers jours',
|
||||
jours: jours.map((j) => ({
|
||||
jour: j,
|
||||
constats: c.filter((x) => x.jour === j).map(({ code, gravite, texte }) => ({ code, gravite, texte })),
|
||||
pistes: p.filter((x) => x.jour === j).map(({ code, piste, retenue, motif, source }) => ({ code, piste, retenue, motif, source })),
|
||||
})),
|
||||
});
|
||||
revueHistoriquePubliee = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function decalageParis(jour) {
|
||||
const d = new Date(`${jour}T12:00:00Z`);
|
||||
const h = Number(new Intl.DateTimeFormat('en-GB', { timeZone: 'Europe/Paris', hour: '2-digit', hour12: false }).format(d));
|
||||
|
||||
Reference in New Issue
Block a user