7.6 KiB
7.6 KiB
FMS 后端架构设计
文档版本:V1.1(精简方案) 编制日期:2026-10-12 状态:待评审 适用范围:沿用现有 FMS API 与 SQL Server 模块配置方式 配套文档:核心表结构设计.md
1. 设计目标
本文以已经使用的 FMS 数据库和 fms-api 接口为基础,只补充模块配置的版本历史能力。目标是让新 ERP 后端和其他 IT 团队能够沿用熟悉的表结构、SQL 和通用数据接口,而不是重新建设一套元数据运行时。
- 保留
s_module、s_field、s_module_schema、s_relation的现有职责和字段约定。 - 元数据描述常用模块、字段和页面配置;SQL 是可选的正式扩展方式,遇到配置不便表达的查询时使用。
- 沿用通用数据 API、机构上下文和 SQL Server 数据源路由;不为每个业务模块新增专用 CRUD API。
- 只新增轻量模块版本历史;不引入模板引擎、编译发布管线、运行时快照目录或复杂审批流程。
2. 总体结构
模块管理界面
├─ s_module:模块树、表/视图、SQL、保存目标
├─ s_field:模块字段及业务类型
├─ s_module_schema:列表 / 表单 / 查询 JSON
└─ s_relation:模块数据关系
│
├─ 普通数据请求 → 现有 /data 通用接口 → SQL Server
├─ 自定义查询 SQL → 只读 SQL 校验 → SQL Server
└─ 显式版本保存/恢复 → s_module_version
运行时继续读取现有模块配置表。s_module_version 只做历史记录与恢复,不成为普通业务请求的读取入口。
3. 模块配置如何驱动请求
3.1 模块与页面配置
- 模块编码
s_module.b_id是稳定业务编码,由配置方提供,不使用运行时雪花 ID。 b_module_type使用现有module、data、virtual约定:分组、标准数据对象和虚拟业务对象。b_view_table、b_save_table、b_key_field描述普通查询和保存目标;数据库对象默认使用dbo。s_field声明模块字段编码、名称和业务类型;具体 SQL 类型通过数据库结构探测获得。s_module_schema的view、edit、queryJSON 控制列表、表单和查询界面;字段语义不在多个 JSON 中重复定义。s_relation声明模块间字段关系;b_parent_id只用于模块树,不表示业务数据关系。
3.2 SQL 兜底
- 常规简单查询使用配置的
b_view_table和通用查询接口。 - 关联、聚合或其他配置表达起来不合适的查询,可在模块配置中使用
b_query_sql;它是模块配置数据,不要求在后端代码中为每家公司登记 SQL 编码。 - 对于按机构隔离的数据库,机构数据源路由继续使用现有
OrgContext/OrgDataSourceManager。各机构可在自己的配置库维护不同模块 SQL,不新增租户配置层。 - 运行查询 SQL 必须经过现有只读校验路径;只允许查询语句,不允许用查询 SQL 执行新增、修改、删除或 DDL。写入走现有保存/删除接口或明确的业务服务。
b_order_sql是模块默认排序;排序标识符按现有DbUtils校验规则处理。查询参数和值不得通过未校验的字符串拼接进入 SQL。
4. 沿用的通用数据 API
已有的 /data/* 契约继续作为数据访问入口,不因模块配置版本化而更换:
| 接口 | 用途 |
|---|---|
POST /data/loaddata |
按表/视图、条件、排序和字段列表查询 |
POST /data/page |
分页查询 |
POST /data/loaddatabysql |
执行只读 SELECT / WITH 查询 |
POST /data/saveobjt |
在一个事务中保存多表新增、修改 |
POST /data/delete |
按模块或受控目标删除 |
POST /data/describe |
探测表或视图列结构 |
POST /data/nextid、/data/nextcode |
取雪花 ID 或模块业务编码 |
loaddata / page 使用表或视图名、结构化筛选和排序参数;loaddatabysql 用于复杂只读查询。已有 DbUtils 负责标识符验证、SQL 只读检查和 SQL 执行。通用保存服务依据真实表结构生成参数化写入,不通过 b_query_sql 写业务数据。
新接入系统应沿用这些请求/响应格式和既有身份、机构、权限上下文;模块管理页面负责读取模块配置并组织请求,不需要另造一套模块专属 CRUD API。
5. 模块配置版本历史
5.1 行为边界
- 版本功能只增加
s_module_version一张表;快照 JSON 包含模块及其字段、界面、关系和相关模块级扩展配置。 - 显式创建版本时,后端从现有配置表读取当前状态,分配递增版本号并保存不可变快照。
- 查看历史只读取版本表;恢复历史版本时,后端校验后在一个事务中恢复现有模块配置表。
- 恢复成功后业务运行仍读取原有
s_module等表;不切换运行时版本指针,也不改变/data/*接口。 - 恢复内容可另存为新的版本记录;禁止覆盖历史快照。
因此这项能力是配置备份、版本查看与恢复,不是草稿/发布隔离。配置当前仍按现有保存机制生效;若之后出现明确的灰度发布需求,再单独扩展。
5.2 最小后端改动
增加一个模块版本服务,负责:
- 创建版本:在数据库事务中读取模块及子配置,验证并序列化快照。
- 查询版本:按模块编码列出版本号、说明、创建人和时间。
- 恢复版本:校验快照结构和关联目标,在同一事务内更新模块配置,并记录恢复结果。
版本操作可通过模块管理 API 暴露;业务数据 API、模块表主键、普通保存流程和 SQL 查询流程不变。版本号由后端分配,不依赖客户端提供。
6. SQL 与数据安全约定
- 客户端不能以任意表名或列名绕过后端标识符验证。
- 普通查询的筛选值以参数传递;字段、排序方向等 SQL 标识由校验后的配置控制。
b_query_sql和/data/loaddatabysql仅用于只读查询,并使用现有DbUtils.validateReadOnlySql()校验。- SQL 配置及执行需经过现有机构、用户和数据范围权限上下文;不能因为使用 SQL 扩展绕过权限校验。
- 写操作使用
/data/saveobjt、/data/delete或已有业务服务,并纳入现有事务和审计规则。 - 版本恢复同样执行配置权限校验、引用校验和事务处理。
7. 不在本次范围内
- 不重构现有 FMS
DataController接口,也不改变 SQL Server、JDBC 或机构数据源路由方式。 - 不增加
s_template/s_template_version、s_module_snapshot、用户偏好新表或权限/工作流新表。 - 不强制运行时从 JSON 快照读取模块定义,不引入
ModuleDefinition编译缓存层。 - 不把 SQL 移到后端固定代码目录;保留模块配置中的可选 SQL 兜底。
- 不重新定义业务表、菜单、用户、权限、工作流、文件和审计子系统。
- 不把模块版本管理等同于数据库 migration;业务表结构仍通过已有 SQL migration 管理。
8. 接入检查清单
- 确认机构/数据库连接按现有路由建立,业务对象位于
dbo。 - 普通表格和表单配置
s_module、s_field、s_module_schema;复杂查询按需配置b_query_sql。 - 用
/data/describe检查实际表/视图字段,用s_field和视图 JSON 保持编码一致。 - 查询、保存、删除分别调用现有通用接口;不从客户端接收未经验证的 DML SQL。
- 重要配置变更后显式保存模块版本;恢复时通过版本服务执行,不手工覆盖版本历史表。