add(new CorsMiddleware()); // Global OPTIONS route for CORS preflight (must be before other routes) $app->options('/{routes:.+}', function ($request, $response) { return $response->withStatus(204); }); // Root route - redirect to docs $app->get('/', function ($request, $response) { return $response ->withHeader('Location', '/docs') ->withStatus(302); }); // Docs route - serve Swagger UI // NOTE: Saat ini PUBLIC. Jika perlu protect, tambahkan JwtMiddleware atau IpWhitelistMiddleware $app->get('/docs', function ($request, $response) { $docsPath = __DIR__ . '/docs/index.html'; if (!file_exists($docsPath)) { $response->getBody()->write('

Documentation not found

'); return $response ->withStatus(404) ->withHeader('Content-Type', 'text/html'); } $html = file_get_contents($docsPath); $response->getBody()->write($html); return $response->withHeader('Content-Type', 'text/html'); }); // Serve OpenAPI JSON // NOTE: Saat ini PUBLIC. Jika perlu protect, tambahkan middleware $app->get('/docs/openapi.json', function ($request, $response) { $openApiPath = __DIR__ . '/docs/openapi.json'; if (!file_exists($openApiPath)) { $response->getBody()->write(json_encode(['error' => 'OpenAPI spec not found'])); return $response ->withStatus(404) ->withHeader('Content-Type', 'application/json'); } $json = file_get_contents($openApiPath); $response->getBody()->write($json); return $response->withHeader('Content-Type', 'application/json'); }); // Register module routes HealthRoutes::register($app); AuthRoutes::register($app); RetribusiRoutes::register($app); SummaryRoutes::register($app); DashboardRoutes::register($app); RealtimeRoutes::register($app); // Run application $app->run();