Files
wevads-platform/scripts/api_api-gateway.php
2026-02-26 04:53:11 +01:00

433 lines
14 KiB
PHP
Executable File

<?php
error_reporting(0);
/**
* 🚪 API GATEWAY - Point d'entrée unique
define("60", 60);
* Version: 1.0 - Février 2026
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/db-connect.php';
class ApiGateway {
private $db;
private $rateLimit = [];
private $modules = [
'mind' => 'Weval Mind Core',
'hamid' => 'HAMID IA Engine',
'brain' => 'Brain Engine',
'perception' => 'Perception Module',
'diagnostic' => 'Diagnostic Module',
'planning' => 'Planning Module',
'execution' => 'Execution Module',
'learning' => 'Learning Module',
'surgeon' => 'Auto-Surgeon',
'reputation' => 'Reputation Monitor',
'alert' => 'Alert System'
];
public function __construct() {
$this->db = getDB();
$this->initRateLimiting();
}
/**
* Initialize rate limiting
*/
private function initRateLimiting() {
$clientIp = $this->getClientIp();
$minute = date('Y-m-d H:i');
// Simple in-memory rate limiting (for demo)
// In production, use Redis or database
$this->rateLimit[$clientIp][$minute] =
($this->rateLimit[$clientIp][$minute] ?? 0) + 1;
}
/**
* Check rate limiting
*/
private function checkRateLimit($clientIp) {
$minute = date('Y-m-d H:i');
$requests = $this->rateLimit[$clientIp][$minute] ?? 0;
if ($requests > 60) {
logMessage('WARNING', 'API Gateway', 'Rate limit exceeded', [
'ip' => $clientIp,
'requests' => $requests
]);
return false;
}
return true;
}
/**
* Get client IP
*/
private function getClientIp() {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ??
$_SERVER['HTTP_CLIENT_IP'] ??
$_SERVER['REMOTE_ADDR'] ??
'0.0.0.0';
return $ip;
}
/**
* Authenticate request
*/
private function authenticate() {
// Check for API key in headers
$apiKey = $_SERVER['HTTP_X_API_KEY'] ??
$_GET['api_key'] ??
$_POST['api_key'] ??
null;
// Check for session (if coming from Arsenal frontend)
$sessionId = $_COOKIE['arsenal_session'] ?? null;
// For now, allow all requests (in production, implement proper auth)
return true;
}
/**
* Route request to appropriate module
*/
private function routeRequest($module, $action, $data) {
switch ($module) {
case 'mind':
return $this->routeToMind($action, $data);
case 'hamid':
return $this->routeToHamid($action, $data);
case 'status':
return $this->getSystemStatus();
case 'health':
return $this->healthCheck();
default:
return [
'error' => 'Module not found',
'available_modules' => array_keys($this->modules)
];
}
}
/**
* Route to Weval Mind
*/
private function routeToMind($action, $data) {
// For now, redirect to existing simple API
// Later, this will call the full Weval Mind Core
$validActions = ['autonomous_cycle', 'status', 'emergency', 'diagnose', 'report'];
if (!in_array($action, $validActions)) {
return [
'error' => 'Invalid action for mind module',
'valid_actions' => $validActions
];
}
// Call the simple API we already have
if ($action === 'autonomous_cycle') {
$result = $this->callSimpleApi('weval-mind-core-simple.php', [
'action' => 'autonomous_cycle'
]);
// Log the cycle
if (isset($result['cycle_id'])) {
$this->logCycle($result);
}
return $result;
}
return [
'module' => 'mind',
'action' => $action,
'status' => 'processing',
'message' => 'Action queued for execution'
];
}
/**
* Route to HAMID IA
*/
private function routeToHamid($action, $data) {
$validActions = ['chat', 'providers', 'stats', 'kb_search', 'kb_add'];
if (!in_array($action, $validActions)) {
return [
'error' => 'Invalid action for hamid module',
'valid_actions' => $validActions
];
}
if ($action === 'chat') {
if (empty($data['message'])) {
return ['error' => 'Message is required for chat action'];
}
// For now, use the simple interface
// Later, this will call the full HAMID Engine
return [
'response' => "HAMID IA Engine is under construction. Your message: " .
htmlspecialchars(substr($data['message'], 0, 100)),
'provider' => 'gateway',
'action' => 'chat',
'note' => 'Full HAMID Engine coming soon'
];
}
return [
'module' => 'hamid',
'action' => $action,
'status' => 'available_soon',
'message' => 'HAMID Engine module in development'
];
}
/**
* Get system status
*/
private function getSystemStatus() {
try {
$dbHealth = $this->db->healthCheck();
// Check if services are running
$services = [
'apache' => $this->checkService('apache2'),
'postgresql' => $this->checkService('postgresql'),
'pmta' => $this->checkService('pmta')
];
// Get system metrics
$load = sys_getloadavg();
$memory = shell_exec("free -m | awk 'NR==2 {printf \"%.1f\", $3/$2*100}'");
$disk = shell_exec("df / | awk 'NR==2 {print $5}' | sed 's/%//'");
return [
'status' => 'operational',
'timestamp' => date('Y-m-d H:i:s'),
'services' => $services,
'metrics' => [
'cpu_load' => [
'1min' => $load[0] ?? 0,
'5min' => $load[1] ?? 0,
'15min' => $load[2] ?? 0
],
'memory_usage' => floatval($memory) ?: 0,
'disk_usage' => floatval($disk) ?: 0
],
'database' => $dbHealth,
'modules' => $this->modules,
'environment' => ENVIRONMENT
];
} catch (Exception $e) {
return [
'status' => 'degraded',
'error' => $e->getMessage(),
'timestamp' => date('Y-m-d H:i:s')
];
}
}
/**
* Health check
*/
private function healthCheck() {
$checks = [];
// Check database
try {
$dbCheck = $this->db->healthCheck();
$checks['database'] = [
'status' => $dbCheck['status'],
'query_count' => $dbCheck['query_count']
];
} catch (Exception $e) {
$checks['database'] = [
'status' => 'unhealthy',
'error' => $e->getMessage()
];
}
// Check services
$services = ['apache2', 'postgresql', 'pmta'];
foreach ($services as $service) {
$checks['service_' . $service] = [
'status' => $this->checkService($service) ? 'running' : 'stopped'
];
}
// Check disk space
$disk = shell_exec("df / | awk 'NR==2 {print $5}' | sed 's/%//'");
$checks['disk_space'] = [
'usage_percent' => floatval($disk) ?: 0,
'status' => (floatval($disk) > 85) ? 'warning' : 'healthy'
];
// Determine overall status
$overall = 'healthy';
foreach ($checks as $check) {
if (isset($check['status']) && $check['status'] === 'unhealthy') {
$overall = 'unhealthy';
break;
}
if (isset($check['status']) && $check['status'] === 'warning') {
$overall = 'warning';
}
}
return [
'status' => $overall,
'checks' => $checks,
'timestamp' => date('Y-m-d H:i:s'),
'uptime' => shell_exec("uptime -p 2>/dev/null || echo 'unknown'")
];
}
/**
* Call simple API
*/
private function callSimpleApi($endpoint, $params = []) {
$url = "http://localhost:5890/api/$endpoint";
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
$response = @file_get_contents($url);
if ($response === false) {
return ['error' => 'Failed to call API endpoint: ' . $endpoint];
}
$data = json_decode($response, true);
return $data ?: ['error' => 'Invalid JSON response'];
}
/**
* Check if service is running
*/
private function checkService($service) {
$status = @shell_exec("systemctl is-active $service 2>/dev/null");
return trim($status) === 'active';
}
/**
* Log cycle to database
*/
private function logCycle($cycleData) {
try {
$cycleId = $this->db->insert('mind_cycles', [
'cycle_uuid' => $cycleData['cycle_id'] ?? 'CYCLE-' . uniqid(),
'trigger_type' => 'api_gateway',
'started_at' => $cycleData['timestamp'] ?? date('Y-m-d H:i:s'),
'ended_at' => date('Y-m-d H:i:s'),
'status' => 'completed',
'health_score' => 95, // Default for now
'issues_found' => 0,
'actions_taken' => 0,
'modules_run' => ['perception'],
'result_json' => json_encode($cycleData)
]);
logMessage('INFO', 'API Gateway', 'Cycle logged to database', [
'cycle_id' => $cycleId,
'uuid' => $cycleData['cycle_id'] ?? 'unknown'
]);
} catch (Exception $e) {
logMessage('ERROR', 'API Gateway', 'Failed to log cycle: ' . $e->getMessage());
}
}
/**
* Process incoming request
*/
public function processRequest() {
try {
// Get request data
$method = $_SERVER['REQUEST_METHOD'];
$clientIp = $this->getClientIp();
// Handle preflight requests
if ($method === 'OPTIONS') {
http_response_code(200);
exit;
}
// Rate limiting
if (!$this->checkRateLimit($clientIp)) {
http_response_code(429);
echo json_encode([
'error' => 'Rate limit exceeded',
'limit' => 60 . ' requests per minute',
'retry_after' => 60
]);
exit;
}
// Authentication
if (!$this->authenticate()) {
http_response_code(401);
echo json_encode(['error' => 'Authentication required']);
exit;
}
// Get module and action
$module = $_GET['module'] ?? $_POST['module'] ?? 'status';
$action = $_GET['action'] ?? $_POST['action'] ?? 'status';
// Get request data
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$data = $_POST ?: [];
}
// Log the request
logMessage('INFO', 'API Gateway', 'Request received', [
'module' => $module,
'action' => $action,
'ip' => $clientIp,
'method' => $method
]);
// Route the request
$result = $this->routeRequest($module, $action, $data);
// Add metadata
$result['gateway'] = [
'version' => '1.0',
'timestamp' => date('Y-m-d H:i:s'),
'request_id' => 'REQ-' . uniqid()
];
// Return response
http_response_code(200);
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
logMessage('ERROR', 'API Gateway', 'Processing error: ' . $e->getMessage());
http_response_code(500);
echo json_encode([
'error' => 'Internal server error',
'message' => $e->getMessage(),
'timestamp' => date('Y-m-d H:i:s')
]);
}
}
}
// Handle request
$gateway = new ApiGateway();
$gateway->processRequest();
?>