connection_type === 'radius' ? $this->radius->testConnection($mikrotik) : $this->routerOs->testConnection($mikrotik); $mikrotik->update([ 'connection_status' => 'online', 'last_checked_at' => now(), 'last_connected_at' => now(), 'last_latency_ms' => $result['latency_ms'], 'consecutive_failures' => 0, 'router_identity' => $result['identity'] ?? null, 'router_version' => $result['version'] ?? null, 'health_details' => $result, 'next_health_check_at' => now()->addMinutes(config('nas.health.online_interval_minutes', 5)), 'last_connection_error' => null, ]); return $result; } catch (Throwable $exception) { $message = $exception instanceof \Illuminate\Validation\ValidationException ? collect($exception->errors())->flatten()->first() : $exception->getMessage(); $failures = $mikrotik->consecutive_failures + 1; $mikrotik->update([ 'connection_status' => 'offline', 'last_checked_at' => now(), 'consecutive_failures' => $failures, 'next_health_check_at' => now()->addMinutes(min( config('nas.health.offline_max_interval_minutes', 30), 2 ** min($failures, 5) )), 'health_details' => [ 'connected' => false, 'host' => $mikrotik->host, 'api_port' => $mikrotik->connection_type === 'api' ? $mikrotik->api_port : null, 'auth_port' => $mikrotik->connection_type === 'radius' ? $mikrotik->radius_auth_port : null, 'accounting_port' => $mikrotik->connection_type === 'radius' ? $mikrotik->radius_accounting_port : null, ], 'last_connection_error' => $message, ]); throw $exception; } } }