option('batch'); $dryRun = $this->option('dry-run'); $webhooks = $service->getRetryableWebhooks($batchSize); $count = $webhooks->count(); if ($count === 0) { $this->info('No pending webhooks to process.'); return self::SUCCESS; } $this->info(sprintf( '%s %d webhook(s)...', $dryRun ? 'Would process' : 'Processing', $count )); if ($dryRun) { $this->table( ['ID', 'Event', 'Workspace', 'Retry #', 'Scheduled For', 'Last Error'], $webhooks->map(fn ($wh) => [ $wh->id, $wh->event_type, $wh->workspace_id ?? 'N/A', $wh->retry_count + 1, $wh->next_retry_at?->format('Y-m-d H:i:s'), mb_substr($wh->last_error ?? '-', 0, 40), ]) ); return self::SUCCESS; } $succeeded = 0; $failed = 0; $this->withProgressBar($webhooks, function ($webhook) use ($service, &$succeeded, &$failed) { $result = $service->retry($webhook); if ($result) { $succeeded++; } else { $failed++; } }); $this->newLine(2); $this->info("Processed: {$count}, Succeeded: {$succeeded}, Failed: {$failed}"); // Log summary Log::info('Webhook retry batch completed', [ 'processed' => $count, 'succeeded' => $succeeded, 'failed' => $failed, 'pending_remaining' => $service->countPendingRetries(), ]); return $failed > 0 ? self::FAILURE : self::SUCCESS; } }