Launch-pflichtiger Compliance-Slice: öffentliche Anfrage zu einer PM speist eine
manuelle Admin-Queue (keine KI).
- Migration legal_requests + Model + Enums (Type: dsgvo/personal_rights/report,
Status: open/in_progress/resolved/rejected) + Factory.
- Öffentliches Formular /release/{slug}/rechtliches (LegalRequestController +
web/legal-request.blade.php): typ-abhängiger Hinweistext (Alpine), E-Mail bei
DSGVO/Persönlichkeitsrecht erforderlich, zwei versteckte Honeypot-Felder,
Rate-Limit + Bremse "1 offene Anfrage pro PM/Typ". Regeltexte als Entwurf mit
TODO für rechtliche Finalisierung markiert.
- Routen bewusst in eigener routes/legal.php (entkoppelt vom laufenden Web-Umbau),
host-agnostisch via domains.php eingebunden.
- Admin-Bereich "Recht & Compliance": Sidebar-Nav mit Offen-Zähler, Volt-Queue
index/show (in Bearbeitung/erledigt/abgelehnt/wieder öffnen + interne Notiz).
- Tests: je Typ, Honeypots (Dataset), Bremse, Admin-Queue + Status-Übergänge.
- Doku: Detailplan WS-3-Status + Deployment-Migrationsreihenfolge ergänzt.
Hinweis: Der "Melden"-/E&F-Button auf der PM-Detailseite (release-detail.blade.php)
wird mit dem separaten Web-Frontend-Commit verdrahtet; Ziel ist legal-request.create.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
144 lines
7.8 KiB
PHP
144 lines
7.8 KiB
PHP
@extends('web.layouts.web-master')
|
||
|
||
@section('title', 'Recht & Compliance – '.$release->title)
|
||
@section('meta_description', 'Datenschutz-, Persönlichkeitsrechts- oder Meldeanfrage zu einer Pressemitteilung.')
|
||
|
||
@section('content')
|
||
{{--
|
||
TODO (Inhalt/Recht): Die untenstehenden Hinweistexte je Anfragetyp sind ein
|
||
erster ENTWURF und müssen noch fachlich/rechtlich finalisiert werden. Hier
|
||
gehört für jeden Typ konkret hinein, WIE der jeweilige Vorgang funktioniert:
|
||
- DSGVO (E): Rechtsgrundlage (Art. 17 DSGVO), welche Daten betroffen sein
|
||
können, ob/wie ein Identitätsnachweis nötig ist, Bearbeitungs-
|
||
frist (i.d.R. 30 Tage), was nach Einreichung passiert.
|
||
- Persönlichkeitsrecht (F): welche Inhalte beanstandet werden können
|
||
(unwahre Tatsachen, Bildrechte …), Nachweise, Ablauf der Prüfung,
|
||
mögliche Folgen (Anpassung/Entfernung).
|
||
- Meldung: welche Gründe sinnvoll sind (Spam, irreführend, rechtswidrig),
|
||
dass jede Meldung manuell geprüft wird, E-Mail optional.
|
||
Diese Regeln mit Recht/Legal abstimmen, bevor sie live gehen.
|
||
--}}
|
||
<section
|
||
x-data="{ type: @js(old('type', $type->value)), emailRequired() { return ['dsgvo', 'personal_rights'].includes(this.type); } }"
|
||
class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-10"
|
||
>
|
||
<a href="{{ route('release.detail', ['slug' => $release->slug]) }}"
|
||
class="text-[12px] text-ink-3 hover:text-ink transition-colors">← Zurück zur Pressemitteilung</a>
|
||
|
||
<div class="eyebrow muted text-[10px] mt-4 mb-2">Recht & Compliance</div>
|
||
<h1 class="font-serif text-[26px] font-semibold tracking-[-0.3px] m-0 mb-2 text-ink">
|
||
Anfrage zu dieser Pressemitteilung
|
||
</h1>
|
||
<p class="text-[13px] text-ink-3 mb-1">
|
||
Betrifft: <span class="text-ink-2 font-medium">{{ $release->title }}</span>
|
||
</p>
|
||
<p class="text-[12.5px] text-ink-3 leading-relaxed mb-6">
|
||
Datenschutz (DSGVO), Persönlichkeitsrechte und Meldungen werden von unserem
|
||
Team manuell geprüft. Bitte wählen Sie die Art Ihrer Anfrage – dazu erscheint
|
||
ein Hinweis mit den genauen Regeln.
|
||
</p>
|
||
|
||
@if (session('legal-status'))
|
||
<div class="mb-6 px-4 py-3 border border-bg-rule bg-bg-elev text-[13px] text-ink-2" role="status">
|
||
{{ session('legal-status') }}
|
||
</div>
|
||
@endif
|
||
|
||
<form method="POST" action="{{ route('legal-request.store', ['slug' => $release->slug]) }}" class="space-y-5">
|
||
@csrf
|
||
|
||
<div>
|
||
<label for="type" class="block text-[12px] font-semibold text-ink mb-1.5">Art der Anfrage</label>
|
||
<select id="type" name="type" x-model="type"
|
||
class="w-full border border-bg-rule px-3 py-2.5 text-[13px] bg-white text-ink focus:outline-none focus:border-brand">
|
||
@foreach ($types as $case)
|
||
<option value="{{ $case->value }}" @selected(old('type', $type->value) === $case->value)>
|
||
{{ $case->publicLabel() }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
@error('type')
|
||
<p class="mt-1 text-[12px] text-red-600">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- Hinweistext je Anfragetyp (ENTWURF – siehe TODO oben). --}}
|
||
<div x-cloak x-show="type === 'report'"
|
||
class="px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
|
||
<strong class="text-ink">Meldung:</strong>
|
||
Melden Sie diese Pressemitteilung, wenn Sie sie für Spam, irreführend oder
|
||
rechtswidrig halten. Bitte beschreiben Sie den Grund konkret. Jede Meldung
|
||
wird manuell geprüft. Eine E-Mail-Adresse ist optional, hilft aber bei
|
||
Rückfragen.
|
||
</div>
|
||
<div x-cloak x-show="type === 'dsgvo'"
|
||
class="px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
|
||
<strong class="text-ink">Datenschutz / DSGVO:</strong>
|
||
Sie können die Löschung oder Anonymisierung Ihrer personenbezogenen Daten
|
||
verlangen (Art. 17 DSGVO). Bitte geben Sie an, welche Angaben Sie betreffen.
|
||
Zur Rückmeldung und ggf. Identitätsprüfung benötigen wir Ihre E-Mail-Adresse.
|
||
Die Bearbeitung erfolgt in der Regel innerhalb von 30 Tagen.
|
||
</div>
|
||
<div x-cloak x-show="type === 'personal_rights'"
|
||
class="px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
|
||
<strong class="text-ink">Persönlichkeitsrecht:</strong>
|
||
Wenn diese Mitteilung Ihre Persönlichkeitsrechte verletzt (z. B. unwahre
|
||
Tatsachenbehauptungen, Bildrechte), schildern Sie bitte konkret, welche
|
||
Inhalte betroffen sind. Für Rückfragen benötigen wir Ihre E-Mail-Adresse.
|
||
Bei berechtigten Ansprüchen wird der Inhalt geprüft und ggf. angepasst oder
|
||
entfernt.
|
||
</div>
|
||
|
||
<div>
|
||
<label for="requester_email" class="block text-[12px] font-semibold text-ink mb-1.5">
|
||
E-Mail-Adresse
|
||
<span class="text-ink-3 font-normal" x-show="emailRequired()">(erforderlich)</span>
|
||
<span class="text-ink-3 font-normal" x-show="!emailRequired()" x-cloak>(optional)</span>
|
||
</label>
|
||
<input id="requester_email" type="email" name="requester_email" value="{{ old('requester_email') }}"
|
||
autocomplete="email"
|
||
class="w-full border border-bg-rule px-3 py-2.5 text-[13px] bg-white text-ink focus:outline-none focus:border-brand" />
|
||
@error('requester_email')
|
||
<p class="mt-1 text-[12px] text-red-600">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
<div>
|
||
<label for="message" class="block text-[12px] font-semibold text-ink mb-1.5">Ihr Anliegen</label>
|
||
<textarea id="message" name="message" rows="6" required
|
||
class="w-full border border-bg-rule px-3 py-2.5 text-[13px] bg-white text-ink focus:outline-none focus:border-brand"
|
||
placeholder="Bitte beschreiben Sie Ihr Anliegen.">{{ old('message') }}</textarea>
|
||
@error('message')
|
||
<p class="mt-1 text-[12px] text-red-600">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{--
|
||
Bot-Schutz: versteckte Honeypot-Felder. Für Menschen unsichtbar
|
||
(display:none via .hidden), für Bots aber im DOM. Werden sie ausgefüllt,
|
||
verwirft der Controller die Anfrage still. Die Namen ('website',
|
||
'homepage') sind bewusst „attraktiv" für Auto-Filler. Zusätzlich greift
|
||
serverseitig ein Rate-Limit pro IP/PM.
|
||
Mögliche Erweiterung später: zeitbasierte Falle (signierter Render-
|
||
Zeitstempel, Ablehnung bei Absenden < 2s) oder Captcha bei Missbrauch.
|
||
--}}
|
||
<div class="hidden" aria-hidden="true">
|
||
<label for="website">Website</label>
|
||
<input id="website" type="text" name="website" tabindex="-1" autocomplete="off" value="{{ old('website') }}" />
|
||
<label for="homepage">Homepage</label>
|
||
<input id="homepage" type="text" name="homepage" tabindex="-1" autocomplete="off" value="{{ old('homepage') }}" />
|
||
</div>
|
||
|
||
<button type="submit"
|
||
class="bg-brand hover:bg-brand-deep text-white px-5 py-2.5 text-[13px] font-semibold transition-colors">
|
||
Anfrage absenden
|
||
</button>
|
||
</form>
|
||
|
||
<p class="mt-6 text-[11.5px] text-ink-3 leading-relaxed">
|
||
Hinweis: Diese Angaben werden ausschließlich zur Bearbeitung Ihrer Anfrage
|
||
verarbeitet. Weitere Informationen in der
|
||
<a href="{{ route('datenschutz') }}" class="underline hover:text-ink">Datenschutzerklärung</a>.
|
||
</p>
|
||
</section>
|
||
@endsection
|