feat(merge): 完成 AL-09 合并接线,整合风控模块与宿主 Wave 0

- 合并 `risk-control-agent` 分支至 `merger`,实现 JWT 统一与模块 API 恢复。
- 更新 `auth_service` 和 `auth_adapter`,确保对外登录/token 统一。
- 增强 chat 模块,支持会话管理与流式对话(SSE)。
- 测试基线更新至 502 passed, 1 skipped,确保系统稳定性。

此更新标志着风控模块的成功集成,提升了系统的整体功能与可维护性。
This commit is contained in:
2026-09-08 20:00:39 +08:00
parent 6d780d45c3
commit f87e11f104
12 changed files with 100 additions and 80 deletions
@@ -36,7 +36,7 @@
| `app/gateway/trade_gateway.py` | 交易网关(C6 需透传 actor_id) |
| `app/model/suitability.py` | 适当性落库行构造(AL-04 引入,与 main 同名 → **冲突时以模块版为准**) |
| `scripts/demo/*`、`scripts/core/*` | 演示与 Core 种子脚本 |
| `tests/`(除 test_module_boundary 外) | 模块测试,406 基线 |
| `tests/`(除 test_module_boundary 外) | 模块测试;**AL-09 后全量基线 502 passed 1 skipped** |
### 1.2 B 类 · 模块私有基建(与宿主同类但模块内自用,**允许与 main 并存**)
@@ -84,7 +84,7 @@ app.include_router(chat_router)
# 模块部分:追加挂载,中间件改为模块内注册(见下)
app.include_router(risk_router)
app.include_router(simulate_router)
setup_risk_module(app) # 待 AL-09 实现:注册 audit + trace 两层 http 中间件
setup_risk_module(app) # AL-09 已完成:注册 audit + trace 两层 http 中间件
```
**注意**:main 用 `add_middleware`,我方用 `@app.middleware("http")`——两种注册方式可共存,但中间件执行顺序需实测确认(trace 必须在 audit 内层,保证 audit 能读到 trace_id)。这列为 AL-09 必测项。
@@ -160,7 +160,7 @@ AL-09 可选优化:让 `config.database` 内部转调 `utils.db.get_engine`,
| 11 | `AGENTS.md` | 文档 | 以我方为准(含 memory 六件套指引),吸收 main 新增条目 |
| 12~18 | `docs/memory/{MEMORY,TODO,REQUIREMENTS,FRAMEWORK,FLOW,ENVIRONMENT,ITERATION}.md` | 文档 | **以我方为准**(六件套是我方进度事实源),逐份吸收 main 新增实质内容 |
| 19 | `scripts/core/02-seed-base.sql` | A 私有 | 手工融合:main 账号(STAFF-10086~50001 等)+ 模块独有 **STAFF-90001**(风控演示账号,main 无!)+ C5 前置 **STAFF-31001/31002** |
| 20 | `tests/conftest.py` | A 私有 | **以模块版为准**(406 用例依赖),再把 main 的 wave0 fixture 增量并入 |
| 20 | `tests/conftest.py` | A 私有 | **以模块版为准**(502 用例依赖),再把 main 的 wave0 fixture 增量并入 |
**另有 13 个 main 独有文件不报冲突、静默并入** → 见 §1.4,全部接纳但模块不得 import。
@@ -170,7 +170,7 @@ AL-09 可选优化:让 `config.database` 内部转调 `utils.db.get_engine`,
| 硬伤 | 原风险 | 自治方案下处置 |
| --- | --- | --- |
| JWT issuer 不一致(`idp.jinrong.internal` vs `.dev`) | 统一后旧 token 全 401 | **不统一**。模块继续认自己的 issuer;跨层调用走 S2 适配器。省掉一次全量 token 重签 |
| JWT issuer 不一致(`idp.jinrong.internal` vs `.dev`) | 统一后旧 token 全 401 | **AL-09 已统一**:`/api/auth/login` → `issue_dev_token`;`gateway/jwt_service` issuer/audience 读 `settings`;旧 dev token 需重签 |
| main 无 STAFF-90001(风控演示账号) | 演示账号变 401 | 模块账号由模块 seed 维护(`02-seed-base.sql` 融合时保留),不走宿主 `DEFAULT_ROLES_BY_ACTOR` |
| main `infer_roles` 未知 actor 默认 `["analyst"]`(fail-open,含 `sql:execute:readonly`) | 越权风险 | 模块鉴权不采用 `infer_roles`;**若宿主侧修复前上线,须在 AL-09 记录为待办 P1**——模块自身为 fail-closed(缺失 X-Agent-Type 即 401) |
@@ -184,14 +184,14 @@ AL-09 可选优化:让 `config.database` 内部转调 `utils.db.get_engine`,
4. 接 S1 挂载点:`main.py` 补 router + 两层中间件,实测中间件顺序(trace 在内层);
5. 处理 S4:确认模块无 `config.database` 导入(防呆测试已覆盖);
6. 融合 `02-seed-base.sql`(保留 STAFF-90001 / 补 STAFF-31001、31002);
7. SOP §2 重灌演示库 → 全量 `pytest` 须回 **406 + 新增边界用例**全绿;
7. SOP §2 重灌演示库 → 全量 `pytest` 须 **502 passed 1 skipped** + 边界用例全绿;
8. uvicorn 冒烟:三端点 + 模块 4 API 逐个验证(注意 JWT 与 debug 头两条通道都要走一遍)。
---
## 7. 待办与遗留
- [ ] AL-09 时实现 `setup_risk_module(app)`(中间件注册函数),当前 main.py 仍为直接装饰器
- [ ] 中间件执行顺序实测(main `add_middleware` vs 模块 `@app.middleware` 双层叠加)
- [ ] 宿主 `infer_roles` fail-open 缺陷:建议在 AL-09 一并提交宿主侧修复(P1,非模块阻塞项)
- [x] AL-09 实现 `setup_risk_module(app)` 与中间件注册(2026-09-08)
- [x] 中间件执行顺序实测;trace 对 ApiError 等 re-raise(2026-09-08)
- [ ] 宿主 `infer_roles` fail-open 缺陷:建议宿主侧修复(P1,非模块阻塞项)
- [ ] 模块代码若未来要彻底隔离,可迁至 `app/modules/risk/`——本次**不做**(属重构,收益 < 风险)