fix(dashboard,worker): vérité produit P0 — dashboard+worker+VWB export
War-room clôture DGX 2026-06-18 (recadrage Dom : graphe/apprentissage/mémoire/dashboard = surface produit P0). Le dashboard et le statut worker affichaient des états faux ; corrige pour refléter la vérité du produit. - dashboard FAISS: distingue index brut / metadata HMAC invalide / runtime / absent (plus de faux "inactif") - dashboard process-mining: 503 explicite missing_dependency (plus de message trompeur) - dashboard /api/workflows + system/status: lecture DB VWB v3 canonique (total réel = 24, plus de 0) - worker /processing/status: véridique (lit _worker_health.json) + statut "idle/armé (lazy)" distinct de "dégradé (échec)" - VWB export: N steps -> N actions/edges (dernière action n'est plus perdue) - tests: dashboard routes, worker status truthfulness, export VWB Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1392,7 +1392,13 @@
|
||||
|
||||
// Status indicator
|
||||
const faissStatusEl = document.getElementById('faissStatus');
|
||||
if (faiss.error) {
|
||||
if (faiss.status === 'metadata_invalid') {
|
||||
faissStatusEl.textContent = '⚠️';
|
||||
faissStatusEl.title = 'Index brut présent, métadonnées invalides';
|
||||
} else if (faiss.status === 'metadata_missing') {
|
||||
faissStatusEl.textContent = '⚠️';
|
||||
faissStatusEl.title = 'Index brut présent, métadonnées absentes';
|
||||
} else if (faiss.error) {
|
||||
faissStatusEl.textContent = '❌';
|
||||
faissStatusEl.title = faiss.error;
|
||||
} else if (faiss.status === 'index_not_found') {
|
||||
@@ -1419,6 +1425,8 @@
|
||||
if (faiss.nlist) details.push(`nlist: ${faiss.nlist}`);
|
||||
if (faiss.nprobe) details.push(`nprobe: ${faiss.nprobe}`);
|
||||
if (faiss.metadata_count) details.push(`Métadonnées: ${faiss.metadata_count}`);
|
||||
if (faiss.metadata_status) details.push(`Metadata: ${faiss.metadata_status}`);
|
||||
if (faiss.metadata_error) details.push(`Metadata error: ${faiss.metadata_error}`);
|
||||
document.getElementById('faissDetails').textContent = details.length > 0 ?
|
||||
details.join(' • ') : (faiss.error || faiss.status || 'Aucune info disponible');
|
||||
|
||||
@@ -1434,6 +1442,12 @@
|
||||
if (faiss.status === 'index_not_found') {
|
||||
recommendations.push('📝 Traitez des sessions pour créer l\'index FAISS');
|
||||
}
|
||||
if (faiss.status === 'metadata_invalid') {
|
||||
recommendations.push('⚠️ Index brut présent mais métadonnées invalides : re-signer ou régénérer les métadonnées FAISS');
|
||||
}
|
||||
if (faiss.status === 'metadata_missing') {
|
||||
recommendations.push('⚠️ Index brut présent sans métadonnées : reconstruire les métadonnées FAISS');
|
||||
}
|
||||
if (recommendations.length > 0) {
|
||||
recoEl.innerHTML = recommendations.join('<br>');
|
||||
recoEl.style.display = 'block';
|
||||
@@ -2818,10 +2832,29 @@
|
||||
const detailsEl = document.getElementById('streamServerDetails');
|
||||
|
||||
try {
|
||||
const data = await fetchJSON(`${STREAMING_BASE}/stats`);
|
||||
const [data, processing] = await Promise.all([
|
||||
fetchJSON(`${STREAMING_BASE}/stats`),
|
||||
fetchJSON(`${STREAMING_BASE}/processing/status`).catch(e => ({error: e.message}))
|
||||
]);
|
||||
|
||||
statusEl.innerHTML = '<span style="color:#22c55e;">✅</span>';
|
||||
statusEl.title = 'Serveur streaming en ligne';
|
||||
const processingReady = processing && processing.processing_ready === true;
|
||||
// « En veille » (armé/lazy) ≠ « dégradé » : un worker neuf sans
|
||||
// session a tous ses composants à false par design (chargement à la
|
||||
// 1re session), ce n'est PAS une panne. Seul status==='degraded'
|
||||
// (init tentée et en échec) est une vraie alerte.
|
||||
const processingArmed = processing && (processing.armed === true || processing.status === 'idle');
|
||||
const processingDegraded = processing && !processing.error && processing.status === 'degraded';
|
||||
const statusHint = (processing && processing.status_hint) || '';
|
||||
statusEl.innerHTML = processingDegraded
|
||||
? '<span style="color:#f59e0b;">⚠️</span>'
|
||||
: processingArmed
|
||||
? '<span style="color:#3b82f6;">⏸️</span>'
|
||||
: '<span style="color:#22c55e;">✅</span>';
|
||||
statusEl.title = processingDegraded
|
||||
? `Streaming en ligne, worker apprentissage dégradé${statusHint ? ' — ' + statusHint : ''}`
|
||||
: processingArmed
|
||||
? `Streaming en ligne, worker en veille${statusHint ? ' — ' + statusHint : ''}`
|
||||
: 'Serveur streaming en ligne';
|
||||
|
||||
document.getElementById('streamActiveSessions').textContent = data.active_sessions || 0;
|
||||
document.getElementById('streamTotalEvents').textContent = data.total_events || 0;
|
||||
@@ -2837,6 +2870,31 @@
|
||||
if (data.events_per_second !== undefined) rows.push({label: 'Événements/sec', value: (data.events_per_second || 0).toFixed(2)});
|
||||
if (data.memory_usage_mb !== undefined) rows.push({label: 'Mémoire utilisée', value: Math.round(data.memory_usage_mb) + ' MB'});
|
||||
if (data.server_version) rows.push({label: 'Version serveur', value: data.server_version});
|
||||
if (processing && !processing.error) {
|
||||
const status = processing.status || 'unknown';
|
||||
const workerIcon = processingReady ? '✅' : (processingArmed ? '⏸️' : '⚠️');
|
||||
rows.push({
|
||||
label: 'Worker apprentissage',
|
||||
value: `${workerIcon} ${status}`
|
||||
});
|
||||
rows.push({
|
||||
label: 'Composants intelligence',
|
||||
value: processing.components_ready
|
||||
? 'prêts'
|
||||
: (processingArmed ? 'en veille (chargés à la 1re session)' : 'non prêts')
|
||||
});
|
||||
if (statusHint) {
|
||||
rows.push({label: 'Détail worker', value: statusHint});
|
||||
}
|
||||
if (processing.queue_length !== undefined) {
|
||||
rows.push({label: 'Queue apprentissage', value: processing.queue_length});
|
||||
}
|
||||
if (processing.last_cycle) {
|
||||
rows.push({label: 'Dernier cycle worker', value: new Date(processing.last_cycle).toLocaleString('fr-FR')});
|
||||
}
|
||||
} else if (processing && processing.error) {
|
||||
rows.push({label: 'Worker apprentissage', value: `❌ ${processing.error}`});
|
||||
}
|
||||
|
||||
if (rows.length === 0) {
|
||||
// Afficher les données brutes si les clés attendues ne sont pas présentes
|
||||
|
||||
Reference in New Issue
Block a user