unauthorized($response, $message); }; // Helper to create admin-only error response $adminOnly = function (ServerRequestInterface $request) use ($unauthorized): ?ResponseInterface { $auth = $request->getAttribute('auth'); if (!$auth || $auth['type'] !== 'platform_admin') { return $unauthorized('Platform admin access required'); } return null; }; // Helper to create tenant-only error response $tenantOnly = function (ServerRequestInterface $request) use ($unauthorized): ?ResponseInterface { $auth = $request->getAttribute('auth'); if (!$auth || $auth['type'] !== 'user') { return $unauthorized('Tenant user access required'); } return null; }; // ========================================== // PUBLIC ROUTES (no auth required) // ========================================== // Health check $app->get('/api/health', function (ServerRequestInterface $request, ResponseInterface $response) { return \App\Support\Response::json($response, ['status' => 'ok', 'timestamp' => date('c')]); }); // Auth routes $app->post('/api/auth/login', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->login($request, $response); }); $app->post('/api/auth/register', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->register($request, $response); }); $app->post('/api/auth/verify-email', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->verifyEmail($request, $response); }); $app->post('/api/auth/forgot-password', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->forgotPassword($request, $response); }); // ========================================== // AUTHENTICATED ROUTES // ========================================== $app->add(function (ServerRequestInterface $request, RequestHandlerInterface $handler) use ($authMiddleware) { return $authMiddleware($request, $handler); }); // Auth (requires auth) $app->post('/api/auth/logout', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->logout($request, $response); }); $app->post('/api/auth/refresh', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->refresh($request, $response); }); $app->get('/api/auth/me', function (ServerRequestInterface $request, ResponseInterface $response) use ($authController) { return $authController->me($request, $response); }); // ========================================== // PLATFORM ADMIN ROUTES // ========================================== $app->group('/api/admin', function (\Slim\Routing\RouteCollectorProxy $group) use ($adminController, $adminOnly) { // Tenants $group->get('/tenants', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->listTenants($request, $response); }); $group->post('/tenants', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->createTenant($request, $response); }); $group->get('/tenants/{id}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->getTenant($request, $response, $args); }); $group->put('/tenants/{id}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->updateTenant($request, $response, $args); }); $group->delete('/tenants/{id}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->deleteTenant($request, $response, $args); }); $group->post('/tenants/{id}/approve', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->approveTenant($request, $response, $args); }); $group->post('/tenants/{id}/suspend', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->suspendTenant($request, $response, $args); }); // Tenant Modules $group->get('/tenants/{id}/modules', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->getTenantModules($request, $response, $args); }); $group->post('/tenants/{id}/modules', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->enableTenantModule($request, $response, $args); }); $group->delete('/tenants/{id}/modules/{moduleId}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->disableTenantModule($request, $response, $args); }); // Platform Modules $group->get('/platform-modules', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->listPlatformModules($request, $response); }); // Audit Logs $group->get('/audit-logs', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->listAuditLogs($request, $response); }); // Invoices $group->get('/invoices', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->listInvoices($request, $response); }); $group->put('/invoices/{id}/mark-paid', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->markInvoicePaid($request, $response, $args); }); // Platform Admins $group->get('/platform-admins', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->listPlatformAdmins($request, $response); }); $group->post('/platform-admins', function (ServerRequestInterface $request, ResponseInterface $response) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->createPlatformAdmin($request, $response); }); $group->put('/platform-admins/{id}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->updatePlatformAdmin($request, $response, $args); }); $group->delete('/platform-admins/{id}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) use ($adminController, $adminOnly) { if ($err = $adminOnly($request)) return $err; return $adminController->deletePlatformAdmin($request, $response, $args); }); }); // ========================================== // TENANT ROUTES (authenticated tenant users) // ========================================== $app->group('/api', function (\Slim\Routing\RouteCollectorProxy $group) use ($tenantOnly) { // These routes need tenant user auth - placeholder for now // Will be implemented in tenant routes file }); // Catch-all for API (404) $app->any('/api/{path:.*}', function (ServerRequestInterface $request, ResponseInterface $response) { return \App\Support\Response::notFound($response, 'API endpoint not found'); });