Add integrations health monitoring
This commit is contained in:
@@ -188,6 +188,31 @@ return [
|
||||
'label' => 'Paddle-Status',
|
||||
],
|
||||
],
|
||||
'integrations_health' => [
|
||||
'navigation' => [
|
||||
'label' => 'Integrationen-Status',
|
||||
],
|
||||
'status' => [
|
||||
'healthy' => 'OK',
|
||||
'pending' => 'Ausstehend',
|
||||
'degraded' => 'Beeinträchtigt',
|
||||
'unconfigured' => 'Nicht konfiguriert',
|
||||
'unknown' => 'Unbekannt',
|
||||
],
|
||||
'heading' => 'Integrationen-Status',
|
||||
'help' => 'Operativer Überblick über Paddle/RevenueCat-Webhooks, Queue-Backlog und jüngste Fehler.',
|
||||
'configured' => 'Konfiguriert',
|
||||
'unconfigured' => 'Nicht konfiguriert',
|
||||
'last_received' => 'Zuletzt empfangen',
|
||||
'last_processed' => 'Zuletzt verarbeitet',
|
||||
'processing_lag' => 'Verarbeitungsdauer',
|
||||
'pending_events' => 'Offene Events',
|
||||
'recent_failures' => 'Fehler (24h)',
|
||||
'queue_backlog' => 'Queue-Backlog',
|
||||
'failed_jobs' => 'Fehlgeschlagene Jobs',
|
||||
'last_error' => 'Letzter Fehler',
|
||||
'empty' => 'Noch keine Integrationsdaten verfügbar.',
|
||||
],
|
||||
'guest_policy' => [
|
||||
'navigation' => [
|
||||
'label' => 'Gast-Richtlinien',
|
||||
|
||||
@@ -188,6 +188,31 @@ return [
|
||||
'label' => 'Paddle health',
|
||||
],
|
||||
],
|
||||
'integrations_health' => [
|
||||
'navigation' => [
|
||||
'label' => 'Integrations health',
|
||||
],
|
||||
'status' => [
|
||||
'healthy' => 'Healthy',
|
||||
'pending' => 'Pending',
|
||||
'degraded' => 'Degraded',
|
||||
'unconfigured' => 'Unconfigured',
|
||||
'unknown' => 'Unknown',
|
||||
],
|
||||
'heading' => 'Integrations health',
|
||||
'help' => 'Operational snapshot of Paddle/RevenueCat webhooks, queue backlog, and recent failures.',
|
||||
'configured' => 'Configured',
|
||||
'unconfigured' => 'Unconfigured',
|
||||
'last_received' => 'Last received',
|
||||
'last_processed' => 'Last processed',
|
||||
'processing_lag' => 'Processing lag',
|
||||
'pending_events' => 'Pending events',
|
||||
'recent_failures' => 'Failures (24h)',
|
||||
'queue_backlog' => 'Queue backlog',
|
||||
'failed_jobs' => 'Failed jobs',
|
||||
'last_error' => 'Last error',
|
||||
'empty' => 'No integration health data available yet.',
|
||||
],
|
||||
'guest_policy' => [
|
||||
'navigation' => [
|
||||
'label' => 'Guest policy',
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@php
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
@endphp
|
||||
|
||||
<x-filament-panels::page>
|
||||
<x-filament::section :icon="Heroicon::InformationCircle">
|
||||
{{ __('admin.integrations_health.help') }}
|
||||
</x-filament::section>
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,77 @@
|
||||
<x-filament-widgets::widget>
|
||||
<x-filament::section heading="{{ __('admin.integrations_health.heading') }}">
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
@forelse($providers as $provider)
|
||||
<div class="rounded-2xl border border-slate-200/70 bg-white/80 p-4 shadow-sm dark:border-white/10 dark:bg-slate-900/60">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-slate-700 dark:text-slate-100">{{ $provider['label'] }}</p>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-400">
|
||||
{{ $provider['config_label'] }}:
|
||||
<span class="font-semibold {{ $provider['is_configured'] ? 'text-emerald-600 dark:text-emerald-400' : 'text-rose-600 dark:text-rose-400' }}">
|
||||
{{ $provider['is_configured'] ? __('admin.integrations_health.configured') : __('admin.integrations_health.unconfigured') }}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<span @class([
|
||||
'rounded-full px-3 py-1 text-xs font-semibold',
|
||||
'bg-emerald-100 text-emerald-800' => $provider['status'] === 'healthy',
|
||||
'bg-amber-100 text-amber-800' => $provider['status'] === 'pending',
|
||||
'bg-rose-100 text-rose-800' => in_array($provider['status'], ['degraded', 'unconfigured']),
|
||||
'bg-slate-100 text-slate-600' => $provider['status'] === 'unknown',
|
||||
])>
|
||||
{{ $provider['status_label'] }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid gap-2 text-xs text-slate-600 dark:text-slate-300">
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.last_received') }}</span>
|
||||
<span class="font-semibold">
|
||||
{{ optional(data_get($provider, 'last_event.received_at'))->diffForHumans() ?? '—' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.last_processed') }}</span>
|
||||
<span class="font-semibold">
|
||||
{{ optional(data_get($provider, 'last_processed.processed_at'))->diffForHumans() ?? '—' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.processing_lag') }}</span>
|
||||
<span class="font-semibold">
|
||||
{{ $provider['processing_lag']['label'] ?? '—' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.pending_events') }}</span>
|
||||
<span class="font-semibold">{{ number_format($provider['pending_count']) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.recent_failures') }}</span>
|
||||
<span class="font-semibold">{{ number_format($provider['recent_failures']) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.queue_backlog') }}</span>
|
||||
<span class="font-semibold">{{ number_format($provider['queue_backlog']) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ __('admin.integrations_health.failed_jobs') }}</span>
|
||||
<span class="font-semibold">{{ number_format($provider['failed_jobs']) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(! empty(data_get($provider, 'last_failed.error_message')))
|
||||
<div class="mt-3 rounded-lg bg-rose-50 px-3 py-2 text-xs text-rose-700 dark:bg-rose-900/30 dark:text-rose-200">
|
||||
{{ __('admin.integrations_health.last_error') }}: {{ data_get($provider, 'last_failed.error_message') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-slate-500 dark:text-slate-300">
|
||||
{{ __('admin.integrations_health.empty') }}
|
||||
</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</x-filament::section>
|
||||
</x-filament-widgets::widget>
|
||||
Reference in New Issue
Block a user