Meta 驱动前后端统一机制(最终确认版)
1. 目标
实现:
后端统一输出 Meta
前端严格按 Meta 驱动
后端保存再次兜底
最终达到:
```text id=”fw0f87” 前后端规则完全一致
避免:
* 前端写死默认值
* 前后端规则漂移
* 不同版本行为不一致
* 非法数据直接入库
---
# 2. 后端:提供“可直接驱动前端”的 Meta 接口
---
# 2.1 Meta 接口职责
后端提供:
```text id="h6vfqy"
geDomainModel
或等价接口。
接口返回:
```text id=”cq39j9” 字段类型定义
- 默认值
- 校验规则
- UI 元信息 ```
让前端:
```text id=”fhlg8m” 不再写任何字段默认常量
---
# 2.2 Meta 接口返回内容
以:
```text id="8f3jqd"
TextField
为例,必须返回:
支持哪些属性
例如:
- FieldName
- Length
- Nullable
- DefaultValue
每个属性默认值
例如:
```text id=”mll6mb” Length = 255 Nullable = true
---
## 每个属性校验规则
例如:
* 最大长度
* 必填条件
* regex
* range
---
## UI 元信息
例如:
* EditorType
* Group
* Visible
* Readonly
---
# 2.3 Meta 返回示例
```json id="4o3zzh"
{
"elementType": "TextField",
"name": "单行文本",
"properties": [
{
"key": "FieldName",
"type": "string",
"required": true
},
{
"key": "Length",
"type": "number",
"defaultValue": 255,
"validators": [
{
"type": "range",
"min": 1,
"max": 4000
}
]
},
{
"key": "Nullable",
"type": "boolean",
"defaultValue": true
},
{
"key": "DefaultValue",
"type": "string"
}
]
}
2.4 Meta 是唯一规则真源
后端 Meta:
```text id=”2b09fj” 是唯一规则真源
统一负责:
* 默认值
* 默认长度
* 校验规则
* 属性结构
* requiredWhen
* validators
* UI 属性
---
# 3. 前端:严格按 Meta 驱动
---
# 3.1 禁止前端写死默认值
禁止:
```javascript id="n8zvvs"
if (fieldType === "TextField") {
field.length = 255;
}
禁止:
- Length=255
- Nullable=true
- 默认 regex
- 默认范围
全部写死。
3.2 新增字段流程
新增字段时:
```text id=”x67v5w” 必须从后端 Meta 获取默认定义
流程:
```text id="sffbvi"
选择字段类型
-> 获取 EffectiveMeta
-> 自动生成默认草稿
-> 用户编辑
-> 保存
3.3 默认值来源
例如新增:
```text id=”p74cc4” TextField
Length 默认值:
```text id="cj5x9m"
来自 Meta.defaultValue
不是:
```text id=”nzrzzg” 前端写死 255
---
# 3.4 用户覆盖默认值
规则:
```text id="g1t4dh"
默认值仅用于初始化
用户修改后:
```text id=”vgg0lj” 用户值优先
---
# 4. 后端保存再次兜底(必须)
即使前端已经按 Meta 初始化:
```text id="39q5c0"
后端仍必须重新执行规则
原因:
- 防止前端绕过
- 防止旧版本前端
- 防止缓存不一致
- 防止非法请求
4.1 保存链路
统一:
```text id=”mk53xm” payload -> normalize -> Meta补默认 -> Meta校验 -> 转领域对象 -> definition序列化 -> 落库
---
# 4.2 normalize
包括:
* 白名单过滤
* trim
* 空值处理
* entity/table 分层
---
# 4.3 默认值补齐
原则:
```text id="x1m9vu"
仅缺失补
不覆盖用户值
示例
用户未传 Length
后端:
```text id=”w0m2c6” 按 Meta.defaultValue 补 255
### 用户传了 Length=128
后端:
```text id="crxw4r"
不覆盖
仅校验是否合法
4.4 Meta 校验
统一按:
```text id=”9rvl1o” EffectiveMeta.validators
执行:
* maxLength
* regex
* range
* required
* requiredWhen
* 引用存在性
---
# 4.5 落库
最终:
```text id="7oaqp2"
领域对象序列化
写入:
```text id=”sjlwm7” md_entity_definition
---
# 5. 统一原则(必须固化)
---
# 5.1 规则真源
唯一:
```text id="2bx3nn"
EffectiveMeta
5.2 前端职责
只负责:
- 展示
- 初始化
- 用户交互
- 基础提示
不负责:
- 规则定义
- 默认值真相
- 最终校验
5.3 后端职责
后端负责:
- normalize
- 默认补齐
- 合法性校验
- 转领域对象
- 最终持久化
6. 最终验收标准(可直接验证)
6.1 前端新增 TextField
新增:
```text id=”h1r1j6” TextField
默认值:
```text id="md0n3x"
必须来自后端 Meta
不是:
```text id=”4ukw0u” 前端常量
---
# 6.2 后端改默认值
例如:
```text id="m75v23"
TextField.Length
255 -> 128
要求:
```text id=”w8r6v5” 前端无需改代码 自动生效
---
# 6.3 保存后 DB 值
最终 DB:
```text id="9u7scm"
来自:
后端规则
+ 领域对象序列化
不是:
```text id=”66zjlwm” 前端传什么存什么
---
# 6.4 非法输入
统一返回:
```json id="7dbkr3"
{
"code": "VALIDATION_ERROR",
"message": "字段校验失败",
"details": [
{
"path": "entity[0].Length",
"message": "长度超过限制"
}
],
"traceId": "xxx"
}
7. 最终架构结论
前端
```text id=”vbyydq” Meta 驱动 UI Meta 驱动默认值
---
# 后端
```text id="yicjpk"
Meta 驱动保存
Meta 驱动校验
Meta 驱动领域对象生成
真源统一
Meta 真源
```text id=”qsy4m6” EffectiveMeta
## 保存真源
```text id="81ebx8"
领域对象
落库真源
```text id=”w9f21h” md_entity_definition
```