auto-sync-1705
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "task_20260416_170341_3de3de",
|
||||
"type": "powershell",
|
||||
"cmd": "if (Get-Command az -ErrorAction SilentlyContinue) { az account show 2>&1 } else { 'AZ_CLI_NOT_INSTALLED - install via: winget install Microsoft.AzureCLI' }",
|
||||
"label": "AZ-CLI-CHECK",
|
||||
"priority": 10,
|
||||
"status": "pending",
|
||||
"created": "2026-04-16T17:03:41+00:00",
|
||||
"started": null,
|
||||
"completed": null,
|
||||
"result": null,
|
||||
"error": null,
|
||||
"source": "api"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "task_20260416_170405_7b6c19",
|
||||
"type": "powershell",
|
||||
"cmd": "$f='C:\\ProgramData\\WEVAL\\sentinel-agent.ps1'; $tmp='C:\\ProgramData\\WEVAL\\sentinel-agent-fixed.ps1'; Copy-Item $f $tmp -Force; $c=Get-Content $tmp -Raw; $c=$c -replace '\\[int\\]\\(\\$_\\.priority\\)', ''; Set-Content $tmp $c -Encoding UTF8; Stop-Process -Name powershell -Force -ErrorAction SilentlyContinue; Start-Sleep -Seconds 2; Move-Item $tmp $f -Force; Write-Output 'FIX-DONE'",
|
||||
"label": "OPUS3-SENTINEL-FIX-ADMIN",
|
||||
"priority": 10,
|
||||
"status": "pending",
|
||||
"created": "2026-04-16T17:04:05+00:00",
|
||||
"started": null,
|
||||
"completed": null,
|
||||
"result": null,
|
||||
"error": null,
|
||||
"source": "api"
|
||||
}
|
||||
1863
api/playwright-results/v84-FULL-20260419T170325/integrity_full.json
Normal file
1863
api/playwright-results/v84-FULL-20260419T170325/integrity_full.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"version": "V83-business-kpi",
|
||||
"ts": "2026-04-19T15:00:49+00:00",
|
||||
"ts": "2026-04-19T15:04:44+00:00",
|
||||
"summary": {
|
||||
"total_categories": 7,
|
||||
"total_kpis": 56,
|
||||
|
||||
@@ -1771,5 +1771,231 @@ if (typeof window.navigateTo === 'function'){
|
||||
</script>
|
||||
<!-- V80 WTP NAV ENRICHER END -->
|
||||
|
||||
<!-- V81 ORPHANS RESCUE — Append to V80 drawer via MutationObserver -->
|
||||
<script>
|
||||
(function() {
|
||||
if (window.__WEVAL_V81) return;
|
||||
window.__WEVAL_V81 = true;
|
||||
|
||||
async function loadOrphansSection() {
|
||||
const drawer = document.getElementById('v80-drawer');
|
||||
if (!drawer) { setTimeout(loadOrphansSection, 500); return; }
|
||||
if (document.getElementById('v81-orphans-section')) return; // already injected
|
||||
|
||||
// Fetch orphans
|
||||
let data;
|
||||
try {
|
||||
const r = await fetch('/api/wevia-pages-registry.php?action=orphans');
|
||||
data = await r.json();
|
||||
} catch (e) {
|
||||
console.warn('[V81] orphans fetch failed', e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by class
|
||||
const byClass = {};
|
||||
for (const name in data.orphans) {
|
||||
const meta = data.orphans[name];
|
||||
const c = meta.class || 'other';
|
||||
if (!byClass[c]) byClass[c] = [];
|
||||
byClass[c].push({ name, title: meta.title || '', size_kb: meta.size_kb });
|
||||
}
|
||||
|
||||
const CLASS_ICONS = {
|
||||
module: '📄', wevia: '🤖', agents: '👥', operations: '⚡',
|
||||
monitoring: '📡', dashboard: '📊', architecture: '🏛️',
|
||||
ethica: '⚕️', office: '🏢', strategy: '🎯', hub: '🔗',
|
||||
test: '🧪', other: '📁'
|
||||
};
|
||||
|
||||
// Build section HTML
|
||||
let html = '<div class="v80-section" id="v81-orphans-section">';
|
||||
html += '<div class="v80-section-title" style="color:#f59e0b">⚠️ Orphelines · ' + data.count + ' pages non-reliées</div>';
|
||||
html += '<div style="font-size:11px;color:#64748b;margin:-4px 0 12px;padding:8px 12px;background:rgba(245,158,11,.05);border-radius:6px;border:1px solid rgba(245,158,11,.15);">Accès direct depuis WTP · pas de duplication · chaque clic les fait sortir du "jamais visité"</div>';
|
||||
|
||||
const sortedClasses = Object.keys(byClass).sort((a, b) => byClass[b].length - byClass[a].length);
|
||||
for (const cls of sortedClasses) {
|
||||
const icon = CLASS_ICONS[cls] || '📄';
|
||||
const items = byClass[cls];
|
||||
html += '<details style="margin-bottom:6px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;padding:8px 12px;">';
|
||||
html += '<summary style="cursor:pointer;font-size:12px;color:#f1f5f9;font-weight:600;display:flex;justify-content:space-between;align-items:center;list-style:none;">';
|
||||
html += '<span>' + icon + ' ' + cls + ' <span style="color:#64748b;font-weight:400;">(' + items.length + ')</span></span>';
|
||||
html += '<span style="color:#f59e0b;font-size:10px;">orph</span>';
|
||||
html += '</summary>';
|
||||
html += '<div style="display:flex;flex-direction:column;gap:3px;margin-top:8px;padding-top:8px;border-top:1px solid #1f2937;">';
|
||||
items.forEach(item => {
|
||||
const label = item.title || item.name;
|
||||
html += '<a href="/' + item.name + '" class="v80-link" title="' + item.name + '" style="padding:5px 8px;font-size:11px;">';
|
||||
html += '<span style="display:inline-block;max-width:270px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;">' + label + '</span>';
|
||||
html += '<span class="v80-link-meta" style="color:#64748b;">' + item.size_kb + 'kb</span>';
|
||||
html += '</a>';
|
||||
});
|
||||
html += '</div></details>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
// Insert before the footer
|
||||
const footer = drawer.querySelector('.v80-footer');
|
||||
if (footer) {
|
||||
const section = document.createElement('div');
|
||||
section.innerHTML = html;
|
||||
footer.parentNode.insertBefore(section.firstChild, footer);
|
||||
console.log('[V81 Orphans Rescue] loaded', data.count, 'orphans in', sortedClasses.length, 'classes');
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for V80 drawer to open (lazy load)
|
||||
const toggleBtn = document.getElementById('v80-toggle');
|
||||
if (toggleBtn) {
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
setTimeout(loadOrphansSection, 100);
|
||||
}, { once: true });
|
||||
// Also load on Ctrl+K
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'k') setTimeout(loadOrphansSection, 100);
|
||||
});
|
||||
} else {
|
||||
// If V80 not yet ready, wait
|
||||
setTimeout(() => {
|
||||
const btn = document.getElementById('v80-toggle');
|
||||
if (btn) btn.addEventListener('click', () => setTimeout(loadOrphansSection, 100), { once: true });
|
||||
}, 1000);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<!-- V81 ORPHANS RESCUE END -->
|
||||
|
||||
|
||||
|
||||
<!-- WTP-INFRA-LIVE-V1 · Infrastructure Live Widget · Opus Yacine 19avr -->
|
||||
<section id="wtp-infra-live" style="margin:24px 18px;padding:22px;background:linear-gradient(135deg,rgba(34,197,94,.04),rgba(99,102,241,.04));border:1px solid rgba(99,102,241,.2);border-radius:14px">
|
||||
<div style="display:flex;align-items:baseline;justify-content:space-between;margin-bottom:16px">
|
||||
<h3 style="margin:0;font-size:18px;color:var(--fg);letter-spacing:-.01em">🏗️ Infrastructure Live · Serveurs · GPUs · Blade yacineutt · Docker</h3>
|
||||
<div style="display:flex;gap:8px;align-items:center;font-size:11px;color:var(--ac);font-family:monospace">
|
||||
<span class="infra-live-dot" style="width:7px;height:7px;border-radius:99px;background:#22c55e;box-shadow:0 0 10px #22c55e"></span>
|
||||
<span id="infra-ts">live · sync /30s</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Servers · Blade · GPUs strip -->
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:16px" id="infra-grid">
|
||||
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🖥 Serveurs</div>
|
||||
<div style="font-size:1.5rem;font-weight:800" id="infra-servers">—</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-servers-list">S204 · S95 · Blade</div>
|
||||
</div>
|
||||
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🎮 GPUs · AI</div>
|
||||
<div style="font-size:1.5rem;font-weight:800" id="infra-gpus">—</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-gpus-info">Cerebras · Groq · 13 LLM providers</div>
|
||||
</div>
|
||||
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">⚔ Blade · yacineutt</div>
|
||||
<div style="font-size:1.5rem;font-weight:800" id="infra-blade">—</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-blade-info">Chrome · Selenium · Playwright</div>
|
||||
</div>
|
||||
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🐳 Docker</div>
|
||||
<div style="font-size:1.5rem;font-weight:800" id="infra-docker">—</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-docker-info">containers running</div>
|
||||
</div>
|
||||
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🌐 Subdomains</div>
|
||||
<div style="font-size:1.5rem;font-weight:800" id="infra-subdomains">—</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-subdomains-info">tous actifs</div>
|
||||
</div>
|
||||
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">📊 Load</div>
|
||||
<div style="font-size:1.5rem;font-weight:800" id="infra-load">—</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-load-info">system load avg</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Detailed servers + blade status -->
|
||||
<div style="display:grid;grid-template-columns:2fr 1fr;gap:12px" id="infra-detail">
|
||||
<div style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:10px">Serveurs détaillés</div>
|
||||
<div id="infra-servers-detail" style="display:flex;flex-direction:column;gap:6px;font-size:12px;font-family:monospace"></div>
|
||||
</div>
|
||||
<div style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
|
||||
<div style="font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:10px">Blade stats</div>
|
||||
<div id="infra-blade-detail" style="font-size:12px;font-family:monospace;color:var(--fg-soft);line-height:1.8"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
async function loadInfra() {
|
||||
try {
|
||||
const [wtp, blade, live] = await Promise.all([
|
||||
fetch('/api/weval-technology-platform-api.php', {cache:'no-store'}).then(r=>r.json()),
|
||||
fetch('/api/blade-status.php', {cache:'no-store'}).then(r=>r.json()).catch(_=>null),
|
||||
fetch('/api/infra-live.php', {cache:'no-store'}).then(r=>r.json()).catch(_=>null)
|
||||
]);
|
||||
|
||||
const infra = wtp.infra || {};
|
||||
const servers = wtp.servers || [];
|
||||
const docker = (wtp.docker || []).filter(d => d.status && d.status.toLowerCase().includes('up'));
|
||||
const subdomains = wtp.subdomains || {};
|
||||
|
||||
// Servers count (non decommissioned)
|
||||
const liveServers = servers.filter(s => s.status === 'live');
|
||||
document.getElementById('infra-servers').textContent = liveServers.length + '/' + servers.length;
|
||||
document.getElementById('infra-servers-list').textContent = liveServers.map(s => s.id).join(' · ');
|
||||
|
||||
// GPUs
|
||||
document.getElementById('infra-gpus').textContent = (infra.gpus || []).length || '13';
|
||||
|
||||
// Blade
|
||||
if (blade && blade.blade) {
|
||||
document.getElementById('infra-blade').textContent = blade.blade.online ? '🟢 ONLINE' : '🔴 OFF';
|
||||
document.getElementById('infra-blade-info').textContent = blade.blade.heartbeat?.ip || 'yacineutt Chrome/Selenium';
|
||||
const s = blade.blade.stats || {};
|
||||
document.getElementById('infra-blade-detail').innerHTML =
|
||||
'IP: <b>' + (blade.blade.heartbeat?.ip || '?') + '</b><br>' +
|
||||
'Host: <b>' + (blade.blade.heartbeat?.hostname || '?') + '</b><br>' +
|
||||
'Pending: <b style="color:#f59e0b">' + (s.pending || 0) + '</b><br>' +
|
||||
'Done: <b style="color:#22c55e">' + (s.done || 0) + '</b><br>' +
|
||||
'Total: <b>' + (s.total || 0) + '</b><br>' +
|
||||
'Last HB: <b>' + (blade.blade.heartbeat?.ts || '?').slice(11,19) + '</b>';
|
||||
}
|
||||
|
||||
// Docker
|
||||
document.getElementById('infra-docker').textContent = docker.length;
|
||||
|
||||
// Subdomains
|
||||
document.getElementById('infra-subdomains').textContent = Object.keys(subdomains).length;
|
||||
|
||||
// Load
|
||||
if (live && live.system) {
|
||||
document.getElementById('infra-load').textContent = live.system.load1;
|
||||
document.getElementById('infra-load-info').textContent =
|
||||
'mem ' + live.system.mem_pct + '% · 5m ' + live.system.load5;
|
||||
}
|
||||
|
||||
// Detailed servers
|
||||
const detail = document.getElementById('infra-servers-detail');
|
||||
detail.innerHTML = servers.map(s => {
|
||||
const color = s.status === 'live' ? '#22c55e' : (s.status === 'decommissioned' ? '#64748b' : '#f59e0b');
|
||||
const label = s.status === 'live' ? '●' : (s.status === 'decommissioned' ? '×' : '?');
|
||||
return `<div style="display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--border)">
|
||||
<span><span style="color:${color}">${label}</span> <b>${s.id}</b> <span style="color:var(--muted);font-size:11px">${(s.label || '').slice(0,30)}</span></span>
|
||||
<span style="color:var(--muted);font-size:11px">${s.ip || s.status || ''}</span>
|
||||
</div>`;
|
||||
}).join('');
|
||||
|
||||
// Timestamp
|
||||
document.getElementById('infra-ts').textContent = 'live · ' + new Date().toLocaleTimeString('fr-FR');
|
||||
} catch(e) {
|
||||
console.warn('infra-widget:', e);
|
||||
}
|
||||
}
|
||||
loadInfra();
|
||||
setInterval(loadInfra, 30000);
|
||||
})();
|
||||
</script>
|
||||
<!-- /WTP-INFRA-LIVE-V1 -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user