@extends('layouts.app') @section('title', __('ui.admin_health_title').' — Coaster World') @section('content')
@include('admin._nav')
{{ __('ui.admin_health_kicker') }}

{{ __('ui.admin_health_title') }}

{{ __('ui.admin_health_intro') }}

{{ __('ui.admin_health_overall') }} {{ __('ui.admin_health_state_'.$overall['state']) }} @if($overall['reasons'] !== []) {{ __('ui.admin_health_overall_cause', ['items'=>implode(' · ', $overall['reasons'])]) }} @elseif($overall['state'] === 'healthy') {{ __('ui.admin_health_overall_ok') }} @else {{ __('ui.admin_health_overall_unknown') }} @endif
{{ __('ui.admin_health_sources_kicker') }}

{{ __('ui.admin_health_sources_title') }}

{{ __('ui.admin_health_sources_help') }}

@foreach($sources as $source)
{{ $source['label'] }}
{{ __('ui.admin_health_state_'.($source['probe']['status'] ?? 'unknown')) }}
{{ __('ui.admin_health_references') }}{{ $source['references'] }}
{{ __('ui.admin_health_last_data') }}{{ $source['last_seen_at']?->diffForHumans() ?? '—' }}
{{ __('ui.admin_health_latency') }}{{ isset($source['probe']['latency_ms']) ? $source['probe']['latency_ms'].' ms' : '—' }}
HTTP{{ $source['probe']['http_status'] ?? '—' }}
{{ isset($source['probe']['checked_at']) ? __('ui.admin_health_last_probe', ['time'=>\Carbon\CarbonImmutable::parse($source['probe']['checked_at'])->diffForHumans()]) : __('ui.admin_health_never_tested') }} @if(!empty($source['probe']['message'])){{ $source['probe']['message'] }}@else@endif
@if($source['key']==='themeparks_wiki')
@csrf
@elseif($source['key']==='openstreetmap') {{ __('ui.admin_health_open_parks') }} @elseif(in_array($source['key'], ['wikidata','coasterpedia'], true)) {{ __('ui.admin_health_open_enrichment') }} @elseif($source['key']==='rcdb') {{ __('ui.admin_health_open_rcdb') }} @endif
@endforeach
{{ __('ui.admin_health_runtime_kicker') }}

{{ __('ui.admin_health_runtime_title') }}

⏱️
{{ __('ui.admin_health_scheduler') }}{{ __('ui.admin_health_state_'.$scheduler['state']) }}{{ $scheduler['heartbeat_at'] ? __('ui.admin_scheduler_heartbeat', ['time'=>$scheduler['heartbeat_at']->diffForHumans()]) : __('ui.admin_health_no_heartbeat') }}
🎢
{{ __('ui.admin_health_live') }}{{ __('ui.admin_health_live_summary', ['fresh'=>$live['fresh'],'expected'=>$live['expected']]) }}{{ __('ui.admin_health_live_detail_smart', ['stale'=>$live['stale'],'outside'=>$live['not_expected'],'failures'=>$live['failures']]) }}
🗄️
{{ __('ui.admin_health_database') }}{{ $migrations['pending_count'] }} {{ __('ui.admin_health_pending_migrations') }}{{ $migrations['pending_count'] ? __('ui.admin_health_migrate_required') : __('ui.admin_health_database_ok') }}
🧠
{{ __('ui.admin_health_enrichment') }}{{ __('ui.admin_health_state_'.$enrichment['state']) }}{{ __('ui.admin_health_enrichment_detail_smart', ['success'=>$enrichment['recent_success'],'errors'=>$enrichment['recent_errors'],'rate'=>$enrichment['issue_rate']]) }}
@if($migrations['pending_count'] > 0)
⚠️
{{ __('ui.admin_health_migration_alert_title') }}

{{ __('ui.admin_health_migration_alert_text') }}

php artisan migrate
@foreach($migrations['pending'] as $migration){{ $migration }}@endforeach
@endif
{{ __('ui.admin_health_errors_kicker') }}

{{ __('ui.admin_health_errors_title') }}

@if($recentErrors === [])
{{ __('ui.admin_health_no_errors_title') }}

{{ __('ui.admin_health_no_errors_text') }}

@else
@foreach($recentErrors as $error)
{{ strtoupper($error['kind']) }}
{{ $error['title'] }}

{{ \Illuminate\Support\Str::limit($error['message'], 260) }}

@endforeach
@endif
{{ __('ui.admin_health_commands_kicker') }}

{{ __('ui.admin_health_commands_title') }}

{{ __('ui.admin_health_commands_help') }}

php artisan migrate:status php artisan cw:live:sync --all --active php artisan cw:map:sync-osm-pois --all --limit=20 php artisan cw:catalog:auto-enrich --limit=3
@endsection