auto-sync via WEVIA git_sync_all intent 2026-04-21T11:33:11+02:00
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
This commit is contained in:
@@ -82,6 +82,10 @@ body.light #theme-toggle::before{content:"\263D"}
|
||||
|
||||
#v-dashboards .dash-tile.pinned{box-shadow:0 0 0 1px rgba(251,191,36,0.3)}
|
||||
#v-dashboards .dash-tile.pinned:hover{box-shadow:0 4px 12px rgba(251,191,36,0.35)!important}
|
||||
/* V137-REFRESH spin keyframe */
|
||||
@keyframes v137spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
||||
#v137-refresh-btn:hover{background:var(--bg3)}
|
||||
#v137-refresh-btn:disabled{opacity:0.7;cursor:wait}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -115,7 +119,9 @@ body.light #theme-toggle::before{content:"\263D"}
|
||||
<a href="/wevcode.html" style="color:var(--mu);text-decoration:none;padding:3px 8px;border-radius:4px;transition:all 0.15s" onmouseover="this.style.background='var(--bg3)';this.style.color='#6ee7b7'" onmouseout="this.style.background='';this.style.color='var(--mu)'" title="WevCode · Sovereign Coding Agent v2.0">💻 WevCode</a>
|
||||
<span style="color:var(--mu);opacity:0.3">·</span>
|
||||
<a href="/wevia-unified-hub.html" style="color:var(--mu);text-decoration:none;padding:3px 8px;border-radius:4px;transition:all 0.15s" onmouseover="this.style.background='var(--bg3)';this.style.color='#00d4b4'" onmouseout="this.style.background='';this.style.color='var(--mu)'" title="WEVIA Unified Hub · Truth Registry source unique">🧠 Truth Hub</a>
|
||||
<span id="v135-kpi-live" onclick="__v136ShowHealthModal()" style="margin-left:auto;color:var(--mu);font-size:9px;cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-decoration-color:rgba(255,255,255,0.2)" title="Platform health live · click pour détail">All-IA Hub · consolidation 84 dashboards</span>
|
||||
<!-- V137-REFRESH: manual refresh button + fresh indicator -->
|
||||
<button id="v137-refresh-btn" onclick="event.stopPropagation();__v137RefreshHealth()" style="margin-left:auto;background:transparent;border:1px solid var(--bd);color:var(--mu);border-radius:4px;padding:2px 6px;cursor:pointer;font-size:10px;transition:all 0.15s" title="Refresh health live" onmouseover="this.style.color='var(--ac)';this.style.borderColor='var(--vl)'" onmouseout="this.style.color='var(--mu)';this.style.borderColor='var(--bd)'">↺</button>
|
||||
<span id="v135-kpi-live" onclick="__v136ShowHealthModal()" style="color:var(--mu);font-size:9px;cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-decoration-color:rgba(255,255,255,0.2)" title="Platform health live · click pour détail">All-IA Hub · consolidation 84 dashboards</span>
|
||||
</div>
|
||||
<!-- V136-HEALTH-MODAL: in-page modal for broken URLs drill-down -->
|
||||
<div id="v136-health-modal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.75);z-index:10000;align-items:center;justify-content:center;padding:24px" onclick="if(event.target.id==='v136-health-modal')__v136HideHealthModal()">
|
||||
@@ -996,11 +1002,14 @@ document.addEventListener('keydown', function(e){
|
||||
}
|
||||
});
|
||||
|
||||
/* V135-KPI-BANNER: load screens-health summary and update banner (zero impact on UX if fetch fails) */
|
||||
(function(){
|
||||
/* V135-KPI-BANNER (V137 refactored): named async function, reusable by V137 refresh */
|
||||
async function __v135UpdateHealthBanner(){
|
||||
const kpi = document.getElementById('v135-kpi-live');
|
||||
if (!kpi) return;
|
||||
fetch('/api/screens-health.json', {cache: 'no-store'}).then(r => r.ok ? r.json() : null).then(d => {
|
||||
try {
|
||||
const r = await fetch('/api/screens-health.json', {cache: 'no-store'});
|
||||
if (!r.ok) return;
|
||||
const d = await r.json();
|
||||
if (!d || !d.counts) return;
|
||||
const c = d.counts;
|
||||
const total = d.total || 0;
|
||||
@@ -1011,10 +1020,40 @@ document.addEventListener('keydown', function(e){
|
||||
const active = total - phantom;
|
||||
const healthPct = active ? Math.round((up / active) * 100) : 0;
|
||||
const dot = (broken + down === 0) ? '\u{1F7E2}' : (broken + down < 20 ? '\u{1F7E1}' : '\u{1F534}');
|
||||
kpi.innerHTML = 'All-IA Hub · ' + dot + ' ' + healthPct + '% (' + up + ' UP · ' + broken + ' broken)';
|
||||
kpi.title = 'Platform health: ' + up + ' UP / ' + broken + ' BROKEN / ' + down + ' DOWN / ' + phantom + ' phantom (total ' + total + ')';
|
||||
}).catch(_ => {});
|
||||
})();
|
||||
// V137: compute scan age
|
||||
let ageStr = '';
|
||||
if (d.generated_at) {
|
||||
const scanMs = new Date(d.generated_at).getTime();
|
||||
if (!isNaN(scanMs)) {
|
||||
const ageMin = Math.floor((Date.now() - scanMs) / 60000);
|
||||
ageStr = ageMin < 1 ? ' · <span style="color:#10b981">just now</span>'
|
||||
: ageMin < 60 ? ' · ' + ageMin + 'min ago'
|
||||
: ' · ' + Math.floor(ageMin/60) + 'h ago';
|
||||
}
|
||||
}
|
||||
kpi.innerHTML = 'All-IA Hub · ' + dot + ' ' + healthPct + '% (' + up + ' UP · ' + broken + ' broken)' + ageStr;
|
||||
kpi.title = 'Platform health: ' + up + ' UP / ' + broken + ' BROKEN / ' + down + ' DOWN / ' + phantom + ' phantom (total ' + total + ')\nScan: ' + (d.generated_at || 'n/a') + '\nClick: détail · Bouton \u21BA: refresh';
|
||||
} catch (_) {}
|
||||
}
|
||||
/* V137-REFRESH: manual refresh with spin animation */
|
||||
async function __v137RefreshHealth(){
|
||||
const btn = document.getElementById('v137-refresh-btn');
|
||||
if (btn) {
|
||||
btn.style.animation = 'v137spin 0.8s linear infinite';
|
||||
btn.style.color = 'var(--vl)';
|
||||
btn.disabled = true;
|
||||
}
|
||||
await __v135UpdateHealthBanner();
|
||||
if (btn) {
|
||||
setTimeout(() => {
|
||||
btn.style.animation = '';
|
||||
btn.style.color = '';
|
||||
btn.disabled = false;
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
/* Initial load */
|
||||
__v135UpdateHealthBanner();
|
||||
|
||||
setTimeout(() => {
|
||||
const btn = document.querySelector('[data-view="dashboards"]');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_Disk_Monitor",
|
||||
"ts": "2026-04-21T11:00:02+02:00",
|
||||
"ts": "2026-04-21T11:30:02+02:00",
|
||||
"disk_pct": 81,
|
||||
"disk_free_gb": 29,
|
||||
"growth_per_day_gb": 1.5,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_Risk_Escalation",
|
||||
"ts": "2026-04-21T11:15:04+02:00",
|
||||
"ts": "2026-04-21T11:30:03+02:00",
|
||||
"dg_alerts_active": 7,
|
||||
"wevia_life_stats_preview": "{
|
||||
"ok": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V45_Leads_Sync",
|
||||
"ts": "2026-04-21T11:20:03+02:00",
|
||||
"ts": "2026-04-21T11:30:05+02:00",
|
||||
"paperclip_total": 48,
|
||||
"active_customer": 4,
|
||||
"warm_prospect": 5,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"agent": "V54_Risk_Monitor_Live",
|
||||
"ts": "2026-04-21T11:00:04+02:00",
|
||||
"ts": "2026-04-21T11:30:04+02:00",
|
||||
"critical_risks": {
|
||||
"RW01_pipeline_vide": {
|
||||
"pipeline_keur": 0,
|
||||
"mql_auto": 19,
|
||||
"residual_risk_pct": 81,
|
||||
"mql_auto": 18,
|
||||
"residual_risk_pct": 82,
|
||||
"trend": "mitigation_V42_V45_active"
|
||||
},
|
||||
"RW02_dependance_ethica": {
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"RW12_burnout": {
|
||||
"agents_cron_active": 15,
|
||||
"load_5min": "7.66",
|
||||
"load_5min": "9.91",
|
||||
"automation_coverage_pct": 70,
|
||||
"residual_risk_pct": 60,
|
||||
"trend": "V52_goldratt_options_active"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-04-21T11:25:01.937710",
|
||||
"generated_at": "2026-04-21T11:30:02.716772",
|
||||
"stats": {
|
||||
"total": 48,
|
||||
"pending": 31,
|
||||
|
||||
13
api/blade-tasks/v137-refresh-proof/proof.json
Normal file
13
api/blade-tasks/v137-refresh-proof/proof.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"v137": "refresh-button-age-indicator",
|
||||
"btn_exists": true,
|
||||
"age_indicator_in_banner": true,
|
||||
"scan_info_in_tooltip": true,
|
||||
"spin_animation_active": true,
|
||||
"btn_disabled_during": true,
|
||||
"btn_reenabled_after": true,
|
||||
"banner_click_still_opens_modal": true,
|
||||
"refresh_click_stopPropagation_works": true,
|
||||
"js_errors": [],
|
||||
"VERDICT": "OK"
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
{
|
||||
"ts": "2026-04-21T09:30:02+00:00",
|
||||
"server": "s204",
|
||||
"s204": {
|
||||
"load": 7.65,
|
||||
"uptime": "2026-04-14 11:51:24",
|
||||
"ram_total_mb": 31335,
|
||||
"ram_used_mb": 11757,
|
||||
"ram_free_mb": 19577,
|
||||
"disk_total": "150G",
|
||||
"disk_used": "116G",
|
||||
"disk_free": "29G",
|
||||
"disk_pct": "81%",
|
||||
"fpm_workers": 140,
|
||||
"docker_containers": 19,
|
||||
"cpu_cores": 8
|
||||
},
|
||||
"s95": {
|
||||
"load": 0.24,
|
||||
"disk_pct": "81%",
|
||||
"status": "UP",
|
||||
"ram_total_mb": 15610,
|
||||
"ram_free_mb": 12049
|
||||
},
|
||||
"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": 293,
|
||||
"php_apis": 775,
|
||||
"wiki_entries": 1928,
|
||||
"vault_doctrines": 59,
|
||||
"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": 110589,
|
||||
"with_phone": 155151,
|
||||
"gap_email": 51144,
|
||||
"pct_email": 68.4,
|
||||
"pct_phone": 95.9,
|
||||
"by_country": [
|
||||
{
|
||||
"country": "DZ",
|
||||
"hcps": 122337,
|
||||
"with_email": 78491,
|
||||
"with_tel": 119396,
|
||||
"pct_email": 64.2,
|
||||
"pct_tel": 97.6
|
||||
},
|
||||
{
|
||||
"country": "MA",
|
||||
"hcps": 19723,
|
||||
"with_email": 15074,
|
||||
"with_tel": 18737,
|
||||
"pct_email": 76.4,
|
||||
"pct_tel": 95
|
||||
},
|
||||
{
|
||||
"country": "TN",
|
||||
"hcps": 17794,
|
||||
"with_email": 15145,
|
||||
"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 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "listmonk",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-1",
|
||||
"status": "Up 3 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-db-1",
|
||||
"status": "Up 3 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-events-db-1",
|
||||
"status": "Up 3 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 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 33 hours (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"status": "Up 6 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
}
|
||||
],
|
||||
"crons": {
|
||||
"active": 35
|
||||
},
|
||||
"git": {
|
||||
"head": "b50dbcb4e auto-sync-1130",
|
||||
"dirty": 7,
|
||||
"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": 3701,
|
||||
"health": {
|
||||
"score": 4,
|
||||
"max": 6,
|
||||
"pct": 67
|
||||
},
|
||||
"elapsed_ms": 11021
|
||||
}
|
||||
@@ -1,27 +1,27 @@
|
||||
{
|
||||
"ok": true,
|
||||
"agent": "V42_MQL_Scoring_Agent_REAL",
|
||||
"ts": "2026-04-21T09:20:02+00:00",
|
||||
"ts": "2026-04-21T09:30:02+00:00",
|
||||
"status": "DEPLOYED_AUTO",
|
||||
"deployed": true,
|
||||
"algorithm": "weighted_behavioral_signals",
|
||||
"signals_tracked": {
|
||||
"wtp_engagement": 100,
|
||||
"wtp_engagement": 40,
|
||||
"chat_engagement": 0,
|
||||
"roi_tool": 0,
|
||||
"email_opened": 0
|
||||
},
|
||||
"avg_score": 25,
|
||||
"avg_score": 10,
|
||||
"mql_threshold": 50,
|
||||
"sql_threshold": 75,
|
||||
"leads_captured": 48,
|
||||
"mql_auto_scored": 20,
|
||||
"sql_auto_scored": 8,
|
||||
"mql_auto_pct": 41,
|
||||
"mql_auto_scored": 18,
|
||||
"sql_auto_scored": 7,
|
||||
"mql_auto_pct": 38,
|
||||
"improvement_vs_manual": {
|
||||
"before_manual_pct": 33.3,
|
||||
"after_auto_pct": 41,
|
||||
"delta": 7.700000000000003
|
||||
"after_auto_pct": 38,
|
||||
"delta": 4.700000000000003
|
||||
},
|
||||
"paperclip_db_ok": true,
|
||||
"paperclip_tables": 1,
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"ts": "20260421_111819", "version": "3.2", "score": 100, "pass": 153, "fail": 0, "total": 153, "elapsed": 57.9, "categories": {"S204": {"pass": 9, "fail": 0}, "S95-WV": {"pass": 12, "fail": 0}, "S95-ARS": {"pass": 17, "fail": 0}, "S95-iR": {"pass": 1, "fail": 0}, "INFRA": {"pass": 5, "fail": 0}, "API": {"pass": 27, "fail": 0}, "SEC": {"pass": 4, "fail": 0}, "S95-BK": {"pass": 6, "fail": 0}, "C2-API": {"pass": 4, "fail": 0}, "C2-SPA": {"pass": 1, "fail": 0}, "C2-WV": {"pass": 3, "fail": 0}, "SSO": {"pass": 25, "fail": 0}, "DATA": {"pass": 5, "fail": 0}, "CRONS": {"pass": 2, "fail": 0}, "BLADE": {"pass": 7, "fail": 0}, "LIFE": {"pass": 3, "fail": 0}, "FUNC": {"pass": 7, "fail": 0}, "01AVR": {"pass": 10, "fail": 0}, "STRUCT": {"pass": 5, "fail": 0}}, "failures": []}
|
||||
{"ts": "20260421_113016", "version": "3.2", "score": 100, "pass": 153, "fail": 0, "total": 153, "elapsed": 67.1, "categories": {"S204": {"pass": 9, "fail": 0}, "S95-WV": {"pass": 12, "fail": 0}, "S95-ARS": {"pass": 17, "fail": 0}, "S95-iR": {"pass": 1, "fail": 0}, "INFRA": {"pass": 5, "fail": 0}, "API": {"pass": 27, "fail": 0}, "SEC": {"pass": 4, "fail": 0}, "S95-BK": {"pass": 6, "fail": 0}, "C2-API": {"pass": 4, "fail": 0}, "C2-SPA": {"pass": 1, "fail": 0}, "C2-WV": {"pass": 3, "fail": 0}, "SSO": {"pass": 25, "fail": 0}, "DATA": {"pass": 5, "fail": 0}, "CRONS": {"pass": 2, "fail": 0}, "BLADE": {"pass": 7, "fail": 0}, "LIFE": {"pass": 3, "fail": 0}, "FUNC": {"pass": 7, "fail": 0}, "01AVR": {"pass": 10, "fail": 0}, "STRUCT": {"pass": 5, "fail": 0}}, "failures": []}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"timestamp": "2026-04-21T11:00:15",
|
||||
"timestamp": "2026-04-21T11:30:15",
|
||||
"features": {
|
||||
"total": 36,
|
||||
"pass": 35
|
||||
@@ -13,7 +13,7 @@
|
||||
"score": 97.2,
|
||||
"log": [
|
||||
"=== UX AGENT v1.0 ===",
|
||||
"Time: 2026-04-21 11:00:02",
|
||||
"Time: 2026-04-21 11:30:02",
|
||||
" core: 4/4",
|
||||
" layout: 3/4",
|
||||
" interaction: 6/6",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"version": "V83-business-kpi",
|
||||
"ts": "2026-04-21T09:25:25+00:00",
|
||||
"ts": "2026-04-21T09:30:29+00:00",
|
||||
"summary": {
|
||||
"total_categories": 8,
|
||||
"total_kpis": 64,
|
||||
|
||||
@@ -2819,6 +2819,9 @@ if (typeof window.navigateTo === 'function'){
|
||||
<div><span style="color:#64748b">Tips:</span> <b id="erp-kpi-tips" style="color:#f9a8d4">⏳</b></div>
|
||||
<div><span style="color:#64748b">Orphans:</span> <b id="erp-kpi-orphans" style="color:#10b981">⏳</b></div>
|
||||
<div><span style="color:#64748b">Pillars HTTP:</span> <b id="erp-kpi-pillars" style="color:#fbbf24">⏳</b></div>
|
||||
<div><span style="color:#64748b">Agents:</span> <b id="erp-kpi-agents" style="color:#00d4b4">⏳</b></div>
|
||||
<div><span style="color:#64748b">Skills:</span> <b id="erp-kpi-skills" style="color:#a78bfa">⏳</b></div>
|
||||
<div><span style="color:#64748b">Brains:</span> <b id="erp-kpi-brains" style="color:#ec4899">⏳</b></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3001,6 +3004,24 @@ if (typeof window.navigateTo === 'function'){
|
||||
if (nrMatch) document.getElementById('erp-kpi-nonreg').textContent = nrMatch[1];
|
||||
} catch(e) {}
|
||||
|
||||
// 7bis. Truth Registry KPIs: agents/skills/brains
|
||||
try {
|
||||
const r = await fetch('/api/wevia-truth-registry.json');
|
||||
const tr = await r.json();
|
||||
const ag = tr.agents || {};
|
||||
const sk = tr.skills || {};
|
||||
const br = tr.brains || {};
|
||||
if (ag.count_unique) document.getElementById('erp-kpi-agents').textContent = ag.count_unique;
|
||||
// skills count may be number or object with total
|
||||
let skc = typeof sk === 'number' ? sk : (sk.count_total || sk.count || (sk.items && sk.items.length) || 0);
|
||||
if (!skc && typeof sk === 'object') {
|
||||
skc = Object.values(sk).reduce((a,b) => a + (typeof b === 'number' ? b : 0), 0);
|
||||
}
|
||||
if (skc) document.getElementById('erp-kpi-skills').textContent = skc.toLocaleString('fr-FR');
|
||||
let brc = typeof br === 'number' ? br : (br.count || (br.items && br.items.length) || 0);
|
||||
if (brc) document.getElementById('erp-kpi-brains').textContent = brc;
|
||||
} catch(e) { /* silent */ }
|
||||
|
||||
// 7. Orphans count (from architecture_quality intent)
|
||||
try {
|
||||
const r = await fetch('/api/wevia-master-api.php', {
|
||||
|
||||
@@ -480,4 +480,7 @@ loadData();
|
||||
|
||||
<script src="/api/v72-drilldown-universal.js" defer></script>
|
||||
<script src="/api/archi-meta-badge.js" defer></script>
|
||||
|
||||
<!-- OPUS_v932g_TRUTH_DROID -->
|
||||
<a href="/wevia-ia/droid.html" id="opus-droid-link" title="WEDROID v3.2 - 19 providers" style="position:fixed;bottom:20px;right:20px;padding:7px 14px;background:rgba(16,185,129,0.15);color:#10b981;text-decoration:none;border-radius:18px;font-size:12px;font-weight:600;border:1px solid rgba(16,185,129,0.4);backdrop-filter:blur(10px);z-index:9997">Droid</a>
|
||||
</body></html>
|
||||
|
||||
124
wiki/V137-banner-refresh-age.md
Normal file
124
wiki/V137-banner-refresh-age.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# V137 Opus WIRE - KPI Banner Refresh + Age Indicator · 21avr 11:32
|
||||
|
||||
## Context
|
||||
Yacine "CONTINUE" après V136. Poursuite polish UX additif.
|
||||
|
||||
## Scan exhaustif (doctrine #1)
|
||||
|
||||
Découverte majeure: `1924285f2` autre Claude a créé **HEXA-PIVOT ERP V107**:
|
||||
- PENTA-PIVOT → HEXA-PIVOT (6-way)
|
||||
- Ajout **wevia-unified-hub** "Source Truth Registry" (turquoise)
|
||||
- Mon V130 breadcrumb étendu de 5 liens à **6 liens**:
|
||||
← WTP · ⚔️ Arena · 🤖 WEVIA Master · 🎛️ Orchestrator · 💻 WevCode · 🧠 Truth Hub
|
||||
- Source vérité: 906 agents / 1263 intents / 15509 skills / 96 dashboards / 20 Qdrant cols
|
||||
- Mes 14 markers V107-V136 tous préservés
|
||||
|
||||
V9.68: intent `wedroid_status` wired (WEDROID 8 backend APIs accessibles via chat)
|
||||
|
||||
## Livrable V137 - Refresh + Age Indicator
|
||||
|
||||
### 1. Bouton refresh manuel (↻)
|
||||
Positionné à gauche du banner KPI dans v130-xnav:
|
||||
- Border subtile, hover purple
|
||||
- Click: spin animation `v137spin` (0.8s linear infinite)
|
||||
- Disabled pendant fetch, re-enabled après complétion
|
||||
- `event.stopPropagation()` : ne déclenche pas la modal V136
|
||||
|
||||
### 2. Age indicator dans banner
|
||||
Ajout de la fraîcheur du scan après les counts:
|
||||
- `< 1min` → "just now" (vert #10b981)
|
||||
- `< 60min` → "Xmin ago"
|
||||
- `≥ 60min` → "Xh ago"
|
||||
|
||||
Exemple live:
|
||||
```
|
||||
All-IA Hub · 🔴 85% (461 UP · 20 broken) · 1min ago
|
||||
```
|
||||
|
||||
### 3. Tooltip enrichi
|
||||
- Scan timestamp complet
|
||||
- Instructions: "Click: détail · Bouton ↻: refresh"
|
||||
|
||||
### 4. Refactoring architecture
|
||||
Transformation de l'IIFE V135 en fonction nommée `__v135UpdateHealthBanner()`:
|
||||
- Réutilisable par V137 refresh
|
||||
- Async/await propre
|
||||
- Try/catch silencieux (zero impact UX si fetch fail)
|
||||
|
||||
### CSS V137
|
||||
```css
|
||||
@keyframes v137spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
||||
#v137-refresh-btn:hover{background:var(--bg3)}
|
||||
#v137-refresh-btn:disabled{opacity:0.7;cursor:wait}
|
||||
```
|
||||
|
||||
## Validation E2E Playwright V137
|
||||
|
||||
```json
|
||||
{
|
||||
"v137": "refresh-button-age-indicator",
|
||||
"btn_exists": true,
|
||||
"age_indicator_in_banner": true,
|
||||
"scan_info_in_tooltip": true,
|
||||
"spin_animation_active": true,
|
||||
"btn_disabled_during": true,
|
||||
"btn_reenabled_after": true,
|
||||
"banner_click_still_opens_modal": true,
|
||||
"refresh_click_stopPropagation_works": true,
|
||||
"js_errors": [],
|
||||
"VERDICT": "OK"
|
||||
}
|
||||
```
|
||||
|
||||
9/9 checks passants.
|
||||
|
||||
## Banner V135 → V136 → V137 (cascade progressive)
|
||||
|
||||
```
|
||||
V135: Affichage live 🟢/🟡/🔴 XX% (UP · broken)
|
||||
↓
|
||||
V136: Banner clickable → modal drill-down (broken + slow URLs)
|
||||
↓
|
||||
V137: + Refresh button ↻ (manual, spin animation)
|
||||
+ Age indicator "Xmin ago"
|
||||
+ Tooltip enrichi Scan timestamp + instructions
|
||||
```
|
||||
|
||||
Each version builds on the previous. Zero régression, zero doublon.
|
||||
|
||||
## Architecture finale banner
|
||||
|
||||
```
|
||||
[↻ V137] All-IA Hub · 🔴 85% (461 UP · 20 broken) · 1min ago
|
||||
└─ click ↻ → refresh in place (spin 400ms)
|
||||
└─ click text → modal V136 drill-down (ESC/click-outside to close)
|
||||
└─ hover text → tooltip complet (Scan: timestamp + instructions)
|
||||
```
|
||||
|
||||
## Métriques V136 → V137
|
||||
|
||||
| | V136 | V137 |
|
||||
|---|---|---|
|
||||
| Hub size | 61.6KB | 63.4KB (+1.8KB) |
|
||||
| Refresh manuel | non | **oui** (↻ bouton spin) |
|
||||
| Age indicator | non | **oui** (just now / Xmin / Xh) |
|
||||
| Banner functions named | non (IIFE) | **oui** (async fn) |
|
||||
| Backward compat V135/V136 | - | **100%** |
|
||||
| JS errors | 0 | 0 |
|
||||
|
||||
## GOLDs préservés
|
||||
- `/opt/wevads/vault/all-ia-hub.html.GOLD-V137-pre-refresh`
|
||||
- 20 GOLDs session V107-V137 sur Hub
|
||||
|
||||
## Multi-Claude collaboration observée
|
||||
- Mon V130 breadcrumb 3-way → PENTA-PIVOT 5-way → **HEXA-PIVOT 6-way**
|
||||
- Mon V135 banner consommé par ERP Command Center V105/V106 (autre Claude)
|
||||
- Mon registry V116 source pour multiples KPI
|
||||
- Autonomie plateforme 100% GODMODE maintenue
|
||||
- V9.68 wedroid_status wired
|
||||
- Source vérité Truth Hub (906 agents / 1263 intents / 15509 skills) ajoutée
|
||||
|
||||
## Doctrines respectées
|
||||
#1 scan exhaustif · #3 GOLD · #4 honnêteté (E2E 9/9) · #13 cause racine (refactoring = architecture propre) · **#14 ADDITIF PUR** · #16 NR · **#60 UX premium** (spin feedback, age indicator, a11y) · #100
|
||||
|
||||
## Sessions consécutives sans régression applicative : **102+** 🏆
|
||||
178
wiki/session-V118-kpi-unified-endpoint.md
Normal file
178
wiki/session-V118-kpi-unified-endpoint.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# V118 - KPI Unified endpoint - Single source of truth pour tous dashboards - 2026-04-21
|
||||
|
||||
## Objectif
|
||||
Résoudre le problème de divergence KPI entre les 4 dashboards principaux
|
||||
(WTP, Master, Arena, All-IA Hub + 25 autres pages HTML) en créant
|
||||
UN SEUL endpoint unifié qui consolide toutes les sources de vérité.
|
||||
|
||||
Doctrine Yacine : *"RÉFÉRENTIELS UNIQUES PAS DE DOUBLON ÉCRAN"*.
|
||||
|
||||
## Problème identifié V115
|
||||
|
||||
Divergences KPI live observées dans `source-of-truth.json` :
|
||||
- `providers_count` = 17 (top-level scalar)
|
||||
- `counts.providers` = 15 (nested)
|
||||
- `agents_count` = 906 vs `counts.agents_total_live` = 950
|
||||
- `skills_count` = 20126 vs `counts.skills_total` = 15509
|
||||
|
||||
**25+ pages HTML** consomment source-of-truth.json avec des accès
|
||||
différents → divergences visuelles sur les KPIs.
|
||||
|
||||
Screenshots Yacine montraient : WTP=906 agents, Master bottom='0 providers',
|
||||
chacun avec sa propre logique de fetch.
|
||||
|
||||
## Solution V118
|
||||
|
||||
### Endpoint unifié `/api/kpi-unified.php` (5674 bytes)
|
||||
|
||||
Consolide en **schéma unique stable** :
|
||||
- source-of-truth.json (manually curated)
|
||||
- nonreg-latest.json (test results live)
|
||||
- token-health-cache.json (V113 cache 5min providers)
|
||||
- v83-business-kpi-latest.json (V83 summary)
|
||||
- `docker ps` shell live (containers)
|
||||
- wevia-pages-registry-cache.json (orphans)
|
||||
|
||||
### Schéma unique V118
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {"total": 17, "ok": 8, "expired": 3, "health_pct": 72.7},
|
||||
"agents": {"active": 906, "total_live": 950},
|
||||
"skills": {"count": 20126, "total": 15509},
|
||||
"intents": {"count": 1263, "total": 1263},
|
||||
"docker": {"running": 19},
|
||||
"orphans": {"count": 0, "status": "ok"},
|
||||
"nonreg": {"pass": 153, "fail": 0, "total": 153, "score": 100},
|
||||
"v83": {"kpis": 64, "ok": 38, "warn": 26, "fail": 0, "complete_pct": 100},
|
||||
"autonomy": {"score": 100, "level": "GODMODE"},
|
||||
"qdrant": {"collections": 20, "points": 17327},
|
||||
"dashboards": {"count": 96},
|
||||
"brains": {"count": 25},
|
||||
"doctrines": {"count": 19},
|
||||
"business": {
|
||||
"cash_collected_month_keur": 2.5,
|
||||
"cash_collected_ytd_keur": 7.5,
|
||||
"cash_target_month_keur": 10,
|
||||
"dso_days": 75
|
||||
},
|
||||
"ethica": {"total_hcps": 161726},
|
||||
"sources_used": {
|
||||
"source_of_truth_json": true,
|
||||
"nonreg_latest": true,
|
||||
"token_health_cache": true,
|
||||
"v83_latest": true,
|
||||
"docker_live": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Cache TTL 60s
|
||||
Pattern similaire V113 :
|
||||
- `/tmp/kpi-unified-cache.json`
|
||||
- `cache_hit=true` + `cache_age_sec=N` si cached
|
||||
- `?force=1` pour bypass admin
|
||||
|
||||
### Performance
|
||||
- Première call: 29ms
|
||||
- Cache hit: <10ms
|
||||
- Size: 1.6KB
|
||||
|
||||
## Agent Orchestrator `kpi_unified`
|
||||
|
||||
Ajouté dans `/api/wevia-autonomous.php` après `infra_health_report` (V112) :
|
||||
|
||||
```php
|
||||
"kpi_unified" => [
|
||||
"cmd" => "curl -sk http://127.0.0.1/api/kpi-unified.php | jq ...",
|
||||
"keywords" => ["kpi","unified","consolidation","single source","tableau bord","dashboard"],
|
||||
"timeout" => 8
|
||||
]
|
||||
```
|
||||
|
||||
Plan Orchestrator : **15 → 16 agents**.
|
||||
|
||||
Output multi-agent bilan : `17|906|20126|153|0|19`
|
||||
(providers|agents|skills|nonreg|orphans|docker)
|
||||
|
||||
## Validation live
|
||||
|
||||
```
|
||||
HTTP 200 size=1590 time=0.029984s
|
||||
cache_hit: true age: 50s
|
||||
providers.total: 17
|
||||
nonreg.total: 153
|
||||
```
|
||||
|
||||
## L99 NonReg V118
|
||||
```
|
||||
153/153 PASS | 0 FAIL | 100% | 67.1s
|
||||
TS: 20260421_113016
|
||||
```
|
||||
|
||||
## Migration progressive des pages HTML
|
||||
|
||||
**Non-intrusive** : les pages HTML actuelles continuent d'utiliser
|
||||
source-of-truth.json. Elles peuvent migrer à leur rythme vers
|
||||
`/api/kpi-unified.php` :
|
||||
|
||||
- **Priorité 1** : wevia-master.html (déjà V115 patché avec fallbacks robustes)
|
||||
- **Priorité 2** : weval-technology-platform.html (le point d'entrée ERP)
|
||||
- **Priorité 3** : weval-arena.html, all-ia-hub.html
|
||||
- **Rest** : 22 autres pages (agents-archi, enterprise-*, erp-gap-fill, etc.)
|
||||
|
||||
Pattern pour chaque migration :
|
||||
```javascript
|
||||
fetch('/api/kpi-unified.php')
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
// Un seul objet, nommage stable
|
||||
$('providers').textContent = d.providers.total;
|
||||
$('agents').textContent = d.agents.active;
|
||||
$('skills').textContent = d.skills.count;
|
||||
// etc.
|
||||
});
|
||||
```
|
||||
|
||||
**ZERO régression** : si /api/kpi-unified.php down, les pages continuent
|
||||
d'utiliser source-of-truth.json (fallback natif).
|
||||
|
||||
## Chain V96→V118
|
||||
|
||||
| Version | Commit | Sujet |
|
||||
|---|---|---|
|
||||
| V96-V108 | cd86b19f9 | Orphans Rescue + ZERO ORPHANS |
|
||||
| V110 | ede9a5197 | fpm_monitor |
|
||||
| V111 | 5e98086e7 | token_health |
|
||||
| V112 | 748d35ee4 | infra_health_report |
|
||||
| V113 | a74448d44 | token-health cache 5min |
|
||||
| V114 | 0e2d8d3e8 | V86 Auth HMAC E2E 7/7 |
|
||||
| V115 | 6100a8954 | wevia-master providers_count fix |
|
||||
| V116 | 5be4136f7 | dev_ecommerce intent |
|
||||
| V117 | bada0e198 | 6 business intents batch |
|
||||
| **V118** | TBD | **kpi-unified endpoint SINGLE SOURCE OF TRUTH** |
|
||||
|
||||
## Autres Claudes synchronisés V118 window
|
||||
- V9.68 ee6b83574 wedroid_status intent (94.6% coverage)
|
||||
- b1629038b WTP donut sparkline V106 (197→202KB)
|
||||
- 14ecacd24 WTP ERP Command Center V105 5 Pillars
|
||||
- (quadri-pivots bidirectionnel WTP<>All-IA<>Arena<>Orchestrator)
|
||||
|
||||
## Doctrines appliquées V118
|
||||
- Doctrine 0: Root cause (divergences KPI multiples sources)
|
||||
- Doctrine 2: Zero écrasement (endpoint additif, pages intactes)
|
||||
- Doctrine 3: Zero suppression
|
||||
- Doctrine 4: Zero régression (L99 153/153)
|
||||
- Doctrine 13: Cause racine (référentiels dispersés)
|
||||
- Doctrine 14: Test-driven (live probe 5 sources validated)
|
||||
- Doctrine 54: chattr unlock/lock wevia-autonomous.php
|
||||
- Doctrine 60: UX premium (single source stable naming)
|
||||
- Doctrine 95: Traçabilité wiki + vault
|
||||
- Doctrine 100: Train release
|
||||
|
||||
## Next V119+ potentiel
|
||||
- [ ] Migration progressive WTP + Arena + All-IA Hub vers /api/kpi-unified.php
|
||||
- [ ] Playwright video portfolio 7 business intents (preuve UX)
|
||||
- [ ] Meta-intent router "je veux développer X" cascade matching
|
||||
- [ ] FPM saturation guard doctrine 24 (V9.67 pattern)
|
||||
- [ ] GitHub PAT renewal (Yacine action)
|
||||
Reference in New Issue
Block a user