T10: DSA-Meldeformulare mit URL-Feld, Vorgangsnummer und Eingangsbestaetigung

Zwei eigenstaendige Formulare unter /melden/rechtswidrig (DSA Art. 16:
URL, Name, E-Mail, Begruendung, Wahrheitsversicherung) und
/melden/kontaktdaten (DSGVO-Antrag) auf allen drei Domains. Gemeldete
URLs werden automatisch der passenden veroeffentlichten PM zugeordnet;
ohne Treffer bleibt die URL im payload. Jede Meldung erhaelt eine
Vorgangsnummer (M-{id}, analog K-{id} der Kuendigung), die meldende
Person unverzueglich eine Eingangsbestaetigung (DSA Art. 16 Abs. 4) und
das Melde-Postfach einen internen Hinweis — auch im bestehenden
Per-PM-Flow. Admin-Queue zeigt Vorgangsnummer, Name und gemeldete URL;
/melden verlinkt die neuen Formulare als ersten Weg.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-06 09:35:30 +00:00
parent 61a677aa0b
commit 2a9be7a9af
14 changed files with 673 additions and 12 deletions

View file

@ -6,11 +6,14 @@ use App\Enums\LegalRequestStatus;
use App\Enums\LegalRequestType;
use App\Enums\Portal;
use App\Enums\PressReleaseStatus;
use App\Mail\LegalRequestReceived;
use App\Mail\LegalRequestSubmitted;
use App\Models\LegalRequest;
use App\Models\PressRelease;
use App\Scopes\PortalScope;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
@ -78,7 +81,7 @@ class LegalRequestController extends Controller
RateLimiter::hit($this->throttleKey($release), 3600);
LegalRequest::query()->create([
$legalRequest = LegalRequest::query()->create([
'press_release_id' => $release->getKey(),
'portal' => $release->portal?->value,
'type' => $type->value,
@ -88,7 +91,19 @@ class LegalRequestController extends Controller
'requester_ip' => $request->ip(),
]);
return $this->done($release);
// T10/DSA Art. 16 Abs. 4: unverzügliche Eingangsbestätigung mit
// Vorgangsnummer (sofern eine E-Mail-Adresse angegeben wurde) +
// interner Hinweis ans Melde-Postfach.
if ($legalRequest->requester_email) {
Mail::to($legalRequest->requester_email)->send(new LegalRequestReceived($legalRequest));
}
Mail::to($this->operatorRecipient())->send(new LegalRequestSubmitted($legalRequest));
return redirect()
->route('release.detail', ['slug' => $release->slug])
->with('legal-status', __('Vielen Dank. Ihre Anfrage ist unter der Vorgangsnummer :reference eingegangen und wird von unserem Team geprüft.', [
'reference' => $legalRequest->reference(),
]));
}
private function done(PressRelease $release): RedirectResponse
@ -98,6 +113,15 @@ class LegalRequestController extends Controller
->with('legal-status', __('Vielen Dank. Ihre Anfrage ist eingegangen und wird von unserem Team geprüft.'));
}
private function operatorRecipient(): string
{
$brand = str_contains(request()->getHost(), 'presseecho')
? config('domains.domains.presseecho.brand', [])
: config('domains.domains.businessportal24.brand', []);
return $brand['report_email'] ?? (string) config('legal.contact_email');
}
private function resolvePublishedRelease(string $slug): PressRelease
{
$portal = str_contains(request()->getHost(), 'presseecho')