diff --git a/backend-compliance/compliance/services/intake_extractor.py b/backend-compliance/compliance/services/intake_extractor.py index 4c3fb90..6642a86 100644 --- a/backend-compliance/compliance/services/intake_extractor.py +++ b/backend-compliance/compliance/services/intake_extractor.py @@ -18,27 +18,34 @@ OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://host.docker.internal:11434") OLLAMA_MODEL = os.environ.get("OLLAMA_MODEL", "qwen3.5:35b-a3b") EXTRACTION_PROMPT = """/no_think -Analysiere den folgenden Text (Datenschutzerklaerung oder Website-Inhalt) und -bestimme fuer JEDES der folgenden Flags ob es zutrifft (true/false). +Du analysierst eine Datenschutzerklaerung oder Website. Bestimme ob der +BETREIBER DIESER WEBSITE die folgenden Daten AKTIV VERARBEITET. + +WICHTIG: Setze ein Flag NUR auf true wenn der Websitebetreiber diese Daten +SELBST erhebt, speichert oder verarbeitet. NICHT wenn die Website nur +UEBER solche Themen BERICHTET oder informiert. + +Beispiel: Eine IHK-Website die UEBER Datenschutz im Gesundheitswesen +berichtet → health_data: false (die IHK verarbeitet keine Gesundheitsdaten) Flags: -- personal_data: Werden personenbezogene Daten verarbeitet? -- customer_data: Werden Kundendaten (Name, Email, Adresse) gespeichert? -- payment_data: Werden Zahlungsdaten (Kreditkarte, IBAN, PayPal) verarbeitet? -- location_data: Werden Standort-/GPS-Daten erhoben? -- biometric_data: Werden biometrische Daten verarbeitet? -- minor_data: Werden Daten von Kindern/Minderjaehrigen verarbeitet? -- health_data: Werden Gesundheitsdaten verarbeitet? -- marketing: Werden Daten fuer Werbung/Marketing/Newsletter genutzt? -- profiling: Findet Profiling, Scoring oder Personalisierung statt? -- automated_decisions: Werden automatisierte Einzelentscheidungen getroffen (Art. 22)? -- third_party_sharing: Werden Daten an Dritte/Partner weitergegeben? -- cross_border_transfer: Findet Datentransfer ausserhalb EU/EWR statt? -- tracking: Werden Cookies/Tracking-Pixel/Analytics eingesetzt? -- ai_usage: Wird KI/Machine Learning/Algorithmen eingesetzt? +- personal_data: Erhebt der Betreiber personenbezogene Daten (Name, Email, IP)? +- customer_data: Speichert der Betreiber Kundendaten (Registrierung, Konto)? +- payment_data: Verarbeitet der Betreiber Zahlungsdaten (Shop, Buchung)? +- location_data: Erhebt der Betreiber GPS/Standortdaten der Nutzer? +- biometric_data: Verarbeitet der Betreiber biometrische Daten? +- minor_data: Richtet sich die Website gezielt an Kinder/Minderjaehrige? +- health_data: Verarbeitet der Betreiber Gesundheitsdaten seiner Nutzer? +- marketing: Nutzt der Betreiber Nutzerdaten fuer eigene Werbung/Newsletter? +- profiling: Erstellt der Betreiber Nutzerprofile oder Scoring? +- automated_decisions: Trifft der Betreiber automatisierte Einzelentscheidungen? +- third_party_sharing: Gibt der Betreiber Nutzerdaten an Dritte weiter? +- cross_border_transfer: Uebermittelt der Betreiber Daten ausserhalb EU/EWR? +- tracking: Setzt der Betreiber Cookies/Tracking/Analytics ein? +- ai_usage: Setzt der Betreiber KI/Machine Learning ein? Antworte NUR mit einem JSON-Objekt, keine Erklaerung: -{"personal_data": true, "customer_data": true, ...} +{"personal_data": true, "customer_data": false, ...} """ diff --git a/backend-compliance/compliance/services/website_compliance_checks.py b/backend-compliance/compliance/services/website_compliance_checks.py index e4db302..5a9dfaf 100644 --- a/backend-compliance/compliance/services/website_compliance_checks.py +++ b/backend-compliance/compliance/services/website_compliance_checks.py @@ -28,7 +28,16 @@ async def check_website_compliance( html_lower = html.lower() base_domain = re.sub(r"https?://([^/]+).*", r"\1", url) - # --- §312k BGB: Kündigungsbutton --- + # E-Commerce detection — §312k only applies to sites with online contracts + ecommerce_indicators = [ + r"warenkorb", r"cart", r"shop", r"bestell", r"order", + r"checkout", r"kasse", r"kaufen", r"add.?to.?cart", + r"stripe|paypal|klarna|mollie|adyen", + r"abo", r"mitgliedschaft", r"subscription", r"premium", + ] + is_ecommerce = any(re.search(p, html_lower) for p in ecommerce_indicators) + + # --- §312k BGB: Kündigungsbutton (NUR bei E-Commerce/Abo-Websites) --- cancel_patterns = [ r'href="[^"]*(?:kuendig|kündig|cancel|vertrag.?beenden|abo.?beenden|mitgliedschaft.?beenden)[^"]*"', r'(?:kündigen|kuendigen|vertrag beenden|abo beenden|mitgliedschaft kündigen)', @@ -52,7 +61,7 @@ async def check_website_compliance( except Exception: continue - if not has_cancel_link: + if not has_cancel_link and is_ecommerce: findings.append( "[§312k BGB] Kein oeffentlich sichtbarer Kuendigungsbutton gefunden. " "Seit 01.07.2022 muessen online geschlossene Vertraege mit max. 2 Klicks kuendbar sein."