增加投顾(advisor)角色;修正登录测试的错误假设;修投顾带入的 2 处文档重号

## 投顾角色

投顾线合并后,bootstrap.py 有 10 处 allowed_roles 引用 advisor,
financial_nl2sql_service.py:272 还硬编码检查 {"advisor","operator","admin","super_admin"},
promotion_material_service.py:164 按 "advisor" in context.roles 走业务分支 ——
但 sys_role 里没有这个角色、sys_permission 里也没有投顾那 16 个权限码(种子只建到 9019)。
表现是所有投顾接口 403,而报错看起来像"权限配错了",实际是角色根本不存在。

- tools/grant_advisor_role.py:建 advisor 角色(id=9004,避开种子的 9001-9003 重建范围)
  + 16 个投顾权限(id 9020-9035)+ 授权(advisor 拿 10 项工作流、admin 补齐 16 项)。
  只增不删、可重复执行、带 --dry-run。
- tools/create_test_user.py:ROLE_IDS 加 advisor。
- 先跑 alembic upgrade head:补 21 张 advisor_* 表,业务表 68 → 89,审计通过。

权限划分:投顾工作流 10 项(read:self / generate:self / review / publish)给 advisor;
治理类 6 项(product-governance:*、profile-governance:*、asset-allocation:backtest)只给 admin。
review/publish 也给 advisor,与既有决策一致(此前已裁定不做双人复核)。

验证:advisor_t 登录 200,roles=['advisor'] data_scope=all 权限 10 项;
用它查 RBAC 清单得 403(没有 audit:read),边界正确。

⚠️ 与种子的冲突:seed_test_rbac.py 是 DELETE 重建语义,其
DELETE FROM sys_permission WHERE id BETWEEN 9001 AND 9099 会清掉本脚本建的权限。
要把投顾权限固化,应并进 seed_test_rbac.py 的 PERMISSIONS 常量。

## 修正登录测试的一个错误假设

test_issued_token_actually_works_on_a_real_endpoint 原本用客户的
/users/me/memory-profile 验证令牌可用,投顾合并后它返回 403。追下去发现**与令牌无关**:
那个接口对客户有业务前置"请先完成开户风险测评问卷",而演示客户 9001 没有测评记录。
是我的测试选错了验证端点,把"业务前置未满足"误判成"令牌坏了"。

- 改用管理员令牌调 /api/v1/admin/roles(需要 audit:read,走完整鉴权链路),
  并补一条反向对照:不带令牌必须 401,否则那个 200 说明不了令牌有效。
- 把那个业务前置单独写成一个用例,让后来者一眼看到条件,而不是反复怀疑令牌。

过程里我先按控制台乱码猜了两次失败原因,都不对;最后把响应抓成 UTF-8 文件才看到真实
消息。教训记下:不要读乱码猜消息。

## 修投顾带入的 2 处文档重号

21-投顾Agent迁移TODO.md → 30-…、22-投顾Agent灰度与回滚操作手册.md → 31-…
(沿用 NL 那次让号的先例:既有文档更早、引用更多;且这两份新文档没有被任何地方引用。)
文档守卫:40 份无编号冲突。

验证:ruff 干净 / mypy 228 文件 0 错 / 文档守卫 40 份无冲突 /
unit+contract 1207 passed(0 failed)/ integration 99 passed / 业务表 89 张。
This commit is contained in:
2026-09-11 21:49:46 +08:00
parent c4a73b735e
commit 5018f11843
7 changed files with 299 additions and 16 deletions
@@ -25,7 +25,8 @@
|---|---|---|---|---|
| 9001 | **`cust_t`** | `123456` | `customer` | 客户界面:自己的会话、适当性、知识问答 |
| 9002 | **`risk_t`** | `666666` | `risk_operator` | 风控界面:预警队列、证据、日报 |
| 9003 | **`admin_t`** | `88888888` | `admin` | 管理界面:配置发布、模型端点、审计 |
| 9003 | **`admin_t`** | `88888888` | `admin` | 管理界面:配置发布、模型端点、审计、RBAC 清单 |
| 9020 | **`advisor_t`** | `abc12345` | `advisor` | 投顾界面:组合分析、产品对比、投资目标、方案发布 |
> 密码由 `tools/set_user_password.py` 设置。**这三种弱口令仅用于演示**,
> 上线前必须全部更换。
@@ -135,9 +136,9 @@ python tools/create_test_user.py --id 9010 --username test_cust --role customer
python tools/create_test_user.py --id 9011 --username test_risk --role risk_operator --password abc12345
```
**角色只有三个可选值**:`customer` / `risk_operator` / `admin`(`sys_role` 里现成的三个)。
要引入**新角色**得同时定义它的权限集合(`sys_role_permission`),那超出这个脚本的范围,
找平台侧。
**角色可选值**:`customer` / `risk_operator` / `admin` / `advisor`(投顾)。
要引入**新角色**得同时定义它的权限集合(`sys_role_permission`)——
`advisor` 就是由 `tools/grant_advisor_role.py` 建立的,可参照它。
### 脚本会做三件事,并**验证第四件**