153 lines
7.3 KiB
PHP
153 lines
7.3 KiB
PHP
<?php
|
|
/**
|
|
* Nabeh API Front Controller
|
|
* Single entry point handling routing and application bootstrap.
|
|
*/
|
|
|
|
// 1. Boot the application (autoloader, env, errors)
|
|
require_once dirname(__DIR__) . '/app/bootstrap.php';
|
|
|
|
use App\Core\Request;
|
|
use App\Core\Response;
|
|
use App\Core\Router;
|
|
|
|
// 2. Initialize request and response objects
|
|
$request = new Request();
|
|
$response = new Response();
|
|
$router = new Router();
|
|
|
|
// 3. Define Global Middleware
|
|
$router->use(\App\Middlewares\SecurityMiddleware::class);
|
|
|
|
// 4. Define API Routes
|
|
// Serve index.html dashboard on root path
|
|
$router->get('/', function ($request, $response) {
|
|
$response->setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
$response->sendHeaders();
|
|
readfile(__DIR__ . '/index.html');
|
|
exit;
|
|
});
|
|
|
|
// Health Check — no php_version or environment in production to avoid info disclosure
|
|
$router->get('/api/health', function ($request, $response) {
|
|
$response->json([
|
|
'status' => 'success',
|
|
'message' => 'Nabeh API is healthy',
|
|
'app_name' => getenv('APP_NAME') ?: 'Nabeh',
|
|
'time' => date('Y-m-d H:i:s')
|
|
]);
|
|
});
|
|
|
|
// Authentication Routes (Rate-limited: 5 attempts per 60 seconds per IP)
|
|
$router->post('/api/auth/register', [\App\Controllers\AuthController::class, 'register'], [\App\Middlewares\RateLimitMiddleware::class]);
|
|
$router->post('/api/auth/login', [\App\Controllers\AuthController::class, 'login'], [\App\Middlewares\RateLimitMiddleware::class]);
|
|
$router->get('/api/auth/me', [\App\Controllers\AuthController::class, 'me'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
// WhatsApp Gateway Routes
|
|
$router->get('/api/whatsapp/status', [\App\Controllers\WhatsAppController::class, 'status'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/whatsapp/qr', [\App\Controllers\WhatsAppController::class, 'requestQr'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/whatsapp/disconnect', [\App\Controllers\WhatsAppController::class, 'disconnect'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/whatsapp/webhook', [\App\Controllers\WhatsAppController::class, 'webhook']); // No AuthMiddleware (Protected by WEBHOOK_SECRET internally)
|
|
|
|
// Phase 4 & 5: CRM, Templates & Campaigns Routes
|
|
$router->get('/api/contacts', [\App\Controllers\ContactController::class, 'index'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/contacts', [\App\Controllers\ContactController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
$router->get('/api/groups', [\App\Controllers\GroupController::class, 'index'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/groups', [\App\Controllers\GroupController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/groups/add', [\App\Controllers\GroupController::class, 'addContact'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/groups/bulk-add', [\App\Controllers\GroupController::class, 'bulkAddContacts'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
$router->get('/api/templates', [\App\Controllers\TemplateController::class, 'index'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/templates', [\App\Controllers\TemplateController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
$router->get('/api/campaigns', [\App\Controllers\CampaignController::class, 'index'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/campaigns', [\App\Controllers\CampaignController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
$router->get('/api/chatbot/rules', [\App\Controllers\ChatbotController::class, 'index'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/chatbot/rules',[\App\Controllers\ChatbotController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/chatbot/generate-prompt-from-audio', [\App\Controllers\ChatbotController::class, 'generatePromptFromAudio'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
// Custom Integration Endpoints Routes (Phase 5)
|
|
$router->get('/api/endpoints', [\App\Controllers\EndpointController::class, 'index'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/endpoints', [\App\Controllers\EndpointController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->delete('/api/endpoints', [\App\Controllers\EndpointController::class, 'delete'], [\App\Middlewares\AuthMiddleware::class]);
|
|
|
|
// Salla Platform Integration Routes (Phase 6+)
|
|
$router->get('/api/integrations/salla/auth', [\App\Controllers\SallaController::class, 'auth']);
|
|
$router->get('/api/integrations/salla/callback', [\App\Controllers\SallaController::class, 'callback']);
|
|
$router->get('/api/integrations/salla/status', [\App\Controllers\SallaController::class, 'status'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/integrations/salla/disconnect',[\App\Controllers\SallaController::class, 'disconnect'], [\App\Middlewares\AuthMiddleware::class]);
|
|
$router->post('/api/webhooks/salla', [\App\Controllers\SallaController::class, 'webhook']);
|
|
|
|
|
|
// Mock External API for Entaleq Driver Info (Used to fetch real-time driver data)
|
|
$router->post('/api/external/driver-info', function ($request, $response) {
|
|
$body = $request->getBody();
|
|
$phone = $body['phone'] ?? '';
|
|
|
|
if (empty($phone)) {
|
|
$response->status(400)->json([
|
|
'status' => 'error',
|
|
'message' => 'Missing phone number'
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$response->json([
|
|
'status' => 'success',
|
|
'data' => [
|
|
'name' => 'أحمد الشريف',
|
|
'phone' => $phone,
|
|
'role' => 'سائق',
|
|
'status' => 'نشط',
|
|
'balance' => 75.25,
|
|
'vehicle' => 'تويوتا كامري 2023',
|
|
'trips_count' => 1420
|
|
]
|
|
]);
|
|
});
|
|
|
|
// Mock External API for Entaleq Payment Verification (Used to demo automated slip validation)
|
|
$router->post('/api/external/verify-payment', function ($request, $response) {
|
|
$body = $request->getBody();
|
|
$phone = $body['phone'] ?? '';
|
|
$transactionId = $body['transaction_id'] ?? '';
|
|
$amount = $body['amount'] ?? '';
|
|
$method = $body['method'] ?? '';
|
|
|
|
if (empty($transactionId) || empty($amount)) {
|
|
$response->status(400)->json([
|
|
'status' => 'error',
|
|
'message' => 'Missing transaction_id or amount'
|
|
]);
|
|
return;
|
|
}
|
|
|
|
// Mock validation rules:
|
|
// If transaction_id contains 'fail' or starts with '9', mock verification failure
|
|
if (strpos(strtolower($transactionId), 'fail') !== false || (is_string($transactionId) && $transactionId[0] === '9')) {
|
|
$response->json([
|
|
'status' => 'failed',
|
|
'message' => 'هذا الرقم التعريفي للعملية تم استخدامه مسبقاً أو غير صحيح'
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$response->json([
|
|
'status' => 'success',
|
|
'message' => 'Payment verified and driver balance updated',
|
|
'data' => [
|
|
'driver_phone' => $phone,
|
|
'transaction_id' => $transactionId,
|
|
'amount' => $amount,
|
|
'method' => $method,
|
|
'new_balance' => 150.00
|
|
]
|
|
]);
|
|
});
|
|
|
|
|
|
// 4. Dispatch the request
|
|
$router->dispatch($request, $response);
|