0c25832b5c
3 Regex fixes: - Telefon: matches '0761 / 48 98 09 01' format (spaces around /) - Registergericht: matches 'AG Freiburg' (not just 'Amtsgericht') - Vertretung: matches 'Geschaeftsfuehrung:' (not just 'Geschaeftsfuehrer:') 6 checks changed from FAIL to INFO severity: - V.i.S.d.P.: only relevant if website has editorial content - Streitbeilegung: only relevant for B2C online shops - Berufsrecht: only relevant for regulated professions - Stammkapital: legally required but rarely enforced - Aufsichtsbehoerde: only for licensed activities - Berufshaftpflicht: only for mandatory insurance INFO checks don't count towards completeness percentage. They appear as hints, not findings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
311 lines
14 KiB
Python
311 lines
14 KiB
Python
"""
|
|
Impressum checks — §5 TMG / §18 MStV.
|
|
|
|
Level 1: Pflichtangabe erwaehnt?
|
|
Level 2: Pflichtangabe korrekt/vollstaendig?
|
|
|
|
Checks mit severity "INFO" sind kontextabhaengig — sie werden nur
|
|
als Hinweis angezeigt, nicht als Finding gewertet. Der Pruefer muss
|
|
selbst entscheiden ob sie fuer das geprueefte Unternehmen relevant sind.
|
|
"""
|
|
|
|
IMPRESSUM_CHECKLIST = [
|
|
# ── L1: Name des Anbieters ────────────────────────────────────────
|
|
{
|
|
"id": "name",
|
|
"label": "Name des Anbieters",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"(?:gmbh|ag|e\.v\.|ohg|kg|gbr|ug|mbh|inc|ltd)",
|
|
r"firma", r"unternehmen",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "§5(1) Nr.1 TMG: Vollstaendiger Firmenname MIT Rechtsform (z.B. 'Muster GmbH', nicht nur 'Muster'). Bei Einzelunternehmen: Vor- und Nachname plus ggf. Geschaeftsbezeichnung. Haeufiger Abmahngrund: Nur Markenname ohne juristische Person.",
|
|
},
|
|
|
|
# ── L1: Anschrift ─────────────────────────────────────────────────
|
|
{
|
|
"id": "address",
|
|
"label": "Anschrift",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"(?:str(?:asse|\.)|weg|platz|allee)\s*\.?\s*\d",
|
|
r"d-\d{5}", r"\d{5}\s+\w+",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "§5(1) Nr.1 TMG verlangt eine ladungsfaehige Anschrift fuer Klagezustellungen. Postfach, c/o-Adresse oder nur Ortsangabe genuegen laut BGH (I ZR 228/03) nicht. Erforderlich: Strasse + Hausnummer + PLZ + Ort.",
|
|
},
|
|
{
|
|
"id": "address_zip_city",
|
|
"label": "PLZ + Ort vorhanden",
|
|
"level": 2, "parent": "address",
|
|
"patterns": [
|
|
r"(?:d[\-\s]?)?\d{5}\s+[a-z\u00c0-\u017e]\w{2,}",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Ohne PLZ und Ort ist die Anschrift nicht ladungsfaehig und damit unvollstaendig i.S.d. §5 TMG.",
|
|
},
|
|
{
|
|
"id": "address_street_number",
|
|
"label": "Strasse + Hausnummer vorhanden",
|
|
"level": 2, "parent": "address",
|
|
"patterns": [
|
|
r"[a-z\u00c0-\u017e]\w+(?:str|stra(?:ss|ß)e|weg|platz|allee|gasse|ring|damm|ufer)\s*\.?\s*\d+",
|
|
r"\w+\s+(?:str|stra(?:ss|ß)e|weg|platz|allee)\s*\.?\s*\d+",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Strasse + Hausnummer fehlen oder sind unvollstaendig. Ohne Hausnummer keine Zustellbarkeit — klassischer Abmahngrund.",
|
|
},
|
|
|
|
# ── L1: Kontaktdaten ──────────────────────────────────────────────
|
|
{
|
|
"id": "contact",
|
|
"label": "Kontaktdaten (E-Mail + Telefon)",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"(?:e-?mail|mail).*@", r"telefon|phone|tel\.",
|
|
r"\+?\d[\d\s/\-\(\)]{8,}",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "§5(1) Nr.2 TMG verlangt Angaben fuer 'schnelle elektronische Kontaktaufnahme und unmittelbare Kommunikation': E-Mail ist Pflicht. EuGH (C-298/17): Telefon nicht zwingend, aber ein zweiter unmittelbarer Kanal (Telefon, Fax oder Chat) ist erforderlich.",
|
|
},
|
|
{
|
|
"id": "contact_email_format",
|
|
"label": "E-Mail-Adresse im korrekten Format",
|
|
"level": 2, "parent": "contact",
|
|
"patterns": [
|
|
r"[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "E-Mail-Adresse muss direkt im Impressum als Text sichtbar sein. Ein reines Kontaktformular genuegt laut OLG Hamm (4 U 59/20) NICHT.",
|
|
},
|
|
{
|
|
"id": "contact_phone_format",
|
|
"label": "Telefonnummer vorhanden",
|
|
"level": 2, "parent": "contact",
|
|
"patterns": [
|
|
r"(?:tel(?:efon)?|phone|fon)\s*[.:]\s*[\+\d][\d\s/\-\(\)]{6,}",
|
|
r"\+49\s*[\d\s/\-\(\)]{8,}",
|
|
r"0\d{2,4}\s*[/\-\s]\s*[\d\s\-]{4,}",
|
|
r"(?:telefon|tel\.?|phone|fon)\s+\d[\d\s/\-]{6,}",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Telefonnummer mit Vorwahl angeben (z.B. '+49 30 12345678' oder '0761 / 489 809 01'). Falls kein Telefon: Ein alternativer unmittelbarer Kommunikationskanal ist laut EuGH (C-298/17) noetig.",
|
|
},
|
|
|
|
# ── L1: Handelsregister ───────────────────────────────────────────
|
|
{
|
|
"id": "register",
|
|
"label": "Handelsregister / Registernummer",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"(?:handelsregister|hrb|hra|registergericht|amtsgericht)",
|
|
r"register.*(?:nr|nummer)",
|
|
r"\bag\s+[a-z\u00c0-\u017e]\w+",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "§5(1) Nr.4 TMG: Bei Eintragung im Handels-, Vereins-, Partnerschafts- oder Genossenschaftsregister muessen Registergericht UND Registernummer angegeben werden.",
|
|
},
|
|
{
|
|
"id": "register_court",
|
|
"label": "Registergericht benannt (Amtsgericht X)",
|
|
"level": 2, "parent": "register",
|
|
"patterns": [
|
|
r"(?:amtsgericht|registergericht)\s+[A-Z\u00c0-\u017e]\w+",
|
|
r"\bag\s+[A-Z\u00c0-\u017e]\w+",
|
|
r"(?:handelsregister|register)\s+(?:ag|amtsgericht)\s+\w+",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Registergericht benennen (z.B. 'Amtsgericht Freiburg' oder 'AG Freiburg'). Beides ist korrekt.",
|
|
},
|
|
{
|
|
"id": "register_number",
|
|
"label": "Registernummer (HRB/HRA + Nummer)",
|
|
"level": 2, "parent": "register",
|
|
"patterns": [
|
|
r"(?:hrb|hra)\s*\d+",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Registernummer im Format 'HRB 12345' (Kapitalgesellschaften) oder 'HRA 12345' (Personengesellschaften) angeben.",
|
|
},
|
|
|
|
# ── L1: USt-IdNr ──────────────────────────────────────────────────
|
|
{
|
|
"id": "vat",
|
|
"label": "USt-IdNr.",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"ust.*id", r"umsatzsteuer.*identifikation",
|
|
r"vat.*id", r"de\s*\d{9}",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "§5(1) Nr.6 TMG: Die USt-IdNr. muss angegeben werden, sofern vorhanden. Die Steuernummer ist KEIN Ersatz.",
|
|
},
|
|
{
|
|
"id": "vat_de_format",
|
|
"label": "USt-IdNr. im Format DE + 9 Ziffern",
|
|
"level": 2, "parent": "vat",
|
|
"patterns": [
|
|
r"de\s*\d{9}",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Deutsche USt-IdNr.: 'DE' + exakt 9 Ziffern (z.B. DE123456789). Validierung: https://evatr.bff-online.de/",
|
|
},
|
|
|
|
# ── L1: Vertretungsberechtigte ────────────────────────────────────
|
|
{
|
|
"id": "representative",
|
|
"label": "Vertretungsberechtigte",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"vertretungsberechtigt",
|
|
r"gesch(?:ae|ä)ftsf(?:ue|ü)hr",
|
|
r"vorstand", r"inhaber",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "§5(1) Nr.1 TMG: Bei juristischen Personen muss der/die Vertretungsberechtigte(n) namentlich benannt werden.",
|
|
},
|
|
{
|
|
"id": "representative_person",
|
|
"label": "Name der vertretungsberechtigten Person",
|
|
"level": 2, "parent": "representative",
|
|
"patterns": [
|
|
r"(?:gesch(?:ae|ä)ftsf(?:ue|ü)hr\w*|vorstand|inhaber)\s*:?\s*[A-Z\u00c0-\u017e]",
|
|
r"(?:vertreten\s+durch|repr(?:ae|ä)sentiert)\s*:?\s*[A-Z\u00c0-\u017e]",
|
|
r"(?:gesch(?:ae|ä)ftsf(?:ue|ü)hrung)\s*:?\s*(?:dr\.?\s+|prof\.?\s+)?[A-Z\u00c0-\u017e]",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Voller Vor- und Nachname mit Funktionsbezeichnung erforderlich (z.B. 'Geschaeftsfuehrung: Dr. Max Mustermann').",
|
|
},
|
|
|
|
# ── Kontextabhaengige Checks (INFO — nur Hinweis, kein Finding) ──
|
|
|
|
{
|
|
"id": "editorial_visdp",
|
|
"label": "V.i.S.d.P. / Redaktionell Verantwortlicher (§18 MStV)",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"v\.?\s*i\.?\s*s\.?\s*d\.?\s*p",
|
|
r"(?:redaktionell|inhaltlich)\s+verantwortlich",
|
|
r"§\s*18\s+m(?:edien)?st(?:aat)?v",
|
|
],
|
|
"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.",
|
|
},
|
|
|
|
{
|
|
"id": "dispute_resolution",
|
|
"label": "Verbraucherstreitbeilegung / OS-Plattform",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"verbraucherstreitbeilegung|streitschlichtung",
|
|
r"(?:os|odr)[\-\s]plattform",
|
|
r"ec\.europa\.eu.*odr",
|
|
r"vsbg|verbraucherstreitbeilegungsgesetz",
|
|
r"alternative\s+streitbeilegung",
|
|
],
|
|
"severity": "INFO",
|
|
"hint": "Nur relevant fuer B2C-Online-Haendler die Waren oder Dienstleistungen an Verbraucher verkaufen. B2B-Unternehmen ohne Verbrauchergeschaeft sind von §36 VSBG und der ODR-Verordnung nicht betroffen. Pruefen Sie, ob das Unternehmen B2C-Geschaeft betreibt.",
|
|
},
|
|
|
|
{
|
|
"id": "regulated_profession",
|
|
"label": "Berufsrechtliche Angaben (§5(1) Nr.5 TMG)",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"(?:rechtsanwalt|anwalt|notar|steuerberater|wirtschaftspr(?:ue|ü)fer|arzt|(?:ae|ä)rzt|zahnarzt|apotheker|architekt|ingenieur|psychotherapeut|heilpraktiker)",
|
|
r"(?:kammer|berufsordnung|berufsrecht|standesrecht|zulassung)",
|
|
r"(?:(?:ae|ä)rztekammer|rechtsanwaltskammer|steuerberaterkammer|architektenkammer|ingenieurkammer)",
|
|
],
|
|
"severity": "INFO",
|
|
"hint": "Nur relevant fuer reglementierte Berufe (Aerzte, Anwaelte, Steuerberater, Architekten, Apotheker). Falls das Unternehmen keinen reglementierten Beruf ausueebt, ist dieser Punkt nicht zutreffend.",
|
|
},
|
|
{
|
|
"id": "profession_chamber",
|
|
"label": "Zustaendige Kammer benannt",
|
|
"level": 2, "parent": "regulated_profession",
|
|
"patterns": [
|
|
r"(?:(?:ae|ä)rztekammer|rechtsanwaltskammer|steuerberaterkammer|architektenkammer|ingenieurkammer|apothekerkammer)",
|
|
r"(?:mitglied|zugelassen|eingetragen)\s+(?:bei|in|der)\s+(?:der\s+)?(?:\w+)?kammer",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Zustaendige Kammer mit vollem Namen und Sitz nennen (z.B. 'Rechtsanwaltskammer Muenchen').",
|
|
},
|
|
{
|
|
"id": "profession_title",
|
|
"label": "Berufsbezeichnung + Verleihungsstaat",
|
|
"level": 2, "parent": "regulated_profession",
|
|
"patterns": [
|
|
r"berufsbezeichnung|gesetzliche\s+berufsbezeichnung",
|
|
r"verliehen\s+in|verleihungsstaat",
|
|
r"(?:rechtsanwalt|steuerberater|arzt|architekt)\s*(?:\(|,)\s*(?:deutschland|bundesrepublik)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Berufsbezeichnung und Staat der Verleihung angeben.",
|
|
},
|
|
{
|
|
"id": "profession_regulations",
|
|
"label": "Berufsrechtliche Regelungen + Zugang",
|
|
"level": 2, "parent": "regulated_profession",
|
|
"patterns": [
|
|
r"(?:berufsordnung|brao|bora|steuerberatungsgesetz|stberg|bundes(?:ae|ä)rzteordnung|heilberufe|mbo|architekteng)",
|
|
r"berufsrecht|standesrecht|berufsrechtliche\s+regelung",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Berufsrechtliche Regelungen nennen und Link zum Volltext bereitstellen.",
|
|
},
|
|
|
|
{
|
|
"id": "share_capital",
|
|
"label": "Stammkapital / Grundkapital (GmbH/AG/UG)",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"stammkapital|grundkapital|haftkapital",
|
|
r"(?:kapital|einlage)\s*:?\s*(?:eur|euro|\u20ac)\s*[\d\.,]+",
|
|
r"[\d\.,]+\s*(?:eur|euro|\u20ac)\s*(?:stammkapital|grundkapital)",
|
|
],
|
|
"severity": "INFO",
|
|
"hint": "§35a GmbHG verlangt die Angabe des Stammkapitals auf Geschaeftsbriefen. Ob dies auch fuer Websites gilt, ist umstritten. In der Praxis wird es selten beanstandet. Bei UG (haftungsbeschraenkt) ist die Angabe empfehlenswert, da das geringe Stammkapital fuer Geschaeftspartner relevant ist.",
|
|
},
|
|
|
|
{
|
|
"id": "supervisory_authority",
|
|
"label": "Aufsichtsbehoerde (genehmigungspflichtige Taetigkeiten)",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"aufsichtsbeh(?:oe|ö)rde|genehmigungsbeh(?:oe|ö)rde|zulassungsbeh(?:oe|ö)rde",
|
|
r"gewerbeaufsicht|gewerbeamt|ordnungsamt",
|
|
r"(?:zugelassen|genehmigt|erlaubt)\s+(?:durch|von)\s+(?:der|dem|die)",
|
|
r"bafin|§\s*34[cdf]\s+gewo",
|
|
],
|
|
"severity": "INFO",
|
|
"hint": "Nur relevant bei genehmigungspflichtigen Taetigkeiten: Immobilienmakler (§34c GewO), Finanzanlagenvermittler (§34f), Versicherungsvermittler (§34d), Gastronomie, Bewachungsgewerbe. Falls das Unternehmen keine solche Taetigkeit ausueebt, ist dieser Punkt nicht zutreffend.",
|
|
},
|
|
|
|
{
|
|
"id": "professional_insurance",
|
|
"label": "Berufshaftpflichtversicherung (DL-InfoV §2(1) Nr.11)",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"berufshaftpflicht|haftpflichtversicherung|pflichtversicherung",
|
|
r"(?:versicherer|versicherung)\s*:?\s*[A-Z\u00c0-\u017e]",
|
|
r"deckungssumme|versicherungsschutz|geltungsbereich",
|
|
],
|
|
"severity": "INFO",
|
|
"hint": "Nur relevant bei gesetzlicher Pflichtversicherung (Aerzte, Anwaelte, Architekten, Steuerberater, Makler). Falls das Unternehmen keine Pflichtversicherung benoetigt, ist dieser Punkt nicht zutreffend.",
|
|
},
|
|
|
|
{
|
|
"id": "illegal_disclaimer",
|
|
"label": "Rechtswidriger Haftungsausschluss fuer Links",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"haftungsausschluss|disclaimer|haftung\s+f(?:ue|ü)r\s+(?:links|inhalte)",
|
|
r"keine\s+(?:gew(?:ae|ä)hr|haftung|verantwortung)\s+f(?:ue|ü)r\s+(?:externe|verlinkte|fremde)",
|
|
r"distanzier|macht\s+sich\s+(?:nicht|kein)\s+(?:zu\s+eigen|verantwortlich)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Der klassische Link-Disclaimer ('Wir distanzieren uns von verlinkten Inhalten') ist seit BGH (I ZR 317/01) rechtlich wirkungslos. Empfehlung: Entfernen Sie pauschale Disclaimer — sie schuetzen nicht und koennen kontraproduktiv sein.",
|
|
},
|
|
]
|