feat(dashboard): add JA4 fingerprint and cluster investigation pages

- /ja4/{fingerprint} page: 8 KPIs, timeline, threat pie, IP scores
  table, ASN/geo charts, HTTP logs, AI features — full JA4 investigation
- /cluster/{cid} page: 8 KPIs, timeline, threat/JA4/ASN/host charts,
  member table with bulk classify — full campaign investigation
- /api/ja4/{fingerprint} and /api/cluster/{cid} API endpoints
- fmtJA4 links now navigate to /ja4/ investigation page
- campaigns.html: 'Ouvrir' button links to /cluster/{cid} full page
- Fix: double-brace {{param}} in non-f-string queries → single {param}
  (was causing HTTP 500 on all parameterized ClickHouse queries)
- 50 routes total, all tests pass, 0 JS console errors

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-09 14:05:52 +02:00
parent 70188b508c
commit 702c0d5edb
6 changed files with 778 additions and 5 deletions

View File

@ -138,6 +138,7 @@
Détail campagne <span class="font-mono text-purple-300" id="detail-cid"></span>
</span>
<button onclick="closeDetail()" class="text-gray-400 hover:text-white transition-colors text-sm">✕ Fermer</button>
<a id="detail-link" href="/cluster/0" class="px-3 py-1 bg-brand-600 text-white rounded text-xs font-medium hover:bg-brand-500 ml-2">Ouvrir ↗</a>
</div>
<div class="section-body p-0">
<!-- Detail KPIs -->
@ -507,6 +508,7 @@ async function selectCampaign(cid) {
const panel = document.getElementById('detail-panel');
panel.classList.add('open');
document.getElementById('detail-cid').textContent = `#${cid}`;
document.getElementById('detail-link').href = `/cluster/${cid}`;
try {
const resp = await fetch(`/api/campaigns/${cid}`);