from fastapi import APIRouter import importlib from shared.config.settings import settings from shared.utils.logger import get_logger from moldinsight.api.route_registry import route_load_status from moldinsight.api.html_report_router import include_into as include_html_report logger = get_logger(__name__) router = APIRouter() # 业务路由装载清单:新增路由必须登记于此。 # 失败语义(原 _safe_include 仅 WARNING 跳过,进程带病启动不可感知): # - 非 DEBUG:记录进 route_load_status["failed"],/api/health 呈现 degraded # - DEBUG:直接抛错 fail fast——开发环境路由缺失必须当场暴露 ROUTE_MODULES = [ # (label, module_path, debug_only) ("健康检查", "moldinsight.api.health_router", False), ("上传", "moldinsight.api.upload_router", False), ("批量", "moldinsight.api.batch_router", False), ("任务", "moldinsight.api.task_router", False), ("历史", "moldinsight.api.history_router", False), ("CAM", "moldinsight.api.cam_router", False), ("设计", "moldinsight.api.design_router", False), ("成本", "moldinsight.api.cost_router", False), ("加工", "moldinsight.api.machining_router", False), ("导出", "moldinsight.api.export_router", False), ("铝价", "moldinsight.api.aluminum_price_routes", False), ("老师傅经验反馈", "moldinsight.api.experience_feedback_router", False), # D17 Human-in-Loop # 调试端点会 dump 全量任务数据,仅 DEBUG 模式注册(双重防线:还需登录) ("调试", "moldinsight.api.debug_router", True), ] def _safe_include(label: str, module_path: str, debug_only: bool = False): if debug_only and not settings.DEBUG: route_load_status["disabled"].append({"label": label, "module": module_path}) return try: module = importlib.import_module(module_path) router_obj = getattr(module, "router", None) if router_obj is None: raise ValueError("未找到 router 对象") router.include_router(router_obj) route_load_status["loaded"].append({"label": label, "module": module_path}) logger.info(f"{label} 路由加载成功") except Exception as exc: route_load_status["failed"].append( {"label": label, "module": module_path, "error": str(exc)} ) logger.error(f"{label} 路由加载失败: {exc}") if settings.DEBUG: raise for _label, _module_path, _debug_only in ROUTE_MODULES: _safe_include(_label, _module_path, _debug_only) def register_moldinsight_routers(app): """注册 moldinsight 全部业务路由到 app(D3 收敛:入口侧单点调用)。 - /api 聚合路由:各子路由模块装载失败经 ROUTE_MODULES/route_load_status 呈现 (/api/health degraded,DEBUG fail-fast),见 _safe_include - HTML 报告代理挂根路径 /html/{filename}(URL 形状与原 StaticFiles 一致), 失败同样登记 route_load_status(html_report_router.include_into) """ app.include_router(router, prefix="/api") include_html_report(app)