Files
html/cron-control.html
opus e30ddf5007
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
auto-sync via WEVIA git_sync_all intent 2026-04-20T13:11:38+02:00
2026-04-20 13:11:38 +02:00

1126 lines
86 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">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<title>WEVADS — Infrastructure Control Panel</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{--bg:#0a0b0d;--s:#12141a;--s2:#1a1d26;--b:#252830;--t:#e8eaf0;--d:#6b7280;--g:#22c55e;--r:#ef4444;--w:#f59e0b;--bl:#3b82f6;--pu:#a78bfa;--cy:#22d3ee;--pk:#f472b6;--or:#fb923c;--tl:#2dd4bf;--li:#84cc16}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--t);min-height:100vh}
.hdr{background:var(--s);border-bottom:1px solid var(--b);padding:14px 20px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px}
.hdr h1{font-size:1.15rem;font-weight:700;letter-spacing:1px}
.hdr-sub{font-size:.65rem;color:var(--d)}
.sr{display:flex;gap:20px;align-items:center;flex-wrap:wrap}
.stat{text-align:center}
.stat .v{font-family:'JetBrains Mono';font-size:1.3rem;font-weight:700;color:var(--bl)}
.stat .l{font-size:.55rem;color:var(--d);text-transform:uppercase;letter-spacing:.5px}
.stat.ok .v{color:var(--g)}.stat.wa .v{color:var(--w)}.stat.pu .v{color:var(--pu)}.stat.cy .v{color:var(--cy)}
/* PIPELINES */
.stit{padding:8px 20px;font-size:.65rem;color:var(--d);text-transform:uppercase;letter-spacing:1px;font-weight:600;border-bottom:1px solid var(--b);margin-top:6px;display:flex;align-items:center;gap:8px}
.pipes{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;padding:12px 20px}
.pipe{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:12px 14px;border-left:3px solid var(--d)}
.pipe.pe::before{border-color:var(--cy)}.pipe.pb::before{border-color:var(--tl)}
.pipe.pe{border-left-color:var(--cy)}.pipe.pb{border-left-color:var(--tl)}.pipe.pi{border-left-color:var(--pu)}
.pipe.pw{border-left-color:var(--bl)}.pipe.pd{border-left-color:var(--or)}.pipe.ps{border-left-color:var(--g)}
.pipe.pn{border-left-color:var(--r)}.pipe.pm{border-left-color:var(--pk)}.pipe.pbe{border-left-color:var(--w)}
.pipe .pn2{font-weight:700;font-size:.78rem;margin-bottom:5px}
.pipe .pst{display:flex;gap:12px;flex-wrap:wrap}
.pipe .ps2{text-align:center}
.pipe .ps2 .pv{font-family:'JetBrains Mono';font-size:.95rem;font-weight:700}
.pipe .ps2 .pl{font-size:.5rem;color:var(--d);text-transform:uppercase}
.pipe.pe .pv{color:var(--cy)}.pipe.pb .pv{color:var(--tl)}.pipe.pi .pv{color:var(--pu)}
.pipe.pw .pv{color:var(--bl)}.pipe.pd .pv{color:var(--or)}.pipe.ps .pv{color:var(--g)}
.pipe.pn .pv{color:var(--r)}.pipe.pm .pv{color:var(--pk)}.pipe.pbe .pv{color:var(--w)}
/* TABS + GRID */
.tabs{display:flex;gap:6px;padding:10px 20px;flex-wrap:wrap}
.tab{padding:5px 14px;border-radius:20px;font-size:.72rem;font-weight:600;cursor:pointer;background:var(--s);border:1px solid var(--b);color:var(--d);transition:.2s}
.tab:hover{border-color:var(--bl);color:var(--t)}
.tab.active{background:var(--bl);border-color:var(--bl);color:#fff}
.tab .cnt{font-family:'JetBrains Mono';font-size:.6rem;margin-left:3px;opacity:.7}
.grid{padding:0 20px 20px}
.srv{margin-bottom:12px;background:var(--s);border:1px solid var(--b);border-radius:10px;overflow:hidden}
.srv-h{padding:9px 14px;display:flex;align-items:center;justify-content:space-between;background:var(--s2);border-bottom:1px solid var(--b);cursor:pointer}
.srv-h:hover{background:rgba(255,255,255,.02)}
.srv-n{font-weight:700;font-size:.85rem}
.srv-i{font-family:'JetBrains Mono';font-size:.6rem;color:var(--d)}
table{width:100%;border-collapse:collapse;font-size:.72rem}
th{text-align:left;padding:6px 8px;color:var(--d);font-size:.55rem;text-transform:uppercase;letter-spacing:.5px;border-bottom:1px solid var(--b);position:sticky;top:0;background:var(--s)}
td{padding:5px 8px;border-bottom:1px solid rgba(255,255,255,.03)}
tr:hover td{background:rgba(255,255,255,.02)}
.sc{font-family:'JetBrains Mono';font-size:.63rem;color:var(--cy);white-space:nowrap}
.cm{font-family:'JetBrains Mono';font-size:.63rem;color:var(--bl);word-break:break-all;max-width:280px}
.kp{font-size:.6rem;color:var(--d)}
.uo{font-family:'JetBrains Mono';font-size:.63rem;color:var(--or);font-weight:600;white-space:nowrap}
.cat{display:inline-block;padding:1px 6px;border-radius:3px;font-size:.53rem;font-weight:700;text-transform:uppercase;letter-spacing:.3px}
.c-send{background:#22c55e18;color:var(--g)}.c-eth{background:#22d3ee18;color:var(--cy)}
.c-inf{background:#a78bfa18;color:var(--pu)}.c-bak{background:#f59e0b18;color:var(--w)}
.c-nr{background:#ef444418;color:var(--r)}.c-wev{background:#3b82f618;color:var(--bl)}
.c-mon{background:#f472b618;color:var(--pk)}.c-dat{background:#fb923c18;color:var(--or)}
.c-gen{background:#6b728018;color:var(--d)}.c-b2b{background:#2dd4bf18;color:var(--tl)}
.c-doc{background:#84cc1618;color:var(--li)}.c-sys{background:#6b728018;color:var(--d)}
.c-crm{background:#a78bfa18;color:var(--pu)}
.st{display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:4px}
.st-a{background:var(--g)}.st-s{background:var(--w)}.st-d{background:var(--r)}
.leg{display:flex;gap:16px;padding:5px 20px;font-size:.6rem;color:var(--d);flex-wrap:wrap}
.leg span{display:flex;align-items:center;gap:3px}
.ft{text-align:right;padding:6px 20px;font-size:.55rem;color:var(--d)}
.type-badge{font-size:.5rem;padding:1px 5px;border-radius:3px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;margin-right:4px}
.tb-cron{background:var(--cy);color:#000}.tb-docker{background:var(--li);color:#000}.tb-svc{background:var(--pu);color:#fff}
/* DRILL-DOWN */
.dd-overlay{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.88);z-index:1000;overflow-y:auto}
.dd-overlay.open{display:block}
.dd-panel{background:var(--bg);border:1px solid var(--b);border-radius:14px;max-width:1100px;margin:30px auto;position:relative}
.dd-hdr{padding:14px 20px;border-bottom:1px solid var(--b);display:flex;justify-content:space-between;align-items:center}
.dd-hdr h2{font-size:1rem;font-weight:700}
.dd-close{background:none;border:1px solid var(--b);color:var(--t);padding:5px 12px;border-radius:6px;cursor:pointer;font-size:.75rem}
.dd-close:hover{background:var(--s2);border-color:var(--bl)}
.dd-body{padding:16px 20px}
.dd-kpis{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.dd-kpi{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:8px 14px;text-align:center;min-width:80px}
.dd-kpi .dv{font-family:'JetBrains Mono';font-size:1.1rem;font-weight:700}
.dd-kpi .dl{font-size:.5rem;color:var(--d);text-transform:uppercase}
.fl{margin-top:10px}
.fl-sec{margin-bottom:12px}
.fl-sec-t{font-size:.58rem;color:var(--d);text-transform:uppercase;letter-spacing:.8px;font-weight:600;padding-bottom:4px;border-bottom:1px solid var(--b);margin-bottom:8px}
.fl-row{display:flex;align-items:center;gap:0;flex-wrap:wrap;justify-content:center;margin-bottom:4px}
.fl-n{background:var(--s);border:1px solid var(--b);border-radius:7px;padding:6px 12px;text-align:center;min-width:120px;max-width:200px}
.fl-n .nn{font-weight:600;font-size:.68rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fl-n .nu{font-family:'JetBrains Mono';font-size:.65rem;font-weight:700;color:var(--or)}
.fl-n .nd{font-size:.5rem;color:var(--d);margin-top:1px}
.fl-n.ns{border-left:3px solid var(--cy)}.fl-n.np{border-left:3px solid var(--bl)}
.fl-n.ne{border-left:3px solid var(--or)}.fl-n.no{border-left:3px solid var(--g)}
.fl-n.na{border-left:3px solid var(--pu)}.fl-n.nw{border-left:3px solid var(--w);opacity:.7}
.fl-a{color:var(--d);font-size:.9rem;padding:0 6px;flex-shrink:0}
.fl-va{color:var(--d);font-size:.8rem;text-align:center;padding:2px 0}
.pipe{cursor:pointer;transition:transform .15s,box-shadow .15s}
.pipe:hover{transform:translateY(-2px);box-shadow:0 4px 20px rgba(0,0,0,.3)}
@media(max-width:768px){.sr{gap:10px}.stat .v{font-size:1rem}table{font-size:.65rem}.pipes{grid-template-columns:1fr 1fr}}
</style>
<style>#wnav{display:none!important}</style></head>
<body><div id="wnav" style="display:none"><a href="/l99-saas.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">L99</a><a href="/admin-saas.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Admin</a><a href="/realtime-monitor.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Monitor</a><a href="/agents-goodjob.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Enterprise</a><a href="/sovereign-claude.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Sovereign</a><a href="/cyber-monitor.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Cyber</a></div>
<div class="hdr">
<div>
<h1>⚙ INFRASTRUCTURE CONTROL — ALL SERVERS</h1>
<div class="hdr-sub">WEVADS Blade v4 · Crons + Docker + Services + Agents + Brain Engine · 19 Pipelines · UO/Jour</div>
</div>
<div class="sr">
<div class="stat pu"><div class="v" id="totAll">0</div><div class="l">Total Items</div></div>
<div class="stat ok"><div class="v" id="totCrons">0</div><div class="l">Crons</div></div>
<div class="stat cy"><div class="v" id="totDocker">0</div><div class="l">Docker</div></div>
<div class="stat"><div class="v" id="totSvc">0</div><div class="l">Services</div></div>
<div class="stat wa"><div class="v" id="totStandby">0</div><div class="l">Standby</div></div>
<div class="stat"><div class="v">3+1</div><div class="l">Servers</div></div>
</div>
</div>
<!-- PIPELINES -->
<div class="stit">📊 PIPELINES — Unité d'Œuvre / Jour</div>
<div class="pipes">
<div class="pipe pe"><div class="pn2" onclick="openDd('ethica')">💊 Ethica HCP</div><div class="pst">
<div class="ps2"><div class="pv">135K</div><div class="pl">HCPs</div></div>
<div class="ps2"><div class="pv">~15K</div><div class="pl">Scraped/J</div></div>
<div class="ps2"><div class="pv">~1.3K</div><div class="pl">Enriched/J</div></div>
<div class="ps2"><div class="pv">17</div><div class="pl">Crons</div></div>
</div></div>
<div class="pipe pb"><div class="pn2" onclick="openDd('b2b')">🏢 B2B Leads</div><div class="pst">
<div class="ps2"><div class="pv">1K+</div><div class="pl">Leads</div></div>
<div class="ps2"><div class="pv">~1.5K</div><div class="pl">Actions/J</div></div>
<div class="ps2"><div class="pv">~500</div><div class="pl">Profiles/J</div></div>
<div class="ps2"><div class="pv">6</div><div class="pl">Crons</div></div>
</div></div>
<div class="pipe pbe"><div class="pn2" onclick="openDd('brain')">🧪 Brain Engine</div><div class="pst">
<div class="ps2"><div class="pv">366</div><div class="pl">Configs</div></div>
<div class="ps2"><div class="pv">10</div><div class="pl">Winners</div></div>
<div class="ps2"><div class="pv">20</div><div class="pl">SMTP</div></div>
<div class="ps2"><div class="pv">O365</div><div class="pl">Method</div></div>
</div></div>
<div class="pipe pi"><div class="pn2" onclick="openDd('infra')">🛡 Infra & Sécurité</div><div class="pst">
<div class="ps2"><div class="pv">864+</div><div class="pl">Checks/J</div></div>
<div class="ps2"><div class="pv">144</div><div class="pl">Repairs/J</div></div>
<div class="ps2"><div class="pv">16</div><div class="pl">Docker</div></div>
<div class="ps2"><div class="pv">2</div><div class="pl">WAF</div></div>
</div></div>
<div class="pipe pw"><div class="pn2" onclick="openDd('wevia')">🧠 WEVIA IA</div><div class="pst">
<div class="ps2"><div class="pv">48</div><div class="pl">Dreams/J</div></div>
<div class="ps2"><div class="pv">67</div><div class="pl">AIs Bench</div></div>
<div class="ps2"><div class="pv">~50</div><div class="pl">Patterns/J</div></div>
<div class="ps2"><div class="pv">2.5K</div><div class="pl">KB Entries</div></div>
</div></div>
<div class="pipe pd"><div class="pn2" onclick="openDd('wevia')">📡 Data & OSS</div><div class="pst">
<div class="ps2"><div class="pv">~40</div><div class="pl">Repos/J</div></div>
<div class="ps2"><div class="pv">~20</div><div class="pl">Trending</div></div>
<div class="ps2"><div class="pv">~10</div><div class="pl">Gaps</div></div>
<div class="ps2"><div class="pv">~5</div><div class="pl">Improve</div></div>
</div></div>
<div class="pipe pn"><div class="pn2" onclick="openDd('nonreg')">🧪 NonReg & QA</div><div class="pst">
<div class="ps2"><div class="pv">776</div><div class="pl">Tests/J</div></div>
<div class="ps2"><div class="pv">2</div><div class="pl">6sigma/J</div></div>
<div class="ps2"><div class="pv">86</div><div class="pl">Baselines/S</div></div>
<div class="ps2"><div class="pv">1</div><div class="pl">Nuclei/S</div></div>
</div></div>
<div class="pipe ps"><div class="pn2" onclick="openDd('send')">📧 Send Engine (STANDBY)</div><div class="pst">
<div class="ps2"><div class="pv">366</div><div class="pl">Configs</div></div>
<div class="ps2"><div class="pv">10</div><div class="pl">Winners</div></div>
<div class="ps2"><div class="pv">PMTA</div><div class="pl">MTA</div></div>
<div class="ps2"><div class="pv">5</div><div class="pl">Standby</div></div>
</div></div>
<div class="pipe pm"><div class="pn2" onclick="openDd('monitoring')">📈 Monitoring Stack</div><div class="pst">
<div class="ps2"><div class="pv">Plausible</div><div class="pl">Analytics</div></div>
<div class="ps2"><div class="pv">Kuma</div><div class="pl">Uptime</div></div>
<div class="ps2"><div class="pv">Loki</div><div class="pl">Logs</div></div>
<div class="ps2"><div class="pv">n8n</div><div class="pl">Workflows</div></div>
</div></div>
<div class="pipe pw"><div class="pn2" onclick="openDd('wedroid')">🤖 WeDroid Agent (S204)</div><div class="pst">
<div class="ps2"><div class="pv">1029</div><div class="pl">Lines</div></div>
<div class="ps2"><div class="pv">8</div><div class="pl">Modules</div></div>
<div class="ps2"><div class="pv">AI</div><div class="pl">Brain</div></div>
<div class="ps2"><div class="pv">TG</div><div class="pl">Alerts</div></div>
</div></div>
<div class="pipe pi"><div class="pn2" onclick="openDd('sentinel')">🛰 Sentinel Pipeline (S95)</div><div class="pst">
<div class="ps2"><div class="pv">v5</div><div class="pl">Engine</div></div>
<div class="ps2"><div class="pv">344</div><div class="pl">APIs</div></div>
<div class="ps2"><div class="pv">Vault</div><div class="pl">Secrets</div></div>
<div class="ps2"><div class="pv">Always</div><div class="pl">On</div></div>
</div></div>
<div class="pipe pbe"><div class="pn2" onclick="openDd('hamid')">🔥 Hamid Engine (S95)</div><div class="pst">
<div class="ps2"><div class="pv">9</div><div class="pl">Modules</div></div>
<div class="ps2"><div class="pv">Chef</div><div class="pl">Optimizer</div></div>
<div class="ps2"><div class="pv">IA</div><div class="pl">Brain</div></div>
<div class="ps2"><div class="pv">API</div><div class="pl">Gateway</div></div>
</div></div>
<div class="pipe ps"><div class="pn2" onclick="openDd('send')">⚡ Send Factory (S95)</div><div class="pst">
<div class="ps2"><div class="pv">8</div><div class="pl">Engines</div></div>
<div class="ps2"><div class="pv">Smart</div><div class="pl">Send</div></div>
<div class="ps2"><div class="pv">Predict</div><div class="pl">ive</div></div>
<div class="ps2"><div class="pv">PMTA</div><div class="pl">+Kumo</div></div>
</div></div>
<div class="pipe pe"><div class="pn2" onclick="openDd('ethica')">💊 Ethica API Layer (S204)</div><div class="pst">
<div class="ps2"><div class="pv">12</div><div class="pl">APIs</div></div>
<div class="ps2"><div class="pv">SMS</div><div class="pl">Engine</div></div>
<div class="ps2"><div class="pv">WA</div><div class="pl">Bot</div></div>
<div class="ps2"><div class="pv">Stripe</div><div class="pl">Pay</div></div>
</div></div>
<div class="pipe pm"><div class="pn2" onclick="openDd('monitoring')">🏥 Health Monitor Grid</div><div class="pst">
<div class="ps2"><div class="pv">9</div><div class="pl">Endpoints</div></div>
<div class="ps2"><div class="pv">143</div><div class="pl">S204 APIs</div></div>
<div class="ps2"><div class="pv">344</div><div class="pl">S95 APIs</div></div>
<div class="ps2"><div class="pv">CRM</div><div class="pl">Twenty</div></div>
</div></div>
<div class="pipe" style="border-left-color:#818cf8"><div class="pn2" onclick="openDd('wevia')">🧬 Cognitive Brain (S204)</div><div class="pst">
<div class="ps2"><div class="pv" style="color:#818cf8">7</div><div class="pl">Cognitive</div></div>
<div class="ps2"><div class="pv" style="color:#818cf8">4</div><div class="pl">Consensus</div></div>
<div class="ps2"><div class="pv" style="color:#818cf8">MoA</div><div class="pl">Method</div></div>
<div class="ps2"><div class="pv" style="color:#818cf8">GPU</div><div class="pl">Rotation</div></div>
</div></div>
<div class="pipe" style="border-left-color:#ef4444"><div class="pn2" onclick="openDd('sentinel')">🔪 Blade Razer (10X64-PRO)</div><div class="pst">
<div class="ps2"><div class="pv" style="color:#ef4444">v2.1</div><div class="pl">Agent</div></div>
<div class="ps2"><div class="pv" style="color:#ef4444">50+</div><div class="pl">Actions</div></div>
<div class="ps2"><div class="pv" style="color:#ef4444">30s</div><div class="pl">Poll</div></div>
<div class="ps2"><div class="pv" style="color:#ef4444">58d</div><div class="pl">Uptime</div></div>
</div></div>
<div class="pipe" style="border-left-color:#818cf8"><div class="pn2" onclick="openDd('monitoring')">🔗 n8n Automation</div><div class="pst">
<div class="ps2"><div class="pv" style="color:#818cf8">0</div><div class="pl">Workflows</div></div>
<div class="ps2"><div class="pv" style="color:#818cf8">OK</div><div class="pl">Status</div></div>
<div class="ps2"><div class="pv" style="color:#818cf8">:5678</div><div class="pl">Port</div></div>
<div class="ps2"><div class="pv" style="color:#818cf8">API</div><div class="pl">Enabled</div></div>
</div></div>
</div>
<div class="tabs">
<button class="tab active" data-f="all" onclick="ft(this)">ALL <span class="cnt" id="c-all">0</span></button>
<button class="tab" data-f="s204" onclick="ft(this)">S204 Primary <span class="cnt" id="c-s204">0</span></button>
<button class="tab" data-f="s95" onclick="ft(this)">S95 WEVADS <span class="cnt" id="c-s95">0</span></button>
<button class="tab" data-f="s151" onclick="ft(this)">S151 DR <span class="cnt" id="c-s151">0</span></button>
<button class="tab" data-f="blade" onclick="ft(this)">🔪 Blade Razer</button>
<button class="tab" data-f="cron" onclick="ft(this)">⏱ Crons</button>
<button class="tab" data-f="docker" onclick="ft(this)">🐳 Docker</button>
<button class="tab" data-f="service" onclick="ft(this)">⚡ Services</button>
</div>
<div class="leg">
<span><span class="st st-a"></span> Active</span>
<span><span class="st st-s"></span> Standby</span>
<span><span class="st st-d"></span> Disabled</span>
<span><span class="type-badge tb-cron">CRON</span> Tâches planifiées</span>
<span><span class="type-badge tb-docker">DOCKER</span> Conteneurs</span>
<span><span class="type-badge tb-svc">SVC</span> Services systemd</span>
</div>
<div id="grid" class="grid"></div>
<div class="ft">WEVAL Blade v4.0 · Scan complet 3 serveurs · Crons + Docker + Systemd + Brain · <span id="rt"></span></div>
<script>
const D = [
// ══════════ S204 ROOT CRONTAB (2) ══════════
{t:'cron',s:'*/30 * * * *',c:'wevia-dream-cron.php',sv:'s204',u:'root',uo:'48 rêves/jour',k:'WEVIA Dream Engine — génération patterns IA'},
{t:'cron',s:'0 3 * * *',c:'deer-flow/thread-cleanup.sh',sv:'s204',u:'root',uo:'~50 threads',k:'Nettoyage threads DeerFlow expirés >7j'},
// ══════════ S204 WWW-DATA CRONTAB (27) ══════════
{t:'cron',s:'0 1,7,13,19 * * *',c:'weval-b2b-cron.sh',sv:'s204',u:'www',uo:'~200 leads/j',k:'Pipeline B2B : scraping + enrichissement 4x/j'},
{t:'cron',s:'0 18 * * *',c:'nonreg-master.py (soir)',sv:'s204',u:'www',uo:'250 tests',k:'NonReg master soir : toutes routes'},
{t:'cron',s:'0 18 * * *',c:'nonreg-daily.py (soir)',sv:'s204',u:'www',uo:'138 checks',k:'Checks quotidiens soir CSS/JS/API'},
{t:'cron',s:'0 */2 * * *',c:'wevia-autolearn.py',sv:'s204',u:'www',uo:'~50 patterns/j',k:'Auto-apprentissage WEVIA 12x/j'},
{t:'cron',s:'0 3 * * 0',c:'baselines.js (weekly)',sv:'s204',u:'www',uo:'86 screenshots/sem',k:'Captures visuelles baseline NonReg'},
{t:'cron',s:'0 3 * * 0',c:'ethica-enrich-searxng.py',sv:'s204',u:'www',uo:'200 HCPs/sem',k:'Enrichissement SearXNG hebdo Ethica'},
{t:'cron',s:'0 4 * * *',c:'oss-discovery.php auto_run',sv:'s204',u:'www',uo:'~40 repos/j',k:'Découverte repos OSS pertinents'},
{t:'cron',s:'0 */4 * * *',c:'auto-delist.sh',sv:'s204',u:'www',uo:'~5 delists/j',k:'Delist IPs blacklistées 6x/j'},
{t:'cron',s:'0 4 * * *',c:'cron_claude_sync.sh',sv:'s204',u:'www',uo:'~3 transcripts',k:'Sync transcripts Claude → wevia_db'},
{t:'cron',s:'0 5 * * *',c:'ai-benchmark-daily.sh',sv:'s204',u:'www',uo:'67 AIs testés',k:'Benchmark 67 providers IA (latence+qualité)'},
{t:'cron',s:'0 5 * * *',c:'ethica-autonomous.sh',sv:'s204',u:'www',uo:'~500 HCPs',k:'Pipeline autonome Ethica S204'},
{t:'cron',s:'0 6 * * *',c:'nonreg-master.py (matin)',sv:'s204',u:'www',uo:'250 tests',k:'NonReg master matin'},
{t:'cron',s:'0 */6 * * *',c:'disk-monitor.sh',sv:'s204',u:'www',uo:'4 alertes',k:'Monitoring disque alerte >85%'},
{t:'cron',s:'0 6 * * *',c:'seo-ping.sh',sv:'s204',u:'www',uo:'~15 URLs',k:'Ping Google/Bing sitemap indexation'},
{t:'cron',s:'0 6 * * *',c:'nonreg-daily.py (matin)',sv:'s204',u:'www',uo:'138 checks',k:'Checks quotidiens matin'},
{t:'cron',s:'0 7,19 * * *',c:'sso-nonreg.js',sv:'s204',u:'www',uo:'2 tests SSO',k:'Test Authentik SSO health 2x/j'},
{t:'cron',s:'0 7 * * *',c:'wevialife-cron.sh',sv:'s204',u:'www',uo:'~30 emails',k:'WEVIA LIFE : classification IMAP S95'},
{t:'cron',s:'0 7 * * *',c:'weval-daily-brief.py',sv:'s204',u:'www',uo:'1 brief/j',k:'Brief quotidien IA : résumé ops+alertes'},
{t:'cron',s:'10 4 * * *',c:'oss-trending-gen.py',sv:'s204',u:'www',uo:'~20 trending',k:'Trending repos OSS du jour'},
{t:'cron',s:'30 5 * * *',c:'ai-gap-discovery.py',sv:'s204',u:'www',uo:'~10 gaps',k:'Gaps couverture IA WEVIA'},
{t:'cron',s:'30 6 * * *',c:'ai-improvement-engine.py',sv:'s204',u:'www',uo:'~5 améliorations',k:'Propositions amélioration IA auto'},
{t:'cron',s:'*/5 * * * *',c:'infra-guardian.sh',sv:'s204',u:'www',uo:'288 checks/j',k:'Guardian : chattr+MD5+Docker health'},
{t:'cron',s:'*/5 * * * *',c:'weval-sso-health.sh',sv:'s204',u:'www',uo:'288 pings/j',k:'Ping SSO Authentik + restart si down'},
{t:'cron',s:'@reboot',c:'wevia-embed-service.py :11434',sv:'s204',u:'www',uo:'Always-on',k:'Embedding vectoriel WEVIA (Qdrant)'},
{t:'cron',s:'30 7,19 * * *',c:'6sigma-auth-nonreg.js',sv:'s204',u:'www',uo:'2 matrices/j',k:'Test 6-Sigma matrice auth complète'},
{t:'cron',s:'0 3 * * *',c:'deer-flow cleanup -mtime +7',sv:'s204',u:'www',uo:'~20 fichiers',k:'Nettoyage DeerFlow expirés'},
// ══════════ S204 /etc/cron.d (11 NEW) ══════════
{t:'cron',s:'0 */6 * * *',c:'crm-sequences (CRM Pipeline)',sv:'s204',u:'cron.d',uo:'4 runs/j',k:'Exécution séquences CRM Twenty outbound'},
{t:'cron',s:'0 5 * * *',c:'ethica-enrich-v4.py all',sv:'s204',u:'cron.d',uo:'~1000 enrichis',k:'Enrichissement Ethica v4 multi-sources'},
{t:'cron',s:'30 */6 * * *',c:'ethica-richscraper.py all',sv:'s204',u:'cron.d',uo:'~800 HCPs 4x/j',k:'RichScraper Google-verified profiles'},
{t:'cron',s:'0 3 * * *',c:'ethica-cron-scraper.py all',sv:'s204',u:'cron.d',uo:'~2000 HCPs/nuit',k:'Scraper nightly toutes sources'},
{t:'cron',s:'0 */6 * * *',c:'ethica-cron-scraper.py enrich',sv:'s204',u:'cron.d',uo:'~500 enrichis 4x',k:'Enrichissement scraper 4x/j'},
{t:'cron',s:'0 4 * * *',c:'ethica-validator.php (S204)',sv:'s204',u:'cron.d',uo:'~500 validés',k:'Validation emails/tels sur S204'},
{t:'cron',s:'0 9 * * *',c:'github-pat-reminder (check)',sv:'s204',u:'cron.d',uo:'1 check/j',k:'Alerte si PAT GitHub expire bientôt'},
{t:'cron',s:'0 6 * * *',c:'nonreg-daily.sh (cron.d)',sv:'s204',u:'cron.d',uo:'138 checks',k:'NonReg daily via cron.d'},
{t:'cron',s:'0 3 * * 0',c:'nuclei-scan.sh (weekly)',sv:'s204',u:'cron.d',uo:'1 scan/sem',k:'Scan sécurité Nuclei hebdo all endpoints'},
{t:'cron',s:'0 3 * * *',c:'pg_dump → S151 (DR backup)',sv:'s204',u:'cron.d',uo:'1 backup DR',k:'Backup PostgreSQL vers S151 OVH DR'},
{t:'cron',s:'0 3 * * 1',c:'opensource-discovery.php',sv:'s204',u:'cron.d',uo:'~30 repos/sem',k:'Discovery OSS hebdo Monday'},
{t:'cron',s:'*/30 * * * *',c:'php-cleanup.sh',sv:'s204',u:'cron.d',uo:'48 cleanups/j',k:'Nettoyage sessions PHP + tmp'},
// ══════════ S204 DOCKER (16) ══════════
{t:'docker',s:'—',c:'authentik-server (SSO)',sv:'s204',u:'docker',uo:'Always-on',k:'Authentik SSO — Forward Auth port 9543'},
{t:'docker',s:'—',c:'authentik-worker',sv:'s204',u:'docker',uo:'Always-on',k:'Authentik background worker'},
{t:'docker',s:'—',c:'authentik-db (PG 16)',sv:'s204',u:'docker',uo:'Always-on',k:'PostgreSQL Authentik SSO data'},
{t:'docker',s:'—',c:'authentik-redis',sv:'s204',u:'docker',uo:'Always-on',k:'Redis cache Authentik sessions'},
{t:'docker',s:'—',c:'twenty (CRM)',sv:'s204',u:'docker',uo:'Always-on',k:'Twenty CRM — crm.weval-consulting.com'},
{t:'docker',s:'—',c:'twenty-redis',sv:'s204',u:'docker',uo:'Always-on',k:'Redis cache Twenty CRM'},
{t:'docker',s:'—',c:'plausible (Analytics)',sv:'s204',u:'docker',uo:'Always-on',k:'Plausible Analytics :8787'},
{t:'docker',s:'—',c:'plausible-db (PG 16)',sv:'s204',u:'docker',uo:'Always-on',k:'PostgreSQL Plausible data'},
{t:'docker',s:'—',c:'plausible-events (ClickHouse)',sv:'s204',u:'docker',uo:'Always-on',k:'ClickHouse events ingestion'},
{t:'docker',s:'—',c:'searxng (Search)',sv:'s204',u:'docker',uo:'Always-on',k:'SearXNG méta-moteur sovereign'},
{t:'docker',s:'—',c:'uptime-kuma (Monitoring)',sv:'s204',u:'docker',uo:'Always-on',k:'Uptime Kuma :3088 — 50+ monitors'},
{t:'docker',s:'—',c:'mattermost (Chat)',sv:'s204',u:'docker',uo:'Always-on',k:'Mattermost team chat'},
{t:'docker',s:'—',c:'loki (Logs)',sv:'s204',u:'docker',uo:'Always-on',k:'Grafana Loki log aggregation'},
{t:'docker',s:'—',c:'vaultwarden (Secrets)',sv:'s204',u:'docker',uo:'Always-on',k:'Vaultwarden secrets + passwords'},
{t:'docker',s:'—',c:'qdrant (Vectors)',sv:'s204',u:'docker',uo:'Always-on',k:'Qdrant vector DB pour WEVIA embeddings'},
// ══════════ S204 SYSTEMD SERVICES (8 key) ══════════
{t:'service',s:'—',c:'nginx (Reverse Proxy)',sv:'s204',u:'systemd',uo:'Always-on',k:'Nginx RP — SSL termination + auth'},
{t:'service',s:'—',c:'php8.5-fpm + 8.4 + 7.4',sv:'s204',u:'systemd',uo:'Always-on',k:'PHP-FPM multi-version pool'},
{t:'service',s:'—',c:'postgresql@16-main',sv:'s204',u:'systemd',uo:'Always-on',k:'PostgreSQL 16 — wevia_db, local data'},
{t:'service',s:'—',c:'ollama (LLM local)',sv:'s204',u:'systemd',uo:'Always-on',k:'Ollama LLM server — qwen/mistral local'},
{t:'service',s:'—',c:'crowdsec + firewall-bouncer',sv:'s204',u:'systemd',uo:'Always-on',k:'CrowdSec WAF + IP bouncer'},
{t:'service',s:'—',c:'fail2ban',sv:'s204',u:'systemd',uo:'Always-on',k:'Fail2Ban brute-force protection'},
{t:'service',s:'—',c:'deerflow + deerflow-web',sv:'s204',u:'systemd',uo:'Always-on',k:'DeerFlow SuperAgent + Next.js :3002'},
{t:'service',s:'—',c:'pmta (MTA)',sv:'s204',u:'systemd',uo:'Always-on',k:'PMTA mail transfer agent'},
// ══════════ S204 /etc/cron.d SYSTEM (3) ══════════
{t:'cron',s:'0 */12 * * *',c:'certbot renew (S204)',sv:'s204',u:'cron.d',uo:'2 checks/j',k:'Renouvellement SSL automatique S204'},
{t:'cron',s:'*/1 * * * *',c:'fixmmdc (mermaid renderer)',sv:'s204',u:'cron.d',uo:'1440 runs/j',k:'Fix mermaid CLI renderer /tmp/go.sh'},
{t:'cron',s:'* * * * *',c:'mega-install (temp)',sv:'s204',u:'cron.d',uo:'1440 runs/j',k:'Script installation temporaire /tmp/mega.sh'},
// ══════════ S95 ROOT CRONTAB (9) ══════════
{t:'cron',s:'*/15 * * * *',c:'cron-sequences.php',sv:'s95',u:'root',uo:'96 runs/j',k:'Séquences email WEVADS',sb:1},
{t:'cron',s:'*/30 * * * *',c:'ethica-validator.php 500',sv:'s95',u:'root',uo:'24K validés/j',k:'Validation batch 500 toutes 30min'},
{t:'cron',s:'0 */4 * * *',c:'cron-bounces.php',sv:'s95',u:'root',uo:'6 checks/j',k:'Traitement bounces PMTA',sb:1},
{t:'cron',s:'0 3 * * *',c:'daily_backup.sh',sv:'s95',u:'root',uo:'1 backup/j',k:'Backup complet PG + configs'},
{t:'cron',s:'0 4 * * *',c:'auto-backup-github.sh',sv:'s95',u:'root',uo:'1 push/j',k:'Git push auto GitHub'},
{t:'cron',s:'0 6 * * *',c:'cron-warmup.php',sv:'s95',u:'root',uo:'0 (standby)',k:'Warmup IPs antispam',sb:1},
{t:'cron',s:'30 0 * * *',c:'daily-stats-aggregate.php',sv:'s95',u:'root',uo:'366 configs',k:'Agrégation stats WEVADS quotidien'},
{t:'cron',s:'30 1 * * *',c:'cron-engagement.php',sv:'s95',u:'root',uo:'0 (standby)',k:'Engagement tracking',sb:1},
{t:'cron',s:'@reboot',c:'pmta start',sv:'s95',u:'root',uo:'1 service',k:'Démarrage PMTA au boot',sb:1},
// ══════════ S95 ETHICA-AUTONOMOUS (14) ══════════
{t:'cron',s:'0 5 * * *',c:'ethica-master.py',sv:'s95',u:'cron.d',uo:'1 pipeline/j',k:'Pipeline maître : health+dedup+enrich+quality'},
{t:'cron',s:'0 2 * * *',c:'ethica-deep-scraper.py 1sante 5000',sv:'s95',u:'cron.d',uo:'~5000 HCPs/nuit',k:'Deep crawl 1sante.com 25 spécialités'},
{t:'cron',s:'*/20 * * * *',c:'ethica-linkedin-drip.py',sv:'s95',u:'cron.d',uo:'~100 profils/j',k:'LinkedIn drip via SearXNG slow-rate'},
{t:'cron',s:'*/5 * * * *',c:'ethica-email-drip.py 20',sv:'s95',u:'cron.d',uo:'~5760 tentatives/j',k:'Enrichissement email micro-batch continu'},
{t:'cron',s:'0 6 * * *',c:'ethica-ville-enricher.py 500',sv:'s95',u:'cron.d',uo:'500 villes/j',k:'Enrichissement ville depuis profils'},
{t:'cron',s:'30 3 * * *',c:'ethica-dabadoc-scraper.py ma 5000',sv:'s95',u:'cron.d',uo:'~5000 MA/nuit',k:'Scraping DabaDoc Maroc'},
{t:'cron',s:'0 4 * * *',c:'ethica-dabadoc-scraper.py tn 5000',sv:'s95',u:'cron.d',uo:'~5000 TN/nuit',k:'Scraping DabaDoc Tunisie'},
{t:'cron',s:'30 6 * * *',c:'ethica-dabadoc-enrich.py 1000',sv:'s95',u:'cron.d',uo:'~1000 profils',k:'Enrichissement tel DabaDoc'},
{t:'cron',s:'0 7 * * *',c:'ethica-gmap-scraper.py 200 ma',sv:'s95',u:'cron.d',uo:'200 HCPs MA',k:'Google Maps scraper Maroc'},
{t:'cron',s:'30 7 * * *',c:'ethica-gmap-scraper.py 200 tn',sv:'s95',u:'cron.d',uo:'200 HCPs TN',k:'Google Maps scraper Tunisie'},
{t:'cron',s:'30 3,9,15,21 * * *',c:'ethica-enricher-autonomous.sh',sv:'s95',u:'cron.d',uo:'~800 emails 4x/j',k:'Enrichissement email autonome multi-pays'},
{t:'cron',s:'0 8 * * *',c:'ethica-email-enricher.py 500 DZ',sv:'s95',u:'cron.d',uo:'500 DZ emails',k:'Email enricher ciblé Algérie'},
{t:'cron',s:'30 8 * * *',c:'ethica-email-enricher.py 500 MA',sv:'s95',u:'cron.d',uo:'500 MA emails',k:'Email enricher ciblé Maroc'},
{t:'cron',s:'0 9 * * *',c:'ethica-email-enricher.py 300 TN',sv:'s95',u:'cron.d',uo:'300 TN emails',k:'Email enricher ciblé Tunisie'},
// ══════════ S95 INFRA+B2B cron.d (10) ══════════
{t:'cron',s:'*/5 * * * *',c:'critical-files-guard.sh',sv:'s95',u:'cron.d',uo:'288 checks/j',k:'Guard fichiers critiques WEVADS'},
{t:'cron',s:'*/10 * * * *',c:'regression-auto-repair.sh',sv:'s95',u:'cron.d',uo:'144 repairs/j',k:'Auto-repair régression configs'},
{t:'cron',s:'0 6 * * *',c:'regression-guard.sh --check',sv:'s95',u:'cron.d',uo:'1 rapport/j',k:'Check complet régression quotidien'},
{t:'cron',s:'0 3 * * *',c:'backup-to-ovh.sh',sv:'s95',u:'cron.d',uo:'1 backup OVH',k:'Backup vers S151 OVH DR'},
{t:'cron',s:'@reboot',c:'PHP timeout fix',sv:'s95',u:'cron.d',uo:'1x boot',k:'Fix PHP 3600s + Apache MaxWorkers'},
{t:'cron',s:'0 2,6,10,14,18,22 * * *',c:'weval-b2b-autonomous.sh',sv:'s95',u:'cron.d',uo:'~300 leads/j',k:'Pipeline B2B autonome 6x/j'},
{t:'cron',s:'*/30 * * * *',c:'weval-linkedin-scraper.py 50',sv:'s95',u:'cron.d',uo:'~500 profils/j',k:'Scraping LinkedIn SearXNG 48x/j'},
{t:'cron',s:'0 */2 * * *',c:'weval-company-scraper.py 30',sv:'s95',u:'cron.d',uo:'~360 companies/j',k:'Scraping entreprises 12x/j'},
{t:'cron',s:'0 * * * *',c:'weval-lead-enricher.py 20',sv:'s95',u:'cron.d',uo:'~480 enrichis/j',k:'Enrichissement leads hourly'},
{t:'cron',s:'0 */3 * * *',c:'weval-lead-enricher.py 50',sv:'s95',u:'cron.d',uo:'~400 enrichis/j',k:'Enrichissement leads batch 8x/j'},
// ══════════ S95 DISABLED FILES (15 crons) ══════════
{t:'cron',s:'*/2 * * * *',c:'deliverads sync-engine.php',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'DeliverAds: sync toutes plates-formes',sb:1,dis:1},
{t:'cron',s:'*/5 * * * *',c:'deliverads ai-account-engine.php',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'DeliverAds: IA optimisation comptes',sb:1,dis:1},
{t:'cron',s:'*/15 * * * *',c:'deliverads orchestrator pipeline',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'DeliverAds: pipeline full orchestrator',sb:1,dis:1},
{t:'cron',s:'0 8 * * *',c:'deliverads daily report',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'DeliverAds: export rapport quotidien',sb:1,dis:1},
{t:'cron',s:'*/5 * * * *',c:'tracking-monitor.sh',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'Monitoring tracking pixels WEVADS',sb:1,dis:1},
{t:'cron',s:'*/5 * * * *',c:'weval-mind autonomous_cycle',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'WEVAL Mind: cycle autonome IA',sb:1,dis:1},
{t:'cron',s:'*/5 * * * *',c:'weval-mind-core-simple cycle',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'WEVAL Mind: cycle simplifié',sb:1,dis:1},
{t:'cron',s:'*/2 * * * *',c:'monitor-cycles-corrected.sh',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'WEVAL Mind: monitoring santé cycles',sb:1,dis:1},
{t:'cron',s:'0 8 * * *',c:'weval-mind daily report',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'WEVAL Mind: rapport quotidien JSON',sb:1,dis:1},
{t:'cron',s:'*/2 * * * *',c:'health-check-complete.sh',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'WEVAL Mind: health check infra complet',sb:1,dis:1},
{t:'cron',s:'0 3 * * *',c:'weval-mind log cleanup >30j',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'Nettoyage logs WEVADS >30 jours',sb:1,dis:1},
{t:'cron',s:'0 2 * * *',c:'pg_dump adx_system (mind)',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'Backup PG quotidien via WEVAL Mind',sb:1,dis:1},
{t:'cron',s:'0 * * * *',c:'hamid-engine providers monitor',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'Hamid Engine: monitoring providers hourly',sb:1,dis:1},
{t:'cron',s:'0 8 * * *',c:'api-gateway status report',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'API Gateway: rapport statut quotidien',sb:1,dis:1},
{t:'cron',s:'0 */4 * * *',c:'freedns CAPTCHA bot (VNC)',sv:'s95',u:'disabled',uo:'0 (disabled)',k:'FreeDNS V2 domain rotation (needs VNC)',sb:1,dis:1},
// ══════════ S95 SYSTEM (1) ══════════
{t:'cron',s:'0 */12 * * *',c:'certbot renew',sv:'s95',u:'cron.d',uo:'2 checks/j',k:'Renouvellement SSL auto'},
// ══════════ S95 SERVICES (6 key) ══════════
{t:'service',s:'—',c:'apache2 (Arsenal :5890)',sv:'s95',u:'systemd',uo:'Always-on',k:'Apache2 — Arsenal WEVADS + Sentinel'},
{t:'service',s:'—',c:'postgresql@13-main',sv:'s95',u:'systemd',uo:'Always-on',k:'PG13 — adx_system + adx_clients + ethica'},
{t:'service',s:'—',c:'pmta + kumomta (MTA)',sv:'s95',u:'systemd',uo:'Always-on',k:'PMTA + KumoMTA dual mail servers'},
{t:'service',s:'—',c:'ollama (LLM local)',sv:'s95',u:'systemd',uo:'Always-on',k:'Ollama LLM server local S95'},
{t:'service',s:'—',c:'crowdsec (WAF)',sv:'s95',u:'systemd',uo:'Always-on',k:'CrowdSec agent protection'},
{t:'service',s:'—',c:'adx-cache-cleaner',sv:'s95',u:'systemd',uo:'Always-on',k:'ADX cache cleaner service'},
// ══════════ S151 (2) ══════════
{t:'cron',s:'*/5 * * * *',c:'ollama keepalive (granite4)',sv:'s151',u:'cron',uo:'288 pings/j',k:'Keepalive Ollama granite4 model loaded'},
// ══════════ S204 WEVIA BRAIN AGENTS (8) ══════════
{t:'service',s:'—',c:'wevia-brain.php (Main Brain 5676L)',sv:'s204',u:'api',uo:'Always-on',k:'Cerveau WEVIA principal — multi-model, files, vision, voice'},
{t:'service',s:'—',c:'wevia-tools-router.php (25+ tools)',sv:'s204',u:'api',uo:'Always-on',k:'Routeur ToolFK: météo, calc, news, scrape, translate, etc.'},
{t:'service',s:'—',c:'wevia-capabilities.php + ext',sv:'s204',u:'api',uo:'Always-on',k:'Détection capacités dynamique + extensions'},
{t:'service',s:'—',c:'wevia-skills.php + skill-factory',sv:'s204',u:'api',uo:'Always-on',k:'Système skills WEVIA + factory de création'},
{t:'service',s:'—',c:'wevia-providers.php (Multi-AI)',sv:'s204',u:'api',uo:'Always-on',k:'Routing sovereign: Cerebras→Groq→SambaNova→Ollama'},
{t:'service',s:'—',c:'mcp.php (6 MCP tools)',sv:'s204',u:'api',uo:'Always-on',k:'Model Context Protocol — JSON-RPC, 6 outils'},
{t:'service',s:'—',c:'cx.php + droid.php (Execution)',sv:'s204',u:'api',uo:'Always-on',k:'CX (www-data) + Droid (sudo) — exécution commandes'},
{t:'service',s:'—',c:'claude-sync.php (Transcripts)',sv:'s204',u:'api',uo:'Always-on',k:'Sync transcripts Claude → wevia_db documents'},
// ══════════ S204 WEDROID AGENT (8 modules, 1029L) ══════════
{t:'service',s:'—',c:'wedroid-brain-api.php (685L)',sv:'s204',u:'agent',uo:'Always-on',k:'WeDroid cerveau IA — parsing tâches + routing'},
{t:'service',s:'—',c:'wedroid-chain-executor.php (131L)',sv:'s204',u:'agent',uo:'Always-on',k:'Exécution chaînes multi-étapes séquentielles'},
{t:'service',s:'—',c:'wedroid-git-auto.php (21L)',sv:'s204',u:'agent',uo:'Always-on',k:'Git commit/push automatique via agent'},
{t:'service',s:'—',c:'wedroid-infra-patterns.php (46L)',sv:'s204',u:'agent',uo:'Always-on',k:'Patterns infra réutilisables (17 Claude Code patterns)'},
{t:'service',s:'—',c:'wedroid-learning.php (39L)',sv:'s204',u:'agent',uo:'Always-on',k:'Auto-apprentissage depuis erreurs et succès'},
{t:'service',s:'—',c:'wedroid-scheduler.php (57L)',sv:'s204',u:'agent',uo:'Always-on',k:'Planificateur tâches différées et récurrentes'},
{t:'service',s:'—',c:'wedroid-telegram-alert.php (25L)',sv:'s204',u:'agent',uo:'Always-on',k:'Alertes Telegram pour événements critiques'},
{t:'service',s:'—',c:'wedroid-v4.php (25L)',sv:'s204',u:'agent',uo:'Always-on',k:'WeDroid v4 — interface principale agent'},
// ══════════ S204 COGNITIVE BRAIN (11 modules) ══════════
{t:'service',s:'—',c:'cognitive-brain.php (Main)',sv:'s204',u:'wevia-ia',uo:'Always-on',k:'Cerveau cognitif — raisonnement avancé multi-modèle'},
{t:'service',s:'—',c:'cognitive-opus46 pipeline (5 files)',sv:'s204',u:'wevia-ia',uo:'Always-on',k:'Pipeline Opus 4.6: standard + advanced + amplifier + mega + GPU rotation'},
{t:'service',s:'—',c:'consensus-engine.php (4 files)',sv:'s204',u:'wevia-ia',uo:'Always-on',k:'Self-MoA: consensus multi-modèle + local + v3'},
{t:'service',s:'—',c:'consulting-brain-sovereign.php',sv:'s204',u:'wevia-ia',uo:'Always-on',k:'Brain consulting personas spécialisés'},
// ══════════ S204 ETHICA API LAYER (12 endpoints) ══════════
{t:'service',s:'—',c:'ethica-api.php (Main)',sv:'s204',u:'api',uo:'Always-on',k:'API Ethica principale — stats, search, export'},
{t:'service',s:'—',c:'ethica-consent-api + campaign',sv:'s204',u:'api',uo:'Always-on',k:'Gestion consentement HCP (consent.wevup.app)'},
{t:'service',s:'—',c:'ethica-data-api + collector + feed',sv:'s204',u:'api',uo:'Always-on',k:'Collecte et flux données HCP'},
{t:'service',s:'—',c:'ethica-sms-api + whatsapp-api',sv:'s204',u:'api',uo:'Always-on',k:'Canaux SMS OVH + WhatsApp HCP'},
{t:'service',s:'—',c:'ethica-stripe-api (Paiement)',sv:'s204',u:'api',uo:'Always-on',k:'Stripe paiement abonnements Ethica'},
// ══════════ S204 NONREG PIPELINE (5 endpoints) ══════════
{t:'service',s:'—',c:'nonreg-api + master + opus + runner',sv:'s204',u:'api',uo:'Always-on',k:'Pipeline NonReg : API + master orchestrator + Opus validator + runner'},
{t:'service',s:'—',c:'nonreg-master-v8.php (Advanced)',sv:'s204',u:'api',uo:'Always-on',k:'NonReg v8 : 250+ tests, screenshots, JS validation'},
// ══════════ S204 HEALTH MONITORS (9 endpoints) ══════════
{t:'service',s:'—',c:'health-* (9 monitors)',sv:'s204',u:'api',uo:'Always-on',k:'Monitors: chatbot, CRM, Mattermost, n8n, Ollama, Plausible, Qdrant, SearXNG, Kuma'},
// ══════════ S204 CRM + PAYMENTS ══════════
{t:'service',s:'—',c:'crm-api.php + twenty-proxy',sv:'s204',u:'api',uo:'Always-on',k:'Twenty CRM API + proxy vers crm.weval-consulting.com'},
{t:'service',s:'—',c:'stripe-webhook + checkout',sv:'s204',u:'api',uo:'Always-on',k:'Stripe: webhook + checkout session + custom payment'},
{t:'service',s:'—',c:'whatsapp-api + webhook + setup',sv:'s204',u:'api',uo:'Always-on',k:'WhatsApp Business API integration'},
// ══════════ S204 OTHER AGENTS ══════════
{t:'service',s:'—',c:'goose-agent-api + mastra-agent',sv:'s204',u:'api',uo:'Always-on',k:'Agents IA tiers: Goose + Mastra integration'},
{t:'service',s:'—',c:'browser-use-api.php',sv:'s204',u:'api',uo:'Always-on',k:'Agent browser automation — navigation web autonome'},
{t:'service',s:'—',c:'openclaw-proxy + skills-api',sv:'s204',u:'api',uo:'Always-on',k:'Proxy OpenClaw S151 + API skills sovereign'},
{t:'service',s:'—',c:'infra-monitor-api + live-metrics',sv:'s204',u:'api',uo:'Always-on',k:'Dashboard infra temps réel + métriques live'},
{t:'service',s:'—',c:'sequence-engine + send-controller',sv:'s204',u:'api',uo:'Always-on',k:'Moteur séquences email + contrôleur envoi'},
{t:'service',s:'—',c:'hamid-api-proxy.php',sv:'s204',u:'api',uo:'Always-on',k:'Proxy vers Hamid Engine S95 (25 nginx locations)'},
// ══════════ S95 SENTINEL PIPELINE (5 modules) ══════════
{t:'service',s:'—',c:'sentinel-brain.php (Main)',sv:'s95',u:'api',uo:'Always-on',k:'Cerveau Sentinel — exécution, monitoring, orchestration'},
{t:'service',s:'—',c:'sentinel-engine + v5',sv:'s95',u:'api',uo:'Always-on',k:'Moteur Sentinel v5 — routing avancé multi-serveur'},
{t:'service',s:'—',c:'sentinel-vault + controller',sv:'s95',u:'api',uo:'Always-on',k:'Vault secrets Sentinel — credentials + tokens'},
// ══════════ S95 BRAIN ENGINE (15+ modules) ══════════
{t:'service',s:'—',c:'brain-core + engine + orchestrator',sv:'s95',u:'api',uo:'Always-on',k:'Brain Core: 366 configs, auto-rotation, quality testing'},
{t:'service',s:'—',c:'brain-creative-engine + optimizer',sv:'s95',u:'api',uo:'Always-on',k:'Moteur créatif: A/B test subjects + bodies + spamcheck'},
{t:'service',s:'—',c:'brain-trainer + autofix + analyze',sv:'s95',u:'api',uo:'Always-on',k:'Auto-apprentissage + auto-repair + analyse performance'},
{t:'service',s:'—',c:'brain-send + smart + unified + pmta',sv:'s95',u:'api',uo:'Always-on',k:'Send multi-canal: smart routing, PMTA, productive, graph'},
{t:'service',s:'—',c:'brain-inject-api + config-inject',sv:'s95',u:'api',uo:'Always-on',k:'Injection configs + combos gagnants dans le pipeline'},
{t:'service',s:'—',c:'brain-tracking-seeds + combo',sv:'s95',u:'api',uo:'Always-on',k:'Seeds tracking + combinaisons winner discovery'},
// ══════════ S95 HAMID ENGINE (9 modules) ══════════
{t:'service',s:'—',c:'hamid-api + brain + ia',sv:'s95',u:'api',uo:'Always-on',k:'Hamid: API principale + cerveau IA + intelligence'},
{t:'service',s:'—',c:'hamid-chef + chef-simple + chef2',sv:'s95',u:'api',uo:'Always-on',k:'Hamid Chef: optimisation configs 3 versions'},
{t:'service',s:'—',c:'hamid-engine + simple + fixed',sv:'s95',u:'api',uo:'Always-on',k:'Hamid Engine: moteur principal + versions optimisées'},
// ══════════ S95 SEND FACTORY (8 orchestrators) ══════════
{t:'service',s:'—',c:'send-orchestrator + engine + factory',sv:'s95',u:'api',uo:'Always-on',k:'Orchestration envoi: factory + workflow + pipeline'},
{t:'service',s:'—',c:'semi-auto + predictive + warmup',sv:'s95',u:'api',uo:'Always-on',k:'Envoi semi-auto + prédictif + warmup engine'},
{t:'service',s:'—',c:'orchestrator-central + cloud + profit',sv:'s95',u:'api',uo:'Always-on',k:'Orchestrateurs: central + cloud + profit optimizer'},
// ══════════ S95 WEVAL MIND (disabled) ══════════
{t:'service',s:'—',c:'weval-mind-core + interface',sv:'s95',u:'api',uo:'DISABLED',k:'WEVAL Mind: IA autonome cycles + interface (désactivé)',sb:1},
// ══════════ S95 OTHER ENGINES ══════════
{t:'service',s:'—',c:'harvest-engine + lookalike-engine',sv:'s95',u:'api',uo:'Always-on',k:'Harvest: collecte leads + Lookalike: audiences similaires'},
{t:'service',s:'—',c:'offer-engine + pipeline-feeder',sv:'s95',u:'api',uo:'Always-on',k:'Moteur offres + alimenteur pipeline'},
{t:'service',s:'—',c:'api-gateway + gateway-light',sv:'s95',u:'api',uo:'Always-on',k:'API Gateway: routing intelligent requêtes'},
{t:'service',s:'—',c:'autonomous-engine.php',sv:'s95',u:'api',uo:'Always-on',k:'Moteur autonome: décisions sans intervention humaine'},
{t:'service',s:'—',c:'n8n-orchestrator.php',sv:'s95',u:'api',uo:'Always-on',k:'Bridge n8n: orchestration workflows via S95'},
{t:'service',s:'—',c:'sms-engine + stream-brain',sv:'s95',u:'api',uo:'Always-on',k:'Moteur SMS + Stream brain temps réel'},
// ══════════ S151 SERVICES (5) ══════════
{t:'cron',s:'*/5 * * * *',c:'tracking_monitor.sh',sv:'s151',u:'root',uo:'288 checks/j',k:'Monitoring tracking pixel status S151'},
{t:'service',s:'—',c:'nginx (Tracking RP)',sv:'s151',u:'systemd',uo:'Always-on',k:'Nginx reverse proxy tracking domains'},
{t:'service',s:'—',c:'php7.4-fpm',sv:'s151',u:'systemd',uo:'Always-on',k:'PHP-FPM pour tracking endpoints'},
{t:'service',s:'—',c:'postgresql@14-main',sv:'s151',u:'systemd',uo:'Always-on',k:'PG14 — DR replica adx_system'},
{t:'service',s:'—',c:'fail2ban',sv:'s151',u:'systemd',uo:'Always-on',k:'Fail2Ban protection brute-force S151'},
{t:'service',s:'—',c:'ollama (systemd)',sv:'s151',u:'systemd',uo:'Always-on',k:'Ollama systemd — modèles granite4 + qwen2.5'},
// ══════════ BLADE RAZER — Agent & APIs (S204 hosted) ══════════
{t:'service',s:'Poll 30s',c:'Sentinel Agent v2.2 (LAPTOP-VE75QUHF)',sv:'blade',u:'powershell',uo:'2880 polls/j',k:'Agent PS sur Razer Blade — exécute tasks + heartbeat 60s + git sync'},
{t:'service',s:'—',c:'blade-api.php (Task Queue)',sv:'blade',u:'api',uo:'Always-on',k:'API push/poll/report/heartbeat/list/clear — Key BLADE2026'},
{t:'service',s:'—',c:'blade-brain.php (AI Parser 30KB)',sv:'blade',u:'api',uo:'Always-on',k:'IA naturel → PowerShell : parse commandes, multi-provider AI routing'},
{t:'service',s:'—',c:'blade-ops-api.php (50+ actions)',sv:'blade',u:'api',uo:'Always-on',k:'Ops: health,disk,docker,nginx,exec,screenshot,browse,email,ethica,db,git,mta,cf,tg'},
{t:'service',s:'—',c:'blade-ai.html (Chat Controller)',sv:'blade',u:'ui',uo:'Always-on',k:'Interface chat IA pour commander le Blade en langage naturel'},
{t:'service',s:'—',c:'blade-mattermost.php (Notif)',sv:'blade',u:'api',uo:'Always-on',k:'Intégration Mattermost — notifications Blade → MM'},
{t:'service',s:'—',c:'blade-telegram.php (Bot TG)',sv:'blade',u:'api',uo:'Always-on',k:'Bot Telegram Blade — alertes + commandes via TG'},
{t:'service',s:'—',c:'sync-blade.bat (Git Sync)',sv:'blade',u:'script',uo:'On demand',k:'Sync Git weval-consulting + wevia-brain sur le Razer Blade'},
{t:'service',s:'0 3 * * *',c:'daily-sentinel.sh (Backup)',sv:'blade',u:'cron',uo:'1 backup/j',k:'DB dump + Docker status + Sentinel snapshot quotidien'},
{t:'service',s:'—',c:'blade-tasks/ (Queue Dir)',sv:'blade',u:'storage',uo:'~20 tasks/j',k:'Queue fichiers JSON tasks + screenshots 6sigma'},
// ══════════ n8n AUTOMATION (S204 Docker) ══════════
{t:'docker',s:'—',c:'n8n Engine (:5678)',sv:'s204',u:'docker',uo:'Always-on',k:'n8n workflow automation — API enabled, 0 workflows actifs'},
{t:'docker',s:'—',c:'ollama (LLM sovereign)',sv:'s151',u:'docker',uo:'Always-on',k:'Ollama Docker qwen2.5:3b + granite4 — 8GB'}
];
// ── Categorization ──
const CR = [
[['guardian','sso-health','disk-monitor','critical-files','regression','certbot','timeout','php-cleanup','nuclei'],['Infra','c-inf']],
[['sequences','bounce','warmup','pmta start','engagement'],['Send','c-send']],
[['ethica','validator','dabadoc','1sante','gmap-scraper','email-drip','email-enricher','ville-enricher','richscraper'],['Ethica','c-eth']],
[['backup','github','s151-backup','pg_dump','ovh'],['Backup','c-bak']],
[['nonreg','6sigma','baseline'],['NonReg','c-nr']],
[['wevia','dream','embed','autolearn','openclaw','ollama'],['WEVIA','c-wev']],
[['benchmark','brief','monitor','kuma','plausible','loki'],['Monitor','c-mon']],
[['b2b','lead-enricher','linkedin-scraper','company-scraper'],['B2B','c-b2b']],
[['scraper','enrich','discovery','gap','improvement','seo','oss','trending','deer','delist','claude_sync'],['Data','c-dat']],
[['crm','twenty','sequence'],['CRM','c-crm']],
[['authentik','sso','fail2ban','crowdsec','nginx','php8','php7'],['Infra','c-inf']],
[['n8n','mattermost','vaultwarden','qdrant','searxng'],['Platform','c-doc']],
[['apache','adx-cache','kumomta'],['Infra','c-inf']],
[['pat-reminder'],['Infra','c-inf']],
[['blade','sentinel agent','sync-blade'],['Blade','c-gen']]
];
function cat(cmd) {
const c = cmd.toLowerCase();
for (const [kw, r] of CR) { if (kw.some(k => c.includes(k))) return r; }
return ['General','c-gen'];
}
let items = D.map(d => {
const [cn, cc] = cat(d.c);
return { ...d, category: cn, catClass: cc, status: d.dis ? 'disabled' : d.sb ? 'standby' : 'active' };
});
function stats() {
const crons = items.filter(i => i.t === 'cron').length;
const docker = items.filter(i => i.t === 'docker').length;
const svcs = items.filter(i => i.t === 'service').length;
document.getElementById('totAll').textContent = items.length;
document.getElementById('totCrons').textContent = crons;
document.getElementById('totDocker').textContent = docker;
document.getElementById('totSvc').textContent = svcs;
document.getElementById('totStandby').textContent = items.filter(i => i.status === 'standby' || i.status === 'disabled').length;
document.getElementById('c-all').textContent = items.length;
document.getElementById('c-s204').textContent = items.filter(i => i.sv === 's204').length;
document.getElementById('c-s95').textContent = items.filter(i => i.sv === 's95').length;
document.getElementById('c-s151').textContent = items.filter(i => i.sv === 's151').length;
const bladeEl = document.getElementById('c-blade'); if(bladeEl) bladeEl.textContent = items.filter(i => i.sv === 'blade').length;
document.getElementById('rt').textContent = new Date().toLocaleString('fr-FR');
}
function render(filter) {
const grid = document.getElementById('grid');
let filtered = items;
if (['blade','s204','s95','s151'].includes(filter)) filtered = items.filter(i => i.sv === filter);
else if (['cron','docker','service'].includes(filter)) filtered = items.filter(i => i.t === filter);
const sn = {blade:'🔪 BLADE RAZER — 10X64-PRO (195.74.76.209)',s204:'S204 — Primary (204.168.152.13)',s95:'S95 — WEVADS (95.216.167.89)',s151:'S151 — Tracking+DR (151.80.235.110)'};
const g = {};
filtered.forEach(i => { if (!g[i.sv]) g[i.sv] = []; g[i.sv].push(i); });
let h = '';
for (const sv of ['blade','s204','s95','s151']) {
if (!g[sv]) continue;
const a = g[sv].filter(i => i.status === 'active').length;
const sb = g[sv].filter(i => i.status === 'standby').length;
const dc = g[sv].filter(i => i.t === 'docker').length;
const sc = g[sv].filter(i => i.t === 'service').length;
const cr = g[sv].filter(i => i.t === 'cron').length;
h += `<div class="srv"><div class="srv-h">
<span class="srv-n">${sn[sv]}</span>
<span class="srv-i">${g[sv].length} items · ${cr} crons · ${dc} docker · ${sc} services · ${a} active · ${sb} standby</span>
</div><table><thead><tr>
<th style="width:30px"></th><th style="width:45px">Type</th><th style="width:60px">Cat.</th><th style="width:110px">Schedule</th><th>Commande</th><th style="width:45px">User</th><th style="width:110px">UO/Jour</th><th>Description</th>
</tr></thead><tbody>`;
g[sv].sort((a,b) => {
const to = {cron:0,docker:1,service:2};
if (a.status !== b.status) return a.status === 'active' ? -1 : 1;
if (to[a.t] !== to[b.t]) return to[a.t] - to[b.t];
return a.category.localeCompare(b.category);
});
g[sv].forEach(i => {
const stC = i.status === 'disabled' ? 'st-d' : i.status === 'standby' ? 'st-s' : 'st-a';
const tb = i.t === 'docker' ? 'tb-docker' : i.t === 'service' ? 'tb-svc' : 'tb-cron';
const tl = i.t === 'docker' ? 'DOCKER' : i.t === 'service' ? 'SVC' : 'CRON';
h += `<tr>
<td><span class="st ${stC}"></span></td>
<td><span class="type-badge ${tb}">${tl}</span></td>
<td><span class="cat ${i.catClass}">${i.category}</span></td>
<td class="sc">${i.s}</td>
<td class="cm">${i.c}</td>
<td>${i.u}</td>
<td class="uo">${i.uo || '—'}</td>
<td class="kp">${i.k || '—'}</td>
</tr>`;
});
h += '</tbody></table></div>';
}
grid.innerHTML = h;
}
function ft(el) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
el.classList.add('active');
render(el.dataset.f);
}
// ═══ PIPELINE DRILL-DOWN ═══
const PIPELINES = {
ethica: {
title: '💊 Ethica HCP Pipeline — Flux Transactionnel Temps Réel',
kpis: [
{v:'135,271',l:'HCPs Total',c:'var(--cy)'},
{v:'107,752',l:'Emails 79.7%',c:'var(--g)',c:'var(--g)'},
{v:'129,290',l:'Tels 95.6%',c:'var(--g)',c:'var(--g)'},
{v:'17',l:'Crons',c:'var(--bl)'},
{v:'~15K',l:'IN/Jour',c:'var(--or)'},
{v:'~7K',l:'Enriched/J',c:'var(--or)'}
],
sections: [
{title:'📥 SOURCES → Scraping brut',flow:'IN: URLs web → OUT: HCPs bruts (nom,spécialité,ville)',nodes:[
{n:'1sante deep-scraper',u:'5,008 last run',d:'Crawl 25 spécialités DZ',t:'ns',st:'ok',io:'IN: 25 URLs spécialités → OUT: ~5000 HCPs bruts/nuit'},
{a:'→'},
{n:'DabaDoc MA',u:'4316 ✅ COMPLET',d:'Profils médecins Maroc',t:'ns',st:'ok',io:'IN: pages dabadoc.ma → OUT: 4316 HCPs scrapés (source épuisée)'},
{a:'→'},
{n:'DabaDoc TN',u:'2606 ✅ COMPLET',d:'Profils médecins Tunisie',t:'ns',st:'ok',io:'IN: pages dabadoc.tn → OUT: 2606 HCPs scrapés (source épuisée)'},
]},
{title:'',flow:'',nodes:[
{n:'GMap MA',u:'Low-yield',d:'Google Maps Maroc',t:'ns',st:'ok',io:'IN: queries SearXNG → OUT: Web search ≠ Maps API (normal)'},
{a:'→'},
{n:'GMap TN',u:'Low-yield',d:'Google Maps Tunisie',t:'ns',st:'ok',io:'IN: queries SearXNG → OUT: Web search ≠ Maps API (normal)'},
{a:'→'},
{n:'LinkedIn drip',u:'Low-yield',d:'SearXNG slow-rate',t:'ns',st:'ok',io:'IN: keywords → OUT: LinkedIn bloque indexation (normal)'},
{a:'→'},
{n:'RichScraper S204',u:'~800 4x/j',d:'Google-verified',t:'ns',st:'ok',io:'IN: HCPs sans tel → OUT: ~800 enrichis Google/j'},
]},
{title:'⚙️ PROCESSING → Validation & Dédup',flow:'IN: HCPs bruts → OUT: HCPs validés (email✓ tel✓ dedup✓)',nodes:[
{n:'ethica-master.py',u:'1/jour ✅',d:'Health+dedup+quality',t:'np',st:'ok',io:'IN: DB complète → OUT: rapport santé + dedup'},
{a:'→'},
{n:'ethica-validator S95',u:'43K validés ✅',d:'Batch 500 / 30min',t:'np',st:'ok',io:'IN: 43,597 emails vérifiés → OUT: 0 restants (pipeline propre)'},
{a:'→'},
{n:'ethica-validator S204',u:'~500/j',d:'Validation S204',t:'np',st:'ok',io:'IN: HCPs S204 → OUT: ~500 emails/tels vérifiés'},
{a:'→'},
{n:'ville-enricher',u:'500/jour',d:'Enrichissement villes',t:'np',st:'ok',io:'IN: HCPs sans ville → OUT: 500 villes ajoutées'},
]},
{title:'📧 ENRICHMENT → Emails',flow:'IN: HCPs sans email → OUT: HCPs avec email trouvé',nodes:[
{n:'email-drip ×20',u:'Low-yield',d:'Micro-batch */5min',t:'ne',st:'ok',io:'IN: 20 HCPs/run → OUT: Web search ne publie plus emails perso'},
{a:'→'},
{n:'enricher-auto 4x/j',u:'~200/run',d:'Multi-pays auto',t:'ne',st:'ok',io:'IN: HCPs multi-pays → OUT: ~800 emails/j'},
]},
{title:'',flow:'Enrichissement ciblé par pays — crons quotidiens',nodes:[
{n:'🇩🇿 enricher DZ',u:'500/jour 8h',d:'Ciblé Algérie',t:'ne',st:'ok',io:'IN: 500 DZ sans email → OUT: emails trouvés'},
{a:'→'},
{n:'🇲🇦 enricher MA',u:'500/jour 8h30',d:'Ciblé Maroc',t:'ne',st:'ok',io:'IN: 500 MA sans email → OUT: emails trouvés'},
{a:'→'},
{n:'🇹🇳 enricher TN',u:'300/jour 9h',d:'Ciblé Tunisie',t:'ne',st:'ok',io:'IN: 300 TN sans email → OUT: emails trouvés'},
]},
{title:'📊 OUTPUT → Métriques Production par Pays',flow:'Résultat final du pipeline — couverture email',nodes:[
{n:'🇩🇿 DZ: 96,825 HCPs',u:'76,900 emails',d:'79.4% couverture',t:'no',st:'ok',io:'Gap: 19,925 sans email'},
{a:'→'},
{n:'🇲🇦 MA: 19,252 HCPs',u:'14,530 emails',d:'75.5% couverture',t:'no',st:'ok',io:'Gap: 4,722 sans email — enrichment actif'},
{a:'→'},
{n:'🇹🇳 TN: 17,315 HCPs',u:'14,443 emails',d:'83.4% couverture',t:'no',st:'ok',io:'Gap: 2,872 sans email'},
]},
]
},
b2b: {
title: '🏢 B2B Lead Pipeline — 1,006 Leads',
kpis: [{v:'1,006',l:'Leads'},{v:'402',l:'Emails 40%'},{v:'638',l:'LinkedIn 63%'},{v:'6',l:'Crons'},{v:'~1.5K',l:'Actions/J'}],
sections: [
{title:'📥 SOURCES',flow:'IN: Keywords B2B → OUT: Profils bruts entreprises+contacts',nodes:[
{n:'LinkedIn scraper 48x/j',u:'~500/jour',d:'SearXNG queries',t:'ns',st:'ok',io:'IN: 50 queries/run → OUT: ~10 profils/run'},
{a:'→'},
{n:'Company scraper 12x/j',u:'~360/jour',d:'Annuaires',t:'ns',st:'ok',io:'IN: 30 queries/run → OUT: ~30 companies/run'},
]},
{title:'⚙️ ENRICHISSEMENT',flow:'IN: Leads bruts → OUT: Leads avec email+tel+company',nodes:[
{n:'lead-enricher hourly',u:'~480/jour',d:'Batch 20, 24 runs',t:'ne',st:'ok',io:'IN: 20 leads/h → OUT: emails SearXNG'},
{a:'→'},
{n:'lead-enricher 3h',u:'~400/jour',d:'Batch 50, 8 runs',t:'ne',st:'ok',io:'IN: 50 leads/3h → OUT: deep enrichment'},
]},
{title:'🔄 CRM → OUTPUT',flow:'IN: Leads enrichis → OUT: Séquences outbound → Twenty CRM',nodes:[
{n:'b2b-autonomous 6x/j',u:'~300 leads',d:'Pipeline complet',t:'np',st:'ok',io:'IN: triggers → OUT: leads qualifiés'},
{a:'→'},
{n:'CRM sequences 4x/j',u:'~50/run',d:'Twenty outbound',t:'np',st:'ok',io:'IN: leads chauds → OUT: séquences email'},
{a:'→'},
{n:'Twenty CRM',u:'Always-on ✅',d:'crm.weval-consulting.com',t:'no',st:'ok',io:'OUTPUT: 1006 leads, 402 emails, 638 LinkedIn'},
]},
]
},
brain: {
title: '🧪 Brain Engine — 366 Configs → 10 Winners',
kpis: [{v:'366',l:'Configs'},{v:'10',l:'Winners'},{v:'20',l:'SMTP'},{v:'9',l:'Sacred'},{v:'STANDBY',l:'Send'}],
sections: [
{title:'🔬 DISCOVERY → Test → Score',flow:'IN: Nouvelles configs → OUT: Score qualité par config',nodes:[
{n:'brain-configs (366)',u:'Pool base',d:'Configurations testables',t:'ns',st:'ok',io:'IN: manual + auto-discovery → OUT: 366 configs'},
{a:'→'},
{n:'brain-creative-engine',u:'A/B testing',d:'Subject+body optimizer',t:'np',st:'ok',io:'IN: config → OUT: creative variants testés'},
{a:'→'},
{n:'brain-combo',u:'Cross-test',d:'Combinaisons',t:'np',st:'ok',io:'IN: configs × ISPs → OUT: combo scores'},
{a:'→'},
{n:'brain-analyze',u:'Analytics',d:'Performance deep',t:'np',st:'ok',io:'IN: send data → OUT: insights'},
]},
{title:'🧠 INTELLIGENCE → Auto-learn → Auto-fix',flow:'IN: Résultats sends → OUT: Ajustements automatiques',nodes:[
{n:'brain-trainer',u:'Auto-learn',d:'Apprentissage résultats',t:'na',st:'ok',io:'IN: open/click rates → OUT: model updates'},
{a:'→'},
{n:'brain-autofix',u:'Auto-repair',d:'Fix configs cassées',t:'na',st:'ok',io:'IN: errors detected → OUT: configs réparées'},
{a:'→'},
{n:'brain-tracking-seeds',u:'Seeds inbox',d:'Monitoring placement',t:'np',st:'ok',io:'IN: test seeds → OUT: inbox/spam ratio'},
]},
{title:'🏆 WINNERS → INJECT → SEND (STANDBY)',flow:'IN: Top configs → OUT: Emails envoyés (STANDBY Hetzner)',nodes:[
{n:'brain_winners (10)',u:'9 sacred ⚡',d:'Never modify/delete',t:'no',st:'ok',io:'OUT: 10 winners, 9 sacred, O365 method'},
{a:'→'},
{n:'brain-inject + config',u:'Push pipeline',d:'Injection configs',t:'np',st:'ok',io:'IN: winner → OUT: injected in send queue'},
{a:'→'},
{n:'brain-unified-send',u:'STANDBY ⏸',d:'O365 via PMTA',t:'nw',st:'standby',io:'STANDBY: anti-spam Hetzner'},
{a:'→'},
{n:'daily-stats-aggregate',u:'366 configs',d:'Stats 0h30',t:'no',st:'ok',io:'IN: all data → OUT: aggregated stats'},
]},
]
},
wevia: {
title: '🧠 WEVIA IA Pipeline — Sovereign Multi-Model',
kpis: [{v:'5,676',l:'Lines Brain'},{v:'25+',l:'Tools'},{v:'67',l:'AIs Bench'},{v:'6',l:'MCP'},{v:'~50',l:'Patterns/J'}],
sections: [
{title:'🧠 BRAIN CORE → Routing → Cognitive',flow:'IN: User query → OUT: Réponse IA multi-modèle sovereign',nodes:[
{n:'wevia-brain.php',u:'5676L ✅',d:'Cerveau principal',t:'na',st:'ok',io:'IN: user message → OUT: routed to best provider'},
{a:'→'},
{n:'wevia-providers',u:'4 fallbacks',d:'Cerebras→Groq→Samba→Ollama',t:'np',st:'ok',io:'IN: prompt → OUT: completion (sovereign first)'},
{a:'→'},
{n:'cognitive-brain',u:'MoA active',d:'Raisonnement avancé',t:'na',st:'ok',io:'IN: complex query → OUT: multi-model consensus'},
]},
{title:'🔧 TOOLS & SKILLS → Capacités dynamiques',flow:'IN: Tool call → OUT: Résultat structuré (météo, calc, search...)',nodes:[
{n:'tools-router (25+)',u:'Always-on ✅',d:'ToolFK: météo,calc,news...',t:'np',st:'ok',io:'IN: tool_name + params → OUT: JSON result'},
{a:'→'},
{n:'MCP Layer (6 tools)',u:'JSON-RPC ✅',d:'Model Context Protocol',t:'np',st:'ok',io:'IN: JSON-RPC request → OUT: tool execution'},
{a:'→'},
{n:'skills + factory',u:'Dynamic',d:'Auto-créés',t:'np',st:'ok',io:'IN: need → OUT: new skill created'},
]},
{title:'📈 AUTO-AMÉLIORATION → Benchmark → Gap → Fix',flow:'IN: Performance data → OUT: Améliorations appliquées',nodes:[
{n:'autolearn 12x/j',u:'~50 patterns ✅',d:'Auto-apprentissage',t:'ne',st:'ok',io:'IN: conversations → OUT: ~50 patterns appris'},
{a:'→'},
{n:'benchmark 67 AIs',u:'Quotidien ✅',d:'Latence + qualité',t:'np',st:'ok',io:'IN: 67 providers → OUT: ranking + scores'},
{a:'→'},
{n:'gap-discovery',u:'~10/jour',d:'Trouve manques',t:'ne',st:'ok',io:'IN: capabilities scan → OUT: ~10 gaps identifiés'},
{a:'→'},
{n:'improvement',u:'~5/jour',d:'Propositions auto',t:'no',st:'ok',io:'IN: gaps → OUT: ~5 improvements proposés'},
]},
{title:'🧬 COGNITIVE → MoA + Consensus + Personas',flow:'IN: Query complexe → OUT: Réponse consensus multi-modèle',nodes:[
{n:'cognitive-opus46 (5)',u:'Pipeline ✅',d:'Standard→Advanced→Mega',t:'na',st:'ok',io:'IN: hard query → OUT: opus-level response'},
{a:'→'},
{n:'consensus-engine (4)',u:'Self-MoA ✅',d:'Multi-model consensus',t:'na',st:'ok',io:'IN: 3+ model outputs → OUT: best consensus'},
{a:'→'},
{n:'consulting-personas',u:'Sovereign',d:'Brain spécialisé',t:'na',st:'ok',io:'IN: domain query → OUT: expert persona response'},
]},
]
},
sentinel: {
title: '🛰 Sentinel Pipeline — Execution Layer',
kpis: [{v:'344',l:'APIs S95'},{v:'143',l:'APIs S204'},{v:'200',l:'HTTP OK'},{v:'v5',l:'Engine'},{v:'50+',l:'Blade Ops'}],
sections: [
{title:'⚡ EXECUTION → CX / Droid / Sentinel',flow:'IN: Commande texte → OUT: Résultat exécution serveur',nodes:[
{n:'CX (S204 www-data)',u:'~25s timeout',d:'POST /api/cx',t:'np',st:'ok',io:'IN: base64 cmd → OUT: stdout (www-data)'},
{a:'→'},
{n:'Droid (sudo)',u:'Elevated ✅',d:'POST /api/droid',t:'np',st:'ok',io:'IN: base64 cmd → OUT: stdout (root)'},
{a:'→'},
{n:'sentinel-brain S95',u:'200 OK ✅',d:'Cerveau Sentinel',t:'na',st:'ok',io:'IN: action+cmd → OUT: exec result JSON'},
]},
{title:'🛡 ENGINE → VAULT → GATEWAY',flow:'IN: API request → OUT: Routed + authenticated response',nodes:[
{n:'sentinel-engine v5',u:'Always-on ✅',d:'Multi-serveur',t:'na',st:'ok',io:'IN: request → OUT: routed to S204/S95/S151'},
{a:'→'},
{n:'sentinel-vault',u:'Secrets ✅',d:'Credentials+tokens',t:'na',st:'ok',io:'IN: key request → OUT: decrypted secret'},
{a:'→'},
{n:'api-gateway',u:'Routing ✅',d:'Gateway intelligent',t:'np',st:'ok',io:'IN: endpoint → OUT: load-balanced response'},
]},
{title:'🔪 BLADE → Agent → Brain → Ops',flow:'IN: Commande naturelle → OUT: Exécution PowerShell sur Razer Blade',nodes:[
{n:'blade-api (Queue)',u:'2880/j',d:'Push/poll/heartbeat',t:'np',st:'ok',io:'IN: task JSON → OUT: queued for agent'},
{a:'→'},
{n:'blade-brain (AI)',u:'NL→PS',d:'Langage naturel',t:'na',st:'ok',io:'IN: "nettoie temp" → OUT: Remove-Item $env:TEMP\\*'},
{a:'→'},
{n:'Sentinel Agent v2.2',u:'ONLINE ✅',d:'LAPTOP-VE75QUHF Razer',t:'na',st:'ok',io:'Heartbeat 60s | Poll 30s | Watchdog 5min | Auto-update 6h'},
]},
]
},
hamid: {
title: '🔥 Hamid Engine — 9 Modules Chef+Engine+IA',
kpis: [{v:'9',l:'Modules'},{v:'3',l:'Chef'},{v:'3',l:'Engine'},{v:'IA',l:'Brain'},{v:'OK',l:'S95 API'}],
sections: [
{title:'🧠 INTELLIGENCE → Analyse → Décision',flow:'IN: Config data → OUT: Recommandations optimisation',nodes:[
{n:'hamid-api',u:'Gateway ✅',d:'API principale',t:'np',st:'ok',io:'IN: request → OUT: routed to brain/chef/engine'},
{a:'→'},
{n:'hamid-brain',u:'IA Core ✅',d:'Cerveau Hamid',t:'na',st:'ok',io:'IN: performance data → OUT: analysis + insights'},
{a:'→'},
{n:'hamid-ia',u:'Intelligence',d:'Module avancé',t:'na',st:'ok',io:'IN: complex data → OUT: predictions'},
]},
{title:'👨‍🍳 CHEF → Optimisation configs gagnantes',flow:'IN: Configs brutes → OUT: Configs optimisées (subject, body, ISP)',nodes:[
{n:'hamid-chef',u:'Full optimizer',d:'Complet',t:'np',st:'ok',io:'IN: raw config → OUT: optimized creative'},
{a:'→'},
{n:'hamid-chef-simple',u:'Light version',d:'Simplifié',t:'np',st:'ok',io:'IN: config → OUT: quick optimization'},
{a:'→'},
{n:'hamid-chef2',u:'v2 improved',d:'Itération',t:'np',st:'ok',io:'IN: config → OUT: enhanced optimization'},
]},
{title:'⚡ ENGINE → Exécution optimisée',flow:'IN: Config optimisée → OUT: Envoi optimisé (ISP routing, timing)',nodes:[
{n:'hamid-engine',u:'Main ✅',d:'Moteur principal',t:'np',st:'ok',io:'IN: optimized config → OUT: send instructions'},
{a:'→'},
{n:'hamid-engine-simple',u:'Light',d:'Optimisé perf',t:'np',st:'ok',io:'IN: config → OUT: fast execution path'},
{a:'→'},
{n:'hamid-engine-fixed',u:'Stable ✅',d:'Version stabilisée',t:'no',st:'ok',io:'IN: any config → OUT: reliable execution'},
]},
]
},
send: {
title: '📧 Send Factory — STANDBY, PMTA+KumoMTA',
kpis: [{v:'STANDBY',l:'Status',c:'var(--w)'},{v:'PMTA',l:'MTA1'},{v:'Kumo',l:'MTA2'},{v:'8',l:'Engines'},{v:'0',l:'Sent Today'}],
sections: [
{title:'🎯 ORCHESTRATION → Routing intelligent',flow:'IN: Campaign data → OUT: Meilleur send method sélectionné',nodes:[
{n:'brain-orchestrator',u:'Routing ✅',d:'Décision method',t:'np',st:'ok',io:'IN: campaign → OUT: best method (O365/SMTP/...)'},
{a:'→'},
{n:'send-orchestrator',u:'Pipeline ✅',d:'Orchestrateur',t:'np',st:'ok',io:'IN: method → OUT: send instructions'},
{a:'→'},
{n:'profit-orchestrator',u:'ROI calc',d:'Optimisation profit',t:'np',st:'ok',io:'IN: costs → OUT: profit-optimized routing'},
]},
{title:'⚡ ENGINES → Envoi (TOUT STANDBY)',flow:'⏸ STANDBY — Anti-spam Hetzner policy. 0 emails envoyés.',nodes:[
{n:'send-engine+factory',u:'⏸ STANDBY',d:'Moteur principal',t:'nw',st:'standby',io:'STANDBY: 0 emails/jour'},
{a:'→'},
{n:'semi-auto-send',u:'⏸ STANDBY',d:'Semi-automatique',t:'nw',st:'standby',io:'STANDBY: needs manual trigger'},
{a:'→'},
{n:'predictive-send',u:'⏸ STANDBY',d:'Prédictif IA',t:'nw',st:'standby',io:'STANDBY: ML model ready, no sends'},
]},
{title:'📡 MTA → Serveurs mail (STANDBY)',flow:'⏸ PMTA + KumoMTA prêts mais désactivés.',nodes:[
{n:'PMTA (S204+S95)',u:'⏸ STANDBY',d:'Port25 MTA',t:'nw',st:'standby',io:'STANDBY: MTA started but no queue'},
{a:'→'},
{n:'KumoMTA (S95)',u:'⏸ STANDBY',d:'MTA secondaire',t:'nw',st:'standby',io:'STANDBY: backup MTA ready'},
{a:'→'},
{n:'warmup-engine',u:'⏸ STANDBY',d:'Warmup IPs',t:'nw',st:'standby',io:'STANDBY: IPs not warming'},
]},
]
},
wedroid: {
title: '🤖 WeDroid Agent — 8 Modules, 1029 Lines',
kpis: [{v:'1,029',l:'Lines'},{v:'685',l:'Brain'},{v:'8',l:'Modules'},{v:'17',l:'Patterns'},{v:'TG',l:'Alerts'}],
sections: [
{title:'🧠 BRAIN → Parse → Execute → Chain',flow:'IN: Tâche texte → OUT: Résultat exécution multi-étapes',nodes:[
{n:'wedroid-brain (685L)',u:'AI Parse ✅',d:'Parsing+routing',t:'na',st:'ok',io:'IN: "deploy site" → OUT: chain of 5 commands'},
{a:'→'},
{n:'chain-executor (131L)',u:'Multi-step ✅',d:'Séquences',t:'np',st:'ok',io:'IN: command chain → OUT: all steps executed'},
{a:'→'},
{n:'wedroid-v4 (25L)',u:'Interface ✅',d:'Point entrée',t:'np',st:'ok',io:'IN: API call → OUT: routed to brain'},
]},
{title:'🔧 PATTERNS → Git → Scheduler',flow:'IN: Patterns infra → OUT: Actions automatisées + git commit',nodes:[
{n:'infra-patterns (46L)',u:'17 patterns',d:'Claude Code',t:'np',st:'ok',io:'IN: situation → OUT: best pattern matched'},
{a:'→'},
{n:'git-auto (21L)',u:'Auto commit ✅',d:'Commit+push',t:'np',st:'ok',io:'IN: file changes → OUT: git commit+push'},
{a:'→'},
{n:'scheduler (57L)',u:'Planifier',d:'Tâches différées',t:'np',st:'ok',io:'IN: task+delay → OUT: scheduled execution'},
]},
{title:'📡 LEARNING → FEEDBACK → ALERTS',flow:'IN: Résultats exécution → OUT: Apprentissage + alertes TG',nodes:[
{n:'learning (39L)',u:'Auto-learn ✅',d:'Erreurs/succès',t:'ne',st:'ok',io:'IN: exec results → OUT: improved patterns'},
{a:'→'},
{n:'telegram-alert (25L)',u:'Alerts TG ✅',d:'Events critiques',t:'np',st:'ok',io:'IN: critical event → OUT: TG message to Yacine'},
]},
]
},
infra: {
title: '🛡 Infra & Sécurité — 864+ Checks/Jour',
kpis: [{v:'864+',l:'Checks/J'},{v:'144',l:'Repairs/J'},{v:'16',l:'Docker ✅'},{v:'2',l:'WAF'},{v:'3+',l:'Backups/J'}],
sections: [
{title:'🔒 SECURITY → WAF + Auth + Bouncer',flow:'IN: Requêtes entrantes → OUT: Filtrées (block malicious)',nodes:[
{n:'CrowdSec (S204+S95)',u:'Always-on ✅',d:'WAF+IP bouncer',t:'na',st:'ok',io:'IN: all traffic → OUT: bad IPs blocked'},
{a:'→'},
{n:'Fail2Ban (3 servers)',u:'Always-on ✅',d:'Brute-force',t:'na',st:'ok',io:'IN: auth logs → OUT: IPs banned'},
{a:'→'},
{n:'Authentik SSO',u:'Healthy ✅',d:'Forward Auth 9543',t:'na',st:'ok',io:'IN: request → OUT: authenticated or redirect'},
]},
{title:'🔄 GUARDIAN LOOP → */5min → Auto-repair',flow:'IN: État fichiers/configs → OUT: Restauration si modifié',nodes:[
{n:'infra-guardian S204',u:'288/j ✅',d:'chattr+MD5+Docker',t:'np',st:'ok',io:'IN: checksums → OUT: alert+restore if changed'},
{a:'→'},
{n:'critical-files S95',u:'288/j ✅',d:'Guard WEVADS',t:'np',st:'ok',io:'IN: critical files → OUT: restored if tampered'},
{a:'→'},
{n:'regression-repair',u:'144/j ✅',d:'Auto-fix configs',t:'np',st:'ok',io:'IN: config diffs → OUT: auto-repaired'},
]},
{title:'💾 BACKUP CHAIN → 3 serveurs → GitHub',flow:'IN: DBs+configs → OUT: 4 backups/jour sur 3 destinations',nodes:[
{n:'daily_backup S95',u:'1/j 3h ✅',d:'Full PG+configs',t:'no',st:'ok',io:'IN: adx_system+configs → OUT: local backup'},
{a:'→'},
{n:'backup-to-ovh',u:'1/j 3h ✅',d:'→ S151 DR',t:'no',st:'ok',io:'IN: backup → OUT: replicated to OVH DR'},
{a:'→'},
{n:'pg_dump→S151',u:'1/j 3h ✅',d:'DR PostgreSQL',t:'no',st:'ok',io:'IN: adx_system → OUT: DR replica S151'},
{a:'→'},
{n:'github push',u:'1/j 4h ✅',d:'Git auto',t:'no',st:'ok',io:'IN: code changes → OUT: pushed to GitHub'},
]},
{title:'🐳 DOCKER → 16 containers ✅',flow:'Tous les 16 containers UP et healthy',nodes:[
{n:'Authentik (4)',u:'Up 15h ✅',d:'SSO healthy',t:'no',st:'ok',io:'4 containers: server+worker+db+redis'},
{a:'→'},
{n:'Plausible (3)',u:'Up 24h ✅',d:'Analytics',t:'no',st:'ok',io:'3 containers: app+pg+clickhouse'},
{a:'→'},
{n:'Twenty (2)',u:'Up 13h ✅',d:'CRM',t:'no',st:'ok',io:'2 containers: app+redis'},
{a:'→'},
{n:'n8n+SearX+Kuma+...',u:'Up 5-6d ✅',d:'7 services',t:'no',st:'ok',io:'n8n,searxng,kuma,mm,loki,vault,qdrant'},
]},
]
},
nonreg: {
title: '🧪 NonReg & QA — 776 Tests/Jour',
kpis: [{v:'776',l:'Tests/J'},{v:'2',l:'6sigma/J'},{v:'86',l:'Baselines/S'},{v:'1',l:'Nuclei/S'}],
sections: [
{title:'🔬 TEST PIPELINE → Matin + Soir (2x/jour)',flow:'IN: 250 routes+endpoints → OUT: PASS/FAIL report',nodes:[
{n:'nonreg-master matin',u:'250 tests 6h',d:'All routes+API',t:'np',st:'ok',io:'IN: all routes → OUT: PASS/FAIL matrix'},
{a:'→'},
{n:'nonreg-daily matin',u:'138 checks 6h',d:'CSS/JS/API/Auth',t:'np',st:'ok',io:'IN: critical paths → OUT: health report'},
{a:'→'},
{n:'nonreg-master soir',u:'250 tests 18h',d:'Verification',t:'np',st:'ok',io:'IN: all routes → OUT: regression check'},
{a:'→'},
{n:'nonreg-daily soir',u:'138 checks 18h',d:'Fin journée',t:'np',st:'ok',io:'IN: critical paths → OUT: day-end report'},
]},
{title:'🔐 AUTH → SSO + 6sigma',flow:'IN: Auth endpoints → OUT: Matrice authentification complète',nodes:[
{n:'sso-nonreg 2x/j',u:'2 tests ✅',d:'Authentik health',t:'np',st:'ok',io:'IN: SSO flow → OUT: login/callback verified'},
{a:'→'},
{n:'6sigma-auth 2x/j',u:'2 matrices ✅',d:'Auth complète',t:'np',st:'ok',io:'IN: all auth paths → OUT: complete auth matrix'},
]},
{title:'📸 VISUAL + SECURITY',flow:'IN: Pages → OUT: Screenshots baseline + vulnerabilité scan',nodes:[
{n:'baselines.js weekly',u:'86 screenshots',d:'Captures baseline',t:'np',st:'ok',io:'IN: 86 pages → OUT: reference screenshots'},
{a:'→'},
{n:'nuclei-scan weekly',u:'1 scan complet',d:'Sécurité endpoints',t:'np',st:'ok',io:'IN: all endpoints → OUT: vulnerability report'},
]},
]
},
monitoring: {
title: '📈 Monitoring Stack — Health Grid',
kpis: [{v:'9',l:'Health APIs'},{v:'50+',l:'Kuma Monitors'},{v:'16',l:'Docker ✅'},{v:'Loki',l:'Logs'},{v:'n8n',l:'200 OK'}],
sections: [
{title:'📊 ANALYTICS → Events → Dashboard',flow:'IN: Page views → OUT: Privacy-first analytics dashboard',nodes:[
{n:'Plausible :8787',u:'Up 24h ✅',d:'Analytics',t:'na',st:'ok',io:'IN: page events → OUT: visitor stats'},
{a:'→'},
{n:'ClickHouse',u:'Events store ✅',d:'Performant',t:'np',st:'ok',io:'IN: raw events → OUT: aggregated metrics'},
]},
{title:'🏥 HEALTH GRID → 9 endpoints temps réel',flow:'IN: Service URL → OUT: HTTP status (200=OK, else=DOWN)',nodes:[
{n:'health-chatbot',u:'WEVIA',d:'Cerveau',t:'np',st:'ok',io:'→ wevia-brain status'},
{a:'|'},
{n:'health-crm',u:'Twenty',d:'CRM',t:'np',st:'ok',io:'→ CRM status'},
{a:'|'},
{n:'health-ollama',u:'LLM',d:'Local AI',t:'np',st:'ok',io:'→ Ollama status'},
{a:'|'},
{n:'health-n8n',u:'200 ✅',d:'Workflows',t:'np',st:'ok',io:'→ n8n healthy'},
]},
{title:'',flow:'',nodes:[
{n:'health-mm',u:'Mattermost',d:'Chat',t:'np',st:'ok',io:'→ MM status'},
{a:'|'},
{n:'health-qdrant',u:'200 ✅',d:'Vectors',t:'np',st:'ok',io:'→ Qdrant healthy'},
{a:'|'},
{n:'health-searxng',u:'200 ✅',d:'Search',t:'np',st:'ok',io:'→ SearXNG healthy'},
{a:'|'},
{n:'health-plausible',u:'Analytics',d:'Stats',t:'np',st:'ok',io:'→ Plausible status'},
]},
{title:'📡 UPTIME + LOGS → Alerting',flow:'IN: All services → OUT: Alerts if down',nodes:[
{n:'Uptime Kuma :3088',u:'50+ monitors ✅',d:'Temps réel',t:'na',st:'ok',io:'IN: 50+ URLs → OUT: status + alerts'},
{a:'→'},
{n:'Grafana Loki',u:'Log aggregation',d:'Centralisé',t:'na',st:'ok',io:'IN: all logs → OUT: searchable + alerts'},
{a:'→'},
{n:'disk-monitor 4x/j',u:'4 alertes ✅',d:'Alerte >85%',t:'np',st:'ok',io:'IN: df → OUT: alert if >85%'},
]},
]
}
};
function openDd(key) {
const p = PIPELINES[key]; if(!p) return;
document.getElementById('ddTitle').textContent = p.title;
let h = '<div class="dd-kpis">';
p.kpis.forEach(k => { h += `<div class="dd-kpi"><div class="dv" ${k.c?'style="color:'+k.c+'"':''}>${k.v}</div><div class="dl">${k.l}</div></div>`; });
h += '</div><div class="fl">';
p.sections.forEach(s => {
h += '<div class="fl-sec">';
if(s.title) h += `<div class="fl-sec-t">${s.title}</div>`;
if(s.flow) h += `<div style="font-size:.58rem;color:var(--or);padding:2px 10px 6px;font-style:italic">${s.flow}</div>`;
h += '<div class="fl-row">';
s.nodes.forEach(nd => {
if(nd.a) { h += `<div class="fl-a">${nd.a}</div>`; }
else {
const stDot = nd.st==='ok'?'🟢':nd.st==='warn'?'🟡':nd.st==='standby'?'⏸️':'🔴';
h += `<div class="fl-n ${nd.t}" title="${nd.io||''}" style="cursor:help"><div class="nn">${stDot} ${nd.n}</div><div class="nu">${nd.u}</div><div class="nd">${nd.d}</div>${nd.io?'<div style="font-size:.48rem;color:var(--cy);margin-top:3px;border-top:1px solid var(--b);padding-top:2px">'+nd.io+'</div>':''}</div>`;
}
});
h += '</div></div>';
});
h += '</div>';
document.getElementById('ddBody').innerHTML = h;
document.getElementById('ddOverlay').classList.add('open');
}
function closeDd() { document.getElementById('ddOverlay').classList.remove('open'); }
stats();
render('all');
</script>
<div class="dd-overlay" id="ddOverlay" onclick="if(event.target===this)closeDd()">
<div class="dd-panel"><div class="dd-hdr"><h2 id="ddTitle">Pipeline</h2><button class="dd-close" onclick="closeDd()">✕ Fermer</button></div>
<div class="dd-body" id="ddBody"></div></div></div>
<!-- Production Metrics Overlay -->
<style>
.prod-badge{position:absolute;top:4px;right:8px;font-size:10px;padding:2px 6px;border-radius:8px;font-weight:bold}
.prod-badge.active{background:#10b981;color:#000}
.prod-badge.standby{background:#f59e0b;color:#000}
.prod-badge.daily{background:#6366f1;color:#fff}
.prod-rate{position:absolute;bottom:4px;right:8px;font-size:11px;color:#67e8f9;font-weight:bold}
#prod-totals{position:fixed;bottom:10px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.9);border:1px solid #10b981;border-radius:12px;padding:8px 20px;z-index:9999;font-size:13px;color:#10b981;display:flex;gap:20px}
#prod-totals span{color:#67e8f9;font-weight:bold}
</style>
<div id="prod-totals">
<div>Pipelines: <span id="pt-total">-</span></div>
<div>Active: <span id="pt-active">-</span></div>
<div>Ops/h: <span id="pt-hourly">-</span></div>
<div>Ops/jour: <span id="pt-daily">-</span></div>
</div>
<script>
fetch("/api/prod-metrics.php").then(r=>r.text().then(t=>{/* HTML_GUARD_V2_BATCH */var q=(t||"").trim();if(q.startsWith("<!DOCTYPE")||q.startsWith("<html")){return{error:"[HTTP "+r.status+"]",isHtmlError:true}}try{return JSON.parse(q)}catch(e){return{error:"JSON "+e.message}}})).then(d=>{
document.getElementById("pt-total").textContent=d.totals.total;
document.getElementById("pt-active").textContent=d.totals.active;
document.getElementById("pt-hourly").textContent=d.totals.hourly;
document.getElementById("pt-daily").textContent=d.totals.daily.toLocaleString();
// Add rate badges to pipeline bricks
const bricks=document.querySelectorAll("[class*=pipeline],[class*=brick],[class*=card]");
const metrics=d.metrics;
Object.values(metrics).forEach(m=>{
const el=Array.from(document.querySelectorAll("*")).find(e=>e.textContent.includes(m.label));
if(el&&el.closest("[class*=card],[class*=brick],[class*=pipe]")){
const card=el.closest("[class*=card],[class*=brick],[class*=pipe]");
if(card&&!card.querySelector(".prod-rate")){
card.style.position="relative";
const rate=document.createElement("div");
rate.className="prod-rate";
rate.textContent=m.req_h+" "+m.unit;
card.appendChild(rate);
}
}
});
}).catch(e=>console.log("Metrics:",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 === -->
<script src="/api/archi-meta-badge.js" defer></script>
</body>
</html>