# geMoldInsight 技术债与治理计划(TECH_DEBT) > 文档定位:**当前活跃技术债与治理计划的权威文档**。 > 本文回答“现在还有哪些重要债务、优先级如何、下一步怎么处理”;不负责维护当前实现状态,当前状态见 [STATUS.md](STATUS.md)。架构边界见 [ARCHITECTURE.md](ARCHITECTURE.md),未来路线见 [ROADMAP.md](ROADMAP.md)。 > 本文由归档文档 [archive/MOLDINSIGHT_TECH_DEBT_PLAN.md](archive/MOLDINSIGHT_TECH_DEBT_PLAN.md) 收敛整理而来,保留活跃债务与治理结论,弱化详细实施流水账。 --- ## 1. 当前技术债概览 当前最主要的技术债集中在两个区域: - **moldinsight API 与处理链路的结构收口** - **文档 / 部署 / 历史语义与当前代码现状未完全一致** 已经完成的高优先级治理不再作为持续待办反复展开,当前重点聚焦在“还没完成、且值得继续推进”的部分。 --- ## 2. 已完成的重要治理(摘要) 以下高价值治理已完成: ### 2.1 安全与权限 - debug/history 路由补鉴权 - 任务访问控制收紧 - 无主数据不再默认放行 - `/api/status/{task_id}` 补 JWT 鉴权与归属校验(原 D5,2026-09-16 清偿,见 D5 条目) - bcrypt 创建口令超 72 字节显式拒绝、验证侧截断比较;`SECRET_KEY` / `RUSTFS_*` 缺失时明确报错,代码侧弱默认移除(D14 部分,2026-09-16) ### 2.2 静默失败与可用性 - `detect-undercuts` 改为基于真实 shape 分析 - OCC 超时后重建 executor,避免全队列永久堵死 - 后台任务统一分派,补强引用与并发控制 ### 2.3 状态存储与缓存 - Redis 任务状态改为 Hash 字段级更新,兼容旧格式 - 完成态任务视图增加缓存 - 导出缓存与持久化链路收口,支持重启后再导出 ### 2.4 架构与代码清理 - 删除旧单体入口与死代码 - 设置惰性配置校验,提升可测试性 - Generator 公共接口提取完成,补充契约测试 ### 2.5 部署正确性(2026-09-16,批次 0/1) - `/api/status/{task_id}` 补鉴权与归属校验(原 D5) - 主处理链路改走 RustFS:分派入参 `stp_file_id` 化,源文件按 object_key 下载;compose 共享卷过渡兜底(原 D6) - `AUTO_MIGRATE` 开关 + 迁移脚本随镜像分发 + `alembic/`→`migrations/` 改名修复包遮蔽(原 D12) - OCC 镜像改 conda 运行时原生执行、基础镜像 tag 锁定(D13 主体);compose 关键项去弱默认(D14 部分) ### 2.6 任务一致性模型(2026-09-16,批次 2) - Redis 内存回退彻底删除,PG 为任务状态单一事实源(原 D7);批量元数据入库(`processing_tasks.batch_id`,迁移 `a3f8c2d91e47`) - 型腔生成失败任务标 failed,不再静默 completed(原 D8) - 持久化事务边界收口:数据本体分阶段原子提交、失败先回滚再置 failed(原 D9) - D11(HTML 双写双读)本批未动:正确性已由共享卷兜底,RustFS 单一来源留待后续批次 详细历史过程保留在原始技术债文档中,后续将转入归档。 --- ## 3. 当前活跃技术债 ### D1. `advanced_router` 过大,职责混杂 现状: - 导出、估算、设计/分析相关接口仍混在同一个 router 中 - 请求体仍有较多手动解析逻辑 影响: - 路由边界不清晰 - OpenAPI 可读性差 - 接口参数校验不统一 - 后续继续扩展时维护成本高 建议: - 拆分为 export / design / cost 等子路由 - 高优先级请求体改为 Pydantic 模型 优先级:**P1** ### D2. 铝价模拟数据未显式标注来源 现状: - 铝价服务返回的是模拟/参考数据,但接口层未明确表达 影响: - 容易误导前端与业务使用者,把模拟数据理解为实时行情 建议: - 响应增加 `source: "simulated"` - 前端界面同步标注“模拟/参考数据” 优先级:**P2** ### D3. shared/platform 边界仍需继续收敛 现状: - `shared` 同时承担平台基础能力与部分历史耦合职责 - 共享 ORM 与 app factory 仍是主要耦合点 影响: - 模块边界认知成本较高 - 新增逻辑容易继续堆入 shared 建议: - 继续从文档、目录语义、职责边界上推进收敛 - 在后续实际重构中优先避免把业务逻辑继续沉入 shared 优先级:**P2** ### D4. 文档现状 / 规划 / 历史混放 现状: - 文档存在部署说明重叠、计划/总结/权威文档混放 - README 承担过多职责 影响: - 新成员难以判断“哪篇才是当前有效说法” - 状态、部署、规划容易发生漂移 建议: - 建立 `STATUS / ARCHITECTURE / ROADMAP / DEPLOYMENT` 主骨架 - 历史材料迁入 `docs/archive/` 优先级:**P1** ### D5. `/api/status/{task_id}` 未鉴权(安全缺口)—— 已清偿(2026-09-16,批次 0) 修复内容(保留编号以维持 D6–D14 引用稳定): - 端点补 `Depends(get_current_active_user)`;归属校验收敛为 `TaskQueryService.ensure_task_access`,task_router 与 advanced_router 共用(advanced_router 原私有 `_ensure_task_access` 改为委托) - 语义:无 token 401、他人/无主任务 403(无主不等于公共)、任务不存在 404 - 回归测试:[tests/test_status_endpoint_auth.py](../tests/test_status_endpoint_auth.py) - 接口行为变化已同步 [API_CONTRACT.md](API_CONTRACT.md) §3.2 ~~原现状 / 影响~~:端点未挂鉴权,匿名可枚举任务号拉取完整分析视图。 ### D6. 主处理链路依赖节点本地文件路径 —— 已清偿(2026-09-16,批次 1) 修复内容(保留编号以维持引用稳定): - 分派入参收敛为 `stp_file_id`(`dispatch_processing` 与 Celery 任务签名同步变更):处理方按 PG 元数据从 RustFS 下载源文件到任务专属临时目录(保留原始文件名,下游产物命名不变),任务结束即清理([processing_service.py](../src/moldinsight/services/processing_service.py) `_materialize_source_file`) - RustFS 不可用时回退 `STPFile.file_path` 节点本地路径;compose 为 backend / celery 增加共享卷 `uploads_data` / `html_data` 作过渡兜底(HTML 产物跨容器写读同源问题一并兜住,正式修复在 D11) ~~原现状 / 影响~~:worker 直读 API 节点本地路径,双容器部署必然 `FileNotFoundError`。 ### D7. Redis 降级为进程内 dict,多副本状态不一致 —— 已清偿(2026-09-16,批次 2) 修复内容(比原建议更彻底:完全删除内存回退,而非仅限 DEBUG): - [redis_task_manager.py](../src/shared/services/redis_task_manager.py) 删除全部 `_fallback_*` 进程内存存储:Redis 不可用时写 no-op、读返回 None(Redis 仅热缓存,任务状态事实源在 PG,缓存缺失不影响正确性) - 批量元数据入库:`processing_tasks` 新增 `batch_id` 列(迁移 `a3f8c2d91e47`),`GET /api/batch/{batch_id}` 改为按列聚合查询 + `STPFile.user_id` 归属校验,删除 Redis batch key 与进程内 dict 双通道 - `TaskQueryService` 的 PG 组装视图补 `progress` / `current_step`(Redis 不可用时前端轮询仍能看到进度);batch 聚合响应同步补 `current_step` ~~原现状 / 影响~~:Redis 故障时状态静默降级各进程内存,多副本互不可见、同任务不同副本读到不同状态。 ### D8. 型腔生成失败被静默标记为 completed —— 已清偿(2026-09-16,批次 2) 修复内容: - [processing_service.py](../src/moldinsight/services/processing_service.py) `_step_generate_cavity` 不再吞异常:分模失败直接向编排层传播 → 任务 failed(error_message 说明型腔阶段失败);已提交的几何/网格数据保留,用户可凭失败原因重新分析 - 未采用 `completed_with_fallback`:多一个状态值会扩散到前端所有状态分支,failed + 明确错误更诚实且成本低 ~~原现状 / 影响~~:型腔失败被吞掉继续主流程,最终 completed,"完成"状态不可信。 ### D9. 持久化事务边界破碎 —— 已清偿(2026-09-16,批次 2) 修复内容(进度可见性与原子性折中设计): - **数据本体写方法只 flush 不 commit**:`save_stp_file` / `save_geometry_data` / `save_mesh_data` / `save_mold_cavity_data` / `save_html_file` / `save_features_and_recommendations` / `update_task_parameters` / `update_stp_file_analysis_summary` / `_save_analysis_metrics` / `_save_verification_metrics` - **编排层分阶段收口**([processing_service.py](../src/moldinsight/services/processing_service.py)):阶段 A = 几何+网格(解析后确定成果,原子提交);阶段 B = 型腔+HTML+特征+指标+摘要+验证(结果包原子提交);完成时先 flush 任务参数、完成状态提交时一并落库(completed 即完整) - **失败路径先 rollback 再置 failed**:未提交半成品回滚,失败状态单独提交,不出现"completed 但数据残缺" - **保留即时 commit**:`update_task_status` / `update_stp_file_status`(处理中进度需跨事务对外可见,分钟级长任务不能憋在一个大事务里) - 调用方补显式 commit:upload_router / batch_router(分派前置事务,STPFile + ProcessingTask 原子,消除孤儿文件记录)、advanced_router 导出两处 ~~原现状 / 影响~~:各存储方法内部自行 commit,型腔保存失败留半成品数据且任务仍 completed。 ### D10. OCC 全局单线程串行 + 超时重建泄漏线程 现状: - 所有 OCC 操作经 `max_workers=1` executor 串行([processing_service.py](../src/moldinsight/services/processing_service.py)),celery 并发无法扩展 OCC 吞吐 - 超时重建 executor 每次泄漏 1 个线程,长期运行只涨不降 影响: - 一个长耗时型腔生成阻塞全部几何处理;线程随故障累积 建议: - 记录吞吐上限为已知约束;线程泄漏治理方案设计先行(见 [ROADMAP.md](ROADMAP.md) §3.1 批次 4) 优先级:**P2** ### D11. HTML 报告本地磁盘与 RustFS 双写双读 现状: - 可视化 HTML/摘要同时写本地 `html_output/`(/html 静态挂载)与 RustFS 影响: - 多副本下 /html 命中结果取决于负载均衡,跨副本文件不共享;同一份报告两套来源 建议: - 统一 RustFS 为唯一来源,本地仅作按需缓存 优先级:**P2** ### D12. 应用启动时自动执行 alembic 迁移 ### D12. 应用启动时自动执行 alembic 迁移 —— 已清偿(2026-09-16,批次 1) 修复内容: - 新增 `AUTO_MIGRATE` 开关(settings / .env.example / compose 透传):默认 `true` 保持单机开发行为;多副本部署设 `false`,由部署流程单点执行 alembic CLI 或 `python -m shared.database.init_db` - **连带发现并修复两个使自动迁移从未真正生效的缺陷**: 1. 迁移目录 `alembic/` 与 alembic 包重名——应用内 `import alembic` 命中本地目录(namespace package)遮蔽真实包,启动期迁移异常被 `init_database` 吞掉只打日志;已改名 `migrations/`(alembic.ini `script_location` 与 4 处文档引用同步) 2. 镜像未打包迁移脚本与 alembic.ini,容器内迁移必然失败——Dockerfile.base / Dockerfile.moldinsight 已补 `COPY migrations/` + `COPY alembic.ini` ### D13. PythonOCC 镜像引入方式脆弱 + 依赖无版本锁(主体已清偿,锁文件遗留) 现状: - ~~从 conda env 拷贝 site-packages 进 python:3.12-slim~~(2026-09-16 已修正:[Dockerfile.moldinsight](../deploy/Dockerfile.moldinsight) 改为 conda 运行时原生执行,不再跨镜像拷贝;基础镜像 tag 锁定 `continuumio/miniconda3:24.7.1-0`、`python:3.12-slim-bookworm`;tag 可用性随下次镜像构建验证) - [requirements.txt](../requirements.txt) 全部为 `>=` 下限,无锁文件(**遗留**:首次镜像构建成功后 `pip freeze` 生成锁文件,命令已注释在 Dockerfile 内) 优先级:**P2**(剩余锁文件部分) ### D14. 配置漂移:弱默认 / 死配置 / 重复解析 现状: - ~~RUSTFS_* 弱默认~~(2026-09-16 代码侧已去除);~~compose 侧 SECRET_KEY / ADMIN_PASSWORD 弱默认~~(2026-09-16 已去除:改用 `${VAR:?}` 强制显式配置,`create_admin_user` 对空 ADMIN_PASSWORD 显式报错) - MAX_FILE_SIZE 配置项未被使用([file_handler.py](../src/shared/utils/file_handler.py) 硬编码 50MB) - [celery_app.py](../src/celery_app.py) 重新 load_dotenv 并手拼 REDIS URL,与 settings 两份实现 影响: - 违背"关键项不兜底"硬约束;配置行为与文档不一致 建议: - 去掉弱默认、对齐或删除死配置、celery_app 复用 settings 优先级:**P2** --- ## 4. 当前推荐治理顺序 > 注:2026-09-15 后端设计审查后,治理**执行顺序**以 [ROADMAP.md](ROADMAP.md) §3.1 批次计划为准(批次 0–4);D5–D14 的批次归属见该表。本节保留原有优先项作为补充说明。 ### 第一优先级 1. `advanced_router` 拆分 2. 高优先级接口补 Pydantic 请求模型 3. 文档主骨架收口并减少重复说明 ### 第二优先级 4. 铝价模拟数据来源显式化 5. 部署历史文档归档 6. shared/platform 语义继续收敛 --- ## 5. 治理原则 ### 5.1 先收口接口与边界,再做更大结构调整 当前最值得继续投入的,不是大规模目录重写,而是: - 先把接口边界、文档边界、部署边界收清楚 - 再逐步推进 shared/platform 的后续调整 ### 5.2 优先做“降低长期维护成本”的改动 优先处理: - 重复逻辑 - 模糊边界 - 静态契约缺失 - 文档漂移风险 ### 5.3 已解决问题不再长期占据主文档中心 已经完成且稳定的问题,只在本文保留摘要结论;详细实施流水账后续归档,不继续作为主文档主体。 --- ## 6. 与相关文档的边界 - 当前项目状态:看 [STATUS.md](STATUS.md) - 当前架构与模块边界:看 [ARCHITECTURE.md](ARCHITECTURE.md) - 后续演进路线:看 [ROADMAP.md](ROADMAP.md) - 部署主题入口:看 [DEPLOYMENT.md](DEPLOYMENT.md) - 原始 moldinsight 细粒度债务记录:看 [archive/MOLDINSIGHT_TECH_DEBT_PLAN.md](archive/MOLDINSIGHT_TECH_DEBT_PLAN.md)