3332eb0bf9
Snapshot-getriebene Result-Views, entkoppelt vom Live-Check:
- CookieResultView: laedt cmp_vendors aus einem Snapshot (kein Re-Crawl),
KPIs (Anbieter/Cookies/Marketing/Drittland) + Empfaenger-Gruppen
(Eigene/AVV/Joint-Controller) + aufklappbare Vendor->Cookie-Tabelle.
- Historie (/sdk/agent/snapshots): alle gespeicherten Checks, jederzeit
oeffnbar (DSB/Mitarbeiter) + Detail-Seite je Snapshot.
- Next.js-Proxys fuer GET /snapshots (Liste) + /snapshots/{id} (einzeln).
BMW-Snapshot 4603d15b: 83 Vendors / 780 Cookies. Library-Abgleich
(cookie_knowledge_db.lookup_cookie) folgt als Phase B.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
'use client'
|
||
|
||
/**
|
||
* Check-Historie — listet gespeicherte Snapshots (alle Sites/Module).
|
||
* Ein DSB/Mitarbeiter kann jeden früheren Check öffnen, ohne neuen Check
|
||
* zu starten. Daten kommen aus den Snapshot-Rohdaten.
|
||
*/
|
||
|
||
import React, { useEffect, useState } from 'react'
|
||
import Link from 'next/link'
|
||
|
||
interface SnapMeta {
|
||
id: string
|
||
check_id?: string
|
||
site_domain?: string
|
||
site_label?: string
|
||
created_at?: string
|
||
replay_count?: number
|
||
}
|
||
|
||
export default function SnapshotHistory() {
|
||
const [snaps, setSnaps] = useState<SnapMeta[]>([])
|
||
const [loading, setLoading] = useState(true)
|
||
|
||
useEffect(() => {
|
||
let cancelled = false
|
||
fetch('/api/sdk/v1/agent/snapshots?limit=50')
|
||
.then(r => r.json())
|
||
.then(d => { if (!cancelled) setSnaps(d.snapshots || []) })
|
||
.catch(() => { if (!cancelled) setSnaps([]) })
|
||
.finally(() => { if (!cancelled) setLoading(false) })
|
||
return () => { cancelled = true }
|
||
}, [])
|
||
|
||
return (
|
||
<div className="p-6 max-w-4xl space-y-4">
|
||
<div>
|
||
<h1 className="text-xl font-semibold text-gray-900">Check-Historie</h1>
|
||
<p className="text-xs text-gray-500 mt-1">
|
||
Frühere Compliance-Checks aus gespeicherten Snapshots — jederzeit
|
||
ansehbar, ohne neuen Check zu starten.
|
||
</p>
|
||
</div>
|
||
|
||
{loading ? (
|
||
<div className="text-sm text-gray-500">Lade Historie…</div>
|
||
) : snaps.length === 0 ? (
|
||
<div className="text-sm text-gray-400">Keine gespeicherten Checks gefunden.</div>
|
||
) : (
|
||
<div className="border rounded-lg divide-y divide-gray-100">
|
||
{snaps.map(s => (
|
||
<Link
|
||
key={s.id}
|
||
href={`/sdk/agent/snapshots/${s.id}`}
|
||
className="flex items-center gap-3 px-4 py-3 hover:bg-gray-50 text-sm"
|
||
>
|
||
<span className="font-medium text-gray-800 w-44 truncate">
|
||
{s.site_label || s.site_domain || 'unbekannt'}
|
||
</span>
|
||
<span className="text-gray-500 flex-1 min-w-0 truncate">{s.site_domain}</span>
|
||
<span className="text-xs text-gray-400 whitespace-nowrap">
|
||
{(s.created_at || '').slice(0, 16).replace('T', ' ')}
|
||
</span>
|
||
<span className="text-gray-300">›</span>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|