date('Y-m-d H:i:s'), 'loaded_env_file' => $loadedEnvPath, 'env_check' => [ 'REDIS_HOST' => getenv('REDIS_HOST') ?: '❌ Not Set', 'REDIS_PORT' => getenv('REDIS_PORT') ?: '❌ Not Set', 'NABEH_AUTH_URL' => getenv('NABEH_AUTH_URL') ? '✅ ' . getenv('NABEH_AUTH_URL') : '❌ Missing', 'NABEH_SEND_URL' => getenv('NABEH_SEND_URL') ? '✅ ' . getenv('NABEH_SEND_URL') : '❌ Missing', 'NABEH_EMAIL' => getenv('NABEH_EMAIL') ? '✅ ' . substr((string)getenv('NABEH_EMAIL'), 0, 4) . '***' : '❌ Missing', 'NABEH_PASSWORD' => getenv('NABEH_PASSWORD') ? '✅ Configured (••••••)' : '❌ Missing', ], 'redis_check' => [ 'target_host' => getenv('REDIS_HOST'), 'target_port' => getenv('REDIS_PORT'), 'connected' => false, 'cached_token_found' => false, 'token_sample' => null ], 'nabeh_auth' => [ 'success' => false, 'token_acquired' => false, 'error' => null ], 'live_otp_test' => null ]; // 1. Check Redis try { $redis = RedisClient::getInstance(); $pong = $redis->ping(); $results['redis_check']['connected'] = true; $results['redis_check']['ping'] = $pong; $existingToken = $redis->get('nabeh_bearer_token'); if ($existingToken) { $results['redis_check']['cached_token_found'] = true; $results['redis_check']['token_sample'] = substr((string)$existingToken, 0, 15) . '...'; $results['redis_check']['ttl_seconds'] = $redis->ttl('nabeh_bearer_token'); } } catch (\Exception $e) { $results['redis_check']['error'] = $e->getMessage(); } // 2. Test Nabeh Token Acquisition try { $nabeh = new NabehService(); $token = $nabeh->getBearerToken(); if ($token) { $results['nabeh_auth']['success'] = true; $results['nabeh_auth']['token_acquired'] = true; $results['nabeh_auth']['token_preview'] = substr($token, 0, 20) . '...' . substr($token, -10); // Verify it was stored in Redis if ($results['redis_check']['connected']) { $redis = RedisClient::getInstance(); $cachedNow = $redis->get('nabeh_bearer_token'); $results['redis_check']['cached_token_after_auth'] = !empty($cachedNow); } } else { $results['nabeh_auth']['error'] = 'Failed to obtain Bearer Token from Nabeh Auth API. Check server logs and credentials.'; } } catch (\Exception $e) { $results['nabeh_auth']['error'] = $e->getMessage(); } // 3. Test Live OTP Send (Optional via ?phone=...) $queryParams = $request->getQueryParams(); $testPhone = $queryParams['phone'] ?? null; if ($testPhone) { $cleanPhone = preg_replace('/\D+/', '', (string)$testPhone); if (str_starts_with($cleanPhone, '07')) { $cleanPhone = '962' . substr($cleanPhone, 1); } $testOtp = (string)random_int(100000, 999999); $type = $queryParams['type'] ?? 'text'; // Fast text mode by default try { $nabeh = new NabehService(); $sendResult = $nabeh->sendOtp($cleanPhone, $testOtp, $type, 'فحص منصة صَقِل'); $results['live_otp_test'] = [ 'phone' => $cleanPhone, 'code_sent' => $testOtp, 'type_used' => $type, 'send_result' => $sendResult ]; } catch (\Exception $e) { $results['live_otp_test'] = [ 'phone' => $cleanPhone, 'error' => $e->getMessage() ]; } } else { $results['live_otp_test'] = 'To test sending an actual WhatsApp OTP, add ?phone=96279XXXXXXX&type=text to this URL'; } $response->json([ 'status' => ($results['nabeh_auth']['success'] && $results['redis_check']['connected']) ? 'success' : 'warning', 'data' => $results ]); } /** * Test Full System Health (Database, Redis, Environment) * GET /api/test/system */ public function testSystem(Request $request, Response $response): void { $loadedEnvPath = defined('LOADED_ENV_PATH') ? LOADED_ENV_PATH : 'Undefined'; $data = [ 'status' => 'healthy', 'loaded_env_file' => $loadedEnvPath, 'app' => [ 'name' => getenv('APP_NAME') ?: 'Saqel', 'url' => getenv('APP_URL') ?: 'Not Set', 'debug' => filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN), 'php_ver' => PHP_VERSION, ], 'database' => [ 'connected' => false, 'tables' => [] ], 'redis' => [ 'connected' => false, ] ]; // 1. Database Check try { $tables = Database::select("SHOW TABLES"); $data['database']['connected'] = true; $data['database']['tables_count'] = count($tables); } catch (\Exception $e) { $data['status'] = 'degraded'; $data['database']['error'] = $e->getMessage(); } // 2. Redis Check try { $redis = RedisClient::getInstance(); $data['redis']['connected'] = true; $data['redis']['ping'] = $redis->ping(); } catch (\Exception $e) { $data['status'] = 'degraded'; $data['redis']['error'] = $e->getMessage(); } $response->json($data); } }