Add integrations health monitoring
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-02 18:35:12 +01:00
parent 9057a4cd15
commit fc3e6715db
21 changed files with 715 additions and 13 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use App\Services\Addons\EventAddonWebhookService;
use App\Services\Checkout\CheckoutWebhookService;
use App\Services\Integrations\IntegrationWebhookRecorder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
@@ -14,6 +15,7 @@ class PaddleWebhookController extends Controller
public function __construct(
private readonly CheckoutWebhookService $webhooks,
private readonly EventAddonWebhookService $addonWebhooks,
private readonly IntegrationWebhookRecorder $recorder,
) {}
public function handle(Request $request): JsonResponse
@@ -32,6 +34,12 @@ class PaddleWebhookController extends Controller
}
$eventType = $payload['event_type'] ?? null;
$eventId = $payload['event_id'] ?? $payload['id'] ?? data_get($payload, 'data.id');
$webhookEvent = $this->recorder->recordReceived(
'paddle',
$eventId ? (string) $eventId : null,
$eventType ? (string) $eventType : null,
);
$handled = false;
$this->logDev('Paddle webhook received', [
@@ -53,6 +61,9 @@ class PaddleWebhookController extends Controller
]);
$statusCode = $handled ? Response::HTTP_OK : Response::HTTP_ACCEPTED;
$handled
? $this->recorder->markProcessed($webhookEvent, ['handled' => true])
: $this->recorder->markIgnored($webhookEvent, ['handled' => false]);
return response()->json([
'status' => $handled ? 'processed' : 'ignored',
@@ -68,6 +79,10 @@ class PaddleWebhookController extends Controller
$this->logDev('Paddle webhook error payload', $this->reducePayload($request->json()->all()));
if (isset($webhookEvent)) {
$this->recorder->markFailed($webhookEvent, $exception->getMessage());
}
return response()->json(['status' => 'error'], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Jobs\ProcessRevenueCatWebhook;
use App\Services\Integrations\IntegrationWebhookRecorder;
use App\Support\ApiError;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -11,6 +12,8 @@ use Symfony\Component\HttpFoundation\Response;
class RevenueCatWebhookController extends Controller
{
public function __construct(private readonly IntegrationWebhookRecorder $recorder) {}
public function handle(Request $request): JsonResponse
{
$secret = (string) config('services.revenuecat.webhook', '');
@@ -61,9 +64,18 @@ class RevenueCatWebhookController extends Controller
);
}
$eventId = (string) $request->header('X-Event-Id', '');
$eventType = data_get($decoded, 'event.type');
$webhookEvent = $this->recorder->recordReceived(
'revenuecat',
$eventId !== '' ? $eventId : null,
is_string($eventType) && $eventType !== '' ? $eventType : null,
);
ProcessRevenueCatWebhook::dispatch(
$decoded,
(string) $request->header('X-Event-Id', '')
$eventId,
$webhookEvent->id,
);
return response()->json(['status' => 'accepted'], 202);