"""B12 wiring — Chatbot-Cookie-Klassifikation. Hängt sich an `state["extra_findings"]` mit ähnlichem Render-Pattern wie B9/B10. Wird vom Orchestrator nach B11 (run_b9b10) aufgerufen. """ from __future__ import annotations import html import logging from compliance.services.chatbot_cookie_classification_check import ( check_chatbot_cookie_classification, ) logger = logging.getLogger(__name__) def run_b12(state: dict) -> None: new = check_chatbot_cookie_classification(state) if not new: return extras = state.get("extra_findings") or [] extras.extend(new) state["extra_findings"] = extras state["chatbot_cookie_html"] = _render(new) logger.info("B12 chatbot-cookies: %d findings", len(new)) def _render(findings: list[dict]) -> str: cards = [] for f in findings: sev = (f.get("severity") or "").upper() color = "#dc2626" if sev == "HIGH" else ( "#f59e0b" if sev == "MEDIUM" else "#64748b" ) meta = ( "
" f"Provider: {html.escape(f.get('provider') or '?')} · " f"Cookie: {html.escape(f.get('cookie_name') or '?')}" "
" ) evidence = "" if f.get("evidence"): evidence = ( "
" f"{html.escape(f['evidence'])}
" ) cards.append( f"
" f"
" f"{sev} · {html.escape(f.get('check_id') or '')}
" f"
" f"{html.escape(f.get('title') or '')}
" f"
" f"{html.escape(f.get('norm') or '')}
" f"{meta}{evidence}" f"
" f"→ Empfehlung: " f"{html.escape(f.get('action') or '')}
" "
" ) return ( "
" "

" "💬 Chatbot-Cookie-Klassifikation (KB-basiert)" "

" + "".join(cards) + "
" )