presseportale/app/Models/LegalRequest.php
Kevin Adametz 2a9be7a9af 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>
2026-07-06 09:35:30 +00:00

94 lines
2.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Models;
use App\Enums\LegalRequestStatus;
use App\Enums\LegalRequestType;
use Database\Factories\LegalRequestFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* Rechts-/Compliance-Anfrage (WS-3) – DSGVO, Persönlichkeitsrecht oder Meldung.
* Bewusst OHNE PortalScope: der Admin-Bereich „Recht & Compliance" sieht alle
* Portale; das Portal wird zur Anzeige/Filterung als eigene Spalte gehalten.
*/
class LegalRequest extends Model
{
/** @use HasFactory<LegalRequestFactory> */
use HasFactory;
protected $fillable = [
'press_release_id',
'portal',
'type',
'status',
'requester_email',
'message',
'payload',
'requester_ip',
'resolved_by_user_id',
'admin_note',
'resolved_at',
];
protected function casts(): array
{
return [
'type' => LegalRequestType::class,
'status' => LegalRequestStatus::class,
'payload' => 'array',
'resolved_at' => 'datetime',
];
}
/**
* Öffentliche Vorgangsnummer (T10) — analog zur Kündigung ("K-{id}").
* Wird in der Eingangsbestätigung genannt und bei Rückfragen referenziert.
*/
public function reference(): string
{
return 'M-'.$this->id;
}
/**
* Name des Meldenden (Standalone-Formulare, DSA Art. 16) — strukturierte
* Zusatzfelder liegen bewusst im payload (WS-3).
*/
public function requesterName(): ?string
{
return $this->payload['requester_name'] ?? null;
}
/**
* Gemeldete URL, wie vom Meldenden angegeben (Standalone-Formulare).
*/
public function reportedUrl(): ?string
{
return $this->payload['reported_url'] ?? null;
}
public function pressRelease(): BelongsTo
{
return $this->belongsTo(PressRelease::class);
}
public function resolver(): BelongsTo
{
return $this->belongsTo(User::class, 'resolved_by_user_id');
}
/**
* @param Builder<LegalRequest> $query
* @return Builder<LegalRequest>
*/
public function scopeOpen(Builder $query): Builder
{
return $query->whereIn('status', [
LegalRequestStatus::Open->value,
LegalRequestStatus::InProgress->value,
]);
}
}