press-releases/jobs: Scheduler respektiert manuelle Prüfung und kommt an Blockaden vorbei, Newsletter-Versand per Schalter gesperrt, kurze Scheduler-Sperren (Umsetzungsaudit 29.09.: K-01, K-02, K-05, K-06, K-09, E9, OPT-8, OPT-9; 02.10.: O06)
- K-01: publish-scheduled filtert manual_review_required_at; publish() prüft für ki/scheduler unter der Sperre (ManualReviewRequiredException) - K-02: Kontingent- und Bildsperre sind fachliche Ausgänge (Exit 0, einmaliger Verlaufseintrag); KI-Job ohne Retry bei Bildsperre - O06: Kandidaten per Cursor (scheduled_at, id), Limit zählt bearbeitete Meldungen, Blockaden nur ein Scan-Budget - K-05: KI-Job lädt vor dem Routing neu, überholter Status ohne Retry; backoff - K-06: Admin-Aktionen mit Permission-Prüfung und Fehlermeldung statt 500 - K-09: withoutOverlapping() mit kurzer Sperrdauer, purge-events 03:50, neuer Wochenlauf press-release-images:sweep-orphan-originals (So 04:45) - E9: NEWSLETTER_SENDING_ENABLED (Standard aus) sperrt Start, Resume und Job - OPT-9: ExpireGrandfathering prüft die Queue-Voraussetzung aus E18 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
c2e0b85242
commit
f0eeef0144
20 changed files with 927 additions and 89 deletions
|
|
@ -50,6 +50,14 @@ class ExpireGrandfathering extends Command
|
|||
|
||||
public function handle(ActivityLog $activityLog, EmailSuppressionService $suppressions): int
|
||||
{
|
||||
// E18 als Zusicherung statt nur als Kommentar (OPT-9): vor jeder
|
||||
// Änderung, damit ein Lauf auf falscher Queue gar nichts anfasst.
|
||||
if (($violation = $this->queueViolation()) !== null) {
|
||||
$this->error($violation);
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$candidates = $this->expiredQuery()->with('user')->get();
|
||||
$pending = $this->pendingNotificationQuery()->with('user')->get();
|
||||
|
||||
|
|
@ -153,7 +161,8 @@ class ExpireGrandfathering extends Command
|
|||
*
|
||||
* Annahme: `QUEUE_CONNECTION=database` ohne eigene `DB_QUEUE_CONNECTION`
|
||||
* (config/queue.php) — der Job-Insert läuft auf derselben Verbindung und
|
||||
* ist damit Teil der Transaktion. Bei einem Wechsel auf Redis o. ä. bräuchte
|
||||
* ist damit Teil der Transaktion. handle() sichert das zu (OPT-9,
|
||||
* queueViolation()). Bei einem Wechsel auf Redis o. ä. bräuchte
|
||||
* es stattdessen einen Zwei-Spalten-Claim (`claimed_at` mit Verfall,
|
||||
* `notified_at` nach Zustellung).
|
||||
*
|
||||
|
|
@ -214,6 +223,36 @@ class ExpireGrandfathering extends Command
|
|||
return [$notified, $failed];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft die Annahme aus notifyPending() (E18): Der Mail-Job wird in
|
||||
* derselben DB-Transaktion eingereiht wie der Marker. Das gilt nur für
|
||||
* die Datenbank-Queue auf der Standard-Verbindung — oder für `sync`
|
||||
* (Tests, lokale Läufe), wo der Versand innerhalb der Transaktion läuft
|
||||
* und ein Fehler den Marker mit zurückrollt. Jede andere Queue würde den
|
||||
* Job unabhängig vom Commit einreihen: dann lieber FAILURE (Alarm) als
|
||||
* stille Doppel- oder Nicht-Zustellung.
|
||||
*/
|
||||
private function queueViolation(): ?string
|
||||
{
|
||||
$default = (string) config('queue.default');
|
||||
|
||||
if ($default === 'sync') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($default !== 'database') {
|
||||
return sprintf('E18 verletzt: QUEUE_CONNECTION ist „%s“, die Benachrichtigung ist nur mit der Datenbank-Queue idempotent. Nichts geändert.', $default);
|
||||
}
|
||||
|
||||
$queueConnection = config('queue.connections.database.connection');
|
||||
|
||||
if ($queueConnection !== null && $queueConnection !== '' && $queueConnection !== config('database.default')) {
|
||||
return sprintf('E18 verletzt: DB_QUEUE_CONNECTION „%s“ weicht von der Standard-Verbindung „%s“ ab, der Job-Insert läge außerhalb der Transaktion. Nichts geändert.', $queueConnection, config('database.default'));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auswahlbedingungen für abgelaufenen Bestandsschutz – bei Auswahl,
|
||||
* Sperre und UPDATE identisch (U11).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue