images: nur freigegebene Bilder in Feed und PDF, versionierte Veröffentlichungssnapshots, Bestätigung an das gezeigte Bild gebunden, getrennte Rückhaltegründe (Umsetzungsaudit 29.09.: B-01 bis B-14, N09, OPT-3 bis OPT-5; 02.10.: O03)
- B-01/B-02: Startseiten-Feed, Card-Helfer und Nachweis-PDF nur mit isPubliclyDeliverable() - B-03: Livewire-Temp-Upload 16 MiB - N09: Snapshot je Bytes- und Metadaten-Hash inkl. OG-Variante, put() geprüft, alle Fassungen ins Archiv - O03: published_ever_at in der Freigabetransaktion (markPublishedIfNowPublic) — Kundenbestätigung, Vorab-Sichtung, Korrektur - B-04/B-14: Bestätigung an Bild-ID und SHA gebunden, unter Sperre - B-05/B-06: Entfernen unter Sperre mit frischem Stand und Archivauftrag; Korrektur archiviert über den Auftrag, Nacharbeiten abgesichert - B-07: precheck_withheld_at getrennt von withheld_at (Migration + Übernahme) - B-08, B-09, B-11, B-12: published_ever_at nur bei Status published, Admin-Eigentümer mit Kundenregel, Sweep verwaister Originale, Verarbeitungsfehler als Formularmeldung - K-02-Teil: nach Kundenbestätigung erneut routen - OPT-3 bis OPT-5: pingImage für JPEG, Hash durchgereicht, erstes Frame Admin-PM-Detailseite enthält zusätzlich K-06 (Autorisierung) und A-08 (Nachweis per POST), weil die Datei ungeteilt committet ist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7cd84b2be3
commit
5ec252da12
23 changed files with 1675 additions and 149 deletions
55
app/Console/Commands/SweepOrphanPressReleaseOriginals.php
Normal file
55
app/Console/Commands/SweepOrphanPressReleaseOriginals.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\Archive\EvidenceArchive;
|
||||
use App\Services\PressRelease\Images\PressReleaseImageRemover;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Umsetzungsaudit 29.09.2026, B-11: Beweisoriginale ohne Bildzeile (harter
|
||||
* Abbruch nach dem Schreiben des Originals, z. B. memory_limit bei
|
||||
* 8000 × 8000 px) nach einer Karenzzeit entfernen.
|
||||
*
|
||||
* Standard ist ein Trockenlauf. Dateien, auf die eine Bildzeile zeigt —
|
||||
* auch weich gelöschte (Beweisarchiv ausstehend) —, bleiben immer liegen.
|
||||
* Nach einem Datenbank-Restore fehlen Zeilen, deren Originale noch Beweis
|
||||
* sind: Solange der Archiv-Sweep ausgesetzt ist (`archive:sweep-orphans
|
||||
* --pause`, setzt auch `archive:reconcile-after-restore`), löscht auch dieser
|
||||
* Befehl nichts.
|
||||
*/
|
||||
class SweepOrphanPressReleaseOriginals extends Command
|
||||
{
|
||||
protected $signature = 'press-release-images:sweep-orphan-originals
|
||||
{--execute : Wirklich löschen (Standard ist ein Trockenlauf)}
|
||||
{--hours=48 : Nur Dateien, die älter als X Stunden sind}';
|
||||
|
||||
protected $description = 'Entfernt Beweisoriginale ohne zugehörige Bildzeile (B-11)';
|
||||
|
||||
public function handle(PressReleaseImageRemover $remover, EvidenceArchive $archive): int
|
||||
{
|
||||
$execute = (bool) $this->option('execute');
|
||||
|
||||
if ($execute && $archive->isSweepPaused()) {
|
||||
$this->warn('Orphan-Sweep ausgesetzt (Restore-Abgleich) — nichts gelöscht. Fortsetzen mit archive:sweep-orphans --resume.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$result = $remover->sweepOrphanOriginals(
|
||||
$execute,
|
||||
(int) $this->option('hours'),
|
||||
fn (string $file) => $this->line(' verwaist: '.$file),
|
||||
);
|
||||
|
||||
$this->info(sprintf(
|
||||
'%s: %d Dateien geprüft, %d verwaist, %d entfernt.',
|
||||
$execute ? 'Bereinigung' : 'Trockenlauf',
|
||||
$result['scanned'],
|
||||
$result['orphans'],
|
||||
$result['removed'],
|
||||
));
|
||||
|
||||
return $execute && $result['removed'] < $result['orphans'] ? self::FAILURE : self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue