9.6 KiB
9.6 KiB
新平台主链路租户边界扫描报告
扫描日期:2026-05-21
范围:新平台主链路
不含:旧evaluation_points兼容链路、旧rules/list、rules/new
1. 总结论
当前新平台主链路已经不是“完全没租户化”,而是进入了一个更危险的阶段:
- 文档主表已经开始写
tenant_code - 首页入口模块已经开始按租户过滤
- 但评查组/规则集/前端上传作用域仍没有完整切到
tenant_code
这意味着系统现在处于一种“半租户化”状态:
- 一部分链路按租户工作
- 一部分链路仍按
region/area/document_type/entry_module_id - 还有一部分链路默认假设主数据是全局共享
真正的风险不是“功能不能用”,而是:
- 会把数据落错边界
- 会把旧脏数据和新租户数据串到同一条版本链
- 会在多租户复用同入口模块/同文档类型时,把用户带到错误的业务树或规则树
2. 三个最危险的核心问题
2.1 评查组/规则集主数据仍然是全局共享模型
当前:
leaudit_evaluation_point_groups没有tenant_codeleaudit_rule_group_bindings没有tenant_codeleaudit_rule_sets/rule_type仍按全局唯一思路工作
结果:
- 不同租户可能共享同一套分组树
- 不同租户可能共享同一个
rule_type -> rule_set - 一个租户新建规则版本,可能覆盖另一个租户当前使用的规则资产
这不是“显示错了”,而是规则资产归属模型本身还没分租户。
2.2 文档链路仍存在 tenant_code + region 混查
当前:
- 文档上传虽然开始写
tenant_code - 但历史版本命中、列表过滤、详情过滤仍允许
tenant_code不命中时回退region
结果:
- 同地区旧脏数据可能被续成新租户文档的新版本
- 列表和详情在历史数据上可能出现租户边界漂移
- 只要旧数据
tenant_code为空,系统就会继续依赖中文展示名做范围匹配
这是当前最容易造成“查对了表面、查错了真实归属”的问题。
2.3 前端上传和页面作用域仍未显式传递 tenant_code
当前:
- 上传页提交时主要传
region - 首页跳转主要传
entryModuleId + documentTypeIds - 子类型分组查询只按
document_type_id - 文档列表读范围也主要依赖 URL/sessionStorage 中的模块/文档类型
结果:
- 当前租户上下文在前端不是一等主语义
- 很多页面只能“假设后端已经帮你隔离好了”
- 一旦后端返回混合数据,前端没有第二道确认防线
3. 高风险问题清单
3.1 评查组/规则集后端高风险
3.1.1 RuleController 基本是裸接口
文件:
问题:
- 缺少统一
verify_access_token - 缺少功能权限校验
- 也没有数据范围/租户上下文透传
影响:
- 规则集列表、版本内容、发布、回滚、绑定增删改都可能绕过租户边界
3.1.2 CreateVersion 仍按全局 rule_type 工作
文件:
问题:
- 规则版本创建仍按全局
rule_type命中rule_set - 没有
tenant_code
影响:
- 不同租户只要规则类型编码一致,就可能共用同一个规则集和版本链
3.1.3 评查组树所有读写都没有租户谓词
文件:
问题:
ListGroupsListAllGroupsGetGroupGetChildrenListGroupsByDocumentTypesCreateGroupUpdateGroupDeleteGroupBatchDeleteRebindGroupCreateBindingUpdateBindingDeleteBinding
以上全部没有显式 tenant_code 约束。
影响:
- 管理页看到的可能是跨租户混合分组
- 修改和删除可能直接作用到其他租户的业务树
3.1.4 RebindGroup 是最高危错挂点
问题:
- 直接按
pid批量迁移子分组 - 只校验层级,不校验租户一致性
影响:
- 一次操作可能把多个二级子类型整体迁入错误根分组
3.1.5 分组/绑定表结构本身没有 tenant_code
文件:
问题:
ensure_rule_group_schema建表时就没有租户字段
影响:
- 即使服务层开始传租户,也没有稳定持久化载体
3.2 文档后端主链路高风险
3.2.1 历史版本命中仍会 tenant_code 回退 region
文件:
问题:
_find_latest_version_candidate_document_tenant_filter_sql_buildDocumentScopeFilters
都还允许 tenant_code 不足时回退 region
影响:
- 新租户文档可能接到旧地区文档的历史版本链
3.2.2 group_id / entry_module_id 仍在查询时反推
问题:
- 列表和详情展示并不完全依赖文档上传时的稳定快照
- 而是会根据当前分组树状态推断
影响:
- 配置一变,历史文档显示的业务树就变了
- 容易造成“文档看起来属于当前子类型,但上传时并不属于”
3.2.3 上传仅校验 group_id 属于 document_type_id
问题:
- 没有进一步校验:
- 是否属于当前入口模块
- 是否属于当前租户允许范围
- 是否属于当前业务树
影响:
- 只要知道一个合法分组 ID,就可能落错业务边界
3.2.4 交叉评查链路会绕过原租户范围
问题:
GetReviewPointsAuditReviewPointConfirmReviewResults
在交叉评查任务成员命中时会 bypass scope
影响:
- 如果业务上不允许跨租户交叉评查,这就是直接越界读取/更新
3.3 前端主链路高风险
3.3.1 上传页没有显式提交 tenant_code
文件:
问题:
- 当前前端主要把
tenant_name/area当region传 - 没有直接传
tenant_code
影响:
- 后端仍要猜
- 租户显示名不唯一时最容易落错数据
3.3.2 子类型分组下拉没有按 tenant_code 拉取
问题:
/api/v3/evaluation-point-groups/by-document-types- 只按
document_type_ids - 最多本地再按
entryModuleId过滤
影响:
- 不同租户复用同文档类型时,前端会把别的租户二级组混到下拉框
3.3.3 首页跳转/文档列表作用域没有显式携带租户
问题:
- 首页只传
selectedModuleId/documentTypeIds - 文档列表和上传页继续从 sessionStorage/URL 恢复范围
影响:
- 模块是对的,不代表租户也是对的
- 最容易在跨页、刷新、缓存残留时串范围
4. 中风险问题清单
4.1 后端中风险
_ensure_entry_module_valid只校验入口模块存在,不校验租户可用性_ensure_document_type_valid仍是全局文种唯一/存在校验_ensure_code_unique仍是全局唯一bootstrap_rule_groups、ensure_group_for_doc_type仍是假设全局分组树- 文档当前用户上下文仍依赖
area兼容与硬编码管理角色 review_point_audits没有租户/入口/分组快照
4.2 前端中风险
rule-groups页面没有当前租户确认层document-types页面只围绕入口模块,不围绕租户- 首页系统概览仍用硬编码
documentTypeIds推断业务
5. 低风险问题清单
- 首页仍把
user_area写入本地缓存 region仍是多个接口 VO 的正式字段- 上传接口同时暴露
typeId/typeCode/groupId/region/tenant_code多套口径 - 多个管理页缺少“当前租户/当前作用域”显式展示
6. 正确的改造顺序
第一阶段:堵住最容易落错/查错数据的链路
- 上传前端显式提交
tenant_code - 后端上传与列表停止
tenant_code -> region混查 - 上传时强校验
group_id + document_type_id + entry_module_id + tenant_code - 文档持久化真实
group_id/root_group_id/entry_module_id/tenant_code
第二阶段:补评查组/规则集的入口防线与读写边界
RuleController全面加鉴权与权限- 评查组 controller/service 全链路透传租户
- 分组树和绑定查询全部加租户过滤
RebindGroup、CreateBinding、CreateRuleDraft改成租户内操作
第三阶段:补主数据模型
- 给
leaudit_evaluation_point_groups增加租户归属 - 给
leaudit_rule_group_bindings增加租户归属 - 重新定义
rule_set是否按租户隔离 - 重做
bootstrap_rule_groups / ensure_group_for_doc_type
第四阶段:补界面确认层
- 首页跳转带上租户上下文
- 上传页/文档列表/评查组页显示当前租户
- 子类型、规则集、文档列表全部按租户查询
7. 建议接下来直接执行的第一批任务
- 后端:收紧文档主链路,去掉危险的
tenant_code + region混查 - 前端:上传显式传
tenant_code,文档列表显式带tenant_code - 后端:给
RuleController全量补 token 和权限 - 后端:评查组接口开始透传
tenant_code - 文档:补“新平台主链路租户改造实施任务单”