908 lines
24 KiB
Markdown
908 lines
24 KiB
Markdown
# geMoldInsight 后端模块化重构蓝图
|
||
|
||
> 目标:在**同一 Git 仓库**、**同一数据库**前提下,将当前代码结构整理为**可独立部署的多模块架构**,明确 gemold、inventory、frontend 的边界与演进路径。本文档是后续实施的权威蓝图,不是历史记录。
|
||
|
||
---
|
||
|
||
## 1. 背景与目标
|
||
|
||
当前项目已经从早期单体演进为“双应用 + 共享层”的形态:
|
||
|
||
- 业务模块:`src/moldinsight/`、`src/inventory/`
|
||
- 共享层:`src/shared/`
|
||
- 部署入口:`src/entrypoints/moldinsight.py`、`src/entrypoints/inventory.py`
|
||
- 前端工程:`frontend/`
|
||
|
||
从代码现状看,`moldinsight` 与 `inventory` 已基本无直接互引,说明模块边界已经初步形成;但同时,数据库模型、认证、配置、应用工厂等仍集中在 `shared/`,导致当前更接近“**模块化中的单体**”,而不是“**可独立部署的模块化单体**”。
|
||
|
||
本次蓝图的目标不是拆库、拆仓、微服务化,而是:
|
||
|
||
1. 保持**单仓库(monorepo)**
|
||
2. 保持**单数据库**
|
||
3. 将后端正式整理为多个模块:
|
||
- **gemold**(模具分析 / moldinsight)
|
||
- **inventory**(进销存)
|
||
- **identity / platform**(共享基础设施与认证)
|
||
4. 保持前端为**独立模块工程**,并增强其对多部署模式的兼容
|
||
5. 支持三种部署模式:
|
||
- **unified**:gemold + inventory 同时部署
|
||
- **gemold-only**:仅部署 gemold
|
||
- **inventory-only**:仅部署 inventory
|
||
|
||
---
|
||
|
||
## 2. 范围与非目标
|
||
|
||
### 2.1 本次蓝图覆盖范围
|
||
|
||
- 后端模块边界
|
||
- 共享层职责重新定义
|
||
- 单数据库下的模型归属与表所有权
|
||
- 独立部署模式设计
|
||
- 前端 API 边界强化策略
|
||
- 分阶段迁移路径
|
||
- 风险与验证方法
|
||
|
||
### 2.2 非目标
|
||
|
||
本蓝图**不包含**以下方向:
|
||
|
||
- 多 Git 仓库拆分
|
||
- 多数据库拆分
|
||
- 分布式微服务重构
|
||
- 全量 DDD 重写
|
||
- 全量前端重构
|
||
- 事件驱动或消息总线主导的跨服务通信改造
|
||
|
||
换句话说,目标架构是:
|
||
|
||
> **单仓库 + 单数据库 + 多模块 + 可独立部署的 modular monolith**
|
||
|
||
而不是微服务系统。
|
||
|
||
---
|
||
|
||
## 3. 当前架构快照
|
||
|
||
### 3.1 后端现状
|
||
|
||
当前核心目录结构如下:
|
||
|
||
```text
|
||
src/
|
||
entrypoints/
|
||
moldinsight.py
|
||
inventory.py
|
||
shared/
|
||
app_factory.py
|
||
config/
|
||
database/
|
||
models/
|
||
services/
|
||
utils/
|
||
moldinsight/
|
||
api/
|
||
core/
|
||
services/
|
||
storage/
|
||
inventory/
|
||
api/
|
||
schemas/
|
||
services/
|
||
```
|
||
|
||
其中:
|
||
|
||
- [app_factory.py](../src/shared/app_factory.py) 已统一 CORS、日志中间件、startup/shutdown、认证路由、健康检查与 SPA fallback。
|
||
- [moldinsight.py](../src/entrypoints/moldinsight.py) 与 [inventory.py](../src/entrypoints/inventory.py) 已提供独立入口。
|
||
- [database.py](../src/shared/models/database.py) 同时包含 identity、moldinsight、inventory 三类模型,是当前最强耦合点。
|
||
|
||
### 3.2 前端现状
|
||
|
||
前端已是独立 Vite/Vue 工程:
|
||
|
||
```text
|
||
frontend/
|
||
src/
|
||
modules/
|
||
moldinsight/
|
||
inventory/
|
||
login/
|
||
users/
|
||
home/
|
||
router/
|
||
shared/
|
||
stores/
|
||
types/
|
||
```
|
||
|
||
特点:
|
||
|
||
- 已按页面/业务模块组织
|
||
- 已有共享 API 层雏形:[api-client.ts](../frontend/src/shared/api-client.ts)
|
||
- 已接入 OpenAPI 生成类型:[api.ts](../frontend/src/types/api.ts)
|
||
- 当前仍有大量相对路径 `/api/...` 与 raw `fetch()` 的同源假设
|
||
|
||
### 3.3 现状判断
|
||
|
||
当前架构可概括为:
|
||
|
||
> **HTTP 入口已分离,业务代码已分组,但平台层与数据层仍共享。**
|
||
|
||
因此,它适合继续朝“可独立部署的模块化单体”演进,而不适合直接跳到微服务。
|
||
|
||
---
|
||
|
||
## 4. 目标架构:可独立部署的模块化单体
|
||
|
||
### 4.1 架构原则
|
||
|
||
目标态采用以下原则:
|
||
|
||
1. **组合优先于复制**:不同部署模式通过组合不同模块得到,而不是复制多套代码。
|
||
2. **平台与业务分离**:`platform` 只承载技术性共享能力,不继续承载业务逻辑。
|
||
3. **模块所有权清晰**:每张表、每条 API、每个服务类都应有明确归属。
|
||
4. **单数据库但显式边界**:允许共享 DB,但不允许“共享数据库 = 没有边界”。
|
||
5. **统一前端,兼容多后端部署形态**:前端继续是一套工程,通过 API client 适配 unified / split deployment。
|
||
|
||
### 4.2 架构定位
|
||
|
||
目标架构不是“多个服务各自拥有数据库”的微服务,而是:
|
||
|
||
- 同一个仓库
|
||
- 同一个数据库
|
||
- 多个模块
|
||
- 多个部署入口
|
||
- 同一套迁移历史
|
||
- 同一套共享基础设施能力
|
||
|
||
这是一种适合当前项目阶段的**治理性重构**,而不是组织级拆分。
|
||
|
||
---
|
||
|
||
## 5. 目标目录结构
|
||
|
||
以下结构是**目标态**,不要求一次性到位:
|
||
|
||
```text
|
||
src/
|
||
platform/
|
||
app/
|
||
app_factory.py
|
||
lifecycle.py
|
||
middleware/
|
||
config/
|
||
auth/
|
||
database/
|
||
engine.py
|
||
session.py
|
||
migrations/
|
||
observability/
|
||
contracts/
|
||
api/
|
||
events/
|
||
shared_kernel/
|
||
types/
|
||
exceptions/
|
||
utils/
|
||
|
||
modules/
|
||
moldinsight/
|
||
application/
|
||
services/
|
||
use_cases/
|
||
domain/
|
||
models/
|
||
policies/
|
||
repositories/
|
||
infrastructure/
|
||
persistence/
|
||
storage/
|
||
adapters/
|
||
interfaces/
|
||
api/
|
||
schemas/
|
||
module.py
|
||
|
||
inventory/
|
||
application/
|
||
services/
|
||
use_cases/
|
||
domain/
|
||
models/
|
||
policies/
|
||
repositories/
|
||
infrastructure/
|
||
persistence/
|
||
adapters/
|
||
interfaces/
|
||
api/
|
||
schemas/
|
||
module.py
|
||
|
||
identity/
|
||
application/
|
||
domain/
|
||
infrastructure/
|
||
interfaces/
|
||
module.py
|
||
|
||
compositions/
|
||
unified_app.py
|
||
gemold_app.py
|
||
inventory_app.py
|
||
|
||
legacy/
|
||
main.py
|
||
```
|
||
|
||
### 5.1 当前目录到目标目录的映射
|
||
|
||
| 当前路径 | 目标路径 | 说明 |
|
||
|---|---|---|
|
||
| `src/shared/*` | `src/platform/*` | 共享基础设施重新命名与归位 |
|
||
| `src/moldinsight/*` | `src/modules/moldinsight/*` | gemold 业务模块 |
|
||
| `src/inventory/*` | `src/modules/inventory/*` | inventory 业务模块 |
|
||
| `src/entrypoints/*` | `src/compositions/*` | 部署组合层 |
|
||
| `src/main.py` | `src/legacy/main.py` | 过渡期兼容入口 |
|
||
|
||
### 5.2 为什么要引入 `compositions/`
|
||
|
||
当前 [entrypoints/](../src/entrypoints/) 已经承担“部署入口”角色,但语义更偏“启动文件”。
|
||
|
||
引入 `compositions/` 的意义是明确:
|
||
|
||
- 它不是业务模块
|
||
- 它不是平台能力
|
||
- 它是“**按部署模式装配模块**”的组合层
|
||
|
||
例如:
|
||
|
||
- `gemold_app.py`:平台 + identity + moldinsight
|
||
- `inventory_app.py`:平台 + identity + inventory
|
||
- `unified_app.py`:平台 + identity + moldinsight + inventory
|
||
|
||
---
|
||
|
||
## 6. 模块职责边界
|
||
|
||
### 6.1 platform
|
||
|
||
`platform` 是技术共享层,只承载**跨模块公共基础设施能力**。
|
||
|
||
#### 归属范围
|
||
- app factory / middleware / 生命周期
|
||
- config
|
||
- 数据库 engine / session / Alembic 接线
|
||
- auth / JWT / 权限
|
||
- 日志 / request_id / observability
|
||
- 通用 contracts / utilities
|
||
|
||
#### 可复用现有实现
|
||
- [app_factory.py](../src/shared/app_factory.py)
|
||
- [settings.py](../src/shared/config/settings.py)
|
||
- [database.py](../src/shared/database/database.py)
|
||
- [auth_service.py](../src/shared/services/auth_service.py)
|
||
- [auth_routes.py](../src/shared/services/auth_routes.py)
|
||
|
||
#### 规则
|
||
`platform` 不得继续吸收业务规则代码,否则新的 `platform` 会变成旧的 `shared`。
|
||
|
||
---
|
||
|
||
### 6.2 moldinsight(gemold)
|
||
|
||
`moldinsight` 模块负责模具分析、几何处理和分析结果生命周期。
|
||
|
||
#### 归属范围
|
||
- 上传、任务、历史、批量分析、成本估算、CAM、分析结果
|
||
- 几何分析、特征检测、模具方案、报告
|
||
- RustFS / 对象存储接入
|
||
- Celery 异步处理链路
|
||
|
||
#### 可复用现有实现
|
||
- [moldinsight/api/__init__.py](../src/moldinsight/api/__init__.py)
|
||
- [processing_service.py](../src/moldinsight/services/processing_service.py)
|
||
- [task_query_service.py](../src/moldinsight/services/task_query_service.py)
|
||
- [moldinsight/core/](../src/moldinsight/core/)
|
||
- [celery_app.py](../src/celery_app.py)
|
||
- [celery_tasks.py](../src/celery_tasks.py)
|
||
|
||
---
|
||
|
||
### 6.3 inventory
|
||
|
||
`inventory` 模块负责 ERP / 进销存类业务流程。
|
||
|
||
#### 归属范围
|
||
- 产品、物料、供应商、客户、仓库
|
||
- 库存、库存流水
|
||
- 销售订单、采购订单、财务、采购建议
|
||
- BOM / 采购需求推导
|
||
|
||
#### 可复用现有实现
|
||
- [inventory/api/__init__.py](../src/inventory/api/__init__.py)
|
||
- [inventory_service.py](../src/inventory/services/inventory_service.py)
|
||
- [sales_order_service.py](../src/inventory/services/sales_order_service.py)
|
||
- [purchase_order_service.py](../src/inventory/services/purchase_order_service.py)
|
||
- [finance_service.py](../src/inventory/services/finance_service.py)
|
||
|
||
---
|
||
|
||
### 6.4 identity
|
||
|
||
`identity` 负责用户、角色、权限与认证授权。
|
||
|
||
#### 归属范围
|
||
- User / Role / Permission
|
||
- 登录、鉴权、管理员接口
|
||
- 统一授权能力
|
||
|
||
在物理目录上,identity 可以先靠近 platform;但逻辑上应从一开始就被视为独立边界,而不是“moldinsight 的一部分”或“inventory 的一部分”。
|
||
|
||
---
|
||
|
||
## 7. 允许的依赖方向
|
||
|
||
这是本蓝图最重要的治理规则之一。
|
||
|
||
### 7.1 依赖规则
|
||
|
||
```text
|
||
compositions -> platform
|
||
compositions -> modules/*
|
||
|
||
platform -> 不依赖业务模块
|
||
|
||
modules/*/interfaces -> modules/*/application
|
||
modules/*/application -> modules/*/domain
|
||
modules/*/infrastructure -> modules/*/domain
|
||
|
||
modules/*/interfaces -> platform
|
||
modules/*/infrastructure -> platform
|
||
```
|
||
|
||
### 7.2 跨模块约束
|
||
|
||
- `inventory` 不能直接 import `moldinsight.api` / `moldinsight.services`
|
||
- `moldinsight` 不能直接 import `inventory.api` / `inventory.services`
|
||
- `platform` 不得依赖任一业务模块
|
||
- 跨模块协作只能通过:
|
||
- 显式 contract / query service
|
||
- composition wiring
|
||
- 受控的共享数据库引用
|
||
|
||
### 7.3 当前代码与规则的差距
|
||
|
||
从代码检查看,当前 `moldinsight` 与 `inventory` 基本没有直接互引,这说明上述规则在业务代码层**已经接近成立**。
|
||
|
||
当前主要问题集中在:
|
||
|
||
- [database.py](../src/shared/models/database.py) 集中承载所有 ORM 模型
|
||
- [app_factory.py](../src/shared/app_factory.py) 同时知道通用平台逻辑与 moldinsight 专属 startup 行为
|
||
|
||
因此,后续实施的重点不是“切断业务模块互引”,而是“**把共享层与数据层的边界拉直**”。
|
||
|
||
---
|
||
|
||
## 8. 单数据库下的模型与表归属策略
|
||
|
||
### 8.1 核心原则
|
||
|
||
数据库继续保持为**一个 PostgreSQL 数据库**,但代码中的模型归属必须显式化。
|
||
|
||
也就是说:
|
||
|
||
> **数据库不拆,模型归属要拆。**
|
||
|
||
### 8.2 当前最强耦合点
|
||
|
||
当前 [database.py](../src/shared/models/database.py) 同时包含:
|
||
|
||
- identity / 平台相关模型
|
||
- moldinsight 业务模型
|
||
- inventory 业务模型
|
||
|
||
这会带来两个问题:
|
||
|
||
1. 代码层看不出模型所有权
|
||
2. 开发者更容易跨模块直接访问整套 ORM 图谱
|
||
|
||
因此,后续实施应优先将这个文件按归属拆分。
|
||
|
||
### 8.3 推荐表归属矩阵
|
||
|
||
#### platform / identity-owned
|
||
- users
|
||
- roles
|
||
- permissions
|
||
- user_roles
|
||
- role_permissions
|
||
- (可选)system_logs
|
||
|
||
#### moldinsight-owned
|
||
- stp_files
|
||
- geometry_data
|
||
- mesh_data
|
||
- html_files
|
||
- processing_tasks
|
||
- mold_cavity_data
|
||
- feature_detections
|
||
- design_recommendations
|
||
- analysis_metrics
|
||
|
||
#### inventory-owned
|
||
- products
|
||
- product_materials
|
||
- material_price_history
|
||
- material_suppliers
|
||
- suppliers
|
||
- customers
|
||
- warehouses
|
||
- inventory
|
||
- stock_movements
|
||
- purchase_orders
|
||
- purchase_order_items
|
||
- sales_orders
|
||
- sales_order_items
|
||
- finance_transactions
|
||
- finance_allocations
|
||
|
||
### 8.4 目标代码形态
|
||
|
||
推荐逐步演进到:
|
||
|
||
```text
|
||
platform/database/base.py
|
||
modules/identity/infrastructure/persistence/models.py
|
||
modules/moldinsight/infrastructure/persistence/models.py
|
||
modules/inventory/infrastructure/persistence/models.py
|
||
```
|
||
|
||
同时保持:
|
||
|
||
- 同一个 SQLAlchemy `Base`
|
||
- 同一个 metadata
|
||
- 同一条 Alembic 历史链
|
||
- 同一个数据库连接
|
||
|
||
### 8.5 跨模块 FK 的处理策略
|
||
|
||
当前存在真实跨模块业务桥:
|
||
|
||
- `STPFile.product_id -> Product.id`
|
||
|
||
这是合理的,因为它反映了真实业务关系:模具分析结果可以创建成品,并与 inventory 中的产品建立连接。
|
||
|
||
原则上允许保留这类稳定 FK,但应遵守:
|
||
|
||
1. 跨模块 FK 是**业务桥**,不是“任意跨模块查询”的许可
|
||
2. 模块之间应逐步通过 query service / repository contract 暴露需要的读取能力
|
||
3. 避免一个模块直接依赖另一个模块的整套 ORM 图谱
|
||
|
||
---
|
||
|
||
## 9. 部署模式设计
|
||
|
||
本项目必须支持三种部署模式。
|
||
|
||
### 9.1 unified
|
||
|
||
#### 组成
|
||
- platform + identity + moldinsight + inventory
|
||
|
||
#### 适用场景
|
||
- 本地开发
|
||
- 小团队部署
|
||
- 集成环境
|
||
- 一体化业务场景
|
||
|
||
#### 说明
|
||
新的 unified 组合层应接替旧 [main.py](../src/main.py) 的语义,但应通过 `compositions/unified_app.py` 的方式实现,而不是继续维持旧单体式入口。
|
||
|
||
---
|
||
|
||
### 9.2 gemold-only
|
||
|
||
#### 组成
|
||
- platform + identity + moldinsight
|
||
|
||
#### 适用场景
|
||
- 仅开放模具分析能力
|
||
- 分析服务独立扩容
|
||
- 单独部署算法/文件处理能力
|
||
|
||
#### 说明
|
||
- 只暴露 gemold 路由
|
||
- 可保留对共享数据库中 `products` 的受控引用
|
||
- RustFS / Celery 等专属基础设施只在该模式启用
|
||
|
||
当前入口基线:
|
||
- [moldinsight.py](../src/entrypoints/moldinsight.py)
|
||
|
||
---
|
||
|
||
### 9.3 inventory-only
|
||
|
||
#### 组成
|
||
- platform + identity + inventory
|
||
|
||
#### 适用场景
|
||
- 仅提供 ERP / 进销存能力
|
||
- 不需要模具分析链路的后台场景
|
||
|
||
#### 说明
|
||
- 只暴露 inventory 路由
|
||
- 不要求启动 RustFS 等 moldinsight 专属基础设施
|
||
|
||
当前入口基线:
|
||
- [inventory.py](../src/entrypoints/inventory.py)
|
||
|
||
---
|
||
|
||
### 9.4 当前共享工厂的边界问题
|
||
|
||
需要特别指出:当前 [app_factory.py](../src/shared/app_factory.py) 通过 `mount_html=True` 分支初始化 RustFS,这说明共享工厂仍然知道 moldinsight 模块专属基础设施。
|
||
|
||
这意味着:
|
||
|
||
- `shared` / `platform` 还不够纯
|
||
- 模块专属 startup hook 还没有完全从平台层剥离
|
||
|
||
后续实施时,这应是**优先解决的问题之一**:
|
||
|
||
> app factory 只负责通用平台装配;模块专属生命周期应由 module hook 或 composition layer 决定。
|
||
|
||
---
|
||
|
||
## 10. 前端 API 边界策略
|
||
|
||
### 10.1 设计原则
|
||
|
||
前端已经是独立工程,不需要再拆目录或拆仓。后续重点应放在:
|
||
|
||
- 强化域 API 边界
|
||
- 消除对单一同源 `/api/...` 的强依赖
|
||
- 兼容 unified / split deployment
|
||
|
||
### 10.2 当前可复用基础
|
||
|
||
当前前端已经具备良好基础:
|
||
|
||
- 域客户端入口:[api-client.ts](../frontend/src/shared/api-client.ts)
|
||
- 生成类型:[api.ts](../frontend/src/types/api.ts)
|
||
- 模块目录:[frontend/src/modules/moldinsight/](../frontend/src/modules/moldinsight/) 与 [frontend/src/modules/inventory/](../frontend/src/modules/inventory/)
|
||
|
||
因此,后续策略应是“**边界强化**”,不是“前端重写”。
|
||
|
||
### 10.3 建议的客户端边界
|
||
|
||
应继续收敛为:
|
||
|
||
- `authApi`
|
||
- `moldinsightApi`
|
||
- `inventoryApi`
|
||
|
||
并要求:
|
||
|
||
- 页面/组件尽量不直接写裸 `/api/...` 字符串
|
||
- multipart upload / download / export 也尽量通过域客户端封装
|
||
- 统一利用 OpenAPI 生成类型,而不是额外维护平行手写类型
|
||
|
||
### 10.4 支持两类部署配置
|
||
|
||
#### unified 模式
|
||
- `VITE_API_BASE_URL`
|
||
|
||
#### split 模式
|
||
- `VITE_AUTH_API_BASE_URL`
|
||
- `VITE_MOLDINSIGHT_API_BASE_URL`
|
||
- `VITE_INVENTORY_API_BASE_URL`
|
||
|
||
客户端实现上应支持:
|
||
|
||
- unified 下三个 client 指向同一个 base URL
|
||
- split 下各 client 指向不同服务
|
||
|
||
### 10.5 capability-aware UI
|
||
|
||
在 gemold-only 或 inventory-only 部署模式下,前端不应假设所有模块总是存在。
|
||
|
||
因此建议:
|
||
|
||
- 后端通过 `/health` 或单独 capability endpoint 暴露已启用模块信息
|
||
- 前端根据 capability 隐藏未部署模块入口或禁用对应页面
|
||
|
||
这样可避免“前端路由还在,但后端根本没部署”的硬失败场景。
|
||
|
||
---
|
||
|
||
## 11. 分阶段迁移计划
|
||
|
||
### Phase 0:蓝图冻结
|
||
|
||
目标:冻结目标结构与边界规则,防止迁移过程中继续长出新的耦合。
|
||
|
||
动作:
|
||
- 确认模块边界
|
||
- 确认依赖规则
|
||
- 确认三种部署模式
|
||
- 确认 shared/platform 的使用边界
|
||
|
||
---
|
||
|
||
### Phase 1:组合层标准化
|
||
|
||
目标:将部署模式从“若干入口脚本”升级为“正式的 composition layer”。
|
||
|
||
动作:
|
||
- 将 `entrypoints/*` 升级为 `compositions/*`
|
||
- 定义 `unified_app.py` / `gemold_app.py` / `inventory_app.py`
|
||
- 将 module-specific startup hooks 从通用 app factory 中迁出
|
||
|
||
重点问题:
|
||
- 当前 `mount_html -> RustFS connect` 属于模块专属逻辑,必须从 shared factory 中剥离
|
||
|
||
---
|
||
|
||
### Phase 2:platform 与业务代码分治
|
||
|
||
目标:把“共享基础设施”从“共享杂项”中真正分离出来。
|
||
|
||
动作:
|
||
- 从 `shared` 语义切换到更清晰的 `platform`
|
||
- 归位 config / auth / db / observability / utils
|
||
- 禁止新业务逻辑继续沉积到 `shared`
|
||
|
||
---
|
||
|
||
### Phase 3:ORM 按归属拆分
|
||
|
||
目标:解决当前最大的代码耦合源。
|
||
|
||
动作:
|
||
- 拆分 [database.py](../src/shared/models/database.py)
|
||
- 保持单 Base / 单 Alembic / 单 DB
|
||
- 先完成代码层归属拆分,再处理更深层的业务隔离
|
||
|
||
这是整个重构中最关键的一步。
|
||
|
||
---
|
||
|
||
### Phase 4:模块内部继续分层
|
||
|
||
目标:让每个模块内部的“路由 / 服务 / 领域 / 基础设施”边界更清晰。
|
||
|
||
动作:
|
||
- inventory:从现有 service 层继续向 `application / domain / infrastructure / interfaces` 拉开
|
||
- moldinsight:逐步理顺 `api / services / core / storage` 的边界
|
||
|
||
原则:
|
||
- 不要求一步完成 DDD 化
|
||
- 先把层次职责清楚,再考虑更纯粹的领域对象抽象
|
||
|
||
---
|
||
|
||
### Phase 5:建立跨模块集成规则
|
||
|
||
目标:把当前 ad hoc 跨表访问逐步收敛成显式桥接能力。
|
||
|
||
动作:
|
||
- 定义跨模块 query services / repository contracts
|
||
- 明确“从分析创建成品”等桥接能力的正式入口
|
||
- 收敛直接穿透跨模块 ORM 图谱的做法
|
||
|
||
重点桥接场景:
|
||
- `STPFile.product_id`
|
||
- [product_routes.py](../src/inventory/api/product_routes.py) 中的“按 task 创建产品”逻辑
|
||
|
||
---
|
||
|
||
### Phase 6:前端边界加固
|
||
|
||
目标:让前端真正适配 unified / split deployment。
|
||
|
||
动作:
|
||
- 强制域 API client 收口
|
||
- 支持 per-module base URL
|
||
- 支持 capability-aware UI
|
||
- 减少页面中裸 `fetch('/api/...')`
|
||
|
||
---
|
||
|
||
### Phase 7:部署与文档收尾
|
||
|
||
目标:使架构蓝图与部署事实一致。
|
||
|
||
动作:
|
||
- 固化 unified / gemold-only / inventory-only 部署说明
|
||
- 更新 README / deployment docs / frontend docs
|
||
- 明确旧入口、旧 Dockerfile、旧部署说明的地位(兼容 / 历史 / 废弃)
|
||
|
||
---
|
||
|
||
## 12. 风险与缓解措施
|
||
|
||
### 风险 1:共享模型文件继续隐藏领域归属
|
||
|
||
**现象**:所有模型集中在 [database.py](../src/shared/models/database.py)
|
||
|
||
**风险**:边界无法落实,任何模块都能自然跨领域访问
|
||
|
||
**缓解**:
|
||
- 先产出表归属矩阵
|
||
- 再拆 ORM 文件
|
||
- 拆归属优先于改业务逻辑
|
||
|
||
---
|
||
|
||
### 风险 2:`shared` 继续变成杂物间
|
||
|
||
**风险**:shared/platform 成为“不知道放哪就放这里”的位置
|
||
|
||
**缓解**:
|
||
- 以 `platform` 重新定义共享层
|
||
- 明确只有技术性共享能力可进入 platform
|
||
- 代码 review 中禁止新增业务逻辑进入 platform
|
||
|
||
---
|
||
|
||
### 风险 3:模块专属启动逻辑继续留在 app factory
|
||
|
||
**现象**:当前 `mount_html` 分支控制 RustFS 连接
|
||
|
||
**风险**:平台层继续了解业务模块内部基础设施
|
||
|
||
**缓解**:
|
||
- module lifecycle hook
|
||
- composition 层控制模块 startup/shutdown
|
||
- 通用 app factory 保持纯平台化
|
||
|
||
---
|
||
|
||
### 风险 4:独立部署后,前端仍假设所有模块存在
|
||
|
||
**风险**:前端路由可见,但后端未部署,造成运行时错误
|
||
|
||
**缓解**:
|
||
- capability metadata
|
||
- feature gating
|
||
- 前端按模块部署形态动态隐藏入口
|
||
|
||
---
|
||
|
||
### 风险 5:单数据库导致开发者随意跨模块查表
|
||
|
||
**风险**:虽然数据库未拆,但代码边界被绕开
|
||
|
||
**缓解**:
|
||
- 表归属规则文档化
|
||
- code review 要求说明跨模块访问理由
|
||
- 逐步通过 query services 收口
|
||
|
||
---
|
||
|
||
### 风险 6:大爆炸式目录迁移导致 import churn
|
||
|
||
**风险**:一次性移动所有目录,修改面过大,回归成本高
|
||
|
||
**缓解**:
|
||
- 分阶段迁移
|
||
- 保留兼容 import 过渡层
|
||
- 先稳定组合层与模型层,再做深层目录调整
|
||
|
||
---
|
||
|
||
## 13. 验证清单
|
||
|
||
### 13.1 结构验证
|
||
|
||
- `platform` 不 import 业务模块
|
||
- `moldinsight` / `inventory` 无直接 api/services 互引
|
||
- ORM 文件已按归属拆分,或至少表归属矩阵已文档化并被遵守
|
||
|
||
### 13.2 运行验证
|
||
|
||
#### unified
|
||
- 两类路由都能正常挂载
|
||
- 统一 health / auth / request-id 机制生效
|
||
|
||
#### gemold-only
|
||
- inventory 路由未挂载
|
||
- gemold 路由可用
|
||
- RustFS / Celery 等专属依赖正常初始化
|
||
|
||
#### inventory-only
|
||
- moldinsight 路由未挂载
|
||
- inventory 路由可用
|
||
- 不依赖 moldinsight 专属基础设施即可启动
|
||
|
||
### 13.3 数据验证
|
||
|
||
- 三种部署模式使用同一 migration head
|
||
- 单数据库中的跨模块 FK 保持有效
|
||
- Alembic 无分叉历史
|
||
|
||
### 13.4 前端验证
|
||
|
||
- unified 模式下,一个 base URL 即可跑通
|
||
- split 模式下,各模块 base URL 可独立配置
|
||
- 未部署模块能被隐藏或优雅失败
|
||
|
||
---
|
||
|
||
## 14. 文档联动更新计划
|
||
|
||
本蓝图批准后,以下文档应逐步对齐:
|
||
|
||
- [EVOLUTION_ROADMAP.md](./EVOLUTION_ROADMAP.md)
|
||
- [LINUX_SETUP.md](./deployment/LINUX_SETUP.md)
|
||
- [DEPLOY_PORT.md](./deployment/DEPLOY_PORT.md)
|
||
- [PORT_CONFIG.md](./deployment/PORT_CONFIG.md)
|
||
- [PORT_REFACTOR_SUMMARY.md](./deployment/PORT_REFACTOR_SUMMARY.md)
|
||
- `README.md`
|
||
- `frontend/README.md`
|
||
|
||
其中需要特别注意:
|
||
|
||
- `README.md` 当前仍主要描述旧单体结构,与当前实际代码已有明显漂移。
|
||
- 本文档应作为“当前目标架构”的权威蓝图,路线图与部署文档随后对齐。
|
||
|
||
---
|
||
|
||
## 15. 附录:实施热点文件
|
||
|
||
以下文件是后续实际重构时最关键的热点:
|
||
|
||
### 平台与组合层
|
||
- [app_factory.py](../src/shared/app_factory.py)
|
||
- [settings.py](../src/shared/config/settings.py)
|
||
- [database.py](../src/shared/database/database.py)
|
||
- [init_db.py](../src/shared/database/init_db.py)
|
||
- [moldinsight.py](../src/entrypoints/moldinsight.py)
|
||
- [inventory.py](../src/entrypoints/inventory.py)
|
||
- [main.py](../src/main.py)
|
||
|
||
### 模型与边界
|
||
- [database.py](../src/shared/models/database.py)
|
||
- [product_routes.py](../src/inventory/api/product_routes.py)
|
||
|
||
### gemold 模块
|
||
- [moldinsight/api/__init__.py](../src/moldinsight/api/__init__.py)
|
||
- [processing_service.py](../src/moldinsight/services/processing_service.py)
|
||
- [task_query_service.py](../src/moldinsight/services/task_query_service.py)
|
||
|
||
### inventory 模块
|
||
- [inventory/api/__init__.py](../src/inventory/api/__init__.py)
|
||
- [inventory_service.py](../src/inventory/services/inventory_service.py)
|
||
- [sales_order_service.py](../src/inventory/services/sales_order_service.py)
|
||
- [purchase_order_service.py](../src/inventory/services/purchase_order_service.py)
|
||
- [finance_service.py](../src/inventory/services/finance_service.py)
|
||
|
||
### 前端边界
|
||
- [api-client.ts](../frontend/src/shared/api-client.ts)
|
||
- [api.ts](../frontend/src/types/api.ts)
|
||
|
||
### 演进与部署参考
|
||
- [EVOLUTION_ROADMAP.md](./EVOLUTION_ROADMAP.md)
|
||
- [docker-compose.yml](../docker-compose.yml)
|
||
|
||
---
|
||
|
||
## 16. 最终结论
|
||
|
||
本项目当前最适合的演进路径不是微服务,而是:
|
||
|
||
> **单仓库 + 单数据库 + 多模块 + 可独立部署的 modular monolith**
|
||
|
||
它既能保留当前业务闭环(模具分析 → 成品 → BOM → 销售/采购/库存),又能逐步降低共享层和模型层的结构耦合。
|
||
|
||
后续实施时,应优先按以下顺序推进:
|
||
|
||
1. 固化组合层(deployment composition)
|
||
2. 纯化 platform/shared 边界
|
||
3. 拆分共享 ORM 文件
|
||
4. 再继续模块内部细分层次
|
||
5. 最后收口前端 API 与部署文档
|
||
|
||
这条路径风险最低、收益最大,也最符合当前代码现状与团队演进成本。 |