Änderungen (relevant):

- Add‑on Checkout auf Transactions + Transaction‑ID speichern: app/Services/Addons/EventAddonCheckoutService.php
  - Paket/Marketing Checkout auf Transactions: app/Services/Paddle/PaddleCheckoutService.php
  - Gift‑Voucher Checkout: Customer anlegen/finden + Transactions: app/Services/GiftVouchers/
    GiftVoucherCheckoutService.php
  - Tests aktualisiert: tests/Feature/Tenant/EventAddonCheckoutTest.php, tests/Unit/PaddleCheckoutServiceTest.php,
tests/Unit/GiftVoucherCheckoutServiceTest.php
This commit is contained in:
Codex Agent
2025-12-29 18:04:28 +01:00
parent 795e37ee12
commit 5f521d055f
26 changed files with 783 additions and 102 deletions

View File

@@ -32,8 +32,10 @@ use App\Services\Checkout\CheckoutSessionService;
use App\Services\Security\PhotoSecurityScanner;
use App\Services\Storage\EventStorageManager;
use App\Services\Storage\StorageHealthService;
use App\Support\SentryReporter;
use App\Testing\Mailbox;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Console\Events\ScheduledTaskFailed;
use Illuminate\Http\Request;
use Illuminate\Mail\Events\MessageSent;
use Illuminate\Queue\Events\JobFailed;
@@ -241,36 +243,63 @@ class AppServiceProvider extends ServiceProvider
];
});
if (config('storage-monitor.queue_failure_alerts')) {
Queue::failing(function (JobFailed $event) {
$context = [
'queue' => $event->job->getQueue(),
'job' => $event->job->resolveName(),
'exception' => $event->exception->getMessage(),
];
Queue::failing(function (JobFailed $event) {
$context = [
'queue' => $event->job->getQueue(),
'job' => $event->job->resolveName(),
'exception' => $event->exception->getMessage(),
];
$command = data_get($event->job->payload(), 'data.command');
$command = data_get($event->job->payload(), 'data.command');
if (is_string($command)) {
try {
$instance = @unserialize($command, ['allowed_classes' => true]);
if (is_object($instance)) {
foreach (['eventId' => 'event_id', 'photoId' => 'photo_id'] as $property => $label) {
if (isset($instance->{$property})) {
$context[$label] = $instance->{$property};
}
if (is_string($command)) {
try {
$instance = @unserialize($command, ['allowed_classes' => true]);
if (is_object($instance)) {
foreach (['eventId' => 'event_id', 'photoId' => 'photo_id'] as $property => $label) {
if (isset($instance->{$property})) {
$context[$label] = $instance->{$property};
}
}
} catch (\Throwable $e) {
$context['unserialize_error'] = $e->getMessage();
}
} catch (\Throwable $e) {
$context['unserialize_error'] = $e->getMessage();
}
}
SentryReporter::captureException($event->exception, [
'tags' => [
'queue' => $context['queue'],
'job' => $context['job'],
'connection' => $event->connectionName,
],
'extra' => [
'event_id' => $context['event_id'] ?? null,
'photo_id' => $context['photo_id'] ?? null,
],
]);
if (config('storage-monitor.queue_failure_alerts')) {
if ($mail = config('storage-monitor.alert_recipients.mail')) {
Notification::route('mail', $mail)->notify(new UploadPipelineFailed($context));
}
});
}
}
});
EventFacade::listen(ScheduledTaskFailed::class, function (ScheduledTaskFailed $event): void {
$task = $event->task;
SentryReporter::captureException($event->exception, [
'tags' => [
'schedule_command' => $task->command ?? 'unknown',
'schedule_expression' => $task->expression ?? null,
],
'extra' => [
'schedule_description' => $task->description ?? null,
'schedule_timezone' => $task->timezone ?? null,
],
]);
});
if ($this->app->runningInConsole()) {
$this->app->register(\App\Providers\Filament\AdminPanelProvider::class);