Files

242 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LeAudit DSL 规则域表结构设计
> **状态**: 核心表已落地 `leaudit_platform` 数据库
> **相关**: [文档域表设计](document_schema_design.md) | [Bridge 目录设计](bridge_directory_design.md)
## 1. 设计目标
- `LeAudit` 运行时仍然按 YAML 规则文件执行
- 规则文件的持久真相源不再依赖固定本地目录
- 数据库存储规则元数据、版本、状态、OSS 地址
- YAML 正文作为文件产物放在 OSS
- 运行时根据数据库当前激活版本下载到本地临时文件,再按 `LeAudit` 原逻辑加载
- 支持规则编辑、校验、发布、回滚、审计
## 2. 核心原则
### 2.1 规则真相源是 "OSS 文件 + 数据库索引"
- 执行规则内容:YAML 文件
- 持久位置:OSS
- 数据库:记录元数据、版本、OSS 地址、激活状态
### 2.2 不让数据库直接变成规则执行解释器
数据库不替代 YAML/DSL 本身,不把规则拆碎存成"行式规则引擎配置"。
原因:
- 会偏离 `LeAudit` 原逻辑
- 会抬高规则编辑和发布成本
- 会让 DSL 的可读性和兼容性变差
### 2.3 规则编辑与规则执行分离
- 编辑阶段:编辑 YAML 文本、校验、上传 OSS、写版本记录
- 执行阶段:查 DB 元数据、下 OSS 文件、本地临时加载执行
## 3. 已落地核心表
| # | 表名 | 用途 | 状态 |
|---|------|------|------|
| 1 | `leaudit_rule_sets` | 规则集主表 | ✅ |
| 2 | `leaudit_rule_versions` | 规则版本表 | ✅ |
| 3 | `leaudit_rule_type_bindings` | 文档类型与规则集绑定 | ✅ |
| 4 | `leaudit_evaluation_point_groups` | 评查点规则组(PID 树形) | ✅ |
| 5 | `leaudit_evaluation_points` | 规则点/评查点元数据 | ✅ |
待补充(后续阶段):
| # | 表名 | 用途 |
|---|------|------|
| 6 | `leaudit_rule_file_artifacts` | 规则文件产物(校验报告、导出包等) |
| 7 | `leaudit_rule_publish_logs` | 规则发布/回滚审计日志 |
| 8 | `leaudit_rule_validation_logs` | 规则校验日志 |
## 4. 核心表结构
### 4.1 `leaudit_rule_sets`
规则集主表,描述一个稳定的业务规则集实体。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint PK | 主键 |
| `rule_type` | varchar(128) | 业务规则类型编码,对应 DSL `metadata.type_id` |
| `rule_name` | varchar(512) | 规则集名称 |
| `domain_type` | varchar(64) | contract / admin_license / legal_doc |
| `description` | text | 规则集描述 |
| `entry_module` | varchar(64) | 对应业务入口模块标识 |
| `current_version_id` | bigint | 当前激活版本 → `leaudit_rule_versions.id` |
| `status` | varchar(32) | draft / active / deprecated / archived |
| `is_builtin` | boolean | 是否内置规则集(内置不可删除) |
| `owner_user_id` | bigint | 负责人 |
| `create_time` / `update_time` / `delete_time` | timestamptz | 标准时间戳 |
### 4.2 `leaudit_rule_versions`
规则版本表,每次编辑/发布都生成一条新版本。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint PK | 主键 |
| `rule_set_id` | bigint FK | → `leaudit_rule_sets.id` |
| `version_no` | varchar(64) | 语义版本号 |
| `version_seq` | int | 顺序号(rule_set 内递增) |
| `status` | varchar(32) | draft / published / deprecated / rollback |
| `source_type` | varchar(32) | oss_yaml / local_yaml / db_snippet |
| `dsl_format` | varchar(32) | yaml / json |
| `oss_url` | varchar(2048) | YAML 文件 OSS 地址 |
| `file_sha256` / `file_size` | — | 文件完整性 |
| `metadata_type_id` / `metadata_name` / `metadata_version` | — | DSL metadata 快照 |
| `change_note` | text | 变更说明 |
| `editor_user_id` / `publisher_user_id` / `published_at` | — | 编辑/发布信息 |
| `create_time` / `update_time` | timestamptz | 标准时间戳 |
### 4.3 `leaudit_rule_type_bindings`
文档类型和规则集的绑定表。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint PK | 主键 |
| `doc_type_id` | bigint | → `leaudit_document_types.id` |
| `doc_type_code` | varchar(128) | 文档类型编码(冗余快速匹配) |
| `rule_set_id` | bigint FK | → `leaudit_rule_sets.id` |
| `binding_mode` | varchar(32) | explicit / wildcard / fallback |
| `priority` | int | 优先级(越大越高) |
| `is_active` | boolean | 是否激活 |
| `note` | text | 备注 |
| `create_time` / `update_time` | timestamptz | 标准时间戳 |
## 5. 规则执行时序
### 5.1 运行时加载(当前流程)
```text
文档类型确定
→ leaudit_rule_type_bindings 查绑定
→ leaudit_rule_sets.current_version_id
→ leaudit_rule_versions.oss_url
→ 下载 YAML 到本地临时文件
→ leaudit.dsl.loader.load_rules_file()
→ 进入执行链
```
### 5.2 编辑保存(后续实现)
```text
前端提交 YAML 文本
→ YAML 语法校验
→ LeAudit DSL 语义校验
→ 上传 YAML 到 OSS
→ 写 leaudit_rule_versions
→ 写 leaudit_rule_validation_logs(可选)
```
### 5.3 发布生效(后续实现)
```text
选择某版本发布
→ 更新 leaudit_rule_sets.current_version_id
→ 写 leaudit_rule_publish_logs(可选)
→ 清理/失效本地规则缓存
```
## 6. 与 OSS 的配合方式
### 6.1 路径建议
规则文件必须版本化,不能固定覆盖同一路径:
```text
oss://leaudit/rules/{rule_type}/{version_no}/rules.yaml
oss://leaudit/rules/{rule_type}/{version_no}/validation_report.json
```
### 6.2 为什么不能只用固定路径
如果始终覆盖同一个 `rules.yaml`
- 难回滚
- 难追踪历史执行结果对应的规则版本
- 本地缓存容易脏
- 无法做结果回放和审计
## 7. 种子数据:从本地 `rules/` 到 OSS + DB
当前项目 `rules/` 目录下已有 20+ 个类型目录、每个包含可用的 `rules.yaml`。需一次性导入。
### 7.1 初始化脚本逻辑
```python
# 伪代码:把 rules/ 导入 OSS + DB
for each rules_dir in rules/:
yaml_text = read(rules_dir / "rules.yaml")
rules_file = parse_rules_yaml_text(yaml_text)
version_no = rules_file.metadata.version
oss_url = f"oss://leaudit/rules/{rules_dir.name}/{version_no}/rules.yaml"
upload_to_oss(oss_url, yaml_text)
rule_set = upsert_rule_set(
rule_type=rules_dir.name,
rule_name=rules_file.metadata.name,
domain_type=classify_domain(rules_file),
status="active",
is_builtin=True,
)
version = insert_rule_version(
rule_set_id=rule_set.id,
version_no=version_no,
oss_url=oss_url,
...
)
update_rule_set(rule_set.id, current_version_id=version.id)
# 绑定文档类型(如果已知)
doc_type_id = resolve_doc_type_id(rules_dir.name)
if doc_type_id:
insert_type_binding(...)
```
### 7.2 初始化后的本地 `rules/` 处置
**推荐方案**:保留为只读紧急回退备份,标记为不再接受编辑。如果 OSS 不可用或规则全损,本地至少有一套可用的规则副本。
### 7.3 `_TYPE_ID_RULES_MAP` 硬编码过渡
`leaudit_bridge/tasks.py` 中的硬编码映射:
```python
_TYPE_ID_RULES_MAP: dict[int, str] = {
3: "行政处罚",
}
```
过渡策略:
1. **阶段 A**:保留硬编码为 fallback,同时 `leaudit_rule_type_bindings` 表已有数据
2. **阶段 B**`_resolve_rules_path()` 先查 `leaudit_rule_type_bindings`,未命中 fallback 到硬编码
3. **阶段 C**:所有绑定入库后,删除 `_TYPE_ID_RULES_MAP`
## 8. 推荐接口能力(后续实现)
- `GET /api/leaudit/rule-sets`
- `GET /api/leaudit/rule-sets/{rule_type}`
- `GET /api/leaudit/rule-sets/{rule_type}/versions`
- `GET /api/leaudit/rule-versions/{version_id}/content`
- `POST /api/leaudit/rule-sets/{rule_type}/validate`
- `POST /api/leaudit/rule-sets/{rule_type}/versions`
- `POST /api/leaudit/rule-sets/{rule_type}/publish`
- `POST /api/leaudit/rule-sets/{rule_type}/rollback`
## 9. 最终结论
- 规则内容继续保持 YAML 形态
- 持久真相源从固定本地文件改为 OSS 文件
- 数据库存规则元数据、版本、状态和 OSS 地址
- 运行时通过 "DB → OSS → 本地临时 YAML → LeAudit loader" 保持 `LeAudit` 原逻辑不变