Dev login no longer honors injected roles; self-service simulate/convert blocks R4 disclosure grades like the UI and chat already do. Reuse of a convert idempotency key with a different body returns 409. CT6 redeem qty is derived from T+2 lots instead of a fixed 35000; CT7-05 and CT10-07 assertions follow. Update project memory and v1.1 post-fix test artifacts.
445 lines
52 KiB
Markdown
445 lines
52 KiB
Markdown
# TODO
|
||
|
||
> 大任务开始时更新;完成一步打钩并验证后再往下。
|
||
> **新 Agent:** 先看 `MEMORY.md` §0 交接清单,再从此处取下一项。
|
||
|
||
## 进行中
|
||
|
||
**2026-09-13 · 客户线交易 + 选购清单(`app/service` · `app/tool` · `web/`)**(分支 **`merger`** · 未 commit)
|
||
|
||
> 设计 spec:`docs/superpowers/specs/2026-09-13-customer-trade-design.md`
|
||
|
||
- [x] **后端**:`trade_action_service` / `trade_flow_service`(Redis 抽槽 · 菜单序号 · `restore_flow_from_context`)· `customer_service` 交易意图与续轮 · `trade_tools` 顾问侧
|
||
- [x] **适当性清单**:多 R「有哪些」列产品 · **「我能买什么」→ `_list_purchasable_product_catalog`**(【R1】… + 全局序号 + PROD 编号 · 非计数汇总)
|
||
- [x] **解读旁路**:含 `请回复上方序号` 的清单 **不经 LLM interpret**(避免又变成「能买几只」)
|
||
- [x] **合规**:C3×R4 **揭示/双录** 助手内不可自助申购 · `subscribe_suitability_block` · prompts 规则 12–14
|
||
- [x] **前端**:`CustomerTradePage` · `TradeConfirmModal` · SSE `pending_trade` · `simulate.ts` 扩展
|
||
- [x] **持仓快照(根因修仪表盘)**:`gateway_repository` **`apply_holding_subscribe` / `apply_holding_redeem`** · `trade_gateway._maintain_lots` 申赎后同步 **`core_holding`**(与 convert 确认段口径一致)
|
||
- [x] **前端 · 能买能卖**:`tradeEligibility.ts` · 交易中心下拉 **适当性标签 + 禁用不可自助申购** · 赎回/转出仅持仓 · `?tab/product/from` 预填
|
||
- [x] **前端 · 看板刷新**:`tradeEvents.ts` **`jr:trade-completed`** · `TradeConfirmModal` 成功派发 · **`useHoldingsDashboard` + `CustomerTradesPage`** 监听
|
||
- [x] **持仓读侧补偿**:`core_ro.list_holdings_from_lots_gap` · **`customer_service.list_holdings` 合并**(历史只写批次仍能在持仓/看板看到)
|
||
- [x] **网关持仓写加固**:`apply_holding_subscribe` UNIQUE 冲突回退 UPDATE · 失败 **warning 日志**
|
||
- [x] **交易中心 UX**:非 **customer** 角色顶栏警示 · 确认 Modal **成功态自关**(父页不再 `onSuccess` 抢先关窗)· `requires_disclosure` **0/1** 口径
|
||
- [x] **前端 · 行情交易入口**:`TradeProductActions`(详情页)· `MarketQuotesPage` 客户列 **申购 / 走势·赎回 / 转换**
|
||
- [x] **单测**:`test_trade_flow_service` · `test_trade_action_service` · `test_wave2_core_ro_tool`(选购清单)· `test_wave3_customer_service` 路由 · **`test_trade_gateway.py` 33 passed**(含申赎批次维护)
|
||
- [x] **运维**:`restart-dev.ps1`(叠尸清理 · Docker 容错 · **结束 Redis 未就绪黄字提醒**)· `restart-dev.bat` · **`start-redis.ps1`(本脚本不代启 Redis)**
|
||
- [x] **前端自检**:`DevReadyBanner` 在 **`degraded`(路由 OK 但 redis=false)** 时顶栏警示
|
||
- [x] **本机验收**:客户 Demo **CUST-9527** → 交易中心或行情页申购 → **首页资产/持仓即时刷新**;下拉见「可申购/需揭示」;助手线「我能买什么」→ 序号 → Modal;换购多轮 + 回「1」不 fallback
|
||
—— **2026-09-13 第四轮端到端**([CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) **v1.2**):真浏览器对账 + 后端 raw 核对到分。**P0/P1/L1/CT6 已于同日收口并复跑取证** —— **Part A 135 PASS / 0 FAIL / 1 SKIP / 25 INFO(退出码 0)· Part B 41 PASS / 0 FAIL / 0 SKIP / 7 INFO(退出码 0)**;缺口已关闭,余 Redis 降级路径未验(见 §第四轮上报)
|
||
- [x] **可选(已读侧兜底)**:历史只写 lot 未写快照 → **`list_holdings_from_lots_gap`**;仍建议新单走网关写快照或 `reset.ps1` 清演示态
|
||
- [ ] **并入 commit `merger`**(与前端字体栈等同批或拆分,你确认后)
|
||
|
||
**2026-09-13 · 前端设计栈补强(`web/` · Inter 字体 + Radix Colors)**(分支 **`merger`** · 未 commit)
|
||
|
||
> 触发:小红书《Codex 必装高级设计感 Skill》推荐的 8 项。**逐项核实后只有 1 项是净收益、4 项完全不适用**,未照单全收。
|
||
|
||
- [x] **Fontsource Inter(真缺口 · 已落地)**:字体栈第一顺位写着 `"Inter"`,但全仓**零加载**(无 `@font-face` / 无外链 / 无依赖),一直静默回退系统字体
|
||
- `@fontsource-variable/inter` 可变字体 · `main.tsx` import · **字族名是 `Inter Variable` 而非 `Inter`**(不改则匹配不上、白装)
|
||
- `theme.ts:21` + `tokens.css:20` 字体栈 **Inter 提到最前**(拍板:全平台一致,牺牲 Mac 原生 SF Pro)
|
||
- 运行时仅下载 latin 48KB(`unicode-range` 分片;中文仍回落 PingFang/雅黑,混排无碍)
|
||
- [x] **Radix Colors(部分采用 · 已落地)**:**只引 `slate` + `jade`**,11 个品牌色**一个都没替换**
|
||
- 选用依据(CIELAB 色差):positive→jade-11 **dE 5.6** ✅ · muted→slate-10 **dE 4.9** ✅ · text→slate-12 **dE 4.8** ✅
|
||
- **刻意不引**:ink(9.5) / info(10.1) / gold(11.5) / negative(**16.0**) 均无匹配 —— 品牌色是**刻意降饱和**的(`#c9564a` 陶土红非 Radix 红、`#c9a66b` 古董金 Radix `gold` 阶里根本没有)
|
||
- **⚠️ 踩坑教训(值得写进规约)**:表面层 bg/surface/border 是**暖米黄**。纯按 dE 最小会误选**冷调 `slate`**(总分 21.5,优于暖调 `sand` 的 27.4),但 `slate-2 #f9f9fb` 是 R<B 冷色,品牌 `#f6f5f1` 是 R>B 暖色 —— **色温正负相反,dE 却只差 3**。欧氏 dE 由明度主导,看不出色温。**选色相不能只看色差**
|
||
- 新增 6 个状态阶 token `--jr-text-soft/-faint`、`--jr-positive-bg/-border/-hover/-strong`(原项目每色仅单值,无 hover/active/disabled 来源)
|
||
- [x] 验证:`npm run build` 绿 · Vitest **27/27** · lint 零新增 · **JS bundle 2,728.22 kB 与装包前完全一致** · CSS +1.88 kB(gzip +0.61 kB)
|
||
- [ ] **Simple Icons:装了但无用武之地(待拍板 留 / 删)**:全仓**零第三方品牌 logo**,应用用自己的 `public/assets/brand/logo-mark.svg` + 7 张手绘插图;业务数据只有 `PROD-110022` 类产品 ID 与净值,**无银行/基金公司名称字段**。**未编造需求去消费它**。当前零成本(`sideEffects:false` + 未被 import,bundle 一字节未涨,已实测)
|
||
- [ ] **未采纳 4 项及理由(留档,避免重复评估)**:`shadcn/ui`(Radix+Tailwind 组件体系,与 antd 6 双栈冲突:行为/z-index/主题变量/bundle 全部重复)· `Rough.js`(手绘草图感与「静奢」克制几何风冲突,"人手痕迹"已由 `global.css` 的 `.jr-grain` 噪点承担)· `README Stats` / `Markdown Badges`(GitHub README 外部图片服务,与 web 应用无关)
|
||
- [ ] **发现的既有 bug(非本次引入 · 待确认语义)**:`web/src/pages/advisor/AdvisorTemplatesPage.tsx:38` 违反 **Rules of Hooks** —— `await useScriptTemplate(auth.accessToken, useModal.id, {...})`,oxlint 报 `Hook "useScriptTemplate" is called in function "Anonymous"`(`HEAD` 原始版本即如此,已核实非本次改动所致)。**需确认 `useScriptTemplate` / `useModal` 是真 hook 还是取名带 `use` 的普通 async 函数**:若为误报,改名即消除;**若确为 hook,则当前在非组件函数中调用,条件分支下有实害**
|
||
- [ ] **技术选型文档已腐化(待确认后一并修)**:`docs/项目框架设计/技术选型和版本/01-技术栈与版本.md` §1.7 / §6.3 / §248 仍写 **Ant Design 5 + Vite 7**,实际 `web/package.json` 已是 **antd ^6.6.3 + vite ^8.2.2**。另按 MEMORY §3 硬阀门「**新增依赖须再确认**」,本次 3 个前端依赖(`@fontsource-variable/inter` · `@radix-ui/colors` · `simple-icons`)**需你确认后补登记**到该文档 §1.7
|
||
|
||
**2026-09-12 · 端到端第三轮:顾问前端 + 风控转换线 + 风控前端**(分支 **`merger`** @ `c09b987`)
|
||
|
||
> 包:[`docs/memory/tests/2026-09-12-agent-frontend-e2e/`](tests/2026-09-12-agent-frontend-e2e/README.md) · 报告 [FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md) · spec [design](../superpowers/specs/2026-09-12-agent-frontend-e2e-design.md) · plan [入库副本](../superpowers/plans/2026-09-12-agent-frontend-e2e.md)
|
||
> **174 用例 · 161 PASS / 12 FAIL / 1 SKIP → 收敛 6 缺陷 + 1 项测试资产腐化。业务代码零改动。**
|
||
|
||
- [x] **Part B 风控 API 真实 HTTP E2E**(新建 `scripts/dev/risk_e2e_smoke.py` · 64 用例 R1–R6):**63 PASS / 0 FAIL / 1 SKIP · 退出码 0**
|
||
- 过程中的 3 条 FAIL **全是脚本自身 bug**(份额自污染 · `accept_date` 格式非法实为 422 非 400 · 撤单跑在 confirm 之后),已逐条定位并修
|
||
- [x] **Part A/C 真浏览器 E2E**(仓库外 `09/10/11-*.mjs` · 47 用例):**38 PASS / 9 FAIL**
|
||
- [x] **Part A 顾问 API 复跑**(`advisor_e2e_smoke.py` 不改):60 PASS / 3 FAIL
|
||
- [x] 改写顾问报告 → **v1.1**(关闭 D1 · D3 重新定性)
|
||
- [x] 履约 superpowers:spec + plan 入库
|
||
- **待你确认后再修(P 级见下)**:**F1** 转换页预置跨主体必失败(**建议首选**)· **F2** 预警编号恒 `—` · D2 KYC 500 · F4 确认日默认越界 · F3 无路由守卫 · D3 语义检索降级
|
||
- [ ] 修完 F1/F2 后重跑 `node 10-risk-pages.mjs`,目标 **21/21 PASS**;修完 D2 后重跑 `advisor_e2e_smoke.py`,目标 **0 FAIL**
|
||
|
||
**2026-09-12 · 基金转换 T+1**(分支 **`integrate/risk-convert`** · `risk-control-agent` → `merger` 方案 A · 待合入 `merger`)
|
||
|
||
- [x] merge 冲突解完(15 文件)· `main.py` 保留平台/问数/顾问 + convert 路由 · `core_ro` 并集 + 顾问行情别名
|
||
- [x] fast-forward **`merger`** → `03fce88`(`integrate/risk-convert`)
|
||
- [x] 本机 Core convert 种子(`verify_convert_seed.py` + nav-history 可选)· `verify_convert_api.py` 9/9
|
||
- [x] 前端:`/app/risk/convert` + `web/src/api/convert.ts`
|
||
- [x] **端到端首验([FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md) v1.0)**:后端四端点 R6 全绿(202 受理 · 幂等同 `group_id` · 未确认单不含 `_CONFIRMED_ONLY_FIELDS` · 撤单 409 语义 · 确认批处理双日期 · RBAC 403)· 前端页 19/21 PASS
|
||
- [ ] **修 F1**:`RiskConvertPage.tsx:16-27` 的 `ACCEPT_PRESETS[0]` 是**跨主体组合**(`110022` 华夏/TA-CN-001 → `161725` 易方/TA-CN-002)→ 点一下就 400 `CROSS_ENTITY_NOT_SUPPORTED`。**演示路径的唯一入口不可用,建议优先修**(实测换 `PROD-000001` 即 202)
|
||
- [ ] **修 F4**:`RiskConvertPage.tsx:37` 的 `confirmDate` 默认 `2026-09-15` 落在 NAV 区间外(最新 `2026-09-11`)→ 一进来就走 `confirmed=0` 的降级路径。改为数据驱动或退化为 `2026-09-11`
|
||
- [ ] 全量 pytest 回归
|
||
|
||
**2026-09-12 · 投资顾问 Agent 合并**(分支 **`integrate/advisor-agent`** · 目标合入 **`merger`**)
|
||
|
||
- [x] 拍板 D1–D9 · 合并说明 + superpowers spec/plan
|
||
- [x] 代码接缝:`/api/advisor-agent/*` · `advisor_auth_adapter` · `advisor_db` · 话术/合规重命名 · `main.py` 挂载
|
||
- [x] Sprint0 冒烟 · OpenAPI **62** 路径 · `test_main` 更新
|
||
- [x] 本机 **`migrate-advisor-agent-sprint1-3.sql`** + 合规/话术 seed(`scripts/demo/seed_advisor_agent.ps1`)
|
||
- [x] **理财师演示前端 A**:四页 + `advisorAgent.ts` · `npm run build` + Vitest **27** 绿
|
||
- [x] **顾问线真实 HTTP 端到端验收**([TEST-2026-09-12-ADV-001](tests/2026-09-12-advisor-agent-e2e/TEST-LOG-2026-09-12-ADV-001.md) **v1.1**,2026-09-12 复跑改写):63 用例 **60 PASS / 3 FAIL / 0 SKIP** → **D1 已关闭** ✅ · D2/D3 待修
|
||
- **D1 已由 `03fce88` 修复**:`app/repository/core_ro.py:839,851` 补齐 `list_product_nav_history` / `list_latest_product_navs`,与 `app/service/market_data_service.py:40,61` 调用一致。实测 G5 市场异动 **10/10 PASS**(`scanned=14 created=2 used_fallback=False`)+ 浏览器 4/4 转绿
|
||
- **D3 定性已更正**:原假设「高层 `MilvusClient` 自动 load,所以不是未 load 的问题」**被服务端日志证伪** —— uvicorn 日志 `MilvusException (code=101, … Collection 'kb_script_templates' is in state 'released'; call load() before search/get/query)` 出现 **10 次**。**第二层**:集合目录 5.0K/2 文件 vs 已灌集合 50K/5 文件 ⇒ **疑似同时是空集**,仅补 `load()` 未必恢复召回
|
||
- [ ] **修 D2**:`app/model/entities.py:116` 的 `created_at` 无 Python 侧 default,`kyc_session_repository` 用 ORM 写且不传该字段 ⇒ 显式 NULL 覆盖 DDL 默认值 → `IntegrityError 1048`。前端取证:KYC 页「创建会话」成功,「发送采集」报 `INTERNAL_ERROR`
|
||
- [ ] **修 D3**:先确认 `kb_script_templates` 是否已灌向量(`sync_template_vectors.py`),再定 `load()` 修法
|
||
- [ ] **`test_sprint*` 全绿**(conftest 内存 SQLite + 规则种子已接;模板 seed · Core 行情 · Milvus 等待补)—— **注意**:sprint 测试全部 fake 掉 Core 提供方,**拦不住 D1 这类接缝错配**,不能替代真实端到端
|
||
- [x] 合入 **`merger`**(2026-09-12 · fast-forward `973bf1b` → `4be27c5`)
|
||
- [ ] 契约附录 · 本说明状态「已接线」· memory 基线收敛
|
||
- [ ] `git commit`(用户确认后)
|
||
|
||
**2026-09-11 批次**(`merger` · 回归 **896 pytest** 不含 sprint · `npm run build` 绿):TEST-RISK-001 · N-03/N-07 · `/api/ready` · **未 commit**
|
||
|
||
### 本批次 · 优先收尾(推荐顺序)
|
||
|
||
- [ ] **git commit `merger`**:Wave3 + analyst D-06/模板缓存 + 风控前端/灌库/深潜课7 + 问数 UI 标签 + **客服问候快路由/闲聊降级** + 答辩清单/课程 + 文档(你确认后执行)
|
||
- [x] **风控深潜课改版(方案 1 · 7 模块 · 读者 dev)**:模块 1–7 已写(含写侧并发)· `jinrong-module-risk/index.html` 已拼接
|
||
- [ ] **数据分析 · 20 题 live battery**:`run_query_battery.py` 已加 `interpret: false` · 本机 `uvicorn` + DeepSeek 跑完写 `battery_report.json`(**不入库**)
|
||
- [x] **口径字典/问数模板种子**:`scripts/dev/seed_analyst.ps1` → `seed-analyst-metric-dict.sql` · `seed-analyst-query-templates.sql`
|
||
- [x] **接口契约发群稿**:`docs/项目管理/接口契约发群-2026-09-09.md`(复制到群即完成 · TODO 已勾)
|
||
- [x] **TEST-AN-001 签核(开发侧)**:`TEST-LOG-2026-09-11-AN-001.md` v1.3 · A/B/D 已修 · **825 pytest**(含 RISK 修复 +1)
|
||
- [ ] **前端 E2E 补齐未跑测试**(见下方「前端 E2E · 未跑测试」;2026-09-10 走查只做到「路由能渲染」,**不是逐功能详测**)
|
||
|
||
### 2026-09-10 日终 · 工作清单(给用户/答辩交接)
|
||
|
||
**今天已完成(代码 + 文档 · 工作区多未 commit)**
|
||
|
||
| 类别 | 内容 |
|
||
| --- | --- |
|
||
| 前端 E2E 收口 | `AuthProvider`(登录崩溃/退出死循环)· Redis 连接超时 0.5s · 预警客户 ID 防抖 · `displayLabels`/`formatDateTime` · 对话 `**` 粗体 · 登录重入/a11y/`index.html` · AntD `<App>` |
|
||
| ChatPanel | 流式续聊 `session_id` · `sessionStorage` 恢复 · 固定高度/侧栏分页 · 用户气泡白字 · 单条删除/清空历史 |
|
||
| 会话 API | `GET /sessions?status=` · `POST /sessions/close-all` · 侧栏仅 active(服务端+客户端双滤)· close 兜底 · `test_chat` 增补 |
|
||
| 文档 | `docs/整体测试/前端整体测试交接.md`(BUG/CHAT 状态列)· `FRONTEND-HANDOFF` §8/§9 · `ITERATION` · `MEMORY`(22 Vitest)· **前端/API 优化 TODO**(本节 §前端/API · 优化) |
|
||
| 盘点 | Agent 输出「现有功能硬伤」→ 已写入下方优化 TODO(P0~P3) |
|
||
|
||
**正在做 / 未验证闭环**
|
||
|
||
- [ ] **本机验证**:重启 **uvicorn**(含 `close-all`)+ **Redis 6380** + 前端强刷 → 客户助手「清空历史」· 多轮 Chat F5 · 四角色登录/退出
|
||
- [ ] **CHAT-1~4 回归**:E2E 脚本去 `login()` 内 reload workaround(仓库外 `e2e-jinrong`)
|
||
- [ ] **PERF-1 复测**:Redis 正常后重测带 token 接口耗时,更新交接文档数字
|
||
|
||
**将要做(已记入 TODO · 推荐顺序)**
|
||
|
||
1. 上方「本批次 · 优先收尾」(commit merger · battery · 客服验收 · 发群稿)
|
||
2. `§前端/API · 优化 TODO` **P0**(启动自检 · E2E 进仓库 · PERF 复测)
|
||
3. `§2026-09-11 接续`(进页转圈 · 看板钻取口径 · 客户趋势拍板)
|
||
4. `§前端 E2E · 未跑测试` P1(对话详测 · 错误态 · 数据对账 · 边界路径)
|
||
|
||
### 2026-09-11 接续(2026-09-10 晚对话落账 · 明天干)
|
||
|
||
> 工作区已有改动 · **未 commit**。先读 `MEMORY.md` §0(Redis≠页面缓存)· §3 客户「趋势」行。
|
||
|
||
**Tonight 已做**
|
||
|
||
- [x] **TEST-AN-001 问数 RBAC**:修复 sql_guard 缺口 A/B + deny 审计 D · v1.2 测试日志 · **820 pytest**(后续 RISK/N-03 等 → **825**)
|
||
- [x] `docs/答辩/答辩知识点清单.md` + 课程对齐(总览模块 8 · 问数 D-06 模块 5)
|
||
- [x] 客服「你好」→ 问候 `keyword_route` + `CHITCHAT_DEGRADED_TEXT`(`customer_service` / `visitor_service` · 单测 `test_greeting_chitchat_without_llm`)
|
||
- [x] **前端 E2E 清单收口**(`AuthProvider` · Redis 连接超时 · 预警防抖 · `displayLabels` · 对话粗体 · 登录/a11y · `docs/整体测试/前端整体测试交接.md`)
|
||
- [x] **ChatPanel CHAT-1~4**:流式 `session_id` · `sessionStorage` 恢复 · 固定高度/侧栏分页 · 用户气泡白字 · 删除/清空会话
|
||
- [x] **会话 API**:`GET /sessions?status=` · `POST /sessions/close-all` · 前端 active 双滤 + close 兜底 · `test_chat` 增补
|
||
- [x] **TEST-RISK-001 修复(F1–F11 子集)**:`repo_access` · service_risk 只读 · compliance 矩阵 · **825 pytest** · 日志 v1.1
|
||
|
||
**明天优先**
|
||
|
||
- [ ] **前端进页转圈**:batch 净值 API 或合并请求 · 客户端 stale-while-revalidate(见 `FRONTEND-HANDOFF.md` §10)
|
||
- [ ] **看板演示口径**:四角色 `/app/{role}/home` 有图表;无 BI 大屏 · D-12 钻取仍 open
|
||
- [ ] **客户持仓产品趋势(若要做)**:拍板 Chat 历史 nav Tool vs 问数引导 · **平台行情详情已接 Core 历史** · Chat §9.6 仍仅问数 `self` 域
|
||
|
||
### 需拍板(定了再开任务)
|
||
|
||
| 项 | 选项 / 说明 |
|
||
| --- | --- |
|
||
| **C-04 阈值 push** | 维持 inline(现状) vs Redis pub / 定时扫仓 |
|
||
| **C-11 匹配说明放开度** | 已拍板:「我能买什么」→ suitability;「推荐稳赚」仍 reject |
|
||
| **`battery_report.json`** | **已拍板:不入库**(`.gitignore` · 本地跑 `run_query_battery.py` 生成) |
|
||
| **本地 `data-analysis-agent` 分支** | 是否 `git pull xinghuo data-analysis-agent` 对齐远程(与 merger 独立) |
|
||
|
||
**已拍板(2026-09-10 · 见下方风控/课程待办)**
|
||
|
||
- [x] 风控 L1/L2 Redis **不做**(仅 L3 cache-aside)
|
||
- [x] 风控前端 P1:**台账筛选 + 适当性页 + AML 扫描页一起做**(自有组件栈)
|
||
- [x] 风控演示:**`scripts/demo/prepare_all.ps1` 一键灌库**
|
||
- [x] 风控深潜课:**加模块 7(写侧并发)**
|
||
|
||
---
|
||
|
||
## 待办(统筹 · P1 推荐顺序)
|
||
|
||
> 2026-09-09 P0 主链路已通;**当前优先看上方「2026-09-10 批次」**。
|
||
|
||
- [x] **代销平台 API v0.1 实现**(2026-09-08)
|
||
- [x] **`web/` P0 脚手架 + 主链路真接**(2026-09-09)
|
||
- [x] **`web/src/api/risk.ts` 补 `X-Agent-Type: risk`**(2026-09-09)
|
||
- [x] **同步 `MEMORY/REQUIREMENTS/FRAMEWORK`**(analyst S3 · 773 基线 · D-01~D04)
|
||
- [x] **接口契约发群稿**(`docs/项目管理/接口契约发群-2026-09-09.md` — 待你复制到群)
|
||
|
||
### 前端 `web/` · P0 收尾
|
||
|
||
> **四角色 Demo 主链路已通**(登录 → Dashboard → Chat/问数/风控 REST);以下为 polish / 规格缺口。
|
||
|
||
- [x] 四角色 Dashboard · 平台只读 · ChatPanel · 游客试聊 · 行情 · 风控台账+筛选+适当性+AML+模拟交易 · 问数工作台+资产沉淀
|
||
- [x] **问数模板原句(2026-09-12)**:`match_phrases` · `/template-prompts` · 常用问法/标星/最近 · TEST-LOG-AN-002 · **861 pytest / 27 Vitest**
|
||
- [x] **问数 NL2SQL few-shot(2026-09-12)**:**仅 published 库**(去掉 `_BUILTIN_SQL_FEW_SHOTS`)· `seed-analyst-few-shots.sql`
|
||
- [x] **D-11 运行时(2026-09-12)**:dict/few_shot/template · **`GET /assets`** · **`POST …/publish`** · **`POST /dict/ambiguity-check`** · 沉淀页列表/歧义 Modal · 问数 clarify 按钮
|
||
- [ ] **D-11 后续**:rolled_back · 成功问数一键沉淀
|
||
- [x] **答辩稳套餐 ①(2026-09-11)**:A1 sql_guard Q17 · A5 流水 clarify 单测 · C1 种子 +2 模板 · D1 分析对话重定向/菜单收 · E1 `docs/答辩/DEMO-SOP-问数.md` · 答辩清单同步
|
||
- [ ] **分析对话菜单下线或强引导**(问数页已承载解读)· **看板钻取** — D-12 往后排
|
||
- [ ] **Vitest 补测**(可选):`useChatPanel` · `api/analyst.ts` mock
|
||
|
||
### 前端/API · 优化 TODO(2026-09-10 硬伤盘点 · 仅现有功能)
|
||
|
||
> 来源:E2E 交接 + 本日修复复盘 + Agent 盘点。**不含** PRD 未做能力(BI 大屏、预警 WebSocket 订阅等)。
|
||
|
||
**P0 · 演示/稳定性**
|
||
|
||
- [x] **启动自检页或 health 条**:`GET /api/ready` + 前端 `DevReadyBanner`(Redis + close-all/问数路由)
|
||
- [ ] **PERF-1 复测**:Redis 正常后重测带 token 接口耗时,更新交接文档数字
|
||
- [ ] **E2E 最小集进仓库**:登录/退出 · 客户 Chat 多轮+F5 · 清空会话(Playwright;可替代仓库外 `e2e-jinrong`)
|
||
**⬆ 优先级上调(2026-09-12 · [FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md))**:47 条浏览器用例的**脚本本体**仍在仓库外 `C:/Users/Windows/e2e-jinrong/`(`09-advisor-pages.mjs` / `10-risk-pages.mjs` / `11-cross-role.mjs` + `harness.mjs`),**他人 clone 拿不到**。
|
||
**已缓解**:本轮**结果明细与 12 张截图已随包入库**(`docs/memory/tests/2026-09-12-agent-frontend-e2e/_raw/`)⇒「结论不可被查阅」已解决。
|
||
**仍缺**:「结论不可被**重跑**」—— 建议至少把 `harness.mjs` + 一支最小脚本入库(用 `npx playwright` 免装依赖,**不动 `web/package.json`**)
|
||
**⬆ 进一步上浮(2026-09-13 · [CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md))——「腐化」已从推测变为实证**:`scripts/e2e/harness.mjs` + `scripts/e2e/12-customer-trade.mjs` **已入库**(客户线两支),Playwright 由 `PW_HOME` 解析、**未动 `web/package.json`** ✅。
|
||
**但仓库外三支本轮被击穿**:前端登录页由「一键 Demo 按钮」重写为**表单**后,仓库外 `harness.mjs` 的按钮式 `login()` 全线超时 ⇒ `09/10/11-*.mjs` **三支集体无法启动**,直到临时改写该 `login()` 才恢复。
|
||
**待办**:把 `09/10/11` 三支也收进 `scripts/e2e/`(它们依赖的 `login()` 修复只存在于仓库外的那份备份里)
|
||
- [ ] **风控演示链自检**:`prepare_all.ps1` 或 SOP §2 后台账/AML/模拟是否「有故事」(`reset.ps1` 后预警常空 — 文档化进自检提示)
|
||
|
||
**P1 · 产品语义 / 安全观感**
|
||
|
||
- [ ] **分析对话菜单** — **已重定向** `/analytics/chat` → 问数;菜单项已删(2026-09-11 答辩稳)
|
||
- [x] **前端角色路由守卫(F3)· ✅ 已修 · 第四轮独立复现转绿(2026-09-13)**:`11-cross-role.mjs` 由 **4 PASS / 5 FAIL → 8 PASS / 1 FAIL**,`C1.2–C1.5` 现为「打开=false hash=#/app/risk/home」即**正确重定向**;余 1 FAIL(`C1.6`)是**前提已失效的陈旧断言**,非缺陷([CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) §8-11)。浏览器侧另以 `B9` 直接验证:顾问直达 `/app/customer/trade` → hash 最终为 `/app/advisor/home`。
|
||
<br>**修复前原貌(存档)**:`AppLayout.tsx:20` 的 `allowedPaths` **只**用于算 Menu 的 `selectedKey`(`:23`),**未参与任何路由守卫**;`routes/menus.ts` 的 `buildMenuGroups(roleLabel)` 只做菜单隐藏。**实测**(`11-cross-role.mjs`):风控身份直达顾问四页、顾问直达 `/app/risk/convert` **全部能打开**,无重定向。**定性:不是数据越权** —— 后端 RBAC 仍生效(风控在顾问页实际点「检测」→ HTTP 403 `/api/advisor-agent/compliance/content-check`),缺口只在 UI 可见性。修法:在 `AppLayout` 或路由层加基于 `roleLabel` 的守卫,越界重定向本角色首页
|
||
- [x] **修 F2 · ✅ 已修 · 第四轮独立复现转绿(2026-09-13)**:`10-risk-pages.mjs` 由 **19 PASS / 2 FAIL → 21 PASS / 0 FAIL**([CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) §7 节 C)。
|
||
<br>**修复前原貌(存档)**:`RiskSimulatePage.tsx:138` 取 `key: 'alert_id'`(**单数**),而 `POST /api/simulate/trade` 返回 `alert_ids`(**复数数组**)⇒ 页面「预警编号」恒显示 `—`。**后端无问题**(已实测返回 `alert_ids=["ALT-20260912-A021D01E"]`),纯渲染缺陷。演示时「造预警」看着像失败,会误导重复操作
|
||
- [ ] **SSE 断流**:半条 assistant 的提示/重试或续发策略(四角色 `ChatPanel` stream)· **心跳注释帧已加**(`: ping`),断连重试仍 open
|
||
- [ ] **会话侧栏性能**:后端稳定后改为 `status=active` 分页即可,去掉全量扫页 + 双端 close 兜底
|
||
|
||
**P2 · 展示 / 数据 / 闭环**
|
||
|
||
- [ ] **I18N 扫尾**:行情/持仓风险码/图表轴等仍可能露英文或原始枚举
|
||
- [ ] **对话 Markdown**:列表/链接(现仅 `**` 粗体)
|
||
- [ ] **OBS-2 种子 UTF-8**:`fix_utf8_seed.py` + 客户资料页扩字段前必做
|
||
- [ ] **资产沉淀页**:仅有 POST 表单,补列表/发布态或菜单降级说明
|
||
- [ ] **AntD 6 弃用 API 清告警**(OBS-1 余量)
|
||
- [ ] **HashRouter 生产说明**:Nginx SPA fallback 写入 `FRONTEND-HANDOFF` 部署节
|
||
|
||
**P3 · 验证债(与「前端 E2E · 未跑测试」重叠)**
|
||
|
||
- [ ] 接口错误态逐页打断验证 · 数据与后端 raw 对账 · 适当性/模拟/AML/处置边界路径
|
||
|
||
### 客户线交易 · 第四轮上报(2026-09-13 [CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) · **初稿 6 FAIL → 2026-09-13 代码收口**)
|
||
|
||
> 初轮口径:**先报告、确认后再修**(`TEST-LOG` v1.0 仍保留当时 162/6 快照)。**同日已落地** P0/P1/L1/CT6(见 `docs/memory/2026-09-13.md`)→ **2026-09-13 19:26 已复跑取证**,三条缺陷**同期望值转绿**。
|
||
|
||
- [x] **P0 · 鉴权提权(高)**:`infer_roles()` 忽略 body `roles` · 未知 actor → 401 · `tests/test_wave0_auth.py`
|
||
- [x] **P1 · 适当性 R4「需揭示」自助阻断(中)**:`simulate_self_service_blocked` · `trade_gateway` + `convert_service` · 相关单测已绿
|
||
- [x] **L1 · 幂等键同键不同体 → 409**:`IdempotencyConflict` · `CT7-05` · `test_accept_same_client_request_id_different_body_raises_conflict`
|
||
- [x] **CT6 赎回覆盖**:`derive_redeem_qty()` · `CT10-07` 无赎回时 SKIP
|
||
- [x] **CT-001 复跑归档** ✅(2026-09-13 19:26):**Part A 161 行 135 PASS / 0 FAIL / 1 SKIP / 25 INFO(退出码 0)· Part B 48 行 41 PASS / 0 FAIL / 0 SKIP / 7 INFO(退出码 0)**;`TEST-LOG` 升至 v1.2、新增 `_raw/ct-api-report-v1.1-postfix.md` + `results-12-customer-trade-v1.1-postfix.json`;5 表还原核对 `95 / 59 / 73 / 19 / 0`
|
||
|
||
**复跑新暴露的三条(需拍板 · 均为「修复本身的残留」,非新缺陷)**
|
||
|
||
- [ ] **P0 只堵了方向①(建议补做,低成本防回归)**:`infer_roles()` 已不信任入参,但 `/api/auth/login`(`app/api/auth.py:16`)**仍无 `app_env` 门禁**、`app/main.py:103` **仍无条件挂载**。本轮只证明「注入 `roles` 不再生效」,**未证明「生产配置下非白名单 actor 一律无法登录」** —— 若日后有人改回 `if roles` 语义,缺陷原样复现
|
||
- [ ] **P1 可能收窄了业务能力(必须业务确认)**:`simulate_self_service_blocked` 把 `allowed_with_disclosure` 并入阻断 ⇒ **R4 产品自助通道完全不可下单**。原设计是「可买但需弹揭示书 + 双录」。当前实现与前端 `tradeEligibility.ts` 口径一致,但**等于收窄业务能力** —— 若期望「揭示后仍可买」,本修复是过渡方案,需另开揭示书续接流程
|
||
- [ ] **`CT3-05` 跨轮次顺序敏感(测试资产设计缺陷)**:查询窗口是 `audit_log.created_at >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)`(**墙钟**),而 `jinrong_agent` 按审计语义**永不还原** ⇒ **距上一轮 <15 分钟复跑会假 FAIL**(本轮实测踩到 `3 条`残留,等待窗口老化后才取得 `0 条`)。建议改为按**本轮 runstamp** 过滤,消除跨轮次串扰。**复跑口径已写入 README 与 `_raw/README.md`**
|
||
- [ ] **Redis 降级路径未验证**:停 Redis 复跑 CT11(`restore_flow_from_context`)**两轮均未执行** —— 唯一一条**主口径未覆盖**的功能路径
|
||
|
||
**证据链缺口(如实声明 · 不可补)**
|
||
|
||
- [ ] `_raw/shots/` 的 11 张截图被 v1.1 复跑**就地覆盖**(脚本 `shots` 路径为固定常量),**v1.0 的修复前截图不可恢复**;v1.0 的修复前结论仅有 `ct-api-report.md` 与 `results-12-customer-trade.json` 可查。**改进方向**:把截图目录改为带 runstamp 的子目录
|
||
|
||
### 测试资产腐化(T1 · 2026-09-12 [FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md) 上报 · **非产品缺陷**)
|
||
|
||
> ⚠️ 这两支**会持续报假红/假绿**,污染后续任何「全绿」结论。**未修**(本轮口径:先报告、确认后再修)。
|
||
|
||
- [x] **`scripts/demo/run_demo_smoke.ps1`**:登录改 **`POST /api/auth/login`**(`actor_id` + `token_type` · `code=0`);注释说明后续 **`/api/v1/*` 仍不存在**,整脚本需按当前路由重写
|
||
- [ ] **`scripts/dev/sandbox_risk_test.py`**:`convert` **跨主体**负例仍断言 **400 `CROSS_ENTITY_NOT_SUPPORTED`**(与当前受理模型一致 · 2026-09-13 核对**无需改**);TODO 初稿误写为「合法 convert 202 vs 400 BAD_REQUEST」—— 以脚本内 `PROD-110022→PROD-161725` 为准
|
||
- [ ] **`docs/演示文档/功能演示版启动手册.md` 等**:残留 `alembic upgrade head` 与 `/api/v1` 指引,与现状不符
|
||
- [x] **(2026-09-13 [CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) 新发现 · 已临时修补)仓库外 harness 按钮式 `login()` 被前端登录页重写击穿**
|
||
前端 `LoginPage.tsx` 由「一键 Demo 账号按钮」改为**表单**(`demoAccounts.ts` 的 `DEMO_ACCOUNTS` 已置空并标 `@deprecated`)⇒ 仓库外 `C:/Users/Windows/e2e-jinrong/harness.mjs` 的 `getByRole('button', {name:/客户 Demo/})` 全线超时,**`09/10/11-*.mjs` 三支集体无法启动**。
|
||
**本轮处置**:仅替换该 harness 的 `login()` 为「填 `input#loginId` → 点表单登录按钮」,**既有断言一字未改**(备份 `harness.mjs.bak-pre-20260913`);三支随后恢复并**转绿**(09 → 17/0 · 10 → 21/0 · 11 → 8/1)。
|
||
**残留**:① 该修复只存在于**仓库外**那份文件里,需随「E2E 最小集进仓库」一并收编;② `11-cross-role.mjs` 的 `C1.6` 是**前提已失效的陈旧断言**(假定顾问页对风控用户会打开,而 F3 修复后应被重定向)⇒ 应改断言或删除
|
||
**教训**:这正是「脚本在仓库外 ⇒ 无法随产品改动同步」的实证,不再是推测
|
||
|
||
### 前端 E2E · 未跑测试(2026-09-10 走查缺口)
|
||
|
||
> ✅ **部分已补(2026-09-13 第四轮 · 客户线)**:`B10` 用 `page.route` 强制 500 验证了**接口错误态**(`ApiErrorResult` 渲染 code/message/trace_id);`B3.2`/`B4.1`/`B8` 把**前端渲染值与后端 raw 对账到分**(总资产 Δ 恰为提交金额 · 明细行文本 · 弹窗 payload)。**但仅限客户线**,顾问线/风控线/问数线的同类对账仍未做。详见 [CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) §4。
|
||
|
||
> ⚠️ **口径说明:** 2026-09-10 那轮 E2E **不是逐功能详测**。25 条路由的断言只是「页面渲染出来 + 无 console error + 无 4xx/5xx」,
|
||
> **页面上的数字、图表、交互是否正确一律未验证**。下面这些是**明确没跑**的,**复测前不要当作已验证**。
|
||
> 报告与脚本:`docs/整体测试/前端整体测试交接.md` · 脚手架在仓库外 `C:/Users/Windows/e2e-jinrong/`。
|
||
> **反例佐证:** CHAT-1~4 这四条真实缺陷是**后来别人发现的**,走查时完全漏掉 —— 因为对话线每条只发了 1 句就收工。
|
||
|
||
**P1**
|
||
|
||
- [ ] **对话模块详测**(最优先 · CHAT-1~4 已修需回归):多轮连发 · F5 刷新保持同一 session · 会话侧栏分页 · 会话切换/删除/关闭 · 并发发送 · 超长消息 · 断流重连
|
||
- [ ] **接口错误态**:主动打断后端(停 uvicorn / 改 proxy 返 500 / 制造超时),逐页验证 `ApiErrorResult` 是否给出 code / message / trace ID + 可重试 —— 这是 `FRONTEND-HANDOFF.md` §8 白纸黑字的验收项,**本轮完全未验证**
|
||
- [ ] **数据正确性**:拿后端原始响应逐项核对前端渲染值(持仓市值/盈亏、AUM、预警条数、仪表指标卡)—— 本轮**一次都没对过**
|
||
- [ ] **业务边界路径**:
|
||
- 适当性:只跑了 A-1 阻断,**通过路径未测**
|
||
- 模拟交易:只跑了放行,**风控拦截路径未测**
|
||
- 预警处置:只提交一次,**其余状态流转 / 校验失败未测**
|
||
- AML 扫描:只全量跑一次,**未核对结果正确性**
|
||
|
||
**P2**
|
||
|
||
- [ ] **图表正确性**:`@ant-design/charts` 数据映射、空数据、单点、极值 —— 本轮只确认「渲染出来没报错」
|
||
- [ ] **排序/分页正确性**:只确认「点了不崩」,**未验证排序真的有序、翻页真的换内容**
|
||
- [ ] **资产沉淀**:只确认表单渲染,**从未提交过一条**
|
||
- [ ] **客户档案**:只看到 5 个字段(customer_id / display_name / risk_code / risk_expires_at / phone_masked),其余字段渲染未验证(另见 OBS-2 后端 `occupation:"???"` 乱码)
|
||
- [ ] **掩码持久化**:眼睛按钮状态跨路由 / 刷新 / 重登录的行为未全量验证
|
||
- [ ] **PERF-1 复测**:Redis 起到 6380 后重测接口耗时 —— 当前记录的 **2.05s 是 Redis 未起环境下**的测量值,环境修好后数字会变
|
||
- [x] **simulate 交易 UI**:风控菜单「模拟交易」+ `RiskSimulatePage` + `api/simulate.ts`(演示说明 · A-3/A-1 预设)
|
||
- [x] **接口契约发群稿**(见 `docs/项目管理/接口契约发群-2026-09-09.md` · 复制到群即完成)
|
||
|
||
## 待办(模块侧开放项)
|
||
|
||
### 客服 Agent · S2 接缝(2026-09-09 已接线 · 并行分流)
|
||
|
||
> 清单:`docs/项目框架设计/客服Agent-合并说明.md` §3–§4 · 原则只增不盖、不覆盖 `main.py`/`chat.py`/`agent_service.py` 整体。
|
||
|
||
- [x] **跑迁移 SQL**:`scripts/agent/migrate-customer-agent-cs-c11.sql`(`conversation_archive` · `customer_notes`)(2026-09-09 本机已执行)
|
||
- [x] **挂游客路由**:`POST /api/chat/visitor` → `main.py`
|
||
- [x] **编排接缝(并行)**:`X-Agent-Type: customer` → `customer_service.run_customer_chat`;其余 Agent 仍 `agent_service.chat`
|
||
- [x] **Wave 3 测试解禁**:`test_wave3_customer_service.py` 19 例绿 · 基线 **554 passed**
|
||
- [x] **Wave 1/2 解禁**:`test_wave1_*` · `test_wave2_*` 已移出 `collect_ignore` 并绿(132+ 例)
|
||
- [x] **Wave 3 profile / 4 / 5 解禁**:`test_wave3_profile_service` · `test_wave4_e2e` · `test_wave5_notes` · 基线 **730 passed**
|
||
- [x] **1B/R1 拍板落地**(2026-09-10):`sanitize_postprocess` · Top-K · TEST-LOG · 776 pytest
|
||
- [x] **Wave3 能力批次**(2026-09-10):C-04 threshold · C-05 nav · C-11/C-07/C-08 · visitor 1B 对齐 · keyword 优先级 · **786→795 pytest**
|
||
- [x] **企业级测试包** `docs/memory/tests/2026-09-10-customer-1b-r1/`
|
||
- [x] **课程 layout 修复**(2026-09-10):`showLayer` 单参回退 · `.module-inner` CSS 别名 · `build_all.py`
|
||
- [x] **客服 KB 第二套(fin_*)· Ollama 灌库**(2026-09-09 本机):
|
||
1. `ollama pull bge-m3` ✓
|
||
2. Ollama 服务 `http://127.0.0.1:11434` ✓
|
||
3. **Windows**:`MILVUS_URI` 须英文绝对路径(如 `C:/Users/Windows/.jinrong/milvus/milvus.db`),中文项目路径 faiss 会炸
|
||
4. `python scripts/kb/build_collections.py --rebuild`(原料 `data/kb_collections/`)✓ 9 块
|
||
5. `python scripts/kb/test_search.py` ✓
|
||
- [x] **客服 RAG 接 fin_* 三库**:`VisitorRagService` → `search_cs_knowledge`(`fin_product` / `fin_policy` / `fin_faq`);宿主 Tool 仍走 `kb_product_rules`(T-21)
|
||
- [x] **tool 层实现 + 种子文档**:`document_parser` / `embedding_tool` / `milvus_tool` + `data/kb_collections/*`(2026-09-09)
|
||
|
||
### 数据分析 Agent · S3 接缝(2026-09-09 已接线)
|
||
|
||
> 清单:`docs/项目框架设计/数据分析Agent-合并说明.md` · **825 passed** · 冒烟 `scripts/dev/smoke_analyst.py`
|
||
|
||
- [x] merge + 接缝(`analyst_router` · `analyst_auth_adapter` · 问数走 `get_platform_auth_context`)
|
||
- [x] customer `self` 域 + 「AI 分析有风险」尾注
|
||
- [x] Wave6 测试 · 迁移 `migrate-analyst-d07-d11.sql` · 重置 `reset-analyst-d07-d11.sql`
|
||
- [x] 前端问数页 · Scope B 冒烟 19/19
|
||
- [x] **P2 · D-11 资产沉淀 UI**(`AnalystAssetsPage` · `POST /api/analyst/assets`)— **仅写 draft 表,未接 NL2SQL/发布(2026-09-12 拍板延后)**
|
||
- [x] **P2 · 问数页 dashboard 卡片**(`GET /api/analyst/dashboard` · `AnalystQueryPage` 顶部 metrics)
|
||
- [x] **P2 · 口径字典种子 SQL**(`scripts/agent/seed-analyst-metric-dict.sql` · 本机需手工执行)
|
||
- [x] **customer Chat SSE**(`chat.py` stream → `prepare_customer_stream` · 前端 `mode="stream"`)
|
||
- [x] **STAFF-30001/30002 追加 risk_demo**(`jwt_service.py` · 模拟交易页可造预警)
|
||
- [x] **445cfbb 功能层 cherry-pick**(2026-09-10):`guardrail.py` · `dict_service.py` · wave6 测试 · `run_query_battery.py`
|
||
- [x] **D-06 双层缓存**(2026-09-10):结果缓存+表世代写侧失效 · 模板填参 · 问数页标签 · 种子 SQL
|
||
- [ ] **D-09 多轮追问** · [x] **N-03 溯源明细** · [x] **N-07 转人工** — N-03/07 最小闭环(sample + escalate + 问数页按钮)
|
||
|
||
### 数据分析 Agent · 445cfbb 合入后开放项
|
||
|
||
- [ ] **20 题 live battery 跑分**(见上方「本批次 · 优先收尾」)
|
||
- [ ] **agent 编排接流水 Ambiguity**:`dict_service` 已返 Ambiguity · 确认 `analyst_agent` 反问链路在 live 20 题里生效(Q 含「流水」)
|
||
- [x] **D-06 写侧主动失效**(2026-09-10):表世代 bump · 模拟交易 `core_trade` · 预警/L3 写侧 · `invalidate_tables` + 单测
|
||
- [x] **D-06 模板缓存**(2026-09-10):`template_service` 匹配+填参 · 问数编排跳过 LLM · 种子 `seed-analyst-query-templates.sql`
|
||
- [ ] **D-06 PII 脱敏后再缓存** — 暂缓(全仓脱敏方案未定)
|
||
- [ ] **已知挂账(迭代文档)**:Q7 无城市字段静默改职业 · 待排期(**Q17 已修**)
|
||
- [ ] **远程分支同步**(可选):本地 `data-analysis-agent` @ `fd9464d` 落后 `xinghuo/data-analysis-agent` 2 commit
|
||
|
||
### 风控 Agent · 2026-09-10 拍板收口
|
||
|
||
> **后端主链路(FR-1~10 · 对话 6 Tool · 处置 API)已完成。** 下列为 polish / 演示 / 文档,不是「风控坏了」。
|
||
|
||
**拍板(已定 · 不再扩 scope)**
|
||
|
||
- [x] **画像 Redis L1/L2 不进风控**:L1/L2 热缓存归**客服线**(`customer_service` + `ProfileHotCache`);风控只保留 **L3 cache-aside**(`profile_l3.get_profile_l3` · `customer_context` Tool 已走)— **不做** risk 侧 L1/L2 Redis
|
||
- [x] **前端用自有组件**:扩页时复用 `PageShell` · `Button`(`components/ui`)· `ApiErrorResult` · AntD `Table/Modal/Select`(对齐 `RiskAlertsPage` / `RiskSimulatePage`),不新引 UI 库
|
||
- [x] **模拟交易 UI 已有**:`RiskSimulatePage` + `api/simulate.ts`(A-1/A-3 预设)
|
||
|
||
**P1 · 前端代码(2026-09-10 拍板 · 三页一起做 · 2026-09-10 完成)**
|
||
|
||
- [x] **台账筛选 UI**:`RiskAlertsPage` · `alert_type` / `customer_id` / 日期窗
|
||
- [x] **适当性检查页**:`RiskSuitabilityPage` · `POST /api/risk/suitability/check`
|
||
- [x] **AML 扫描页**:`RiskAmlScanPage` · `POST /api/risk/aml/scan`
|
||
- [x] **路由/菜单**:`/app/risk/suitability` · `/app/risk/aml-scan`
|
||
|
||
**P1 · 演示一键灌库(2026-09-10 完成)**
|
||
|
||
- [x] **`scripts/demo/prepare_all.ps1`**:双库 DROP → core + agent 种子 → AML → prepare_risk_demo → sync_advisor_rel
|
||
- [x] **TEST-RISK-001 修复**:见 `docs/memory/tests/2026-09-11-risk-agent-e2e/TEST-LOG-2026-09-11-RISK-001.md` v1.1 · `sandbox_risk_test.py` D 节期望 `TypeError`
|
||
|
||
**P2 · 深潜课(2026-09-10 完成)**
|
||
|
||
- [x] **模块 7 · 写侧并发**:`modules/07-concurrency.html` · nav 7 dots · `build.sh` / python 拼接 `index.html`
|
||
|
||
**后端 / 架构 · 挂账(非 P1 · 动契约前先出方案)**
|
||
|
||
- [ ] **AL-06**:chat 链路 `risk_suitability_log.actor_id` 暂落 SYSTEM(`agent_tool_call` 已覆盖发起者;改须动 `core_tools`/`kb_tools` 冻结签名)
|
||
|
||
**对话 Tool(risk Chat SSE)— 已完成**
|
||
|
||
- [x] risk Chat SSE(`ChatPanel` · `X-Agent-Type: risk`)
|
||
- [x] 6 只 Tool 已注册(含 `query_agent_behavior`)
|
||
|
||
**运维 / 演示 checklist(脚本已有 · 非产品化 · 见 `演示SOP-风控模块.md`)**
|
||
|
||
> 走查时手工跑即可;**不等于**后端缺 API。
|
||
|
||
- [ ] `subscribe_alerts.py` → Redis `risk:pub:alert` 实时推送演示
|
||
- [ ] `escalation_scan.py` / `agent_behavior_scan.py`(FR-9/10 · cron 无 UI,运维手跑)
|
||
- [ ] `rebuild_alerts.py`(engine_error 补偿)
|
||
- [x] SOP §2 灌库:`seed-aml-list.sql` + `prepare_risk_demo.sql`(`reset.ps1` 只重建 core)→ **`prepare_all.ps1` 一键串联**
|
||
- [ ] 走查样例 A-1~A-5 · FR-9/10 · L3 high 样例(文档步骤,非代码任务)
|
||
|
||
### 客服 Agent · Wave3 开放项(2026-09-10 后)
|
||
|
||
- [x] **C-04 push/cron(演示最小)**:`POST .../threshold-check?push=` · `scripts/demo/push_threshold_alerts.py` · 持仓页「检查阈值提醒」
|
||
- [ ] **C-05 Phase B**:`nav-snapshot` **外部 sync**(Core 内 **07 历史种子 + nav/history API + 详情页** 已做 · 见 v0.2 草案)
|
||
- [ ] **C-08 偏离检测**:仅 L1 槽位,无自动调仓建议
|
||
- [ ] **Vitest**:客户 Chat 新 intent 无前端单测(后端已覆盖)
|
||
- [ ] **手工验收 + TEST-LOG 签核**(见上方「本批次 · 优先收尾」)
|
||
|
||
### 画像 Redis · cache-aside(2026-09-09 · **客服域,非风控**)
|
||
|
||
- [x] **L3 热读(风控)**:`get_profile_l3` cache-aside · `customer_context` Tool 已走此路径
|
||
- [x] **L1 懒读(客服)**:`ProfileHotCache.get_style_tags_lazy` · 写侧 `warm_l1` · `customer_service` 已切懒读
|
||
- [ ] **L2 热读/写(顾问)**:表与 JWT scope 已有 · Repository/Redis **未实现** — **风控不做**
|
||
- [x] **【前端接入·方案 B】chat 拉侧三端点**(commit `8328c24`,2026-09-08):`GET /api/chat/sessions`(本人+本 Agent 线分页列表)、`GET /api/chat/sessions/{id}/messages`(历史消息升序分页,closed 仍可读)、`POST /api/chat/sessions/{id}/close`(active→closed,重复/非 active 409);chat.py 抽 `_resolve_agent_type`/`_assert_chat_entry`/`_guard_session` 三守卫供四端点共用,POST "" 行为零回归;risk_manager 在对话线数据面保持 403(PRD 4A.1)。测试 482→**494 绿**;独立评审 P0=0,P1(close 并发 rowcount 静默 200)已修复
|
||
- [x] **【前端接入·方案 C】SSE 流式对话**(commit `01ec5fc`,2026-09-08):新增 `POST /api/chat/stream`(OpenAI 兼容 chunk:首帧 meta → delta → finish_reason=stop → `[DONE]`);`agent_service.stream_chat` 生成器 + `needs_disclaimer`;`_guard_request`/`_prepare_turn` 与同步端点共用守卫;`session_repository.insert_turn` user+assistant 同事务落库(修评审 P0/P1)。测试 494→**503 绿**。遗留:无心跳帧、断连留空会话待清理
|
||
- [x] chat 同步/流式落库免责声明口径统一(2026-09-09):`chat.py` `_assistant_content_for_persist` · sync/stream 共用 · `test_chat` 回归
|
||
- [x] 2026-09-05 memory 文件夹更新(新 Agent 交接清单)
|
||
|
||
> **AL-09 已完成(2026-09-08)**——见 `docs/项目框架设计/合并注意事项-风控模块并入main.md` 执行记录。
|
||
|
||
- [x] **【AL-09】合并接线**(2026-09-08):JWT 统一 · 模块 chat 恢复 · auth_adapter · test_module_boundary 绿 · **502 pytest 绿**
|
||
|
||
- [x] T-04 Core RO 封装为 Tool 节点;A-01 归属校验(chat Tool 接入 + agent_tool_call 落库)—— **完成(2026-09-07)**:`app/tool/core_tools.py`(L0/持仓/流水三只读 Tool + TOOL_REGISTRY 白名单)+ `app/service/tool_service.py`(关键词意图仅 customer/advisor;归属校验对齐 deps.assert_customer_access 口径——Tool 层拒绝不抛 403 而 blocked 留痕,纵深防御;run_tool 执行+落库,落库失败降级)+ agent_service 图 tool 节点(START→tool→llm→guard;结果注入 LLM 上下文,降级回复带摘要)+ session_repository.insert_tool_call(message_id 一期 NULL)。**A-01 口径:本任务只做 Tool 层归属校验语义(customer 本人/advisor assigned/risk_officer 全量/其余拒),A-01 完整场景(代理人画像)仍归 T-20**;risk 分支四 Tool 归 C1 复用 run_tool。**评审闭环(2026-09-07):首评 P1×2+P2×3+P3×2 → 修复 `40a9ee2` → 复审 P2×1+P3×4 → 修复 `1216d26`,pytest 321 绿;入参白名单+days 钳制、公共鉴权双写 `utils/authz.py`、list_holdings LIMIT 均落地**
|
||
- [x] T-21 Milvus Lite + kb_product_rules 首批入库 —— **完成(2026-09-07,commits e34973f~535c8a0 共 6 个 + 评审闭环 9cc2e59)**:`app/service/embedding.py`(Ollama bge-m3 批量 /api/embed 1024 维,四类失败一律 EmbeddingError 不静默降级)+ `app/service/milvus_service.py`(kb_product_rules 幂等建集合+upsert+search_kb 溯源/effective_date 合规过滤)+ `data/kb/` 6 只种子产品手册(prospectus/fee/rule/risk 四节 24 块)+ `scripts/kb/build_kb.py`(--dry-run/--kb-dir)+ `app/service/rag_service.py` 落地(search_knowledge→chunks+source_refs,异常上抛防 LLM 编造)+ `app/tool/kb_tools.py` 挂注册表第三层(**ToolSpec 新增 skip_access_check**:公开知识无归属语义,advisor 无绑定客户可查;意图层限定 customer/advisor,risk 不开放——用户拍板)+ tool_node 按 spec 白名单注入 query + summarize 溯源口径。**真库验收:24 块入库,search_knowledge("基金申购") Top3 命中申赎规则(score 0.73+),溯源完整**。三坑收口:Milvus Lite 跨进程重开须显式 load / faiss 不支持中文路径(本机 .env 改 C:/Users/YUAN/.jinrong/milvus/)/ build_kb sys.path 引导。知识库 API(上传/重建端点)一期不做(knowledge.py 仍空壳,用户拍板),425 绿
|
||
- [x] T-03 输入防护规则(F-03:prompt_injection/oversize/限流)—— **完成(2026-09-07,commits 497554d/65b45aa/cc6f34f/207fc79)**:`app/service/input_guard.py`(注入短语词表 42 条四类纯函数检测 + `inspect_message` oversize 4000 先于 injection + `check_rate_limit` Redis INCR 固定窗口 actor 级 30 次/分 fail-open)+ chat 路由接入(顺序:鉴权→准入→空白→限流 429→注入/超长 400→归属→会话;被拒 fail-fast 不建会话不落消息,blocked 落 input_guard_log,留痕降级不改拒绝语义;Pydantic 硬顶 20000,业务限 4000 移 guard 层换留痕)+ redis_gateway.incr + settings.guard_rate_limit_*;拍板:命中即拒不清洗、仅 blocked 留痕、词表代码常量可审计。**独立 AI 评审 PASS with findings(P0=0;P2×3 已收口:词表断言修正/补 7 条同构变体/窗口 TTL 断言+EXPIRE 失败取舍锁定;P3 已收 session_id 截断,挂账对抗变体扩表)**,378 绿
|
||
- [x] 风控阶段 C(C0 pytest-asyncio / C1 chat_tools / C2 risk 分支 StateGraph / C3 A-6 验收)—— **完成(2026-09-07)**:`app/service/risk/chat_tools.py` 四只读 Tool(alert_query/customer_context/suitability_check/aml_lookup)挂 `RISK_TOOL_REGISTRY`;`tool_service.run_tool` 改查 core+risk 统一注册表 `get_registered_tool` 且恒传 `risk_repo`;`_normalize_params` 读 spec 白名单;`match_intent` 按 agent 分组扩 risk 关键词;`agent_service.tool_node` 守卫放宽(`requires_customer=False` 允许无绑定客户,支撑 A-6 全量待审);A-6 验收+诱导处置边界(无处置 Tool、系统提示禁自动处置、诱导只触发只读且预警状态不变);**独立 AI 评审 PASS(P0=0,P2 补 advisor 归属/空 product_id 单测已收口),345 绿,tag `risk-m3`**
|
||
|
||
### 风控模块(PRD v1.0 已冻结 · `docs/PRD/PRD-风控监测Agent.md`,事件驱动线不依赖 T-07 可先行)
|
||
|
||
- [x] T-30 风控事件线 —— **全部完成(B1~B9b,M2 tag risk-m2)**:规则引擎/预警聚合/L3/AML/交易网关/4 API/演示走查 11/11 PASS + 核查单①~⑥收口,均经独立 AI 评审闭环;scan_all 幂等读后写无锁留痕(接批量时 run_locked)
|
||
- [x] T-31 `service/suitability.py` 公共校验(SUIT-001~008)+ `POST /api/risk/suitability/check` —— **交付=suitability 服务函数+单测(77 例;check API 随 B6 带鉴权+直调审计);MySQL 手工 SQL 对照(阶段 A 评审 P2-8)2026-09-07 收口:4 组演示组合真库 SQL 推导与函数判定逐项一致(演示 SOP 核查单附行)。【2026-09-07 阶段一退役】SUIT-001~008 编号体系已随 AL-05 换核退役,判定内核改为 main 的 core_ro.check_suitability(C×R 矩阵 + JR-AST/FM 契约),测试按 main 契约重写(原 77 例作废,全量基线 425→406)**
|
||
- [x] T-32 预警台账与人工处置 API + 对话线 —— **台账/处置 API 已由 B6 覆盖并复审通过(A-7/A-9 用例绿);交付=对话线,归阶段 C(C1~C3,T-07 已就绪)**
|
||
|
||
## 已完成
|
||
|
||
- [x] 2026-09-07 风控 M2 收尾(M4 复核):MEMORY/TODO 状态与边界文字对齐(任务映射 T-30/T-31/T-32 口径确认;B7 复审留痕「成功响应不包裹外壳」演进口径维持并登记开发计划 M4 节)——风控阶段 B 正式完结
|
||
- [x] 2026-09-07 T-01 JWT 鉴权(commit 36f476f + 评审闭环 61711cb):`app/service/auth_service.py` Auth SDK(HS256 dev/RS256 生产、必填 claims 显式校验、jti 吊销 fail-open、RS256/HS256 算法白名单互斥)+ `deps.get_auth_context` 工厂替换(Bearer 全环境优先;debug 头降级 dev 兜底,双闸门=APP_ENV+无 RS256 公钥)+ X-Agent-Type 交叉校验(手册 §4.6/§5.4 AGENT_ACCESS_MATRIX)+ `scripts/dev/issue_dev_token.py` 签发 CLI + lifespan 改验 jwt_ready
|
||
- [x] 2026-09-07 T-02 审计中间件(commit 3cec034):`app/api/audit_middleware.py` http_access 全量访问审计(actor 经 request.state.auth,排障路径/OPTIONS 跳过,写库失败降级)+ 独立 request_id(X-Request-Id 贯通,B7 复审 P3-4)+ 422/404/405/500 统一错误体(500 由 trace 中间件兜底回写 trace 头,B7 复审 P2-2)+ input_guard_log 双写(挂账⑧收口;401 归 platform、四 Agent 入口写 guard)
|
||
- [x] 2026-09-07 T-07 LangGraph 骨架(commit fb18c04):`agent_service` StateGraph(llm→guard)+ DeepSeek/langchain-openai(无 key 降级明确标注)+ 四 Agent 边界 system prompt + customer/risk 免责声明(has_disclaimer)+ 单测 mock LLM 不依赖外网
|
||
- [x] 2026-09-07 T-06 chat 最小闭环(commit ee5c78a):`api/chat.py` POST /api/chat(X-Agent-Type 分流+准入+归属校验+SessionGuard AUTH_403_SESSION_AGENT+closed 409)+ `session_repository`(agent_session/agent_message)+ `memory_service`(Redis 窗口 sess:{agent}:{id}:msgs TTL2h N≤20,miss/异常回源 MySQL)+ main 挂载
|
||
- [x] 2026-09-07 Wave 0 独立 AI 评审有条件通过→闭环(commit 61711cb):P2×5(python-jose>=3.5.0 防 CVE / audit 降级测试 / JWT 通道 chat 用例 / debug 兜底纵深防御 / 留痕失败降级显式化)+ P3×11 顺手,273 测试绿
|
||
- [x] 2026-09-05 init 项目记忆目录 + `app/` 脚手架(api/service/tool/model/config/utils)
|
||
- [x] 2026-09-05 需求拆解文档(业务场景/矩阵/合规)
|
||
- [x] 2026-09-05 表设计 + 技术选型 + JWT 手册
|
||
- [x] 2026-09-05 Core 模拟库 `scripts/core/*` + `reset.ps1` + 文档
|
||
- [x] 2026-09-05 `core_ro.py` + `settings.mysql_core_database` + sync 脚本
|
||
- [x] 2026-09-05 Agent 编排依赖改为 LangGraph(requirements.txt)
|
||
- [x] 2026-09-05 memory 文件夹更新(新 Agent 交接清单)
|
||
- [x] 2026-09-10 merger 批次(工作区 · **804 pytest** · 未 commit):Wave3 · analyst D-06 · 风控前端/灌库/深潜课7 · 问数 template 标签
|
||
- [x] 2026-09-10 客服 Wave3 + analyst 445cfbb cherry-pick + 课程 layout 修复(**795 pytest** · 已并入上项)
|
||
- [x] 2026-09-09 数据分析 Agent S3 合并接线 + 问数页 + 迁移/冒烟(`773 passed` · commit `af9fb71`)
|
||
- [x] 2026-09-09 数据分析 Agent 需求规格定稿 v1.1(`docs/需求拆解/01-数据分析Agent需求规格.md`)
|