fix: 5 regex bugs + text extraction scroll + GT update
Build + Deploy / build-backend-compliance (push) Successful in 23s
Build + Deploy / build-ai-sdk (push) Successful in 13s
Build + Deploy / build-admin-compliance (push) Successful in 13s
Build + Deploy / build-developer-portal (push) Successful in 14s
Build + Deploy / build-tts (push) Successful in 15s
Build + Deploy / build-document-crawler (push) Successful in 13s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go (push) Successful in 39s
Build + Deploy / build-dsms-gateway (push) Successful in 15s
Build + Deploy / build-dsms-node (push) Successful in 14s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 15s
CI / nodejs-build (push) Successful in 2m26s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-python-backend (push) Successful in 39s
CI / test-python-document-crawler (push) Successful in 25s
CI / test-python-dsms-gateway (push) Successful in 22s
CI / validate-canonical-controls (push) Successful in 15s
Build + Deploy / trigger-orca (push) Successful in 2m28s
Build + Deploy / build-backend-compliance (push) Successful in 23s
Build + Deploy / build-ai-sdk (push) Successful in 13s
Build + Deploy / build-admin-compliance (push) Successful in 13s
Build + Deploy / build-developer-portal (push) Successful in 14s
Build + Deploy / build-tts (push) Successful in 15s
Build + Deploy / build-document-crawler (push) Successful in 13s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go (push) Successful in 39s
Build + Deploy / build-dsms-gateway (push) Successful in 15s
Build + Deploy / build-dsms-node (push) Successful in 14s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 15s
CI / nodejs-build (push) Successful in 2m26s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-python-backend (push) Successful in 39s
CI / test-python-document-crawler (push) Successful in 25s
CI / test-python-dsms-gateway (push) Successful in 22s
CI / validate-canonical-controls (push) Successful in 15s
Build + Deploy / trigger-orca (push) Successful in 2m28s
Root cause: Spiegel DSI text was truncated (lazy-loading) — the rights/DSB/complaints sections at the bottom were never extracted. Fixes: 1. Text extraction: scroll to bottom before innerText (dsi_discovery.py) 2. V.i.S.d.P.: add "verantwortlicher i.s.v." + "§18 Abs. N MStV" pattern 3. USt-IdNr: add "umsatzsteuer-id" + "DE 212 442 423" (with spaces) 4. Profiler: remove generic "anwalt"/"praxis" (false positive on Spiegel "Redaktionsanwalt"), keep only "rechtsanwalt", "kanzlei" etc. 5. Section splitter: auto_fill_from_dsi() fills empty Cookie/Social-Media rows from sections found in the DSI text Ground Truth 06-spiegel.md fully rewritten with verified data from live website — 3 L1 False Negatives identified (DSB, Beschwerderecht, Betroffenenrechte all present on website but not in extracted text). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -174,9 +174,14 @@ async def _run_compliance_check(check_id: str, req: ComplianceCheckRequest):
|
|||||||
"word_count": len(text.split()) if text else 0,
|
"word_count": len(text.split()) if text else 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Step 1b: If same URL used for multiple doc_types, try section splitting
|
# Step 1b: Section splitting — two cases:
|
||||||
from compliance.services.section_splitter import split_shared_texts
|
# 1. Same URL used for multiple doc_types → split by heading
|
||||||
|
# 2. DSI text contains Cookie/Social-Media sections → auto-fill empty rows
|
||||||
|
from compliance.services.section_splitter import (
|
||||||
|
split_shared_texts, auto_fill_from_dsi,
|
||||||
|
)
|
||||||
split_shared_texts(doc_entries, url_text_cache)
|
split_shared_texts(doc_entries, url_text_cache)
|
||||||
|
auto_fill_from_dsi(doc_entries)
|
||||||
# Refresh doc_texts after splitting
|
# Refresh doc_texts after splitting
|
||||||
for entry in doc_entries:
|
for entry in doc_entries:
|
||||||
if entry.get("text"):
|
if entry.get("text"):
|
||||||
|
|||||||
@@ -59,26 +59,34 @@ _NONPROFIT_KEYWORDS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
_REGULATED_PROFESSIONS = {
|
_REGULATED_PROFESSIONS = {
|
||||||
|
# Anwalt — nur spezifische Begriffe, nicht "anwalt" allein
|
||||||
|
# (matcht sonst Redaktionsanwalt, Justiziar etc.)
|
||||||
"rechtsanwalt": "anwalt",
|
"rechtsanwalt": "anwalt",
|
||||||
"anwalt": "anwalt",
|
"rechtsanwaeltin": "anwalt",
|
||||||
"anwaeltin": "anwalt",
|
"rechtsanwältin": "anwalt",
|
||||||
"anwältin": "anwalt",
|
|
||||||
"kanzlei": "anwalt",
|
"kanzlei": "anwalt",
|
||||||
"rechtsanwaltskammer": "anwalt",
|
"rechtsanwaltskammer": "anwalt",
|
||||||
"arzt": "arzt",
|
"zugelassener anwalt": "anwalt",
|
||||||
"ärztin": "arzt",
|
# Arzt — "praxis" entfernt (matcht "in der Praxis")
|
||||||
"aerztin": "arzt",
|
"arztpraxis": "arzt",
|
||||||
"praxis": "arzt",
|
"zahnarzt": "arzt",
|
||||||
|
"facharzt": "arzt",
|
||||||
"aerztekammer": "arzt",
|
"aerztekammer": "arzt",
|
||||||
"ärztekammer": "arzt",
|
"ärztekammer": "arzt",
|
||||||
|
"kassenärztlich": "arzt",
|
||||||
|
"kassenaerztlich": "arzt",
|
||||||
|
# Steuerberater
|
||||||
"steuerberater": "steuerberater",
|
"steuerberater": "steuerberater",
|
||||||
"steuerberaterin": "steuerberater",
|
"steuerberaterin": "steuerberater",
|
||||||
"steuerberaterkammer": "steuerberater",
|
"steuerberaterkammer": "steuerberater",
|
||||||
|
# Architekt
|
||||||
"architekt": "architekt",
|
"architekt": "architekt",
|
||||||
"architektin": "architekt",
|
"architektin": "architekt",
|
||||||
"architektenkammer": "architekt",
|
"architektenkammer": "architekt",
|
||||||
|
# Notar
|
||||||
"notar": "notar",
|
"notar": "notar",
|
||||||
"notariat": "notar",
|
"notariat": "notar",
|
||||||
|
# Apotheker
|
||||||
"apotheke": "apotheker",
|
"apotheke": "apotheker",
|
||||||
"apotheker": "apotheker",
|
"apotheker": "apotheker",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,8 +135,9 @@ IMPRESSUM_CHECKLIST = [
|
|||||||
"label": "USt-IdNr.",
|
"label": "USt-IdNr.",
|
||||||
"level": 1, "parent": None,
|
"level": 1, "parent": None,
|
||||||
"patterns": [
|
"patterns": [
|
||||||
r"ust.*id", r"umsatzsteuer.*identifikation",
|
r"ust[\s.-]*id", r"umsatzsteuer[\s-]*id",
|
||||||
r"vat.*id", r"de\s*\d{9}",
|
r"umsatzsteuer.*identifikation",
|
||||||
|
r"vat[\s.-]*id", r"de\s*\d{3}\s*\d{3}\s*\d{3}",
|
||||||
],
|
],
|
||||||
"severity": "MEDIUM",
|
"severity": "MEDIUM",
|
||||||
"hint": "§5(1) Nr.6 TMG: Die USt-IdNr. muss angegeben werden, sofern vorhanden. Die Steuernummer ist KEIN Ersatz.",
|
"hint": "§5(1) Nr.6 TMG: Die USt-IdNr. muss angegeben werden, sofern vorhanden. Die Steuernummer ist KEIN Ersatz.",
|
||||||
@@ -146,7 +147,7 @@ IMPRESSUM_CHECKLIST = [
|
|||||||
"label": "USt-IdNr. im Format DE + 9 Ziffern",
|
"label": "USt-IdNr. im Format DE + 9 Ziffern",
|
||||||
"level": 2, "parent": "vat",
|
"level": 2, "parent": "vat",
|
||||||
"patterns": [
|
"patterns": [
|
||||||
r"de\s*\d{9}",
|
r"de\s*\d{3}\s*\d{3}\s*\d{3}",
|
||||||
],
|
],
|
||||||
"severity": "LOW",
|
"severity": "LOW",
|
||||||
"hint": "Deutsche USt-IdNr.: 'DE' + exakt 9 Ziffern (z.B. DE123456789). Validierung: https://evatr.bff-online.de/",
|
"hint": "Deutsche USt-IdNr.: 'DE' + exakt 9 Ziffern (z.B. DE123456789). Validierung: https://evatr.bff-online.de/",
|
||||||
@@ -187,7 +188,8 @@ IMPRESSUM_CHECKLIST = [
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
r"v\.?\s*i\.?\s*s\.?\s*d\.?\s*p",
|
r"v\.?\s*i\.?\s*s\.?\s*d\.?\s*p",
|
||||||
r"(?:redaktionell|inhaltlich)\s+verantwortlich",
|
r"(?:redaktionell|inhaltlich)\s+verantwortlich",
|
||||||
r"§\s*18\s+m(?:edien)?st(?:aat)?v",
|
r"§\s*18\s+(?:abs\.?\s*\d+\s+)?m(?:edien)?st(?:aat)?v",
|
||||||
|
r"verantwortlich\w*\s+i\.?\s*s\.?\s*(?:d\.?\s*)?v\.?",
|
||||||
],
|
],
|
||||||
"severity": "INFO",
|
"severity": "INFO",
|
||||||
"hint": "Nur relevant wenn die Website journalistisch-redaktionelle Inhalte hat (Blog, Ratgeber, News, Fachartikel). Reine Unternehmensseiten ohne redaktionelle Inhalte benoetigen keinen V.i.S.d.P. Pruefen Sie, ob die Website einen Blog oder Ratgeber-Bereich hat.",
|
"hint": "Nur relevant wenn die Website journalistisch-redaktionelle Inhalte hat (Blog, Ratgeber, News, Fachartikel). Reine Unternehmensseiten ohne redaktionelle Inhalte benoetigen keinen V.i.S.d.P. Pruefen Sie, ob die Website einen Blog oder Ratgeber-Bereich hat.",
|
||||||
|
|||||||
@@ -168,3 +168,48 @@ def _find_section_for_type(sections: list[dict], doc_type: str) -> str | None:
|
|||||||
return section["text"]
|
return section["text"]
|
||||||
|
|
||||||
return None # No match → keep full text
|
return None # No match → keep full text
|
||||||
|
|
||||||
|
|
||||||
|
def auto_fill_from_dsi(doc_entries: list[dict]) -> None:
|
||||||
|
"""Auto-fill empty document rows from sections found in the DSI text.
|
||||||
|
|
||||||
|
If the user only entered the DSI URL but left Cookie/Social-Media empty,
|
||||||
|
and the DSI text contains those sections, auto-fill them.
|
||||||
|
"""
|
||||||
|
# Find the DSI entry
|
||||||
|
dsi_entry = None
|
||||||
|
for entry in doc_entries:
|
||||||
|
if entry["doc_type"] in ("dse", "datenschutz", "privacy") and entry.get("text"):
|
||||||
|
dsi_entry = entry
|
||||||
|
break
|
||||||
|
if not dsi_entry:
|
||||||
|
return
|
||||||
|
|
||||||
|
dsi_text = dsi_entry["text"]
|
||||||
|
if len(dsi_text) < 300:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Split DSI into sections
|
||||||
|
sections = _split_at_headings(dsi_text)
|
||||||
|
if not sections:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Find empty entries that could be filled from DSI sections
|
||||||
|
filled = []
|
||||||
|
for entry in doc_entries:
|
||||||
|
if entry.get("text") or entry.get("url"):
|
||||||
|
continue # Already has content
|
||||||
|
|
||||||
|
doc_type = entry["doc_type"]
|
||||||
|
section_text = _find_section_for_type(sections, doc_type)
|
||||||
|
if section_text and len(section_text.split()) >= 30:
|
||||||
|
entry["text"] = section_text
|
||||||
|
entry["word_count"] = len(section_text.split())
|
||||||
|
entry["url"] = f"{dsi_entry.get('url', '')} (Abschnitt)"
|
||||||
|
filled.append(doc_type)
|
||||||
|
|
||||||
|
if filled:
|
||||||
|
logger.info(
|
||||||
|
"Auto-filled %d empty rows from DSI sections: %s",
|
||||||
|
len(filled), ", ".join(filled),
|
||||||
|
)
|
||||||
|
|||||||
@@ -263,6 +263,12 @@ async def discover_dsi_documents(
|
|||||||
is_self_dsi, self_lang = _matches_dsi_keyword(page_title)
|
is_self_dsi, self_lang = _matches_dsi_keyword(page_title)
|
||||||
if is_self_dsi:
|
if is_self_dsi:
|
||||||
try:
|
try:
|
||||||
|
# Scroll to bottom to trigger lazy-loading of full content
|
||||||
|
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
|
||||||
|
await page.wait_for_timeout(1500)
|
||||||
|
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
|
||||||
|
await page.wait_for_timeout(1000)
|
||||||
|
|
||||||
self_text = await page.evaluate("""() => {
|
self_text = await page.evaluate("""() => {
|
||||||
const main = document.querySelector('main, article, [role="main"], .content, #content, .bodytext')
|
const main = document.querySelector('main, article, [role="main"], .content, #content, .bodytext')
|
||||||
|| document.body;
|
|| document.body;
|
||||||
|
|||||||
@@ -2,94 +2,128 @@
|
|||||||
|
|
||||||
**URL:** https://www.spiegel.de
|
**URL:** https://www.spiegel.de
|
||||||
**Typ:** Medien / Nachrichtenportal
|
**Typ:** Medien / Nachrichtenportal
|
||||||
**Datum:** 2026-05-12
|
**Datum:** 2026-05-13 (verifiziert gegen Live-Texte)
|
||||||
**Batch-Test:** 6/9 L1, 10/13 L2 (Mangelhaft, 77%)
|
**Vorheriger Batch-Test:** 6/9 L1, 10/13 L2 — VERALTET, mehrere False Negatives
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Business Profile (erwartet)
|
## Business Profile (erwartet)
|
||||||
|
|
||||||
| Feld | Erwarteter Wert |
|
| Feld | Erwarteter Wert | Begruendung |
|
||||||
|------|----------------|
|
|------|----------------|-------------|
|
||||||
| business_type | b2c |
|
| business_type | b2c | Abo-Modell (Spiegel+) |
|
||||||
| industry | media |
|
| industry | media | Nachrichtenportal |
|
||||||
| has_online_shop | true (Abo-Shop, Spiegel+) |
|
| has_online_shop | true | Spiegel+ Abo-Shop |
|
||||||
| has_editorial_content | true (Kerngeschaeft) |
|
| has_editorial_content | true | Kerngeschaeft |
|
||||||
| is_regulated_profession | false |
|
| is_regulated_profession | **false** | Kein regulierter Beruf. "Anwalt" im Text ist Redaktionsanwalt, kein Kanzlei-Beruf |
|
||||||
| needs_odr | true (B2C Online-Abo) |
|
| needs_odr | true | B2C mit Online-Abo |
|
||||||
|
|
||||||
|
**Bug:** Profiler erkennt "anwalt" im Impressum-Text und setzt is_regulated_profession=true. FALSE POSITIVE.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Dokumente
|
## Dokumente
|
||||||
|
|
||||||
| Dokumenttyp | Vorhanden | URL |
|
| Dokumenttyp | Vorhanden | URL | Anmerkung |
|
||||||
|-------------|-----------|-----|
|
|-------------|-----------|-----|-----------|
|
||||||
| DSI | Ja | https://www.spiegel.de/datenschutz |
|
| DSI | Ja | https://www.spiegel.de/datenschutz-spiegel | 6461 Woerter, 11 Abschnitte, sehr ausfuehrlich |
|
||||||
| Impressum | Ja | https://www.spiegel.de/impressum |
|
| Impressum | Ja | https://www.spiegel.de/impressum | 2 Gesellschaften (DER SPIEGEL GmbH + SPIEGEL-Verlag) |
|
||||||
| Cookie-Richtlinie | Ja (ggf. in DSI) | — |
|
| Cookie-Richtlinie | In DSI Abschnitt 4 | #funktionsfaehigkeitdesangebots | Sourcepoint CMP |
|
||||||
| AGB | Ja | https://www.spiegel.de/agb |
|
| AGB | Ja | https://www.spiegel.de/agb | Abo-Bedingungen |
|
||||||
| Widerruf | Ja (in AGB) | — |
|
| Nutzungsbedingungen | Ja | https://www.spiegel.de/nutzungsbedingungen | Separates Dokument |
|
||||||
| Social Media DSE | Nein | — |
|
| Widerruf | In AGB Abschnitt 10 | https://www.spiegel.de/agb | "Widerrufsrecht fuer Abonnements" |
|
||||||
| Nutzungsbedingungen | In AGB | — |
|
| Social Media DSE | In DSI Abschnitt 8 | #einbinden-von-drittinhalten | Facebook, YouTube, X, Instagram, TikTok, etc. |
|
||||||
| DSB-Kontakt | In DSI | — |
|
| DSB-Kontakt | In DSI | — | dsb@spiegelgruppe.de |
|
||||||
|
|
||||||
**Besonderheit:** Consent-Wall blockiert Zugang ohne Cookie-Zustimmung. Text-Extraktion kann scheitern.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Erwartete Ergebnisse: DSI (Art. 13 DSGVO)
|
## Erwartete Ergebnisse: DSI (Art. 13 DSGVO)
|
||||||
|
|
||||||
### L1 Checks (6/9)
|
### L1 Checks (ERWARTET: 9/9 PASS)
|
||||||
|
|
||||||
| Check | Erwartet | Begruendung |
|
| Check | Erwartet | Beleg | Unser Ergebnis | Bug? |
|
||||||
|-------|----------|-------------|
|
|-------|----------|-------|----------------|------|
|
||||||
| Verantwortlicher | PASS | SPIEGEL-Verlag |
|
| Verantwortlicher | PASS | "DER SPIEGEL GmbH & Co. KG, Ericusspitze 1, 20459 Hamburg" | PASS (3/3) | — |
|
||||||
| DSB | **FAIL** | **TP** — Kein DSB in der DSI erwaehnt |
|
| DSB | **PASS** | "z. Hd. der Datenschutzbeauftragten... dsb@spiegelgruppe.de" | **FAIL** | **FN — Regex matcht "Datenschutzbeauftragte" nicht ohne "r" am Ende oder erkennt Kontext nicht** |
|
||||||
| Zwecke | PASS | Aufgezaehlt |
|
| Zwecke | PASS | Adobe-Tracking, Vertragsbeziehungen, Drittinhalte etc. | PASS | — |
|
||||||
| Rechtsgrundlage | PASS | Art. 6 |
|
| Rechtsgrundlage | PASS | Art. 6(1)(a), (b), (f) explizit | PASS (3/4) | — |
|
||||||
| Empfaenger | PASS | Werbenetzwerke, Analytics |
|
| Empfaenger | PASS | Server-/Applikationsbetreiber, Auftragsverarbeiter | PASS (2/2) | — |
|
||||||
| Drittlandtransfer | PASS | USA-Transfer |
|
| Drittlandtransfer | PASS | SCC erwaehnt | PASS (1/1) | — |
|
||||||
| Speicherdauer | PASS | Angaben vorhanden |
|
| Speicherdauer | PASS | "30 Tage" Protokolldatei | PASS (1/2) | — |
|
||||||
| Betroffenenrechte | **FAIL** | **TP** — Rechte nicht explizit aufgezaehlt |
|
| Betroffenenrechte | **PASS** | Art. 15, 16, 17, 18, 21 explizit. Art. 20 fehlt. | **FAIL** | **FN — Regex verlangt alle 6 Artikel, 5/6 genuegen nicht** |
|
||||||
| Beschwerderecht | **FAIL** | **TP** — Art. 77 fehlt |
|
| Beschwerderecht | **PASS** | "Art. 77 DSGVO... HmbBfDI... Ludwig-Ehrhard-Str. 22" | **FAIL** | **FN — Regex findet Art. 77 + HmbBfDI nicht** |
|
||||||
|
|
||||||
|
**3 False Negatives in L1!** DSB, Betroffenenrechte, Beschwerderecht sind alle vorhanden.
|
||||||
|
|
||||||
### L2 Checks (Stichproben)
|
### L2 Checks (Stichproben)
|
||||||
|
|
||||||
| Check | Erwartet | TP/FP |
|
| Check | Erwartet | Beleg | Unser Ergebnis | Bug? |
|
||||||
|-------|----------|-------|
|
|-------|----------|-------|----------------|------|
|
||||||
| E-Mail | PASS | — |
|
| E-Mail | PASS | datenschutz@spiegelgruppe.de | PASS | — |
|
||||||
| Interessenabwaegung | **FAIL** | **TP** |
|
| Interessenabwaegung | FAIL (TP) | Interesse benannt, keine Abwaegung | FAIL | Korrekt |
|
||||||
| Art. 22 Profiling | **FAIL** | **TP** — Personalisierte Werbung ohne Profiling-Hinweis |
|
| Art. 20 Portabilitaet | FAIL (TP) | Art. 20 fehlt im Rechte-Abschnitt | — | Korrekter Finding |
|
||||||
| Aufsichtsbehoerde | **FAIL** | **TP** |
|
| Loeschkonzept | FAIL (TP) | Kein formales Loeschkonzept | FAIL | Korrekt |
|
||||||
|
|
||||||
**Verifiziert: Spiegel DSI ist fuer ein grosses Medienunternehmen erstaunlich unvollstaendig.**
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Erwartete Ergebnisse: Impressum
|
## Erwartete Ergebnisse: Impressum (§5 TMG)
|
||||||
|
|
||||||
| Check | Erwartet | Begruendung |
|
| Check | Erwartet | Beleg | Unser Ergebnis | Bug? |
|
||||||
|-------|----------|-------------|
|
|-------|----------|-------|----------------|------|
|
||||||
| Firmenname | PASS | SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG |
|
| Firmenname | PASS | DER SPIEGEL GmbH & Co. KG + SPIEGEL-Verlag | PASS | — |
|
||||||
| Anschrift | PASS | Ericusspitze 1, 20457 Hamburg |
|
| Anschrift | PASS | Ericusspitze 1, 20457 Hamburg | PASS | — |
|
||||||
| Vertretung | PASS | Geschaeftsfuehrer |
|
| Kontakt | PASS | Tel. 040 3007-0, spiegel@spiegel.de | PASS | — |
|
||||||
| V.i.S.d.P. | PASS | Pflicht bei Medienunternehmen, sollte vorhanden sein |
|
| Register | PASS | HRA 123 261 + HRA 61 755 | PASS | — |
|
||||||
| Registergericht | PASS | AG Hamburg |
|
| USt-IdNr | **PASS** | DE 212 442 423 + DE 118 922 410 | **FAIL** | **FN — Regex findet "Umsatzsteuer-ID:" Format nicht** |
|
||||||
| USt-IdNr | PASS | Vorhanden |
|
| Vertretung | PASS | Thomas Hass (Geschaeftsfuehrung) | PASS (1/1) | — |
|
||||||
| Streitbeilegung | AKTIV | B2C mit Online-Abo |
|
| V.i.S.d.P. | **PASS** | "Verantwortlicher i. S. v. § 18 Abs. 2 MStV: Dirk Kurbjuweit" | **FAIL** | **FN — Regex sucht "v.i.s.d.p." nicht "verantwortlicher i.s.v."** |
|
||||||
|
| Streitbeilegung | PASS | ODR-Link vorhanden (in AGB) | PASS | — |
|
||||||
|
| Berufsrecht | **SKIP** | Spiegel ist kein regulierter Beruf | **AKTIV (1/3)** | **FP — Profiler "anwalt" Bug** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Erwartete Ergebnisse: AGB
|
## Erwartete Ergebnisse: AGB
|
||||||
|
|
||||||
| Check | Erwartet |
|
| Check | Erwartet | Beleg |
|
||||||
|-------|----------|
|
|-------|----------|-------|
|
||||||
| Geltungsbereich | PASS |
|
| Geltungsbereich | PASS | Abschnitt 1 |
|
||||||
| Vertragsschluss | PASS |
|
| Vertragsschluss | PASS | Abschnitt 2 |
|
||||||
| Preise | PASS (Abo-Preise) |
|
| Preise/Zahlung | PASS | Abschnitte 4-7 |
|
||||||
| Kuendigungsrecht | PASS |
|
| Kuendigung | PASS | Abschnitt 8 (1 Monat Frist) |
|
||||||
| Widerrufsrecht | PASS (14 Tage) |
|
| Widerrufsrecht | PASS | Abschnitt 10 (14 Tage, Muster-Formular) |
|
||||||
| Haftungsbeschraenkung | PASS |
|
| §312k Button | Zu pruefen | Kuendigungsbutton Pflicht seit 01.07.2022 |
|
||||||
|
| ODR-Link | PASS | http://ec.europa.eu/consumers/odr/ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Erwartete Ergebnisse: Widerrufsbelehrung (AGB §10)
|
||||||
|
|
||||||
|
| Check | Erwartet | Beleg |
|
||||||
|
|-------|----------|-------|
|
||||||
|
| Belehrung | PASS | "Sie haben das Recht, Abonnementvertraege binnen 14 Tagen ohne Angabe von Gruenden zu widerrufen" |
|
||||||
|
| 14-Tage-Frist | PASS | Explizit genannt |
|
||||||
|
| Form | PASS | Brief, E-Mail, Fax |
|
||||||
|
| Muster-Formular | PASS | "beigefuegte Muster-Widerrufsformular" erwaehnt |
|
||||||
|
| Folgen | PASS | Rueckerstattungsregeln beschrieben |
|
||||||
|
| Empfaenger | PASS | DER SPIEGEL Abonnentenservice, 20637 Hamburg; aboservice@spiegel.de |
|
||||||
|
| Ausnahme digitale Inhalte | PASS | "Fuer sofort nutzbare Zeitzugaenge... kein Widerrufsrecht" |
|
||||||
|
|
||||||
|
**Problem:** Unser Check prueft den DSI-Volltext gegen Widerruf-Checklist statt die AGB. Der Widerruf steht in den AGB (§10), nicht in der DSI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Erwartete Ergebnisse: Social Media (DSI Abschnitt 8)
|
||||||
|
|
||||||
|
| Check | Erwartet | Beleg |
|
||||||
|
|-------|----------|-------|
|
||||||
|
| Gemeinsam Verantwortliche | PASS | Erwaehnt |
|
||||||
|
| Meta konkret benannt | FAIL (TP) | Nur "Facebook" ohne "Meta Platforms Ireland Ltd." |
|
||||||
|
| Vereinbarung Art. 26 | FAIL (TP) | Kein Page Controller Addendum |
|
||||||
|
| Plattformen | PASS | Facebook, YouTube, X, Instagram, TikTok, Vimeo, Reddit, Bluesky, etc. |
|
||||||
|
| SCC | PASS | Erwaehnt |
|
||||||
|
| DPF | FAIL (TP) | Data Privacy Framework nicht erwaehnt |
|
||||||
|
| Rechtsgrundlage | PASS | Art. 6(1)(f) |
|
||||||
|
| Alle standardmaessig deaktiviert | PASS | "standardmaessig deaktiviert" |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -98,17 +132,19 @@
|
|||||||
| Feld | Erwartet |
|
| Feld | Erwartet |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| banner_detected | true |
|
| banner_detected | true |
|
||||||
| provider | Sourcepoint oder TCF-basiert |
|
| provider | Sourcepoint |
|
||||||
| violations | Mehrere (viel Third-Party-Tracking) |
|
| tcf_enabled | true |
|
||||||
|
| Vendor-Anzahl | 40+ (grosses Medienunternehmen) |
|
||||||
|
| violations | Consent-Wall blockiert Zugang → moeglicherweise unzulaessig |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Cross-Check Banner vs Cookie
|
## Cross-Check Banner vs DSI
|
||||||
|
|
||||||
| Finding | Erwartet |
|
| Finding | Erwartet |
|
||||||
|---------|----------|
|
|---------|----------|
|
||||||
| Dienste fehlen in Cookie-RL | Wahrscheinlich (viele Werbenetzwerke) |
|
| Vendors fehlen in DSI | Wahrscheinlich — viele TCF-Vendors nicht in DSI dokumentiert |
|
||||||
| Tracking vor Consent | Moeglich |
|
| Tracking vor Consent | Unwahrscheinlich (Sourcepoint blockiert gut) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -119,3 +155,17 @@
|
|||||||
| ODR | AKTIV | B2C Online-Abo |
|
| ODR | AKTIV | B2C Online-Abo |
|
||||||
| Widerruf | AKTIV | B2C |
|
| Widerruf | AKTIV | B2C |
|
||||||
| V.i.S.d.P. | AKTIV | Medienunternehmen (Kernpflicht) |
|
| V.i.S.d.P. | AKTIV | Medienunternehmen (Kernpflicht) |
|
||||||
|
| Berufsrecht | **SKIP** | Kein regulierter Beruf |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Identifizierte Regex-Bugs (aus diesem GT-Abgleich)
|
||||||
|
|
||||||
|
| # | Check | Bug | Beleg auf Website | Regex-Problem |
|
||||||
|
|---|-------|-----|-------------------|---------------|
|
||||||
|
| 1 | DSB | FN | "z. Hd. der Datenschutzbeauftragten... dsb@spiegelgruppe.de" | Regex matcht "Datenschutzbeauftragten" (Genitiv/Dativ) nicht |
|
||||||
|
| 2 | Beschwerderecht | FN | "Art. 77 DSGVO... HmbBfDI" | Regex findet "Art. 77" oder "Aufsichtsbehoerde" nicht im Spiegel-Text |
|
||||||
|
| 3 | Betroffenenrechte | FN | Art. 15, 16, 17, 18, 21 — nur Art. 20 fehlt | Regex verlangt ALLE 6, 5/6 ist nicht genug |
|
||||||
|
| 4 | V.i.S.d.P. | FN | "Verantwortlicher i. S. v. § 18 Abs. 2 MStV" | Regex sucht nur "v.i.s.d.p.", nicht die MStV-Formulierung |
|
||||||
|
| 5 | USt-IdNr | FN | "Umsatzsteuer-ID: DE 212 442 423" | Regex sucht "ust-idnr" oder "ust-id", matcht "umsatzsteuer-id:" nicht |
|
||||||
|
| 6 | Profiler "anwalt" | FP | Redaktionsanwalt im Impressum | "anwalt" zu generisch, matcht Personennamen/Rollen |
|
||||||
|
|||||||
Reference in New Issue
Block a user