recht: Meldeverfahren v2 Phasen 5+7 — DSGVO-Strukturformular, 10-€-Checkout mit KI-Vorprüfung, Triage & Panel-Modal
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled

Phase 7 (Spur D, E2 revidiert): KI-Vorprüfung VOR der Zahlung im Modal —
rot lehnt ohne Zahlung ab, gelb/grün führt zum Stripe-Checkout
(SinglePurchaseType::Change, 10 € netto), nach Zahlungseingang übernimmt
der Webhook die geprüfte Fassung sofort (applyPaid: Snapshot, Sperre,
Verlauf). Nur einmal je PM; Obergrenze legal.change_max_distance_percent
(50 %) verhindert die verdeckte Selbst-Depublizierung.

Phase 5 (Spur B): strukturiertes Schwärzungsformular mit Pflicht-Vorschau
im verifizierten Web-Bereich UND als Modal im Kunden-Panel; Admin-Editor
wird aus payload.redaction vorbefüllt. Umsetzungsmail LegalRequestExecuted
an Antragsteller, Bestätigungsmail PressReleaseChangeApplied (Spur A/D,
neuer abbestellbarer Typ press_release_corrected).

Außerdem:
- Re-Sync-Sperre + Sitemap-Invalidierung fest in depublish() verankert
  (Lücke im bezahlten Webhook-Pfad geschlossen)
- Öffentliche „Rechtliches"-Seite als zweistufige Triage: primär der
  Portal-Anmeldelink, Formular nur Fallback mit Identifizierungs-Hinweis;
  Store auf report/dsgvo/personal_rights gehärtet
- Panel-Button „Ändern/Melden" öffnet Anliegen-Modal (4 Spuren) statt
  des Web-Formulars
- Pressekontakt-Fallback für Legacy-Bestände (30k PMs ohne Verknüpfung):
  Detailseite + pressContactEmail() nutzen PM-Kontakt → Firmen-Kontakt →
  Firmendaten
- Korrektur-Gate entity-fest (Editor-Normalisierung zählt nicht als
  Änderung), toEditorHtml() in Admin-Edit + Korrektur-Panel,
  Wochenlimit-Hinweis in Text und Bremsen-Meldung

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-23 13:02:57 +00:00
parent 04b49c567d
commit e6eca9c85f
40 changed files with 2507 additions and 169 deletions

View file

@ -17,6 +17,7 @@ enum EmailNotificationType: string
case PressReleasePublished = 'press_release_published';
case PressReleaseRejected = 'press_release_rejected';
case PressReleaseDepublished = 'press_release_depublished';
case PressReleaseCorrected = 'press_release_corrected';
case Newsletter = 'newsletter';
public function label(): string
@ -25,6 +26,7 @@ enum EmailNotificationType: string
self::PressReleasePublished => 'Pressemitteilung veröffentlicht',
self::PressReleaseRejected => 'Pressemitteilung abgelehnt',
self::PressReleaseDepublished => 'Pressemitteilung depubliziert',
self::PressReleaseCorrected => 'Pressemitteilung korrigiert/geändert',
self::Newsletter => 'Newsletter & Plattform-Infos',
};
}
@ -38,6 +40,7 @@ enum EmailNotificationType: string
self::PressReleasePublished => 'Benachrichtigung, sobald eine von Ihnen eingereichte Pressemitteilung geprüft und veröffentlicht wurde.',
self::PressReleaseRejected => 'Benachrichtigung, wenn eine eingereichte Pressemitteilung abgelehnt wurde — inklusive Ablehnungsgrund.',
self::PressReleaseDepublished => 'Bestätigung, wenn eine beauftragte Depublikation durchgeführt wurde.',
self::PressReleaseCorrected => 'Bestätigung, wenn eine Korrektur oder kostenpflichtige Änderung an einer veröffentlichten Pressemitteilung übernommen wurde.',
self::Newsletter => 'Gelegentliche Informationen zur Plattform: Neuigkeiten, neue Funktionen und wichtige Hinweise zu Ihrem Konto.',
};
}
@ -51,6 +54,7 @@ enum EmailNotificationType: string
self::PressReleasePublished => 'Sie wurden als Pressekontakt hinterlegt und werden daher über die Veröffentlichung Ihrer Pressemitteilungen informiert.',
self::PressReleaseRejected => 'Sie wurden als Pressekontakt hinterlegt und werden daher über die Ablehnung Ihrer eingereichten Pressemitteilungen informiert.',
self::PressReleaseDepublished => 'Sie haben die Depublikation dieser Pressemitteilung beauftragt und erhalten daher diese Bestätigung.',
self::PressReleaseCorrected => 'Sie haben die Korrektur bzw. Änderung dieser Pressemitteilung beauftragt und erhalten daher diese Bestätigung.',
self::Newsletter => 'Sie haben ein Benutzerkonto bei pressekonto bzw. den Portalen presseecho und businessportal24 und erhalten daher gelegentlich Informationen zur Plattform.',
};
}
@ -64,6 +68,7 @@ enum EmailNotificationType: string
self::PressReleasePublished => 'Benachrichtigungen über das Veröffentlichen Ihrer Pressemitteilungen',
self::PressReleaseRejected => 'Benachrichtigungen über die Ablehnung Ihrer Pressemitteilungen',
self::PressReleaseDepublished => 'Bestätigungen über die Depublikation Ihrer Pressemitteilungen',
self::PressReleaseCorrected => 'Bestätigungen über Korrekturen und Änderungen Ihrer Pressemitteilungen',
self::Newsletter => 'Newsletter und Plattform-Informationen',
};
}

View file

@ -9,6 +9,7 @@ enum SinglePurchaseType: string
case Boost = 'boost';
case ProofPdf = 'proof_pdf';
case Depublication = 'depublication';
case Change = 'press_release_change';
public function label(): string
{
@ -18,6 +19,7 @@ enum SinglePurchaseType: string
self::Boost => 'Boost / Platzierung',
self::ProofPdf => 'Veröffentlichungsnachweis (PDF)',
self::Depublication => 'Depublikation (Entfernung aus der öffentlichen Ansicht)',
self::Change => 'Änderung einer veröffentlichten Pressemitteilung',
};
}
@ -34,6 +36,7 @@ enum SinglePurchaseType: string
self::Boost => 'Boost',
self::ProofPdf => 'Veröffentlichungsnachweis',
self::Depublication => 'Depublikation',
self::Change => 'Änderung',
};
}