2026-09-01 18:05:18 +08:00
|
|
|
|
# geMoldInsight 架构与边界(ARCHITECTURE)
|
|
|
|
|
|
|
|
|
|
|
|
> 文档定位:**当前架构、模块边界与结构原则的权威文档**。
|
|
|
|
|
|
> 本文描述“现在的系统结构是什么、边界如何划分、目标形态是什么”;不负责维护当前实现进度,当前状态见 [STATUS.md](STATUS.md),部署见 [DEPLOYMENT.md](DEPLOYMENT.md),演进路线见 [ROADMAP.md](ROADMAP.md)。
|
|
|
|
|
|
> 如需追溯模块化设计蓝图与扩展讨论,见 [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](archive/BACKEND_MODULARIZATION_BLUEPRINT.md)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 架构目标
|
|
|
|
|
|
|
|
|
|
|
|
geMoldInsight 的目标架构不是微服务,也不是继续维持历史单体,而是:
|
|
|
|
|
|
|
|
|
|
|
|
> **单仓库 + 单数据库 + 多模块 + 可独立部署的 modular monolith**
|
|
|
|
|
|
|
|
|
|
|
|
这意味着:
|
|
|
|
|
|
|
|
|
|
|
|
- 保持同一 Git 仓库
|
|
|
|
|
|
- 保持同一 PostgreSQL 数据库
|
|
|
|
|
|
- 按模块组织业务代码与部署入口
|
|
|
|
|
|
- 在不拆库、不拆仓的前提下,明确业务边界与部署边界
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 当前模块划分
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 moldinsight
|
|
|
|
|
|
|
|
|
|
|
|
目录:
|
|
|
|
|
|
- [src/moldinsight/](../src/moldinsight/)
|
|
|
|
|
|
|
|
|
|
|
|
职责:
|
|
|
|
|
|
- STEP/STP 上传与任务管理
|
|
|
|
|
|
- 几何分析与特征识别
|
|
|
|
|
|
- 模具方案生成
|
|
|
|
|
|
- 批量分析
|
|
|
|
|
|
- 成本估算
|
|
|
|
|
|
- 导出与结果查询
|
|
|
|
|
|
- 结合 Celery 执行异步分析链路
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 inventory
|
|
|
|
|
|
|
|
|
|
|
|
目录:
|
|
|
|
|
|
- [src/inventory/](../src/inventory/)
|
|
|
|
|
|
|
|
|
|
|
|
职责:
|
|
|
|
|
|
- 成品/物料管理
|
|
|
|
|
|
- BOM 管理
|
|
|
|
|
|
- 库存与库存流水
|
|
|
|
|
|
- 采购订单 / 销售订单
|
|
|
|
|
|
- 财务与对账
|
|
|
|
|
|
- 采购建议推导
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 frontend
|
|
|
|
|
|
|
|
|
|
|
|
目录:
|
|
|
|
|
|
- [frontend/](../frontend/)
|
|
|
|
|
|
|
|
|
|
|
|
职责:
|
|
|
|
|
|
- 模具分析页面
|
|
|
|
|
|
- 进销存页面
|
|
|
|
|
|
- 登录/用户管理
|
|
|
|
|
|
- 统一路由与状态管理
|
|
|
|
|
|
- 基于 OpenAPI 类型生成的前端调用
|
|
|
|
|
|
|
|
|
|
|
|
### 2.4 shared(当前平台层)
|
|
|
|
|
|
|
|
|
|
|
|
目录:
|
|
|
|
|
|
- [src/shared/](../src/shared/)
|
|
|
|
|
|
|
|
|
|
|
|
职责:
|
|
|
|
|
|
- 配置
|
|
|
|
|
|
- 数据库连接与 session
|
|
|
|
|
|
- 认证与权限
|
|
|
|
|
|
- 日志与 request_id
|
|
|
|
|
|
- 应用工厂与共用中间件
|
|
|
|
|
|
|
|
|
|
|
|
说明:
|
2026-09-18 18:21:01 +08:00
|
|
|
|
- `shared` 的定位已明确为**平台层(跨模块基础能力)**;模块专属接线(RustFS 启动 / HTML 报告挂载 / 路由聚合)已收敛回模块层(见 §6.2),当前仓库结构仍以 `shared` 为事实名称
|
|
|
|
|
|
- 剩余语义收敛(identity 平台表 vs 模块表的命名与注释口径)随实际重构继续推进
|
2026-09-01 18:05:18 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 当前代码结构
|
|
|
|
|
|
|
|
|
|
|
|
当前核心结构如下:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
geMoldInsight/
|
|
|
|
|
|
├── src/
|
|
|
|
|
|
│ ├── entrypoints/
|
|
|
|
|
|
│ │ ├── moldinsight.py
|
|
|
|
|
|
│ │ └── inventory.py
|
|
|
|
|
|
│ ├── shared/
|
|
|
|
|
|
│ ├── moldinsight/
|
|
|
|
|
|
│ ├── inventory/
|
|
|
|
|
|
│ ├── celery_app.py
|
|
|
|
|
|
│ └── celery_tasks.py
|
|
|
|
|
|
├── frontend/
|
2026-09-16 17:55:04 +08:00
|
|
|
|
├── migrations/
|
2026-09-01 18:05:18 +08:00
|
|
|
|
├── deploy/
|
|
|
|
|
|
├── docs/
|
|
|
|
|
|
└── tests/
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
这反映的是**当前实际代码组织**,不是历史单体结构。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 部署边界
|
|
|
|
|
|
|
|
|
|
|
|
当前设计上支持三种部署模式:
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 unified
|
|
|
|
|
|
|
|
|
|
|
|
一个统一后端同时承载 moldinsight + inventory,并作为前端默认反代目标。
|
|
|
|
|
|
|
|
|
|
|
|
适合:
|
|
|
|
|
|
- 本地开发
|
|
|
|
|
|
- 集成环境
|
|
|
|
|
|
- 小团队统一部署
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 moldinsight-only
|
|
|
|
|
|
|
|
|
|
|
|
只部署模具分析后端。
|
|
|
|
|
|
|
|
|
|
|
|
适合:
|
|
|
|
|
|
- 单独开放分析能力
|
|
|
|
|
|
- 异步任务与文件处理独立扩容
|
|
|
|
|
|
|
|
|
|
|
|
入口:
|
|
|
|
|
|
- [src/entrypoints/moldinsight.py](../src/entrypoints/moldinsight.py)
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 inventory-only
|
|
|
|
|
|
|
|
|
|
|
|
只部署进销存后端。
|
|
|
|
|
|
|
|
|
|
|
|
适合:
|
|
|
|
|
|
- 独立使用 ERP / 库存能力
|
|
|
|
|
|
- 与 moldinsight 分开部署节奏
|
|
|
|
|
|
|
|
|
|
|
|
入口:
|
|
|
|
|
|
- [src/entrypoints/inventory.py](../src/entrypoints/inventory.py)
|
|
|
|
|
|
|
|
|
|
|
|
部署操作与当前推荐方案见 [DEPLOYMENT.md](DEPLOYMENT.md)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 关键架构原则
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 单数据库是刻意设计
|
|
|
|
|
|
|
|
|
|
|
|
项目不是把 moldinsight 与 inventory 强拆成两个数据库,而是保留共享数据库,以支撑完整业务闭环:
|
|
|
|
|
|
|
|
|
|
|
|
- 分析结果
|
|
|
|
|
|
- 创建成品
|
|
|
|
|
|
- 成品 BOM
|
|
|
|
|
|
- 销售 / 采购 / 库存
|
|
|
|
|
|
|
|
|
|
|
|
典型桥接关系示例:
|
|
|
|
|
|
- `STPFile.product_id -> Product.id`
|
|
|
|
|
|
|
2026-09-17 16:15:49 +08:00
|
|
|
|
桥接只允许**裸 FK 列**(字符串表名),**不允许跨模块 ORM relationship**——单模块部署下另一模块的模型类可能未注册,跨模块 relationship 会让 mapper 配置直接失败(2026-09-17 批次 4 起为硬规则,原三条跨模块 relationship 均无使用方,已删除;对象化查询由使用方显式 select)。
|
|
|
|
|
|
|
2026-09-01 18:05:18 +08:00
|
|
|
|
### 5.2 模块边界优先于“临时方便”
|
|
|
|
|
|
|
|
|
|
|
|
新增逻辑时,应优先放入对应业务模块,而不是继续堆进 `shared`。
|
|
|
|
|
|
|
|
|
|
|
|
原则上:
|
|
|
|
|
|
- moldinsight 业务进入 `src/moldinsight/`
|
|
|
|
|
|
- inventory 业务进入 `src/inventory/`
|
|
|
|
|
|
- 只有真正跨模块复用的基础能力才进入 `src/shared/`
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 前端是独立工程,不是后端静态附属
|
|
|
|
|
|
|
|
|
|
|
|
前端已是独立 Vite/Vue 工程,部署上可与后端组合,但在代码组织上应视为独立模块,而不是后端 `static/` 的扩展。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 当前主要耦合点
|
|
|
|
|
|
|
|
|
|
|
|
虽然模块化已经成型,但仍有几个关键耦合点需要持续关注:
|
|
|
|
|
|
|
2026-09-17 16:15:49 +08:00
|
|
|
|
### 6.1 共享 ORM 模型 —— 已按模块拆分(2026-09-17,批次 4)
|
|
|
|
|
|
|
|
|
|
|
|
历史上的 `shared/models/database.py`(31 个模型类三类同居)已拆除,现为按归属分置:
|
|
|
|
|
|
|
|
|
|
|
|
- [src/shared/models/base.py](../src/shared/models/base.py):唯一 `Base` + 归属约定与全量注册点说明
|
|
|
|
|
|
- [src/shared/models/identity.py](../src/shared/models/identity.py):用户/角色/权限/审计(平台层,所有部署形态共用)
|
|
|
|
|
|
- [src/moldinsight/models/](../src/moldinsight/models/):STEP 分析域 9 表(stp_files 及各阶段产物、processing_tasks)
|
|
|
|
|
|
- [src/inventory/models/](../src/inventory/models/):进销存 15 表(catalog / warehouse / trading / finance 四域文件)
|
2026-09-01 18:05:18 +08:00
|
|
|
|
|
2026-09-17 16:15:49 +08:00
|
|
|
|
跨模块只允许裸 FK(规则见 §5.1);全量模型注册点收敛为 `migrations/env.py` 与 `tests/conftest.py`;归属边界由 [tests/test_model_ownership.py](../tests/test_model_ownership.py) 锁定(含单模块独立 mapper 配置与旧模块无 facade 断言)。
|
2026-09-01 18:05:18 +08:00
|
|
|
|
|
2026-09-18 18:21:01 +08:00
|
|
|
|
### 6.2 app factory 组合职责 —— 已收敛(2026-09-18,D3 剩余)
|
2026-09-01 18:05:18 +08:00
|
|
|
|
|
2026-09-18 18:21:01 +08:00
|
|
|
|
平台层与模块专属接线的边界已明确(`shared` = 跨模块基础能力,模块专属接线归属模块层):
|
|
|
|
|
|
|
|
|
|
|
|
- **平台工厂 [src/shared/app_factory.py](../src/shared/app_factory.py) 只做纯平台引导**:CORS / 请求日志 / 目录准备 / 静态托管 / 数据库与 Redis 启动 / auth 路由 / /health / SPA fallback。`startup_hooks` 参数承载模块专属启动接线——原 `connect_rustfs` 参数(平台工厂持有 moldinsight 依赖)已移除。
|
|
|
|
|
|
- **moldinsight 专属接线收敛回 moldinsight 层**:
|
|
|
|
|
|
- RustFS 启动 → [init_storage.py](../src/moldinsight/storage/init_storage.py) 的 `rustfs_startup_hook`(moldinsight/unified 入口经 `startup_hooks` 注入)
|
|
|
|
|
|
- /api 路由聚合 + HTML 报告根路径挂载 → [moldinsight/api/__init__.py](../src/moldinsight/api/__init__.py) 的 `register_moldinsight_routers`(入口只做单点调用,不再重复 include html_report)
|
|
|
|
|
|
- **入口 [src/entrypoints/](../src/entrypoints/) 退化为纯组装**:sys.path 修正 + 调 create_app + 传 startup_hooks / register_routers。
|
2026-09-01 18:05:18 +08:00
|
|
|
|
|
|
|
|
|
|
### 6.3 文档与结构尚未完全同步
|
|
|
|
|
|
|
|
|
|
|
|
代码结构已明显模块化,但历史文档中仍保留不少阶段性叙述、旧部署语义与重复说明,这也是本轮文档整理要解决的问题之一。
|
|
|
|
|
|
|
2026-09-24 10:15:36 +08:00
|
|
|
|
### 6.4 D17 Human-in-Loop 老师傅经验反馈闭环 —— 已完成(2026-09-23~24,3 个 commit)
|
|
|
|
|
|
|
|
|
|
|
|
算法演进由老师傅经验驱动:通过方案级整体反馈(采纳 / 建议调整 / 拒绝)按"产品指纹 + 工艺参数"为键跨任务匹配,下次同指纹产品分析自动消费老师傅沉淀的经验。这是少数"算法层由用户在线学习样本持续校准"的端到端闭环。
|
|
|
|
|
|
|
|
|
|
|
|
**端到端数据流**:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 老师傅在 ResultView 点 👍 老师傅反馈按钮 │
|
|
|
|
|
|
│ → HumanFeedbackDialog 三选一(采纳 / 建议调整 / 拒绝) │
|
|
|
|
|
|
└──────────────────────────────┬──────────────────────────────┘
|
|
|
|
|
|
│ POST /api/tasks/{id}/experience-feedback
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ experience_feedback_router (src/moldinsight/api/) │
|
|
|
|
|
|
│ - ensure_task_access 归属校验 │
|
|
|
|
|
|
│ - current_user.has_permission("feedback_experience_hint") │
|
|
|
|
|
|
│ - service.record_feedback (flush; commit + invalidate) │
|
|
|
|
|
|
└──────────────────────────────┬───────────────────────────────┘
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ experience_feedback_service.record_feedback │
|
|
|
|
|
|
│ - compute_fingerprint (bbox_aspect / volume_bucket / │
|
|
|
|
|
|
│ face_bucket / undercut_class / material_family / is_foam) │
|
|
|
|
|
|
│ - 写 experience_feedback 表(D9 边界 / D17 衰减 90d TTL) │
|
|
|
|
|
|
│ - 同 stp_file_id 整体续期 expires_at │
|
|
|
|
|
|
└──────────────────────────────┬───────────────────────────────┘
|
|
|
|
|
|
│ 同 stp_file_id 上传新 STP 自动消费
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ processing_service._step_generate_cavity │
|
|
|
|
|
|
│ - experience_feedback_service.resolve_for_process_params │
|
|
|
|
|
|
│ → hints (List[{scheme_axis, weight, sample_count, ...}]) │
|
|
|
|
|
|
│ - hints 装进 run_occ payload 顶层 experience_hints │
|
|
|
|
|
|
└──────────────────────────────┬───────────────────────────────┘
|
|
|
|
|
|
│ OCC 子进程(spawn 隔离)
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ occ_worker._op_generate_cavity │
|
|
|
|
|
|
│ - payload.get("experience_hints") or {} → planner.generate_plan(hints=...) │
|
|
|
|
|
|
└──────────────────────────────┬───────────────────────────────┘
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ MultiSchemeMoldPlanner.generate_plan(..., hints=None) │
|
|
|
|
|
|
│ - candidate_generator.generate_candidates(..., hints) │
|
|
|
|
|
|
│ * priority_score += weight × 20 │
|
|
|
|
|
|
│ * sample_count ≥ 2 + weight ≥ 0.5 → method="human_experience_primary" │
|
|
|
|
|
|
│ - scheme_scorer.score_schemes(schemes, *, hints) │
|
|
|
|
|
|
│ * score_breakdown["human_hint_bonus"] = weight × 12 │
|
|
|
|
|
|
│ (sample_count < 2 时 ×0.5 折半) │
|
|
|
|
|
|
│ - global_summary.applied_hints 注入返回 │
|
|
|
|
|
|
└──────────────────────────────┬───────────────────────────────┘
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ ResultView 渲染: │
|
|
|
|
|
|
│ - summary-header 加 t-tag theme="success" 📚 历史经验 N 条 │
|
|
|
|
|
|
│ - 反馈提交后 onFeedbackSubmitted → loadExperienceHints 即刷 │
|
|
|
|
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**硬规则遵守**:
|
|
|
|
|
|
|
|
|
|
|
|
- 跨模块 FK 仍守 §5.1(`experience_feedback.user_id` / `processing_task_id` / `stp_file_id` 全用字符串表名,无 ORM relationship)
|
|
|
|
|
|
- OCC 跨进程守 [occ_worker.py:7-8](../src/moldinsight/core/occ_worker.py#L7-L8) "杜绝 pickle OCC 对象"——payload 普通 dict 透传
|
|
|
|
|
|
- D9 边界不破:service.flush + 路由 commit(无 service 内 commit)
|
|
|
|
|
|
- 现有 `init_db.py` 幂等修复:按 code 补登权限/角色
|
|
|
|
|
|
|
|
|
|
|
|
**重量级约束**:
|
|
|
|
|
|
|
|
|
|
|
|
- `weight = max(0, (adopted-rejected)/total)`:仅正向有效,老师傅拒绝不"扣分"老算法
|
|
|
|
|
|
- `sample_count < 2` 时 bonus ×0.5:信号不足折半,但 priority_score 仍加成(候选方向仍偏向)
|
|
|
|
|
|
- 解析失败回退空 list:graceful,主流程不因下游错误退化
|
|
|
|
|
|
- `canGiveFeedback` 角色门控:`is_superuser || roles 含 process_engineer`
|
|
|
|
|
|
|
|
|
|
|
|
**测试基线**:192 passed, 13 skipped(批 3 净增 +4 OCC-gated:candidate_generator 3 / scheme_scorer 4 / multi_scheme_planner 2 / processing_service 2);前端 vue-tsc + vite 通过。
|
|
|
|
|
|
|
|
|
|
|
|
详见 [TECH_DEBT.md](TECH_DEBT.md) D17 + [STATUS.md](STATUS.md) 2026-09-23~24 日志。
|
|
|
|
|
|
|
2026-09-01 18:05:18 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 专题文档与主骨架的关系
|
|
|
|
|
|
|
|
|
|
|
|
以下文档仍可作为专题补充参考,但不再承担默认入口职责:
|
|
|
|
|
|
|
|
|
|
|
|
- 存储方向:
|
|
|
|
|
|
- [topics/storage/RUSTFS_STORAGE.md](topics/storage/RUSTFS_STORAGE.md)
|
|
|
|
|
|
- [topics/storage/STORAGE_SETUP.md](topics/storage/STORAGE_SETUP.md)
|
2026-09-17 16:15:49 +08:00
|
|
|
|
- 性能方向:
|
|
|
|
|
|
- [topics/performance/OCC_THROUGHPUT.md](topics/performance/OCC_THROUGHPUT.md)(OCC 吞吐与隔离方案设计,TECH_DEBT D10 归属)
|
2026-09-02 18:18:42 +08:00
|
|
|
|
|
2026-09-17 16:15:49 +08:00
|
|
|
|
AI、铝泡沫等更偏历史设计/规划性质的专题材料已迁入 [archive/README.md](archive/README.md)。
|
2026-09-01 18:05:18 +08:00
|
|
|
|
|
|
|
|
|
|
阶段性任务清单、迁移计划、历史总结等文档会逐步迁入 [archive/README.md](archive/README.md)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 与相关文档的边界
|
|
|
|
|
|
|
|
|
|
|
|
- 想看“当前做到哪一步”:看 [STATUS.md](STATUS.md)
|
|
|
|
|
|
- 想看“后面还要往哪演进”:看 [ROADMAP.md](ROADMAP.md)
|
|
|
|
|
|
- 想看“当前有哪些活跃技术债”:看 [TECH_DEBT.md](TECH_DEBT.md)
|
2026-09-15 18:02:25 +08:00
|
|
|
|
- 想看“配置怎么给、服务怎么起”:看 [OPERATIONS.md](OPERATIONS.md)
|
|
|
|
|
|
- 想看“前后端接口契约”:看 [API_CONTRACT.md](API_CONTRACT.md)
|
2026-09-01 18:05:18 +08:00
|
|
|
|
- 想看“怎么部署”:看 [DEPLOYMENT.md](DEPLOYMENT.md)
|
|
|
|
|
|
- 想看“模块化蓝图与更完整设计讨论”:看 [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|