- Updated test files to import `AgentSessionLocal` from `advisor_db` instead of directly, preventing session binding to the real database during tests. - Fixed 6 test cases to use the new login token utility, ensuring consistency across authentication methods. - Adjusted customer risk codes in `test_convert_confirm.py` to reflect changes in customer classification (C3 to C4). - Verified that changes resulted in zero database pollution during test runs, maintaining integrity of the testing environment. - Documented findings and updates in the relevant test logs and memory files, ensuring clarity on the current state of tests and defects.
298 lines
41 KiB
Markdown
298 lines
41 KiB
Markdown
# 项目记忆(人 + Agent 共用)
|
||
|
||
> 各阶段的**简化快照**(门闸索引)。只留基础信息,不写源文件正文。
|
||
> **新 Agent 无上下文:先读本节 → 第 0 节交接清单 → 按需打开源文件。**
|
||
|
||
------
|
||
|
||
## 0. 新 Agent 交接(5 分钟)
|
||
|
||
**项目是什么:** 金融四 Agent(客户财富 / 代理人 / 数据分析 / 风控)共用数据层与合规底座;**不**互调 LLM,跨 Agent 走 L1/L2/L3 画像与预警表。
|
||
|
||
**当前进度:** 需求与表设计已定 · **`pytest` 实测 1236 passed / 102 failed / 9 skipped / 21 errors**(全量 1368 collected,2026-09-13 第五轮实测;**⚠️ 旧记的「926 / 896 passed」已作废** —— 见 **F-α**(文档门槛陈旧)与 **F-ζ**(`--ignore-glob=test_sprint*.py` 为空操作,"排除 sprint"从未生效);修正 glob `'*/test_sprint*.py'` 后为 **1199 passed / 45 failed / 9 skipped / 21 errors**)· **⚠️ 套件非幂等(F-η)**:连跑两次 FAIL 集合不同 ⇒ 引用该数字须附跑批序号 · **27 Vitest** · **Redis @ 6380** · **`merger` 未 commit** · **前端设计栈补强未 commit(2026-09-13:Inter 自托管 + Radix 状态阶)** · **客户线交易 + 选购清单 + 持仓快照/行情快捷交易未 commit(2026-09-13)** · **顾问线已 fast-forward 合入 `merger`** · **端到端第三轮(真浏览器 + 真 HTTP)174 用例 161 PASS / 12 FAIL / 1 SKIP → 6 缺陷待修**([FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md) · **D1 已关闭** ✅ · D2 KYC `created_at` · D3 Milvus 集合 `released` · ~~F1 转换页预置跨主体必失败~~ ✅ **第四轮复跑已转绿** · ~~F2 `alert_id`/`alert_ids` 字段名不匹配~~ ✅ **已转绿** · ~~F3 无路由级角色守卫~~ ✅ **已转绿** · F4 确认日默认越界)
|
||
|
||
**端到端第四轮(客户线交易 · 真浏览器 + 真 HTTP + 真库对账)**([CT-001](tests/2026-09-13-customer-trade-e2e/TEST-LOG-2026-09-13-CT-001.md) v1.2 · 初稿 203 用例 **162 PASS / 6 FAIL** → **同日复跑取证:Part A 161 行 135 PASS / 0 FAIL / 1 SKIP / 25 INFO(退出码 0)· Part B 48 行 41 PASS / 0 FAIL / 0 SKIP / 7 INFO(退出码 0)**)
|
||
- ✅ **P0 已修**:`jwt_service.infer_roles()` **忽略外部 `roles`**,只认 `DEFAULT_ROLES_BY_ACTOR`;未知 actor 登录 → 401。单测 `test_wave0_auth.py`
|
||
- ✅ **P1 已修**:自助通道 `simulate_self_service_blocked()`(`allowed_with_disclosure` / `requires_disclosure` / `needs_branch_confirm` 视同阻断)· `trade_gateway` + `convert_service` 转入端 · 单测 `test_trade_gateway` / `test_convert_accept`
|
||
- ✅ **L1 已修**:同 `client_request_id`、不同 body → **409 `IDEMPOTENCY_CONFLICT`**(`accept_convert` 比对四元组 · `CT7-05` 硬断言)
|
||
- ✅ **CT6 脚本已修**:`derive_redeem_qty()` 由 T+2 批次推导申报量(优先 FIFO 跨档),不再写死 `35000` · `CT10-07` 无赎回时 **SKIP**(避免空 PASS)
|
||
- ✅ **复跑已取证(2026-09-13 19:26)**:P0/P1/L1 三条**同期望值转绿**(退出码 1 → 0),**CT6 赎回覆盖缺口关闭**(组中止 SKIP → 7 PASS,含 FIFO 跨档 `30000+150` 与金额复算 `44922.38`);5 表还原核对 `95 / 59 / 73 / 19 / 0`
|
||
- ⚠️ **复跑新发现(需拍板)**:① **P0 只堵了方向①** —— `infer_roles` 已不信任入参,但 `/api/auth/login` 仍无 `app_env` 门禁、`main.py:103` 仍无条件挂载;② **P1 可能收窄业务能力** —— `allowed_with_disclosure` 被并入阻断 ⇒ R4 产品自助通道**完全不可下单**(原设计是「弹揭示书后可买」),需业务确认是否补揭示书续接流程;③ **`CT3-05` 顺序敏感** —— 15 分钟墙钟窗口 + `jinrong_agent` 永不还原 ⇒ 距上一轮 <15 min 复跑会假 FAIL(本轮踩过,已声明复跑口径)
|
||
- ⚠️ **仍开放**:**B1** 持仓 vs 批次和基线不一致(种子/历史态,非本轮引入)· **T1** `run_demo_smoke.ps1` 仅登录改 canonical(后续 `/api/v1/*` 仍 404)· 仓库外 `11-cross-role.mjs` **`C1.6` 陈旧断言** · **Redis 降级路径**(两轮均未跑,唯一未覆盖的功能路径)
|
||
- ⚠️ **证据链缺口(如实声明)**:`_raw/shots/` 的 11 张截图被 v1.1 复跑**就地覆盖**,v1.0 的修复前截图**不可恢复**;v1.0 结论仅有报告文本与 JSON 可查
|
||
- ✅ 初轮已证口径:前端渲染与后端 raw **核对到分** · 数据副作用可回滚 · 对话/挂单红线全绿
|
||
|
||
**端到端第五轮(覆盖缺口补测 · 三条线全补 · 一线一包 · 2026-09-13)** —— 起因:「还有哪块没有端到端跑过?」
|
||
- **产出四个包**:[AN-003](tests/2026-09-13-analyst-e2e/TEST-LOG-2026-09-13-AN-003.md) 问数线 · [AD-001](tests/2026-09-13-advisor-e2e/TEST-LOG-2026-09-13-AD-001.md) 理财师线 · [RK-001](tests/2026-09-13-risk-e2e/TEST-LOG-2026-09-13-RK-001.md) 风控线 · [XC-001](tests/2026-09-13-crosscut-e2e/TEST-LOG-2026-09-13-XC-001.md) 横切
|
||
- ✅ **Part A 真实 HTTP**:问数线 **137 PASS / 6 FAIL**(= 缺陷 A/A2/B,此前 12 条路由**零 HTTP E2E**)· 理财师 **31 PASS / 4 FAIL**(AD8 为取证组)· 风控 **23 PASS / 0 FAIL** · 横切 **33 PASS / 0 FAIL / 1 SKIP**
|
||
- ✅ **Part B 真浏览器**:8 支脚本 **123 PASS / 0 FAIL / 6 INFO**(`03/04/06/07/08/09/10/11` 全部收复进 `scripts/e2e/`,改指向仓库内 harness)
|
||
- ⚠️ **Part C 回归**:`npm run build` ✅ 0 · `npm run test` ✅ 27 · **四文件交易单测 ❌ 49/28(F-β)** · **`pytest` ❌ 1236/102/9/21(F-α + F-ζ)**
|
||
- ✅ **Phase 6 还原已校验**:`core` 5 表按快照还原,**逐表 COUNT + CHECKSUM 与快照完全一致**(`95/59/73/19/0`)· `script_template` 页面可见恢复到 **20**
|
||
- 🟢 **已拍板 2 项(用户 2026-09-13 定)**:**F-14 维持现状**(「目前够用就行」—— 接受 LLM 自撰风险提示措辞,**不扩** `compliance_guard.py:109` 名单;代价是措辞与是否出现由 LLM 随机决定,`06-chat.mjs` 中该条已降级为 2 条 INFO)· **RK 发现-1 关闭**(「这个不用管」—— 未知客户语义保持 officer 200 / advisor 403 / customer 403 **无一 404**,现状不泄漏客户存在性,仅作实测事实保留在风控包与横切包)
|
||
- 🟢 **已拍板 · F-β = 选 A(用户 2026-09-13 定)**:**维持现状语义不动,下一轮只改测试**(`test_convert_confirm.py` 客户档位 C3→**C4** 或产品 R4→**R3**),**零业务代码改动**。**规则固化:`C3×R4`/`C4×R5` = 匹配但需揭示 ⇒ 自助渠道阻断并引导线下,这是设计意图不是缺陷**;**禁止给阻断响应体补 `forced_full_transfer` 让测试变绿**。上一轮 P1 修复使 `test_convert_confirm.py` **28 条失败**,**根因是测试前提过期,非接口缺陷**。依据:① L0 矩阵**刻意设三态**(`core_suitability_rule` 25 行实测)—— `C3×R4`/`C4×R5` = `allowed_with_disclosure`,服务层 `matched=True`/`blocked=False`/`mismatch_type="none"`/`block_code="SUIT_NEED_DISCLOSURE"`,**不是"不匹配"**,而是"匹配但须特别风险警示+签揭示书"(适当性办法 §19);② "需揭示→自助端阻断"是**已定设计**,三处同指:答辩稿 `答辩知识点清单.md:59`「**C3×R4 揭示 block**」· `CustomerTradePage.tsx:116`「标有『风险不匹配/需揭示』的请换产品或**到网点办理**」· `tradeEligibility.ts` 两类均 `canSelfServe:false`+`tone:'warn'`+标签「需揭示/**网点办理**」(揭示需双录/柜面,**线上无法完成"签署"动作**)⇒ P1 修复是**后端追平前端**;③ 28 条失败根因 = **测试前提过期**:`test_convert_confirm.py:1013` 的 `forced_full_transfer` 是**受理成功路径**字段,`CUST-CC`(C3) 被阻断后受理未发生 ⇒ `KeyError`;**阻断体里本就不该有该键**。**选项 B(已否决)**=把 PRD 二期(放行+提示)提前做,需新建前端揭示书 Modal + 留痕 + 后端受理分支;**只改后端不建前端更糟**。**🟠 新增记账(真缺口,只记录不修)**:文案引导的「网点办理/请联系持证投顾」**无实现通路** —— 理财师线**零交易 API**,全仓唯一入口 `POST /api/simulate/trade` 不区分渠道身份 ⇒ `C3×R4` 当前**任何渠道都买不成**,**文案承诺 > 实现能力**。处置二选一待定:① 答辩口径统一为"线下受理一期未实现";② 改前端文案(`CustomerTradePage.tsx:116`)
|
||
- 🟢 **F-ε(已修 · 2026-09-13 修复轮)**:`pytest` 写真库根因 = 测试文件**模块级** `from app.advisor_db import AgentSessionLocal` 在收集期绑定真库 sessionmaker,绕过 fixture 对 `app.advisor_db.AgentSessionLocal` 的 monkeypatch(`test_sprint1_compliance_rule_import.py` 早已用正确模式 `import app.advisor_db as advisor_db`)。**修法**:① 10 个 `test_sprint*.py` 改 `from app import advisor_db` + 调用点 `advisor_db.AgentSessionLocal`/`advisor_db.agent_engine`;② `import_script_templates.py` 同改;③ 唯一写真库的 subprocess 用例(seed 脚本独立跑)改 `@pytest.mark.skip`(另两处 subprocess `sync_template_vectors --dry-run` 只计数、`evaluate_compliance` 不带 trace_id/advisor_id 不写日志,经查只读)。**验证**:跑后 `script_template` 仍 65 / seed 20 / `test:*` 36,零污染。**同轮另发现并修**:6 个 `test_sprint2_*.py` 的 `token_for(username,password)` 打 `/api/v1/auth/login` + `{username,password}`,与现行 `POST /api/auth/login`(`actor_id`+`token_type`+`roles`)不符 ⇒ 迁移到 `tests/advisor_test_utils.login_token`。**副作用(如实)**:转 sqlite 后暴露 F-α 假 DDL 缺列(`agent_session` 无 `metadata` 等),sprint 组 45 条失败为陈旧 DDL/期望,非本轮引入
|
||
- 🔴 **F-ζ**:`--ignore-glob=test_sprint*.py` **是空操作**(pytest 匹配完整路径,缺 `*/`)⇒ 文档门槛"排除 sprint 后的 896"**从未按设计生效**。修正写法 `--ignore-glob='*/test_sprint*.py'`(1368→1274)
|
||
- 🔴 **F-η**:测试套件**非幂等** —— 同库同命令**连跑两次 FAIL 集合不同**(129 vs 127 行)⇒ **单次 `pytest` 的 passed 数不可作"不退步"基线**,引用须附跑批序号
|
||
- ⚠️ **F-γ 更正**:Phase 0 记的 `core_share_lot=74` 与同次快照(**73 行**)**不自洽** ⇒ 还原判据改为「**与快照逐表 CHECKSUM 一致**」,不再用某个读数值
|
||
- ✅ **ADV-3 实证**(原为读码推断):`agent_graph.py` 的 5 个工具**有 3 个接错**(`chat`/`search`/`check` 不存在、`get_session` 缺 keyword-only `auth`),**孤儿代码** ⇒ P3;`tests/test_step11_agent_graph.py` 全注入 `Mock()` ⇒ **遮蔽**(Mock 对任意属性返回可调用对象)
|
||
- ⚠️ **本轮未做完(如实声明)**:`/register` 注册链路仍**零覆盖** · `/app/home`·`/app` 未访问 · 面包屑/登出/会话侧栏切换未做浏览器验证 · `AnalystAssetsPage` 表单仍未提交
|
||
- ⚠️ **已登记残留**:`risk_alert.pending_review` **41 → 35**(追加型审计表,按语义不还原)· `script_template` 的 `test:*` 行置 `is_active=0` 留库
|
||
|
||
**工作分支:** 主线 **`merger`**(已纳入顾问线 + 基金转换线 · HEAD **`c09b987`**);保留 **`integrate/advisor-agent`** 作历史指针;历史 `risk-control-agent` 交付冻结。
|
||
|
||
**仓库地图:**
|
||
|
||
| 路径 | 状态 | 说明 |
|
||
| --- | --- | --- |
|
||
| `app/main.py` | **已集成(AL-09)** | 宿主 TraceMiddleware + 模块 audit/trace + 路由(auth/**platform**/chat/risk/simulate)+ lifespan |
|
||
| `app/api/auth.py` | **已实现(AL-09)** | Mock 登录;签发走 `auth_service.issue_dev_token`(与模块 API 同一 issuer) |
|
||
| `app/api/auth_adapter.py` | **已接线(S2)** | `module_auth_from_host()`:宿主 AuthContext → 模块 AuthContext |
|
||
| `app/gateway/` | **宿主 Wave 0(并存)** | jwt_service(**`infer_roles` 忽略 body.roles · 2026-09-13 CT-001 P0**)/ auth_deps / rbac / ownership;模块 API 走 `deps.py`,禁止模块 import gateway |
|
||
| `app/api/risk.py` `simulate.py` `deps.py` | **已实现** | 风控 4 API + 模拟网关 · **compliance/service_risk 矩阵(F2/F3)** · 台账 **`stats` 待审计数(F7)** |
|
||
| `app/api/chat.py` `audit_middleware.py` | **已实现** | POST /api/chat · **POST /api/chat/stream(customer 分流 → prepare_customer_stream)** · visitor · sessions 三端点 |
|
||
| `app/api/customers.py` `products.py` `advisors.py` `staff.py` `compliance.py` | **已实现(v0.1 + 行情历史)** | 代销平台 REST;`get_platform_auth_context`;**`GET /api/products/{id}/nav/history`**(RBAC · compliance 拒) |
|
||
| `app/api/analyst.py` `analyst_auth_adapter.py` | **已实现(S3+D-06 + N-03/N-07 + analyze)** | 问数/chat · **`POST /analyze`** · interpret · sample · escalate · dashboard |
|
||
| `app/api/advisor_*.py` `kyc.py` `market.py` `copy.py` 等 | **已合入 `merger`** | 对外 **`/api/advisor-agent/*`**(合规 · 话术 · 异动 · KYC · 复制门闸 · guard · dashboard/allocation ping);鉴权 **`advisor_auth_adapter`** + `get_platform_auth_context`;**不迁** `/api/v1` · demo_ui · `admin/audit-logs`。**端到端实测(v1.1):鉴权/合规/门闸/模板/防护/跨线回归全绿;市场异动 D1 已修转绿(10/10 + 浏览器 4/4);KYC 采集(D2)仍 500,语义检索(D3)仍静默降级**——[ADV-001](tests/2026-09-12-advisor-agent-e2e/TEST-LOG-2026-09-12-ADV-001.md) · [FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md) |
|
||
| `app/advisor_db.py` `entities_advisor.py` `advisor_schemas.py` | **接缝已挂** | 顾问 ORM/会话工厂 · 与 merger `entities.AgentSession` 共用 `metadata_` 列名 |
|
||
| `scripts/agent/migrate-advisor-agent-sprint1-3.sql` | **已新增(待本机执行)** | 顾问专用表(compliance_rule · kyc_session · market_alert · script_template 等) |
|
||
| `app/api/ready.py` | **已实现(2026-09-11)** | `GET /api/ready`:Redis + 关键路由自检;前端 `DevReadyBanner` |
|
||
| `app/service/analyst_agent.py` `template_service.py` `cache_service.py` `analyst_chart.py` | **已实现(S3+D-06 + D-11)** | NL2SQL · **published few-shot 仅库** · `_nl_sql_hints` 双极值 UNION · 模板 · **`reload_published_assets`** · **`clarify` 结构化** · analyze 图表 |
|
||
| `app/api/knowledge.py` `admin.py` | 空壳 | 待审计查询台与知识库 API(T-21 拍板一期只做脚本入库,上传/重建端点不做) |
|
||
| `app/service/platform/` | **已实现(v0.1)** | 封装 core_ro + `PLATFORM_RESPONSE_DESENSITIZE` 脱敏开关 |
|
||
| `app/service/embedding.py` `milvus_service.py` `rag_service.py` | **已实现(T21-1/2/4)** | Ollama bge-m3 1024 维(失败不静默降级)/ kb_product_rules 建集合+upsert+合规过滤检索 / search_knowledge→chunks+source_refs 溯源 |
|
||
| `app/tool/kb_tools.py` | **已实现(T21-5)** | search_knowledge 对话 Tool(skip_access_check 公开知识;仅 customer/advisor 意图开放,risk 不开放);kb_product_rules 首批 24 块已入库(data/kb 6 产品手册,scripts/kb/build_kb.py 可重灌) |
|
||
| `app/service/auth_service.py` | **已实现(T-01)** | Auth SDK:JWT 验签(HS256 dev/RS256 生产)、必填 claims、jti 吊销(Redis fail-open);签发 CLI `scripts/dev/issue_dev_token.py` |
|
||
| `app/service/risk/*` + `service/suitability.py` | **已实现** | RISK-001~005 规则 / 预警聚合 / L3 写入 / AML / 引擎编排 / suitability(**阶段一换核:内核改调 core_ro.check_suitability,SUIT-001~008 已退役**)/ locks+redis_gateway 公共原语(B7) |
|
||
| `app/service/agent_service.py` `memory_service.py` | **已实现(T-07/T-06/T-04/C2 + 方案 C)** | LangGraph StateGraph(tool→llm→guard)+ DeepSeek(无 key 降级);T-04 tool 节点(关键词意图 customer/advisor/risk 分组 + tool_service.run_tool);C2 tool_node 守卫放宽(requires_customer=False 允许无绑定客户,支撑 A-6 全量待审);Redis 会话窗口 + MySQL 回源。**方案 C:`stream_chat` 生成器(Tool 同步跑完→逐块推 LLM 文本)+ `needs_disclaimer`(首帧 meta 与落库尾部共用口径)** |
|
||
| `app/service/tool_service.py` `app/tool/core_tools.py` `service/risk/chat_tools.py` | **已实现(T-04/C1)** | 对话 Tool 编排(统一注册表 get_registered_tool:core+risk / 归属校验 / agent_tool_call 落库)+ Core RO 三只读 Tool(L0/持仓/流水)+ C1 风控四只读 Tool(alert_query/customer_context/suitability_check/aml_lookup,RISK_TOOL_REGISTRY) |
|
||
| `app/repository/session_repository.py` | **已实现(T-06/T-04 + 前端接入 B/C)** | agent_session / agent_message / agent_tool_call 读写;**方案 B 增 `list_sessions`(分页+total)/ `list_messages_page`(seq 升序分页,勿与 LLM 窗口的 `list_messages` 混用)/ `close_session`(条件更新防并发)**;**方案 C 增 `insert_turn`(user+assistant 同事务落库 + 事务内取 seq,修评审 P0/P1)** |
|
||
| `app/gateway/gateway_repository.py` `trade_gateway.py` | **已实现(2026-09-13 持仓同步 + 自助适当性)** | 模拟交易网关 · **R4 揭示类自助阻断**(`simulate_self_service_blocked`)· 申赎 `_maintain_lots` 同步 `core_holding` |
|
||
| `app/repository/core_ro.py` | **已实现(2026-09-13 持仓补偿读)** | Core 只读 SELECT;**`list_holdings`(qty>0)** · **`list_holdings_from_lots_gap`**(批次有余量但快照未体现 · 历史只写 lot 的演示修复)· check_suitability / list_products_for_customer / list_trades / get_customer_l0 |
|
||
| `app/service/platform/customer_service.py` | **已实现(v0.1 + 持仓合并)** | `list_holdings` 合并 gap 行并按净值估市值 · L0/流水/可购产品 |
|
||
| `app/repository/risk_repository.py` | **已实现** | risk_alert / … · **`list_alerts` 须 `RiskListAccess`(F1)** · **`status=handled` 聚合筛选** · `count_pending_stats` |
|
||
| `app/repository/repo_access.py` | **已实现(2026-09-11)** | `RiskListAccess` / `ThresholdWriteAccess` 仓储调用凭证 |
|
||
| `app/repository/threshold_repository.py` | **已实现** | 阈值配置 · **`upsert_portfolio` 须 `ThresholdWriteAccess`** |
|
||
| `app/utils/` | **基本就绪** | trace(trace_id+request_id 双 contextvar)/ desensitize / db(引擎工厂)/ response(统一错误体+4xx/500 handler)/ exceptions(含 ApiError)已实现;logger 占位 |
|
||
| `app/config/database.py` | **已实现** | MySQL 双引擎 + **Redis 单例**(`REDIS_URL` · **RESP2 `protocol=2`** 兼容 Docker Redis 7 / 旧 Windows Redis 3) |
|
||
| `app/config/settings.py` | **已实现** | 双库 + risk_* 阈值 + JWT + **customer/visitor/profile** 字段 + `kb_root_dir` |
|
||
| `app/service/customer_service.py` `visitor_service.py` | **已实现(S2 + Wave3 + 交易 + 问候快路由)** | 客服 14 节点 + **`trade_prepare`/`process_trade_turn`** · **C-04/C-05/C-11** · **选购清单 `fact_text` 不经 LLM 改写**(防压成「能买几只」)· **`trade_dialogue_should_continue` 续轮** · 问候 `chit_chat` · 游客 9 节点;`sanitize_postprocess`(1B);RAG **fin_* 三库** |
|
||
| `app/service/trade_flow_service.py` `trade_action_service.py` | **已实现(2026-09-13 · 未 commit)** | Redis 交易抽槽 · 菜单序号解析 · **`restore_flow_from_context`**(Redis 丢态从助手菜单恢复)· 申购/赎回/转换草稿 · **C3×R4 揭示类 `subscribe_suitability_block`** · 与 `simulate` 字段对齐 |
|
||
| `app/tool/trade_tools.py` `app/tool/core_ro_tool.py` | **已实现(扩展)** | 顾问 `prepare_simulate_trade` · **适当性:多 R 列清单** · **无参「我能买什么」→ `_list_purchasable_product_catalog`(【R1】… 全局序号 + PROD 编号 · 回复序号进申购)** |
|
||
| `web/src/pages/customer/CustomerTradePage.tsx` `CustomerTradesPage.tsx` `TradeConfirmModal.tsx` `tradeEligibility.ts` `tradeEvents.ts` | **已实现(2026-09-13 · 未 commit)** | 交易中心三 Tab · 适当性标签 · **`simulate` 须 CUST-* 客户 JWT**(非客户顶栏警示)· 确认成功 **`jr:trade-completed`** → **首页/持仓/交易明细** 刷新 · Modal 成功态自关(父页不再抢先关窗)· Chat **`pending_trade`**(spec [customer-trade-design](../superpowers/specs/2026-09-13-customer-trade-design.md)) |
|
||
| `web/src/components/trade/TradeProductActions.tsx` · `ProductNavDetailPage` · `MarketQuotesPage` | **已实现(2026-09-13 · 未 commit)** | **客户角色**:净值详情「快捷交易」三按钮(申购/赎回/转换)· 行情列表列 **申购·走势/赎回·转换**(赎回建议在详情看持仓份数) |
|
||
| `scripts/dev/restart-dev.ps1` `restart-dev.bat` | **已增强(2026-09-13)** | 重启 uvicorn + Vite · **不启动 Redis**(须先 `start-redis.ps1` 或 `docker compose up -d redis`)· 结束时 **探测 `api/ready` checks.redis** 并黄字提醒 · `.bat` 可双击 |
|
||
| `scripts/dev/start-redis.ps1` | **已实现** | Docker `jinrong-redis` · **6380→6379** · `.env REDIS_URL=redis://127.0.0.1:6380/0` |
|
||
| `app/service/threshold_service.py` | **已实现(C-04)** | L1 `threshold_pref_summary` → `customer_threshold_config`;持仓查询加权盈亏 vs 阈值 → `customer_notify_log` |
|
||
| `app/utils/sanitize_postprocess.py` | **已实现(1B 共用)** | 数据查询 intent(含 nav_query)违禁 → 回退 fact_text;RAG/闲聊 → COMPLIANCE_REJECT;均不自动 transfer |
|
||
| `scripts/core/*.sql` + `reset.ps1` | **已实现** | Core 模拟库 DDL + 种子 · **`07-seed-nav-history.sql`(14 产品 ×364 日)** · 再生 `seed_nav_history.py --export-sql` |
|
||
| `scripts/agent/` `scripts/demo/` `scripts/dev/` | **已实现** | **`prepare_all.ps1`** · **`push_threshold_alerts.py`** · **`seed_analyst.ps1`** · **`sandbox_risk_test.py`** · `run_query_battery.py`(**不入库**) |
|
||
| `scripts/sync/*.py` | **已实现** | 归属同步 + Neo4j 全图 |
|
||
| `tests/` | **已实现** | **926+ 用例**(含顾问 sprint)· merger 回归 **896 绿**(`-k 'not test_sprint'` 口径:`--ignore-glob=test_sprint*.py`)· 问数 [AN-002](tests/2026-09-12-analyst-template-phrases/TEST-LOG-2026-09-12-AN-002.md) |
|
||
| `docs/项目框架设计/理财顾问Agent-合并说明.md` | **实施中** | D1–D9 拍板 · 接缝清单 · 与 `docs/superpowers/plans/2026-09-12-advisor-agent-merge.md` 对齐 |
|
||
| `docs/答辩/` | **答辩手册 + Demo SOP + 幻灯片 + 答辩稿 + 功能测试** | [`README.md`](答辩/README.md) · 知识点清单 · `DEMO-SOP-*` · `presentation/index.html` · `答辩稿.md` · `DEMO-功能测试流程.md` |
|
||
| `docs/course/` | **交互课程集** | 导览中心 + 总览 **8 模块** + 问数 **5 模块**(D-06)+ 风控深潜 **7 模块** · 与答辩清单同步 |
|
||
| `docs/PRD/PRD-风控监测Agent.md` | **已冻结(v1.1)** | 风控 PRD v1.0 + v1.1 追加 FR-8/9/10(§4A)+ 规则表附录 |
|
||
| `docs/项目框架设计/实现方案-风控追加需求v1.1-C4C6.md` | **已定稿** | C4~C6 编码依据(经独立 AI 评审修订闭环);分支/进度速览另见项目根 `交接文档.md` |
|
||
| `docs/项目框架设计/合并注意事项-风控模块并入main.md` | **AL-09 已执行(2026-09-08)** | 合并接线完成;接缝见《风控Agent模块边界与合并接缝标注.md》 |
|
||
| `docs/项目管理/04-从需求到公共API开发方法.md` | **已定(2026-09-08)** | 需求→矩阵→存储→Service→API→Agent 主线;Phase A 清单 |
|
||
| `docs/项目框架设计/接口契约-代销平台API-v0.1.md` | **已定(2026-09-08)** | 代销平台 REST canonical 路径、命名规范、Agent 迁移表 |
|
||
| `docs/项目框架设计/C-05-行情数据源选型对比.md` | **已定(2026-09-09)** | C-05 净值数据源分阶段选型;禁止爬虫/前端直连第三方 |
|
||
| `docs/项目框架设计/接口契约-代销平台API-v0.2-行情扩展草案.md` | **草案(2026-09-09)** | `nav-snapshot` · `sync_market_nav` · 前端产品行情 Phase B |
|
||
| `docs/项目框架设计/表设计/` | 已定 | Agent 共用 11 表 + agent 专用 SQL |
|
||
| `docs/项目框架设计/Core模拟底座/` | 已定 | 无真实 Core 时的 L0 方案 |
|
||
| `web/` | **P0 + 行情详情图表 + 客户快捷交易(2026-09-11/13)** | **`/app/market/:productId`**:走势图表 + **TradeProductActions** · 列表客户列三链 · **DevReadyBanner** · `restart-dev.ps1` 校验 `nav/history` |
|
||
| `web/src/styles/tokens.css` `src/theme.ts` | **字体/状态阶(2026-09-13)** | **Inter Variable 自托管**(`@fontsource-variable/inter` · 字体栈已提到最前 · **字族名带 ` Variable` 后缀**,写 `"Inter"` 匹配不上)· **Radix Colors 只引 `slate`/`jade`**,补 6 个状态阶 token(**11 个品牌色一律未替换**)· 选用依据与「色温陷阱」见 [TODO 2026-09-13](TODO.md) |
|
||
|
||
**本地 bootstrap(首次):** 完整步骤与前置说明见 `FLOW.md` §0(权威),速览:
|
||
|
||
```text
|
||
1. cp .env.example .env → 填 MYSQL_PASSWORD、NEO4J_PASSWORD、DEEPSEEK_API_KEY
|
||
2. pip install -r requirements.txt
|
||
3. .\scripts\core\reset.ps1 # 建 jinrong_core(含 07 净值历史 ~365 日/产品)
|
||
4. mysql … < 01-mysql-共用底座.sql # jinrong_agent 共用 11 表
|
||
mysql … < 02-mysql-agent专用.sql # 风控四表 + risk_aml_list
|
||
mysql … < scripts/agent/migrate-advisor-agent-sprint1-3.sql # 投资顾问专用表(合并后必跑)
|
||
5. mysql … < scripts/agent/seed-aml-list.sql # AML 名单(Windows 乱码:`python scripts/dev/fix_utf8_seed.py`)
|
||
python scripts/seed/import_compliance_rules.py # 顾问合规规则(源:`docs/开发文档/20-Sprint1首批合规规则数据集.md`)
|
||
.\scripts\demo\seed_advisor_agent.ps1 # 一键:迁移 + 规则 + 话术 + 演示审核(推荐)
|
||
.\scripts\demo\seed_advisor_agent.ps1 # 一键:迁移 + 规则 + 话术 + 演示审核(推荐)
|
||
(风控演示:`.\scripts\demo\prepare_all.ps1` 或 `prepare_risk_demo.sql` · PRD §10.2)
|
||
6. python scripts/sync/sync_advisor_rel.py && python scripts/sync/sync_neo4j.py
|
||
7. `docker compose up -d redis`(或 `.\scripts\dev\start-redis.ps1`)→ **REDIS_URL=redis://127.0.0.1:6380/0**(Docker Redis 7;避开本机 Windows Redis 占 6379)
|
||
8. uvicorn … · python -m pytest(**merger 回归 ~896 绿**;全量含 sprint **926 passed / 65 failed**);问数答辩:`docs/答辩/DEMO-SOP-问数.md` · 模板种子 **`scripts/agent/seed-analyst-query-templates.sql`**
|
||
```
|
||
|
||
**AL-09 合并后架构(一句话):** 宿主 `gateway/` + 模块 `deps.py` **双栈并存**;对外登录/token **统一**;chat/risk 均走模块鉴权;接缝 S2 用 `auth_adapter`。
|
||
|
||
**下一步(见 TODO):** **修 F1/F2**(演示可见 · 改动面极小)→ D2 → F4 → F3 → D3 · git commit `merger` · battery · 客服验收 · D-12 往后排
|
||
|
||
**⚠️ 前端 E2E 覆盖现状:** **2026-09-12 第三轮已完成顾问前端四页 + 风控前端六页的逐功能点按**(真浏览器 · 47 用例,见 [FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md)),**两个 SSE 对话页与客户线仍属 2026-09-10 的「仅能渲染」口径** —— 接口错误态、对话多轮/会话管理、数据与后端 raw 对账、排序分页正确性等**仍未验证**(CHAT-1~4 就是这样漏掉的)。**未跑清单见 `TODO.md` §「前端 E2E · 未跑测试」**,旧报告见 `docs/整体测试/前端整体测试交接.md`。
|
||
**⚠️ 本轮已知复现性缺口:** 浏览器脚本(`09/10/11-*.mjs`)在**仓库外** `C:/Users/Windows/e2e-jinrong/`,他人 clone 拿不到 → 已挂 `TODO.md`「E2E 最小集进仓库」P0。
|
||
|
||
**Redis(2026-09-09):** 推荐 **Docker** `jinrong-redis`(`redis:7-alpine`)· 宿主机 **6380** → 容器 6379 · `.env` `REDIS_URL=redis://127.0.0.1:6380/0` · 客户端 **RESP2**(`database.py` / `redis_gateway.py`)。
|
||
|
||
**Redis 不加速页面看板(2026-09-10 澄清):** Redis 管 **Chat 会话窗口 / 问数 D-06 结果 / 限流 / L3 热读**;**平台 GET(持仓/净值/预警列表)与 Dashboard hooks 每次进页仍打 MySQL**,前端无跨路由缓存 · 净值 **`fetchNavMap` 按产品 N 次 HTTP** → 体感「每页都转圈」见 `TODO.md` §2026-09-11 · `FRONTEND-HANDOFF.md` §10。
|
||
|
||
**前端启动(`web/`):** `npm install` → `npm run dev`(`5173`,`/api` 代理 `8000`)· 验收四 demo 账号见 **`docs/frontend/FRONTEND-HANDOFF.md` §8** · 改 UI 后跑 `npm run build && npm run test && npm run lint`。
|
||
|
||
**平台 API 硬规则(2026-09-08 拍板):** 路由 **A · 按业务域**(`/api/customers` 等);与 Agent 功能重复时 **以本平台 API 为准**;命名见契约 §2;合并时统一改 canonical 路径。
|
||
|
||
**禁止(改代码前必记):** Core 正式 C1~C5 不可被画像覆盖 · 审计表只 INSERT · 代理人草稿不外发 · 仅 R-02 可阻断交易 · 四 Agent 不互调 LLM。
|
||
|
||
**里程碑 tag 中文对照(tag 本体保留英文原名——git 技术标识符需跨平台/脚本稳定引用,符合「技术字面量保留英文」约定;中文名经对照表统一):**
|
||
|
||
| tag | 中文名 | 状态 |
|
||
| --- | --- | --- |
|
||
| `risk-m1` | 阶段A · 适当性校验可用 | 已补打(2026-09-07,指向阶段 A 完成提交 `3c07de6`,历史归档) |
|
||
| `risk-m2` | 阶段B · 事件线全链路 | 已打(2026-09-07,附注含验收走查记录) |
|
||
| `risk-m3` | 阶段C前半 · 对话线闭环 | 已打(2026-09-07,指向 C1~C3 完成提交) |
|
||
| `risk-m4` | 追加需求 · C4~C6(FR-8/9/10) | 已打(2026-09-07,annoted tag 指向 `323d98b`,仅本地未 push;C4 `fe4801b`/C5 `90d0660`/C6 `66ec7eb` 三提交 + 文档落账 `323d98b`,全量 482 绿,挂账 #1~#9 核对无违规) |
|
||
| `risk-align1`(拟) | 阶段一 · 对齐 main 基准 | 待定(AL-01~08 已完成,是否为此打 tag 由用户拍板;当前仅 AL 逐项 commit) |
|
||
|
||
------
|
||
|
||
## 1. 项目简介
|
||
|
||
- **名称:** JinRong 金融四 Agent 智能管家
|
||
- **当前阶段:** **代销平台 v0.1 + AL-09 + 客服 Wave3 + 客户交易/选购清单(2026-09-13)+ 问数 D-06/D-11 + 投资顾问 Agent 接缝(2026-09-12)**
|
||
- **当前优先级:** **CT-001 复跑已完成** ✅ · **merger commit**(客户线 + CT 收口 + 字体栈 —— 现在可以提交了对某个确定 SHA 负责)· 复跑新发现三条待拍板(P0 补方向②③ / P1 业务口径 / `CT3-05` 顺序敏感)· F4/D2/D3 · battery · sprint pytest
|
||
|
||
------
|
||
|
||
## 2. 阶段快照
|
||
|
||
| 阶段 | 当前一句话 | 源文件 |
|
||
| --- | --- | --- |
|
||
| 服务对象大环境 | 公募四类角色;**无真实 Core**,L0 由 `jinrong_core` 模拟库供给 | `ENVIRONMENT.md` |
|
||
| 需求目的 | 四 Agent + 统一数据层 + 合规可审计;Wave 0~3 P0 见 REQUIREMENTS | `REQUIREMENTS.md` |
|
||
| 项目框架 | FastAPI 分层 + LangGraph + MySQL 双库/Redis/Milvus Lite/Neo4j + React | `FRAMEWORK.md` |
|
||
| 实现流程 | Gateway JWT → chat → LangGraph → Tool → 审计;bootstrap 见 FLOW §0 | `FLOW.md` |
|
||
|
||
------
|
||
|
||
## 3. 约束
|
||
|
||
**硬阀门:技术选型**
|
||
|
||
`docs/项目框架设计/技术选型和版本/01-技术栈与版本.md` 中已标「已定」视为用户确认;新增依赖须再确认。
|
||
|
||
**禁止触碰:**
|
||
|
||
```text
|
||
Core 正式 C1~C5、持仓/交易真账(Agent 只读;当前为模拟库)
|
||
audit_log 等审计表(只 INSERT)
|
||
代理人草稿自动外发客户
|
||
风控自动冻户 / 改正式风险等级
|
||
各 Agent 自建第二套 JWT/RBAC
|
||
```
|
||
|
||
**高风险(改前需确认):** 数据库表结构、JWT/RBAC、部署密钥、删生产数据。
|
||
|
||
**开发开关:**
|
||
|
||
| 项 | YES / NO |
|
||
| --- | --- |
|
||
| 允许新增依赖 | YES(对齐技术选型文档) |
|
||
| 允许重构 | YES(最小范围) |
|
||
| 允许改表 / schema | 需确认 |
|
||
| 允许改接口协议 | 需确认 |
|
||
|
||
**特殊规则:**
|
||
|
||
```text
|
||
四 Agent 不互调 LLM;跨 Agent 走 L1/L2/L3 画像与预警表
|
||
客户 Agent:无投资建议/收益承诺/自动下单
|
||
代理人:不对 C 端直发
|
||
数据分析:仅 SELECT,不处置预警
|
||
画像不得覆盖 L0 正式测评
|
||
```
|
||
|
||
**客服合规拍板(2026-09-10 · 已落地):**
|
||
|
||
| ID | 决策 | 代码落点 |
|
||
| --- | --- | --- |
|
||
| **1B** | 数据查询 intent(持仓/流水/风评/适当性/**净值**)经 `sanitize_reply` 命中违禁词 → **回退 `fact_text`,不转人工**;RAG/闲聊命中 → `COMPLIANCE_REJECT`,**也不自动 transfer**;**customer + visitor 共用** | `app/utils/sanitize_postprocess.py` · `finalize_sanitized_reply` |
|
||
| **R1** | L1 `product_preferences` / `excluded_products` 合并时写 `items_meta`;注入 prompt **Top-K + 时间衰减 + TTL**(K=3 · TTL=90d · 半衰 30d) | `profile_service` · `settings.profile_preference_*` |
|
||
| **C-04** | 持仓内联提醒 + **演示 push**:`POST /api/customers/{id}/threshold-check?push=` · `push_threshold_alerts.py` · 持仓页按钮(**无定时 cron**) | `threshold_service` · `customers.py` |
|
||
| **C-05** | 「最新净值/单位净值」→ Core `get_latest_nav`(快照,非实时盘口);**「实时净值」仍 reject** | `core_ro_tool.query_product_nav` · intent `nav_query` |
|
||
| **C-11** | 「我能买什么/有什么可以买」→ `suitability_check` · **按 R1–R5 列产品名 + 全局序号 + `PROD-*` 编号**(非各档「能买 N 只」计数);回复序号接交易菜单(仅 **可直接申购** 进金额;**揭示/双录** 引导代理人;**forbidden** 拦截)· **「推荐稳赚/买什么好」仍 reject** | `core_ro_tool._list_purchasable_product_catalog` · `customer_prompts._ELIGIBLE_PRODUCTS_KW` · `trade_flow_service.parse_product_menu_from_context` |
|
||
| **客户交易(2026-09-13)** | 助手内 **不** 聊天打字确认下单 · **Modal + POST simulate**;多轮抽槽 Redis + 上下文恢复;见 spec | `docs/superpowers/specs/2026-09-13-customer-trade-design.md` · `trade_action_service` · `chat` SSE `pending_trade` |
|
||
| **客户交易 · 持仓与 UI(2026-09-13)** | **展示口径**:`GET .../holdings` = `core_holding`(qty>0)**∪** 批次 gap 补偿(`list_holdings_from_lots_gap`)· 新单网关 **`apply_holding_*`** 写快照 · 前端 **`subscribeEligibility`**(`requires_disclosure` 按 0/1)· **`jr:trade-completed`** 刷新看板+**交易明细** · 演示须 **CUST-\*** 登录否则 simulate 403、流水不会出现 | `customer_service.list_holdings` · `gateway_repository` · `CustomerTradesPage` · `tradeEvents.ts` |
|
||
| **C-07** | 风评查询走 Core;**「重新测评/重做风评」** → 引导 App/网点(Agent 内不做问卷) | `customer_prompts._RISK_KW` |
|
||
| **C-08** | 仅 L1 槽位 `investment.allocation_target`(13 槽);**无自动偏离检测/调仓** | `profile_slots.py` |
|
||
| **问数 vs 分析对话** | 问数页 · **`/interpret`** · **`/analyze` 对话框(文/图)** · N-03/N-07 · 分析对话 URL 重定向问数 | spec `2026-09-11-query-interpret-split` · `2026-09-12-analyst-query-visualization` |
|
||
| **问数 Demo(2026-09-12)** | **`match_phrases` 原句命中** · `GET /template-prompts` · 问数页标星/最近(**localStorage,非模板**)· UNION 括号 · 分析 **`POST /analyze`** | spec + [TEST-LOG-AN-002](tests/2026-09-12-analyst-template-phrases/TEST-LOG-2026-09-12-AN-002.md) |
|
||
| **问数 NL2SQL(2026-09-12)** | **复合问不走模板** · **published few-shot / dict** · 模板 **published + match_phrases** · 问数 **clarify 可点选** | MEMORY §D-11 · `metric_ambiguity.py` |
|
||
| **客户「趋势/走势」** | **平台行情详情**:`nav/history` + **区间(1M~ALL)/粒度(日周)/图型(走势/涨跌柱/组合)** · Chat 仍无历史 Tool · Phase B 外部 sync 未做 | 见 `web/src/utils/navChartSeries.ts` |
|
||
| **L0 优先** | 抽槽与 L0 撞车**永远听 L0**;L1 只 enrich 措辞 | `profile_slots` D7 |
|
||
|
||
------
|
||
|
||
## 4. 入口与运行
|
||
|
||
```text
|
||
后端入口:app/main.py · 配置 app/config/settings.py · Core 只读 app/repository/core_ro.py
|
||
Agent 库 SQL:docs/项目框架设计/表设计/01-mysql-共用底座.sql · 02-mysql-agent专用.sql(含 risk_aml_list)
|
||
Core 模拟:scripts/core/reset.ps1 · 文档 docs/项目框架设计/Core模拟底座/
|
||
种子:scripts/agent/seed-aml-list.sql(AML 名单)· scripts/demo/prepare_risk_demo.sql(reset 后重跑)
|
||
依赖:requirements.txt(LangGraph + langchain-core/openai + FastAPI + SQLAlchemy)
|
||
启动:uvicorn app.main:app --reload → GET /health · **GET /api/ready**(环境自检)
|
||
Redis:`docker compose up -d redis` · `REDIS_URL=redis://127.0.0.1:6380/0` · `scripts/dev/start-redis.ps1`
|
||
测试:python -m pytest(**926 passed / 65 failed / 1 skipped** 全量 · **896 passed** 不含 `test_sprint*`;集成需 MySQL + 顾问迁移 SQL + AML + 风控演示数据)
|
||
风控沙盘:`python scripts/dev/sandbox_risk_test.py`(TEST-RISK-001 · **`:325-326` 断言已腐化**:仍期 `convert` → 400,`03fce88` 后合法受理为 202)
|
||
真实 HTTP E2E:`python scripts/dev/advisor_e2e_smoke.py` · `python scripts/dev/risk_e2e_smoke.py`(**需 uvicorn 已起** · 退出码 0 全过 / 1 有 FAIL / 2 前置失败 · `--only R6` 单组 · `--report <path>`)
|
||
浏览器 E2E(**仓库外**):`cd C:/Users/Windows/e2e-jinrong && node 09-advisor-pages.mjs && node 10-risk-pages.mjs && node 11-cross-role.mjs`(**须先起 Vite 5173**)
|
||
前端:cd web && npm run dev · npm run build/test/lint(**27** Vitest)· 四角色 Demo 见 **`docs/frontend/FRONTEND-HANDOFF.md` §8** · 本地后端 **`scripts/dev/restart-dev.ps1 -Backend Local`**
|
||
问数模板:mysql … < scripts/agent/seed-analyst-query-templates.sql
|
||
风控一键灌库:.\scripts\demo\prepare_all.ps1
|
||
运维/演示脚本:scripts/demo/subscribe_alerts.py(订阅推送演示)· rebuild_alerts.py TRD-xxx(引擎异常补偿重放)
|
||
JWT 联调:python scripts/dev/issue_dev_token.py --sub STAFF-30001 --roles risk_officer(+ Authorization: Bearer + X-Agent-Type)
|
||
配置:.env(见 .env.example)
|
||
RBAC 联调账号:scripts/dev/rbac-seed-reference.md
|
||
```
|
||
|
||
------
|
||
|
||
## 5. 文档资产约定
|
||
|
||
| 文件 | 何时读 |
|
||
| --- | --- |
|
||
| `docs/memory/MEMORY.md` | **每次任务先读**(本文件) |
|
||
| `docs/memory/REQUIREMENTS.md` | 对照场景 ID(F/C/A/D/R)与 Wave |
|
||
| `docs/memory/FRAMEWORK.md` | 分层、选型、模块、**实现状态表** |
|
||
| `docs/memory/FLOW.md` | 端到端链路 + 本地 bootstrap |
|
||
| `docs/memory/ENVIRONMENT.md` | As-Is 业务环境与 Core 模拟说明 |
|
||
| `docs/memory/TODO.md` | 当前待办与已完成 |
|
||
| `docs/PRD/PRD-风控监测Agent.md` | 风控 PRD v1.0(已冻结;FR-1~FR-7 + §8 验收表) |
|
||
| `docs/PRD/附-风控规则表.md` | RISK-001~005 / SUIT-001~008 / AML 规则权威 |
|
||
| `docs/项目框架设计/开发计划-风控模块.md` | 风控分阶段计划(阶段 A/B/C + 挂账登记 + B7~B9b 复审记录)**风控开发必读** |
|
||
| `docs/项目框架设计/演示SOP-风控模块.md` | 演示/走查操作手册(重灌 + A-1~A-9 步骤 + 核查单结论);**跑集成测试前先按 §2 重灌** |
|
||
| `docs/项目框架设计/架构设计-风控模块.md` | 风控模块架构(§3.1 编排 / §5 service 职责) |
|
||
| `docs/需求拆解/` | 业务原文(场景、矩阵、合规) |
|
||
| `docs/项目框架设计/` | 表结构、JWT 手册、Core 模拟、技术版本 |
|
||
| `docs/项目管理/04-从需求到公共API开发方法.md` | 搭公共底座/API 前;新人 onboarding |
|
||
| `docs/项目框架设计/接口契约-代销平台API-v0.1.md` | 写/Review 代销平台 REST;Agent 合并对照 canonical 路径 |
|
||
| `docs/项目框架设计/C-05-行情数据源选型对比.md` | C-05 行情/净值数据源拍板与禁止项 |
|
||
| `docs/项目框架设计/接口契约-代销平台API-v0.2-行情扩展草案.md` | Phase B `nav-snapshot` 与 sync 脚本契约(未实现) |
|
||
| `docs/frontend/FRONTEND-HANDOFF.md` | **改 `web/` 必读**:启动/分层/设计令牌/组件边界/浏览器验收清单 |
|
||
|
||
缺 `docs/memory/*` 文件:按 project-memory-kit 同名补回,**禁止空模板盖进度**。
|
||
|
||
------
|
||
|
||
## 6. 协作口令
|
||
|
||
【大环境】→ ENVIRONMENT · 【需求讨论】→ REQUIREMENTS · 【框架讨论】→ FRAMEWORK · 【实现流程】→ FLOW · 【Plan】→ TODO
|
||
|
||
------
|
||
|
||
## 7. 阅读完成门闸(Agent)
|
||
|
||
1. 四个 Agent 服务谁、禁止什么?
|
||
2. 改动属于 api / service / tool / repository 哪一层?
|
||
3. 是否需 customer_id 归属与 JWT RBAC?
|
||
4. Core 是模拟库只读还是 agent 库读写?
|
||
5. 如何验证?(`python -m pytest` · 顾问冒烟 **`tests/test_sprint0_foundation.py`** · **`from app.main import app`** → OpenAPI **62** 路径 · `cd web && npm run test` **27 绿** · Redis **6380** · `/api/ready` · 问数 [AN-002](tests/2026-09-12-analyst-template-phrases/TEST-LOG-2026-09-12-AN-002.md) · **真实 HTTP E2E `python scripts/dev/{advisor,risk}_e2e_smoke.py`**(需 uvicorn 起着 · 退出码 0/1/2)· 浏览器 E2E 见 [FE-001](tests/2026-09-12-agent-frontend-e2e/TEST-LOG-2026-09-12-FE-001.md) · 合并说明 **`docs/项目框架设计/理财顾问Agent-合并说明.md`**)
|
||
|
||
大任务:FRAMEWORK/FLOW 与实现状态不符时先更新 memory 再编码(用户确认跳过除外)。
|