14 KiB
规则域多租户方案 A 实施计划
适用范围:
leaudit-platform新平台规则配置、评查组、规则版本、评查运行结果链路
方案结论:采用方案 A = 共享业务树 + 租户规则绑定 + 租户结果快照
更新日期:2026-05-21
文档定位:把“规则域如何接入多租户”从概念方案落成可执行的修改计划,作为后续开发、联调、数据库迁移、验收的统一基线。
1. 定案结论
规则域本轮正式采用 方案 A,不直接做“每租户独立整棵业务树”,也不在第一阶段引入“租户扩展节点”。
当前统一口径如下:
leaudit_evaluation_point_groups继续作为共享业务树- 租户差异主要放在:
leaudit_rule_setsleaudit_rule_versionsleaudit_rule_group_bindingsleaudit_audit_runsleaudit_rule_results / leaudit_run_errors / leaudit_run_metrics
- 运行时规则生效顺序固定为:
TENANTPROVINCIALPUBLIC
tenant_code是唯一真实租户边界tenant_name只做展示与快照area / region / default / 公共 / 省级只允许留在兼容层与历史清洗层
2. 当前问题复盘
规则域目前不是“功能不可用”,而是“资产归属模型仍是全局共享思路”,因此天然不满足真正多租户隔离。
当前高风险点如下:
leaudit_rule_sets仍缺tenant_codeleaudit_rule_versions仍缺租户快照leaudit_rule_group_bindings仍缺租户边界leaudit_audit_runs仍缺租户快照,导致结果链条没有稳定归属锚点leaudit_rule_results / leaudit_run_errors / leaudit_run_metrics只能靠run_id间接推断租户auditServiceImpl运行时按group_id取规则,但没有按租户选“当前生效规则”ruleServiceImpl仍以全局rule_type -> rule_set为主语义
这意味着:
- 不同租户可能共用同一个规则集与版本链
- 一个租户发布的新版本,可能直接影响另一个租户的运行结果
- 规则结果报表、失败诊断、运行统计无法稳定按租户回溯
3. 方案 A 的边界定义
3.1 保持共享的部分
以下内容第一阶段继续共享:
- 业务树:
leaudit_evaluation_point_groups - 文档类型:
leaudit_document_types - 入口模块与业务树的主挂载关系
共享的含义不是“不做租户控制”,而是:
- 树结构本身平台统一维护
- 哪些租户能看到哪些入口/业务节点,由可见性控制解决
- 某业务节点下到底生效哪套规则,由租户绑定解决
3.2 租户化的部分
以下内容必须 tenant-first:
- 规则集归属
- 规则版本归属
- 业务组到规则集的绑定关系
- 评查运行记录
- 评查结果、错误、指标等衍生记录
3.3 暂不纳入第一阶段的部分
本轮明确不做:
- 每租户复制整棵业务树
- 租户自定义树层级结构
- 树节点级继承编辑器
- 租户扩展节点能力
这些能力只预留扩展位,不进入本轮交付范围。
4. 目标架构
规则域的目标链路收口为:
文档(tenant_code) -> 共享业务树 group -> 按 tenant_code 解析生效 binding -> 命中 tenant/provincial/public 规则集 -> 锁定规则版本 -> 创建带租户快照的 audit_run -> 结果/错误/指标带租户快照落库
核心设计点:
- 业务树是“分类锚点”
- 规则绑定是“租户差异入口”
audit_run是“历史快照锚点”- 结果表是“查询与报表加速层”,不再只靠运行时 join 推断租户
5. 数据模型修改计划
5.1 leaudit_rule_sets
新增字段
tenant_code VARCHAR(64) NULLscope_type VARCHAR(32) NOT NULL DEFAULT 'PROVINCIAL'source_rule_set_id BIGINT NULLtenant_name_snapshot VARCHAR(255) NULL
约束与索引
- 索引:
idx_leaudit_rule_sets_tenant_code - 索引:
idx_leaudit_rule_sets_scope_type - 唯一索引建议调整为:
tenant_code + rule_type + deleted_at IS NULL- 或
COALESCE(tenant_code, '') + rule_type + deleted_at IS NULL
语义
TENANT:租户私有规则集PROVINCIAL:省级统一治理规则集PUBLIC:真正公共资源域规则集source_rule_set_id:租户规则集如果来自省级继承/复制,记录来源
5.2 leaudit_rule_versions
新增字段
tenant_code_snapshot VARCHAR(64) NULLscope_type_snapshot VARCHAR(32) NULLsource_version_id BIGINT NULL
原则
- 版本归属以创建时快照固化
- 不允许完全依赖 join
rule_set才知道版本属于谁
5.3 leaudit_rule_group_bindings
新增字段
tenant_code VARCHAR(64) NULLscope_type VARCHAR(32) NOT NULL DEFAULT 'PROVINCIAL'tenant_name_snapshot VARCHAR(255) NULL
索引与约束
- 索引:
idx_leaudit_rule_group_bindings_group_tenant - 索引:
idx_leaudit_rule_group_bindings_scope_type - 唯一索引调整为:
group_id + rule_set_id + COALESCE(tenant_code, '') + deleted_at IS NULL
语义
同一个 group_id 可以同时存在:
- 一个租户私有绑定
- 一个省级绑定
- 一个公共绑定
运行时按优先级解析,不再只看 priority。
5.4 leaudit_rule_type_bindings
第一阶段处理原则
- 不再作为新主链路真相来源
- 补
tenant_code / scope_type仅用于兼容老接口与迁移脚本 - 新平台运行与配置以
leaudit_rule_group_bindings为准
5.5 leaudit_audit_runs
必补字段
tenant_code VARCHAR(64) NULLtenant_name_snapshot VARCHAR(255) NULLscope_type_snapshot VARCHAR(32) NULLgroup_id_snapshot BIGINT NULLrule_binding_id_snapshot BIGINT NULL
原因
audit_run 是整个历史追溯的锚点。
没有这层快照,后续规则换绑、租户改名、共享域清洗后,历史运行会失去稳定归属。
5.6 leaudit_rule_results
建议新增字段
tenant_code VARCHAR(64) NULLtenant_name_snapshot VARCHAR(255) NULL
原则
虽然可以通过 run_id 反查,但结果表是高频列表、导出、统计来源,补快照能避免后续大量 join。
5.7 leaudit_run_errors
建议新增字段
tenant_code VARCHAR(64) NULLtenant_name_snapshot VARCHAR(255) NULL
5.8 leaudit_run_metrics
建议新增字段
tenant_code VARCHAR(64) NULL
6. 历史数据回填策略
6.1 回填总原则
- 现有规则资产默认回填为
PROVINCIAL - 不把现有全局规则直接回填成
PUBLIC - 历史
region/default/公共/省级只作为映射依据,不作为新模型长期值
6.2 回填顺序
- 先补字段与索引
- 再给
rule_sets / rule_versions / group_bindings回填省级归属 - 再给
audit_runs补租户快照 - 最后给
rule_results / run_errors / run_metrics做快照回填
6.3 回填映射口径
- 原来全局共享规则集:回填
tenant_code='PROVINCIAL' - 原来
default / 省级 / 省局:统一映射到PROVINCIAL - 原来真正公共资源:才回填
PUBLIC
7. 运行时解析修改计划
7.1 目标规则
运行时解析“某文档某分组到底用哪套规则”时,必须以文档 tenant_code 为第一主语义。
7.2 生效顺序
固定解析顺序:
- 精确租户:
tenant_code = document.tenant_code - 省级继承:
tenant_code = 'PROVINCIAL' - 公共继承:
tenant_code = 'PUBLIC'
即:
TENANT -> PROVINCIAL -> PUBLIC
7.3 修改点
文件:
需要改造:
_resolve_rule_binding_from_group_resolve_unique_group_binding_by_doc_typeRun
目标:
- 查询绑定时显式带入
tenant_code - 绑定结果返回:
binding_idbinding tenant_codebinding scope_typerule_set tenant_code
- 创建
audit_run时直接写入租户快照与绑定快照
8. 后端改造任务拆分
8.1 R1 数据库迁移脚本
涉及:
- 新增一套规则域迁移 SQL
- 新增预检 SQL
- 新增回填验证 SQL
建议文件:
scripts/创建sql/schema_rule_domain_tenant_phase1.sqlscripts/创建sql/precheck_rule_domain_tenant_phase1.sqlscripts/创建sql/verify_rule_domain_tenant_phase1.sql
交付目标:
- 字段补齐
- 索引补齐
- 历史数据回填
- 验证 SQL 可重复执行
8.2 R2 规则资产服务租户化
涉及文件:
改造范围:
ListSetsGetVersionsGetContentCreateVersionPublishRuleVersionRollbackRuleVersion
目标:
- 规则集列表按当前租户 + 继承层展示
- 创建新版本时,不再按全局
rule_type命中资产 - 发布/回滚只影响当前租户生效链
8.3 R3 业务组绑定租户化
涉及文件:
改造范围:
ListBindingsCreateBindingUpdateBindingDeleteBindingGetRuleTemplateCreateRuleDraft
目标:
- 绑定表支持租户归属
- 同组可见绑定区分:
- 本租户
- 继承省级
- 继承公共
- 后台页面能识别“当前生效绑定来自哪里”
8.4 R4 运行链路租户化
涉及文件:
改造范围:
- 运行时选规则
- 创建
audit_run - 结果、错误、指标落库
目标:
- 运行链路 tenant-first
- 所有衍生记录带租户快照
- 后续报表不再依赖复杂 join 推断
8.5 R5 规则配置页聚合租户化
涉及文件:
目标:
ListPackSummaries与GetPack按当前租户解析生效规则- 返回新增标准字段:
effectiveTenantCodeeffectiveScopeTypeisInheritedsourceRuleSetId
- 页面能区分:
- 本租户私有规则
- 继承省级规则
- 继承公共规则
8.6 R6 鉴权与权限补齐
涉及文件:
目标:
- 所有规则域接口强制登录态
- 功能权限校验与租户上下文透传统一化
- 杜绝“裸接口 + 全局资产”的组合风险
9. 前端改造计划
9.1 规则配置页
目标:
- 展示当前规则来源
- 展示当前租户是否继承上层规则
- 发布/回滚操作前明确告知影响范围
应补能力:
- “当前生效租户域”标签
- “继承来源”标签
- “复制省级为租户私有规则”入口
9.2 评查组管理页
目标:
- 共享业务树继续展示
- 绑定列表显式展示租户域
- 避免让用户误以为业务树已经按租户独立
9.3 历史兼容口径
前端主模型不再依赖:
regiondefault- 中文共享常量
前端应统一消费:
tenant_codetenant_namescope_typeisInherited
10. 验收矩阵
10.1 规则资产
- 租户 A 创建规则版本,不影响租户 B 当前规则
- 省级发布规则,未覆盖的租户自动继承
- 已有租户私有规则的组,不再被省级发布直接覆盖
10.2 运行链路
- 梅州文档运行时优先命中
MZ MZ无绑定时回退PROVINCIALPROVINCIAL无绑定时回退PUBLICaudit_run落库后可直接看到租户快照
10.3 结果与报表
rule_results可直接按tenant_code过滤run_errors可直接按tenant_code过滤run_metrics可直接按tenant_code聚合
10.4 页面行为
- 规则配置页能显示“本租户规则 / 继承省级 / 继承公共”
- 评查组绑定页能正确显示当前生效规则来源
- 非当前租户用户不能修改本租户规则资产
11. 执行顺序
建议按下面顺序推进,不再交叉大爆改:
R1数据库迁移脚本R4运行链路租户化R2规则资产服务租户化R3业务组绑定租户化R5规则配置页聚合租户化R6鉴权与权限补齐- 前端联调与发布级验收
执行原则:
- 先补“数据真相字段”
- 再改“运行时生效逻辑”
- 最后改“后台配置与页面展示”
12. 风险与边界
12.1 高风险
rule_type当前可能被多处假定为全局唯一- 历史运行结果回填需要保证与旧
document.tenant_code一致 - 省级与公共域清洗口径必须先定死,不能一边跑一边改
12.2 中风险
- 前端若仍只展示“当前绑定”,用户会误判租户隔离是否生效
rule_type_bindings老兼容链路如果不断回写,容易污染新模型
12.3 本轮不做
- 不做租户扩展节点
- 不做独立业务树
- 不做历史规则资产自动差异合并
13. 最终交付定义
当以下 6 条同时满足时,规则域多租户方案 A 才算真正落地:
- 规则集、规则版本、组绑定都有稳定
tenant_code - 运行时规则解析已改为
TENANT -> PROVINCIAL -> PUBLIC audit_run已带完整租户快照rule_results / run_errors / run_metrics已能直接按租户查询- 规则配置页能明确展示当前规则来源与继承关系
- 发布级验收已证明不同租户互不串规则、互不串结果