Files
html/l99.html
2026-04-18 12:20:02 +02:00

224 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL L99 Command Center</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:#0a0e1a;color:#e2e8f0;min-height:100vh}
.w{max-width:1400px;margin:0 auto;padding:16px}.hdr{background:linear-gradient(135deg,#6d28d9,#4338ca);border-radius:16px;padding:24px;margin-bottom:16px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px}
.hdr h1{font-size:20px;font-weight:800}.hdr .s{font-size:11px;opacity:0.7}
.btn{padding:10px 22px;border-radius:8px;border:2px solid rgba(255,255,255,.3);background:rgba(255,255,255,.12);color:#fff;font-size:12px;font-weight:700;cursor:pointer;font-family:inherit}
.metrics{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px}.m{background:#111827;border:1px solid #1e293b;border-radius:10px;padding:12px 16px;text-align:center;flex:1;min-width:90px}
.m .v{font-size:24px;font-weight:800}.m .l{font-size:9px;color:#64748b;margin-top:2px}.g{color:#10b981}.r{color:#ef4444}.y{color:#f59e0b}.b{color:#3b82f6}.p{color:#8b5cf6}
.tabs{display:flex;gap:6px;margin-bottom:16px;flex-wrap:wrap}.tab{padding:7px 16px;border-radius:8px;border:none;cursor:pointer;font-size:11px;font-weight:600;font-family:inherit;background:#1e293b;color:#64748b}.tab.a{background:#8b5cf6;color:#fff}
.card{background:#111827;border:1px solid #1e293b;border-radius:12px;padding:16px;margin-bottom:12px}.card h3{font-size:13px;margin-bottom:10px;color:#a5b4fc}
table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:5px 10px;border-bottom:1px solid #1e293b;font-size:11px}th{color:#64748b}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:12px}.grid3{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}
.vc{background:#111827;border:1px solid #1e293b;border-radius:12px;overflow:hidden}.vc h4{font-size:12px;color:#a5b4fc;padding:10px 12px 6px}.vc video{width:100%;display:block;background:#000}.vc .info{padding:6px 12px 10px;font-size:10px;color:#64748b}
.sc{background:#111827;border:1px solid #1e293b;border-radius:10px;overflow:hidden;cursor:pointer}.sc img{width:100%;display:block;background:#0a0e1a;min-height:60px}.sc .sn{padding:4px 8px;font-size:9px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bar{height:5px;border-radius:3px;transition:width .5s}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.9);z-index:9999;display:flex;align-items:center;justify-content:center;cursor:pointer}.overlay img{max-width:95vw;max-height:95vh;border-radius:8px}
.ft{text-align:center;padding:16px;font-size:9px;color:#475569}
</style></head><body>
<div class="w">
<div class="hdr"><div><h1 id="title">L99 COMMAND CENTER</h1><div class="s">Lean Six Sigma | Playwright | Self-Healing</div><div class="s" id="info">Chargement...</div></div>
<div style="display:flex;gap:10px;align-items:center"><div id="sigma" style="font-size:28px;font-weight:800">--</div><button class="btn" onclick="runL99()">Lancer L99</button> <a href="/wevia.html" id="wevia-chat-link" style="margin-left:10px;padding:8px 16px;background:#22c55e;color:#fff;border-radius:8px;text-decoration:none;font-weight:bold">WEVIA Chat</a></div></div>
<div class="metrics" id="met"></div>
<div class="tabs" id="tabs"></div>
<div id="ct"><div class="card"><h3>Chargement...</h3></div></div>
</div>
<div class="ft">WEVAL L99 v7 | /opt/weval-l99/ | Playwright | 3 Serveurs | 21 Apps</div>
<script>
var API='/api/l99-api.php';
var D=null,V=[],S=[],TAB='overview';
function init(){
Promise.all([
fetch(API+'?action=results').then(function(r){return r.json()}),
fetch(API+'?action=videos').then(function(r){return r.json()}),
fetch(API+'?action=screenshots').then(function(r){return r.json()})
]).then(function(arr){
D=arr[0];V=arr[1].videos||[];S=arr[2].screenshots||[];
render();
}).catch(function(e){
document.getElementById('ct').innerHTML='<div class="card"><h3>Erreur: '+e.message+'</h3></div>';
})
}
function render(){
if(!D||D.error){document.getElementById('ct').innerHTML='<div class="card"><h3>'+(D&&D.error?D.error:'Lancez python3 /opt/weval-l99/l99-master.py')+'</h3></div>';return}
var p=D.pass||0,f=D.fail||0,w=D.warn||0,t=D.total||0,pct=t?p/t*100:0;
var sig=(3.4+Math.max(0,(pct-90))*.1).toFixed(1);
document.getElementById('info').textContent=t+' tests | '+V.length+' videos | '+S.length+' screenshots | '+(D.timestamp||'').substring(0,19);
document.getElementById('sigma').textContent=sig+'s';
document.getElementById('sigma').style.color=sig>=4.5?'#10b981':sig>=3.5?'#f59e0b':'#ef4444';
document.getElementById('met').innerHTML='<div class="m"><div class="v g">'+p+'</div><div class="l">PASS</div></div><div class="m"><div class="v r">'+f+'</div><div class="l">FAIL</div></div><div class="m"><div class="v y">'+w+'</div><div class="l">WARN</div></div><div class="m"><div class="v">'+t+'</div><div class="l">TOTAL</div></div><div class="m"><div class="v '+(pct>=95?'g':pct>=90?'y':'r')+'">'+pct.toFixed(0)+'%</div><div class="l">SCORE</div></div><div class="m"><div class="v b">'+V.length+'</div><div class="l">VIDEOS</div></div><div class="m"><div class="v p">'+S.length+'</div><div class="l">SCREENSHOTS</div></div>';
var tabList=[['overview','Overview'],['tests','Tests ('+t+')'],['videos','Videos ('+V.length+')'],['screenshots','Screenshots ('+S.length+')'],['cc','Command Centers'],['history','Historique'],['exec','Execution']];
document.getElementById('tabs').innerHTML=tabList.map(function(tb){return '<button class="tab'+(TAB===tb[0]?' a':'')+'" onclick="TAB=\''+tb[0]+'\';render()">'+tb[1]+'</button>'}).join('');
var C=document.getElementById('ct');
if(TAB==='overview')showOverview(C);
else if(TAB==='tests')showTests(C);
else if(TAB==='videos')showVideos(C);
else if(TAB==='screenshots')showSS(C);
else if(TAB==='cc')showCC(C);
else if(TAB==='history')showHistory(C);
else if(TAB==='exec')showExec(C);
}
function showOverview(C){
var layers={};
(D.tests||[]).forEach(function(t){var l=t.layer;if(!layers[l])layers[l]={P:0,F:0,W:0};layers[l][t.status]=(layers[l][t.status]||0)+1});
var lr='',fr='';
Object.keys(layers).sort().forEach(function(l){var d=layers[l],tot=d.P+d.F+(d.W||0),pct=tot?d.P/tot*100:0;var col=d.F===0?'#10b981':d.F<=1?'#f59e0b':'#ef4444';lr+='<tr><td>'+(d.F===0?'OK':d.F<=1?'WARN':'FAIL')+' '+l+'</td><td style="font-weight:700;color:'+col+'">'+d.P+'/'+tot+'</td><td><div style="background:#1e293b;border-radius:3px;height:5px"><div class="bar" style="width:'+pct+'%;background:'+col+'"></div></div></td><td style="color:'+(d.F?'#ef4444':'#64748b')+'">'+(d.F?d.F+'F':'-')+'</td></tr>'});
(D.tests||[]).filter(function(t){return t.status==='F'}).forEach(function(t){fr+='<tr><td style="color:#64748b">'+t.layer+'</td><td>FAIL '+t.test+'</td><td style="color:#64748b;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">'+(t.detail||'')+'</td></tr>'});
if(!fr)fr='<tr><td colspan=3 style="text-align:center;color:#10b981;padding:20px">Zero failures!</td></tr>';
C.innerHTML='<div class="grid"><div class="card"><h3>Layers</h3><table><tr><th>Layer</th><th>Score</th><th></th><th></th></tr>'+lr+'</table></div><div class="card"><h3>Failures</h3><table>'+fr+'</table></div></div>'
}
function showTests(C){
var tests=D.tests||[];
var html='<div class="card"><div style="max-height:600px;overflow-y:auto"><table>';
tests.forEach(function(t){html+='<tr><td style="color:#64748b;width:50px">'+t.layer+'</td><td>'+(t.status==='P'?'OK':t.status==='F'?'FAIL':'WARN')+' '+t.test+'</td><td style="color:#64748b;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">'+(t.detail||'')+'</td></tr>'});
html+='</table></div></div>';
C.innerHTML=html
}
function showVideos(C){
if(!V.length){C.innerHTML='<div class="card"><h3>Aucune video</h3></div>';return}
var html='<div class="grid">';
V.forEach(function(v){html+='<div class="vc"><h4>'+v.name+'</h4><video controls preload="metadata"><source src="'+v.url+'" type="video/webm"></video><div class="info">'+v.size_h+'</div></div>'});
html+='</div>';
C.innerHTML=html
}
function showSS(C){
if(!S.length){C.innerHTML='<div class="card"><h3>Aucun screenshot</h3></div>';return}
var html='<div class="grid3">';
S.forEach(function(s){html+='<div class="sc" onclick="openImg(\''+s.url+'\')"><img src="'+s.url+'" loading="lazy"><div class="sn">'+s.name+'</div></div>'});
html+='</div>';
C.innerHTML=html
}
function showCC(C){
var ccLinks=[
{t:'Command Center',u:'/command-center.html',d:'Dashboard principal'},
{t:'Mega CC',u:'/mega-command-center.html',d:'Vue 360 tous serveurs'},
{t:'Arsenal CC',u:'http://10.1.0.3:5890/command-center.html',d:'WEVADS Arsenal S95'},
{t:'Blade AI',u:'/blade-ai.html',d:'IA souveraine'},
{t:'BPMS',u:'http://10.1.0.3:5890/bpms-command-center.html',d:'Business Process S95'},
{t:'L99',u:'/l99.html',d:'Ce dashboard'}
];
var html='<div class="card"><h3>Command Centers</h3><div class="grid">';
ccLinks.forEach(function(c){html+='<div style="background:#1e293b;border:1px solid #334155;border-radius:10px;padding:16px"><h4 style="color:#a5b4fc;font-size:13px">'+c.t+'</h4><p style="font-size:10px;color:#64748b;margin:6px 0">'+c.d+'</p><a href="'+c.u+'" target="_blank" style="color:#8b5cf6;font-size:11px">Ouvrir</a></div>'});
html+='</div>';
var ccss=S.filter(function(s){return s.name.indexOf('cc-')===0||s.name.indexOf('blade')>=0});
if(ccss.length){
html+='<h3 style="margin-top:16px">Screenshots CC</h3><div class="grid3">';
ccss.forEach(function(s){html+='<div class="sc" onclick="openImg(\''+s.url+'\')"><img src="'+s.url+'" loading="lazy"><div class="sn">'+s.name+'</div></div>'});
html+='</div>';
}
html+='</div>';
C.innerHTML=html
}
function showHistory(C){
C.innerHTML='<div class="card"><h3>Chargement...</h3></div>';
fetch(API+'?action=history').then(function(r){return r.json()}).then(function(h){
var rows='';
h.forEach(function(x){var pct=x.pct||0;var col=pct>=95?'#10b981':pct>=90?'#f59e0b':'#ef4444';rows+='<tr><td>'+((x.ts||'').substring(0,19))+'</td><td style="font-weight:700;color:'+col+'">'+pct.toFixed(0)+'%</td><td style="color:#10b981">'+x.pass+'</td><td style="color:#ef4444">'+x.fail+'</td><td>'+x.total+'</td></tr>'});
if(!rows)rows='<tr><td colspan=5 style="text-align:center;color:#64748b;padding:20px">Vide</td></tr>';
C.innerHTML='<div class="card"><h3>Historique SPC</h3><table><tr><th>Date</th><th>Score</th><th>Pass</th><th>Fail</th><th>Total</th></tr>'+rows+'</table></div>'
})
}
function showExec(C){
C.innerHTML='<div class="card"><h3>Execution</h3><button class="btn" style="width:100%;margin-bottom:16px" onclick="runL99()">Lancer TOUT</button><pre style="background:#0a0e1a;border:1px solid #1e293b;border-radius:8px;padding:12px;font-size:10px;color:#10b981;max-height:300px;overflow:auto">python3 /opt/weval-l99/l99-master.py\nhttps://weval-consulting.com/l99.html\nhttps://weval-consulting.com/api/l99-api.php</pre></div>'
}
function runL99(){fetch(API+'?action=run',{method:'POST'}).then(function(){alert('L99 lance en background. Rechargez dans 10 min.')}).catch(function(e){alert('Erreur: '+e.message)})}
function openImg(url){var o=document.createElement('div');o.className='overlay';o.onclick=function(){o.remove()};o.innerHTML='<img src="'+url+'">';document.body.appendChild(o)}
init();
setInterval(init,120000);
</script>
<script src=/api/l99-showss-override.js></script><!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
<!-- WTP-GAP-FILL-V1 (doctrine 90-v2 gap-fill showcase, 18avr 2026) -->
<style>
.wtp-gapfill-banner{position:fixed;bottom:0;left:0;right:0;z-index:99999;background:linear-gradient(90deg,#05060a,#0b0d15 20%,#181d2e 50%,#0b0d15 80%,#05060a);border-top:2px solid #14b8a6;color:#e2e8f0;padding:10px 16px;font-family:Inter,system-ui,-apple-system,sans-serif;font-size:11.5px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;box-shadow:0 -10px 30px rgba(20,184,166,.28)}
.wtp-gapfill-banner a{color:#5eead4;text-decoration:none;font-weight:600;transition:color .15s}
.wtp-gapfill-banner a:hover{color:#22d3ee}
.wtp-gapfill-banner .pill{padding:2px 9px;background:rgba(99,102,241,.14);color:#a5b4fc;border-radius:10px;font-size:10.5px;font-family:JetBrains Mono,monospace;font-weight:600}
.wtp-gapfill-banner .pill.new{background:rgba(20,184,166,.22);color:#5eead4}
.wtp-gapfill-banner .pill.hot{background:rgba(236,72,153,.22);color:#f472b6}
.wtp-gapfill-banner .close{margin-left:auto;cursor:pointer;color:#64748b;padding:0 8px;font-size:16px;line-height:1;border:1px solid #334155;border-radius:4px}
.wtp-gapfill-banner .close:hover{color:#e2e8f0;border-color:#64748b}
.wtp-gapfill-banner.hidden{display:none}
@media(max-width:768px){.wtp-gapfill-banner{font-size:10px;padding:7px 10px;gap:8px}}
</style>
<div class="wtp-gapfill-banner" id="wtpGapFillBanner">
<span>🎯 <strong>WEVAL Agents Gap-Fill ERP</strong></span>
<span class="pill hot">45 gaps</span>
<span class="pill">SAP · Oracle · NetSuite · Dynamics</span>
<span class="pill new">🆕 Meeting Rooms</span>
<span class="pill new">🆕 Lean 6 Sigma</span>
<span id="wtp-gfb-metrics" class="pill">— chargement —</span>
<a href="/weval-technology-platform.html">→ WTP Portal (16 mod)</a>
<a href="/enterprise-model.html">Enterprise Model</a>
<a href="/api/weval-agents-gap-fill-manifest.json" target="_blank">📋 Manifest</a>
<span class="close" onclick="document.getElementById("wtpGapFillBanner").classList.add("hidden");localStorage.setItem("wtpGapFillHidden","1")">×</span>
</div>
<script>
(async()=>{
if(localStorage.getItem("wtpGapFillHidden")==="1"){document.getElementById("wtpGapFillBanner").classList.add("hidden");return;}
try{
const r=await fetch("/api/source-of-truth.json?t="+Date.now());
const d=await r.json();
const el=document.getElementById("wtp-gfb-metrics");
if(el)el.textContent=(d.ethica_total||"?")+" HCPs · "+(d.nonreg||"?")+" · "+(d.providers_count||"?")+" IA · "+(d.agents_count||"?")+" agents · "+(d.docker_running||"?")+" 🐳";
}catch(e){}
})();
</script>
<!-- WTP-D90V2-ENRICH-BANNER (doctrine 90-v2, 17avr 2026) -->
<style>
.wtp-enrich-banner{position:fixed;bottom:0;left:0;right:0;z-index:9999;background:linear-gradient(90deg,#0b0d15,#181d2e,#0b0d15);border-top:2px solid #14b8a6;color:#e2e8f0;padding:9px 18px;font-family:'JetBrains Mono',monospace,-apple-system,system-ui;font-size:11.5px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;box-shadow:0 -8px 24px rgba(20,184,166,.25)}
.wtp-enrich-banner a{color:#14b8a6;text-decoration:none;font-weight:600}
.wtp-enrich-banner a:hover{color:#22d3ee}
.wtp-enrich-banner .pill{padding:2px 8px;background:rgba(99,102,241,.15);color:#a5b4fc;border-radius:10px;font-size:10.5px}
.wtp-enrich-banner .pill.new{background:rgba(20,184,166,.2);color:#5eead4}
.wtp-enrich-banner .close{margin-left:auto;cursor:pointer;color:#64748b;padding:0 6px;font-size:14px}
.wtp-enrich-banner .close:hover{color:#e2e8f0}
.wtp-enrich-banner.hidden{display:none}
@media(max-width:768px){.wtp-enrich-banner{font-size:10px;padding:6px 10px}}
</style>
<div class="wtp-enrich-banner" id="wtpEnrichBanner">
<span>🏛️ <strong>Enterprise Model 16 depts</strong></span>
<span class="pill new">🆕 Meeting Rooms</span>
<span class="pill new">🆕 Lean 6 Sigma</span>
<span id="wtp-eb-metrics" class="pill">— chargement —</span>
<a href="/weval-technology-platform.html">→ WEVAL Technology Platform (16 modules)</a>
<a href="/enterprise-model.html">Enterprise Model</a>
<a href="/wevia-master.html">WEVIA Master</a>
<span class="close" onclick="document.getElementById('wtpEnrichBanner').classList.add('hidden')">×</span>
</div>
<script>
(async()=>{try{const r=await fetch('/api/source-of-truth.json?t='+Date.now());const d=await r.json();const el=document.getElementById('wtp-eb-metrics');if(el)el.textContent=(d.ethica_total||'?')+' HCPs · '+(d.nonreg||'?')+' · '+(d.providers_count||'?')+' IA · '+(d.docker_running||'?')+' 🐳 · '+(d.subdomains_live||'?')+' subdomains';}catch(e){}})();
</script>
</body></html>