feat: Art. 26 Joint Controller + DSFA checklists for Social Media sections
New checklists: - JOINT_CONTROLLER_CHECKLIST (Art. 26 DSGVO, 7 checks): Joint parties, arrangement, contact point, processing split, data categories, third-country transfer (USA), rights - DSFA_CHECKLIST (Art. 35 DSGVO, 5 checks): Description, necessity, risk assessment, measures, DSB involvement Section detection: 'Datenschutzerklaerung fuer Social Media' → social_media, 'Datenschutzfolgeabschaetzung/Risikoanalyse' → dsfa classify_document_type: DSFA and social_media detected before generic DSE Frontend: DOC_TYPES dropdown + ChecklistView labels updated Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -263,9 +263,8 @@ SECTION_TYPE_MAP = [
|
||||
(r"widerrufsrecht|widerrufsbelehrung", "widerruf"), # Widerruf → §355 BGB
|
||||
(r"^impressum$", "impressum"), # Impressum → §5 TMG
|
||||
(r"^(?:agb|allgemeine geschäftsbedingungen|nutzungsbedingungen)$", "agb"),
|
||||
# NOTE: Social Media, DSFA, Datensicherheit, Betroffenenrechte are NOT
|
||||
# separate documents — they are sections within the parent DSI.
|
||||
# DSFA needs its own checklist (RAG-based) — Phase 2.
|
||||
(r"datenschutzerkl.*social|datenschutz.*social\s*media", "social_media"),
|
||||
(r"datenschutzfolge|dsfa|risikoanalyse.*social", "dsfa"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -196,6 +196,58 @@ COOKIE_CHECKLIST = [
|
||||
"patterns": [r"(?:widerspruch|opt.?out|ablehnen|deaktivieren).*cookie", r"cookie.*(?:ablehnen|deaktivieren|loeschen)"]},
|
||||
]
|
||||
|
||||
# Art. 26 DSGVO Joint Controller (Social Media DSE)
|
||||
JOINT_CONTROLLER_CHECKLIST = [
|
||||
{"id": "joint_parties", "label": "Gemeinsam Verantwortliche benannt (Art. 26(1))",
|
||||
"patterns": [r"gemeinsam.*verantwortlich", r"joint.*controller", r"gemeinsame\s+verantwortlichkeit",
|
||||
r"art\.\s*26", r"mitverantwortlich"]},
|
||||
{"id": "arrangement", "label": "Vereinbarung nach Art. 26 DSGVO",
|
||||
"patterns": [r"vereinbarung.*art\.\s*26", r"art\.\s*26.*vereinbarung",
|
||||
r"page\s*controller", r"fanpage", r"insights",
|
||||
r"gemeinsame.*verantwortung.*(?:vertrag|vereinbarung)"]},
|
||||
{"id": "contact_point", "label": "Anlaufstelle fuer Betroffene (Art. 26(1) S.3)",
|
||||
"patterns": [r"anlaufstelle", r"kontaktstelle", r"ansprechpartner.*betroffene",
|
||||
r"rechte.*(?:gegenueber|gegenüber)\s+(?:uns|beiden)",
|
||||
r"rechte.*(?:sowohl|grundsaetzlich|grundsätzlich).*(?:uns|als auch)"]},
|
||||
{"id": "processing_split", "label": "Verarbeitungsaufteilung (wer macht was)",
|
||||
"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)"]},
|
||||
{"id": "social_data_types", "label": "Kategorien verarbeiteter Daten",
|
||||
"patterns": [r"(?:nutzungsstatistik|insight|reichweite|interaktion|klick|aufruf)",
|
||||
r"(?:ip.?adresse|standort|browser|geraet|alter|geschlecht).*(?:social|profil|seite|fanpage)",
|
||||
r"(?:personenbezogen|daten).*(?:social|netzwerk|plattform)"]},
|
||||
{"id": "third_country", "label": "Drittlandtransfer (USA bei Social Media)",
|
||||
"patterns": [r"(?:usa|vereinigte\s+staaten|drittland|drittstaaten).*(?:social|facebook|meta|google)",
|
||||
r"(?:social|facebook|meta|google).*(?:usa|drittland|drittstaaten)",
|
||||
r"privacy\s+shield|data\s+privacy\s+framework|angemessenheitsbeschluss",
|
||||
r"standardvertragsklausel|standard.*contractual"]},
|
||||
{"id": "rights", "label": "Betroffenenrechte (Art. 15-21)",
|
||||
"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"]},
|
||||
]
|
||||
|
||||
# DSFA minimal checklist (Art. 35 DSGVO) — basic structure checks
|
||||
DSFA_CHECKLIST = [
|
||||
{"id": "description", "label": "Beschreibung der Verarbeitungsvorgaenge (Art. 35(7)(a))",
|
||||
"patterns": [r"beschreibung.*verarbeitung", r"verarbeitungsvorg(?:ae|ä)ng",
|
||||
r"systematische\s+beschreibung", r"gegenstand.*verarbeitung"]},
|
||||
{"id": "necessity", "label": "Notwendigkeit und Verhaeltnismaessigkeit (Art. 35(7)(b))",
|
||||
"patterns": [r"notwendigkeit", r"verh(?:ae|ä)ltnism(?:ae|ä)ssigkeit",
|
||||
r"erforderlichkeit", r"zweckbindung"]},
|
||||
{"id": "risks", "label": "Risikobewertung fuer Betroffene (Art. 35(7)(c))",
|
||||
"patterns": [r"risiko.*(?:bewertung|analyse|einsch(?:ae|ä)tzung)",
|
||||
r"risiken.*(?:rechte|freiheit)", r"eintrittswahrscheinlichkeit",
|
||||
r"schwere.*(?:risiko|auswirkung)"]},
|
||||
{"id": "measures", "label": "Abhilfemassnahmen (Art. 35(7)(d))",
|
||||
"patterns": [r"abhilfe", r"massnahmen.*risiko", r"schutzma(?:ss|ß)nahm",
|
||||
r"(?:technisch|organisatorisch).*massnahm", r"tom"]},
|
||||
{"id": "stakeholders", "label": "Einbeziehung des DSB (Art. 35(2))",
|
||||
"patterns": [r"datenschutzbeauftragt.*(?:einbez|konsult|beteilig|rat)",
|
||||
r"dsb.*(?:konsult|einbez|rat)", r"stellungnahme.*dsb"]},
|
||||
]
|
||||
|
||||
|
||||
def check_document_completeness(
|
||||
text: str,
|
||||
@@ -255,6 +307,12 @@ def check_document_completeness(
|
||||
elif doc_type in ("cookie",):
|
||||
checklist = COOKIE_CHECKLIST
|
||||
label = "§25 TDDDG"
|
||||
elif doc_type in ("social_media", "joint_controller"):
|
||||
checklist = JOINT_CONTROLLER_CHECKLIST
|
||||
label = "Art. 26 DSGVO"
|
||||
elif doc_type in ("dsfa",):
|
||||
checklist = DSFA_CHECKLIST
|
||||
label = "Art. 35 DSGVO"
|
||||
else:
|
||||
checklist = ART13_CHECKLIST # Default: check as DSE
|
||||
label = "Art. 13 DSGVO"
|
||||
@@ -323,6 +381,11 @@ def classify_document_type(title: str, url: str) -> str:
|
||||
"""Classify a document by its title/URL into a legal document type."""
|
||||
combined = f"{title} {url}".lower()
|
||||
|
||||
if any(kw in combined for kw in ["datenschutzfolge", "dsfa", "risikoanalyse für nutzung"]):
|
||||
return "dsfa"
|
||||
if any(kw in combined for kw in ["social media", "facebook", "instagram", "linkedin", "fanpage"]):
|
||||
if any(kw in combined for kw in ["datenschutzerkl", "datenschutz für", "datenschutzinformation"]):
|
||||
return "social_media"
|
||||
if any(kw in combined for kw in ["datenschutz", "privacy", "dsgvo", "data protection", "données"]):
|
||||
return "dse"
|
||||
if any(kw in combined for kw in ["widerruf", "withdrawal", "rétractation", "desistimiento"]):
|
||||
|
||||
Reference in New Issue
Block a user