docs: 记录 PR #7 合并门禁结果、两处顺手修正与权限号段冲突的来龙去脉
This commit is contained in:
@@ -111,9 +111,12 @@ DELETE FROM sys_permission WHERE id BETWEEN 9001 AND 9099
|
||||
(客服二期 3 个 + 投顾 16 个,共 19 个)。这样重建种子后权限是**完整**的,
|
||||
`grant_*.py` 退化成"局部补齐",不再承担正确性。
|
||||
|
||||
这件事在**我方公共文件**里,会影响另外几条线(跑种子的队友会多拿到 19 个权限 —— 方向是纯增益,
|
||||
但毕竟动了环境基线),所以我先跟项目方报备再动,**不需要你做任何事**;
|
||||
你若在自己环境把两个 `memory:candidate:*` 并进了种子,告我一声避免两边定义不一致。
|
||||
> **更新(合并时已办)**:项目方已同意,这 6 个权限码已并入 `seed_test_rbac.py` 的
|
||||
> `PERMISSIONS`(id **9041-9046**)—— 是 6 个不是 19 个:投顾那 13 个投顾线(`bbf623a`)
|
||||
> 早已并进种子,只有 3 个治理类(`product-governance:*`)漏了,一并补上。
|
||||
> 顺带查到库里一批 `9020-9035` 与种子的 `9020-9034` **id→code 映射冲突**(我方环境的历史遗留),
|
||||
> 已把号段整体上移到 9041-9046。
|
||||
> 详见 `docs/36-PR7合并记录与权限号段修正.md`。**不需要你做任何事。**
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
# PR #7 合并记录与权限号段修正
|
||||
|
||||
> **合并时间**:2026-09-12
|
||||
> **合并提交**:`4413644`(`merge: 合并 ZSY 的客服 Agent 接入(访客身份、画像候选、转人工工单)—— PR #7`)
|
||||
> **来源**:`origin/ZSY_develop` = `f68b052` → `qyqy_develop`
|
||||
> **规模**:90 文件、+7897 / −73
|
||||
> **门禁**:全部通过(见 §2),数据库侧无迁移、表结构未变
|
||||
|
||||
---
|
||||
|
||||
## 1. 合并内容
|
||||
|
||||
ZSY 的客服 Agent 接入线,含三块新能力与一次合规清理:
|
||||
|
||||
| 块 | 内容 |
|
||||
|---|---|
|
||||
| 访客身份 | `VisitorTokenIssuer`(`/api/v1/auth/visitor-tokens`)、`security.py` 的 `visitor:true` 分支、`auth.py` 跳过 `IdentityService.resolve()` |
|
||||
| 画像候选(二期) | 候选生成 Worker、用户确认 / 管理员审核四个端点、Milvus + Neo4j 投影适配器、`memory_sync_outbox` 消费者 |
|
||||
| 转人工工单 | 工单只读管理端点、转接上下文构造、会话凭据最小化(`conversation_privacy.py`) |
|
||||
| 合规清理(`9aaacc2`) | 删除生产死代码 `knowledge_tool_service.py` 与硬编码 Milvus 字段名的 `milvus_knowledge_adapter.py`(9 文件 +189/−483) |
|
||||
|
||||
评审往返见 `docs/33`(v1 回复)、`docs/34`(v2 回复)、`docs/35`(v3 回执核实)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 合并后门禁实测
|
||||
|
||||
| 项 | 结果 |
|
||||
|---|---|
|
||||
| `git merge f68b052 --no-ff` | ✅ 无冲突 |
|
||||
| `ruff check app tests tools` | ✅ 干净 |
|
||||
| `mypy app` | ✅ **244 文件 0 错**(基线 228,+16 为新模块) |
|
||||
| `python tools/check_authoritative_docs.py` | ✅ **49 份文档无撞号** |
|
||||
| `pytest tests/unit tests/contract` | ✅ **1275 passed, 2 skipped, 0 failed**(基线 1207,+68 为新用例) |
|
||||
| `alembic current` | ✅ 已在 `20260911_merge_adv_risk_heads`(head),`upgrade head` 无操作 → **无新迁移** |
|
||||
| `python tools/audit_schema.py` | ✅ **89 business tables, no missing or unexpected tables** |
|
||||
|
||||
> 说明:`f68b052` **单独一棵树**跑文档守卫会报 `21`/`22` 撞车 —— 那是**我方基线**的问题
|
||||
> (投顾那两份的改名在我方 `5018f11`,不在 ZSY 的基线上)。合并后消失:`21`/`22` 归
|
||||
> 风控与四大 Agent,投顾挪到 `30`/`31`。**不是 ZSY 引入的。**
|
||||
|
||||
---
|
||||
|
||||
## 3. 合并时顺手修掉的两处
|
||||
|
||||
### 3.1 `tests/unit/core/test_security.py` 的密钥路径漂移(2 行)
|
||||
|
||||
第 48、108 行原本硬编码 `Path("config/jwt/jwt-private.pem")`,**漏了 `dev/`**:
|
||||
|
||||
- `tools/generate_jwt_keys.py:107` 的默认 `--out-dir` 是 `config/jwt/dev`;
|
||||
- `app/core/config.py:26-27` 的默认值也是 `config/jwt/dev/...`;
|
||||
- 同一个文件第 13 行已定义 `DEV_KEY_DIR = Path("config/jwt/dev")`,注释写着
|
||||
「路径只在这里定义一次……避免多处硬编码各自漂移」。
|
||||
|
||||
后果:在**没有** `config/jwt/jwt-private.pem` 的环境里必红 2 个用例(本机即如此)。
|
||||
已改为 `(DEV_KEY_DIR / "jwt-private.pem")`,与第 132 行写法一致。全仓这种写法只此 2 处,
|
||||
其余 12 处引用都是 `config/jwt/dev/`。
|
||||
|
||||
### 3.2 权限号段冲突(**我方环境的历史遗留,ZSY 不受影响**)
|
||||
|
||||
**问题**:库里有一批 `9020-9035`,是本方 `tools/grant_advisor_role.py` 用**旧号段**建的;
|
||||
而投顾线(`bbf623a`)后来把 `9020-9034`(15 个)写进了公共种子 `seed_test_rbac.py`。
|
||||
两套 **id→code 映射不同**:
|
||||
|
||||
| id | 种子(投顾线) | 库里(旧 `grant_advisor_role.py`) |
|
||||
|---|---|---|
|
||||
| 9020 | `investment-goal:write:self` | `asset-allocation:generate:self` |
|
||||
| 9023 | `product-recommendation:generate:self` | `investment-goal:review` |
|
||||
| 9031 | `product-recommendation:review` | `product-governance:read` |
|
||||
|
||||
**后果**:种子的清理是 `DELETE FROM sys_permission WHERE id BETWEEN 9001 AND 9099`,
|
||||
但角色绑定只清 `role_id IN (9001,9002,9003)` —— **`advisor`(9004) 的绑定不在清理范围内**。
|
||||
所以跑一次种子会把 `9020-9034` 换成种子的语义,而 advisor 的绑定仍指向这些 id ⇒
|
||||
**advisor 会拿到错误的权限组合**,且不会报错。
|
||||
|
||||
**处置**(已改代码,见下):权限号段整体上移到 **9041-9046**,与种子的 `9001-9034` 和
|
||||
库里的旧数据都不冲突;并把"权限码的定义以种子为准"写进了三个文件的文档字符串。
|
||||
|
||||
> ZSY 侧不受影响:他的库只有 `9001-9018`,没有这批旧数据。
|
||||
|
||||
---
|
||||
|
||||
## 4. 代码改动清单
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `tests/unit/core/test_security.py` | 2 行改用 `DEV_KEY_DIR`(§3.1) |
|
||||
| `tools/seed_test_rbac.py` | `PERMISSIONS` 增 `9041-9046`(投顾治理类 3 个 + 客服二期 3 个);`CUSTOMER_PERMISSIONS` 增 `9044`;文档字符串写清「DELETE 重建」的两个后果 |
|
||||
| `tools/grant_advisor_role.py` | `ADVISOR_PERMISSIONS` 由 16 个收敛为**种子里缺的 3 个**(`9041-9043`);文档字符串记录号段冲突与处置顺序 |
|
||||
| `tools/grant_customer_service_phase2_permissions.py` | 权限 id `9036-9038` → `9044-9046`;文档字符串改为「已并入种子,本脚本仅作幂等补齐」 |
|
||||
|
||||
新增的 6 个权限码:
|
||||
|
||||
| id | 权限码 | 授给 |
|
||||
|---|---|---|
|
||||
| 9041 | `product-governance:read` | admin(治理类) |
|
||||
| 9042 | `product-governance:review` | admin |
|
||||
| 9043 | `product-governance:sync` | admin |
|
||||
| 9044 | `memory:candidate:confirm` | **customer**(确认自己的候选)+ admin |
|
||||
| 9045 | `memory:candidate:review` | admin |
|
||||
| 9046 | `handover:read` | admin |
|
||||
|
||||
一致性自检(只读):种子 40 条权限、id 唯一、无重复;两个 `grant_*.py` 的每一条
|
||||
`(id, code)` 都与种子逐字一致;`CUSTOMER_PERMISSIONS` 引用的 id 全部存在。
|
||||
|
||||
---
|
||||
|
||||
## 5. 我方环境待执行(写库,需确认后跑)
|
||||
|
||||
代码侧已就绪,但**本机数据库还没对齐**,按顺序跑(顺序不能颠倒,原因见 §3.2):
|
||||
|
||||
```powershell
|
||||
# 1) 对齐 9001-9034 到种子版本(会清掉库里 9020-9035 的旧映射)
|
||||
D:\conda\envs\jr_py313\python.exe tools\seed_test_rbac.py
|
||||
|
||||
# 2) 补投顾治理类 3 个权限 + 建 advisor 角色 + 重建绑定
|
||||
D:\conda\envs\jr_py313\python.exe tools\grant_advisor_role.py --dry-run
|
||||
D:\conda\envs\jr_py313\python.exe tools\grant_advisor_role.py
|
||||
|
||||
# 3) 客服二期 3 个权限(已并入种子,跑过第 1 步后这步通常只做授权)
|
||||
D:\conda\envs\jr_py313\python.exe tools\grant_customer_service_phase2_permissions.py --dry-run
|
||||
D:\conda\envs\jr_py313\python.exe tools\grant_customer_service_phase2_permissions.py
|
||||
```
|
||||
|
||||
⚠️ 第 1 步是 **DELETE 重建**,会重置 `customer`/`risk_operator`/`admin` 三个角色及其
|
||||
`sys_user_role` 绑定(`cust_t`/`risk_t`/`admin_t` 会被重建,密码哈希是占位 `'x'`,
|
||||
**需要重新用 `tools/set_user_password.py` 设密码**)。所以它不适合在有真实数据的环境跑。
|
||||
|
||||
### 已知的既有环境缺口(本次顺带发现)
|
||||
|
||||
本机库里 **`9018 knowledge:query` 与 `9019 knowledge:manage` 都不存在** —— 本机的 RBAC
|
||||
数据比种子旧。`knowledge:query` 是 `search_knowledge` 工具的必需权限,缺它会让客服 Agent
|
||||
调检索工具时被拒。跑上面第 1 步即可补齐。**与 ZSY 的合并无关**,是我方环境的账。
|
||||
|
||||
---
|
||||
|
||||
## 6. 遗留事项
|
||||
|
||||
| 项 | 归属 | 状态 |
|
||||
|---|---|---|
|
||||
| 品牌名(`COMPANY` 南方科技 → 奶龙基金责任有限公司) | ZSY 上报项目方 | 走 (b):保持现状,定后单行 revert,须与 `customer_service_rules.py:116/129` 一起处理 |
|
||||
| 候选流程缺走 RBAC 的集成用例(服务层测试测不出"权限码不存在") | ZSY | 他认账,承诺补 |
|
||||
| 只读真机冒烟(用真实令牌打 §19 新增端点,403 当失败) | 待 ZSY 回话 | 已提议 |
|
||||
| 环境数据不可跨环境 | 全员 | 第 4 次踩坑,已写进种子文档字符串 |
|
||||
| `docs/05` §19 端点编号 | 已解决 | `A039`/`A040`,全表 62 个编号唯一 |
|
||||
Reference in New Issue
Block a user