presseportale/app/Console/Commands/SweepOrphanPressReleaseOriginals.php
Kevin Adametz f1c0e2766b 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>
2026-10-02 13:09:01 +00:00

55 lines
2.1 KiB
PHP
Raw Permalink 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\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;
}
}