presseportale/app/Http/Controllers/Web/NewsroomDetailController.php
Kevin Adametz 2aebb9d27e companies: Zusammenführung im Bestand, rückabwickelbar (Roadmap 1a.3)
companies:merge führt Firmen mit derselben Firmen-E-Mail zu einem Newsroom
zusammen — nur über Adressen, die 1a.2 als Dublette oder Namensvariante
klassifiziert hat. Es bleibt die Firma mit den meisten jemals
veröffentlichten Meldungen; Meldungen, Kontakte, Nutzer- und
Zahlungsverknüpfungen wandern per company_id, jede Bewegung steht in
company_merge_moves. companies:unmerge spielt sie rückwärts ab.

77 % der Gruppen sind dieselbe Firma auf beiden Portalen (Altsystem: eine
Firma je Portal). Der Überlebende wird dann `both`; die Meldungen behalten
ihr Portal. Der alte Newsroom-Slug führt per 301 zum Überlebenden.
Slug-Kollisionen auf dem anderen Portal werden übersprungen, nicht
umbenannt. Company::slugExists() kennt jetzt `both`.

Dev-DB: 14 142 Adressen, 16 194 Firmen, 13 297 Meldungen in 2 min;
Rückabwicklung in 1:15 min exakt auf den Stand davor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 08:43:46 +00:00

36 lines
1.4 KiB
PHP

<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Services\Web\NewsroomDetailPageData;
use App\Support\WebPortalContext;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response;
class NewsroomDetailController extends Controller
{
// $edition stammt aus dem Gruppen-Prefix {edition} und steht positionsbedingt
// vor {slug}; es wird hier nicht gebraucht, muss aber in der Signatur stehen.
public function __invoke(string $edition, string $slug, NewsroomDetailPageData $pageData): View|Response|RedirectResponse
{
$data = $pageData->build(WebPortalContext::fromRequest(), $slug);
// Firma in einer Zusammenführung aufgegangen → dauerhaft zum
// bleibenden Newsroom (Roadmap 1a.3).
// Host aus dem Request wie bei den anderen 301-Weiterleitungen in
// routes/web.php — route() allein trüge den konfigurierten Root-Host.
if (isset($data['redirect'])) {
return redirect(request()->getSchemeAndHttpHost().route('newsroom', ['slug' => $data['redirect']], absolute: false), 301);
}
// Bewusst entfernter Newsroom → Tombstone mit 410 Gone (ohne Inhalte).
// Vollständig gelöschte Firmen bleiben bei 404.
if (isset($data['tombstone'])) {
return response()->view('web.newsroom-tombstone', [], 410);
}
return view('web.newsroom', $data);
}
}