web: Transparenzseiten — was kostet, ohne Abo, loeschen/aendern (Roadmap 2.4)

Drei Seiten mit unterschiedlicher Suchintention, DE/EN, Hub + Spokes:
- /was-kostet-eine-pressemitteilung: kurze Antwort im ersten Bildschirm,
  vier Abrechnungsmodelle ohne Anbieternamen und fremde Preise, sechs
  Prueffragen fuer Folgekosten, "Was bei uns gilt" (sieben Zusagen mit
  Einloesung), Rechenbeispiel Einzelabrechnung gegen Starter-Monate mit
  Zeilen fuer beide Seiten.
- /pressemitteilung-veroeffentlichen-ohne-abo: Ablauf, enthalten / nicht
  enthalten, nichts verfaellt, wann sich ein Tarif lohnt.
- /pressemitteilung-loeschen-oder-aendern-lassen: fuenf Wege als
  Tabelle (Korrektur, Aenderung, DSGVO, Depublikation, DSA), Antragsweg
  ueber /melden/pm, Korrektur statt Loeschung, Absatz fuer Meldungen auf
  fremden Portalen ohne Zusagen ueber Dritte.

PricingTransparencyData liefert alle Zahlen aus config/billing, credits,
legal und dem Starter-Tarif; TransparencyPageController leitet die Marke
aus dem Host ab. Tabellen-Typografie fuer .pm-body. Verlinkt aus
Preisuebersicht, Hilfe-Center, Sitemaps und llms.txt.

Test TransparencyPagesTest (9) erzwingt u. a., dass im Rechenbeispiel
beide Modelle Zeilen gewinnen. Protokoll Teil 5, Roadmap 2.4 abgehakt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-17 12:00:28 +00:00
parent 4616bb7aad
commit 106edb1384
18 changed files with 953 additions and 4 deletions

View file

@ -22,6 +22,7 @@ use App\Http\Controllers\Web\ReportFormController;
use App\Http\Controllers\Web\SitemapController;
use App\Http\Controllers\Web\SucheController;
use App\Http\Controllers\Web\TerminationController;
use App\Http\Controllers\Web\TransparencyPageController;
use App\Http\Controllers\Web\VeroeffentlichenController;
use App\Http\Middleware\SetEdition;
use App\Models\Category;
@ -161,6 +162,7 @@ $htmlRedirect = static function (string $edition, string $path) {
'preise', 'faq', 'veroeffentlichen',
'suche', 'newsrooms', 'api',
'hilfe', 'gute-pressemitteilung', 'impressum', 'datenschutz', 'agb',
'was-kostet-eine-pressemitteilung', 'pressemitteilung-veroeffentlichen-ohne-abo', 'pressemitteilung-loeschen-oder-aendern-lassen',
];
if (isset($staticAliases[$clean])) {
@ -262,6 +264,11 @@ Route::prefix('{edition}')->whereIn('edition', SetEdition::EDITIONS)->group(func
// Roadmap 1d.1: Hilfeseite ohne kommerziellen Anteil — Ziel des
// Textbausteins in der Ablehnungsmail (1d.2).
Route::view('gute-pressemitteilung', 'web.gute-pressemitteilung')->name('gute-pressemitteilung');
// Transparenzseiten (Roadmap 2.4): Preis, ohne Abo, löschen/ändern.
Route::get('was-kostet-eine-pressemitteilung', [TransparencyPageController::class, 'cost'])->name('was-kostet-eine-pressemitteilung');
Route::get('pressemitteilung-veroeffentlichen-ohne-abo', [TransparencyPageController::class, 'noSubscription'])->name('pressemitteilung-veroeffentlichen-ohne-abo');
Route::get('pressemitteilung-loeschen-oder-aendern-lassen', [TransparencyPageController::class, 'changeOrDelete'])->name('pressemitteilung-loeschen-oder-aendern-lassen');
Route::view('impressum', 'web.impressum')->name('impressum');
// Gesetzlicher Kündigungsbutton (§ 312k BGB): öffentliche Bestätigungsseite