feat: add tenant-scoped rule and permission management

This commit is contained in:
wren
2026-05-21 22:03:08 +08:00
parent a2c2bf1969
commit 1f1bccf3b3
193 changed files with 64463 additions and 1771 deletions
@@ -0,0 +1,409 @@
# 大版本发布验收总表(2026-05-21)
> 目标:把当前超大改动面压缩成可验收、可证明、可发布的 `RC` 版本。
> 原则:不再按“继续开发”推进,而按“关卡验收 -> 暴露故障 -> 定点修复 -> 回归通过”推进。
---
## 1. 发布前总原则
本次版本只有在以下条件同时满足时,才允许进入大版本推送:
1. 数据库结构与 SQL 脚本执行状态已确认
2. 所有 `P0` 关卡全部通过
3. 所有 `P1` 关卡全部通过
4. 关键页面与关键接口无 `500`
5.`UndefinedTable / UndefinedColumn` 级别错误
6. 核心租户边界验证完成
7. 发布说明、执行 SQL、上线步骤、观察项已整理完毕
---
## 2. 关卡定义
| 关卡 | 优先级 | 范围 | 当前状态 |
| --- | --- | --- | --- |
| `G0` | `P0` | 数据库结构与迁移脚本对齐 | 待验收 |
| `G1` | `P0` | 登录 / 当前用户 / RBAC / 租户上下文 | 已通过(人工重放 + Pytest |
| `G2` | `P0` | 租户管理 + 用户租户设置 | 已通过(人工重放 + Pytest |
| `G3` | `P0` | 首页入口 + 入口模块后台 + 新租户分配 | 已通过(人工重放 + Pytest |
| `G4` | `P0` | 文档 / 合同模板 / 公文 上传-列表-详情-边界 | 已通过(Pytest,文档主链路) |
| `G5` | `P1` | RAG 应用 / 知识库 / 会话 读写边界 | 部分通过(Pytest,当前真实权限模型) |
| `G6` | `P1` | 评查组 / 规则集 / 交叉评查 主链路 | 部分通过(Pytest,只读矩阵 + 建单边界) |
| `G7` | `P1` | 使用统计 / 审计快照 / 租户聚合 | 未开始 |
| `G8` | `P2` | 前端去角色硬编码与菜单/按钮一致性 | 未开始 |
---
## 3. 通过标准
每个关卡只允许有三种判定:
1. `通过`
2. `失败`
3. `未验证`
判定标准:
1. `通过`
- 有真实接口或真实页面操作证据
- 有明确返回结果
- 无日志级严重错误
2. `失败`
- 出现 4xx/5xx 且不符合预期
- 数据写错、查错、串租户、越权
- 页面与接口口径不一致
3. `未验证`
- 没有实际执行
- 只有历史日志,无本次独立重放
---
## 4. G0 数据库结构与脚本对齐
### 验收目标
确认这轮租户化与权限改造依赖的数据库对象,在**新数据库**中完整存在。
### 必验对象
1. `sys_tenants`
2. `sys_tenant_aliases`
3. `sys_tenant_feature_flags`
4. `leaudit_entry_module_tenants`
5. `sso_users.tenant_code`
6. 高风险阶段新增 `tenant_code` 字段与索引
### 通过标准
1. 表存在
2. 关键列存在
3. 索引存在或已确认可延后
4. 初始化种子不缺失到影响主链路
---
## 5. G1 登录 / RBAC / 租户上下文
### 核心用例
1. `POST /api/auth/login`
2. `GET /api/auth/me`
3. `GET /api/v3/rbac/users`
4. `GET /v3/rbac/roles`
5. `GET /api/rbac/user/routes`
6. `GET /admin/users/organizations/tree`
### 关注点
1. 登录是否正常签发 token
2. 当前用户是否返回正确 `tenant_code`
3. 用户列表是否按租户边界收敛
4. 路由列表是否正常返回
5. 组织树是否仍能正常读取
### 通过标准
1. `000` 可登录
2. `/api/auth/me` 返回 `tenant_code`
3. `RBAC` 只读接口无 `500`
4. 日志无 `UndefinedTable / UndefinedColumn`
---
## 6. G2 租户管理 + 用户租户设置
### 核心用例
1. `GET /api/v3/tenants`
2. `GET /api/v3/tenants/options`
3. `GET /api/v3/tenants/{tenantCode}`
4. `POST /api/v3/tenants`
5. `PUT /api/v3/tenants/{tenantCode}`
6. `PATCH /api/v3/tenants/{tenantCode}/status`
7. `PUT /api/v3/rbac/users/{userId}/tenant`
### 关注点
1. 租户能否真实新增
2. 新增后能否查到详情
3. 功能开关与能力字段能否正确保存
4. 用户租户更新后重新登录是否生效
5. 禁用租户时是否有引用保护
### 通过标准
1. 能新增一个测试租户
2. 能更新测试租户
3. 能启停测试租户
4. 能把用户切到测试租户并重新读取到正确上下文
---
## 7. G3 首页入口 + 入口模块后台 + 新租户分配
### 核心用例
1. `GET /api/home/entry-modules`
2. `GET /api/v3/entry-modules`
3. `GET /api/v3/entry-modules/{id}`
4. `POST /api/v3/entry-modules`
5. `PUT /api/v3/entry-modules/{id}`
6. `GET /api/v3/tenants/options?feature_key=home.entry_module`
### 关注点
1. 首页是否按当前用户租户展示入口
2. 后台列表/详情是否以 `tenants` 为主输出
3. 能否把新租户分配到入口模块
4. 新分配后首页是否能看到入口
### 通过标准
1. 现有入口读取正常
2. 新建或更新入口模块时可写入 `tenants`
3. 新租户分配后首页展示正确
4. 管理端和首页口径一致
---
## 8. G4 文档 / 合同模板 / 公文
### 核心用例
1. 文档上传
2. 文档列表
3. 文档详情
4. 附件追加
5. 合同模板上传
6. 公文上传与运行
### 通过标准
1. 写入不落错租户
2. 同租户可查可读
3. 跨租户不可见
4. 详情、附件、状态、运行链路不绕边界
---
## 9. G5 RAG
### 核心用例
1. 应用列表 / 默认应用
2. 会话列表 / 消息列表
3. 会话重命名 / 删除
4. 消息反馈 / StopMessage
5. 知识库创建 / 更新 / 删除
### 通过标准
1. 读链路正常
2. 写链路按租户边界收敛
3. 不再因角色名误放行
---
## 10. G6 评查组 / 规则集 / 交叉评查
### 核心用例
1. 评查组只读
2. 规则集只读
3. 规则版本创建 / 发布 / 回滚
4. 交叉评查建单
5. 补传文档
6. 成员与文档混租户拦截
### 通过标准
1. 只读链路正常
2. 敏感写操作不越权
3. 任务维度不串租户
---
## 11. 当前执行策略
本轮先执行并已固化为黑盒验收:
1. `G1`
2. `G2`
3. `G3`
4. `G4`
5. `G5`
6. `G6` 的首轮主链路矩阵
### 当前已完成补充
已新增 `pytest` 黑盒验收基座:
1. `tests/release/test_g1_rbac_context.py`
2. `tests/release/test_g2_g3_tenant_entry_chain.py`
3. `tests/release/test_role_tenant_matrix.py`
4. `tests/release/test_g4_documents.py`
5. `tests/release/test_g5_rag.py`
6. `tests/release/test_g5_rule_cross_review_matrix.py`
已通过结果:
1. 发布级黑盒验收总数:`16 passed`
2. `G1-G3`:已通过
3. 角色/租户矩阵基础:已通过
4. `G4` 文档跨租户读写边界:已通过
5. `G5` RAG 可见性与管理边界:按当前真实权限模型通过
6. `G6` 规则集/评查组只读矩阵与交叉评查建单边界:已通过
本轮验收中暴露并已修复:
1. `tenantServiceImpl._replaceTenantAliases()` 由“软删 + 重插”改为“物理删 + 重插”,解决 `PUT /api/v3/tenants/{tenantCode}` 的重复更新 `500`
执行规则:
1. 先验收
2. 出故障就只修该故障
3. 修完立刻回归
4. 不顺手扩散
---
## 12. 发布阻塞定义
以下任一项存在,直接判定为**不可推大版本**:
1. 关键写链路未验证
2. 出现 `500`
3. 出现 `UndefinedTable / UndefinedColumn`
4. 租户边界存在串数据或落错数据
5. 管理端与首页、前端与后端口径不一致
6. SQL 执行顺序和上线步骤未确认
---
## 13. 当前备注
当前仓库处于大改冻结态,后续所有推进都必须回写本总表和冻结版验收文档:
1. [冻结版进度盘点与最小冒烟验收-2026-05-21.md](/home/wren-dev/Porject/leaudit-platform/docs/权限与地区隔离/冻结版进度盘点与最小冒烟验收-2026-05-21.md)
2. 本文档
---
## 14. 本轮实测结果(G1-G3
### `G1` 登录 / RBAC / 租户上下文
判定:`通过`
实测通过:
1. `POST /api/auth/login`
2. `GET /api/auth/me`
3. `GET /api/v3/rbac/users?page=1&page_size=5`
4. `GET /api/rbac/user/routes`
5. `GET /api/admin/users/organizations/tree?include_users=false`
关键结果:
1. `000 / admin06111` 可正常登录
2. `/api/auth/me` 返回 `tenant_code=MZ`,后续切换后返回 `tenant_code=ZZRC1`
3. 组织树真实可用路径是 `/api/admin/users/organizations/tree`
说明:
1. 之前打 `/admin/users/organizations/tree` 得到 `404`,属于验收口径错误,不是后端能力缺失
### `G2` 租户管理 + 用户租户设置
判定:`通过`
实测通过:
1. `POST /api/v3/tenants`
2. `GET /api/v3/tenants/ZZRC1`
3. `PUT /api/v3/tenants/ZZRC1`
4. `PATCH /api/v3/tenants/ZZRC1/status`
5. `PUT /api/v3/rbac/users/5/tenant`
6. 重新登录后 `GET /api/auth/me`
本轮实际创建测试租户:
1. `tenant_code=ZZRC1`
2. `tenant_name=发布验收租户1-更新`
本轮修复:
1. 修复 [tenantServiceImpl.py](/home/wren-dev/Porject/leaudit-platform/fastapi_modules/fastapi_leaudit/services/impl/tenantServiceImpl.py) 中租户更新 `feature_flags` 时,软删后重插撞唯一约束导致的 `500`
### `G3` 首页入口 + 入口模块后台 + 新租户分配
判定:`通过`
实测通过:
1. `GET /api/home/entry-modules`
2. `GET /api/v3/tenants/options?feature_key=home.entry_module`
3. `GET /api/v3/entry-modules/2`
4. `PUT /api/v3/entry-modules/2`
5. 更新后再次 `GET /api/home/entry-modules`
关键结果:
1. `000` 切到 `ZZRC1` 后,首页初始返回空入口
2. 给模块 `2` 补充 `ZZRC1` 租户分配后,首页立即返回该入口
结论:
1. `租户主数据 -> 用户租户 -> 入口模块租户分配 -> 首页展示` 链路已被真实打通
---
## 15. 本轮新增实测结果(G4-G6)
### `G4` 文档上传 / 列表 / 详情 / 附件 / 删除边界
判定:`通过`
已由 `tests/release/test_g4_documents.py` 黑盒验证:
1. 租户 A 创建文档后,租户 A 可见、租户 B 不可见
2. 本租户管理员可更新本租户文档
3. 跨租户更新、追加附件、删除均被拒绝
4. 普通用户仅能看到自己创建的文档
5. 附件追加 `mergeMode=new` 当前真实行为为“生成新版本”,不是在原文档上原地追加
### `G5` RAG 应用 / 知识库 / 会话边界
判定:`部分通过`
已由 `tests/release/test_g5_rag.py` 黑盒验证的当前真实行为:
1. 全局管理员可创建并更新不同租户数据集
2. 租户管理员可读取本租户数据集详情
3. 租户管理员当前不能访问 `/api/v3/rag/datasets/admin`
4. 租户管理员当前不能创建或修改数据集
5. 本租户私有应用仅本租户可见,公共数据集挂载应用可跨租户可见
说明:
1. 这表示 `RAG` 当前已经具备租户可见性边界
2. 但“管理能力”仍保留在当前权限种子对应的全局管理侧,不能宣称已完成最终去角色化或最终权限化
### `G6` 评查组 / 规则集 / 交叉评查主链路
判定:`部分通过`
已由 `tests/release/test_g5_rule_cross_review_matrix.py` 黑盒验证:
1. 规则集元数据列表当前为全局可读
2. 规则绑定与评查组树已按入口模块租户映射做过滤
3. 交叉评查任务建单支持同租户正常创建
4. 建单时混入跨租户文档会返回 `403`
5. 建单时混入跨租户成员会返回 `403`
未纳入本轮通过范围:
1. 规则版本创建
2. 规则发布/回滚
3. 交叉评查后续提案、投票、归档深链路