Files
group_fqcd_jr/docs/软件需求文档-2026-09-14.md
T
lzf_0626 e59a9905a0 把「今日盈亏是硬编码 0」提级为待业务确认项(SRS Q22)
## 问题

`today_profit_loss` / `today_profit_loss_ratio` 在 `app/service/trade_service.py` 里是
**硬编码 `ZERO`**(持仓列表 L678、账户看板 L748-749),客户看板、持仓页、盈亏分析页的
「今日盈亏」永远显示 0.00。同一函数里的「持有盈亏」是**真算的**
(`market_value - cost_amount`,L660 / L726),所以只有这一项是占位。

三份 2026-09-14 文档其实**都记录了这个事实**(接口文档第 11 条、SRS 第 212 / 458 / 615 行),
但**都埋在「注意事项」里,没有进第 0 章那份「★ 请先回答本章」的待确认清单** ——
业务翻文档时看不到,演示现场被问到就答不上来。而且 SRS 第 212 行还把它**错引到了 Q7**
(Q7 讲的是场外阈值,与此无关)。

## 改动

**docs/软件需求文档-2026-09-14.md**
- 新增 **0.5 节「占位实现与本期边界」**,登记 **Q22**:客户看板的「今日盈亏」本期是否实现。
  该节专门收这类「接口有、值还没真算」的偏差(不报错、单元测试全绿、只有业务看得出不对),
  以后同类问题继续往这里追加。
- 第 0 章项数 21 -> 22;阻塞项清单补上 Q22。
- 修正 F-4.2 的错误引用(见 Q7 延伸 -> 见 Q22)。
- R2 状态改为「已提级为待决项 -> 见 Q22」。
- **R1 状态改为已修复**:组员提交 `4b7ee13`「修复管理员工作台函数缺少闭合大括号」
  已解决 `workspace.js` 的语法错误。按该条自己要求的方式复验过 ——
  `node --experimental-vm-modules` + `vm.SourceTextModule` 遍历 `app/static/portal`,
  **44 个模块全部通过**(`node --check` 会假通过,不能用来判定)。

**docs/44-演示流程.md**(演示现场用)
- §3「可能被问到的问题」新增话术:直说这是占位值、指出持有盈亏是真算的、
  指向 SRS Q22 与两条口径的结论;并建议「时间紧就避开这一栏,被问到不要含糊也不要现编」。
- 场景 2(客户资产)加现场提示:讲「持有盈亏 / 总市值 / 可用资金」,不要指着「今日盈亏」讲。

**docs/后端接口文档-2026-09-14.md**
- 第 11 条补上代码行号与交叉引用,并点明同一响应里的 `profit_loss` 是**真算的**。

## 顺带交给业务:两条口径的可行性(实测,非推测)

业务要决定的是「要不要做」,但「能不能做」也得一起给,否则业务选完还要再问一轮:

| 口径 | 数据现状 | 结论 |
|---|---|---|
| 用行情算(今收 − 昨收) | `fin_market_price` **只在同步时才写行**,实测每个产品**只有 2 行**(515450 只有 09-11 与 09-14,还跨了周末) | ❌ 取不到连续「昨收」 |
| 用净值算(今净值 − 上一交易日净值) | `fin_nav_history` 每个产品 **120~160 行连续交易日净值** | ✅ 建议按这个口径 |

⇒ 文档建议按**净值口径**实现,并提醒业务一并确认语义:净值是日终数据,
该指标实际是「最近一个交易日的盈亏」,**不是盘中实时**。

## 入库说明

三份 `docs/*-2026-09-14.md` 此前是**未跟踪文件**,本次一并入库(同一批文档交付物且互相引用)。
`.workbuddy/`(工具会话记忆)属工作区过程产物,**未入库**。
2026-09-14 11:24:51 +08:00

53 KiB
Raw Blame History

软件需求文档(SRS)——金融 Agent 平台

文档版本:v1.0(2026-09-14) 文档状态:待确认稿——第 0 章列出 22 项必须由业务方补充确认的问题,确认后本文件升为 v1.1 适用范围:场内基金模拟交易 + 客服问答 + 风控 + 投顾 + 场外基金运营 + 推介材料(六大业务域) 依据材料(均为仓库内既有文档,非本文件臆造):docs/00 数据库基线、docs/03 端到端流程、docs/05 接口文档、docs/22 四大 Agent 拆解、docs/10 业务域接入评估、docs/43 场内产品手册、docs/44 演示流程、docs/验收与审计/phase1-*、docs/28 场外表登记、docs/31 投顾灰度、docs/场外申购赎回工作流程图.md、以及 app/service/* 实际实现代码。


0. 需要业务方补充确认的问题(★ 请先回答本章)

本文件是在不臆造业务的前提下,依据仓库既有设计文档与已落地代码反推整理的。以下 22 项在现有材料中确实没有权威答案或存在口径冲突,其中标 [阻塞] 的会直接影响功能需求与验收标准的写法;标 [影响] 的只影响细节精度,可先按建议默认值推进。

0.1 范围与优先级(最高优先回答)

# 问题 现状 / 冲突点 影响
Q1 一期交付范围是否就是"六大业务域全部"? 还是要分两批(如客服+场内交易先上,场外+推介后上)? docs/22 §7 建议的建设顺序是 客服 → 投顾 → 风控 → 场外;但代码里六个域都已落地,docs/44 演示流程 8 个场景横跨全部域。文档需要一个明确的"本期交付边界"。 [阻塞]
Q2 本期是"演示验收"还是"生产上线"? 两者的非功能需求(可用性、备份、等保、并发量)量级差一个数量级。 现状:数据库口令、JWT 密钥走本地配置;docs/26 有密钥轮换设计;无出金/入金通道(docs/00 §5 明示"无充值提现与银行流水匹配通道")。 [阻塞]
Q3 是否仍严格限定"仅场内基金模拟交易"? 场外运营是否仅做"辅助核对+留痕",不产生真实资金动作? AGENTS.md 规则 8 明确:场外运营独立,不得写入场内交易表;app/service/offsite_fund_service.py 确实只读到 OffsiteFundDocument 等 offsite_* 表。请确认这条边界在需求层面不可松动。 [阻塞]

0.2 业务规则口径(现有文档明确写了"未定义",需业务填空)

# 问题 现状 / 冲突点 影响
Q4 客服 RAG 的混合检索决策公式与分数分段阈值(向量分/关键词分如何加权、多少分以上直答、多少分以下转人工、中间区间怎么办)? docs/22 §2.3 明确列为该设计自身未定义项;代码侧只落了 snippet/knowledge_id 与 TopK(FAQ 3 / 产品 5 / 政策 5),未见阈值常量。 [阻塞](直接影响"低置信不硬答"的验收判定)
Q5 低置信转人工的触发阈值与话术,以及"多轮澄清后仍无法解决"的兜底路径? docs/03 只说"低置信不得硬答、转人工需带完整上下文";phase1 教师标准认可 [无法确认] 标记 + 真实热线 15936583816。阈值本身未给。 [阻塞]
Q6 风控规则引擎的规则清单从哪来? 是业务方给一份规则表(规则名/口径/阈值/等级),还是要我们从 docs/21、docs/25 反推? docs/22 §2.3 明确列为未定义;代码 app/service/risk_scan_service.py 已有扫描实现但规则阈值需与业务对齐。 [阻塞]
Q7 场上/场下若干"业务阈值"请业务给数:申购单笔份额上限比例(现为总份额 10%)、单一投资者持有比例上限(现为 20%)、赎回巨额比例(现为 20%)、申购最低金额(现为 >1 元)是否为最终口径? 来自 app/service/offsite_fund_rules.py 实际常量 TEN_PERCENT=0.10、TWENTY_PERCENT=0.20、ONE_YUAN=1。这些是代码现状,不排除是占位值。 [影响]
Q8 场外"巨额赎回"是否要联动风控通知?清算是按单只基金聚合还是全市场聚合? docs/场外申购赎回工作流程图.md 边界明确:AML 与开放期规则不在本次实现范围;风险通知/邮件回复/清算通知三条路径相互独立、无自动联动。请确认这是有意为之还是待补。 [影响]
Q9 合规检查放在生成前还是生成后?(docs/22 §6 列为待定决策) 现状:推介材料代码里两者都有(_generate_tx 有"输入资料未通过合规校验"与"生成内容未通过合规校验"两个 422);客服侧未见显式前置校验。 [阻塞]
Q10 是否允许 Agent 给出"投资建议"? 边界是什么? 现状代码是保守的:asset_allocation_service.py 常量 analysis_only: True 且 disclaimer = "分析结果仅供参考,不生成交易指令。";docs/43 明确客服不得承诺收益、不得修改风险测评。 [影响]
Q11 投顾灰度白名单的最终开放范围(现为 ADVISOR_ROLLOUT_CUSTOMER_IDS,空名单 = 全体客户 fail-closed)? docs/31 有开关与回滚手册;具体放量节奏需业务定。 [影响]

0.3 缺失的输入材料(需要业务方提供文件)

# 问题 影响
Q12 原始需求文档 HTML(设计提到 C:\Users\Windows\Desktop\金融\需求文档-修改版.html,本工作区不可达)能否提供? [阻塞]——本文件是从代码+设计反推的,若有原始需求,可对齐措辞与遗漏项。
Q13 场外申购/赎回单的真实样例件(至少各 1 份 PDF/扫描件)。 docs/22 明确"场外是唯一需要新表的模块,且缺样例单据"。没有样例,OCR 字段与规则无法验收。[阻塞]
Q14 投顾 21 张表的登记文档是否已有?(docs/28 只登记了场外 10 张 + 推广 7 张,投顾 21 张"登记文档待补") [影响]——影响投顾模块的数据字典完整性。
Q15 部署环境是否具备 LibreOffice / soffice? product_promotion_to_do_list.md 记录:推介材料 PPTX 已能真实生成,但 PDF 转换依赖部署环境的 LibreOffice,本机未验证。[阻塞](影响"PPT 导出"这项验收)
Q16 生产数据库/中间件规格(MySQL 8.0 版本、Redis、Milvus 版本与部署形态、Neo4j 是否必装)? 现状:app/core/knowledge_schema.py 显示Milvus 集合 schema 因环境而异(本机 knowledge_id/snippet,架构师环境 doc_id/content/visibility/chapter),检索层做了运行时探测。生产环境以哪套为准需定。[影响]
Q17 模型与供应商清单(对话模型、Embedding 模型及其向量维度、是否允许外网调用、是否需私有化)? docs/22 §6 明确:模型选择决定 Milvus schema,是待定决策。现状配置含 deepseek-flash 等。[阻塞]

0.4 流程与角色

# 问题 影响
Q18 客服工单与风控工单是否要真正打通?(docs/22 §2.3 列"跨 Agent 联动规则未定义") docs/03 验收要求"客服工单与风控工单不得混用",跨域升级路径未定。[影响]
Q19 是否需要"客户主动发起风险评估"入口,还是测评只由运营/客服在后台维护? docs/43 说客服不能改风险测评;那客户自己能否改?未写明。[影响]
Q20 人工兜底的值守时段与 SLA(客服转人工后多久响应?风控告警多久必须处置?)? docs/03 有状态机但无时间承诺;风控有 overdue 概念但阈值来源未明。[影响]
Q21 免责声明 / 适当性提示的标准文案由谁出?(合规部?) 现状:代码里有 disclaimer 常量与 disclosures 结构,但正式文案需合规确认。[影响]

0.5 占位实现与本期边界(★ 接口有、值还没真算)

本节专门登记一类偏差:接口存在、字段有返回、但值是占位常量。它不报错、单元测试全绿, 也不会被现有任何自动化检查发现 —— 只有业务对着真实口径才看得出不对, 因此是演示现场最容易被追问的地方。以后发现同类问题请继续往本节追加。

# 问题 现状 / 冲突点 影响
Q22 客户看板的「今日盈亏」本期是否实现? app/service/trade_service.py 里 today_profit_loss 是硬编码 ZERO:持仓列表 L678、账户看板 L748;today_profit_loss_ratio 同理(L749)。对比:同一函数里的「持有盈亏」是真算的(market_value - cost_amount,L660 / L726),所以只有「今日盈亏」恒为 0。客户看板、持仓页(T006)、盈亏分析页的该字段永远显示 0.00。 [阻塞] —— 演示必被问。若本期不做,需明确对外口径:要么前端不展示该列/卡片,要么显示 —,不要显示 0(0 会被当成真实值)

若决定实现:口径与数据可行性(2026-09-14 实测核实)

候选口径 数据现状 可行性
(今日收盘价 − 昨收) × 数量,基准取 fin_market_price 不可行:该表只在行情同步时写行,实测每个产品仅 2 行(如 515450 只有 2026-09-11 与 2026-09-14),取不到连续的「昨收」,且这两行还跨了周末 ❌
(今日净值 − 上一交易日净值) × 数量,基准取 fin_nav_history 可行:该表每个产品有 120~160 行连续交易日净值(由 tools/sync_nav_history.py 同步,按 (product_id, nav_date) 幂等 upsert) ✅

⇒ 建议按净值口径实现。同时请业务确认语义:净值是日终数据,该指标实际含义是 「最近一个交易日相对前一交易日的盈亏」,不是盘中实时;当天净值同步之前它会与「昨日」一致。 这一点要在界面文案上讲清楚,否则又会被当成 bug。

建议回答方式:不必逐条写长文,可直接在本章表格后追加"Q1:……"式的短答,或在对话中直接回复序号+结论。标 [阻塞] 的 12 项(Q1/Q2/Q3/Q4/Q5/Q6/Q9/Q12/Q13/Q15/Q17/Q22)建议优先给出,其余可先按本文给出的默认口径执行,后续修订。


1. 项目背景与目标

1.1 项目背景

本项目是一个面向基金业务的通用 Agent 平台,采用"厚平台、薄 Agent"的设计哲学:

  • 厚平台:统一承担会话、幂等、长短期记忆、关系推理(Neo4j)、配置快照与发布、多模型路由、工具执行、合规校验、审计留痕、可靠事件投递(Outbox)等横切能力;
  • 薄 Agent:业务 Agent 只负责"检索、分析、生成、归纳、分诊",不得自行实现鉴权、记忆、模型调用、审计等能力,必须继承公共 BaseAgent 并由 AgentFactory 创建。

平台当前覆盖六大业务域:

域 业务Agent / 服务 数据表归属
客服问答 CustomerServiceAgent 场内基线的客服相关表
场内基金模拟交易 交易服务(非 Agent,确定性服务) 场内 51 张表
风控 RiskAgent + 规则引擎 场内基线的风控相关表
投顾 AdvisorAgent advisor_* 21 张表
场外基金运营 OffsiteFundAgent offsite_* 10 张表
基金推介材料 PromotionMaterialAgent promotion_* 7 张表

1.2 项目目标

目标一:建一个"不绕过统一执行骨架"的 Agent 平台。 所有业务 Agent 走同一套七步执行流程(输入校验 → 记忆召回 → 意图识别 → 核心业务 → 生成与合规 → 数据落库 → 事件广播),保证鉴权、合规、审计、事件四条链路不可能被旁路。

目标二:让四类高风险业务在"人在环中"(Human-in-the-loop)下可用。

  • 场内交易:模拟撮合,所有成交、资金、持仓均为平台内部虚拟数据,不涉及真实资金;
  • 风控:规则引擎做确定性扫描,模型只用于生成"建议优化方向",不得替代规则判断;
  • 场外运营:Agent 只做识别与核对,最终确认必须由运营人员点击;
  • 投顾:只输出分析,不生成交易指令。

目标三:权威业务事实不可被记忆或模型覆盖。 记忆分层中,MySQL 中的权威事实(持仓、现金、成交、风险测评)优先级高于用户自述与 AI 推断;低版本记忆不得覆盖高版本。

目标四:满足课程/项目的阶段性验收标准。 一期 7 条验收标准(见第 6 章)已全部达成,附真机证据;本文件在此基础上把需求正式化。

1.3 业务模式

维度 说明
产品形态 B2C 模拟交易 + B2B2C 运营辅助。客户端为访客/客户自助问答与模拟下单;员工端为客服工作台、风控工作台、投顾工作台、运营控制台
收入模式 无收入(模拟盘)。若转生产需业务补充商业模式(见 Q2)
资金流 无真实资金流。场内为虚拟账户记账;场外只做单据核对与通知留痕,不做划款
数据流 行情来自外部接口(实时价 + 日K,落 fin_nav_history);其余全部为平台内部产生
合规模式 事前(适当性校验、白名单发布)+ 事中(模型生成后合规检查、人工确认闸门)+ 事后(全链路审计、trace_id 贯穿)

2. 用户角色与典型使用场景

2.1 角色清单

平台共定义 8 类角色(5 个人类角色 + 3 个非人角色),每一类都带明确的禁止事项——这是本项目合规设计的核心,需求层面不可弱化。

# 角色 系统角色码 可以做 明确禁止
1 访客 visitor 浏览公开产品页、提问(受知识边界限制) 不得访问任何客户数据;不得下单
2 客户 customer 提问、看自己资产/持仓/成交、做测评、确认方案、下单(模拟) 不得查询他人任何数据
3 客服人员 employee + 客服权限 受理咨询/投诉/转交工单、查知识库 不得做产品推荐
4 持证投顾 advisor 复核方案、解释风险、确认适当性 不得绕过适当性、不得承诺收益
5 运营人员 operator / employee 核实业务数据、处理异常、做最终确认 不得让 Agent 自动完成最终确认
6 风控专员 risk_operator 调查/排除/升级/结案告警 不得修改交易、资金、持仓事实
7 平台管理员 admin 配置、模型路由、知识发布、权限治理 不得绕过配置不可变版本机制
8 规则引擎(非人) — 确定性扫描 → 产生告警 不得用模型判断替代规则
9 Agent(非人) — 检索/分析/生成/归纳/分诊 不得代客交易、不得越权查询、不得做最终业务决策
10 通用平台(非人) — 鉴权/记忆/工具/合规/审计/事件 不得被业务旁路

演示账号(来自 docs/44):cust_t / 123456(客户)、risk_t / 666666(风控)、admin_t / 88888888(管理员)、advisor_t / abc12345(投顾)。另种子脚本 tools/seed_test_rbac.py 内置 review_t(故意不授予角色、不设密码,用于边界测试)。

2.2 典型使用场景

编号 场景名 角色 触发 期望结果
S-01 访客知识边界问答 访客 问"基金申购后多久确认" 命中知识库给出答案;问超出范围内容时不硬答,给 [无法确认] 与热线
S-02 客户查看资产 客户 打开"我的资产" 返回现金余额、总市值、总资产;持仓查询不校验行情时效
S-03 客户模拟买入 ⭐ 客户 选基金、填数量(100 的整数倍) 走完校验链→立即全额成交→生成订单+流水+持仓+资金变动
S-04 客服多轮对话与转人工 客户/客服 连续追问或明确要求转人工 3 轮以上保持上下文;转人工时上下文完整带入工单
S-05 风控告警处置 ⭐ 风控专员 规则扫描产生告警 走 待处理 → 调查中 → 已排除/已结案;升级为独立标记
S-06 风控日报流式查看 风控专员 打开日报 SSE 流式产出;规则部分确定性,仅"建议优化方向"用模型
S-07 投顾方案生成与复核 投顾 客户已填目标与画像 生成资产配置与产品推荐;只分析、不下单;需适当性+合同证据三重校验
S-08 管理员配置治理 管理员 改配置/知识 走 draft→review→activate 不可变版本;If-Match 乐观锁防并发覆盖
S-09 场外单据核对与回复 运营 收到申购/赎回邮件 OCR+字段识别→NL2SQL 查数→规则核对→人工确认→按类型发通知
S-10 推介材料生成 运营/市场 上传结构化资料 合规校验→生成 PPTX→复核→内部发送记录留痕

3. 功能需求(按模块划分 + 优先级)

优先级定义 P0 = 本期必须交付,缺失则验收不通过; P1 = 本期应交,可接受降级实现(如以人工替代自动化); P2 = 本期可不做,但需在架构上预留。


3.1 模块一:通用 Agent 平台底座(P0)

编号 需求 优先级 验收要点
F-1.1 提供统一七步执行骨架,业务 Agent 必须继承 BaseAgent,由 AgentFactory 创建 P0 无法绕过鉴权/记忆/模型路由/工具/合规/审计/事件
F-1.2 统一成功信封 {"data":..., "meta":{"trace_id":...}};列表额外含 next_cursor/has_more P0 业务接口不得新增其他顶层字段
F-1.3 统一错误信封 {"error":{code,message,retryable,field_errors}, "meta":{trace_id}} P0 36 个错误码,retryable 逐码标注(不由状态码推导)
F-1.4 trace_id 全链路贯穿 P0 取值顺序:请求上下文→request.state→X-Trace-ID→空串;不得伪造
F-1.5 幂等:Idempotency-Key,范围 = user_id + method + 规范化路径 + key P0 同键并发只产生一条消息/工单/领域事件;记录与业务写入同事务
F-1.6 乐观并发:If-Match vs 行内容摘要,冲突→409 RESOURCE_VERSION_CONFLICT(可重试) P0 每个支持 If-Match 的资源必须同时提供返回 etag 的读接口
F-1.7 游标分页:cursor 表示"取更旧一页";非法游标→400 INVALID_CURSOR P0 校验在权限闸门之后、数据访问之前
F-1.8 限流 enforce_rate_limit 作为路由依赖,鉴权始终先于限流 P0 交易类(/api/v1/users/me/**)不限流
F-1.9 三段式异步 Agent 运行:POST → 202 + status_url/events_url;轮询或 SSE 取结果 P0 需常驻 Worker,否则 agent_run 停在 queued
F-1.10 SSE 契约:start/tools/replace/delta/done/error,心跳为注释行 P0 终态走重放模式;delta 按 sse_chunk_characters(默认 256)切分
F-1.11 记忆分层:短期(Redis) → 情节(中期) → 长期(promotion) P0 召回权威性:MySQL 权威事实 > 用户自述 > AI 推断
F-1.12 配置发布:不可变版本,draft→review→activate→rollback P0 一次请求内配置不得漂移;发布白名单为工具可用范围上限
F-1.13 审计与事件:所有写操作留痕;Outbox 保证事件可靠投递 P0 每条请求可凭 trace_id 追溯

3.2 模块二:认证与权限(P0)

编号 需求 优先级 验收要点
F-2.1 登录:POST /api/v1/auth/tokens P0 失败不区分原因,统一"用户名或密码不正确";用户不存在时仍走 dummy bcrypt 防时序侧信道
F-2.2 JWT 只携带 sub;角色/权限/data_scope 每请求实时解析 P0 支持即时吊销;ACCESS_TOKEN_TTL_SECONDS=1800
F-2.3 访客令牌跳过身份解析 P0 访客只能命中公开面接口
F-2.4 新人引导闸门:客户未完成引导访问 /api/v1/**(onboarding 除外)→ 403 ONBOARDING_REQUIRED P0 —
F-2.5 RBAC:权限码定义源为 tools/seed_test_rbac.py 的 PERMISSIONS P0 该脚本为 DELETE 重建语义,未并入的权限码重建即消失(表现为"接口突然 403 且无报错")
F-2.6 三种 data_scope:self / own_customers / all P0 零跨客户访问(重要验收红线)

3.3 模块三:客服 Agent 与知识库(P0)

编号 需求 优先级 验收要点
F-3.1 五类意图识别:faq / product_inquiry / policy_explain / chitchat / transfer_human P0 五类均需端到端可测
F-3.2 三集合知识路由:FAQ TopK 3、产品 TopK 5、政策 TopK 5 P0 检索层运行时探测字段名,不得硬编码
F-3.3 知识只使用"已发布 + 在有效期"的版本 P0 未发布版本不得被召回
F-3.4 低置信不得硬答;转人工上下文完整 P0 需 Q4/Q5 提供阈值
F-3.5 知识管理三端点:上传 / 列表 / 删除 P0 上传 201 / 列表 200 / 删除 200;客户访问上传应 403
F-3.6 知识发布流程:上传→草稿/待审→抽取分块→法务审核→批准→向量化→发布生效 P0 512/64 字符分块(非 token)
F-3.7 客服工单状态机:pending→assigned→processing→resolved→closed P1 与风控工单不得混用
F-3.8 客户画像候选流程:候选→客户确认→管理员复核 P1 候选视图不含对话原文证据
F-3.9 一期验收:产品咨询 ≥5 题、准确率 ≥80% P0 已达成(5/5)
F-3.10 一期验收:政策解释 ≥2 题 P0 已达成(3/3)
F-3.11 一期验收:多轮上下文 ≥3 轮 P0 已达成(3 轮)

3.4 模块四:场内基金模拟交易(P0)

编号 需求 优先级 验收要点
F-4.1 20 只场内基金(13 ETF + 7 LOF)产品数据 P0 风险等级 R1–R5;管理费 0.15%–1.20%/年;托管费 0.05%–0.20%/年
F-4.2 账户看板:现金余额、总市值、总资产 P0 注意:today_profit_loss / _ratio 当前为硬编码 0(占位),需业务确认是否本期实现 → 见 Q22(含数据可行性与建议口径)
F-4.3 持仓查询 P0 只读持仓故意不校验行情时效
F-4.4 下单(买入/卖出),市价全额成交 P0 首版仅支持 price_type="market",limit_price 恒为 null
F-4.5 完整校验链(顺序不可调) P0 见 5.5 节
F-4.6 交易数量约束:1 手 = 100 份,最低 0.001 元价位 P0 quantity % lot_size == 0
F-4.7 行情时效:MAX_QUOTE_AGE = 15 分钟 P0 超龄→所有委托 503,无自动刷新;需 python tools/sync_market_prices.py 补刷
F-4.8 撤单 P0 仅 待风控 状态可撤;其余→409 ORDER_NOT_CANCELLABLE
F-4.9 流水与资金流水查询 P0 金额字段全部为字符串化 Decimal,非 JSON number
F-4.10 成交需满足幂等与事务原子性 P0 订单+流水+持仓+账户同事务

3.5 模块五:风控(P0)

编号 需求 优先级 验收要点
F-5.1 规则引擎确定性扫描 → 产生告警 P0 不得用模型判断替代规则
F-5.2 告警处置:待处理 → 调查中 → 已排除/已结案 P0 五动作均需 risk:alert:write
F-5.3 升级为独立标记(非状态) P0 返回 is_escalated/escalated_at/escalation_reason
F-5.4 风控日报:前 8 项确定性计算,仅"建议优化方向"可用模型 P0 SSE 事件 start/progress/replace/done
F-5.5 证据查询:8 类来源 customers/products/transactions/capital_flows/holdings/login_records/alerts/notifications P0 未知来源→404;须与前端 EVIDENCE_COLUMNS 对齐
F-5.6 证据归档(multipart 上传) P1 成功/失败均审计;try/finally close()
F-5.7 日报邮件发送 P1 唯一曾漏鉴权的风控端点,现于 Service 层强制 risk:report:mail;默认 dry_run
F-5.8 扫描互斥:MySQL GET_LOCK('jr_risk_scan_schedule', 0) P0 锁在入口层获取,不得放在 RiskScanService.scan() 内(否则调度器自锁死)
F-5.9 风控专员不得修改交易/资金/持仓事实 P0 边界红线
F-5.10 列表 limit 上限严格:告警 max 5;证据/通知 max 10 P0 风控是唯一扩展 meta.total/meta.page_size 的域

3.6 模块六:投顾(P1)

编号 需求 优先级 验收要点
F-6.1 投资目标管理(AD001–AD007) P1 目标/方案状态机失败返回 409 但复用 RUN_NOT_CANCELLABLE 字面量(已知文档缺陷,见 Q 补充说明)
F-6.2 组合分析(AD008) P1 status ∈ no_positions/valuation_required/ready;7 类警告码;图上下文降级不抛错
F-6.3 资产配置(AD009) P1 硬编码 C1–C5 战略比例;常量 analysis_only: True
F-6.4 产品推荐(AD010/AD011) P1 三重校验:场内可交易 + 权威适当性 + 合同证据
F-6.5 灰度放量:ADVISOR_ROLLOUT_ENABLED + ADVISOR_ROLLOUT_CUSTOMER_IDS P0 空白名单 = 全体 fail-closed;拒绝→403 AGENT_PERMISSION_DENIED + 审计 advisor.rollout_denied
F-6.6 admin/super_admin 始终放行 P0 —
F-6.7 不承诺收益、不绕过适当性 P0 边界红线

3.7 模块七:场外基金运营(P1)

编号 需求 优先级 验收要点
F-7.1 邮件增量收取:IMAP UID 增量扫描 → MIME 解析 → 附件落盘 P1 原文 EML + 附件哈希留存
F-7.2 附件识别:OCR → 结构化字段抽取 P1 申购 8 个必填字段;赎回 7 个必填字段
F-7.3 单据字段:基金代码/名称/账户标识/申请编号/申请日期/代销机构/申购金额/金额单位/赎回份额 P1 金额支持"万元"换算、币种前缀剥离
F-7.4 NL2SQL 只读查数(最新净值、最新总份额、申请前持有份额、可用份额) P1 查询失败→无法判断,不得猜测
F-7.5 确定性规则核对 P0 见 5.7 节四规则
F-7.6 运营人员最终确认(确认正常/确认异常) P0 识别未完成时→422 不得确认
F-7.7 通知四类型:risk/settlement/mail_return/normal_return/exception_return P1 校验规则严格:风控只发"确认异常"、清算只发"确认正常"
F-7.8 发送前必须完成运营确认(operator_confirmed) P0 未确认→422"邮件发送前必须完成运营确认"
F-7.9 清算统计只统计"确认正常 + 回复发送成功"的单据 P1 口径见 5.7
F-7.10 字段人工修正(OCR 字段 + NL2SQL 字段) P1 修正值优先,原值落库不变;有缺失/低置信字段时默认进"编辑态"
F-7.11 附件在线预览(PDF/图片)与下载 P2 仅白名单 MIME 内联;其余强制下载 + X-Content-Type-Options: nosniff
F-7.12 AML 与开放期规则不在本次范围(边界明确) — 见 Q8

3.8 模块八:基金推介材料(P2)

编号 需求 优先级 验收要点
F-8.1 任务创建与结构化资料维护 P2 X001..X008
F-8.2 附件类型与限额:经理照片(.jpg/.jpeg/.png/.webp)、业绩数据(.csv/.xlsx/.xlsm)、来源佐证(30MB, .pdf/.docx/.xlsx/.csv)、模板(50MB, .pptx) P2 sha256 去重→"duplicate": true
F-8.3 生成:4 种 code 结果(0 / 422 缺资料 / 422 输入未过合规 / 422 生成未过合规 / 503) P2 HTTP 恒 200,业务码在 body
F-8.4 复核:要求 version.status == "pending_review" 且无阻断性合规发现 P2 —
F-8.5 投递:要求 version.status == "approved" 且 delivery_channel == "internal_record" P2 首版只支持内部发送记录,未接入外部投顾端
F-8.6 PPTX 真实生成(10 段式大纲) P2 已达成
F-8.7 PDF 转换 P2 依赖部署环境 LibreOffice/soffice,本机未验证(见 Q15)

3.9 模块九:前端与运维(P0)

编号 需求 优先级 验收要点
F-9.1 四套页面:guest/、customer/、employee-console/、employee-risk/(+ employee-advisor) P0 挂载于 /portal/;/ 与 /portal/ 均 307 跳 /portal/guest/home/
F-9.2 端点表集中在 common/api-client.js P0 改接口调用只改这一份
F-9.3 健康检查:/internal/health/live、/internal/health/ready、/internal/metrics P0 无鉴权、无信封;ready 真实探测 MySQL/Redis/Milvus,超时 2s;不 ready→503
F-9.4 一键启动:双击 启动金融Agent平台.bat P0 找解释器→检查中间件→刷新行情→起 API+Worker→等应答→开浏览器;重复双击安全
F-9.5 演示数据一键准备:tools/seed_demo_data.py P0 10 步有依赖顺序;第 2 步非幂等(重跑会重置密码)
F-9.6 自检工具两条线互补 P0 e2e_smoke_test.py(业务 6 线 40 项)+ portal_api_check.py(契约 41 项)

4. 非功能需求

4.1 性能需求

编号 指标 目标值 说明 / 现状依据
N-1.1 访客一问端到端响应 ≤ 5 秒 本机实测(Worker 在跑 + deepseek-flash)4.1–4.8 秒;其中受理环节仅占很小部分,主要耗时在模型生成
N-1.2 Agent 受理接口(POST /agent-runs) ≤ 200ms(同步返回 202) 三段式设计目的即为把长耗时甩给 Worker
N-1.3 异步运行结果可见时延 ≤ 8 秒(P95) 轮询/SSE 均可;需 Q20 补充 SLA
N-1.4 场内下单接口 ≤ 500ms 纯数据库事务 + 一次行情读取,无模型调用
N-1.5 SSE 首字节 ≤ 1 秒 日报流式产出
N-1.6 健康检查就绪判定 ≤ 3 秒 Milvus 探测超时 2s
N-1.7 列表接口分页 全部走游标/限额 风控告警 limit 最大 5,避免大结果集
N-1.8 并发承载 需业务确认(见 Q2) 演示级无需压测;生产级需给出目标 QPS
N-1.9 行情数据量 ~120 个交易日日K fin_nav_history 同步量级

4.2 安全需求

编号 需求 优先级 说明
N-2.1 鉴权先于一切:鉴权 → 限流 → 权限 → 游标校验 → 数据访问 P0 顺序错乱会产生"存在性预言机"(406 vs 404 泄露资源是否存在)
N-2.2 零跨客户访问:data_scope 三值严格生效 P0 验收红线
N-2.3 零适当性违规:无匹配风险等级不得成交 P0 校验链第 2 位
N-2.4 零敏感信息泄露:audit:read-sensitive 脱敏为 {"redacted": true} P0 —
N-2.5 JWT 密钥管理与轮换 P0 docs/26 有设计;密钥不得进仓库
N-2.6 登录防暴力破解:enforce_login_rate_limit P0 —
N-2.7 登录不区分失败原因 + dummy hash 抗时序侧信道 P0 —
N-2.8 幂等防重:同键并发只产生一条副作用 P0 —
N-2.9 乐观锁防并发覆盖 P0 If-Match;冲突 409 且 retryable=true
N-2.10 附件安全:白名单 MIME/后缀;非白名单强制下载 + nosniff P0 防 XSS
N-2.11 不得绕过统一执行骨架(含合规、审计、事件) P0 AGENTS.md 规则 7
N-2.12 AI 输出不得作为最终业务决策 P0 场外确认、风控处置、投顾下单均需人在环中
N-2.13 工具可用范围 = 代码上限 ∩ 当前 active 发布白名单;缺配置失败关闭 P0 fail-closed
N-2.14 生产环境不得启用 SMTP 真实发信而未做鉴权 P0 曾有风控邮件端点漏鉴权,已修(F-5.7)

4.3 兼容性需求

编号 需求 说明
N-3.1 数据库兼容:MySQL 8.0,utf8mb4,默认 schema aaa 主键 BIGINT UNSIGNED;金额 DECIMAL(18,2),价格 DECIMAL(18,6),场内数量 DECIMAL(18,4)
N-3.2 基线不可变:docs/00 为不可变业务基线 只允许新增表/新增字段;禁止重命名、删除、复用已有字段,禁止改类型/可空性/业务含义
N-3.3 前后端契约兼容:信封例外仅三处 ① V001 裸 body;② K003 的 data 包 {items,count};③ 场外运营全域沿用旧式 {code,message,data}(成功 = code===0)
N-3.4 推介材料特例:422/503 放 body code,HTTP 保持 200 前端必须按 body 判断,不能只看 HTTP 状态
N-3.5 Milvus schema 环境差异:检索层运行时探测字段名 本机 knowledge_id/snippet;架构师环境 doc_id/content/visibility/chapter。任何地方不得硬编码字段名
N-3.6 config_release 是环境数据,不随代码合并 "白名单已发布"必须带环境限定;换环境需重发
N-3.7 浏览器兼容:现代 Chromium / Edge / Safari(ESM 模块) 注意 employee-console/workspace/workspace.js 存在语法错误(见第 6 章风险项)
N-3.8 解释器与依赖:Python ≥ 3.11(使用 datetime.UTC)+ fastapi/sqlalchemy/asyncmy/pydantic 版本门槛必须实测 import 依赖,不能只看 --version
N-3.9 脚本编码:start.ps1 必须 UTF-8 with BOM;启动器 bat 必须 GBK + CRLF + 无 BOM 缺 BOM 会导致 PowerShell 5.1 按 GBK 解析报语法错
N-3.10 场外/推广/投顾 38 张表不进 docs/00 基线 依据 AGENTS.md 规则 8(场外独立);投顾 21 张登记文档待补(Q14)

4.4 可靠性与可维护性

编号 需求 说明
N-4.1 三段式异步 + 常驻 Worker 无 Worker 时 agent_run 停在 queued,前端只显示"客服响应超时"——排查第一步是查 agent_run 最新行是否 queued
N-4.2 事件可靠投递(Outbox) 幂等键并发只产生一条领域事件
N-4.3 降级不抛错:外部依赖(Neo4j/NL2SQL)失败时降级标记而非异常 如 neo4j_unavailable:...
N-4.4 配置文件不可变版本 + 回滚演练记录 docs/31 要求保留回滚演练记录
N-4.5 观测:trace_id 可追溯 + /internal/metrics metrics 当前为 Prometheus 桩 jr_agent_up 1
N-4.6 Redis 丢失后,澄清轮次可从 MySQL 恢复 验收红线

5. 关键业务流程说明

5.1 通用 Agent 七步执行骨架(P0 核心)

所有业务 Agent 必须走同一骨架,任何一步都不可省略:

① 输入校验     → 结构校验(Pydantic)+ 业务前置校验;失败→422 AGENT_INPUT_INVALID
② 记忆召回     → 短期(Redis) → 情节(中期) → 长期;权威性:MySQL 事实 > 用户自述 > AI 推断
③ 意图识别     → 配置化意图分类(config_release 中的意图配置)
④ 核心业务     → 检索 / 计算 / 查询(工具执行,受白名单约束)
⑤ 生成与合规   → 模型生成 → 合规校验(不通过则不得输出)
⑥ 数据落库     → 与幂等记录同事务写入
⑦ 事件广播     → Outbox → 可靠投递

关键约束:④ 步的工具可用范围 = 代码上限 ∩ 当前 active config_release 的发布白名单,缺发布配置则失败关闭(fail-closed)。

5.2 客服五意图与知识路由(P0)

用户提问
  ↓
意图识别 ──┬─ faq            → FAQ 集合 TopK 3
           ├─ product_inquiry → 产品集合 TopK 5
           ├─ policy_explain  → 政策集合 TopK 5
           ├─ chitchat        → 闲聊话术模板(customer_service_chitchat)
           └─ transfer_human  → 转人工,上下文完整带入工单
  ↓
置信度判定 ─┬─ 高 → 组织答案输出
            └─ 低 → 【不得硬答】→ 标记 [无法确认] + 给人工热线 15936583816
  ↓
工单状态机:pending → assigned → processing → resolved → closed

已知口径:分块为 512/64 字符(非 token,不引入分词器依赖);低置信热线为真实号码 15936583816(非占位符)。 待确认:混合检索加权公式与分数分段(Q4)、转人工阈值(Q5)。

5.3 知识发布流程(P0)

上传文档 → 草稿/待审 → 文本抽取与分块 → 法务审核 → 批准
   → 向量化(Embedding)→ 发布生效(published + active)

约束:检索时只使用已发布且在有效期内的版本;发布是不可变版本,可回滚;一次请求内配置不得漂移。

5.4 投顾业务流程(9 步,P1)

① 客户填投资目标
② 客户完成风险测评(权威事实,Agent/客服不可修改)
③ 拉取客户画像(持仓/交易/偏好)
④ 组合分析(AD008)—— Neo4j 关系推理,失败降级
⑤ 资产配置(AD009)—— C1–C5 战略比例,analysis_only
⑥ 候选产品筛选(场内可交易 + 适当性 + 合同证据 三重校验)
⑦ 生成推荐方案(AD010/AD011)—— 含证据卡、排除清单、披露信息
⑧ 投顾复核 + 风险解释
⑨ 客户确认方案
   ✗ 全流程【不生成交易指令】,如需交易跳转至场内模拟交易

灰度闸门:/api/v1/advisor 除限流外,额外经 enforce_advisor_rollout;空白名单 = 全体客户 fail-closed;admin/super_admin 始终放行;拒绝→403 + 审计 advisor.rollout_denied。

5.5 场内模拟交易流程与校验链(P0 核心 ⭐)

客户提交委托
  ↓
【校验链——顺序不可调,任何一步失败即终止】
  ① 产品可交易?        否 → 422 PRODUCT_NOT_TRADABLE
  ② 适当性匹配?        否 → 422 SUITABILITY_MISMATCH
  ③ 行情未超 15 分钟?  否 → 503 FUND_QUOTE_UNAVAILABLE   ← 全委托级拦截
  ④ 账户存在且已开户?  否 → 404 ACCOUNT_NOT_FOUND
  ⑤ quantity > 0?
  ⑥ quantity % lot_size == 0?
  ⑦ 买入:available_cash >= gross + fee?
                          否 → 422 INSUFFICIENT_FUNDS
  ⑧ 持仓比例上限?      超 → 422 HOLDING_RATIO_EXCEEDED
  ⑨ 卖出:available_quantity >= quantity?
                          否 → 422 INSUFFICIENT_HOLDING
  ↓
【成交】市价全额成交(首版仅 market)
  买入 net = gross + fee
  卖出 net = gross - fee
  ↓
【同事务写入】订单(SO…) + 成交(TX…) + 持仓 + 账户 + 资金流水(L…)
  ↓
【撤单】仅 status == "待风控" 可撤,其余 → 409 ORDER_NOT_CANCELLABLE

重要注意事项:

  • 行情有效期仅 15 分钟(MAX_QUOTE_AGE),超时后所有委托一律 503 且无自动刷新——这是演示最容易翻的一环。补刷命令:python tools/sync_market_prices.py(立即生效,无需重启服务)。
  • 只读持仓查询故意不校验时效(enforce_freshness=False)。
  • 账户看板的 today_profit_loss / today_profit_loss_ratio 当前为硬编码 0(占位实现),非真实当日盈亏——需业务确认是否本期实现。
  • 所有金额字段均为字符串化 Decimal,前端不得按 number 处理。
  • 客户必须状态为 已开户 才能访问账户接口(employee 映射为 closed)。

5.6 风控流程(P0)

【扫描】定时/手动 → MySQL 互斥锁 GET_LOCK('jr_risk_scan_schedule', 0)
         ↓(锁在入口层获取,绝不在 RiskScanService.scan() 内——否则调度器自锁死)
       规则引擎确定性扫描 → 产生告警(含等级:高/中/低)
         ↓ 高风险 → 创建通知(通知失败不回归已建告警,返回 notification_failure)
【处置】风控专员:待处理 → 调查中 → 已排除 / 已结案
         · acknowledge  需 status == 待处理 且 ack_at is None
         · investigate  需已确认且 status == 待处理
         · exclude/resolve 需已确认且未结案
         · escalate     独立标记(非状态),可随时升级
【日报】SSE 流式:start → progress → replace → done
         前 8 类指标确定性计算;仅"建议优化方向"可用模型
【边界】风控专员不得修改交易、资金、持仓事实

列表限额:/risk/alerts max 5(默认 5);/risk/evidence/{source} 与 /risk/notifications max 10。 幂等范围:风控写操作使用**实际路径(含 alert_no)**作为 scope,绝不用模板路径。

5.7 场外基金运营流程(P1)

【收取】IMAP UID 增量扫描
   → MIME 解析 + 附件拉取 → 发件人/鉴权校验
   → 原始 EML + 附件哈希落盘(去重)
【识别】OCR(附件)→ DeepSeek 分类与字段抽取
   申购必填 8 字段:基金代码/基金名称/账户标识/申请编号/申请日期/代销机构/申购金额/金额单位
   赎回必填 7 字段:基金代码/基金名称/账户标识/申请编号/申请日期/代销机构/赎回份额
   缺失或低置信 → 该附件默认进入【编辑态】,等人工修正
【查数】NL2SQL 只读查询(三阶段:query → calc → verify)
   申购依赖:最新净值 / 基金最新总份额 / 申请前持有份额
   赎回依赖:基金最新总份额 / 当前最新可用份额
   查询失败 → 规则结果 = 无法判断(【不得猜测】)
【核对】确定性规则引擎(不读库、不调模型)
   ① 申购最低金额       标准化金额 ≤ 1 元 → 异常
   ② 申购后单一投资者持有比例  (申请前持有 + 本次份额) / 最新总份额 > 20% → 异常
   ③ 申购单笔份额上限    本次份额 > 最新总份额 × 10% → 异常
   ④ 赎回巨额比例        赎回份额 / 最新总份额 > 20% → 异常
   ⑤ 账户可用份额        赎回份额 > 可用份额 → 异常
   每条规则输出:规则码/规则名/结果/单据值/库值/计算过程(实际值·规则值·比较)
【人工】运营人员确认 → 确认正常 / 确认异常
   ✗ 识别或核对未完成(recognition_exception / recognition_review /
      recognition_retrying / query_failed)→ 422 不得确认
【通知】类型 → 接收方与前置条件
   · risk            → 风控接收人   ;仅允许"确认异常"
   · settlement      → 清算接收人   ;仅允许"确认正常"
   · normal_return   → 邮件返回接收人;仅允许"确认正常"
   · exception_return→ 邮件返回接收人;仅允许"确认异常"
   · mail_return     → 邮件返回接收人;必须先完成人工确认
   ✗ 发送前必须 operator_confirmed = true,否则 422
【清算】统计口径:仅纳入「operator_decision == 确认正常」
        且「notification_type ∈ (mail_return, normal_return) 且 status == 发送成功」的单据
        按基金代码聚合

明确边界(来自流程图文档,不可自行扩张):

  • 本次仅实现后端 / Agent / 数据 / 接口 / 异步 / 审计;
  • AML 与开放期规则不在本次实现范围;
  • 邮件回复、风控通知、清算通知三条路径相互独立,无自动联动;
  • 邮件收取超时或断连时,按 IDLE 超时做 UID 补偿扫描;
  • 场外流程独立,不得写入场内交易表。

5.8 记忆分层与召回权威性(P0)

短期记忆(Redis,短 TTL)
   ↓ 沉淀
情节记忆(中期,episodes)
   ↓ 提升(promotion)
长期记忆(含证据/冲突/提升/同步/删除链路)
   ↓
召回权威性(由高到低):MySQL 权威业务事实 > 用户自述 > AI 推断
约束:低版本记忆【不得覆盖】高版本;澄清轮次在 Redis 丢失后可从 MySQL 恢复

5.9 异常处理矩阵(摘要)

docs/03 §13 列出 15 行异常场景。核心原则:

异常类型 处理原则
模型超时/失败 降级答复,不得编造业务事实
外部依赖不可用(Neo4j/NL2SQL/Milvus) 降级标记返回,不抛错给用户
行情过期 一律 503,明确提示,不静默用旧价
识别失败/低置信 进入人工修正态,不猜测
通知发送失败 记录失败原因与重试次数,不回归已产生的业务数据
并发冲突 409 + retryable=true,客户端可重试
幂等重复请求 返回首次结果,不产生重复副作用

6. 验收标准

6.1 一期验收标准(教师给定 7 条 —— 全部已达成)

# 验收标准(原文口径) 结果 证据
A1 FastAPI 能启动,/docs Swagger 可访问 ✅ docs/验收与审计/phase1-acceptance-report.md 真机证据
A2 建表成功(SHOW TABLES 返回 10 张) ✅ 实际库中为 52 张(超出标准)
A3 FAQ 问答对导入 Milvus 且检索正确("基金申购后多久确认") ✅ FAQ 106 行,命中分 0.7837
A4 客服 Agent 回答产品咨询 ≥5 题,准确率 ≥80% ✅ 5/5
A5 能处理政策解释类问题 ≥2 题 ✅ 3/3
A6 多轮上下文保持 ≥3 轮 ✅ 3 轮
A7 知识管理接口:上传/列表/删除可用 ✅ 上传 201 / 列表 200 / 删除 200;客户访问上传 403

两项已记录的取舍(有意为之,非缺陷):

  1. 分块按 512/64 字符,非 token(避免引入分词器依赖);
  2. 低置信兜底热线为真实号码 15936583816,非占位符 400-XXX-XXXX。

6.2 平台验收标准(18 条红线 —— 来自 docs/03 §15)

# 验收点
B1 Agent 均由工厂创建,权限隔离正确
B2 七步骨架不可被旁路
B3 客服五意图端到端可测
B4 低置信不硬答;转人工上下文完整
B5 知识只使用"已发布 + 有效"版本
B6 客服工单与风控工单不得混用
B7 场内模拟成交满足幂等与事务原子性
B8 规则引擎与风控 Agent 边界正确(模型不替代规则)
B9 权威业务事实不被记忆覆盖
B10 零跨客户访问 / 零适当性违规 / 零敏感信息泄露
B11 每条请求可凭 trace_id 追溯
B12 同幂等键并发只产生一条消息/工单/领域事件
B13 Redis 丢失后,澄清轮次可从 MySQL 恢复
B14 配置按不可变版本发布/评审/生效/回滚;一次请求内无漂移
B15 只使用备份端点;模型与提示词版本可审计
B16 长期记忆具备证据/冲突/提升/同步/删除测试;低版本不覆盖高版本
B17 Neo4j 受视图/深度/数量/超时/data-scope 约束;失败不编造关系
B18 所有迁移中,原有表名与既有字段定义保持不变

B18 是本项目最硬的一条:修改数据库文档或迁移前,必须对比基线并证明没有改变任何已有表名和字段定义。核验命令:python tools/audit_schema.py。

6.3 交付前自检(两条线互补,都跑一遍)

工具 覆盖 命令 说明
业务链路冒烟 登录→下单→成交、风控扫描→处置闭环、客服问答,共 6 条线 40 项 python tools/e2e_smoke_test.py --read-only 不动数据
接口契约体检 按前端方式调每个端点,核对状态码/信封形状/字段,共 41 项 python tools/portal_api_check.py --write 加测写操作;--dangerous 再加测改生效配置的操作
数据库基线校验 表/字段与 docs/00 基线对比 python tools/audit_schema.py —
RBAC 种子一致性 权限码两套映射一致性 python tools/check_rbac_seed_consistency.py 曾有 advisor 在种子重建后拿到语义错误权限

⚠️ 跑验收脚本前必须先停掉常驻 Worker,否则会抢队列(见 docs/20)。

6.4 本期已知风险与未闭环项(验收时应逐条确认状态)

# 风险/缺口 影响 当前状态
R1 app/static/portal/employee-console/workspace/workspace.js 曾存在真实语法错误(submitRule,约 L500–539,缺一个 }) 管理端工作台该模块无法加载 ✅ 已修复(2026-09-14 提交 4b7ee13「修复管理员工作台函数缺少闭合大括号」)。复验:node --experimental-vm-modules + vm.SourceTextModule 遍历 app/static/portal,44 个模块全部通过。⚠️ 注意 node --check 会假通过,必须用真实 ESM 解析
R2 today_profit_loss 为占位 0 客户看板"今日盈亏"无意义 ⚠️ 已提级为待决项 → 见 Q22(含数据可行性实测与建议口径:行情基准不可行、净值基准可行)
R3 投顾目标/方案状态机失败 409 复用 RUN_NOT_CANCELLABLE 字面量 错误码语义不准 ⚠️ 已知文档缺陷
R4 ResourceNotFoundError 直接抛出得到 SESSION_NOT_FOUND,集成测试期望 RESOURCE_NOT_FOUND 错误码不一致 ⚠️ 推介材料模块遗留(来自 product_promotion_to_do_list.md)
R5 PDF 转换依赖部署环境 LibreOffice/soffice 推介材料 PDF 导出不可用 ⚠️ 本机未验证(Q15)
R6 仅支持 price_type="market" 无限价单 ✅ 设计如此(首版范围)
R7 投顾 21 张表登记文档缺失 数据字典不完整 ⚠️ 待补(Q14)
R8 场外缺真实样例单据 OCR/规则无法端到端验收 ⚠️ 需业务提供(Q13)
R9 无充值提现/银行流水匹配通道 依赖真实资金流的 AML 规则不可做 ✅ 已在基线中明示"不得伪造"(Q8)
R10 config_release 是环境数据不随代码合并 换环境需重发白名单 ✅ 已知,需环境限定声明
R11 RUN_CANCELLED 不是 HTTP 错误类 不要当错误码处理 ✅ 已澄清(它是 request_idempotency 的状态标记)
R12 /internal/** 无鉴权(含真实 Milvus 探测) 生产部署需网关层限制访问 ⚠️ 上线前需网络隔离

7. 附录

7.1 端点规模

22 个路由模块,端点数量约 140 个(表格驱动的路由为循环注册,故为估算值)。精确核对命令:

python -c "from app.main import app; print(len([r for r in app.routes if hasattr(r,'methods')]))"

注:本工作区无 .venv(被 .gitignore 忽略,未随仓库分发),受管解释器缺项目依赖,故该命令未能本地执行。请在有 .venv 的环境执行:.\.venv\Scripts\python.exe -c "..."。

7.2 环境与命令口径

项 值
本机解释器 .\.venv\Scripts\python.exe
架构师环境 D:\conda\envs\jr_py313\python.exe
两者关系 等价,各用本机可用的那个(.venv 不进仓库,不存在统一问题)
启动 API python -m uvicorn app.main:app --port 8000(模块级变量是 app,不是 application)
启动 Worker python -m app.worker(必需,否则 Agent 永远 queued)
一键启动 双击 启动金融Agent平台.bat 或 powershell -ExecutionPolicy Bypass -File start.ps1
刷新行情 python tools/sync_market_prices.py
演示数据 python tools/seed_demo_data.py(10 步,第 2 步非幂等)
前端入口 /portal/(访问 / 会 307 跳到访客首页)

7.3 数据表规模

域 表数 是否进 docs/00 基线
场内(含客服、风控相关) 51 ✅ 是
场外 offsite_* 10 ❌ 否(规则 8) — 登记于 docs/28
推广 promotion_* 7 ❌ 否 — 登记于 docs/28
投顾 advisor_* 21 ❌ 否 — 登记文档待补
合计(业务表) 89 含 alembic_version 则为 90

7.4 已注册业务 Agent(7 个)

FundQueryDemoAgent、CustomerServiceAgent、RiskAgent、PlatformProbeAgent、AdvisorAgent、OffsiteFundAgent、PromotionMaterialAgent

7.5 已注册公共只读工具

search_knowledge(客服知识检索)、check_suitability(适当性校验)、query_customer_profile(画像)、query_fund_quote(行情)。 query_knowledge 是 search_knowledge 的别名(同一 handler,为兼容一期发布配置与旧客户端保留)。 其余业务线工具(风控、投顾、NL2SQL)按各自 Agent 白名单注册,全部在 bootstrap.py 的 get_agent_factory() 中。

7.6 本文档与既有文档的关系

本文档章节 权威来源
第 0 章 待确认问题 本文档新增(汇总 docs/22/docs/10/docs/28/product_promotion_to_do_list.md 的未定义项)
第 1 章 背景目标 docs/01、docs/03、AGENTS.md
第 2 章 角色场景 docs/03 §2、tools/seed_test_rbac.py、docs/44
第 3 章 功能需求 docs/05 接口文档 + app/service/* 实际实现
第 4 章 非功能需求 docs/00 §3、docs/26、docs/07、docs/08、实测数据
第 5 章 业务流程 docs/03 §5–§13、docs/场外申购赎回工作流程图.md、app/service/offsite_fund_rules.py
第 6 章 验收标准 docs/验收与审计/phase1-*、docs/03 §15、docs/44

本文档不替代 docs/00(不可变业务基线)与 docs/05(接口唯一权威)。若三者出现冲突,以 docs/00 / docs/05 为准,并回头修订本文件。