Files
wevia-brain/s89-arsenal-screens/dark-matrix.html
2026-04-12 23:01:36 +02:00

186 lines
17 KiB
HTML
Executable File
Raw Permalink 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.
<?php include_once("/opt/wevads-arsenal/public/api/wevads-metrics.php"); ?>
<?php
@$_db=new PDO("pgsql:host=localhost;dbname=adx_system","admin","admin123");$_db->exec("SET search_path TO admin");
$_total=(int)$_db->query("SELECT COUNT(*) FROM brain_send_configs")->fetchColumn();
$_tested=(int)$_db->query("SELECT COUNT(*) FROM brain_send_configs WHERE total_sent>0")->fetchColumn();
$_avgInbox=$_db->query("SELECT ROUND(AVG(NULLIF(inbox_rate,0))::numeric,1) FROM brain_send_configs WHERE total_sent>0")->fetchColumn() ?: 0;
$_totalSent=(int)$_db->query("SELECT COALESCE(SUM(total_sent),0) FROM brain_send_configs")->fetchColumn();
$_totalInbox=(int)$_db->query("SELECT COALESCE(SUM(total_inbox),0) FROM brain_send_configs")->fetchColumn();
// Get unique methods and ISPs
$_methodList=$_db->query("SELECT DISTINCT send_method FROM brain_send_configs WHERE send_method IS NOT NULL ORDER BY send_method")->fetchAll(PDO::FETCH_COLUMN);
$_ispList=$_db->query("SELECT DISTINCT isp_target FROM brain_send_configs WHERE isp_target IS NOT NULL AND isp_target!='' ORDER BY isp_target")->fetchAll(PDO::FETCH_COLUMN);
// Matrix data: method x isp -> avg inbox rate
$_matrix=$_db->query("SELECT send_method, isp_target, ROUND(AVG(NULLIF(inbox_rate,0))::numeric,1) as avg_inbox, COUNT(*) as cnt, SUM(total_sent) as total_sent FROM brain_send_configs WHERE isp_target IS NOT NULL AND isp_target!='' GROUP BY send_method, isp_target ORDER BY send_method, isp_target")->fetchAll(PDO::FETCH_ASSOC);
// Build matrix lookup
$_matrixMap=[];
foreach($_matrix as $m) $_matrixMap[$m['send_method']][$m['isp_target']]=['inbox'=>$m['avg_inbox'],'cnt'=>$m['cnt'],'sent'=>$m['total_sent']];
// Best combos
$_bestCombos=$_db->query("SELECT send_method, isp_target, inbox_rate, total_sent, from_domain, status FROM brain_send_configs WHERE total_sent>0 AND inbox_rate>0 ORDER BY inbox_rate DESC LIMIT 10")->fetchAll(PDO::FETCH_ASSOC);
// Worst combos
$_worstCombos=$_db->query("SELECT send_method, isp_target, inbox_rate, total_sent, from_domain FROM brain_send_configs WHERE total_sent>0 AND inbox_rate>0 ORDER BY inbox_rate ASC LIMIT 5")->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html><html lang="fr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVADS - Dark Matrix</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root{--bg:#060a14;--s:#0c1220;--s2:#111827;--b:#1e293b;--t:#e2e8f0;--d:#64748b;--cy:#22d3ee;--gn:#34d399;--am:#fbbf24;--rd:#f87171;--pu:#a78bfa;--bl:#60a5fa;--pk:#f472b6}
*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--t);font-family:'DM Sans',sans-serif;font-size:12px}
.mono{font-family:'JetBrains Mono',monospace}
.hdr{background:var(--s);border-bottom:1px solid var(--b);padding:14px 20px;display:flex;justify-content:space-between;align-items:center}
.hdr h1{font-size:18px;font-weight:700;margin-left:80px}.hdr h1 span{background:linear-gradient(135deg,var(--gn),var(--cy));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.wrap{padding:16px 20px;max-width:1500px;margin:0 auto}
.stats{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:16px}
.sc{background:var(--s);border:1px solid var(--b);border-radius:10px;padding:14px;text-align:center;cursor:pointer;transition:all .2s}
.sc:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,.3);border-color:var(--cy)}
.sc .n{font-family:'JetBrains Mono',monospace;font-size:22px;font-weight:700}.sc .l{font-size:9px;text-transform:uppercase;color:var(--d);margin-top:4px}.sc .delta{font-size:9px;margin-top:3px}
.g2{display:grid;grid-template-columns:1fr 1fr;gap:12px}.cd{background:var(--s);border:1px solid var(--b);border-radius:10px;padding:14px}
table{width:100%;border-collapse:collapse;font-size:11px}th{text-align:left;color:var(--d);text-transform:uppercase;font-size:9px;padding:6px 8px;border-bottom:1px solid var(--b)}td{padding:6px 8px;border-bottom:1px solid rgba(30,41,59,.3)}
.badge{font-size:8px;padding:2px 6px;border-radius:3px;font-weight:600}.badge-gn{background:rgba(52,211,153,.15);color:var(--gn)}.badge-rd{background:rgba(248,113,113,.15);color:var(--rd)}.badge-am{background:rgba(251,191,36,.15);color:var(--am)}.badge-cy{background:rgba(34,211,238,.15);color:var(--cy)}
.btn{padding:8px 16px;border-radius:6px;border:1px solid var(--b);background:var(--s2);color:var(--t);cursor:pointer;font-size:10px;font-weight:600;transition:all .2s;text-decoration:none}.btn:hover{border-color:var(--cy);transform:translateY(-1px)}
.tabs{display:flex;gap:2px;margin-bottom:14px;border-bottom:1px solid var(--b)}.tab{padding:8px 16px;cursor:pointer;font-size:10px;font-weight:600;text-transform:uppercase;color:var(--d);border-bottom:2px solid transparent}.tab:hover{color:var(--t)}.tab.active{color:var(--cy);border-color:var(--cy)}
.panel{display:none}.panel.active{display:block}
.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.75);z-index:9999;justify-content:center;align-items:center}.modal-box{background:var(--s);border:1px solid var(--b);border-radius:12px;padding:20px;max-width:950px;width:94%;max-height:82vh;overflow-y:auto}
.cell{width:54px;height:38px;border-radius:6px;display:flex;align-items:center;justify-content:center;font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:700;cursor:pointer;transition:all .2s;border:1px solid transparent}
.cell:hover{transform:scale(1.15);z-index:1;border-color:var(--cy)}
.matrix-grid{display:grid;gap:3px;overflow-x:auto}
.legend{display:flex;gap:16px;justify-content:center;margin-top:10px;font-size:10px;color:var(--d)}
.legend span{display:flex;align-items:center;gap:4px}.legend .dot{width:12px;height:12px;border-radius:3px}
@media(max-width:900px){.stats{grid-template-columns:repeat(3,1fr)}.g2{grid-template-columns:1fr}}
</style>
<link rel="stylesheet" href="wevads-global.css?v1770777318">
</head><body>
<div class="hdr"><div><h1>🧪 <span>Dark Matrix</span></h1><div style="color:var(--d);font-size:11px;margin-top:4px">ISP × Send Method delivery matrix — heatmap — combo analysis</div></div><div style="display:flex;gap:8px;align-items:center"><span class="badge badge-cy">● MATRIX</span><a href="menu.html" class="btn">Menu</a><a href="operations-overview.html" class="btn">← Overview</a></div></div>
<div class="wrap">
<div class="stats">
<div class="sc" onclick="drill('total')"><div class="n" style="color:var(--cy)"><?=$_total?></div><div class="l">Total Configs ▼</div><div class="delta"><?=count($_methodList)?> methods × <?=count($_ispList)?> ISPs</div></div>
<div class="sc" onclick="drill('tested')"><div class="n" style="color:var(--gn)"><?=$_tested?></div><div class="l">Tested ▼</div><div class="delta"><?=$_total-$_tested?> untested</div></div>
<div class="sc" onclick="drill('inbox')"><div class="n" style="color:var(--am)"><?=$_avgInbox?>%</div><div class="l">Avg Inbox ▼</div><div class="delta">across tested</div></div>
<div class="sc" onclick="drill('sent')"><div class="n" style="color:var(--bl)"><?=number_format($_totalSent)?></div><div class="l">Total Sent ▼</div><div class="delta"><?=number_format($_totalInbox)?> inbox</div></div>
<div class="sc" onclick="drill('best')"><div class="n" style="color:var(--gn)"><?=count($_bestCombos)?></div><div class="l">Best Combos ▼</div><div class="delta">top performers</div></div>
<div class="sc" onclick="drill('gaps')"><div class="n" style="color:var(--rd)"><?=count($_worstCombos)?></div><div class="l">Weak Spots ▼</div><div class="delta">needs work</div></div>
</div>
<div class="tabs">
<div class="tab active" onclick="showTab('matrix')">🧪 Heatmap</div>
<div class="tab" onclick="showTab('best')">🏆 Best Combos</div>
<div class="tab" onclick="showTab('worst')">⚠️ Worst</div>
<div class="tab" onclick="showTab('gaps')">🕳️ Gap Analysis</div>
</div>
<!-- HEATMAP -->
<div class="panel active" id="tab-matrix">
<div class="cd">
<h3 style="font-size:13px;margin-bottom:12px;color:var(--cy)">🧪 ISP × Method Inbox Rate Matrix</h3>
<div style="overflow-x:auto">
<table>
<thead><tr><th style="min-width:100px">Method \ ISP</th>
<?php foreach($_ispList as $isp):?><th style="text-align:center;min-width:60px;font-size:8px"><?=htmlspecialchars($isp)?></th><?php endforeach;?>
</tr></thead>
<tbody>
<?php foreach($_methodList as $method): ?>
<tr><td style="font-weight:600;white-space:nowrap"><?=htmlspecialchars($method)?></td>
<?php foreach($_ispList as $isp):
$cell=$_matrixMap[$method][$isp]??null;
if($cell){
$v=$cell['inbox'];
if($v>=70){$bg='rgba(52,211,153,.25)';$col='#34d399';}
elseif($v>=40){$bg='rgba(251,191,36,.25)';$col='#fbbf24';}
else{$bg='rgba(248,113,113,.25)';$col='#f87171';}
echo "<td style=\"text-align:center;background:$bg;color:$col;font-family:'JetBrains Mono',monospace;font-weight:700;font-size:11px;cursor:pointer\" title=\"{$method} → {$isp}: {$v}% inbox ({$cell['cnt']} configs, ".number_format($cell['sent'])." sent)\" onclick=\"drillCell('{$method}','{$isp}')\">{$v}%</td>";
} else {
echo "<td style=\"text-align:center;color:var(--d);font-size:10px\">—</td>";
}
endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="legend">
<span><div class="dot" style="background:rgba(52,211,153,.4)"></div> &gt;70% (Good)</span>
<span><div class="dot" style="background:rgba(251,191,36,.4)"></div> 40-70% (Medium)</span>
<span><div class="dot" style="background:rgba(248,113,113,.4)"></div> &lt;40% (Poor)</span>
<span><div class="dot" style="background:var(--s2)"></div> — (Untested)</span>
</div>
</div>
</div>
<!-- BEST COMBOS -->
<div class="panel" id="tab-best">
<div class="cd">
<h3 style="font-size:13px;margin-bottom:10px;color:var(--gn)">🏆 Best Method × ISP Combinations</h3>
<table><thead><tr><th>#</th><th>Method</th><th>ISP</th><th>Domain</th><th>Inbox</th><th>Sent</th><th>Status</th></tr></thead><tbody>
<?php foreach($_bestCombos as $i=>$c): $col=$c['inbox_rate']>80?'var(--gn)':($c['inbox_rate']>50?'var(--am)':'var(--rd)'); ?>
<tr><td style="font-weight:700;color:var(--am)">#<?=$i+1?></td><td style="font-weight:600"><?=htmlspecialchars($c['send_method'])?></td><td><?=htmlspecialchars($c['isp_target']??'—')?></td><td style="font-size:10px;color:var(--d)"><?=htmlspecialchars($c['from_domain']??'—')?></td><td class="mono" style="color:<?=$col?>;font-weight:700"><?=$c['inbox_rate']?>%</td><td class="mono"><?=number_format($c['total_sent'])?></td><td><span class="badge badge-<?=$c['status']==='winner'?'gn':($c['status']==='testing'?'am':'cy')?>"><?=strtoupper($c['status']??'?')?></span></td></tr>
<?php endforeach; ?>
</tbody></table>
</div>
</div>
<!-- WORST -->
<div class="panel" id="tab-worst">
<div class="cd">
<h3 style="font-size:13px;margin-bottom:10px;color:var(--rd)">⚠️ Worst Performers</h3>
<table><thead><tr><th>Method</th><th>ISP</th><th>Domain</th><th>Inbox</th><th>Sent</th></tr></thead><tbody>
<?php foreach($_worstCombos as $w): ?>
<tr><td style="font-weight:600"><?=htmlspecialchars($w['send_method'])?></td><td><?=htmlspecialchars($w['isp_target']??'—')?></td><td style="font-size:10px"><?=htmlspecialchars($w['from_domain']??'—')?></td><td class="mono" style="color:var(--rd);font-weight:700"><?=$w['inbox_rate']?>%</td><td class="mono"><?=number_format($w['total_sent'])?></td></tr>
<?php endforeach; if(empty($_worstCombos)):?><tr><td colspan="5" style="text-align:center;color:var(--d);padding:20px">No bad performers</td></tr><?php endif;?>
</tbody></table>
</div>
</div>
<!-- GAP ANALYSIS -->
<div class="panel" id="tab-gaps">
<div class="cd">
<h3 style="font-size:13px;margin-bottom:10px;color:var(--pu)">🕳️ Untested Combinations</h3>
<p style="color:var(--d);margin-bottom:12px">These method × ISP combinations have no test data yet. Consider prioritizing tests for high-value ISPs.</p>
<div style="display:flex;flex-wrap:wrap;gap:6px">
<?php
$tested_combos=[];foreach($_matrix as $m)$tested_combos[$m['send_method'].'→'.$m['isp_target']]=true;
$gaps=0;
foreach($_methodList as $method){foreach($_ispList as $isp){
if(!isset($tested_combos[$method.'→'.$isp])){
echo '<span style="background:var(--s2);border:1px solid var(--b);border-radius:6px;padding:4px 8px;font-size:10px;color:var(--d)">'.htmlspecialchars($method).' → '.htmlspecialchars($isp).'</span>';
$gaps++;
}
}}
if($gaps===0) echo '<div style="color:var(--gn)">All combinations tested ✅</div>';
?>
</div>
<div style="margin-top:12px;color:var(--d);font-size:11px"><strong><?=$gaps?></strong> untested combinations out of <?=count($_methodList)*count($_ispList)?> possible</div>
</div>
</div>
</div>
<div class="modal" id="drillModal" onclick="if(event.target===this)this.style.display='none'"><div class="modal-box"><div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px"><h3 id="drillTitle" style="font-size:14px;color:var(--cy)"></h3><button onclick="document.getElementById('drillModal').style.display='none'" style="background:none;border:none;color:var(--rd);font-size:18px;cursor:pointer"></button></div><div id="drillContent" style="font-size:11px"></div></div></div>
<script>
function showTab(id){document.querySelectorAll('.tab').forEach(function(t){t.classList.remove('active')});document.querySelectorAll('.panel').forEach(function(p){p.classList.remove('active')});document.getElementById('tab-'+id).classList.add('active');event.target.classList.add('active')}
function drillCell(method,isp){
var m=document.getElementById('drillModal'),tt=document.getElementById('drillTitle'),ct=document.getElementById('drillContent');
m.style.display='flex';
tt.textContent='⚙️ '+method+' → '+isp;
ct.innerHTML='<div class="cd" style="text-align:center;margin-bottom:12px"><div style="font-size:14px;color:var(--d)">Config detail for <strong style="color:var(--cy)">'+method+'</strong> targeting <strong style="color:var(--am)">'+isp+'</strong></div><div style="margin-top:12px;color:var(--d)">Click the heatmap cell tooltip for full performance data including inbox rate, total sent, and configuration count.</div></div>';
}
async function drill(type){
var m=document.getElementById('drillModal'),tt=document.getElementById('drillTitle'),ct=document.getElementById('drillContent');
m.style.display='flex';ct.innerHTML='<div style="text-align:center;padding:40px;color:var(--d)">Loading...</div>';
var html='';
var titles={total:'🧪 All Configs',tested:'✅ Tested Configs',inbox:'📊 Inbox Analysis',sent:'📤 Send Volume',best:'🏆 Best Combos',gaps:'🕳️ Weak Spots'};
tt.textContent=titles[type]||type;
html+='<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:14px">';
html+='<div class="cd" style="text-align:center"><div style="font-size:18px;font-weight:700;color:var(--cy)"><?=$_total?></div><div class="l">Configs</div></div>';
html+='<div class="cd" style="text-align:center"><div style="font-size:18px;font-weight:700;color:var(--gn)"><?=$_tested?></div><div class="l">Tested</div></div>';
html+='<div class="cd" style="text-align:center"><div style="font-size:18px;font-weight:700;color:var(--am)"><?=$_avgInbox?>%</div><div class="l">Avg Inbox</div></div>';
html+='<div class="cd" style="text-align:center"><div style="font-size:18px;font-weight:700;color:var(--bl)"><?=number_format($_totalSent)?></div><div class="l">Total Sent</div></div></div>';
if(type==='best'){
html+='<table><thead><tr><th>Method</th><th>ISP</th><th>Inbox</th><th>Sent</th></tr></thead><tbody>';
<?php foreach($_bestCombos as $c):$col=$c['inbox_rate']>70?'var(--gn)':'var(--am)';?>html+='<tr><td style="font-weight:600"><?=addslashes($c['send_method'])?></td><td><?=addslashes($c['isp_target']??'-')?></td><td class="mono" style="color:<?=$col?>"><?=$c['inbox_rate']?>%</td><td class="mono"><?=number_format($c['total_sent'])?></td></tr>';<?php endforeach;?>
html+='</tbody></table>';
} else if(type==='gaps'){
html+='<table><thead><tr><th>Method</th><th>ISP</th><th>Inbox</th><th>Sent</th></tr></thead><tbody>';
<?php foreach($_worstCombos as $w):?>html+='<tr><td style="font-weight:600"><?=addslashes($w['send_method'])?></td><td><?=addslashes($w['isp_target']??'-')?></td><td class="mono" style="color:var(--rd)"><?=$w['inbox_rate']?>%</td><td class="mono"><?=number_format($w['total_sent'])?></td></tr>';<?php endforeach;?>
html+='</tbody></table>';
} else {
html+='<div class="cd" style="color:var(--d)">Matrix covers <strong><?=count($_methodList)?></strong> send methods × <strong><?=count($_ispList)?></strong> ISPs = <strong><?=count($_methodList)*count($_ispList)?></strong> possible combinations. <?=count($_matrix)?> have data.</div>';
}
ct.innerHTML=html;
}
</script>
<script src="arsenal-common.js?v1770778169"></script>
<?php include("/opt/wevads-arsenal/public/universal-drill.html"); ?>
</body></html>