Horizon fuer Live vorbereitet

- Supervisor bedient alle Queues der Jobs (high-priority, default, dhl-*),
  production mit 3 statt 10 Prozessen
- Redis-Queue mit after_commit: der Stripe-Paid-Pfad plant den
  Rechnungsnummer-Sync innerhalb der Transaktion ein
- /horizon nur fuer System-Admins (admin >= 4)
- horizon:snapshot alle 5 Minuten, queue:prune-failed nach 30 Tagen
- deploy.sh: QUEUE_WORKER (horizon | none), Anleitung Abschnitt F

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin 2026-10-07 10:32:26 +00:00
parent e1c6178bc7
commit 21daab259f
7 changed files with 95 additions and 25 deletions

View file

@ -0,0 +1,45 @@
<?php
use App\User;
use Illuminate\Support\Facades\Gate;
use Tests\TestCase;
uses(TestCase::class);
/**
* Horizon auf Live (QUEUE_DRIVER=redis): jede Queue, auf die ein Job sich
* legt, muss ein Supervisor bedienen — sonst bleibt der Job still liegen.
*/
test('horizon serves every queue the jobs are pushed to', function () {
$queues = collect(glob(app_path('Jobs/*.php')))
->flatMap(function (string $file): array {
preg_match_all("/onQueue\\('([^']+)'\\)/", file_get_contents($file), $matches);
return $matches[1];
})
->push('default')
->unique();
$served = collect(config('horizon.defaults'))->pluck('queue')->flatten();
expect($queues->diff($served)->values()->all())->toBe([]);
});
test('jobs dispatched inside a transaction wait for the commit', function () {
expect(config('queue.connections.redis.after_commit'))->toBeTrue();
});
test('only system admins may open the horizon dashboard', function (int $admin, bool $allowed) {
$user = new User;
$user->admin = $admin;
expect(Gate::forUser($user)->allows('viewHorizon'))->toBe($allowed);
})->with([
'system admin' => [4, true],
'super admin' => [3, false],
'consultant' => [0, false],
]);
test('guests may not open the horizon dashboard', function () {
expect(Gate::allows('viewHorizon'))->toBeFalse();
});