394 lines
29 KiB
HTML
394 lines
29 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>WEVAL — Value Stream Mapping</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800;900&display=swap');
|
||
*{margin:0;padding:0;box-sizing:border-box}
|
||
:root{--bg:#0f1117;--card:#1a1d27;--border:#2a2d3a;--text:#e2e4eb;--dim:#6b7280;--accent:#3b82f6;--green:#10b981;--orange:#f59e0b;--red:#ef4444;--purple:#8b5cf6;--cyan:#06b6d4;--pink:#ec4899}
|
||
body{background:var(--bg);color:var(--text);font-family:'DM Sans',sans-serif;min-height:100vh}
|
||
.header{background:linear-gradient(135deg,#1a1d27 0%,#0f1117 100%);border-bottom:1px solid var(--border);padding:16px 24px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}
|
||
.header h1{font-family:'JetBrains Mono',monospace;font-size:18px;font-weight:700;background:linear-gradient(135deg,#3b82f6,#8b5cf6);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
||
.header .live{font-size:11px;color:var(--green);animation:pulse 2s infinite}
|
||
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
||
.tabs{display:flex;gap:2px;background:var(--card);border-radius:8px;padding:3px;border:1px solid var(--border)}
|
||
.tab{padding:6px 14px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;color:var(--dim);transition:.2s}
|
||
.tab:hover{color:var(--text)}
|
||
.tab.active{background:var(--accent);color:#fff}
|
||
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:10px;padding:16px 24px}
|
||
.kpi{background:var(--card);border:1px solid var(--border);border-radius:10px;padding:12px;text-align:center}
|
||
.kpi .val{font-family:'JetBrains Mono',monospace;font-size:22px;font-weight:700}
|
||
.kpi .lbl{font-size:10px;color:var(--dim);margin-top:2px;text-transform:uppercase;letter-spacing:1px}
|
||
.kpi.green .val{color:var(--green)}.kpi.blue .val{color:var(--accent)}.kpi.orange .val{color:var(--orange)}.kpi.purple .val{color:var(--purple)}.kpi.cyan .val{color:var(--cyan)}.kpi.pink .val{color:var(--pink)}.kpi.red .val{color:var(--red)}
|
||
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(420px,1fr));gap:12px;padding:0 24px 24px}
|
||
.dept{background:var(--card);border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:.2s}
|
||
.dept:hover{border-color:var(--accent);transform:translateY(-1px)}
|
||
.dept-head{padding:12px 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border)}
|
||
.dept-head h3{font-size:14px;font-weight:700;display:flex;align-items:center;gap:8px}
|
||
.dept-head .badge{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:600}
|
||
.dept-head .cnt{font-size:11px;color:var(--dim)}
|
||
.dept-body{padding:12px 16px;display:flex;flex-wrap:wrap;gap:6px}
|
||
.agent{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;border:1px solid transparent;transition:.15s;cursor:default}
|
||
.agent:hover{transform:scale(1.05);border-color:rgba(255,255,255,.1)}
|
||
.agent .icon{font-size:13px}
|
||
.pipeline{padding:8px 16px;border-top:1px solid var(--border);display:flex;align-items:center;gap:8px;overflow-x:auto}
|
||
.pipe-step{font-size:10px;padding:3px 8px;border-radius:4px;background:rgba(59,130,246,.1);color:var(--accent);font-weight:600;white-space:nowrap}
|
||
.pipe-arrow{color:var(--dim);font-size:10px}
|
||
.output{padding:8px 16px;border-top:1px solid var(--border);font-size:11px;color:var(--dim);display:flex;align-items:center;gap:6px}
|
||
.output .metric{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:13px}
|
||
.section-title{padding:20px 24px 8px;font-size:13px;font-weight:700;color:var(--dim);text-transform:uppercase;letter-spacing:2px;display:flex;align-items:center;gap:8px}
|
||
.section-title::after{content:'';flex:1;height:1px;background:var(--border)}
|
||
.n8n-tag{font-size:9px;padding:1px 5px;border-radius:3px;background:rgba(59,130,246,.2);color:var(--accent);font-weight:700;margin-left:4px}
|
||
.status-dot{width:6px;height:6px;border-radius:50%;display:inline-block}
|
||
.status-dot.green{background:var(--green)}.status-dot.orange{background:var(--orange)}.status-dot.red{background:var(--red)}
|
||
#view-agents,#view-n8n,#view-infra{display:none}
|
||
#view-overview{display:block}
|
||
</style>
|
||
</head>
|
||
<body style="padding-top:60px"><div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
|
||
<div style="position:fixed;top:30px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:4px;z-index:100;background:#f8fafcee;backdrop-filter:blur(8px);font-family:Nunito,sans-serif">
|
||
<a href="/agents-archi.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Architecture</a>
|
||
<a href="/director-center.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Director</a>
|
||
<a href="/wevia-meeting-rooms.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Rooms</a>
|
||
<a href="/enterprise-model.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Enterprise</a>
|
||
<a href="/agents-ia.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Pyramid</a>
|
||
<a href="/director-chat.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Chat</a>
|
||
<a href="/l99-brain.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">L99</a>
|
||
</div>
|
||
<div class="header">
|
||
<h1>⚡ WEVAL Value Stream Mapping</h1>
|
||
<div style="display:flex;align-items:center;gap:16px">
|
||
<div class="tabs" id="tabs">
|
||
<div class="tab active" onclick="showView('overview')">Overview</div>
|
||
<div class="tab" onclick="showView('agents')">Agents</div>
|
||
<div class="tab" onclick="showView('n8n')">n8n Workflows</div>
|
||
<div class="tab" onclick="showView('infra')">Infrastructure</div>
|
||
</div>
|
||
<span class="live">● LIVE</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpis">
|
||
<div class="kpi blue"><div class="val">191</div><div class="lbl">Agents</div></div>
|
||
<div class="kpi purple"><div class="val">21</div><div class="lbl">Depts</div></div>
|
||
<div class="kpi cyan"><div class="val">15</div><div class="lbl">n8n Flows</div></div>
|
||
<div class="kpi green"><div class="val">685</div><div class="lbl">OSS Tools</div></div>
|
||
<div class="kpi orange"><div class="val">3M</div><div class="lbl">Contacts</div></div>
|
||
<div class="kpi pink"><div class="val">141K+</div><div class="lbl">HCPs</div></div>
|
||
<div class="kpi blue"><div class="val">20</div><div class="lbl">Docker</div></div>
|
||
<div class="kpi green"><div class="val">94%</div><div class="lbl">L99 Score</div></div>
|
||
</div>
|
||
|
||
<div id="view-overview">
|
||
<div class="section-title">🏢 Departments & Pipelines</div>
|
||
<div class="grid" id="dept-grid"></div>
|
||
</div>
|
||
|
||
<div id="view-agents">
|
||
<div class="section-title">🤖 All Agents by Department</div>
|
||
<div class="grid" id="agent-grid"></div>
|
||
</div>
|
||
|
||
<div id="view-n8n">
|
||
<div class="section-title">⚙ n8n Workflows (15)</div>
|
||
<div class="grid" id="n8n-grid"></div>
|
||
</div>
|
||
|
||
<div id="view-infra">
|
||
<div class="section-title">🏗️ Infrastructure</div>
|
||
<div class="grid" id="infra-grid"></div>
|
||
</div>
|
||
|
||
<script>
|
||
const DEPTS=[
|
||
{id:'ceo',name:'CEO Office',icon:'👑',color:'#f59e0b',agents:['CEO Brain','Decision','Budget','Strategy','Hiring','Review'],pipeline:['Decision','Orchestration','TaskMgr','Intro','Brief'],output:'1 brief/j',metric:'Leadership'},
|
||
{id:'sal',name:'Prospect & Sales',icon:'🎯',color:'#ef4444',agents:['Leads','Qualify','Outreach','Convert','Close','Ethica','Analyst','Writer','Proposal','Contract'],pipeline:['LeadForge','Outreach','MailWarm','Proposal'],output:'1052 leads',metric:'B2B Pipeline'},
|
||
{id:'con',name:'Consulting',icon:'💼',color:'#8b5cf6',agents:['Architect','Planner','DeerFlow','Critic','Translate','Academy','ECC-36','Persona-6'],pipeline:['Analyse','Design','Process','Deliver','Support'],output:'3 proposals',metric:'SAP/Cloud/IA'},
|
||
{id:'dev',name:'Dev Lab',icon:'⚡',color:'#3b82f6',agents:['FullCode','Review','Test','Deploy','Mauricio','Debugger','Designer','WEDROID','Simplifier','Blueprint','DevForge'],pipeline:['Code','Review','Test','Deploy'],output:'12 deploys/j',metric:'CI/CD'},
|
||
{id:'srv',name:'Infrastructure',icon:'🏗️',color:'#06b6d4',agents:['Watchdog','Guardian','Blade','GitMaster','Loki','Monitor','Fix','Discover','Verify','Report'],pipeline:['Watch','Alert','Fix','Report'],output:'99.9% uptime',metric:'S204+S95+S151'},
|
||
{id:'sec',name:'Security',icon:'🛡️',color:'#ef4444',agents:['Security','Verifier','TruffleHog','DetectSecrets','KeyHacks','shhgit','GitDorking','Nuclei'],pipeline:['Scan','Audit','Patch','Lock'],output:'0 CVE',metric:'5 scanners'},
|
||
{id:'qa',name:'QA / L99',icon:'🧪',color:'#10b981',agents:['QA','Testing','Tracer','Scientist','L99','Plan','Execute','Analyse','Report','Fix'],pipeline:['Plan','Run','Report','Ship'],output:'148 PASS',metric:'153/153'},
|
||
{id:'pha',name:'Pharma & Ethica',icon:'💊',color:'#ec4899',agents:['Explore','DabaDoc','MiroFish','Validate','Enrich','Campaign','Ship'],pipeline:['Scrape','Enrich','Campaign','Ship'],output:'132.7K HCPs',metric:'DZ+MA+TN'},
|
||
{id:'ops',name:'Monitor',icon:'📊',color:'#f59e0b',agents:['TrustMRR','Grafana','Alert','Ortho','Dashboard'],pipeline:['Watch','Alert','Fix','Report'],output:'7.7K opens',metric:'1394 stats'},
|
||
{id:'cron',name:'Automation / Crons',icon:'⏰',color:'#f97316',agents:['EthicaCron','B2BCron','NonRegCron','BackupCron','OSSChainCron','L99AliveCron','GuardianCron','SecretScanCron','KeySyncCron'],pipeline:['Ethica','B2B','NonReg','Backup'],output:'50+ crons',metric:'24/7 auto'},
|
||
{id:'mta',name:'Email MTA',icon:'📧',color:'#6366f1',agents:['PMTA :25','KumoMTA :587','Postfix :2525'],pipeline:['PMTA','KumoMTA','Postfix','Deliver'],output:'7.7K opens',metric:'3M contacts'},
|
||
{id:'ai',name:'AI Engine',icon:'🧠',color:'#8b5cf6',agents:['Groq','Cerebras','MistralAI','SambaNovaAI','AlibabaQwen','NVIDIA-GLM5','Ollama','Sovereign','ClaudeCode','OpenWebUI','Lyria3','SunoAI'],pipeline:['Ingest','Route','Infer','Validate','Deliver'],output:'12 models',metric:'6 providers'},
|
||
{id:'saas',name:'SaaS Products',icon:'📦',color:'#10b981',agents:['LeadForge','OutreachAI','MailWarm','ProposalAI','WEVIA PUBLIC','Manager','WhatsApp API'],pipeline:['Build','Launch','Sell','Support','Scale'],output:'28 tools',metric:'7 products'},
|
||
{id:'intg',name:'OSS Integration',icon:'🔗',color:'#06b6d4',agents:['BrowserUse','OpenClaw','Goose','AIOS','Dify','Mastra','EvoMaster','Activepieces','AEGIS','Prometheus','CrewAI','LangChain','Scrapy','Supermemory','SkillSmith','Flowise','HuggingFace','Langflow','LibreChat','llama-cpp'],pipeline:['Discover','Evaluate','Wire','Test','Deploy'],output:'685 tools',metric:'22/22 INTG'},
|
||
{id:'dock',name:'Docker / Services',icon:'🐳',color:'#2563eb',agents:['Authentik x3','Plausible x3','Uptime-Kuma','Mattermost','SearXNG','Loki','Twenty-Redis','Paperclip','OpenWebUI','Flowise','Vaultwarden','n8n','Qdrant','Redis','Sovereign','CrowdSec'],pipeline:['Start','Configure','Monitor','Scale','Update'],output:'20 dock',metric:'19 UP'},
|
||
{id:'wevia',name:'WEVIA Suite',icon:'🤖',color:'#ec4899',agents:['WEVCODE','WEVIA Life','WEVIAGateway','TTS','MermaidGen','L99','ClaudeSync'],pipeline:['Chat','Code','Life','Gateway'],output:'200/j',metric:'71 modules'},
|
||
{id:'plat',name:'Platform',icon:'🔧',color:'#0d9488',agents:['SkillsRAG','PromptsLib','CodeWiki','AIBench','ModelScope','OSSDiscover','GHGrab','AgentShield','Obsidian'],pipeline:['Skills','Prompts','Wiki','Bench'],output:'4414 sk',metric:'528 skills'},
|
||
{id:'n8n',name:'n8n Workflows',icon:'⚙',color:'#3b82f6',agents:['n8n-EthicaHCP','n8n-B2BLeads','n8n-NonReg','n8n-Sovereign','n8n-WhatsApp','n8n-EmailDrip','n8n-OSSSync','n8n-DeerFlow','n8n-Paperclip','n8n-AzureAD','n8n-Guardian','n8n-SecretScan','n8n-KeySync','n8n-L99Alive','n8n-Backup'],pipeline:['Trigger','Process','Transform','Output'],output:'15 WF',metric:'13 active'},
|
||
{id:'wire',name:'TO WIRE',icon:'🔌',color:'#f97316',agents:['OVH SMS','ListMonk','NoVNC'],pipeline:['Commit','Config','Test','Activate'],output:'3 TODO',metric:'Needs creds'},
|
||
{id:'dorm',name:'Dormants',icon:'💤',color:'#6b7280',agents:['vLLM→Colab','LocalAI→HF','AutoGen→Eval','AnythingLLM','Wazuh','LlamaIndex'],pipeline:['Clone','Evaluate','Wire','Activate'],output:'6 wait',metric:'GPU/eval'},
|
||
];
|
||
|
||
function renderDepts(container,depts){
|
||
const g=document.getElementById(container);
|
||
g.innerHTML='';
|
||
depts.forEach(d=>{
|
||
const agents=d.agents.map(a=>{
|
||
const isN8n=a.startsWith('n8n-');
|
||
const isCron=a.includes('Cron');
|
||
const bg=isN8n?'rgba(59,130,246,.15)':isCron?'rgba(249,115,22,.15)':`rgba(${hexToRgb(d.color)},.12)`;
|
||
const fg=isN8n?'#60a5fa':isCron?'#fb923c':d.color;
|
||
return `<span class="agent" style="background:${bg};color:${fg}">${a}${isN8n?'<span class="n8n-tag">n8n</span>':''}</span>`;
|
||
}).join('');
|
||
const pipe=d.pipeline.map((s,i)=>`<span class="pipe-step">${i+1}. ${s}</span>${i<d.pipeline.length-1?'<span class="pipe-arrow">→</span>':''}`).join('');
|
||
g.innerHTML+=`<div class="dept">
|
||
<div class="dept-head"><h3>${d.icon} ${d.name} <span class="cnt">${d.agents.length}</span></h3><span class="badge" style="background:${d.color}20;color:${d.color}">${d.metric}</span></div>
|
||
<div class="dept-body">${agents}</div>
|
||
<div class="pipeline">${pipe}</div>
|
||
<div class="output"><span class="status-dot green"></span> OUTPUT: <span class="metric" style="color:${d.color}">${d.output}</span></div>
|
||
</div>`;
|
||
});
|
||
}
|
||
|
||
function hexToRgb(h){const r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16);return`${r},${g},${b}`}
|
||
|
||
const N8N_FLOWS=[
|
||
{name:'Ethica HCP Enrichment',schedule:'*/6h',nodes:12,status:'active',desc:'DabaDoc scrape → enrich tel/email → Telegram alert'},
|
||
{name:'B2B Lead Generation',schedule:'*/4h',nodes:8,status:'active',desc:'LinkedIn → email pattern → CRM → outbound sequence'},
|
||
{name:'NonReg Watchdog',schedule:'6h/18h',nodes:6,status:'active',desc:'153 tests → Telegram + Mattermost → L99 update'},
|
||
{name:'Sovereign AI Router',schedule:'Webhook',nodes:5,status:'active',desc:'Request → Ollama/Cerebras/Groq → format Anthropic'},
|
||
{name:'WhatsApp Campaign',schedule:'Manual',nodes:7,status:'ready',desc:'HCP list → template → Meta API → track delivery'},
|
||
{name:'Email Drip DZ+MA+TN',schedule:'*/5min',nodes:9,status:'active',desc:'Queue → KumoMTA → track opens/clicks → re-engage'},
|
||
{name:'OSS Discovery Sync',schedule:'*/6h',nodes:6,status:'active',desc:'GitHub scan → score → wire → Paperclip sync'},
|
||
{name:'DeerFlow Research',schedule:'Webhook',nodes:8,status:'active',desc:'Query → 528 skills → Groq → synthesize → report'},
|
||
{name:'Paperclip Chain',schedule:'API',nodes:10,status:'active',desc:'CEO heartbeat → agents → tools → execute → report'},
|
||
{name:'Azure AD O365',schedule:'Daily',nodes:5,status:'active',desc:'6 tenants → token refresh → 1311 accounts sync'},
|
||
{name:'Guardian Auto-Heal',schedule:'*/5min',nodes:4,status:'active',desc:'chattr check → service health → disk → auto-fix'},
|
||
{name:'Secret Scanner',schedule:'Sun 3am',nodes:5,status:'active',desc:'TruffleHog → detect-secrets → dorking → report'},
|
||
{name:'Key Sync',schedule:'*/6h',nodes:4,status:'active',desc:'secrets.env → inventory → validate → alert expired'},
|
||
{name:'L99 Alive Monitor',schedule:'*/30min',nodes:7,status:'active',desc:'14 pages → Playwright → screenshot → state update'},
|
||
{name:'Backup GOLD',schedule:'4am',nodes:5,status:'active',desc:'PG dump → vault → S95 → verify → clean old'},
|
||
];
|
||
|
||
function renderN8n(){
|
||
const g=document.getElementById('n8n-grid');
|
||
g.innerHTML='';
|
||
N8N_FLOWS.forEach(f=>{
|
||
const st=f.status==='active'?'green':'orange';
|
||
g.innerHTML+=`<div class="dept">
|
||
<div class="dept-head"><h3>⚙ ${f.name} <span class="n8n-tag">n8n</span></h3><span class="badge" style="background:rgba(59,130,246,.2);color:#60a5fa">${f.schedule}</span></div>
|
||
<div style="padding:10px 16px;font-size:12px;color:var(--dim)">${f.desc}</div>
|
||
<div class="output"><span class="status-dot ${st}"></span> ${f.nodes} nodes — <span class="metric" style="color:var(--accent)">${f.status.toUpperCase()}</span></div>
|
||
</div>`;
|
||
});
|
||
}
|
||
|
||
const INFRA=[
|
||
{name:'S204 (204.168.152.13)',status:'UP',details:'Hetzner AX102 · 150G SSD · 84% used · 24G free · 20 Docker · Nginx+PHP8.5+PG13 · Ollama 7 models'},
|
||
{name:'S95 (95.216.167.89)',status:'UP',details:'Hetzner · Apache+PHP8.4 · PG13 · 12 schemas 619 tables · PMTA+KumoMTA+Postfix · 192 Arsenal · 40 crons'},
|
||
{name:'S151 (151.80.235.110)',status:'UP',details:'OVH · OpenClaw+Ollama · Tracking relay · 45% disk · Redis+PG+Nginx'},
|
||
{name:'Blade (Razer)',status:'ONLINE',details:'Windows · Claude Code v2.1.89 · Sentinel v2.4 · GLM-5 · 34 capabilities'},
|
||
{name:'S88 (88.198.4.195)',status:'DEAD',details:'GPU mort · Hetzner ANNULÉ · -45€/mois économisés · Archives dans vault'},
|
||
{name:'Sovereign API (:4000)',status:'UP',details:'FastAPI · Ollama PRIMARY → Cerebras → Groq fallback · Anthropic Messages API'},
|
||
{name:'Paperclip (:3100)',status:'UP',details:'150 agents · 520 files · 747KB instructions · CEO org chart'},
|
||
{name:'DeerFlow',status:'UP',details:'528 skills · 3 systemd · Groq primary · Mattermost alerts'},
|
||
];
|
||
|
||
function renderInfra(){
|
||
const g=document.getElementById('infra-grid');
|
||
g.innerHTML='';
|
||
INFRA.forEach(s=>{
|
||
const color=s.status==='UP'||s.status==='ONLINE'?'var(--green)':s.status==='DEAD'?'var(--red)':'var(--orange)';
|
||
g.innerHTML+=`<div class="dept">
|
||
<div class="dept-head"><h3>🖥️ ${s.name}</h3><span class="badge" style="background:${color}20;color:${color}">${s.status}</span></div>
|
||
<div style="padding:10px 16px;font-size:12px;color:var(--dim)">${s.details}</div>
|
||
</div>`;
|
||
});
|
||
}
|
||
|
||
function showView(v){
|
||
['overview','agents','n8n','infra'].forEach(x=>document.getElementById('view-'+x).style.display='none');
|
||
document.getElementById('view-'+v).style.display='block';
|
||
document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
|
||
event.target.classList.add('active');
|
||
if(v==='n8n')renderN8n();
|
||
if(v==='infra')renderInfra();
|
||
if(v==='agents')renderDepts('agent-grid',DEPTS);
|
||
}
|
||
|
||
renderDepts('dept-grid',DEPTS);
|
||
</script>
|
||
<!-- 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>
|
||
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
|
||
<script>
|
||
(function(){
|
||
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
|
||
var d = document;
|
||
var m = d.createElement('div');
|
||
m.id = 'opus-udrill';
|
||
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
|
||
var inner = d.createElement('div');
|
||
inner.id = 'opus-udrill-in';
|
||
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
|
||
inner.addEventListener('click', function(e){ e.stopPropagation(); });
|
||
m.appendChild(inner);
|
||
m.addEventListener('click', function(){ m.style.display='none'; });
|
||
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
|
||
(d.body || d.documentElement).appendChild(m);
|
||
|
||
function openCard(card) {
|
||
// Clone card content + show close btn + increase font-size
|
||
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
|
||
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
|
||
inner.innerHTML = html;
|
||
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
|
||
m.style.display = 'flex';
|
||
}
|
||
|
||
function wire(root) {
|
||
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
|
||
var cards = root.querySelectorAll(sels);
|
||
for (var i = 0; i < cards.length; i++) {
|
||
var c = cards[i];
|
||
if (c.__opusWired) continue;
|
||
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
|
||
var r = c.getBoundingClientRect();
|
||
if (r.width < 60 || r.height < 40) continue;
|
||
c.__opusWired = true;
|
||
c.style.cursor = 'pointer';
|
||
c.setAttribute('role','button');
|
||
c.setAttribute('tabindex','0');
|
||
c.addEventListener('click', function(ev){
|
||
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
|
||
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
|
||
if (ev.target.closest('a,button,input,select')) return;
|
||
ev.preventDefault(); ev.stopPropagation();
|
||
openCard(this);
|
||
});
|
||
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
|
||
}
|
||
}
|
||
|
||
// Initial + mutation observer
|
||
var initRun = function(){ wire(d.body || d.documentElement); };
|
||
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
|
||
else initRun();
|
||
var mo = new MutationObserver(function(muts){
|
||
var newCard = false;
|
||
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
|
||
if (newCard) initRun();
|
||
});
|
||
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
|
||
})();
|
||
</script>
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
|
||
|
||
|
||
<!-- === OPUS HONEST NR/L99 OVERLAY v1 19avr - append-only doctrine #14 === -->
|
||
<script>
|
||
(function(){
|
||
if (window.__opusHonestOverlay) return; window.__opusHonestOverlay = true;
|
||
async function updateHonestValues(){
|
||
try {
|
||
const r = await fetch('/api/l99-honest.php', {cache:'no-store'});
|
||
const d = await r.json();
|
||
if (!d.ok) return;
|
||
const realNR = `${d.combined.pass}/${d.combined.total}`;
|
||
const realSigma = d.sigma;
|
||
// Find elements showing the myth values
|
||
const mythRegex = /(153\/153|304\/304|NR status 153\/153|L99 status 304\/304|NR 153\/153|L99 304\/304)/g;
|
||
// Walk text nodes
|
||
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
|
||
const toReplace = [];
|
||
let node;
|
||
while (node = walker.nextNode()) {
|
||
if (node.nodeValue && mythRegex.test(node.nodeValue)) toReplace.push(node);
|
||
}
|
||
toReplace.forEach(textNode => {
|
||
const parent = textNode.parentNode;
|
||
if (!parent || parent.hasAttribute('data-opus-honest-applied')) return;
|
||
const newText = textNode.nodeValue.replace(/153\/153/g, realNR).replace(/304\/304/g, realNR);
|
||
textNode.nodeValue = newText;
|
||
parent.setAttribute('data-opus-honest-applied', '1');
|
||
});
|
||
// Add a small badge bottom-right showing honest live status
|
||
if (!document.getElementById('opus-honest-badge')) {
|
||
const b = document.createElement('div');
|
||
b.id = 'opus-honest-badge';
|
||
b.style.cssText = 'position:fixed;bottom:12px;right:12px;background:linear-gradient(90deg,#14b8a6,#a855f7);color:#05060a;padding:6px 12px;font:10px/1.3 Inter,system-ui,sans-serif;font-weight:700;border-radius:8px;z-index:99993;box-shadow:0 4px 12px rgba(0,0,0,0.3);cursor:pointer;max-width:280px';
|
||
b.title = 'Cliquer pour détails';
|
||
b.innerHTML = `✓ NR ${realNR} · ${realSigma} live`;
|
||
b.onclick = () => {
|
||
alert(`HONEST NonReg (doctrine #4):\n\nmaster: ${d.master.pass}/${d.master.total}\nopus: ${d.opus.pass}/${d.opus.total}\ncombined: ${realNR}\nsigma: ${realSigma}\n\n${d.myth_153}\n${d.myth_304}`);
|
||
};
|
||
document.body.appendChild(b);
|
||
}
|
||
} catch(e){console.error('L99-honest fetch error:', e);}
|
||
}
|
||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateHonestValues);
|
||
else updateHonestValues();
|
||
setInterval(updateHonestValues, 90000);
|
||
})();
|
||
</script>
|
||
<!-- === OPUS HONEST END === -->
|
||
|
||
</body>
|
||
</html>
|