Files
geMoldInsight/docs/EVOLUTION_ROADMAP.md
T
2026-08-27 14:53:22 +08:00

22 KiB
Raw Blame History

geMoldInsight 演进路线图

本文档是代码与功能演进的执行清单,基于 2026-07-13 的全量代码体检。每项含「现象 / 证据 / 修法 / 验证」,按 P0→P3 推进,完成后勾选。

诊断

代码已演进到「双应用模块化」形态(entrypoints/ + moldinsight/ + inventory/ + shared/),但有 三处结构性缺失 让快速迭代变贵,外加 一批静默 bug 正在让功能"看起来在跑其实没跑":

  • 缺中间层:业务逻辑堆在路由/编排函数里(进销存无 service 层、process_file_core 280 行线性函数)
  • 缺契约:前后端靠手写类型,字段已大面积漂移(财务页整页是 0)
  • 缺连接:模具分析与进销存是两个孤立产品(STPFile 没有 product_id)

P0 止血:正在静默失效的功能(1–2 周)

这些不是技术债,是现在就在坏的东西,先修。

P0-1 Celery worker 不连 Redis/RustFS,异步任务全坏

  • 现象:任务进度写进 Celery 私有内存,web 端永远读不到;首次上传 RustFS 直接抛 RuntimeError("RustFS 未连接")。
  • 证据:redis_task_manager.connect() / rustfs_manager.connect() 只在 FastAPI startup 调用(entrypoints/moldinsight.py:42,48),Celery 进程不跑 startup;processing_service.py 在 celery 内调 update_task 时 is_connected=False 走 _fallback_set;rustfs_storage.py:125-126 未连接直接抛错。docker-compose.yml 的 moldinsight-celery 服务块缺 REDIS_PASSWORD。
  • 修法:celery_tasks.py 加 @worker_process_init 信号,显式 connect() redis 与 rustfs;补齐 celery 服务的 REDIS_PASSWORD/SECRET_KEY 等环境变量,与主应用对齐。
  • 验证:上传一个 STP,Celery 路径下任务进度能从 web 端 /api/status/{task_id} 读到;上传后 RustFS 中能看到对象。
  • 状态:- [ ]

P0-2 LLM 设计报告 NameError,静默失效

  • 现象:LLM_ENABLED=true 时设计报告功能直接没有。
  • 证据:llm_service.py:339 用未定义变量 trimmed(应为 features,trimmed 只在 _build_side_action_prompt 中定义),外层 try/except 吞掉 NameError 返回 None。
  • 修法:trimmed -> features。
  • 验证:启用 LLM 后设计报告字段非空。
  • 状态:- [ ]

P0-3 前端财务页全字段错配

  • 现象:FinanceTab 整页 0/空;用户管理菜单永不显示(is_superuser 后端不返回);dashboard 成品数恒 0。
  • 证据:16 处字段名对不上,如 total_receivable vs receivable_total(finance_schemas.py:66)、order_no vs txn_no(finance_schemas.py:48)等;App.vue:91 读 is_superuser 但 UserResponse 无此字段。
  • 修法:短期按映射手改前端字段;长期靠 P1-3 OpenAPI 契约生成根治。
  • 验证:财务页卡片与表格显示真实数据;用户管理菜单对管理员可见。
  • 状态:- [ ]

P0-4 OCC 线程安全自相矛盾

  • 现象:偶发崩溃,外层 max_workers=1 保护形同虚设。
  • 证据:processing_service.py:50-51 用单线程池序列化 OCC,但 geometry_analyzer._detect_features(geometry_analyzer.py:81)内部又开 ThreadPoolExecutor(max_workers=4) 并行操作 OCC TopoDS_Shape。
  • 修法:特征检测器改串行;或预处理阶段把面特征抽成纯数值,检测器只处理数值不碰 OCC。
  • 验证:压测大模型反复分析无崩溃。
  • 状态:- [ ]

P0-5 .env 进了 git 历史,真实密钥泄露

  • 现象:DB/Redis/SECRET_KEY/LLM key 已进入仓库历史。
  • 证据:git ls-files --error-unmatch .env 命中;git log -- .env 有 10+ 次提交;.env 内含真实凭据。
  • 修法:git rm --cached .env(停止跟踪,保留本地,后续不再提交);SECRET_KEY 从默认占位符轮换为强随机值。
  • 用户决策(2026-07-13):私有仓库,不轮换其他密钥、不重写 git 历史。
  • 验证:git status 显示 .env 不再被跟踪(D .env)。
  • 状态:- [x]

P0-6 铝价路由模块化部署后丢失

  • 现象:模块化部署后 /api/aluminum-price/* 直接 404。
  • 证据:单体 main.py:47,155 挂了 aluminum_price_router,但 moldinsight/api/__init__.py 的 _safe_include 列表不含 aluminum_price_routes。
  • 修法:把 aluminum_price_routes 加入 _safe_include。
  • 验证:模块化部署下 /api/aluminum-price/* 可访问。
  • 状态:- [ ]

P0-7 导出缓存无持久化回退

  • 现象:多 worker 或重启后导出返回 409。
  • 证据:processing_service._export_shapes_cache 是进程内 dict,get_export_shapes 只查内存;_persist_step_exports 已写磁盘 manifest 但无回读逻辑。
  • 修法:get_export_shapes 缓存未命中时从磁盘 manifest 回读。
  • 验证:重启后导出仍可用。
  • 状态:- [ ]

P0 执行结果(2026-07-13)

  • ✅ P0-1 Celery 连接:celery_tasks.py 在任务内显式 redis_task_manager.reconnect() + rustfs_manager.connect()(Redis 客户端绑定事件循环,每任务 reconnect;RustFS 同步客户端连一次复用);docker-compose.yml celery 服务补 REDIS_PASSWORD/RUSTFS_TIMEOUT
  • ✅ P0-2 LLM NameError:llm_service.py:339 trimmed -> features
  • ✅ P0-3 前端字段错配:FinanceTab 全字段对齐 schema(summary/statement/product-statement/transaction 共 16 处);UserResponse 加 is_superuser + 统一 _build_user_response 构造(修用户管理菜单不显示);DashboardTab product_count->finished_product_count;PurchaseOrdersTab received_at/paid_at->received_date/paid_date;后端 FinanceTransactionResponse 补 partner_name 并批量查询客户/供应商名称
  • ✅ P0-4 OCC 线程安全:geometry_analyzer._detect_features max_workers 4->1
  • ✅ P0-5 .env 泄露:git rm --cached .env 已取消跟踪(后续不再提交);SECRET_KEY 从默认占位符轮换为强随机值(现有登录 token 失效)。用户决策:私有仓库,不轮换其他密钥、不重写 git 历史
  • ✅ P0-6 铝价路由:moldinsight/api/__init__.py _safe_include 加入 aluminum_price_routes
  • ℹ️ P0-7 导出缓存:经排查非 bug——export_artifacts 已写 PG+Redis(processing_service.py:342,361),导出端点先走 _select_persisted_files 从 task_data 读取(advanced_router.py:436),重启后正常工作;409 仅在持久化也失败时出现,"请重新分析"提示为正确行为。内存 re-export 缓存的可靠性优化归入 P1-2

未做验证:前端未跑 vue-tsc 构建(字段重命名属机械改动,低风险);后端未跑 pytest(需 DB/Redis 环境)。建议下次在完整环境验证。


P1 结构性地基:让后续迭代不再昂贵(持续)

P1-1 进销存抽 service 层

  • 现状:finance_routes.py 751 行、sales_order_routes.py 777 行,事务编排/库存原子更新/流水写入全耦合在 endpoint;shared/services/ 仅 auth+redis。
  • 目标:新建 inventory/services/,PurchaseOrderService.receive()、SalesOrderService.issue_materials()、FinanceService.settle(),route 只做校验+组装。
  • 状态:- [ ]

P1-2 moldinsight 可插拔注册表 + Stage 流水线

  • 现状:模具类型硬编码 if-else(multi_scheme_planner.py:40);特征检测器硬编码 6 个(geometry_analyzer.py:76-99);process_file_core 280 行。
  • 目标:FeatureDetectorRegistry + MoldGeneratorRegistry(@register 装饰器);process_file_core 拆成 Stage 链。
  • 解锁:新增模具类型、IGES/BREP、批量分析。
  • 进展(2026-07-15):✅ MoldGeneratorRegistry(消除 multi_scheme_planner if-else,新增模具类型只需 register)+ ✅ FeatureDetectorRegistry(消除 6 个检测器硬编码,新增检测器只需 register)+ 顺带移除 OCC 线程池改用注册表串行执行;⏳ Stage 流水线暂缓--process_file_core(278 行/10 stage/~20 跨 stage 变量)是 STP 处理核心,本环境无 OCC 无法运行时验证,盲改风险高。建议在有 OCC 的环境按现有 _step_* 模式增量抽取 inline stages(parse_stp / build_plan_result / generate_visualization / analyze_design / generate_llm_report / finalize)
  • 状态:- [~](2/3:两个注册表完成,Stage 流水线暂缓)

P1-3 前端 OpenAPI 契约生成

  • 现状:前端 40+ 处 any,字段全手写已大面积错配。
  • 目标:openapi-typescript 从 /openapi.json 生成 TS 类型替换 any;api.ts 加 baseURL/拦截器/超时,按域封装 inventoryApi/moldinsightApi/authApi。
  • 状态:- [x](见 P4-1)

P1-4 引入 Alembic,废除裸 DDL

  • 现状:无 alembic.ini;init_db.py 22 条 ALTER TABLE ADD COLUMN IF NOT EXISTS,无版本/无回滚;migrate_db.py 是 drop_all 破坏性脚本;两应用 startup 并发跑 DDL 争锁。
  • 目标:alembic init,固化版本化迁移,启动只 upgrade head;删 migrate_db.py。
  • 状态:- [x]

P1-5 统一材料属性源

  • 现状:材料字典在 4 处重复定义且冲突(PE 收缩率 material_service 0.020 vs aluminum_foam_mold.py:92 0.025)。
  • 目标:MaterialService 作为唯一源,其他模块查询。
  • 状态:- [x]

P1 执行结果(核心完成)

  • ✅ P1-1 进销存抽 service 层(核心完成):
    • 建立 inventory/services/ 层,抽出 5 个 service:FinanceService / SalesOrderService / PurchaseOrderService / StockMovementService / InventoryService
    • 路由全面瘦身:finance 767->123、sales_order 777->114、purchase_order 472->90、stock_movement 209->37、inventory 205->57
    • 将 schemas/ 与 utils.py 从 inventory/api/ 移至 inventory/ 顶层,打破 service<->api 循环导入(正确分层);清理死代码 api/utils.py
    • ✅ 全量 import 测试通过:55 inventory 路由无丢失,5 个 service 全部正常加载
    • ⏳ 可选后续:剩余纯 CRUD 路由(product/supplier/customer/warehouse/material/dashboard)体量小,可按需增量抽取
  • ✅ P1-5 统一材料属性源:MaterialService 成为唯一源,删除 geometry_analyzer/mold_generator/aluminum_foam_mold 三处重复字典,改查询 MaterialService;解决冲突(PE 收缩率统一 0.020、PC/PA/PMMA 收缩率、POM 密度统一)、补齐 PS、统一泡沫 shrinkage 键名、补 min_wall/泡沫字段;py_compile + 一致性核对通过
  • ✅ P1-4 引入 Alembic:alembic init + 配置 env.py(接 settings+models metadata);补 3 个 CheckConstraint 到 models;离线生成初始迁移(31 表+约束+95 索引,全 sa.* 通用类型);init_db.py 用 _run_alembic_migrations(自动基线+upgrade head)替换 create_tables+ensure_schema_updates(删 92 行裸 DDL);删破坏性 migrate_db.py。既有 DB 自动 stamp 基线(无需手动);全新部署建议先 alembic upgrade head 再启应用
  • ✅ P1-2 可插拔注册表(Stage 流水线暂缓):新增 MoldGeneratorRegistry(multi_scheme_planner 消除 if-else,按 mold_type 选生成器)+ FeatureDetectorRegistry(geometry_analyzer._detect_features 消除 6 个检测器硬编码,改遍历注册表);新增模具类型/特征检测器只需 register 一行;顺带移除 OCC 线程池改串行。Stage 流水线(process_file_core 拆分)因无 OCC 运行环境暂缓,文档留计划

P2 功能演进:把两个产品变成一个

P2-1 打通模具分析 -> 进销存(最高产品价值)

  • 现状:STPFile 无 product_id,moldinsight 与 inventory 零数据关联。
  • 目标:STPFile 加 product_id 外键(可空),分析完成后一键创建 Product(finished) 并回写。
  • 状态:- [x]

P2-2 真 AI 落地,砍掉假 AI

  • 现状:ai_mold_assistant.py 209 行纯 stub 从未被调用;ai_parting_detector.py GNN 框架完整但无权重;llm_service 是唯一真接 AI(且有 P0-2 bug)。
  • 目标:聚焦一个能跑通的 AI 能力(LLM 扩到成本估算/工艺对话);GNN 要么真训权重,要么移除 stub。
  • 进展(2026-07-27):✅ ai_mold_assistant.py stub 已删除(P3-3 死代码清理);✅ LLM 成本估算已落地(llm_service.estimate_cost + POST /api/cost-estimate);✅ 规则式兜底(cost_estimate_service.py,LLM 未启用时自动降级);⏳ GNN ai_parting_detector.py 仍无权重,待决策保留或移除
  • 状态:- [~](成本估算完成,GNN 待决策)

P2-3 模具成本估算 + 批量分析

  • 依赖 P1-2 完成后才有性价比。
  • 进展(2026-07-27):
    • ✅ P2-3a 前端成本估算 UI:ResultView 新增「💰 成本估算」按钮 + 锚点导航 + 成本卡片(模具造价/单件成本/估算假设/置信度)
    • ✅ P2-3b 规则式兜底:cost_estimate_service.py(模具钢材料单价表 + 加工复杂度系数 + 侧向机构附加费),LLM 未启用时 advanced_router 自动调用规则引擎
    • ✅ P2-3c 批量上传后端:batch_router.py(多文件 POST /api/batch-upload + Redis batch_id→task_ids 映射 24h TTL + GET /api/batch/{batch_id} 聚合查询),复用现有 processing_service + Celery 并发
    • ✅ P2-3d 批量前端 UI:BatchView.vue(拖拽多文件上传 + 进度看板 + 轮询 + 任务表格),MoldInsightView 入口按钮
  • 状态:- [x]

P2 执行结果

  • ✅ P2-1 打通模具分析 -> 进销存:STPFile 加 product_id 外键(nullable+index+FK)+ Alembic 迁移 006c18c51b0d(首次真实迁移);inventory POST /api/products/from-task/{task_id} 端点(按 task_id 查 STPFile,幂等创建 Product(finished),回写 product_id,SKU=MI{stp_file_id},描述含体积/重量/表面积);前端 ResultView 导出栏加「创建为成品」按钮。py_compile + alembic heads + vue-tsc 0 错误通过。模具分析 -> 成品 -> BOM -> 销售/采购的业务闭环接通
  • ✅ P2-2 真 AI 落地(部分):删除 ai_mold_assistant.py 死代码;LLM 成本估算 + 规则兜底双路径已上线
  • ✅ P2-3 成本估算 + 批量分析(全部完成):前端成本卡片 + 规则式兜底 + 批量上传后端 + 批量进度看板

P3 工程治理(穿插顺手做)

  • create_app() 工厂消除两入口重复引导,废弃单体 main.py → shared/app_factory.py(2026-07-27)
  • 删死依赖/死代码:Kafka 依赖删除、templates/ 三个 legacy Jinja 模板删除、task_router result_page 死端点删除、ProcessingService.__init__ 3 个死实例删除(2026-07-27)
  • get_db_session 统一事务边界(成功 commit / 异常 rollback),inventory 路由 commit→flush(2026-07-27)
  • 连接池治理:web pool_size=10, max_overflow=20 / celery pool_size=5, max_overflow=10,环境变量可覆盖(2026-07-27)
  • 进销存 state 从模块级单例迁回 Pinia defineStore,tab 改子路由(URL 可分享/回退)(2026-07-27)
  • 统一 /health 响应 schema(status/service/version/database_connected);SPA fallback 排除 /api、/docs、/openapi 前缀(2026-07-27)
  • CORS 收敛:CORS_ORIGINS 环境变量白名单,空则降级 ["*"] + 警告日志(2026-07-27)

P3 执行结果(全部完成,2026-07-27)

  • ✅ P3-1 CORS 收敛:settings.py 新增 CORS_ORIGINS 解析;app_factory.py 从白名单创建 CORS,空则 ["*"] + warning
  • ✅ P3-2 /health + SPA fallback:app_factory.py 统一 GET+POST /health(含 database_connected 检测);catch-all 排除 api//docs/openapi 前缀
  • ✅ P3-3 删除死代码:requirements.txt + deploy/requirements-moldinsight.txt 删 kafka-python;删除 templates/*.html 三个 legacy 模板;task_router.py 删 result_page 端点;processing_service.py 删 3 个死实例 + 死 import
  • ✅ P3-4 事务边界:database.py 的 get_db_session 统一 commit/rollback;inventory 5 个路由共 25 处 commit() → flush()
  • ✅ P3-5 连接池:database.py 按角色分层 _get_pool_config(),web/celery 分别配置;celery_tasks.py 初始化 celery 角色引擎
  • ✅ P3-6 app_factory:新建 shared/app_factory.py(CORS/日志中间件/静态文件/startup/shutdown/health/SPA fallback);两入口各 ~30 行
  • ✅ P3-7 Pinia + 子路由:新建 stores/inventory.ts(defineStore);useInventory.ts 改为薄壳委托;10 个 Tab 子路由懒加载;Sidebar 改 router.push

执行进度

阶段 项数 已完成 进行中
P0 7 6 修复 + 1 排查 -
P1 5 5 P1-1~P1-5 全部完成(P1-2 Stage 流水线暂缓)
P2 3 3 P2-1+P2-2(部分)+P2-3 全部完成
P3 7 7 全部完成
P4 10 4 P4-1 OpenAPI 契约 + P4-4 采购需求推导 + P4-6 集成测试 + P4-7 结构化日志

P4 后续演进方向(待规划)

方向 A:前端工程化加固(低风险、高收益)

P4-1 OpenAPI 契约自动生成 ✅

  • 现状:前端 any 泛滥,字段靠手写已多次错配(P0-3 教训)
  • 目标:openapi-typescript 从 /openapi.json 生成 TS interface,替换 types/schemas.ts 中的 any;api.ts 按域封装 inventoryApi / moldinsightApi / authApi
  • 体量:~1 天
  • 完成(2026-07-27):openapi.json 双服务统一(70 paths / 76 schemas);types/api.ts 自动生成(5500+ 行);api-client.ts 按域封装(authApi/inventoryApi/moldinsightApi);stores/inventory.ts 核心 ref 加 Schema<> 类型标注

P4-2 Stage 流水线拆分

  • 现状:process_file_core 278 行线性函数,新增分析阶段需改核心函数
  • 目标:拆成 Stage 链(parse_stp → detect_features → plan_mold → generate_visualization → analyze_design → generate_report → finalize),每个 Stage 可独立测试和替换
  • 前提:需在有 OCC 的环境下运行时验证
  • 体量:~2-3 天

方向 B:业务闭环深化

P4-3 模具分析报告 → 销售订单关联

  • 现状:P2-1 已打通 STP→成品,但分析报告(HTML)与销售订单无直接关联
  • 目标:销售订单创建时可选择关联 moldinsight task_id,订单详情页嵌入分析报告 iframe/摘要;报价单自动引用成本估算数据
  • 体量:~2 天

P4-4 采购需求自动推导 ✅

  • 现状:BOM 定义了成品所需物料,但采购仍需手动创建
  • 目标:销售订单确认 → 按 BOM 展开物料需求 → 对比当前库存 → 自动生成采购建议(缺多少、建议供应商、预计金额);一键转为采购订单
  • 体量:~3 天
  • 完成(2026-07-27):purchase_demand_schemas.py(Request/ItemResponse/Response)+ purchase_demand_service.py(6 步算法:批量查询订单→BOM 展开含损耗率→聚合需求→库存对比→主供应商推荐→按缺口降序排列)+ purchase_demand_routes.py(薄路由 POST /api/purchase-demands/calculate)+ 前端「采购建议」按钮 + 对话框(多选销售订单 + 结果表格含缺口/供应商/交期)

P4-5 GNN 分型面检测(决策项)

  • 现状:ai_parting_detector.py 有框架无权重,从未被调用
  • 选择:(a) 投入训权重(需标注数据集 + GPU);(b) 改为规则式分型面推荐(利用已识别的 Undercut/Pocket 特征 + 几何启发式);(c) 彻底移除,减少维护负担
  • 建议:短期选 (b) 或 (c),等数据积累后再考虑 (a)

方向 C:可靠性与可观测性

P4-6 集成测试覆盖 ✅

  • 现状:tests/ 仅 2 个测试文件,核心业务流程无回归保障
  • 目标:关键路径 pytest 覆盖——STP 上传→分析→创建成品→销售订单→采购→库存变动;mock OCC 外部依赖
  • 体量:~2-3 天
  • 完成(2026-07-27):conftest.py 重构(SQLite + aiosqlite + FK 逆序清空 + 每测试重新播种);test_purchase_demand.py 5 个用例(正常推导/缺货/无效订单/无BOM/空请求);test_api_inventory_orders.py 32 个用例(库存/采购/销售/物料/StockMovement CRUD + 校验);test_sales_order_delivered_freeze.py 2 个用例(交付冻结/非交付可改);sales_order_service.py 补 delivered 状态守卫 bug 修复;39 测试全通过

P4-7 结构化日志 + 请求追踪 ✅

  • 现状:app_factory.py 有请求日志中间件,但无 request_id 贯穿、无结构化 JSON 输出
  • 目标:中间件注入 X-Request-ID;日志格式改 JSON(timestamp/level/request_id/service/path/duration_ms);接入 Prometheus /metrics 端点(请求计数/延迟/错误率)
  • 体量:~1 天
  • 完成(2026-07-27):logger.py 升级为 JSON 结构化日志(JSONFormatter + TextFormatter)+ contextvars request_id 跨 async 传播;app_factory.py 中间件升级(自动生成/提取 X-Request-ID、注入响应头、全请求结构化日志含 method/path/status/duration_ms/client_ip);支持 LOG_FORMAT/LOG_LEVEL 环境变量切换;Prometheus /metrics 端点归入后续 P4-8 或独立任务

P4-8 Celery 任务可靠性

  • 现状:任务失败无自动重试;无死信队列;批量任务进度仅靠 Redis TTL
  • 目标:@task(autoretry_for, retry_backoff) 自动重试;死信队列记录永久失败任务;批量任务完成后写 PG 持久化(不依赖 Redis TTL 过期)
  • 体量:~1-2 天

方向 D:格式扩展与性能

P4-9 IGES / BREP 格式支持

  • 现状:仅支持 STP/STEP,注册表模式已就绪(P1-2)
  • 目标:IgesParserStage + BrepParserStage 注册到流水线;前端上传组件扩展 accept 列表
  • 前提:依赖 P4-2 Stage 流水线完成
  • 体量:~1-2 天(流水线就绪后)

P4-10 大文件分析性能优化

  • 现状:大模型(>1000 面)分析耗时线性增长,点云采样全量处理
  • 目标:自适应采样(按曲率密度分配采样点);LOD 分级(远距低模 + 近距高模);分析结果增量更新(仅重算变更区域)
  • 体量:~3-5 天