feat(cookie): A — Findings auditfest an Controls verdrahten

Jeder Cookie-Befund traegt jetzt ein strukturiertes control-Feld
(control_id aus doc_check_controls + regulation + article) statt nur
hardcodeter Strings: vague_duration->AUTH-2051-A03 (Art.5(1)e+13),
tracker_as_necessary->DATA-2851-A05 (§25 TDDDG), third_country->
DATA-1624-A04 (Art.44). Kette Regulation->Article->Control->Finding.
Frontend zeigt die Rechtsgrundlage je Befund. (Controls tragen
regulation/article noch NULL -> hier mitgeliefert bis gepflegt.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-11 08:44:19 +02:00
parent 4c45f11e43
commit 901de1ca97
3 changed files with 38 additions and 0 deletions
@@ -22,6 +22,19 @@ from compliance.services.cookie_knowledge_db import lookup_cookie
_TRACKER_CATS = {"marketing", "statistics", "social_media", "targeting"}
# A — auditfeste Verdrahtung: jeder Befund-Typ → echter Control (control_id aus
# doc_check_controls) + legal_basis. Die Controls tragen regulation/article noch
# NULL, daher liefern wir die Rechtsgrundlage hier strukturiert mit (bis sie in
# den Controls gepflegt ist). Kette: Regulation → Article → Control → Finding.
_CONTROL_MAP = {
"vague_duration": {"control_id": "AUTH-2051-A03", "regulation": "DSGVO", "article": "Art. 5 Abs. 1 lit. e + Art. 13"},
"excessive_lifetime": {"control_id": "AUTH-2051-A02", "regulation": "DSGVO", "article": "Art. 5 Abs. 1 lit. e"},
"tracker_as_necessary": {"control_id": "DATA-2851-A05", "regulation": "TDDDG", "article": "§ 25 Abs. 1"},
"missing_purpose": {"control_id": "AUTH-2053-A05", "regulation": "DSGVO", "article": "Art. 13"},
"third_country": {"control_id": "DATA-1624-A04", "regulation": "DSGVO", "article": "Art. 44 ff."},
"eu_alternative": {"control_id": None, "regulation": "", "article": "kommerzielle Empfehlung"},
}
def load_big_library(db, names: list[str]) -> dict:
"""Batch-Lookup der grossen Open-Cookie-Database (compliance.cookie_library,
@@ -219,6 +232,9 @@ def analyze_cookies(vendors: list[dict], big_lib: dict | None = None) -> dict:
),
})
# A: jeden Befund an seinen Control + Rechtsgrundlage haengen (auditfest).
for f in findings:
f["control"] = _CONTROL_MAP.get(f["type"], {})
findings.sort(key=lambda f: _SEV_ORDER.get(f["severity"], 3))
return {
"summary": {