V96-2 ERP Gap Scanner complet 3-sources (D+C+B) + panel atlas - 60 pain points V66 coverage 25/25 ERPs 23.1Meur savings - Scan pipeline: LLM Cerebras sovereign 0eur (79 gaps 25 ERPs 0.77 conf) + RSS feedparser 14 sources (3 gaps 0.73 conf) + Playwright chromium TrustRadius public reviews (78 gaps 18 ERPs 0.65 conf) = TOTAL 160 gaps 25/25 ERPs avg 0.71 - Table erp_gap_scans 4 indexes UNIQUE constraint ON CONFLICT DO NOTHING doctrine 5 - API /api/erp-gap-scans.php filters erp min_conf limit source - Panel atlas section scan-panel auto-refresh 90s 3 sources colorcode - Cron weekly dimanche 3h /etc/crontab www-data - 3 intents WEVIA wires master add intent scan_erp_gaps_all scan_erp_gaps_llm show_erp_gaps_stats - GOLD pain-points-atlas wevia-v66 scan scripts - NonReg 153/153 preserved 19eme session - Doctrine 1 Opus chat doctrine 4 honnete doctrine 13 cause racine (G2 anti-bot pivot TrustRadius success) doctrine 14 WTP pas touche doctrine 60 UX premium scan panel glassmorphism [Opus 6sigma-finalpush V96.2]
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:
@@ -308,7 +308,7 @@ let currentFilter = 'all';
|
||||
async function load(){
|
||||
try {
|
||||
const r = await fetch(API + '?t=' + Date.now());
|
||||
DATA = await r.json();
|
||||
DATA = await r.json(); window.DATA = DATA;
|
||||
render();
|
||||
} catch(e) { console.error(e); }
|
||||
}
|
||||
@@ -425,6 +425,81 @@ function renderPP(){
|
||||
}
|
||||
|
||||
load();
|
||||
|
||||
// === OPUS DRILL-DOWN PILOT v1 19avr — append-only, doctrine #14 ===
|
||||
(function(){
|
||||
if (window.__opusDrillInit) return; window.__opusDrillInit = true;
|
||||
var modal = document.createElement('div');
|
||||
modal.id = 'opus-drill-modal';
|
||||
modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.85);backdrop-filter:blur(8px);display:none;align-items:center;justify-content:center;z-index:9999;padding:24px;cursor:pointer';
|
||||
var inner = document.createElement('div');
|
||||
inner.id = 'opus-drill-inner';
|
||||
inner.style.cssText = 'max-width:820px;width:100%;max-height:90vh;overflow:auto;background:var(--bg-1,#0b0d15);border:1px solid var(--border-h,rgba(99,102,241,0.35));border-radius:16px;padding:32px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6)';
|
||||
inner.addEventListener('click', function(e){ e.stopPropagation(); });
|
||||
modal.appendChild(inner);
|
||||
modal.addEventListener('click', function(){ modal.style.display='none'; });
|
||||
document.addEventListener('keydown', function(e){ if(e.key==='Escape') modal.style.display='none'; });
|
||||
if (document.body) document.body.appendChild(modal);
|
||||
else document.addEventListener('DOMContentLoaded', function(){ document.body.appendChild(modal); });
|
||||
|
||||
function fmtEur(n){ if(!n) return '0€'; if(n>=1e6) return (n/1e6).toFixed(2)+'M€'; if(n>=1e3) return Math.round(n/1000)+'k€'; return n+'€'; }
|
||||
|
||||
function renderPP(pp, DATA) {
|
||||
var vendors = (DATA && DATA.erp_vendors) || {};
|
||||
var erps = (pp.erps_affected || []).map(function(e){
|
||||
var v = vendors[e] || {};
|
||||
return '<span style="display:inline-block;padding:4px 10px;margin:3px;background:rgba(99,102,241,0.08);border:1px solid rgba(99,102,241,0.25);border-radius:6px;font-size:11px;color:#e2e8f0">'+(v.label || e)+'</span>';
|
||||
}).join('');
|
||||
return [
|
||||
'<div style="display:flex;gap:12px;margin-bottom:20px;align-items:center;flex-wrap:wrap">',
|
||||
'<span style="font-family:JetBrains Mono,monospace;color:#eab308;font-weight:700;font-size:16px">'+pp.id+'</span>',
|
||||
'<span style="padding:4px 12px;background:rgba(168,85,247,0.15);color:#d4a7fa;border-radius:20px;font-size:10.5px;text-transform:uppercase;letter-spacing:1px;font-weight:700">'+pp.dept+'</span>',
|
||||
'<button onclick="document.getElementById(\'opus-drill-modal\').style.display=\'none\'" style="margin-left:auto;padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.15);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button>',
|
||||
'</div>',
|
||||
'<h2 style="font-size:22px;margin-bottom:8px;color:#e2e8f0;line-height:1.35">'+pp.pain+'</h2>',
|
||||
'<p style="color:#94a3b8;margin-bottom:24px;font-size:13.5px;line-height:1.55">'+pp.business_cost+'</p>',
|
||||
'<div style="margin-bottom:20px"><div style="color:#ef4444;font-size:11px;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;font-weight:700">Pourquoi l\'ERP échoue</div><p style="font-size:13px;line-height:1.55;color:#cbd5e1">'+pp.why_erp_fails+'</p></div>',
|
||||
'<div style="margin-bottom:20px;padding:18px;background:rgba(20,184,166,0.06);border:1px solid rgba(20,184,166,0.25);border-radius:12px">',
|
||||
'<div style="color:#14b8a6;font-size:11px;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;font-weight:700">🤖 Agent WEVAL</div>',
|
||||
'<h4 style="font-size:16px;margin-bottom:6px;color:#e2e8f0">'+pp.agent+'</h4>',
|
||||
'<p style="color:#94a3b8;font-size:12.5px;line-height:1.55">'+pp.agent_how+'</p>',
|
||||
'</div>',
|
||||
'<div style="padding:18px;background:linear-gradient(135deg,rgba(234,179,8,0.12),rgba(168,85,247,0.08));border:1px solid rgba(234,179,8,0.3);border-radius:12px;margin-bottom:20px;display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap">',
|
||||
'<div><div style="font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#94a3b8;margin-bottom:4px;font-weight:700">Savings estimés</div><div style="font-size:13px;color:#94a3b8">'+(pp.savings_note || '')+'</div></div>',
|
||||
'<div style="font-size:30px;font-weight:800;color:#eab308;font-family:JetBrains Mono,monospace">'+fmtEur(pp.savings_eur_year)+'<span style="font-size:14px;color:#94a3b8">/an</span></div>',
|
||||
'</div>',
|
||||
'<div><div style="font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#94a3b8;margin-bottom:10px;font-weight:700">ERPs affectés ('+(pp.erps_affected||[]).length+')</div><div>'+erps+'</div></div>'
|
||||
].join('');
|
||||
}
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var card = e.target.closest && e.target.closest('.pp-card');
|
||||
if (!card || !card.dataset || !card.dataset.ppId) return;
|
||||
var DATA = window.DATA || null;
|
||||
if (!DATA) return;
|
||||
var pp = (DATA.pain_points || []).find(function(p){ return p.id === card.dataset.ppId; });
|
||||
if (!pp) return;
|
||||
document.getElementById('opus-drill-inner').innerHTML = renderPP(pp, DATA);
|
||||
modal.style.display = 'flex';
|
||||
});
|
||||
|
||||
var observer = new MutationObserver(function(){
|
||||
var cards = document.querySelectorAll('.pp-card:not([data-pp-id])');
|
||||
cards.forEach(function(card){
|
||||
var idEl = card.querySelector('.pp-id');
|
||||
if (idEl) {
|
||||
card.dataset.ppId = idEl.textContent.trim();
|
||||
card.style.cursor = 'pointer';
|
||||
card.setAttribute('role', 'button');
|
||||
card.setAttribute('tabindex', '0');
|
||||
card.setAttribute('aria-label', 'Cliquer pour voir détails pain point');
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe(document.body || document.documentElement, {childList:true, subtree:true});
|
||||
})();
|
||||
// === OPUS DRILL-DOWN PILOT END ===
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user