c281464071
CI / detect-changes (push) Successful in 10s
CI / branch-name (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 15s
CI / test-python-backend (push) Successful in 39s
CI / test-python-document-crawler (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / loc-budget (push) Failing after 17s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
jc_avv_decision.py: detect_ambiguous_jc_avv prueft ob DSE-Text sowohl JC-Signale (gemeinsame Auswertung, Schwesterunternehmen, Konzern...) als auch AVV-Signale (Auftragsverarbeiter, weisungsgebunden...) enthaelt. Bei Treffer rendert build_jc_avv_decision_html einen Block mit 4 EDPB- basierten Leitfragen + jeweiliger Empfehlung. Quellen: EDPB Guidelines 7/2020, EuGH C-25/17, C-40/17. In Mail-Render zwischen Solutions-Block und VVT eingehaengt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
117 lines
4.7 KiB
Python
117 lines
4.7 KiB
Python
"""
|
|
P71 — JC-vs-AVV Entscheidungsbaum.
|
|
|
|
Hilft dem Nutzer zu bestimmen, ob ein bestimmtes Verarbeitungsverhaeltnis
|
|
gemeinsame Verantwortlichkeit (Art. 26 DSGVO) oder Auftragsverarbeitung
|
|
(Art. 28 DSGVO) ist. EDPB 7/2020 ist die Grundlage.
|
|
|
|
Wird gerendert als kleiner Block am Ende der Mail, wenn im DSE-Text
|
|
Konstrukte vorkommen die ambivalent sind (z.B. 'gemeinsame Auswertung
|
|
mit Schwesterunternehmen', 'gemeinsame Plattform-Nutzung'). Liefert
|
|
3-4 Leitfragen + jeweilige Empfehlung.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_JC_SIGNALS = (
|
|
"schwesterunternehmen", "konzernschwester", "gemeinsame plattform",
|
|
"gemeinsame auswertung", "gemeinsame studie", "joint venture",
|
|
"konzernweite analyse", "gemeinsame zwecke", "gemeinsame ziele",
|
|
"konzernweit", "gemeinsamer kunde", "gemeinsamer datenpool",
|
|
)
|
|
|
|
_AVV_SIGNALS = (
|
|
"auftragsverarbeiter", "auftragsverarbeitung", "weisungsgebunden",
|
|
"im auftrag von", "im namen des verantwortlichen",
|
|
"art. 28 dsgvo", "art 28 dsgvo", "dpa (data processing agreement",
|
|
)
|
|
|
|
_QUESTIONS = [
|
|
{
|
|
"q": "Bestimmen beide Seiten gemeinsam Zweck UND Mittel der Verarbeitung?",
|
|
"yes": "JC (Art. 26)",
|
|
"no": "AVV-Indikator",
|
|
"explain": "EDPB 7/2020 Rn. 51-65: beidseitige Zweckbestimmung ist "
|
|
"das Hauptmerkmal der gemeinsamen Verantwortlichkeit.",
|
|
},
|
|
{
|
|
"q": "Verfolgen die Parteien eigene, getrennte Zwecke (z.B. eigene "
|
|
"Kundenbeziehung) oder einen gemeinsamen Zweck?",
|
|
"yes": "Wenn getrennt: AVV (oder zwei getrennte Verantwortliche)",
|
|
"no": "Wenn gemeinsam: JC (Art. 26)",
|
|
"explain": "EuGH C-25/17 Zeugen Jehovas: getrennte Zwecke "
|
|
"schliessen JC aus.",
|
|
},
|
|
{
|
|
"q": "Existiert eine schriftliche Weisungs-Hierarchie und Pflicht "
|
|
"zur Loeschung am Vertragsende?",
|
|
"yes": "AVV (Art. 28 Pflichten erfuellt)",
|
|
"no": "Pruefen ob JC vorliegt + Art. 26-Vereinbarung noetig",
|
|
"explain": "Art. 28 (3)(g) DSGVO + EDPB 7/2020 Rn. 88.",
|
|
},
|
|
{
|
|
"q": "Haben Betroffene gegenueber beiden Stellen vollstaendige "
|
|
"Rechte (Art. 15-22)?",
|
|
"yes": "JC — Art. 26 (3) verlangt einheitliche Anlaufstelle",
|
|
"no": "AVV — Auftragsverarbeiter weist Rechtsausuebung an "
|
|
"Verantwortlichen zurueck",
|
|
"explain": "Art. 26 (3) DSGVO macht beide Stellen als gemeinsame "
|
|
"Anlaufstelle ansprechbar.",
|
|
},
|
|
]
|
|
|
|
|
|
def detect_ambiguous_jc_avv(dse_text: str | None) -> bool:
|
|
"""Heuristik: liegen sowohl JC- als auch AVV-Signale im DSE? Dann
|
|
ist die Konstellation typischerweise unklar und der Entscheidungsbaum
|
|
hilft."""
|
|
if not dse_text:
|
|
return False
|
|
t = dse_text.lower()
|
|
has_jc = any(s in t for s in _JC_SIGNALS)
|
|
has_avv = any(s in t for s in _AVV_SIGNALS)
|
|
return has_jc and has_avv
|
|
|
|
|
|
def build_jc_avv_decision_html(dse_text: str | None) -> str:
|
|
if not detect_ambiguous_jc_avv(dse_text):
|
|
return ""
|
|
items = []
|
|
for i, q in enumerate(_QUESTIONS, 1):
|
|
items.append(
|
|
f'<li style="margin-bottom:8px;font-size:11px;line-height:1.5">'
|
|
f'<strong>{i}. {q["q"]}</strong><br>'
|
|
f'<span style="color:#16a34a">Ja: </span>{q["yes"]} | '
|
|
f'<span style="color:#dc2626">Nein: </span>{q["no"]}<br>'
|
|
f'<span style="color:#64748b;font-size:10px;font-style:italic">'
|
|
f'{q["explain"]}</span>'
|
|
f'</li>'
|
|
)
|
|
return (
|
|
'<div style="font-family:-apple-system,BlinkMacSystemFont,sans-serif;'
|
|
'max-width:760px;margin:0 auto 16px;padding:12px 16px;'
|
|
'background:#f1f5f9;border:1px solid #cbd5e1;border-radius:6px">'
|
|
'<div style="font-size:11px;color:#475569;text-transform:uppercase;'
|
|
'letter-spacing:1.2px;margin-bottom:4px;font-weight:600">'
|
|
'JC vs AVV — Entscheidungshilfe</div>'
|
|
'<h3 style="margin:0 0 6px;font-size:14px;color:#1e293b">'
|
|
'Im DSE-Text gibt es sowohl gemeinsame-Verantwortlichkeits- als '
|
|
'auch Auftragsverarbeitungs-Hinweise</h3>'
|
|
'<p style="margin:0 0 10px;font-size:11px;color:#475569;line-height:1.5">'
|
|
'Pruefen Sie mit dem DSB die folgenden 4 Leitfragen aus EDPB 7/2020. '
|
|
'Das Ergebnis bestimmt ob eine Art. 26-Vereinbarung (JC) oder ein '
|
|
'Art. 28-AVV vorliegen muss.'
|
|
'</p>'
|
|
'<ol style="margin:0 0 0 18px;padding:0">'
|
|
+ "".join(items) +
|
|
'</ol>'
|
|
'<p style="margin:8px 0 0;font-size:10px;color:#94a3b8;'
|
|
'font-style:italic">Quelle: EDPB Guidelines 7/2020 (Controller/Processor) '
|
|
'+ EuGH C-25/17, C-40/17.</p>'
|
|
'</div>'
|
|
)
|