Files
breakpilot-compliance/backend-compliance/compliance/services/doc_checks/social_media_checks.py
T
Benjamin Admin b363c28539 feat: Add 76 Level-2 regex checks for document correctness verification
Split dsi_document_checker.py (466 LOC) into doc_checks/ package (9 files).
Two-pass L1→L2 logic: L1 checks "Is it mentioned?", L2 checks "Is it correct?"
(e.g. controller has full address, specific Art. 6 lit., concrete time periods).

138 total checks (62 L1 + 76 L2) across 7 doc types:
- DSE Art. 13: 31, Impressum §5 TMG: 16, Cookie §25 TDDDG: 15
- Widerruf §355: 15, AGB §305ff: 21, Social Media Art. 26: 20, DSFA Art. 35: 18

Frontend: hierarchical L1→L2 display with dual progress bars
(green=completeness, blue=correctness).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 12:37:03 +02:00

254 lines
10 KiB
Python

"""
Social Media DSE checks — Art. 26 DSGVO Joint Controller.
Level 1: Pflichtangabe erwaehnt?
Level 2: Pflichtangabe korrekt/vollstaendig?
"""
JOINT_CONTROLLER_CHECKLIST = [
# ── L1: Gemeinsam Verantwortliche ─────────────────────────────────
{
"id": "joint_parties",
"label": "Gemeinsam Verantwortliche benannt (Art. 26(1))",
"level": 1, "parent": None,
"patterns": [
r"gemeinsam.*verantwortlich", r"joint.*controller",
r"gemeinsame\s+verantwortlichkeit",
r"art\.\s*26", r"mitverantwortlich",
r"wir.*(?:und|gemeinsam).*(?:betreiber|facebook|meta|google)",
r"(?:betreiber|netzwerk).*verantwortlich",
],
"severity": "HIGH",
},
{
"id": "facebook_meta_named",
"label": "Facebook/Meta konkret als Verantwortlicher benannt",
"level": 2, "parent": "joint_parties",
"patterns": [
r"(?:facebook|meta)\s+(?:ireland|platforms|inc)",
r"meta\s+platforms.*(?:verantwortlich|controller|betreiber)",
],
"severity": "MEDIUM",
},
# ── L1: Vereinbarung Art. 26 ──────────────────────────────────────
{
"id": "arrangement",
"label": "Vereinbarung nach Art. 26 DSGVO",
"level": 1, "parent": None,
"patterns": [
r"vereinbarung.*art\.\s*26", r"art\.\s*26.*vereinbarung",
r"page\s*controller", r"fanpage", r"insights",
r"gemeinsame.*verantwortung.*(?:vertrag|vereinbarung)",
r"addendum|nachtrag|seiten.*insights",
],
"severity": "HIGH",
},
{
"id": "insights_referenced",
"label": "Seiteninsights / Page Insights erwaehnt",
"level": 2, "parent": "arrangement",
"patterns": [
r"(?:seiten[\-\s]?)?insights",
r"page\s+insights",
r"(?:statistik|nutzungsstatistik).*(?:facebook|meta|fanpage|seite)",
],
"severity": "MEDIUM",
},
{
"id": "page_controller_addendum",
"label": "Page Controller Addendum / Seiten-Insights-Ergaenzung",
"level": 2, "parent": "arrangement",
"patterns": [
r"page\s+controller\s+addendum",
r"seiten[\-\s]?insights[\-\s]?erg(?:ae|ä)nzung",
r"(?:addendum|nachtrag|erg(?:ae|ä)nzung).*(?:controller|verantwortlich)",
],
"severity": "LOW",
},
# ── L1: Anlaufstelle ──────────────────────────────────────────────
{
"id": "contact_point",
"label": "Anlaufstelle fuer Betroffene (Art. 26(1) S.3)",
"level": 1, "parent": None,
"patterns": [
r"anlaufstelle", r"kontaktstelle",
r"ansprechpartner.*betroffene",
r"rechte.*(?:gegen(?:ue|ü)ber)\s+(?:uns|beiden)",
r"rechte.*geltend\s+machen",
r"wenden\s+sie\s+sich",
],
"severity": "MEDIUM",
},
{
"id": "contact_both_parties",
"label": "Kontaktdaten beider Verantwortlicher",
"level": 2, "parent": "contact_point",
"patterns": [
r"(?:sowohl|beide).*(?:kontakt|wenden|geltend)",
r"(?:uns|bei\s+uns).*(?:als\s+auch|oder|und).*(?:facebook|meta|google|plattform)",
r"(?:facebook|meta|google|plattform).*(?:als\s+auch|oder|und).*(?:uns|bei\s+uns)",
],
"severity": "LOW",
},
# ── L1: Verarbeitungsaufteilung ───────────────────────────────────
{
"id": "processing_split",
"label": "Verarbeitungsaufteilung (wer macht was)",
"level": 1, "parent": None,
"patterns": [
r"(?:wir|betreiber).*(?:verarbeiten|erheben|nutzen).*(?:daten|informationen)",
r"(?:facebook|meta|google|youtube|instagram|linkedin|twitter|x\.com).*(?:verarbeit|erhebt|nutzt|speichert)",
r"bei\s+besuch\s+(?:unserer|der)\s+(?:seite|fanpage|profil)",
r"(?:nutzungsstatistik|statistik|insight).*(?:betreiber|netzwerk)",
],
"severity": "HIGH",
},
# ── L1: Datenkategorien ───────────────────────────────────────────
{
"id": "social_data_types",
"label": "Kategorien verarbeiteter Daten",
"level": 1, "parent": None,
"patterns": [
r"(?:nutzungsstatistik|insight|reichweite|interaktion|klick|aufruf)",
r"(?:ip.?adresse|standort|browser|ger(?:ae|ä)t|alter|geschlecht)",
r"(?:personenbezogen|daten).*(?:social|netzwerk|plattform)",
r"(?:nutzername|beitr(?:ae|ä)g|profil|like|kommentar)",
],
"severity": "HIGH",
},
# ── L1: Plattformen ───────────────────────────────────────────────
{
"id": "platforms",
"label": "Auflistung der genutzten Plattformen",
"level": 1, "parent": None,
"patterns": [
r"(?:facebook|instagram|youtube|twitter|x\.com|linkedin|xing|tiktok)",
r"(?:kan(?:ae|ä)le|plattform|netzwerk|profil|account|auftritte).*(?:social|medien)",
r"social\s*media.*(?:angebot|pr(?:ae|ä)senz|auftritte)",
],
"severity": "MEDIUM",
},
{
"id": "platform_dse_links",
"label": "Links zu Datenschutzerklaerungen der Plattformen",
"level": 2, "parent": "platforms",
"patterns": [
r"(?:datenschutz|privacy).*(?:facebook|meta|google|youtube|instagram|linkedin|twitter)",
r"(?:facebook|meta|google|youtube|instagram|linkedin|twitter).*(?:datenschutz|privacy)",
r"(?:privacy\s+policy|datenschutzerkl(?:ae|ä)rung).*(?:finden\s+sie|abrufbar|unter)",
],
"severity": "LOW",
},
# ── L1: Drittlandtransfer ─────────────────────────────────────────
{
"id": "third_country",
"label": "Drittlandtransfer (USA bei Social Media)",
"level": 1, "parent": None,
"patterns": [
r"(?:usa|vereinigte\s+staaten|drittland|drittstaaten)",
r"privacy\s+shield|data\s+privacy\s+framework|angemessenheitsbeschluss",
r"standardvertragsklausel|standard.*contractual",
r"(?:(?:ue|ü)bermittlung|(?:ueber|über)mittlung).*(?:usa|drittland|au(?:ss|ß)erhalb)",
],
"severity": "MEDIUM",
},
{
"id": "usa_transfer_scc",
"label": "Standardvertragsklauseln (SCC) fuer US-Transfer",
"level": 2, "parent": "third_country",
"patterns": [
r"standard\s*vertragsklausel|scc",
r"standard\s+contractual\s+clause",
],
"severity": "MEDIUM",
},
{
"id": "usa_transfer_dpf",
"label": "Data Privacy Framework (DPF) fuer US-Transfer",
"level": 2, "parent": "third_country",
"patterns": [
r"data\s+privacy\s+framework|dpf",
r"angemessenheitsbeschluss.*(?:usa|us|amerika)",
r"adequacy\s+decision",
],
"severity": "LOW",
},
# ── L1: Rechtsgrundlage ───────────────────────────────────────────
{
"id": "legal_basis",
"label": "Rechtsgrundlage (Art. 6 DSGVO)",
"level": 1, "parent": None,
"patterns": [
r"rechtsgrundlage", r"art\.\s*6",
r"berechtigtes\s+interesse",
r"einwilligung.*art\.\s*6", r"lit\.\s*[a-f]",
],
"severity": "MEDIUM",
},
{
"id": "legal_basis_specific_lit",
"label": "Konkretes Art. 6(1) lit. angegeben",
"level": 2, "parent": "legal_basis",
"patterns": [
r"art\.\s*6\s*(?:abs\.\s*)?1\s*(?:s\.\s*1\s*)?(?:lit\.\s*)?[a-f]",
],
"severity": "LOW",
},
# ── L1: Betroffenenrechte ─────────────────────────────────────────
{
"id": "rights",
"label": "Betroffenenrechte (Art. 15-21)",
"level": 1, "parent": None,
"patterns": [
r"recht\s+auf\s+auskunft", r"recht\s+auf\s+l(?:oe|ö)schung",
r"art\.\s*1[5-9]", r"betroffenenrecht",
r"ihre\s+rechte", r"rechte.*betroffene",
r"widerspruchsrecht",
],
"severity": "MEDIUM",
},
{
"id": "opt_out_social",
"label": "Opt-Out-Moeglichkeit fuer Social-Media-Tracking",
"level": 2, "parent": "rights",
"patterns": [
r"(?:opt[\-\s]?out|widerspruch|deaktivieren).*(?:social|facebook|tracking|insight)",
r"(?:social|facebook|tracking|insight).*(?:opt[\-\s]?out|widerspruch|deaktivieren)",
r"(?:abmelden|abschalten).*(?:tracking|statistik|insight)",
],
"severity": "LOW",
},
# ── L1: Social Bookmarks vs Plugins ───────────────────────────────
{
"id": "social_bookmarks",
"label": "Hinweis auf Social Bookmarks vs. Plugins",
"level": 1, "parent": None,
"patterns": [
r"social\s*(?:bookmark|plugin|button|widget)",
r"(?:kein|keine).*(?:plugin|widget|button).*(?:gesetzt|eingebunden|geladen)",
r"(?:link|verweis|weiterleitung).*(?:dienst|anbieter|netzwerk)",
],
"severity": "MEDIUM",
},
{
"id": "two_click_solution",
"label": "2-Klick-Loesung oder vergleichbare Technik",
"level": 2, "parent": "social_bookmarks",
"patterns": [
r"(?:zwei|2)[\-\s]?klick",
r"(?:shariff|share[\-\s]?buttons?\s+ohne\s+tracking)",
r"(?:erst|nur)\s+(?:bei|nach|durch)\s+(?:klick|aktivierung).*(?:daten|verbindung)",
],
"severity": "LOW",
},
]