文档:T-12 回写 + 全仓进度一致性(开发计划 DoD 全勾 + 执行记录)

- 开发计划 v2.0 T-12 节:DoD 4/4 全勾 + 执行记录(三改动面 / 联网核实留痕 /
  confirm_one 留痕修复 / 真库 56/56 / 突变 4 组 / rebuild_alerts 路径勘误)
- 交接文档 v4.2(T-12 完成块 + 基线 849,.gitignore 内不入库)
- TODO.md / MEMORY.md / AGENTS.md:T-1~T-12 ✅ / T-13~T-17 ⬜,基线 849
- 2026-09-12.md 追加 T-12 执行记录(含用户铁律:外部真实业务事实必须联网核实)
This commit is contained in:
2026-09-12 10:55:01 +08:00
parent 03feacf173
commit 9ad8a90de1
5 changed files with 131 additions and 11 deletions
+3 -2
View File
@@ -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-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 订正)。
- **(二)下一线 · 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-12 完成(全量 pytest 849 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、T-12 重写 verify_convert_compensate 56/56,退出码均 0),下一步 T-13(全量回归 + 并发/性能补录 + convert_fund 退役)**。撤单范围:PRD §5.5 原表述与实现(仅 `accepted`)不矛盾、无需回填(第三轮 C1 订正)。
### 基金转换线待办(推荐顺序)
@@ -38,7 +38,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 用例变红 → 还原)
- [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/风险已加)
- [x] **T-12 补偿 + SLA 清理切 T+1 链路 ✅(2026-09-12)**:① `cleanup_pending_convert.py` **整体重写**(扫描对象迁 Core:`list_inflight_before` 扫 `accepted/nav_pending` 且 `requested_at` 严格早于 cutoff → 条件 UPDATE 置 `expired`(S2 不硬删、天然幂等不加锁);SLA 边界 = 当前业务日上推 `convert_confirm_sla_days` 个交易日 00:00(`previous_biz_day` 链式,与 `_window_start` 同口径,日历缺失降级自然日并告警);`--days`/`--dry-run`;**不动镜像**(T-4 契约));② `compensate_convert` **从 v1.0 Deprecated 组救回在役**(详情侧 = Core 三件套前置校验(流水 ≥2 → `confirmed` → 明细非空,任一不满足 `missing` 零写入),补写与确认段第⑧步同口径 `sync_mirror` + `confirmed` 审计 `phase='confirm-compensate'`);③ `convert_request_repository` +`list_inflight_before`。**联网核实**(用户铁律):基金转换「无效申请」真实口径(多家基金公司业务规则:TA T+1 确认、无效资金退回 → `rejected` 映射成立)+ A 股连续休市最长 = 2020 春节 10 自然日(上交所通知,`_MAX_SCAN_DAYS=256` 依据成立)。**⚠️ 真库脚本暴露并修复**:`confirm_one` 第⑦步引擎异常只 log 不留痕(全仓唯一不落痕路径)→ except 补写 `decision='engine_error'` 审计 + `engine_error` 标志贯穿(D17 不阻断保留;test_convert_confirm 断言翻转 is True + 补审计断言)。**验证**:全量 **849 passed / 10 skipped**(846+3 零回归);真库 `verify_convert_compensate.py` **整体重写 T+1 链路 56/56 残留 0**(含幂等重跑;真库修正 1 条口径:`confirmed` 审计真链路恰 2 条 = 确认段 + 补偿各 1);**突变 4 组全被抓还原**(cleanup 窗口反转 5 红 / 前置守卫删除 1 红 / 真库 expired→cancelled 2 红 / 真库 nav_stale=True 1 红)。**勘误**:开发计划原写 `scripts/agent/rebuild_alerts.py` 实际在 `scripts/demo/`(零改动)
- [ ] T-13 ~ T-17(全量回归 + 并发/性能补录 + convert_fund 退役 / 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「提升为公开函数」是两回事。