from starlette.middleware.base import BaseHTTPMiddleware from starlette.responses import JSONResponse from services.config_service import ConfigService # Paths that are always accessible, even when DB is not configured _ALLOWED_PREFIXES = ("/api/setup", "/docs", "/openapi", "/redoc") class ConfigGuardMiddleware(BaseHTTPMiddleware): """Return 503 for all business routes when the database is not configured.""" async def dispatch(self, request, call_next): path = request.url.path # Always allow: setup routes, root, docs, OPTIONS (CORS preflight) if path == "/" or request.method == "OPTIONS": return await call_next(request) for prefix in _ALLOWED_PREFIXES: if path.startswith(prefix): return await call_next(request) if not ConfigService.is_db_configured(): return JSONResponse( status_code=503, content={ "error_code": "SERVICE_NOT_CONFIGURED", "detail": "数据库未配置,请先完成系统初始化", }, ) return await call_next(request)