20261007220117

This commit is contained in:
oneao committed 2026-10-07 22:01:17 +08:00
1 parent 9217b3fa42
commit 8b1ec67609
275 files changed
+20026 -49299

No files matched your search

@@ -0,0 +1,447 @@
# FMS 新系统核心架构实施计划 V1.0
> 文档版本:V1.0
> 编制日期:2026-09-30
> 适用范围:FMS/ERP 新系统第一阶段核心架构重构
> 执行方式:由多个 AI 按任务卡顺序执行,人负责最终取舍和验收
## 1. 计划目标
本计划用于指导其他 AI 实现 FMS 新系统第一阶段核心架构。
第一阶段只解决以下问题:
- SQL Server 数据库如何迁移和版本化;
- 租户数据库如何连接和路由;
- 用户、公司、组织、仓库和账簿如何形成统一上下文;
- 业务域如何组织自己的表、SQL、服务、接口和页面;
- SQL 如何成为查询、报表和数据处理的主要实现;
- 简单基础资料如何使用通用 CRUD;
- 核心业务如何使用专用 SQL 和业务处理器;
- 如何用一个完整业务域验证架构。
第一阶段不实现完整 ERP,也不建设通用低代码平台。
## 2. 已确定的架构约束
其他 AI 执行所有任务时必须遵守以下约束:
1. SQL Server 是第一阶段唯一数据库目标。
2. 一个租户对应一个数据库,租户库内不使用 `tenant_id` 做日常业务过滤。
3. 业务域代码包是代码组织中心。
4. 真实业务表和 SQL 视图是事实来源。
5. SQL 文件是查询、报表和数据处理的主要实现。
6. 业务代码负责业务动作、事务和复杂业务规则。
7. 页面配置只负责表现和少量参数。
8. 不做全量 EAV,不做运行时任意生成业务表。
9. 通用 CRUD 只用于简单基础资料,不作为核心业务默认实现。
10. 工作流负责流程编排,库存、财务和结算动作必须由业务处理器完成。
11. 第一阶段不引入通用配置版本引擎、通用公式引擎和通用规则解释器。
12. 内部开发人员可以直接维护 SQL,不增加 SQL 安全沙箱、ORM 替代层或复杂 SQL DSL。
13. 所有新代码必须遵守统一目录、命名和 SQL 文件风格。
## 3. 阶段依赖
```text
T0 架构基线和代码规范
↓
T1 SQL Migration 和数据库运行时
↓
T2 租户路由和业务上下文
↓
T3 系统基础数据和权限
↓
T4 业务域模板和 SQL 调用约定
↓
T5 客户或产品示例业务域
↓
T6 工作流、审计和多语言接入
↓
T7 第一阶段验收和旧设计迁移清单
```
T0 到 T4 必须顺序完成。T5 完成后,T6 可以拆分给不同 AI,但最终必须统一接口和风格。
## 4. 任务 T0:架构基线和代码规范
### 4.1 目标
把新架构的原则转成开发人员和 AI 都能执行的规则。
### 4.2 工作内容
- 阅读并理解以下文档:
- `ERP动态配置多租户多公司多语言需求分析.md`;
- `FMS新系统核心表结构设计.md`;
- `FMS新系统核心架构设计.md`。
- 确定 SQL Server 版本和连接方式;
- 确定数据库迁移目录和文件命名;
- 确定业务域目录结构;
- 确定表名、字段名、索引、主键和时间字段规范;
- 确定 SQL 文件参数和返回结果规范;
- 明确哪些旧设计暂时不迁移。
### 4.3 输出物
```text
开发规范补充文档
SQL Migration 目录
业务域目录模板
SQL 文件示例
架构决策记录
```
### 4.4 验收标准
- 新增一个业务域时不需要重新发明目录结构;
- SQL 文件可以被数据库工具独立执行和验证;
- 不存在同时使用两套字段命名和 SQL 组织方式的说明;
- 其他 AI 可以只读本阶段输出物开始后续工作。
## 5. 任务 T1:SQL Migration 和数据库运行时
### 5.1 目标
让每个租户数据库可以可靠地初始化、升级和记录结构版本。
### 5.2 工作内容
- 创建迁移记录表;
- 实现迁移文件扫描和顺序执行;
- 实现重复执行判断;
- 记录迁移名称、版本、checksum、执行时间和结果;
- 支持初始化新租户数据库;
- 支持租户数据库版本查询;
- 补充失败迁移的人工处理方式。
### 5.3 Migration 规则
```text
V001__create_core_tables.sql
V002__create_company_tables.sql
V003__create_audit_tables.sql
```
Migration 可以包含建表、改表、索引、视图、约束和必要的数据回填。
Migration 不负责页面布局和用户偏好,也不作为通用配置表使用。
### 5.4 验收标准
- 空数据库可以从零初始化;
- 已执行的迁移不会重复执行;
- 迁移失败时可以明确定位文件和错误;
- 两个租户数据库可以独立升级;
- 应用启动时可以读取数据库结构版本。
## 6. 任务 T2:租户路由和业务上下文
### 6.1 目标
建立统一的数据库连接、租户识别和请求上下文,不让业务域自行处理这些基础问题。
### 6.2 工作内容
- 定义 `TenantRegistry` 接口;
- 首期使用配置文件实现租户注册;
- 实现租户数据库连接创建和复用;
- 实现请求级数据库连接选择;
- 实现请求级业务上下文;
- 请求结束后清理上下文;
- 记录当前租户、用户、公司和请求编号。
### 6.3 上下文结构
```text
tenant_code
user_id
company_id
organization_id
warehouse_id
ledger_id
language
timezone
currency
request_id
```
### 6.4 验收标准
- 同一个请求内所有业务 SQL 使用同一个租户数据库;
- 业务域不需要自己读取租户配置文件;
- 用户可以切换授权公司并重新建立上下文;
- 上下文不会泄漏到下一个请求;
- 日志可以定位租户、用户、公司和请求。
## 7. 任务 T3:系统基础数据和权限
### 7.1 目标
建立所有业务域依赖的用户、角色、公司、组织、仓库和账簿。
### 7.2 第一批表
```text
s_user
s_role
s_user_role
s_role_permission
s_role_data_scope
s_company
s_organization
s_warehouse
s_ledger
s_user_company
s_user_organization
s_user_warehouse
s_user_ledger
```
### 7.3 权限范围
首期只实现:
- 用户可用公司;
- 用户可用组织;
- 用户可用仓库;
- 模块访问权限;
- 业务动作权限;
- 全部、指定公司、本组织、本组织及下级、本人和指定仓库等简单数据范围。
不实现角色继承、拒绝权限和通用权限表达式。
### 7.4 验收标准
- 一个用户可以属于多个公司;
- 一个用户可以在不同公司拥有不同角色;
- 公司、组织、仓库和账簿不会混用编码;
- 权限查询可以使用 SQL 完成;
- 所有业务查询可以取得当前公司上下文。
## 8. 任务 T4:业务域模板和 SQL 调用约定
### 8.1 目标
建立所有业务域共同遵守的实现模板,解决“一个文件一个风格”的问题。
### 8.2 业务域模板
```text
domains/<domain_code>/
├── migration/
├── sql/
├── repository/
├── service/
├── api/
├── page/
└── i18n/
```
### 8.3 SQL 文件命名
```text
<object>_list.sql
<object>_detail.sql
<object>_save.sql
<object>_<action>.sql
<object>_report.sql
```
### 8.4 访问约定
- 查询由 repository 调用 SQL;
- 保存由 repository 调用保存 SQL或 service 组织多条 SQL;
- 业务动作由 service 作为唯一入口;
- 页面只调用 API;
- 业务域不直接修改另一个业务域的内部表;
- 复杂业务必须有明确事务边界;
- 简单资料才允许使用通用 CRUD。
### 8.5 验收标准
- 创建新业务域只需复制模板并替换业务名称;
- list、detail、save、action 的代码结构统一;
- SQL 不散落在页面、控制器和配置数据库中;
- 通用 CRUD 的适用范围有明确示例。
## 9. 任务 T5:客户或产品示例业务域
### 9.1 目标
用一条完整业务链路验证新架构,而不是先建设一个空的通用引擎。
### 9.2 推荐对象
优先选择客户或产品,不要一开始选择库存或财务。
### 9.3 工作内容
```text
SQL Migration
→ b_customer 或 b_product
→ 查询 SQL
→ 保存 SQL
→ 业务域 service
→ API
→ 页面
→ 公司范围
→ 审计
→ 多语言名称
```
### 9.4 验收标准
- 可以在 SQL Server 中直接执行列表和详情查询;
- 页面不需要通用模块解释器才能运行;
- 保存过程经过明确的 repository/service;
- 公司范围可以生效;
- 关键变更有审计记录;
- 新增字段可以通过 Migration 完成;
- 业务域目录、SQL 命名和代码风格符合 T4。
## 10. 任务 T6:工作流、审计和多语言接入
### 10.1 工作流
保留 `wf_*` 工作流子系统,但绑定业务动作,不绑定任意页面配置:
```text
sales_order.submit
sales_order.approve
purchase_order.submit
expense.approve
```
工作流实例固定流程版本,真正的库存、财务和结算动作由业务域 service 执行。
### 10.2 审计
审计至少记录:
```text
user_id
company_id
domain_code
business_id
operation
before_value
after_value
request_id
occurred_at
```
### 10.3 多语言
第一阶段只实现:
```text
s_i18n_type
s_i18n
```
业务主数据按业务域使用翻译表。暂不实现多层 overlay、翻译变更集和运行时语言管理。
### 10.4 验收标准
- 工作流可以调用一个业务域动作;
- 流程实例记录固定的流程版本;
- 业务动作和审批动作有审计记录;
- 系统文案和主数据翻译可以按语言读取;
- 翻译读取不影响业务 SQL 查询。
## 11. 任务 T7:第一阶段验收和旧设计迁移清单
### 11.1 验收重点
第一阶段不是验收页面数量,而是验收架构是否成立:
- SQL 是事实来源;
- 业务域可以独立拥有表、SQL、服务和页面;
- 不依赖通用模块解释器才能运行;
- 简单对象可以使用通用 CRUD;
- 核心动作使用专用 service 和 SQL;
- 多公司上下文贯通查询、保存、权限和审计;
- 数据库结构变更通过 Migration 管理;
- 代码目录和 SQL 风格统一。
### 11.2 旧设计迁移分类
```text
保留:真实业务表、成熟 SQL、工作流运行表
迁移:散落 SQL、通用保存调用、模块页面配置
降级:s_module、s_field、s_module_schema 只做登记和表现
后置:全局配置版本、通用规则引擎、多层配置覆盖
删除:以元数据解释器为中心的核心业务运行时
```
## 12. 给其他 AI 的执行规则
每个 AI 接任务时必须先阅读:
1. `FMS新系统核心架构设计.md`;
2. `FMS新系统核心架构实施计划.md`;
3. 与当前任务直接相关的旧设计文档。
每个 AI 的任务输出必须包含:
```text
完成内容
修改文件
数据库变更
验证方式
未完成事项
风险或需要人工决策的地方
```
执行限制:
- 不得自行增加通用配置引擎;
- 不得把业务逻辑放进页面 JSON;
- 不得为一个业务对象创建第二套 SQL 调用方式;
- 不得修改无关业务域;
- 不得为了“以后可能需要”提前抽象;
- 不得删除旧表或旧接口,除非任务明确要求迁移;
- 不得把 SQL 改写成 ORM 查询作为默认方案;
- 不得只提交页面而没有 SQL、服务和验收说明。
## 13. 第一张任务卡
可以把下面内容直接交给第一个 AI:
```text
你负责 FMS 新系统核心架构实施计划的 T0 任务:架构基线和代码规范。
请先阅读:
1. FMS新系统核心架构设计.md
2. FMS新系统核心架构实施计划.md
3. FMS新系统核心表结构设计.md
4. 开发规范.md
你的目标是确定 SQL Server、Migration、业务域目录、SQL 文件命名、数据库命名和业务动作入口规范。
要求:
- 不实现业务模块;
- 不新增通用低代码引擎;
- 不修改无关文件;
- 不把 SQL 改写成 ORM 查询;
- 输出一份开发规范补充文档;
- 提供一个客户或产品业务域的空目录模板;
- 提供至少三个 SQL 文件示例;
- 最后报告修改文件、验证方式和未决问题。
```
## 14. 计划结论
第一阶段的正确顺序不是先做一个“万能模块引擎”,而是:
```text
统一规范
→ 数据库迁移
→ 租户和公司上下文
→ 系统基础数据
→ 业务域模板
→ 一个完整业务域
→ 工作流和通用能力
```
先用一个真实业务域验证架构,再决定哪些能力值得抽象。所有通用能力都必须来自实际重复,而不是来自对未来场景的猜测。
+732
View File
@@ -0,0 +1,732 @@
# FMS 新系统核心架构设计 V2.0
> 文档版本:V2.0
> 编制日期:2026-09-30
> 文档状态:核心架构设计草案
> 适用范围:FMS/ERP 新系统第一阶段重构
## 1. 文档目的
本文档重新定义 FMS 新系统的核心架构,重点解决以下问题:
- SQL 是系统的第一等公民;
- 代码风格和模块实现方式统一;
- 第一阶段保持简单,不建设通用低代码平台;
- 真实业务表、业务 SQL 和业务代码拥有清晰边界;
- 支持一个租户多个公司,但不提前建设复杂的平台能力。
本文档替代旧设计中以 `s_module`、通用 CRUD 和动态 JSON 为中心的架构思路。旧表结构中的业务数据、工作流和可复用 SQL 可以迁移,但运行时中心需要重新组织。
## 2. 根本改变
### 2.1 旧架构
旧设计的主链路是:
```text
s_module
→ s_field
→ s_module_schema
→ 通用 SQL 拼接
→ 通用保存
→ 页面
```
它的优点是页面和简单模块创建较快,缺点是业务模块逐渐依赖元数据解释器,容易变成一个低代码平台。
### 2.2 新架构
新设计的主链路是:
```text
业务域代码包
→ 真实 SQL 表和视图
→ 业务查询与业务动作
→ API / 页面
```
新系统的中心不再是全局模块元数据,而是**业务域代码包**。每个业务域自己拥有表结构、迁移、SQL、业务动作和页面入口。
```text
客户域
├── 数据库迁移
├── 业务表和视图
├── 查询 SQL
├── 保存 SQL
├── 业务动作
├── 接口
├── 页面
└── 多语言资源
```
### 2.3 核心原则
```text
业务域是组织中心
SQL 表和视图是事实来源
SQL 文件是查询和处理的主要实现
业务代码负责动作和事务
页面是业务域的使用界面
配置只解决少量表现和参数问题
```
## 3. 总体架构
```text
租户注册配置
│
▼
租户数据库路由
│
▼
SQL Server 租户数据库
├── 系统内核
│ ├── 用户、角色和业务上下文
│ ├── 公司、组织、仓库和账簿
│ ├── 多语言和审计
│ └── 文件和运行记录
├── 业务域
│ ├── 客户和供应商
│ ├── 产品和基础资料
│ ├── 销售
│ ├── 采购
│ ├── 库存
│ └── 财务
├── 工作流
└── SQL 视图和报表
```
运行时链路:
```text
请求
→ 租户路由
→ 建立用户和公司上下文
→ 进入业务域
→ 执行查询或业务动作
→ SQL 事务
→ 审计记录
→ 返回结果
```
## 4. 核心内核
核心内核只提供所有业务域都需要的能力,不负责解释所有业务。
### 4.1 租户路由
第一阶段采用一个租户一个数据库:
- 租户注册信息使用配置文件;
- 一个租户对应一个 SQL Server 数据库;
- 租户库内不重复使用 `tenant_id` 过滤业务数据;
- 数据库连接由统一的 `TenantRegistry` 获取;
- 每个租户数据库单独执行迁移并记录版本。
平台库、在线租户开通和集中运维不进入第一阶段。
### 4.2 业务上下文
每次请求建立统一上下文:
```text
tenant_code
user_id
company_id
organization_id
warehouse_id
ledger_id
language
timezone
currency
request_id
```
上下文由运行时创建,业务域只能读取,不由页面自行拼接。SQL 和业务动作通过上下文得到当前公司、用户和账簿。
### 4.3 基础表
第一阶段的系统基础表:
```text
s_user
s_role
s_user_role
s_company
s_organization
s_warehouse
s_ledger
s_user_company
s_user_organization
s_user_warehouse
s_user_ledger
s_i18n_type
s_i18n
s_audit_log
s_file
```
角色先采用简单模型,不实现角色继承和复杂拒绝规则。公司、组织、仓库和账簿是明确的独立对象,不使用一个 `org_id` 代替它们。
## 5. 业务域代码包
### 5.1 业务域定义
业务域是新系统的主要代码组织单位,例如:
```text
customer
supplier
product
sales
purchase
inventory
finance
workflow
```
一个业务域负责自己的:
- 业务表和表关系;
- 数据库迁移;
- 查询视图;
- 查询 SQL;
- 保存 SQL;
- 业务动作;
- 事务边界;
- API;
- 页面;
- 多语言资源;
- 审计事件。
业务域之间通过明确的业务表关系、SQL 查询和服务接口协作,不通过全局 JSON 规则互相解释。
### 5.2 业务对象
业务对象仍然存在,但它属于业务域,而不是全局通用元数据引擎。
一个业务对象至少包含:
```text
对象编码
主表或视图
查询 SQL
保存方式
业务动作
```
例如销售订单:
```text
sales_order
├── b_sales_order
├── b_sales_order_line
├── sales_order_list.sql
├── sales_order_save.sql
├── submit_sales_order()
└── approve_sales_order()
```
### 5.3 业务域目录
建议使用以下代码组织方式:
```text
fms/
├── core/
│ ├── tenant/
│ ├── context/
│ ├── auth/
│ ├── audit/
│ └── i18n/
├── domains/
│ ├── customer/
│ │ ├── migration/
│ │ ├── sql/
│ │ ├── repository/
│ │ ├── service/
│ │ ├── api/
│ │ └── page/
│ ├── product/
│ ├── sales/
│ ├── purchase/
│ ├── inventory/
│ └── finance/
├── workflow/
└── shared/
```
每个业务域使用同一种目录结构,不允许某个模块把 SQL 放数据库字段、另一个模块把 SQL 放页面代码、第三个模块再放配置 JSON。
## 6. SQL 设计
### 6.1 SQL 的职责
SQL 负责:
- 查询;
- 关联;
- 分组和统计;
- 排序和分页;
- 批量更新;
- 事务内的数据处理;
- 报表和视图。
业务代码负责:
- 业务动作入口;
- 事务编排;
- 状态变化;
- 幂等处理;
- 跨模块规则;
- 库存和财务业务约束。
### 6.2 SQL 文件规范
SQL 统一放在业务域目录下:
```text
domains/sales/sql/
├── order_list.sql
├── order_detail.sql
├── order_save.sql
├── order_submit.sql
└── order_report.sql
```
SQL 命名统一使用:
```text
对象_动作.sql
```
例如:
```text
customer_list.sql
customer_save.sql
customer_disable.sql
sales_order_submit.sql
inventory_lock.sql
```
### 6.3 通用 CRUD 的边界
新架构不移除通用 CRUD,但不把通用 CRUD 作为所有业务的默认核心。它可以用于简单基础资料,核心业务必须由业务域自己的 SQL 和业务动作实现。
以下内容不再作为系统核心:
- 数据库中的 `b_query_sql` 作为所有模块的默认查询入口;
- `b_save_table` 驱动所有业务模块的通用保存;
- `b_order_sql` 在运行时任意拼接排序;
- 全局 `data / virtual` 模块解释器;
- 页面 JSON 中的业务公式和业务写入规则;
- 一张通用配置表承载所有业务行为。
内部开发人员可以自由编写 SQL,但 SQL 由对应业务域维护,并与代码和迁移一起发布。
### 6.4 通用保存边界
通用保存仅用于简单基础资料。以下内容必须使用业务域专用服务和 SQL:
- 库存扣减、锁定和释放;
- 采购和销售状态推进;
- 财务过账和反过账;
- 公司间交易;
- 审批提交和审批动作;
- 任何需要多个业务表一致提交的操作。
## 7. 数据库模型
### 7.1 表分层
```text
s_* 系统内核和控制数据
b_* 业务主表和业务明细表
wf_* 工作流定义和运行数据
```
核心业务表使用真实列和真实关系,不使用全量 EAV。
### 7.2 公司字段
公司级业务表根据业务实际需要包含:
```text
company_id
organization_id
warehouse_id
ledger_id
```
跨公司业务另外保存:
```text
source_company_id
target_company_id
settlement_company_id
```
共享基础资料不复制多份,使用共享范围或公司关联表表达。
### 7.3 动态字段
第一阶段不支持普通用户通过页面配置直接创建数据库字段。新增业务字段使用:
```text
迁移脚本增加物理列或扩展表
→ 更新查询 SQL 和视图
→ 更新页面字段定义
→ 增加多语言资源
```
字段分为:
1. 核心字段:真实列,参与业务逻辑和统计;
2. 扩展字段:通过迁移增加的可选列或扩展表字段;
3. 低频扩展:JSON,仅用于非核心展示。
需要筛选、排序、统计或导出的字段不能只放在 JSON 中。
运行时字段分为两种情况:
- **表现字段**:标签、显隐、只读、排序和布局可以运行时调整;
- **物理字段**:需要存储、查询、排序、统计或导出的字段,必须通过 SQL Migration 增加物理列或扩展表。
后续如果确实需要管理员在线增加物理字段,可以增加一个受控的字段变更服务,由它生成并执行 SQL Migration,同时更新视图、字段定义和页面配置。这个过程仍然是数据库结构变更,不是普通 JSON 配置。
### 7.4 数据库约束
数据库负责结构完整性:
- 主键;
- 外键;
- 唯一索引;
- 非空约束;
- 必要 CHECK;
- 查询和关联索引。
不使用触发器替代库存、财务和审批业务流程。业务规则放在业务域服务和事务 SQL 中。
## 8. 页面和配置
### 8.1 页面不是元数据生成的
核心业务页面由业务域代码实现。页面可以复用通用列表、表单和查询组件,但页面的字段、动作和业务行为由业务域明确声明。
页面配置只保存:
- 列显示顺序;
- 列宽;
- 表单分组;
- 查询默认值;
- 用户个人偏好;
- 显示格式。
不使用 JSON 描述完整业务页面和业务处理器。
### 8.2 模块表的定位
如果保留 `s_module`,它只用于:
- 菜单和路由登记;
- 权限对象登记;
- 模块名称和多语言资源键;
- 业务域对象的索引。
它不负责:
- 生成所有 SQL;
- 推断所有保存逻辑;
- 承载业务状态;
- 解释任意 JSON 规则。
### 8.3 公司差异
第一阶段不建设通用的租户、公司、部门、角色多层配置继承。
确实存在公司差异时,在具体业务表中直接使用 `company_id`,例如:
```text
s_number_rule(company_id, domain_code, field_code)
wf_binding(company_id, domain_code, event_code)
s_print_template(company_id, template_code)
```
不把所有差异都抽象为一个通用覆盖引擎。
## 9. 权限
权限采用简单的角色模型:
```text
s_role
s_user_role
s_role_permission
s_role_data_scope
s_user_company
```
权限对象绑定业务域和业务动作:
```text
customer.read
customer.create
sales_order.submit
sales_order.approve
inventory.adjust
finance.post
```
第一阶段支持:
- 用户可用公司;
- 用户可用组织;
- 用户可用仓库;
- 模块访问权限;
- 业务动作权限;
- 简单数据范围。
不实现角色继承、拒绝权限和通用权限表达式。复杂范围由对应业务域的 SQL 实现。
## 10. 工作流
工作流是业务域的流程编排器,不是业务规则中心。
工作流绑定业务域动作:
```text
sales_order.submit
sales_order.approve
purchase_order.submit
expense.approve
```
工作流可以决定:
- 下一节点;
- 审批人;
- 当前流程状态;
- 需要调用哪个业务动作。
业务域负责真正的动作:
- 销售订单批准后是否允许出库;
- 采购收货如何增加库存;
- 财务单据如何过账;
- 审批失败如何补偿。
工作流实例固定流程版本,历史审批记录只追加不修改。
## 11. 多语言
第一阶段保持简单:
```text
s_i18n_type
s_i18n
```
系统文案使用稳定资源键:
```text
sales.order.name
sales.order.customer
action.submit
```
业务主数据使用业务域自己的翻译表:
```text
b_product
b_product_translation
b_customer
b_customer_translation
```
系统资源可以放在代码资源文件或租户库中,但必须统一一种来源。第一阶段不实现三层 overlay、翻译变更集和运行时语言管理。
历史单据保存产品名称、客户名称、税率、地址、币种和金额等快照。
## 12. 配置和版本
第一阶段不建设覆盖所有对象的通用配置版本引擎。
配置分为三类:
| 类型 | 实现方式 |
| --- | --- |
| 数据库结构 | SQL Migration |
| 业务逻辑 | 代码和业务 SQL |
| 页面表现 | 页面代码和少量布局配置 |
| 工作流 | 独立流程版本表 |
| 业务参数 | 明确的参数表 |
只有工作流、编号规则、打印模板等确实需要历史追溯的内容,才单独设计版本。
### 12.1 SQL Migration
SQL Migration 是按顺序执行、可追踪的数据库结构变更脚本。例如:
```text
migration/
├── V001__create_company.sql
├── V002__create_customer.sql
└── V003__add_customer_tax_no.sql
```
迁移工具在每个租户数据库中记录已执行的版本。发布新代码时,先执行缺少的迁移,再启动依赖新结构的代码。
Migration 可以包含:
- 建表、改表和删表;
- 增加或停用字段;
- 创建视图、索引和约束;
- 初始化字典和系统数据;
- 必要的数据回填。
Migration 不等于运行时页面配置。页面配置可以立即保存,数据库结构变化则必须经过迁移记录。
数据库迁移记录:
```text
schema_version
migration_name
checksum
executed_at
```
## 13. 代码风格和目录规范
新系统的代码按业务域组织,不按页面组织,也不按一组通用配置表组织。
```text
domains/
sales/
migration/
sql/
repository/
service/
api/
page/
i18n/
```
统一要求:
- 一个业务动作只有一个主要入口;
- SQL 统一放业务域的 `sql` 目录;
- 页面只调用业务域 API,不直接写业务 SQL;
- 业务域不通过另一个域的内部表直接修改数据;
- 数据库表、SQL、服务、接口和页面使用同一业务名称;
- 新增抽象必须来自至少两个真实业务域的重复需求。
数据库命名在新系统中一次确定:
- 表名使用小写 `snake_case`;
- 系统表使用 `s_`;
- 业务表使用 `b_` 或明确业务域前缀;
- 工作流表使用 `wf_`;
- 字段命名统一使用一套规则,不再混用 `b_`、`mx_` 和裸字段名。
## 14. 第一阶段建设范围
第一阶段只建设架构内核和一条完整业务链路。
### 14.1 必须完成
1. SQL Server 迁移工具和数据库版本表;
2. 租户数据库连接和路由;
3. 用户、角色、公司、组织、仓库和账簿;
4. 统一业务上下文;
5. 业务域目录和 SQL 调用约定;
6. 基础权限和公司范围;
7. 审计日志;
8. 基础多语言;
9. 一个业务域的表、SQL、服务、接口和页面完整闭环。
### 14.2 建议示例
建议先做客户或产品域:
```text
SQL Migration
→ 真实业务表
→ 查询 SQL
→ 保存 SQL
→ 业务域服务
→ API
→ 页面
→ 公司权限
→ 审计
```
这个示例必须验证“业务域代码包是中心”,不只是验证通用页面是否能显示。
### 14.3 第一阶段不做
- 以全局 `s_module` 驱动的通用 CRUD 作为核心业务默认实现;
- 全局 `s_field` 驱动的运行时字段创建;
- 通用页面设计器;
- 通用公式和规则解释器;
- 全对象配置版本和变更集;
- 多层公司配置覆盖;
- 复杂多语言发布体系;
- 集团分析库和跨租户业务查询。
## 15. 第一阶段验收标准
### 15.1 架构中心
- 一个业务域拥有自己的迁移、SQL、服务和页面;
- 业务域可以不依赖通用模块解释器运行;
- 页面配置不能替代业务代码;
- 工作流只能调用明确登记的业务动作。
### 15.2 SQL 驱动
- 业务查询可以直接在 SQL Server 中验证;
- 复杂查询使用业务域 SQL 文件或视图;
- 业务表和关联关系是真实 SQL 结构;
- 新增可统计字段需要物理列或索引扩展;
- 不为了页面功能复制业务表。
### 15.3 简单和一致
- 同类业务域使用相同目录和调用流程;
- 不存在同一类配置的多种格式;
- 不存在同一业务动作的多个通用入口;
- 数据库迁移和代码可以一起发布;
- 第一阶段不依赖通用低代码运行时。
## 16. 旧设计迁移原则
旧设计不是全部废弃,而是按职责迁移:
| 旧内容 | 新系统处理方式 |
| --- | --- |
| 真实业务表 | 保留并按业务域归属整理 |
| 业务 SQL | 移入对应业务域 `sql` 目录 |
| `wf_*` 工作流表 | 保留,改为绑定业务动作 |
| `s_module` | 降为菜单、权限和对象索引 |
| `s_field` | 降为字段说明,不负责运行时造字段 |
| `s_module_schema` | 页面局部配置,不作为核心运行时 |
| 通用保存接口 | 仅保留简单基础资料使用 |
| JSON 公式和动态规则 | 迁移到业务代码或 SQL |
| `b_query_sql` 等全局 SQL 字段 | 逐步迁移到业务域 SQL 文件 |
## 17. 最终架构关系
```text
业务域代码包是组织中心
SQL 表和视图是事实来源
SQL 文件是查询和处理的主要实现
业务代码负责动作和事务
页面负责交互
工作流负责流程编排
少量配置负责表现和参数
```
新系统不是旧系统增加一层配置,也不是把旧模块表重新命名。它的核心变化是:
> **从元数据驱动的通用模块,改成业务域驱动的 SQL 应用。**