fix(browser-matrix): Tracking-Signal statt Cookie-Rohzahl + Matrix-Schnellpfad

Korrektheit (§ 25 TDDDG): "Cookies vor Consent" ist KEIN Verstoss per se —
technisch notwendige Cookies inkl. des Consent-Cookies (speichert die
Ablehnung) sind nach Abs. 2 erlaubt. Verstoss ist nur nicht-essentielles
TRACKING vor Consent.
- browser_cross_finding: Befund haengt jetzt an violations.before_consent
  (Tracking), nicht an der Cookie-Rohzahl; § 25 Abs. 2-Hinweis im Detail.
  Regressionstest: Cookies-ohne-Tracking → KEIN Befund.
- multi_browser_scanner._extract_dimensions: Score nutzt Tracking-Violations
  + reject_respected-Verdikt statt Rohzahl (Fallback erhalten).
- BrowserBehaviorView: "Cookies vor Consent" nur rot/⚠ bei Tracking,
  "nach Ablehnen" neutral (Verdikt = reject-Spalte); erklaerende Zeile.

Speed: run_consent_test ueberspringt im Matrix-Modus (browser_profile gesetzt)
die teuren Phasen C/D-F/G — nur A+B noetig. Verhindert das 504 beim
Multi-Engine-Scan (BMW 4 Engines lief sonst in den 338s-Gateway-Timeout).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-13 00:10:41 +02:00
parent fa8ad030cb
commit 3f90e40807
5 changed files with 99 additions and 34 deletions
@@ -13,10 +13,12 @@ import React, { useEffect, useState } from 'react'
type Finding = { text: string; severity: string; legal_ref?: string; service?: string }
type Surface = { has_impressum_link?: boolean; has_dse_link?: boolean; banner_text_issues?: number }
type Violations = { before_consent?: number; after_reject?: number; banner_text?: number }
type Summary = {
cookies_before_consent?: number; cookies_after_reject?: number
reject_respected?: boolean; banner_detected?: boolean; banner_provider?: string
banner_screenshot_b64?: string; surface?: Surface; banner_findings?: Finding[]
violations?: Violations
}
type Row = {
profile_id: string; label: string; engine?: string; is_mobile?: boolean
@@ -164,6 +166,7 @@ export function BrowserBehaviorView({ snapshotId }: { snapshotId: string }) {
const s = r.summary
const before = s?.cookies_before_consent ?? null
const after = s?.cookies_after_reject ?? null
const trackBefore = s?.violations?.before_consent ?? 0
const sld = r.profile_id === sel
return (
<tr key={r.profile_id} onClick={() => setSel(r.profile_id)}
@@ -178,8 +181,11 @@ export function BrowserBehaviorView({ snapshotId }: { snapshotId: string }) {
</td>
) : (
<>
<td className={`px-3 py-2 text-center ${(before ?? 0) > 0 ? 'text-red-700 font-semibold' : 'text-green-700'}`}>{before}</td>
<td className={`px-3 py-2 text-center ${(after ?? 0) > 0 ? 'text-amber-700' : 'text-green-700'}`}>{after}</td>
<td className={`px-3 py-2 text-center ${trackBefore > 0 ? 'text-red-700 font-semibold' : 'text-gray-500'}`}
title={trackBefore > 0 ? `${trackBefore} davon Tracking (Verstoß)` : 'kein Tracking vor Consent'}>
{before}{trackBefore > 0 ? ` · ${trackBefore}⚠` : ''}
</td>
<td className="px-3 py-2 text-center text-gray-500">{after}</td>
<td className="px-3 py-2 text-center">
{s.reject_respected ? <span className="text-green-700">✓</span> : <span className="text-red-700 font-semibold">✗</span>}
</td>
@@ -200,6 +206,13 @@ export function BrowserBehaviorView({ snapshotId }: { snapshotId: string }) {
</table>
</div>
<p className="text-xs text-gray-400">
„Cookies vor Consent" ist die Rohzahl technisch notwendige Cookies
(inkl. des Consent-Cookies, das die Ablehnung speichert) sind nach
§ 25 Abs. 2 TDDDG erlaubt. Rot/ markiert nur den einwilligungs­pflichtigen
Tracking-Anteil. Das Verdikt zu Ablehnen" trägt die Spalte rechts.
</p>
{selRow && (
<div className="border border-gray-200 rounded-xl p-4 space-y-3">
<div className="flex items-center gap-2 flex-wrap">