legal/web: Zustimmungsgate je Dokumentversion (aus bis AGB 0.7), OG-Variante mit eingebranntem Bildnachweis, Nachweis in Teasern (Bildkennzeichnung Blöcke G und H)
- legal_document_acceptances (insert-only), LegalAcceptanceGate, Pflicht-Schalter im Einreichungs-Modal über den gemeinsamen Trait; API: GET/POST /api/v1/legal/acceptances, submit antwortet 428 mit den geforderten Fassungen; LEGAL_ACCEPTANCE_GATE - ImageService: og-Variante (1200×630) mit halbtransparentem Balken und Inter SemiBold, regenerateOgVariant() für Korrekturen und Bestand; Fokuspunkt/Letterbox getestet - Uploader brennt den Nachweis beim Upload ein, ImageCorrectionService baut die OG-Variante nach einer Korrektur neu; Artikelseite nutzt og für og:image - Teaser: Nachweis in alt/title (Feed, Hero, Kategorie, Newsroom), Unterschrift am Hero-Bild; PressRelease::cardImageCredit() Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
b5b70416f2
commit
075d0d931f
27 changed files with 866 additions and 15 deletions
|
|
@ -3,6 +3,8 @@
|
|||
namespace App\Livewire\Concerns;
|
||||
|
||||
use App\Enums\AiTextDeclaration;
|
||||
use App\Models\LegalDocumentAcceptance;
|
||||
use App\Services\Legal\LegalAcceptanceGate;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
|
@ -21,19 +23,51 @@ trait InteractsWithAiDeclaration
|
|||
|
||||
public bool $aiDeclarationConfirmed = false;
|
||||
|
||||
/**
|
||||
* Zustimmungsgate (Bildkennzeichnung Block G): aktive Annahme der
|
||||
* aktuellen AGB- und Richtlinien-Fassung, wenn das Gate an ist und eine
|
||||
* Fassung noch nicht angenommen wurde.
|
||||
*/
|
||||
public bool $legalAcceptanceConfirmed = false;
|
||||
|
||||
/**
|
||||
* Pflichtprüfung vor dem Einreichen — Fehler erscheinen direkt im
|
||||
* Submit-Modal. Entwurf-Speichern bleibt frei von dieser Pflicht.
|
||||
*/
|
||||
protected function validateAiDeclaration(): void
|
||||
{
|
||||
$this->validate([
|
||||
$rules = [
|
||||
'aiTextDeclaration' => ['required', Rule::in(AiTextDeclaration::values())],
|
||||
'aiDeclarationConfirmed' => ['accepted'],
|
||||
], [
|
||||
];
|
||||
$messages = [
|
||||
'aiTextDeclaration.required' => __('Bitte angeben, ob und wie generative KI beim Text eingesetzt wurde.'),
|
||||
'aiDeclarationConfirmed.accepted' => __('Bitte bestätigen, dass die Angaben zum KI-Einsatz vollständig und wahrheitsgemäß sind.'),
|
||||
]);
|
||||
];
|
||||
|
||||
if (app(LegalAcceptanceGate::class)->requiredFor(auth()->user())->isNotEmpty()) {
|
||||
$rules['legalAcceptanceConfirmed'] = ['accepted'];
|
||||
$messages['legalAcceptanceConfirmed.accepted'] = __('Bitte nehmen Sie die aktuelle Fassung der AGB und der Veröffentlichungsrichtlinien an.');
|
||||
}
|
||||
|
||||
$this->validate($rules, $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Annahme protokollieren (nach validateAiDeclaration, vor dem Einreichen).
|
||||
* Ohne Gate oder ohne offene Fassung passiert nichts.
|
||||
*/
|
||||
protected function persistLegalAcceptances(): void
|
||||
{
|
||||
$gate = app(LegalAcceptanceGate::class);
|
||||
$required = $gate->requiredFor(auth()->user());
|
||||
|
||||
if ($required->isEmpty() || ! $this->legalAcceptanceConfirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
$gate->accept(auth()->user(), $required, LegalDocumentAcceptance::CONTEXT_SUBMIT, request()->ip(), request()->userAgent());
|
||||
$this->legalAcceptanceConfirmed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue