docs: 记录本机 RBAC 对齐的实际执行结果,以及 seed_test_rbac.py 被投顾 FK 挡住这一既有破坏

This commit is contained in:
2026-09-12 12:16:41 +08:00
parent e0468a9d9f
commit 39f7b81200
+44 -18
View File
@@ -105,32 +105,56 @@ ZSY 的客服 Agent 接入线,含三块新能力与一次合规清理:
--- ---
## 5. 我方环境待执行(写库,需确认后跑) ## 5. 本机 RBAC 对齐:实际执行记录
代码侧已就绪,但**本机数据库还没对齐**,按顺序跑(顺序不能颠倒,原因见 §3.2): 代码侧已就绪。**原计划是"种子 + 三个 grant 脚本"的全套对齐,但实测发现种子在这台环境上
根本跑不通**(见 §5.1),于是改用**不依赖种子**的方案,已执行完毕:
```powershell | 步骤 | 命令 | 结果 |
# 1) 对齐 9001-9034 到种子版本(会清掉库里 9020-9035 的旧映射) |---|---|---|
D:\conda\envs\jr_py313\python.exe tools\seed_test_rbac.py | 1 | 清理 `advisor`(9004) 的旧绑定 | ✅ 删 10 条(防 id 语义漂移,见 §3.2) |
| 2 | `tools/grant_advisor_role.py` | ✅ **按权限码重建 advisor 的 10 条绑定** |
| 3 | `tools/grant_customer_service_phase2_permissions.py` | ✅ 新增权限 `9044-9046`;授权 `customer` +1、`admin` +3 |
| 4 | `tools/grant_risk_permissions.py` | ✅ 风控 4 个权限幂等确认(本就存在) |
| 5 | `pytest tests/integration/test_auth_login_mysql.py tests/integration/test_rbac_read_mysql.py` | ✅ **19 passed** |
# 2) 补投顾治理类 3 个权限 + 建 advisor 角色 + 重建绑定 对齐后的实测状态:权限 **41 条**;绑定数 `admin 40 / customer 11 / risk_operator 10 / advisor 10 / operator 1`。
D:\conda\envs\jr_py313\python.exe tools\grant_advisor_role.py --dry-run 三个新权限的绑定实测为:`memory:candidate:confirm` → `customer` + `admin`,
D:\conda\envs\jr_py313\python.exe tools\grant_advisor_role.py `memory:candidate:review` → `admin`,`handover:read` → `admin`。
# 3) 客服二期 3 个权限(已并入种子,跑过第 1 步后这步通常只做授权) **没有跑** `tools/set_user_password.py`:种子失败后事务完整回滚,`cust_t`/`risk_t`/`admin_t`/`advisor_t`
D:\conda\envs\jr_py313\python.exe tools\grant_customer_service_phase2_permissions.py --dry-run 的 bcrypt 密码都还在(已用 `--list` 核实),无需重设。
D:\conda\envs\jr_py313\python.exe tools\grant_customer_service_phase2_permissions.py
### 5.1 ⚠️ 新发现的既有破坏:`seed_test_rbac.py` 在这台环境上已经跑不通
```
sqlalchemy.exc.IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key
constraint fails (`jr`.`advisor_profile_tag`, CONSTRAINT `fk_advisor_profile_tag_customer`
FOREIGN KEY (`customer_id`) REFERENCES `sys_user` (`id`))')
[SQL: DELETE FROM sys_user WHERE id IN (9001,9002,9003)]
``` ```
⚠️ 第 1 步是 **DELETE 重建**,会重置 `customer`/`risk_operator`/`admin` 三个角色及其 投顾线引入的 `advisor_profile_tag` 有 FK 指向 `sys_user`,而库里有数据引用 `9001-9003`,
`sys_user_role` 绑定(`cust_t`/`risk_t`/`admin_t` 会被重建,密码哈希是占位 `'x'`, 于是种子最后那步 `DELETE FROM sys_user` 被外键拒绝。
**需要重新用 `tools/set_user_password.py` 设密码**)。所以它不适合在有真实数据的环境跑。
### 已知的既有环境缺口(本次顺带发现) **好消息是种子是原子的**:`session.commit()` 在最后,失败即完整回滚 —— 本次已实测确认
(权限仍 38 条、三个用户密码完好)。**但不能依赖这一点**:哪天有人把 `commit()` 挪到中间,
就会出现"权限被删、用户还在"的半成品状态。
本机库里 **`9018 knowledge:query` 与 `9019 knowledge:manage` 都不存在** —— 本机的 RBAC **影响**:任何人在这台环境、或任何有投顾数据的环境上跑种子都会失败。
数据比种子旧。`knowledge:query` 是 `search_knowledge` 工具的必需权限,缺它会让客服 Agent
调检索工具时被拒。跑上面第 1 步即可补齐。**与 ZSY 的合并无关**,是我方环境的账。 **待定修法(需项目方定,本次未动)**,三种取向:
1. **把 `DELETE FROM sys_user` 改为 UPSERT,且不覆盖 `password_hash`** —— 破坏最小:
用户不被删、密码不丢,FK 也不会被触发。**我倾向这个**;
2. 种子只重建权限与角色、不碰 `sys_user`,用户创建交给 `create_test_user.py`;
3. 给该 FK 加 `ON DELETE CASCADE` —— 会改已有约束,牵涉规则 4,**不建议**。
### 5.2 仍然存在的既有环境缺口
本机库里 **`9018 knowledge:query` 与 `9019 knowledge:manage` 仍然不存在** —— 本机 RBAC
数据比种子旧。前者是 `search_knowledge` 工具的必需权限,缺它会让客服 Agent 调检索工具时被拒。
**因为种子跑不通,这一项本次没能补上**,已列入 §6。与 ZSY 的合并无关,是我方环境的账。
--- ---
@@ -143,3 +167,5 @@ D:\conda\envs\jr_py313\python.exe tools\grant_customer_service_phase2_permission
| 只读真机冒烟(用真实令牌打 §19 新增端点,403 当失败) | 待 ZSY 回话 | 已提议 | | 只读真机冒烟(用真实令牌打 §19 新增端点,403 当失败) | 待 ZSY 回话 | 已提议 |
| 环境数据不可跨环境 | 全员 | 第 4 次踩坑,已写进种子文档字符串 | | 环境数据不可跨环境 | 全员 | 第 4 次踩坑,已写进种子文档字符串 |
| `docs/05` §19 端点编号 | 已解决 | `A039`/`A040`,全表 62 个编号唯一 | | `docs/05` §19 端点编号 | 已解决 | `A039`/`A040`,全表 62 个编号唯一 |
| **`seed_test_rbac.py` 在有投顾数据的环境跑不通** | **项目方定修法** | 见 §5.1,三种取向待选;种子本身是原子的,已实测回滚无损 |
| 本机缺 `9018 knowledge:query` / `9019 knowledge:manage` | 我方环境 | 见 §5.2,依赖 §5.1 的修法;缺 `knowledge:query` 会让客服检索工具被拒 |