diff --git a/api/em-live-inject.js b/api/em-live-inject.js new file mode 100644 index 000000000..c272a4be5 --- /dev/null +++ b/api/em-live-inject.js @@ -0,0 +1,182 @@ +/* ═══ WEVAL Enterprise Management — Live KPI Injector ═══ + ENRICHIT sans écraser. Ajouté par session Opus 17avr. + Fetch /api/em-live-kpi.php et met à jour les KPIs visuels. +*/ +(function(){ + const API = '/api/em-live-kpi.php'; + + async function loadLiveKPI() { + try { + const r = await fetch(API, {signal: AbortSignal.timeout(12000)}); + const d = await r.json(); + + // 1. Mettre à jour les stat-cards existantes + const el = id => document.getElementById(id); + if (el('statPages')) el('statPages').textContent = d.assets?.html_pages || '–'; + if (el('statApis')) el('statApis').textContent = d.assets?.php_apis || '–'; + if (el('statWiki')) el('statWiki').textContent = d.assets?.wiki_entries || '–'; + if (el('statVault')) el('statVault').textContent = d.assets?.vault_doctrines || '–'; + if (el('statSvc')) el('statSvc').textContent = (d.services?.filter(s=>s.status==='UP').length || 0); + if (el('statIntents')) el('statIntents').textContent = '20+'; + if (el('statGrand')) el('statGrand').textContent = d.grand_total || '–'; + if (el('statHealth')) el('statHealth').textContent = (d.health?.pct || 0) + '%'; + + // 2. Injecter la section LIVE DASHBOARD si elle n'existe pas + if (!document.getElementById('liveKpiSection')) { + const section = document.createElement('div'); + section.id = 'liveKpiSection'; + section.className = 'section'; + section.innerHTML = buildLiveDashboard(d); + // Insérer après le hero-stats + const heroStats = document.querySelector('.hero-stats'); + if (heroStats && heroStats.parentNode) { + heroStats.parentNode.insertBefore(section, heroStats.nextSibling); + } + } else { + document.getElementById('liveKpiSection').innerHTML = buildLiveDashboard(d); + } + + console.log('[EM-LIVE] KPIs loaded in ' + d.elapsed_ms + 'ms'); + } catch(e) { + console.warn('[EM-LIVE] KPI fetch failed:', e); + } + } + + function buildLiveDashboard(d) { + const svc = (d.services||[]).map(s => + `${s.name}` + ).join(''); + + const providers = (d.sovereign?.providers||[]).map(p => + `${p}` + ).join(''); + + const countries = (d.ethica?.by_country||[]).map(c => + `
+ ${c.country==='DZ'?'🇩🇿':c.country==='MA'?'🇲🇦':c.country==='TN'?'🇹🇳':'🌍'} + ${c.country} + ${Number(c.t||0).toLocaleString()} HCPs + ${Number(c.e||0).toLocaleString()} emails +
` + ).join(''); + + const pmta = (d.pmta||[]).map(p => + `${p.name}` + ).join(''); + + const docker = (d.docker||[]).slice(0,10).map(c => + `
${c.name}${c.status.split(' ')[0]} ${c.status.split(' ')[1]||''}
` + ).join(''); + + return ` + +
📊 Live Infrastructure — temps réel LIVE
+
+ + +
+

🖥️ S204 — WEVIA + Ethica

+
${d.s204?.load || '?'}
+
Load avg · ${d.s204?.cpu_cores || 8} CPU · ${d.s204?.ram_total_mb || 0}MB RAM
+
RAM libre: ${d.s204?.ram_free_mb?.toLocaleString() || '?'}MB · Disk: ${d.s204?.disk_pct || '?'}
+
FPM: ${d.s204?.fpm_workers || '?'} workers · Docker: ${d.s204?.docker_containers || '?'}
+
+
+ + +
+

🖥️ S95 — WEVADS + Arsenal

+
${d.s95?.load || '?'}
+
Load avg · ${d.s95?.ram_total_mb?.toLocaleString() || '?'}MB RAM · Disk: ${d.s95?.disk_pct || '?'}
+
Status: ${d.s95?.status || '?'}
+
+
+ + +
+

🧠 Sovereign IA — ${d.sovereign?.cost || '0€'}

+
${d.sovereign?.active || 0}/${d.sovereign?.total || 0}
+
Providers actifs · Primary: ${d.sovereign?.primary || '?'}
+
${providers}
+
+ + +
+

💊 Ethica HCPs — Maghreb

+
${Number(d.ethica?.total_hcps||0).toLocaleString()}
+
${Number(d.ethica?.with_email||0).toLocaleString()} emails (${d.ethica?.pct_email||0}%) · ${Number(d.ethica?.with_phone||0).toLocaleString()} phones (${d.ethica?.pct_phone||0}%)
+
Gap email: ${Number(d.ethica?.gap_email||0).toLocaleString()}
+
${countries}
+
+ + +
+

⚡ Services Live

+
${svc}
+
PMTA ECS: ${pmta}
+
+ + +
+

🐳 Docker Containers

+ ${docker} +
+ +
+ +
+ +
+

🎙️ Whisper.cpp

+
Binary: ${d.whisper?.binary||'?'}
+
Model: ${d.whisper?.model||'?'}
+
+ + +
+

📦 Git

+
HEAD: ${d.git?.head?.substring(0,30) || '?'}
+
Status: ${d.git?.status||'?'}
+
+ + +
+

🧪 NonReg Playwright

+
${d.nonreg?.passed||0}/${d.nonreg?.total||0}
+
Score: ${d.nonreg?.score||'?'}
+
+
+ +
Dernière mise à jour: ${d.ts || '?'} · API: ${d.elapsed_ms||'?'}ms · Auto-refresh: 60s
+ `; + } + + // Load immédiat + refresh toutes les 60s + loadLiveKPI(); + setInterval(loadLiveKPI, 60000); +})(); diff --git a/weval-enterprise-management.html b/weval-enterprise-management.html index 20697e619..fd8e8d328 100644 --- a/weval-enterprise-management.html +++ b/weval-enterprise-management.html @@ -594,5 +594,65 @@ loadData(); // Refresh health every 60s setInterval(() => { checkHealth(); }, 60000); + + + diff --git a/weval-enterprise-management.html.gold.17avr b/weval-enterprise-management.html.gold.17avr new file mode 100644 index 000000000..fd8e8d328 --- /dev/null +++ b/weval-enterprise-management.html.gold.17avr @@ -0,0 +1,658 @@ + + + + + +WEVAL Enterprise Management — Hub Unifié + + + + +
+ + +
+

🏛️ WEVAL Enterprise Management

+
Hub unifié — toute notre architecture, accessible en un clic. Zero régression, enrichissement continu.
+
+
Screens
+
APIs REST
+
Wiki Entries
+
Vault Docs
+
Services
+
WEVIA Intents
+
GRAND TOTAL
+
%
Health
+
+
+ + + + +
+
⚡ Quick Actions 0
+
+
+ + +
+

🧠 WEVIA Master — Intents via Chat NL

+
Pilote toute la plateforme en langage naturel. Clique un intent pour l'exécuter, ou ouvre le chat.
+
+
+ + +
+
🧬 Services & Capabilities 0
+
+
+ + +
+ + +
+ + +
+
📚 Wiki Entries 0
+ +
+
+ + +
+
🔒 Vault Docs 0
+
+
+ + +
+ +💬 Chat WEVIA Master + + + + + + +