diff --git a/AGENTS.md b/AGENTS.md index 7109664..10227d8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,7 +24,7 @@ - 技术选型 / JWT:`docs/项目框架设计/技术选型和版本/` - Core 模拟底座:`docs/项目框架设计/Core模拟底座/` - 业务记忆分层:`docs/业务记忆管理/业务记忆管理手册.md` -- **基金转换线(✅ 全流程收官 2026-09-12 · T+1 受理/确认分离模型 · AIcoding 六步全部完成)**:**第 5 步 T-1 ~ T-17 全部完成 + 第 6 步集成测试 ✅ 通过**(集成测试零代码改动五步全过:按 SOP 重灌双库(DoD 断言全 PASS 含 ⑨a/⑩/⑫)→ 全量 **849 passed / 8 skipped 零失败** → CONVERT_STRESS=1 **7/7**(T-15 争批用例加入)→ 真库 verify 套件 **9/9 退出码 0**:accept 43 / confirm 103 / engine 39 / api 89 / compensate 56 / apply 30 / lots 20 / tools 14 / seed 全 PASS → 残留检查零命中 + 收尾重灌恢复干净演示态;**验收 31 紧池重测 = 受理 50/50 + 串行确认 50/50 = 100%**、**验收 18 性能重测端到端 P50 78.8 / P95 94.8 ms**(< 2s 余量约 20 倍);执行记录 = 开发计划 §10 + `docs/memory/2026-09-12.md`;**无待办,可选项 = 分支推送 / 里程碑 tag 由用户拍板**);开工入口 **`交接文档.md` §B**(§B.11 下一条立项指引 = 最新状态)· `docs/PRD/PRD-基金转换交易.md`(**v1.1**)· `docs/项目框架设计/架构设计-基金转换交易.md`(**v2.1**)· `docs/项目框架设计/开发计划-基金转换交易.md`(**v2.0** · T-1~T-17 逐任务改法 + DoD + §10 集成测试记录) +- **基金转换线(✅ 全流程收官 2026-09-12 · T+1 受理/确认分离模型 · AIcoding 六步全部完成)**:**第 5 步 T-1 ~ T-17 全部完成 + 第 6 步集成测试 ✅ 通过**(集成测试零代码改动五步全过:按 SOP 重灌双库(DoD 断言全 PASS 含 ⑨a/⑩/⑫)→ 全量 **849 passed / 8 skipped 零失败** → CONVERT_STRESS=1 **7/7**(T-15 争批用例加入)→ 真库 verify 套件 **9/9 退出码 0**:accept 43 / confirm 103 / engine 39 / api 89 / compensate 56 / apply 30 / lots 20 / tools 14 / seed 全 PASS → 残留检查零命中 + 收尾重灌恢复干净演示态;**验收 31 紧池重测 = 受理 50/50 + 串行确认 50/50 = 100%**、**验收 18 性能重测端到端 P50 78.8 / P95 94.8 ms**(< 2s 余量约 20 倍);执行记录 = 开发计划 §10 + `docs/memory/2026-09-12.md`;**README 已更新(2026-09-12:最新更新章节 + 前端已留接口契约);分支已于 2026-09-12 用户授权推送远程(以 `git ls-remote` 为准),合并 main 由合并执行人负责**);开工入口 **`交接文档.md` §B**(§B.11 下一条立项指引 = 最新状态)· `docs/PRD/PRD-基金转换交易.md`(**v1.1**)· `docs/项目框架设计/架构设计-基金转换交易.md`(**v2.1**)· `docs/项目框架设计/开发计划-基金转换交易.md`(**v2.0** · T-1~T-17 逐任务改法 + DoD + §10 集成测试记录) - **架构改进线(✅ 2026-09-10 已结项,无待办)**:开工入口 **`交接文档.md` §C** - **风控模块主线**:**`交接文档.md` §A** diff --git a/README.md b/README.md index 2a2b1a8..8ec3f35 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,34 @@ 四个 Agent(客户财富 / 代理人助手 / 数据分析 / **风控监测**)共用统一数据层与合规底座;Agent 之间**不互调 LLM**,跨 Agent 协作走 L1/L2/L3 画像与预警表。 -> **本分支(`risk-control-agent`)= 风控 Agent 模块的交付分支**。模块功能已全部交付(2026-09-07),合并 main 的事宜见《合并注意事项》一文,后续人员请按下表对号入座。 +> **本分支(`risk-control-agent`)= 风控 Agent 模块 + 基金转换(convert)交易的交付分支**。风控模块全量交付(2026-09-07);**基金转换 T+1 受理/确认分离模型已于 2026-09-12 全流程收官**(AIcoding 六步:PRD → 架构 → 开发计划 → T-1~T-17 开发 → 集成测试全绿)。合并 main 的事宜见《合并注意事项》,后续人员请按下表对号入座。 ## 你是哪种后续人员? | 角色 | 先读 | | --- | --- | | 接手模块开发 / 维护 | [交接文档.md](交接文档.md)(本地)→ [docs/memory/MEMORY.md](docs/memory/MEMORY.md) §0 → [docs/memory/TODO.md](docs/memory/TODO.md) | +| 接手 / 评审基金转换功能 | [docs/PRD/PRD-基金转换交易.md](docs/PRD/PRD-基金转换交易.md)(v1.1)→ [架构设计-基金转换交易.md](docs/项目框架设计/架构设计-基金转换交易.md)(v2.1)→ [开发计划-基金转换交易.md](docs/项目框架设计/开发计划-基金转换交易.md)(v2.0,含集成测试记录 §10) | | 负责把模块并入 main | [docs/项目框架设计/合并注意事项-风控模块并入main.md](docs/项目框架设计/合并注意事项-风控模块并入main.md)(自包含操作手册) | | 了解需求 / 做方案评审 | [docs/PRD/PRD-风控监测Agent.md](docs/PRD/PRD-风控监测Agent.md)(v1.1)+ [附-风控规则表.md](docs/PRD/附-风控规则表.md) | | 起环境跑演示 | [docs/项目框架设计/演示SOP-风控模块.md](docs/项目框架设计/演示SOP-风控模块.md) + 本页「快速启动」 | +| **前端开发(接入已留接口)** | 本页「核心接口一览」+「前端接入契约」(chat 四端点 + 基金转换四端点,契约均有 curl/字段级样例) | -## 模块交付状态(截至 2026-09-08) +## 最新更新(2026-09-12 · 基金转换线全流程收官) -**后端功能全部完成,全量 pytest 510 passed 0 failed(sqlite + 真 MySQL 集成),核心接口实调验收通过。** +**基金转换(转出 A 基金 → 转入 B 基金)已从「一期显式拒收」放开为完整可交易**,建模对齐真实业务 T+1 受理/确认分离:T 日受理(未知价、不扣份额、15:00 前可撤销)→ T+1 登记机构批量串行确认(权益扣除 + 登记)→ T+2 可查可用。 + +- **AIcoding 六步全流程完成**:需求讨论(10 项真实业务拍板)→ PRD v1.1 → 架构 v2.1 → 开发计划 v2.0(三轮独立审核)→ T-1~T-17 逐任务开发 → **第 6 步集成测试通过**。 +- **集成测试结果**:全量 pytest **849 passed / 8 skipped 零失败**;`CONVERT_STRESS=1` 真库并发 **7/7**;9 个真库验证脚本 **9/9 退出码 0**;**紧池场景受理 + 串行确认 = 100% 成功率**(旧实时扣减模型同场景 80%,结构性消除争抢);端到端性能 **P95 94.8ms**(硬门禁 2s,余量约 20 倍)。 +- **种子数据补拉**:净值种子重抓至 **2026-09-11**(东方财富真实净值 × 14 产品,历史值零修订);交易日历经联网核实与交叉校验(169 净值日 0 偏差)无需变更。 +- **关键能力**:受理幂等(`client_request_id`)/ 在途占用校验(可用 = 批次余量 − 未确认受理单)/ 部分成交 / 强制全转 / T 日撤单两道闸门 / 缺净值 `nav_pending` 挂起不降级 / SLA 超时 `expired` 释放 / 补差费(口径 B)/ 逐批次 FIFO 计费(<7 日 1.5% …)/ 份额位数按产品配置(half_up/truncate)/ A/C 份额类别互转开关 / 资金流中转(`core_cash_flow` 同事务两条)/ 规则引擎确认后恰好一次(RISK-002 计一次)。 +- **旧模型退役**:v0.x 两阶段实时编排 `convert_fund` 及其依赖链已删除(466 行),`risk_convert_detail` 镜像写收敛为 `sync_mirror` 单点。 + +架构定位不变:风控 Agent 为**独立封装模块**——模块内自带鉴权(`app/api/deps.py` + `app/service/auth_service.py`)、防护、trace、引擎工厂;与宿主的耦合只走 4 个接缝(挂载点 / AuthContext / settings / 引擎工厂),由 `tests/test_module_boundary.py` 防呆锁定。详见《[风控Agent模块边界与合并接缝标注.md](docs/项目框架设计/风控Agent模块边界与合并接缝标注.md)》。 + +## 模块交付状态(截至 2026-09-12) + +**风控模块 + 基金转换全部完成,全量 pytest 849 passed / 8 skipped(sqlite + 真 MySQL 集成),核心接口实调验收通过。** | 里程碑 tag | 内容 | | --- | --- | @@ -25,10 +39,9 @@ | `risk-m3` | 对话线闭环(风控四只读 Tool + StateGraph risk 分支;现为五只读 Tool,C5 追加 `query_overdue_alerts`) | | 阶段一 | 对齐 main 基准 AL-01~08(SUIT-001~008 退役 → core_ro.check_suitability 矩阵判定) | | `risk-m4` | 追加需求:FR-8 集中度预警 RISK-006 / FR-9 处置时效升级 RISK-007 / FR-10 代理人行为链 RISK-008 | +| **基金转换 T+1(2026-09-12 收官)** | 受理/确认分离全链路:受理幂等 · 在途占用 · T+1 批量串行确认 · 部分成交 · 撤单 · 补偿与 SLA 清理 · 引擎时机收口(详见上节与本页「前端接入契约」3) | -**前端接入面(2026-09-08 补齐,后端侧已齐)**:方案 B 会话管理三端点(`8328c24`)+ 方案 C SSE 流式对话(`01ec5fc`)。同步端点 `POST /api/chat` 契约不变,前端可任选同步/流式。详见下文「前端接入契约」。 - -**架构定位**:风控 Agent 为**独立封装模块**——模块内自带鉴权(`app/api/deps.py` + `app/service/auth_service.py`)、防护、trace、引擎工厂;与宿主的耦合只走 4 个接缝(挂载点 / AuthContext / settings / 引擎工厂),由 `tests/test_module_boundary.py` 防呆锁定。详见《[风控Agent模块边界与合并接缝标注.md](docs/项目框架设计/风控Agent模块边界与合并接缝标注.md)》。 +**前端接入面(后端侧已齐)**:方案 B 会话管理三端点(`8328c24`)+ 方案 C SSE 流式对话(`01ec5fc`)+ 基金转换受理/撤单/查询/确认四端点(2026-09-12)。同步端点 `POST /api/chat` 契约不变,前端可任选同步/流式。详见下文「前端接入契约」。 ## 更新说明(2026-09-09,已推送 origin/risk-control-agent,待合并 main) @@ -103,12 +116,13 @@ cp .env.example .env # 填 MYSQL_PASSWORD / NEO4J_PASSWORD / DEEPSEEK_A pip install -r requirements.txt # 首次灌库与同步:见 docs/memory/FLOW.md §0(权威步骤) uvicorn app.main:app --reload # → GET http://127.0.0.1:8000/health -python -m pytest # 基线 510 用例(系统 Python) +python -m pytest # 基线 849 用例(系统 Python 3.13.14) ``` **演示库重灌(走查/集成测试前必做,两步缺一不可)**: `scripts/core/reset.ps1`(交互式输密码)→ `scripts/demo/prepare_risk_demo.sql`。 ⚠️ 只跑第一步不跑第二步 → 33 客户中 27 人风评过期、约 82% 适当性检查返回 risk_expired,这是种子设计不是 bug。 +💡 非交互环境用 `python scripts/dev/verify_convert_seed.py` 等价替代(pymysql 重放同一组 00~11 SQL + 自动补跑演示数据 + DoD 断言);净值种子过期(真实净值只到抓取当日)时重跑 `python scripts/core/fetch_nav.py --days 60` 补拉。 **调接口(JWT 通道)**: @@ -132,7 +146,10 @@ dev 环境无 Bearer 时可用 `X-Debug-Role` / `X-Debug-Actor` 头兜底(仅 | `POST /api/risk/alerts/{id}/handle` | 人工处置(状态机 + 审计) | risk_officer | | `POST /api/risk/suitability/check` | 适当性校验(C×R 矩阵,G-01 归属) | customer 本人 / advisor 名下 / risk_officer | | `POST /api/risk/aml/scan` | 手动全量 AML 扫描(FR-5) | risk_officer | -| `POST /api/simulate/trade` | 模拟交易(适当性阻断 + 规则引擎) | risk_demo 或客户本人 | +| `POST /api/simulate/trade` | 模拟交易(适当性阻断 + 规则引擎;`trade_type=convert` 时为**基金转换受理** → 202 + 受理回执) | risk_demo 或客户本人 | +| `POST /api/simulate/trade/convert/{gid}/cancel` | 基金转换撤单(T 日 15:00 前;超窗/非 accepted → 409) | 交易 owner(本人) | +| `GET /api/simulate/trade/convert/{gid}` | 基金转换进度查询(受理/确认/驳回终态回执) | 交易 owner / 代理人(查询 scope) | +| `POST /api/admin/convert/confirm?accept_date=` | **T+1 确认批处理触发**(捞当日 accepted 串行确认,运维接口) | risk_officer | | `POST /api/chat` | 对话(X-Agent-Type 分流四 Agent;风控线五只读 Tool) | 按准入矩阵 | | `GET /api/chat/sessions` | 会话列表(本人 + 本 Agent 线,分页) | 按准入矩阵 | | `GET /api/chat/sessions/{id}/messages` | 会话历史消息(seq_no 升序分页) | 仅本人会话 | @@ -173,13 +190,47 @@ curl "http://127.0.0.1:8000/api/chat/sessions//messages?limit=50&offset=0" - 断连/生成异常 = 整轮消息不落库(Tool 留痕仍可审计),前端需提示重试 - 心跳帧未做:长生成空隙靠反代 `proxy_read_timeout` 兜(已知遗留) +**3)基金转换(T+1 受理/确认分离,2026-09-12)** + +```bash +# ① 受理:POST /api/simulate/trade —— trade_type=convert 时走受理分支(份额申报,不是金额!) +curl -X POST http://127.0.0.1:8000/api/simulate/trade \ + -H "Authorization: Bearer " -H "X-Agent-Type: customer" -H "Content-Type: application/json" \ + -d '{"trade_type":"convert","customer_id":"CUST-1001","from_product_id":"PROD-110022", + "to_product_id":"PROD-003095","qty":"50000.00","client_request_id":""}' +# → 202(受理回执){"blocked":false,"accepted":true,"idempotent":false,"status":"accepted", +# "convert_group_id":"CNV-…","client_request_id":"", +# "requested_qty":"48000.00","qty":"50000.00", ← qty=实际受理份额(强制全转时与申请不同) +# "forced_full_transfer":false,"min_hold_action":"force_transfer", +# "accept_date":"2026-09-11","confirm_date":"2026-09-14","available_date":"2026-09-15", +# "cancel_deadline":"2026-09-11 15:00","estimated":true} + +# ② 撤单:T 日 cancel_deadline 前可撤 +curl -X POST http://127.0.0.1:8000/api/simulate/trade/convert/CNV-xxx/cancel -H ... +# → 200;超窗 / 非 accepted → 409 CANCEL_NOT_ALLOWED + +# ③ 进度查询(未确认时返回 processing 语义,前端可轮询) +curl http://127.0.0.1:8000/api/simulate/trade/convert/CNV-xxx -H ... +# → confirmed 后返回确认回执(两端净值/金额/费率/逐批明细/confirm_date) + +# ④ T+1 确认批处理(运维/演示触发,risk_officer) +curl -X POST "http://127.0.0.1:8000/api/admin/convert/confirm?accept_date=2026-09-11" -H "X-Agent-Type: risk" ... +``` + +前端须知: +- **入参是份额(`qty`),不是金额**——真实业务「金额申购、份额赎回/转换」;15:00 截点后受理自动顺延下一交易日(`confirm_date`/`available_date` 回执已算好) +- **两类 202 分辨**:`status=accepted` = 新受理;幂等重试带**同一 `client_request_id`** 会命中在飞单(`processing` 语义)并回显预计确认日——网络超时后**原样重发**即可,不会重复受理 +- 错误码:`TOO_MANY_LOTS`(400,批次 >200 需拆分申请)/ `INSUFFICIENT_SHARES`(可用份额不足)/ `CROSS_ENTITY_NOT_SUPPORTED`(400,A/C 份额类别互转未开通)/ `CANCEL_NOT_ALLOWED`、`CONCURRENT_CONFLICT`(409) +- 未知价法:受理时**不折算金额**,确认回执才含按 T 日净值折算的两端金额与费率;T+1 缺净值会挂 `nav_pending`(确认延迟,非失败) +- `requested_qty`(客户申请)与 `qty`(实际受理)可能不同:触发最低持有余额强制全转时受理段会把指令收敛为实际全转量,**前端展示以 `qty` 为准** + ## 文档地图 | 目录 / 文件 | 内容 | | --- | --- | | [docs/memory/](docs/memory/) | 项目记忆六件套(MEMORY/TODO/REQUIREMENTS/FRAMEWORK/FLOW/ENVIRONMENT),入口为 MEMORY.md §0 | -| [docs/PRD/](docs/PRD/) | 风控 PRD v1.1(§4A = 追加需求)+ 风控规则表 | -| [docs/项目框架设计/](docs/项目框架设计/) | 架构设计 · 开发计划 · 实现方案 C4~C6 · 表设计(SQL 单一事实源)· 技术选型与 JWT 手册 · Core 模拟底座 · 演示 SOP · 边界标注 · **合并注意事项** | +| [docs/PRD/](docs/PRD/) | 风控 PRD v1.1(§4A = 追加需求)+ 风控规则表 + **PRD-基金转换交易 v1.1**(T+1 受理/确认分离) | +| [docs/项目框架设计/](docs/项目框架设计/) | 架构设计 · 开发计划 · **架构设计-基金转换交易 v2.1 / 开发计划-基金转换交易 v2.0(含集成测试记录 §10)** · 实现方案 C4~C6 · 表设计(SQL 单一事实源)· 技术选型与 JWT 手册 · Core 模拟底座 · 演示 SOP · 边界标注 · **合并注意事项** | | [docs/需求拆解/](docs/需求拆解/) | 业务场景优先级、数据交互矩阵、合规约束、四角色用户故事(docx) | | [docs/业务记忆管理/](docs/业务记忆管理/) | 业务记忆分层手册 | | [交接文档.md](交接文档.md) | 模块开发交接(本地保留,不入库) | @@ -188,4 +239,8 @@ curl "http://127.0.0.1:8000/api/chat/sessions//messages?limit=50&offset=0" React 19 + Vite 7 + TypeScript strict + Ant Design 5 + HashRouter——`web/` 目录尚未 init,为下一主线。 -后端接入面已就绪,前端只需三件事:① `POST /api/chat/stream` 接 SSE(首帧拿 `session_id`/`disclaimer`,逐帧拼 `delta.content`,收到 `[DONE]` 收尾);② 进页面先 `GET /api/chat/sessions` 拉会话列表、选中后 `GET .../messages` 拉历史;③ 结束会话调 `POST .../close`。所有请求带 `Authorization: Bearer` + `X-Agent-Type`。 +后端接入面已就绪(chat + 基金转换),前端只需: +① `POST /api/chat/stream` 接 SSE(首帧拿 `session_id`/`disclaimer`,逐帧拼 `delta.content`,收到 `[DONE]` 收尾); +② 进页面先 `GET /api/chat/sessions` 拉会话列表、选中后 `GET .../messages` 拉历史;③ 结束会话调 `POST .../close`; +④ 基金转换:`POST /api/simulate/trade`(convert 分支)受理 → `GET /api/simulate/trade/convert/{gid}` 轮询进度 → T 日内可 `POST .../cancel` 撤单(完整契约见上节「前端接入契约」3)。 +所有请求带 `Authorization: Bearer` + `X-Agent-Type`。 diff --git a/docs/memory/2026-09-12.md b/docs/memory/2026-09-12.md index 0374d43..1fd601c 100644 --- a/docs/memory/2026-09-12.md +++ b/docs/memory/2026-09-12.md @@ -584,3 +584,74 @@ cancelled)是幂等 skip**(批处理单笔容错语义),`ConfirmConflict 六步全流程收官**:第 1 步讨论 ✅ → 第 2 步 PRD v1.1 ✅ → 第 3 步架构 v2.1 ✅ → 第 4 步开发计划 v2.0 ✅ → 第 5 步 T-1~T-17 ✅ → **第 6 步集成测试 ✅**。 后续可选项(由用户拍板):分支推送 / 里程碑 tag 等收尾事项。 + +--- + +# 种子补拉 + 全套重测 ✅(2026-09-12 · 用户指示「大更新后重新抓数据生成种子再重测」) + +## 一、净值种子更新(`06-seed-nav.sql` · 提交 `d2d00dd`) + +- **重抓**:`python scripts/core/fetch_nav.py --days 60`(东方财富接口,14 产品 × 60 净值日), + 抓取时间 2026-09-12 14:56,区间滚动为 **2026-06-19 ~ 2026-09-11**——补上 09-11(周五)净值。 +- **diff 核对(零修订实证)**:新旧文件行级对比 = 仅新增 09-11 的 14 行 + 窗口起点 + 06-18 的 14 行滚动挤出 + 行尾符号调整(09-10 从末日 `;` 变中间日 `,`); + **同日期同产品净值值零变化**(09-10 两次抓取值逐项一致)。demo 锚定的 + T=2026-09-09 净值(PROD-110022=1.3604 / PROD-003095=1.9194)不受影响。 +- **实际价值**:下周一(09-14)起真库脚本 `previous_biz_day` 回推链锚定 09-11 + 时不再缺 T 日净值(旧种子截至 09-10,缺 09-11 会让确认段 nav_pending)。 + +## 二、交易日历种子(`10-seed-trade-calendar.sql` · 无需重生成,留痕依据) + +- **联网核实**:2026 年上交所休市安排仍为 2025-12-22 年度公告(上证公告〔2025〕45 号), + **无临时调整**;脚本 `SSE_CLOSED_2026` 的中秋(09-25~27)/国庆(10-01~07) + 区间与公告一致、种子休市行在位。 +- **交叉校验**(`gen_trade_calendar.py --verify-nav`):用**最新**净值校验 + 「净值日 ⊆ 交易日」不变式——510300 共 169 个净值发布日(原 168 + 新增 09-11) + 全部落在交易日,**0 偏差**;503 交易日不变。 + +## 三、新种子下全套重测(全绿) + +| 项 | 结果 | +| --- | --- | +| 重灌双库(`verify_convert_seed.py`) | DoD 断言全 PASS | +| 全量 pytest | **849 passed / 8 skipped** 零失败 | +| CONVERT_STRESS=1 | **7/7** | +| 真库 verify 套件(按真实退出码复验) | **9/9 退出码 0**(accept 43 / apply 30 / lots 20 / tools 14 / confirm 103 / engine 39 / api 89 / compensate 56 / seed 全 PASS) | +| 收尾重灌 | 全 PASS,库恢复干净演示态 | + +**方法论留痕**:种子数据类文件(净值/日历)的正确维护节奏 = 演示/跑测前 +重跑 `fetch_nav.py` 补最新净值(脚本头注本就内置此指引),日历在交易所公布 +新安排(年度公告/临时调整)时重跑 `gen_trade_calendar.py`——两者都是 +「贴真实项目」铁律在数据层的落点。 + +--- + +# README 更新 + 分支推送 ✅(2026-09-12 · 用户指示) + +## 一、README 更新(重点 = 本次更新 + 前端已留接口) + +- **新增「最新更新(2026-09-12)」章节**:基金转换 T+1 全流程收官(AIcoding 六步、 + 集成测试 849 绿 / CONVERT_STRESS 7/7 / 真库 9/9 / 紧池 100% / 性能 P95 94.8ms)、 + 种子补拉(净值至 09-11)、关键能力清单、v0.x `convert_fund` 退役。 +- **「前端接入契约」新增 3)基金转换**(契约逐项对照实现核对后写入): + ① 受理 `POST /api/simulate/trade`(convert 分支,**份额申报** `qty`,202 + 受理回执; + 回执字段按 `convert_service` 实际返回核对:`blocked/accepted/idempotent/status/ + convert_group_id/client_request_id/requested_qty/qty/forced_full_transfer/ + min_hold_action/accept_date/confirm_date/available_date/cancel_deadline/estimated`) + ② 撤单 `POST /api/simulate/trade/convert/{gid}/cancel`(409 CANCEL_NOT_ALLOWED) + ③ 查询 `GET /api/simulate/trade/convert/{gid}`(未确认 = processing 可轮询) + ④ 确认批处理 `POST /api/admin/convert/confirm?accept_date=`(risk_officer); + 错误码按 `errors.py` 常量逐一核对(TOO_MANY_LOTS/INSUFFICIENT_SHARES/ + CROSS_ENTITY_NOT_SUPPORTED/CANCEL_NOT_ALLOWED/CONCURRENT_CONFLICT)。 +- **其余**:头部定位改「风控 + 基金转换交付分支」、交付状态基线 510→849、 + 「核心接口一览」补 convert 四端点、快速启动补 `verify_convert_seed.py` + 非交互重灌与 `fetch_nav.py` 补拉指引、文档地图补基金转换三文档、 + 「前端」章节从三件事扩为四件事(+基金转换受理/轮询/撤单)。 + +## 二、推送(用户授权) + +- 本轮提交(README + 文档回写)随分支全部推送 `origin/risk-control-agent`; + 推送后以 `git ls-remote` 校验远程 = 本地 HEAD(本仓 `refs/remotes/**` 写入 + 不落盘的已知异常,判断远程存亡只能用 `git ls-remote`)。 +- 合并 main 仍由合并执行人负责(手册《合并注意事项-风控模块并入main.md》), + AI 不发起 PR / 不执行合并。 diff --git a/docs/memory/MEMORY.md b/docs/memory/MEMORY.md index ea89b8d..093f85d 100644 --- a/docs/memory/MEMORY.md +++ b/docs/memory/MEMORY.md @@ -13,7 +13,7 @@ **⚡ 基金转换(convert)线 — 两条子线**: - **(一)v0.x 两阶段实时模型(已结项 2026-09-10)**:PRD **v0.9.3** + 架构 **v1.0.1** + 开发计划 **v1.0**,T-0 ~ T-13 全部完成(第 5+6 步闭环,最终 **739 passed / 10 skipped**,`CONVERT_STRESS=1` 并发 9/9,含死锁重试补丁 `43cf2a1`);**该模型已被下一线取代,其 PRD/架构/开发计划作废,代码保留作过渡基线**。 -- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11**(10 项真实业务拍板)· PRD **v1.1** + 架构 **v2.1** 已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做**(`docs/项目框架设计/开发计划-基金转换交易.md`,797 行:T-0~T-17 按架构 §15 重排 + §1.4 代码事实核对表 F-1~F-25 + §1.5 实现级裁定 R-1~R-15 + §5 十六条回归面 + §6 验收 31 条 + FR-C29/C30 全映射),**经三轮独立审核闭环(第一轮挑毛病 2 阻断+5 重要+3 可选 / 第二轮验证型 12 项零残留 / 第三轮白纸重审 C1~C5+O1~O4 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**核心认知:不新增冻结列,在途占用由受理单推导;紧池 80% 病根在 T+1 串行确认下自动消失。** 下一步:**第 5 步 todo 开发已收官(2026-09-12,T-1~T-17 全部完成 + 三项开口闭环【PRD §2.5.3 修订 / truncate 已接入 / R-12 定稿】,**849 passed / 8 skipped** 零失败;真库 verify 套件 **9/9 退出码 0**:accept 43 / confirm 103 / engine 39 / api 89 / compensate 56 / apply 30 / lots 20 / seed 全 PASS / tools 14。T-15 = D28 部分成交专项(终态单幂等 skipped 口径 + 防御纵深三道防线实证 + Barrier 窄窗争批);T-16 = D29 资金流中转(core_cash_flow 全仓唯一写入点,out/redeem + in/subscribe 各 1 条 remark 带 gid 同事务,5 处清理段 FK 坑修复);T-17 = D30 A/C 互转(share_class 非空且不同才查 allow_ac_convert 开关,任一端=1 两向放行,联网核实 = 摩根 2025-11「开通」公告;口径裁定:NULL 不参与判定、同类走一般规则,已追认定稿);**第 6 步集成测试已通过(2026-09-12 · 零代码改动:按 SOP 重灌双库 → 全量 849 passed / 8 skipped 零失败 → CONVERT_STRESS 7/7(T-15 争批用例加入)→ 真库 9/9 退出码 0 → 残留检查 + 收尾重灌恢复干净演示态;验收 31 紧池重测 100%、验收 18 性能端到端 P95 94.8ms < 2s)——AIcoding 六步全流程收官**)**。**T-7 关键裁定:强制全转属受理段决策** —— 受理由 `plan_lots` 判定并把 `qty` 收敛为实际全转量 + 受理单 `remark='full_transfer'`,确认段**只继承不重判**(`plan_lots` 不传 `min_hold_qty`);重判会因 T→T+1 可用份额变化(部分成交/他人申赎/产品参数改)得出与受理承诺不一致的结论(擅自扩大客户指令)。**T-8 关键裁定**:引擎时机(R-7)的实现部分在 T-7 已完成,T-8 补的是**守护与验证**(AST 守护唯一调用点 / 受理不触引擎 / 确认链路真引擎正证+反证);⚠️ **T-8 不动去重口径** —— `amount_view` 三处消费方原样不动(属 T-11);`convert_fund` 的阶段 1.5 调用点随 T-9 删函数一并清除(只摘调用会让 v1.0 过渡函数「扣份额但不出预警单」,风控缺失比时机错更危险)。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。已就绪:`fetch_nav.py` / `06-seed-nav.sql`(60 个真实净值日)/ `gen_trade_calendar.py` / `10-seed-trade-calendar.sql`(503 交易日)。 +- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11**(10 项真实业务拍板)· PRD **v1.1** + 架构 **v2.1** 已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做**(`docs/项目框架设计/开发计划-基金转换交易.md`,797 行:T-0~T-17 按架构 §15 重排 + §1.4 代码事实核对表 F-1~F-25 + §1.5 实现级裁定 R-1~R-15 + §5 十六条回归面 + §6 验收 31 条 + FR-C29/C30 全映射),**经三轮独立审核闭环(第一轮挑毛病 2 阻断+5 重要+3 可选 / 第二轮验证型 12 项零残留 / 第三轮白纸重审 C1~C5+O1~O4 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**核心认知:不新增冻结列,在途占用由受理单推导;紧池 80% 病根在 T+1 串行确认下自动消失。** 下一步:**第 5 步 todo 开发已收官(2026-09-12,T-1~T-17 全部完成 + 三项开口闭环【PRD §2.5.3 修订 / truncate 已接入 / R-12 定稿】,**849 passed / 8 skipped** 零失败;真库 verify 套件 **9/9 退出码 0**:accept 43 / confirm 103 / engine 39 / api 89 / compensate 56 / apply 30 / lots 20 / seed 全 PASS / tools 14。T-15 = D28 部分成交专项(终态单幂等 skipped 口径 + 防御纵深三道防线实证 + Barrier 窄窗争批);T-16 = D29 资金流中转(core_cash_flow 全仓唯一写入点,out/redeem + in/subscribe 各 1 条 remark 带 gid 同事务,5 处清理段 FK 坑修复);T-17 = D30 A/C 互转(share_class 非空且不同才查 allow_ac_convert 开关,任一端=1 两向放行,联网核实 = 摩根 2025-11「开通」公告;口径裁定:NULL 不参与判定、同类走一般规则,已追认定稿);**第 6 步集成测试已通过(2026-09-12 · 零代码改动:按 SOP 重灌双库 → 全量 849 passed / 8 skipped 零失败 → CONVERT_STRESS 7/7(T-15 争批用例加入)→ 真库 9/9 退出码 0 → 残留检查 + 收尾重灌恢复干净演示态;验收 31 紧池重测 100%、验收 18 性能端到端 P95 94.8ms < 2s)——AIcoding 六步全流程收官**;**README 已同步更新(2026-09-12:最新更新章节 + 前端已留接口契约)+ 分支已推送远程(用户授权,以 `git ls-remote` 为准)**)**。**T-7 关键裁定:强制全转属受理段决策** —— 受理由 `plan_lots` 判定并把 `qty` 收敛为实际全转量 + 受理单 `remark='full_transfer'`,确认段**只继承不重判**(`plan_lots` 不传 `min_hold_qty`);重判会因 T→T+1 可用份额变化(部分成交/他人申赎/产品参数改)得出与受理承诺不一致的结论(擅自扩大客户指令)。**T-8 关键裁定**:引擎时机(R-7)的实现部分在 T-7 已完成,T-8 补的是**守护与验证**(AST 守护唯一调用点 / 受理不触引擎 / 确认链路真引擎正证+反证);⚠️ **T-8 不动去重口径** —— `amount_view` 三处消费方原样不动(属 T-11);`convert_fund` 的阶段 1.5 调用点随 T-9 删函数一并清除(只摘调用会让 v1.0 过渡函数「扣份额但不出预警单」,风控缺失比时机错更危险)。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。已就绪:`fetch_nav.py` / `06-seed-nav.sql`(60 个真实净值日)/ `gen_trade_calendar.py` / `10-seed-trade-calendar.sql`(503 交易日)。 **仓库地图:** | 路径 | 状态 | 说明 |