文档:T-11 回写 + 全仓进度一致性(开发计划 DoD 全勾 + 执行记录 / 交接文档 v4.1 / TODO / MEMORY / AGENTS / 当日日志)
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
- 技术选型 / JWT:`docs/项目框架设计/技术选型和版本/`
|
||||
- Core 模拟底座:`docs/项目框架设计/Core模拟底座/`
|
||||
- 业务记忆分层:`docs/业务记忆管理/业务记忆管理手册.md`
|
||||
- **基金转换线(第 5 步 todo 开发进行中 · T+1 受理/确认分离模型)**:**T-1 ~ T-10 ✅ / T-11 ~ T-17 ⬜**(当前基线 **844 passed / 10 skipped** 实测;真库 T-6 `verify_convert_accept.py` **37/37**、T-7 `verify_convert_confirm.py` **83/83**、T-8 `verify_convert_engine.py` **39/39**、T-9/T-10 `verify_convert_api.py` **89/89**,退出码均 0;下一步 **T-11** = 汇总去重);开工入口 **`交接文档.md` §B**(§B.11 下一条立项指引 = 最新状态)· `docs/PRD/PRD-基金转换交易.md`(**v1.1**)· `docs/项目框架设计/架构设计-基金转换交易.md`(**v2.1**)· `docs/项目框架设计/开发计划-基金转换交易.md`(**v2.0** · T-1~T-17 逐任务改法 + DoD)
|
||||
- **基金转换线(第 5 步 todo 开发进行中 · T+1 受理/确认分离模型)**:**T-1 ~ T-11 ✅ / T-12 ~ T-17 ⬜**(当前基线 **846 passed / 10 skipped** 实测;真库 T-6 `verify_convert_accept.py` **37/37**、T-7 `verify_convert_confirm.py` **83/83**、T-8 `verify_convert_engine.py` **39/39**、T-9/T-10 `verify_convert_api.py` **89/89**、T-11 复跑 `verify_convert_tools.py` **14/14**,退出码均 0;下一步 **T-12** = 补偿脚本改写);开工入口 **`交接文档.md` §B**(§B.11 下一条立项指引 = 最新状态)· `docs/PRD/PRD-基金转换交易.md`(**v1.1**)· `docs/项目框架设计/架构设计-基金转换交易.md`(**v2.1**)· `docs/项目框架设计/开发计划-基金转换交易.md`(**v2.0** · T-1~T-17 逐任务改法 + DoD)
|
||||
- **架构改进线(✅ 2026-09-10 已结项,无待办)**:开工入口 **`交接文档.md` §C**
|
||||
- **风控模块主线**:**`交接文档.md` §A**
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# 2026-09-12 工作日志
|
||||
|
||||
> 本日:基金转换线(T+1 受理/确认分离模型)**第 5 步 T-11 完成** —— core_tools 汇总去重 + 持仓过滤(确认段场景补用例,生产代码零改动)。
|
||||
|
||||
---
|
||||
|
||||
## 一、接手与状态核对
|
||||
|
||||
读入:项目根 `交接文档.md`(v4.0,§0 + §B.11)→ 开发计划 v2.0 §1.4 / §1.5 / §5 / T-11 节 →
|
||||
现状代码(`core_tools.py` / `rules.py` / `core_ro.py`)→ 既有测试(`test_core_tools.py` / `test_concentration_c4.py` / `test_convert_confirm.py`)。
|
||||
|
||||
**基线复核**:全量 `pytest -q`(系统 Python 3.13.14)沿用户上次实测 **844 passed / 10 skipped**(当日收尾实测 846,见下)。
|
||||
|
||||
## 二、T-11 · core_tools 汇总去重 + 持仓过滤 ✅
|
||||
|
||||
### 任务定位(与 v0.x T-11 的区别)
|
||||
|
||||
开发计划 v2.0 T-11 的改法两条都是「已实现 → 确认不回归 → 补用例」:
|
||||
|
||||
- 口径三处同调(F-10)与 `list_holdings` 的 SQL 层 `qty > 0` 过滤**均已就位**
|
||||
(v0.x T-11 产物:`_amount_view` 提升公开 + SQL 去重 R-d + 归零行过滤);
|
||||
- 本轮实质增量 = **把既有「直接插 SQL 模拟流水」的口径用例升级为 T+1 真实链路场景**
|
||||
(回归面 R-回归 8「保留 + 补用例」/ R-回归 13「保留断言 + 补确认段场景」)——
|
||||
T+1 模型下流水与持仓**只在确认段产生**(受理段零写入),直接插 SQL 的既有用例覆盖不了这一点。
|
||||
|
||||
### 落地(仅 `tests/test_core_tools.py` +2,生产代码零改动)
|
||||
|
||||
新增 `t1_env` fixture(`seed_suitability_matrix` + 最小受理/确认种子:C3 客户、转出 R2 债基
|
||||
1 批 30000 份 + 持仓 30000、转入 R4 股基、两端 T 日净值 1.3604/1.9194、5 档费率、60 天日历)
|
||||
+ `_quiet_th()`(全阈值推高让引擎静默,不依赖 settings 与 conftest autouse 隔离):
|
||||
|
||||
1. `test_confirm_then_sum_amount_counts_once`(验收 11 · 确认段场景):受理全转 30000 →
|
||||
`confirm_one`(T+1=2026-09-07)落两条同 gid 流水 → 同窗口插一笔无组普通赎回 100000 →
|
||||
`query_recent_trades`:`sum_amount` = 40812.00 + 100000 = **140812.00**(转入端不计)、
|
||||
`total_count` = 3(明细全量)、`sum_trades_on_date(T+1)` 跨口径一致。
|
||||
2. `test_confirm_full_transfer_holding_zero_row_excluded`(F-12 / R-回归 13 · 确认段场景):
|
||||
先直查 SQL 证明转出端 `core_holding.qty=0` 行**仍在库**(台账留痕,D 决策),
|
||||
再断言 `list_holdings` / `query_holdings` 只剩转入端、qty 与 `res["in_qty"]` 逐字节一致。
|
||||
|
||||
既有 3 条口径级用例与 `test_concentration_profile_filters_zero_qty`(集中度读取方)**保留不动**。
|
||||
|
||||
### 执行期裁定 2 条(留痕)
|
||||
|
||||
1. **转出端流水 `amount` = 费前转出金额**(40812.00 = 30000×1.3604,与 PRD §5.3.2 示例
|
||||
68020.00 同语义;赎回费 204.06 单列 `redeem_fee` 字段)—— 初版锚点误按「费后 40607.94」
|
||||
断言,真跑第一轮即抓出(`assert '40812.00' == '40607.94'`),已在用例注释钉死口径。
|
||||
2. **`t1_env` 必须调 `_ddl.seed_suitability_matrix`**:C×R 矩阵是 `check_suitability` 的 L0
|
||||
权威,裸 `create_sqlite_engine()` 缺矩阵 → 受理段全量 `forbidden`(`SUIT_RISK_MISMATCH`),
|
||||
症状是 `confirm_one` 返回 `missing`(受理单根本没落)。与 conftest `sqlite_engine` fixture
|
||||
同源(自检第 13 问:同一种子不得有两份实现)。
|
||||
|
||||
### 验证
|
||||
|
||||
- `pytest tests/test_core_tools.py` **5/5** → 全量 **846 passed / 10 skipped**(基线 844 + 2,零回归);
|
||||
- **突变 2 组防假绿**(均精准命中后还原,`git status` 仅测试文件改动、无 MUTATION 残留):
|
||||
① 去掉 `core_ro.list_holdings` 的 `AND h.qty > 0` → **精准 3 红**
|
||||
(新确认段用例 + 既有 `test_query_holdings_excludes_zero_qty` + `test_concentration_profile_filters_zero_qty` 的跨口径一致性断言);
|
||||
② `core_tools.query_recent_trades` 绕开 `amount_view` 直加全量 → **精准 3 红**
|
||||
(新确认段用例 + 既有不翻倍用例 + 跨口径一致性断言);
|
||||
- 真库 `verify_convert_tools.py` 复跑 **14/14、退出码 0、零残留**(v0.x 口径真库证据零回归)。
|
||||
|
||||
## 三、文档回写
|
||||
|
||||
开发计划 v2.0 T-11 节(DoD 全勾 + 执行记录)· `交接文档.md`(v4.0 → **v4.1**:头部版本块 /
|
||||
§0 导航表 / §B.11 状态块 + T-11 完成条目)· `docs/memory/TODO.md`(进度行 + T-11 勾选)·
|
||||
`docs/memory/MEMORY.md`(3 处进度)· `AGENTS.md`(进度行)· 本日志。
|
||||
|
||||
## 四、下一步
|
||||
|
||||
**T-12 补偿脚本改写**(R-14):`cleanup_pending_convert.py` 扫描对象迁 `core_convert_request`
|
||||
(accepted/nav_pending 超 2 交易日 → expired)+ `rebuild_alerts.py` 凭 Core 侧数据补写。
|
||||
入口:开发计划 T-12 节。
|
||||
@@ -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 开发进行中(T-1~T-10 ✅,**844 passed / 10 skipped** 零失败;T-6 真库 verify **37/37**、T-7 真库 verify **83/83**、T-8 真库 verify **39/39**、T-9/T-10 真库 verify_convert_api **89/89**,退出码均 0;下一步 T-11 汇总去重)**。**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 开发进行中(T-1~T-11 ✅,**846 passed / 10 skipped** 零失败;T-6 真库 verify **37/37**、T-7 真库 verify **83/83**、T-8 真库 verify **39/39**、T-9/T-10 真库 verify_convert_api **89/89**、T-11 复跑 verify_convert_tools **14/14**,退出码均 0;下一步 T-12 补偿脚本改写)**。**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 交易日)。
|
||||
**仓库地图:**
|
||||
|
||||
| 路径 | 状态 | 说明 |
|
||||
@@ -200,8 +200,8 @@ RBAC 联调账号:scripts/dev/rbac-seed-reference.md
|
||||
2. 改动属于 api / service / tool / repository 哪一层?
|
||||
3. 是否需 customer_id 归属与 JWT RBAC?
|
||||
4. Core 是模拟库只读还是 agent 库读写?
|
||||
5. 如何验证?(`python -m pytest` 全量(当前 **844 passed / 10 skipped**,风控基线 510 / v0.x convert 完结 739)· uvicorn 启动 + /health · SQL / sync 脚本 · 对照 REQUIREMENTS 验收列)
|
||||
6. **当前有哪两条并行线?**(① 风控/架构改进线:**已结项**(510 基线绿、§7.2 七项冒烟 7/7 PASS、`037ce7e` 已核实早已推送);② **基金转换线**:v0.x 实时模型已结项(739 绿,**已被 T+1 模型取代**);**下一线 T+1 受理/确认分离模型进行中(2026-09-11)**:PRD v1.1 / 架构 v2.1 / 开发计划 v2.0 重写完毕并经独立审查收敛,**已定稿**(2026-09-11 用户批准),第 5 步 todo 开发进行中(T-1~T-17;**当前进度 T-1~T-10 ✅,844 绿**))——动代码前先确认自己属于哪条线,别混淆前置条件。
|
||||
5. 如何验证?(`python -m pytest` 全量(当前 **846 passed / 10 skipped**,风控基线 510 / v0.x convert 完结 739)· uvicorn 启动 + /health · SQL / sync 脚本 · 对照 REQUIREMENTS 验收列)
|
||||
6. **当前有哪两条并行线?**(① 风控/架构改进线:**已结项**(510 基线绿、§7.2 七项冒烟 7/7 PASS、`037ce7e` 已核实早已推送);② **基金转换线**:v0.x 实时模型已结项(739 绿,**已被 T+1 模型取代**);**下一线 T+1 受理/确认分离模型进行中(2026-09-11)**:PRD v1.1 / 架构 v2.1 / 开发计划 v2.0 重写完毕并经独立审查收敛,**已定稿**(2026-09-11 用户批准),第 5 步 todo 开发进行中(T-1~T-17;**当前进度 T-1~T-11 ✅,846 绿**))——动代码前先确认自己属于哪条线,别混淆前置条件。
|
||||
7. **远程分支到底还在不在?**(**在**。`git ls-remote --heads origin` 实测 `refs/heads/risk-control-agent` = `fffb78a`。⚠️ **判断远程存亡只能用 `git ls-remote`** —— 2026-09-10 **同日误报两次**,勿再踩。)
|
||||
**本仓特有异常(2026-09-10 深挖确认,别误判为 stale ref)**:`.git/refs/remotes/**` **写入不落盘** ——
|
||||
`git update-ref refs/remotes/origin/X <sha>` 返回 0,但松散引用消失,**且整个 `refs/remotes/origin/` 目录被删**
|
||||
|
||||
+3
-2
@@ -9,7 +9,7 @@
|
||||
|
||||
**⚡ 并行新线 · 基金转换(convert)**—— **两条子线**:
|
||||
- **(一)v0.x 两阶段实时模型(已结项 2026-09-10)**:PRD **v0.9.3** + 架构 **v1.0.1** + 开发计划 **v1.0**,**T-0 ~ T-13 全部完成**(第 5 步 + 第 6 步闭环,**736 passed / 10 skipped**;7 个 convert 真库脚本复跑零回归;压测修复 2 处并发缺陷 + 死锁重试后补 `43cf2a1` 最终 **739 passed / 10 skipped**)。**注:该模型已被下一线取代(按下述),其设计文档作废,代码仍保留作过渡基线**。
|
||||
- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11** · PRD **v1.1** + 架构 **v2.1** 均已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做(`docs/项目框架设计/开发计划-基金转换交易.md`,T-1~T-17 按架构 §15 重排 + 代码事实 F-1~F-25 + 裁定 R-1~R-15 + 16 条回归面 + 验收 31 条 + FR-C29/C30 全映射),经三轮独立审核闭环(挑毛病 / 验证型 / 白纸重审 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**第 5 步 todo 开发已开工(2026-09-11):T-1 ~ T-10 完成(全量 pytest 844 passed / 10 skipped 零失败;T-6 真库 verify 37/37、T-7 真库 verify 83/83、T-8 真库 verify 39/39、T-9/T-10 真库 verify_convert_api 89/89,退出码均 0),下一步 T-11(汇总去重)**。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。
|
||||
- **(二)下一线 · T+1 受理/确认分离模型(进行中 · 2026-09-11)**:入口 **交接文档.md §B.11** · PRD **v1.1** + 架构 **v2.1** 均已整体重写并经独立 AI 联网审查通过(0 阻断级),**已定稿**(2026-09-11 用户批准);**第 4 步开发计划 v2.0 已整体重做(`docs/项目框架设计/开发计划-基金转换交易.md`,T-1~T-17 按架构 §15 重排 + 代码事实 F-1~F-25 + 裁定 R-1~R-15 + 16 条回归面 + 验收 31 条 + FR-C29/C30 全映射),经三轮独立审核闭环(挑毛病 / 验证型 / 白纸重审 + 验证型复核 22/22 落位),已定稿(2026-09-11 用户批准)**。**第 5 步 todo 开发已开工(2026-09-11):T-1 ~ T-11 完成(全量 pytest 846 passed / 10 skipped 零失败;T-6 真库 verify 37/37、T-7 真库 verify 83/83、T-8 真库 verify 39/39、T-9/T-10 真库 verify_convert_api 89/89、T-11 复跑 verify_convert_tools 14/14,退出码均 0),下一步 T-12(补偿脚本改写)**。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。
|
||||
|
||||
### 基金转换线待办(推荐顺序)
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
- [x] **T-8 引擎时机收口 ✅(2026-09-11,提交 `57f16a5`)**:**R-7 的实现部分在 T-7 已完成**(`engine_call.run_convert_engine` 是引擎唯一出口、位于确认事务 commit 之后;`accept_convert` 自实现起不含引擎调用)。本轮补**守护与端到端验证**:① `test_process_convert_event_has_single_call_site` —— 用 **AST** 统计 `app/` 下 `process_convert_event(` 的 Call 节点**恰 1 处**且宿主为 `run_convert_engine`(字符串匹配会被 `engine_call.py` 说明段误判);② 受理无副作用用例补「不触引擎」断言(受理后 `risk_alert` 0 行、无 `pass`/`engine_error` 审计,验收 29 前半);③ `test_real_engine_on_confirm_dedupes_daily_total` —— 确认链路接**真引擎**(不注入 hook)的正证 + 反证(阈值夹逼 → RISK-002 不命中 / 阈值下调 → 命中),并断言一张单 + `payload.events` 两条 + 去重不删行(验收 5/6/7)。两条新用例**均做突变验证**(加第二处调用 / 禁用引擎调用 → 变红 → 还原)。真库 `verify_convert_engine.py` **整体切换 T+1 链路**(此前走 v1.0 `convert_fund`):受理 → 确认,新增 A0 组「受理不触引擎」,折算期望改用 T 日净值,**真库 39/39 一致**。**订正**:原记「T-8 剩余工作仅为 `rules.amount_view`」有误 —— F-10 明确 T-8 **不动**去重口径(属 T-11 范围),T-8 剩余的是**验证面**。
|
||||
- [x] **T-9 API |网关分派 ✅(2026-09-11)**:三接口路径以 PRD 为准(裁定 11/12)——`convert_admin.py` 撤单/确认批处理/查询 + `simulate.py` convert 分支 **202 + 受理回执**(两类 202)+ `trade_gateway` 分派改调 `accept_convert`(`SUPPORTED_TRADE_TYPES` 维持 2 类型)+ **redeem 份额申报**(D26/R-6 `_redeem_quote = qty × D 净值 − 赎回费`)+ 错误码 `CANCEL_NOT_ALLOWED`/`CONCURRENT_CONFLICT`(409)。**验证**:端到端 test_convert_integration 重写 T+1 两段链路 13 passed;全量 **834 passed / 10 skipped**;真库 `verify_convert_api.py` HTTP 全链路 **88/88**;3 组突变验证全命中;修 2 处口径缺陷(`out_nav` 反推漂移 → 直读明细、幂等字段面对齐)。**执行缺口**:`convert_fund` 退役并入 **T-13**
|
||||
- [x] **T-10 普通申赎批次维护 + T+2 校验 + rebuild_lots ✅(2026-09-11)**:`trade_gateway` 主流程改 —— `_redeem_quote` 走 `available_qty_with_inflight` **硬校验**(R-3,申报超可赎抛 `InsufficientShares` 不静默裁剪);`_maintain_lots` redeem 三重裁剪(T+2 过滤 → D8 补建 → 在途占用 → 哨兵 FIFO 扣减),subscribe 落新批次;`core_ro.list_share_lots`/`share_lot_repository.select_for_convert` 加 `available_from` **T+2 半开区间过滤**(R-4,日历缺行降级不过滤同口径);`gateway_repository` 扣批次哨兵 `remain_qty >= :q`(防超扣)。**验证**:`test_share_lot` +10(半开区间双向/区分度/在途拦截与释放/哨兵回滚/转换后不超扣)+ `test_trade_gateway` +1(金额公式 995.00)→ 全量 **844 passed / 10 skipped**(834+11 零回归);真库 `verify_convert_api.py` **89/89**(H 节提前 + H2 在途占用拦截断言);`rebuild_lots.py --dry-run` 58 持仓 0 补建 0 写入;6 项 DoD 全闭环 + 突防验证(移除透传 → t2 用例变红 → 还原)
|
||||
- [ ] T-11 ~ T-17(汇总去重 / 补偿改写 / 全量回归 / D27 产品级舍入 / D28 巨额赎回 / D29 资金流中转 / D30 A/C 互转)。**注(2026-09-11 用户裁定)**:`convert_fund` 退役并入 **T-13**(T-13 目标/改法 6/DoD/风险已加)
|
||||
- [x] **T-11 core_tools 汇总去重 + 持仓过滤 ✅(2026-09-12,生产代码零改动)**:口径三处同调(F-10)与 `list_holdings` 的 `qty > 0` SQL 过滤均已就位(v0.x T-11 产物),本轮增量 = 把口径用例升级为 **T+1 真实链路场景**(R-回归 8「保留 + 补用例」/ R-回归 13「补确认段场景」—— T+1 下流水与持仓只在确认段产生):`tests/test_core_tools.py` +2 —— ① `test_confirm_then_sum_amount_counts_once`(受理→`confirm_one` 落两条同 gid 流水后 `sum_amount` = 转出端 40812.00 + 无组普通 100000 = 140812.00,明细仍 3 条全量,`sum_trades_on_date(T+1)` 跨口径一致)② `test_confirm_full_transfer_holding_zero_row_excluded`(先证归零行仍在库(台账留痕),再断言 `list_holdings`/`query_holdings` 只剩转入端)。**验证**:全量 **846 passed / 10 skipped**(844+2 零回归);突变 2 组均精准 3 红(去 `qty>0` / 绕开 `amount_view`)已还原;真库 `verify_convert_tools.py` 复跑 **14/14** 零残留。**执行期裁定 2 条**:① 转出端流水 `amount` = **费前**转出金额(与 PRD §5.3.2 的 68020.00 同语义,赎回费单列 `redeem_fee`)—— 初版锚点误按费后被真跑抓出;② `t1_env` 必须调 `seed_suitability_matrix`(缺 C×R 矩阵 → 受理全量 forbidden,与 conftest 同源)
|
||||
- [ ] T-12 ~ T-17(补偿改写 / 全量回归 / D27 产品级舍入 / D28 巨额赎回 / D29 资金流中转 / D30 A/C 互转)。**注(2026-09-11 用户裁定)**:`convert_fund` 退役并入 **T-13**(T-13 目标/改法 6/DoD/风险已加)
|
||||
|
||||
> **第 0~2 批结果(2026-09-10)**:基线 **510 passed** → 批 0 后 **516 passed / 3 skipped**(+3 T-0 用例 +3 T-0b 引擎用例)→ 批 1(T-1)后**仍 516 passed / 3 skipped**(只加表与种子,未加用例 → **零回归**);**T-1 数据层断言 8/8 PASS**(含新增断言 ⑧:费率档 ↔ `product_type` 匹配,越档即 FAIL)→ 批 2(T-2 + T-2b)后 **609 passed / 3 skipped**(**+93 纯函数用例**,零回归);T-2b 实算脚本 15/15 与 PRD §5.3 一致(退出码 0)。
|
||||
> ⚠️ **以下四条引用块均为 v0.x 两阶段实时线记录,其 T 编号与新线(T-1~T-17)无关、勿混**:新线 T-11 亦涉 `amount_view`,与 v0.x T-11「提升为公开函数」是两回事。
|
||||
|
||||
@@ -643,9 +643,14 @@
|
||||
**依赖**:T-8(口径三处同调链)
|
||||
|
||||
**DoD**:
|
||||
- [ ] convert 两流水场景:`sum_amount` 计一次(验收 11)
|
||||
- [ ] 全转归零:`list_holdings` 不含 qty=0 行
|
||||
- [ ] pytest 全量绿
|
||||
- [x] convert 两流水场景:`sum_amount` 计一次(验收 11)—— `test_confirm_then_sum_amount_counts_once`(**走真实链路**:受理 → `confirm_one` 落两条同 gid 流水后,`sum_amount` = 转出端 40812.00 + 无组普通 100000 = 140812.00;`total_count` 仍 3 = 明细全量;并以 `sum_trades_on_date(T+1)` 复验跨口径一致)
|
||||
- [x] 全转归零:`list_holdings` 不含 qty=0 行 —— `test_confirm_full_transfer_holding_zero_row_excluded`(**确认段场景**:先直查 SQL 证明归零行**仍在库里**(台账留痕,D 决策),再断言 `list_holdings` 只剩转入端且 qty 与 `res["in_qty"]` 逐字节一致,`query_holdings`(Tool 层)同口径;既有 `test_query_holdings_excludes_zero_qty`(口径级)与 `test_concentration_profile_filters_zero_qty`(集中度读取方)**保留不动**)
|
||||
- [x] pytest 全量绿 —— **846 passed / 10 skipped**(基线 844 + 新增 2,零回归)
|
||||
|
||||
**✅ T-11 完成(core_tools 汇总去重 + 持仓过滤 · 确认段场景补用例 · 2026-09-12)**:
|
||||
**生产代码零改动**(计划即判「风险低;仅补用例」)—— 口径三处同调(F-10:`rules.amount_view` ① RISK-002/005 ② `query_recent_trades.sum_amount` ③ `sum_trades_on_date` SQL 条件)与 `list_holdings` 的 SQL 层 `qty > 0` 过滤**均已就位**(v0.x T-11 产物 + F-9/F-10 实测),本轮增量 = **把既有「直接插 SQL 模拟流水」的口径用例升级为 T+1 真实链路场景**(R-回归 8「保留 + 补用例」/ R-回归 13「保留断言 + 补确认段场景」——T+1 模型下流水与持仓**只在确认段产生**,既有用例覆盖不了这一点)。**落地**:`tests/test_core_tools.py` +2(新增 `t1_env` fixture:`seed_suitability_matrix` + 最小受理/确认种子;`_quiet_th()` 全阈值推高让引擎静默,避免依赖 settings 与 conftest autouse 隔离)。
|
||||
**执行期裁定 2 条(留痕)**:① **转出端流水 `amount` = 费前转出金额**(40812.00 = 30000×1.3604,与 PRD §5.3.2 示例 68020.00 同语义;赎回费 204.06 单列 `redeem_fee` 字段)—— 初版锚点误按「费后 40607.94」断言被真跑抓出,已在用例注释钉死口径;② `t1_env` 必须调 `_ddl.seed_suitability_matrix`(C×R 矩阵是 `check_suitability` 的 L0 权威,裸 `create_sqlite_engine()` 缺矩阵 → 受理全量 forbidden)—— 与 conftest `sqlite_engine` fixture 同源(自检第 13 问)。
|
||||
**验证**:`pytest tests/test_core_tools.py` 5/5 → 全量 **846 passed / 10 skipped**(844+2 零回归);**突变 2 组防假绿**:① 去掉 `list_holdings` 的 `qty > 0` → **精准 3 红**(新确认段用例 + 既有归零行用例 + 集中度跨口径一致性断言);② `query_recent_trades` 绕开 `amount_view` 直加全量 → **精准 3 红**(新确认段用例 + 既有不翻倍用例 + 跨口径一致性断言)—— 均已还原,`git status` 仅测试文件改动、`grep MUTATION` 无残留;真库 `verify_convert_tools.py` 复跑 **14/14、退出码 0、零残留**(零回归佐证)。
|
||||
|
||||
**风险**:低;仅补用例
|
||||
**回滚点**:无代码改动风险
|
||||
|
||||
Reference in New Issue
Block a user