Compare commits
3 Commits
wave-213-c
...
wave-214-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1a2a6490d | ||
|
|
0925c771a0 | ||
|
|
d46f607976 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_Disk_Monitor",
|
||||
"ts": "2026-04-21T16:00:01+02:00",
|
||||
"ts": "2026-04-21T16:30:01+02:00",
|
||||
"disk_pct": 82,
|
||||
"disk_free_gb": 27,
|
||||
"growth_per_day_gb": 1.5,
|
||||
|
||||
33
api/ambre-pw-deep.php
Normal file
33
api/ambre-pw-deep.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Read playwright-check.sh
|
||||
$f = "/var/www/html/api/v76-scripts/playwright-check.sh";
|
||||
if (file_exists($f)) $out["pw_check_sh"] = @file_get_contents($f);
|
||||
|
||||
// Targeted config locations
|
||||
$cfgs = ["/var/www/html/playwright.config.js", "/var/www/html/playwright.config.ts",
|
||||
"/var/www/html/api/playwright.config.js", "/opt/weval-l99/playwright.config.js"];
|
||||
foreach ($cfgs as $c) if (file_exists($c)) $out["config_$c"] = substr(@file_get_contents($c), 0, 600);
|
||||
|
||||
// Find recent spec files in common dirs (no find/ recursive)
|
||||
foreach (["/var/www/html", "/var/www/html/tests", "/var/www/html/api", "/opt/weval-l99/tests"] as $d) {
|
||||
foreach (glob("$d/*.spec.{js,ts}", GLOB_BRACE) as $s) $out["specs"][] = $s;
|
||||
foreach (glob("$d/tests/*.spec.{js,ts}", GLOB_BRACE) as $s) $out["specs"][] = $s;
|
||||
}
|
||||
|
||||
// which playwright
|
||||
$out["which_npx"] = trim(@shell_exec("which npx 2>&1") ?: "");
|
||||
$out["which_playwright"] = trim(@shell_exec("which playwright 2>&1") ?: "");
|
||||
|
||||
// Look for package.json with playwright
|
||||
foreach (["/var/www/html/package.json", "/var/www/html/api/package.json", "/opt/weval-l99/package.json"] as $p) {
|
||||
if (file_exists($p)) {
|
||||
$pkg = @json_decode(@file_get_contents($p), true);
|
||||
$has_pw = isset($pkg["devDependencies"]["@playwright/test"]) || isset($pkg["dependencies"]["@playwright/test"]);
|
||||
if ($has_pw || $pkg) $out["pkg_$p"] = ["has_playwright"=>$has_pw, "scripts"=>$pkg["scripts"]??[]];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-04-21T16:25:01.526924",
|
||||
"generated_at": "2026-04-21T16:30:01.984827",
|
||||
"stats": {
|
||||
"total": 48,
|
||||
"pending": 31,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"status": "ALIVE",
|
||||
"ts": "2026-04-21T16:15:02.035623",
|
||||
"last_heartbeat": "2026-04-21T16:15:02.035623",
|
||||
"last_heartbeat_ts_epoch": 1776780902,
|
||||
"ts": "2026-04-21T16:30:02.091494",
|
||||
"last_heartbeat": "2026-04-21T16:30:02.091494",
|
||||
"last_heartbeat_ts_epoch": 1776781802,
|
||||
"tasks_today": 232,
|
||||
"tasks_week": 574,
|
||||
"agent_id": "blade-ops",
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
{
|
||||
"ts": "2026-04-21T14:25:01+00:00",
|
||||
"server": "s204",
|
||||
"s204": {
|
||||
"load": 1.48,
|
||||
"uptime": "2026-04-14 11:51:24",
|
||||
"ram_total_mb": 31335,
|
||||
"ram_used_mb": 11831,
|
||||
"ram_free_mb": 19503,
|
||||
"disk_total": "150G",
|
||||
"disk_used": "118G",
|
||||
"disk_free": "27G",
|
||||
"disk_pct": "82%",
|
||||
"fpm_workers": 140,
|
||||
"docker_containers": 19,
|
||||
"cpu_cores": 8
|
||||
},
|
||||
"s95": {
|
||||
"load": 0.7,
|
||||
"disk_pct": "81%",
|
||||
"status": "UP",
|
||||
"ram_total_mb": 15610,
|
||||
"ram_free_mb": 12027
|
||||
},
|
||||
"pmta": [
|
||||
{
|
||||
"name": "SER6",
|
||||
"ip": "110.239.84.121",
|
||||
"status": "DOWN"
|
||||
},
|
||||
{
|
||||
"name": "SER7",
|
||||
"ip": "110.239.65.64",
|
||||
"status": "DOWN"
|
||||
},
|
||||
{
|
||||
"name": "SER8",
|
||||
"ip": "182.160.55.107",
|
||||
"status": "DOWN"
|
||||
},
|
||||
{
|
||||
"name": "SER9",
|
||||
"ip": "110.239.86.68",
|
||||
"status": "DOWN"
|
||||
}
|
||||
],
|
||||
"assets": {
|
||||
"html_pages": 315,
|
||||
"php_apis": 811,
|
||||
"wiki_entries": 2046,
|
||||
"vault_doctrines": 75,
|
||||
"vault_sessions": 104,
|
||||
"vault_decisions": 12
|
||||
},
|
||||
"tools": {
|
||||
"total": 627,
|
||||
"registry_version": "?"
|
||||
},
|
||||
"sovereign": {
|
||||
"status": "UP",
|
||||
"providers": [
|
||||
"Cerebras-fast",
|
||||
"Cerebras-think",
|
||||
"Groq",
|
||||
"Cloudflare-AI",
|
||||
"Gemini",
|
||||
"SambaNova",
|
||||
"NVIDIA-NIM",
|
||||
"Mistral",
|
||||
"Groq-OSS",
|
||||
"HF-Space",
|
||||
"HF-Router",
|
||||
"OpenRouter",
|
||||
"GitHub-Models"
|
||||
],
|
||||
"active": 13,
|
||||
"total": 13,
|
||||
"primary": "Cerebras-fast",
|
||||
"cost": "0€"
|
||||
},
|
||||
"ethica": {
|
||||
"total_hcps": 161733,
|
||||
"with_email": 110611,
|
||||
"with_phone": 155151,
|
||||
"gap_email": 51122,
|
||||
"pct_email": 68.4,
|
||||
"pct_phone": 95.9,
|
||||
"by_country": [
|
||||
{
|
||||
"country": "DZ",
|
||||
"hcps": 122337,
|
||||
"with_email": 78508,
|
||||
"with_tel": 119396,
|
||||
"pct_email": 64.2,
|
||||
"pct_tel": 97.6
|
||||
},
|
||||
{
|
||||
"country": "MA",
|
||||
"hcps": 19723,
|
||||
"with_email": 15077,
|
||||
"with_tel": 18737,
|
||||
"pct_email": 76.4,
|
||||
"pct_tel": 95
|
||||
},
|
||||
{
|
||||
"country": "TN",
|
||||
"hcps": 17794,
|
||||
"with_email": 15147,
|
||||
"with_tel": 17018,
|
||||
"pct_email": 85.1,
|
||||
"pct_tel": 95.6
|
||||
},
|
||||
{
|
||||
"country": "INTL",
|
||||
"hcps": 1879,
|
||||
"with_email": 1879,
|
||||
"with_tel": 0,
|
||||
"pct_email": 100,
|
||||
"pct_tel": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"docker": [
|
||||
{
|
||||
"name": "loki",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "listmonk",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-db-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-events-db-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "n8n-docker-n8n-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mm-db-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mattermost-1",
|
||||
"status": "Up 5 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 38 hours (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"status": "Up 7 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
}
|
||||
],
|
||||
"crons": {
|
||||
"active": 35
|
||||
},
|
||||
"git": {
|
||||
"head": "69dcf0a39 auto-sync-1625",
|
||||
"dirty": 2,
|
||||
"status": "DIRTY"
|
||||
},
|
||||
"nonreg": {
|
||||
"total": 153,
|
||||
"passed": 153,
|
||||
"score": "100%"
|
||||
},
|
||||
"services": [
|
||||
{
|
||||
"name": "DeerFlow",
|
||||
"port": 3002,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "DeerFlow API",
|
||||
"port": 8001,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Qdrant",
|
||||
"port": 6333,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Ollama",
|
||||
"port": 11434,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Redis",
|
||||
"port": 6379,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Sovereign",
|
||||
"port": 4000,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "SearXNG",
|
||||
"port": 8080,
|
||||
"status": "UP"
|
||||
}
|
||||
],
|
||||
"whisper": {
|
||||
"binary": "COMPILED",
|
||||
"model": "142MB"
|
||||
},
|
||||
"grand_total": 3893,
|
||||
"health": {
|
||||
"score": 5,
|
||||
"max": 6,
|
||||
"pct": 83
|
||||
},
|
||||
"elapsed_ms": 10544
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"agent": "V42_MQL_Scoring_Agent_REAL",
|
||||
"ts": "2026-04-21T14:20:01+00:00",
|
||||
"ts": "2026-04-21T14:30:02+00:00",
|
||||
"status": "DEPLOYED_AUTO",
|
||||
"deployed": true,
|
||||
"algorithm": "weighted_behavioral_signals",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"version": "V83-business-kpi",
|
||||
"ts": "2026-04-21T14:26:43+00:00",
|
||||
"ts": "2026-04-21T14:29:43+00:00",
|
||||
"summary": {
|
||||
"total_categories": 8,
|
||||
"total_kpis": 64,
|
||||
|
||||
149
token-health-dashboard.html
Normal file
149
token-health-dashboard.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr"><head><meta charset="UTF-8"><title>Token Health Dashboard · WEVAL</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<style>
|
||||
*{margin:0;padding:0;box-sizing:border-box;font-family:-apple-system,'Segoe UI',sans-serif}
|
||||
body{background:#060d1a;color:#e2e8f0;min-height:100vh;padding:20px}
|
||||
.container{max-width:1200px;margin:0 auto}
|
||||
h1{font-family:'Orbitron',sans-serif;background:linear-gradient(135deg,#06b6d4,#a855f7);
|
||||
-webkit-background-clip:text;-webkit-text-fill-color:transparent;
|
||||
font-size:2rem;margin-bottom:8px;letter-spacing:1px}
|
||||
.subtitle{color:#94a3b8;margin-bottom:24px;font-size:0.9rem}
|
||||
.hero{background:linear-gradient(135deg,rgba(6,182,212,0.08),rgba(168,85,247,0.08));
|
||||
border:1px solid rgba(6,182,212,0.25);border-radius:16px;padding:24px;margin-bottom:24px;
|
||||
backdrop-filter:blur(12px)}
|
||||
.hero-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:16px}
|
||||
.stat{text-align:center}
|
||||
.stat-val{font-family:'Orbitron',sans-serif;font-size:2.5rem;font-weight:900;line-height:1}
|
||||
.stat-val.danger{color:#ef4444}
|
||||
.stat-val.warn{color:#f59e0b}
|
||||
.stat-val.success{color:#22c55e}
|
||||
.stat-lbl{font-size:0.7rem;color:#64748b;text-transform:uppercase;letter-spacing:1.5px;margin-top:6px}
|
||||
.providers{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;margin-bottom:24px}
|
||||
.provider{background:rgba(15,23,42,0.8);border:1px solid rgba(100,116,139,0.15);
|
||||
border-radius:12px;padding:14px 16px;transition:all 0.2s}
|
||||
.provider.ok{border-left:3px solid #22c55e}
|
||||
.provider.expired{border-left:3px solid #ef4444;background:rgba(239,68,68,0.05)}
|
||||
.provider-name{font-weight:700;font-size:0.95rem;display:flex;justify-content:space-between;align-items:center}
|
||||
.badge{padding:2px 8px;border-radius:10px;font-size:0.65rem;font-weight:700;text-transform:uppercase}
|
||||
.badge.ok{background:rgba(34,197,94,0.15);color:#22c55e}
|
||||
.badge.expired{background:rgba(239,68,68,0.15);color:#ef4444}
|
||||
.provider-meta{font-size:0.75rem;color:#94a3b8;margin-top:6px}
|
||||
.provider-action{margin-top:10px;display:flex;gap:8px;flex-wrap:wrap}
|
||||
.btn{padding:4px 10px;border-radius:6px;font-size:0.7rem;font-weight:700;cursor:pointer;
|
||||
text-decoration:none;border:none;transition:all 0.15s}
|
||||
.btn-primary{background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#fff}
|
||||
.btn-secondary{background:rgba(100,116,139,0.15);color:#94a3b8;border:1px solid rgba(100,116,139,0.25)}
|
||||
.btn:hover{transform:translateY(-1px);opacity:0.9}
|
||||
.runbook{background:rgba(15,23,42,0.8);border:1px solid rgba(100,116,139,0.15);
|
||||
border-radius:12px;padding:20px;margin-top:24px}
|
||||
.runbook h2{color:#06b6d4;font-size:1.2rem;margin-bottom:14px;
|
||||
border-left:3px solid #06b6d4;padding-left:10px}
|
||||
.runbook-step{padding:12px;margin:10px 0;background:rgba(11,13,21,0.6);border-radius:8px;border-left:3px solid rgba(168,85,247,0.4)}
|
||||
.runbook-step strong{color:#c084fc}
|
||||
code{background:#0f0f15;color:#22c55e;padding:2px 6px;border-radius:4px;font-size:0.85em}
|
||||
</style></head><body>
|
||||
<div class="container">
|
||||
<h1>🔑 Token Health Dashboard</h1>
|
||||
<p class="subtitle">Monitoring centralisé des credentials API providers · cascade souveraine WEVIA</p>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-stats" id="hero-stats">
|
||||
<div class="stat"><div class="stat-val warn" id="stat-health">—</div><div class="stat-lbl">Health</div></div>
|
||||
<div class="stat"><div class="stat-val success" id="stat-ok">—</div><div class="stat-lbl">Actifs</div></div>
|
||||
<div class="stat"><div class="stat-val danger" id="stat-exp">—</div><div class="stat-lbl">Expirés</div></div>
|
||||
<div class="stat"><div class="stat-val" id="stat-total">—</div><div class="stat-lbl">Total</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 style="color:#06b6d4;margin-bottom:14px;border-left:3px solid #06b6d4;padding-left:10px">Providers Status</h2>
|
||||
<div class="providers" id="providers-grid"><div style="color:#64748b">Chargement live...</div></div>
|
||||
|
||||
<section class="runbook">
|
||||
<h2>📘 Runbook Rotation Tokens (manuel ou via Selenium blueprint)</h2>
|
||||
|
||||
<div class="runbook-step">
|
||||
<strong>Groq</strong> · dashboard: <code>https://console.groq.com/keys</code><br>
|
||||
1. Se connecter avec yacineutt@gmail.com<br>
|
||||
2. Créer nouvelle API key · label: <code>weval-prod-2026</code><br>
|
||||
3. Copier dans <code>/etc/weval/secrets.env</code> → <code>GROQ_API_KEY=gsk_...</code><br>
|
||||
4. Reload: <code>sudo systemctl reload php8.5-fpm</code>
|
||||
</div>
|
||||
|
||||
<div class="runbook-step">
|
||||
<strong>SambaNova</strong> · dashboard: <code>https://cloud.sambanova.ai/</code><br>
|
||||
1. Se connecter avec yacineutt@gmail.com<br>
|
||||
2. Settings → API Keys → Generate new<br>
|
||||
3. Update <code>SAMBANOVA_API_KEY=...</code> dans secrets.env
|
||||
</div>
|
||||
|
||||
<div class="runbook-step">
|
||||
<strong>Alibaba (DashScope)</strong> · dashboard: <code>https://dashscope.console.aliyun.com/</code><br>
|
||||
1. Login Chinese account<br>
|
||||
2. API Key Management → Create new<br>
|
||||
3. Update <code>ALIBABA_API_KEY=sk-...</code> dans secrets.env
|
||||
</div>
|
||||
|
||||
<div class="runbook-step">
|
||||
<strong>GitHub PAT</strong> · dashboard: <code>https://github.com/settings/tokens?type=beta</code><br>
|
||||
1. Regenerate → copy new <code>ghp_...</code><br>
|
||||
2. Update <code>GITHUB_PAT=ghp_...</code> dans secrets.env<br>
|
||||
3. Test: <code>sudo git push origin main</code>
|
||||
</div>
|
||||
|
||||
<div class="runbook-step">
|
||||
<strong>Blueprint Selenium automatisé</strong> · voir <code>/opt/obsidian-vault/doctrines/tips-6-mois-cracked.md</code><br>
|
||||
Script Python + Selenium Grid Docker + Chrome + YacineUTT session sync
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="margin-top:20px;text-align:center;color:#64748b;font-size:0.85rem">
|
||||
<button class="btn btn-primary" onclick="location.reload()">🔄 Refresh</button>
|
||||
<a href="/wiki.html" class="btn btn-secondary">📘 Wiki</a>
|
||||
<a href="/wtp-udock-coverage.html" class="btn btn-secondary">📊 WTP Dashboard</a>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
fetch('/api/wevia-autonomy-status.json', {cache:'no-store'})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
const alerts = d.alerts || [];
|
||||
const expiredList = alerts.filter(a => a.msg && /expir/i.test(a.msg)).map(a => {
|
||||
const m = a.msg.match(/Token\s+(\w+)/i);
|
||||
return m ? m[1].toLowerCase() : null;
|
||||
}).filter(Boolean);
|
||||
|
||||
const KNOWN = ['cerebras','groq','deepseek','mistral','together','openrouter','sambanova',
|
||||
'alibaba','gemini','nvidia-nim','cohere','huggingface','replicate','zhipu',
|
||||
'anthropic','github','whatsapp'];
|
||||
|
||||
const health = Math.round((KNOWN.length - expiredList.length) / KNOWN.length * 100);
|
||||
document.getElementById('stat-health').textContent = health + '%';
|
||||
document.getElementById('stat-ok').textContent = KNOWN.length - expiredList.length;
|
||||
document.getElementById('stat-exp').textContent = expiredList.length;
|
||||
document.getElementById('stat-total').textContent = KNOWN.length;
|
||||
|
||||
const grid = document.getElementById('providers-grid');
|
||||
grid.innerHTML = '';
|
||||
KNOWN.forEach(p => {
|
||||
const isExpired = expiredList.includes(p);
|
||||
const card = document.createElement('div');
|
||||
card.className = 'provider ' + (isExpired ? 'expired' : 'ok');
|
||||
card.innerHTML = `
|
||||
<div class="provider-name">
|
||||
<span>${p}</span>
|
||||
<span class="badge ${isExpired?'expired':'ok'}">${isExpired?'EXPIRED':'OK'}</span>
|
||||
</div>
|
||||
<div class="provider-meta">${isExpired ? '⚠️ Rotation requise' : '✅ Active'}</div>
|
||||
${isExpired ? '<div class="provider-action"><button class="btn btn-primary" onclick="alert(\'Voir runbook dans cette page pour '+p+'\')">Rotate</button></div>' : ''}
|
||||
`;
|
||||
grid.appendChild(card);
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
document.getElementById('providers-grid').innerHTML = '<div style="color:#ef4444">Erreur: ' + e.message + '</div>';
|
||||
});
|
||||
</script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t39) --><script src=\/wtp-unified-dock.js\ defer></script>
|
||||
</body></html>
|
||||
@@ -3350,6 +3350,144 @@ if (typeof window.navigateTo === 'function'){
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<section id="wtp-drill-resolver-wave214" data-added-by="opus-wave-214" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#3b0764 0%,#083344 100%);border:1px solid #a855f7;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(168,85,247,.2)">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
|
||||
<div>
|
||||
<div style="display:flex;align-items:center;gap:10px">
|
||||
<span style="font-size:22px">🧩</span>
|
||||
<h2 style="margin:0;color:#e9d5ff;font-size:20px;font-weight:700">Drill-down 7σ Fails · Resolver Catalog</h2>
|
||||
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#a855f7,#22d3ee);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 214</span>
|
||||
</div>
|
||||
<p style="margin:4px 0 0 0;color:#c4b5fd;font-size:12.5px">49 dimensions à fixer vers 7σ · 310 intents Resolver · 224 wired · gap 86</p>
|
||||
</div>
|
||||
<div id="wtp-dr-status" style="padding:6px 14px;border-radius:16px;background:rgba(168,85,247,.15);color:#ddd6fe;font-size:11px;font-weight:600;border:1px solid rgba(168,85,247,.3)">LOADING</div>
|
||||
</div>
|
||||
|
||||
<!-- Two columns: 7σ fails + Resolver catalog -->
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:16px">
|
||||
|
||||
<!-- 7σ Fails drill-down -->
|
||||
<div style="padding:18px;background:rgba(255,255,255,.03);border:1px solid rgba(251,146,60,.25);border-radius:10px">
|
||||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
|
||||
<span style="font-size:18px">🎯</span>
|
||||
<h3 style="margin:0;color:#fed7aa;font-size:14px;font-weight:700">7σ Fails par page</h3>
|
||||
<span id="wtp-dr-7s-count" style="margin-left:auto;padding:2px 8px;border-radius:10px;background:rgba(251,146,60,.15);color:#fdba74;font-size:10px;font-weight:700">...</span>
|
||||
</div>
|
||||
<div id="wtp-dr-7s-grid" style="max-height:340px;overflow-y:auto"></div>
|
||||
</div>
|
||||
|
||||
<!-- Resolver Catalog -->
|
||||
<div style="padding:18px;background:rgba(255,255,255,.03);border:1px solid rgba(139,92,246,.25);border-radius:10px">
|
||||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
|
||||
<span style="font-size:18px">🧠</span>
|
||||
<h3 style="margin:0;color:#ddd6fe;font-size:14px;font-weight:700">Resolver Catalog</h3>
|
||||
<span id="wtp-dr-res-count" style="margin-left:auto;padding:2px 8px;border-radius:10px;background:rgba(139,92,246,.15);color:#c4b5fd;font-size:10px;font-weight:700">...</span>
|
||||
</div>
|
||||
<div id="wtp-dr-res-kpi" style="display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:12px"></div>
|
||||
<div id="wtp-dr-res-domains" style="max-height:270px;overflow-y:auto"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
function dimChip(name, ok){
|
||||
var col = ok ? '#10b981' : '#ef4444';
|
||||
return '<span style="padding:1px 6px;border-radius:8px;background:'+col+'22;color:'+col+';font-size:9.5px;font-weight:700;font-family:monospace;margin:1px">'+name+'</span>';
|
||||
}
|
||||
function pageRow(pg){
|
||||
var fails = pg.fails || [];
|
||||
var total_dims = pg.total_dims || 0;
|
||||
var name = pg.id || pg.url || '?';
|
||||
var col = fails.length === 0 ? '#10b981' : (fails.length <= 2 ? '#fbbf24' : '#ef4444');
|
||||
var chips = fails.map(function(f){ return dimChip(f,false); }).join('');
|
||||
return '<div style="padding:8px 10px;margin-bottom:6px;background:rgba(255,255,255,.02);border-left:3px solid '+col+';border-radius:4px">'
|
||||
+'<div style="display:flex;align-items:center;justify-content:space-between;gap:8px"><div style="font-size:11.5px;color:#fed7aa;font-family:monospace;font-weight:600">'+name+'</div><div style="font-size:10px;color:'+col+';font-weight:700">'+fails.length+' fails</div></div>'
|
||||
+'<div style="margin-top:4px">'+chips+'</div>'
|
||||
+'</div>';
|
||||
}
|
||||
function kpiCard(label, value, color){
|
||||
return '<div style="padding:8px 10px;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.18);border-radius:6px;text-align:center">'
|
||||
+'<div style="font-size:9.5px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.4px">'+label+'</div>'
|
||||
+'<div style="font-size:18px;font-weight:700;color:'+color+';margin-top:2px">'+value+'</div>'
|
||||
+'</div>';
|
||||
}
|
||||
function domainChip(name, info){
|
||||
var cnt = (typeof info === 'number') ? info : (info.count || info.intents || 0);
|
||||
return '<div style="display:flex;align-items:center;justify-content:space-between;padding:6px 10px;margin-bottom:4px;background:rgba(139,92,246,.05);border:1px solid rgba(139,92,246,.12);border-radius:6px;font-size:11px;color:#ddd6fe"><span style="font-family:monospace">'+name+'</span><span style="font-weight:700;color:#a78bfa">'+cnt+'</span></div>';
|
||||
}
|
||||
|
||||
function render(){
|
||||
// 7σ fails
|
||||
fetch('/api/seven-sigma-latest.json?cb='+Date.now())
|
||||
.then(function(r){return r.json();})
|
||||
.then(function(d){
|
||||
var pages = d.pages || [];
|
||||
var grid = document.getElementById('wtp-dr-7s-grid');
|
||||
var badge = document.getElementById('wtp-dr-7s-count');
|
||||
if (!grid) return;
|
||||
var total_fails = 0;
|
||||
var items = pages.map(function(p){
|
||||
var dims = p.dimensions || {};
|
||||
var fails = [];
|
||||
Object.keys(dims).forEach(function(k){
|
||||
var v = dims[k];
|
||||
if (v && typeof v === 'object' && (v.status === 'FAIL' || v.status === 'fail')) fails.push(k);
|
||||
});
|
||||
total_fails += fails.length;
|
||||
return {id: p.id || p.url, fails: fails, total_dims: Object.keys(dims).length};
|
||||
}).sort(function(a,b){return b.fails.length - a.fails.length;});
|
||||
if (badge) badge.textContent = total_fails+' fails / '+pages.length+' pages';
|
||||
grid.innerHTML = items.map(pageRow).join('');
|
||||
})
|
||||
.catch(function(){
|
||||
var grid = document.getElementById('wtp-dr-7s-grid');
|
||||
if (grid) grid.innerHTML = '<div style="color:#f87171;font-size:11px;padding:10px">seven-sigma unavailable</div>';
|
||||
});
|
||||
|
||||
// Resolver catalog
|
||||
fetch('/api/arena-intent-registry.json?cb='+Date.now())
|
||||
.then(function(r){return r.json();})
|
||||
.then(function(d){
|
||||
var kpi = document.getElementById('wtp-dr-res-kpi');
|
||||
var doms = document.getElementById('wtp-dr-res-domains');
|
||||
var cnt = document.getElementById('wtp-dr-res-count');
|
||||
var wired = d.wired || 0;
|
||||
var gap = d.gap || 0;
|
||||
var total = d.total_intents || (wired + gap);
|
||||
var pct = total ? Math.round(wired*100/total) : 0;
|
||||
if (cnt) cnt.textContent = wired+'/'+total+' ('+pct+'%)';
|
||||
if (kpi) {
|
||||
kpi.innerHTML = kpiCard('INTENTS', total, '#ddd6fe')
|
||||
+ kpiCard('SKILLS', d.total_skills||0, '#c4b5fd')
|
||||
+ kpiCard('WIRED', wired, '#10b981')
|
||||
+ kpiCard('GAP', gap, gap===0?'#10b981':'#fbbf24');
|
||||
}
|
||||
if (doms) {
|
||||
var domains = d.domains || {};
|
||||
var html = '<div style="font-size:10px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px">Domains · '+Object.keys(domains).length+'</div>';
|
||||
if (Array.isArray(domains)) {
|
||||
html += domains.map(function(n){return domainChip(n, 0);}).join('');
|
||||
} else {
|
||||
Object.keys(domains).forEach(function(k){ html += domainChip(k, domains[k]); });
|
||||
}
|
||||
doms.innerHTML = html;
|
||||
}
|
||||
})
|
||||
.catch(function(){
|
||||
var doms = document.getElementById('wtp-dr-res-domains');
|
||||
if (doms) doms.innerHTML = '<div style="color:#f87171;font-size:11px;padding:10px">registry unavailable</div>';
|
||||
});
|
||||
|
||||
var status = document.getElementById('wtp-dr-status');
|
||||
if (status) { status.textContent = 'LIVE'; status.style.background='rgba(16,185,129,.2)'; status.style.color='#6ee7b7'; }
|
||||
}
|
||||
render();
|
||||
setInterval(render, 180000);
|
||||
})();
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<section id="wtp-visual-mgmt-wave212" data-added-by="opus-wave-212" style="margin:32px 16px 20px;padding:28px;background:linear-gradient(135deg,#164e63 0%,#1e3a8a 100%);border:1px solid #0ea5e9;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(14,165,233,.2)">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user