项目

一般

简介

0002-Sprint2各阶段验收标准 » 历史记录 » 版本 1

Huarui Lin, 2026-04-15 21:19

1 1 Huarui Lin
# 0002-Sprint2各阶段验收标准
2
3
基于本次 Sprint 2 规划会议形成的 17 项确认项(CONF)与 6 项待办项(TODO),以下为严格对齐会议决策后的 S2-01 至 S2-05 验收标准更新全景表:
4
5
| 周次 | Story ID | Story 描述 | 规约硬性映射 | 验收标准(S2 会议纪要对齐版) | 工时 |
6
|:---:|:---|:---|:---|:---|:---:|
7
| **W2** | **S2-01** | **配置扩展与 DuckDB 粗筛降维**<br>在 `config.yaml` 新增数据源路径配置;实现 DuckDB 读取 CSV、显式列投影、周频聚合、白名单 JOIN,输出精简 Arrow。 | 规约 1.2;章程 R-5;FW-1/FW-2;CONF-03/06 | ① `config.yaml` 新增 `data.raw_paths`(字典结构)与 `duckdb.memory_limit`(默认 `"40GB"`)节点;<br>② DuckDB SQL **绝对禁止** `SELECT *`,对 `fund_basic_info` 必须硬编码 `SELECT fund_id, fund_name, fund_type, create_date`,对净值表仅取核心 3 列;<br>③ Arrow Schema 包含上述 4 列 + 净值 3 列(`fund_type` 仅作临时审计流转,**严禁带入最终落盘**);<br>④ **S1 遗留核销**:首个 PR 必须物理删除 S1 阶段的占位 Mock 测试代码,CI 全绿;<br>⑤ 单测:Mock 小 CSV 验证列裁剪与 JOIN 正确性。 | 2天 |
8
| **W2** | **S2-02** | **Polars 时序状态机(核心攻坚)**<br>接收全量 Arrow,实现 ffill、>4周缺失截断并打 `segment_id`、建仓期硬删、异常值处理。 | 规约 1.2;CR-001;全量 Arrow 破局方案;CONF-07/08 | ① `segment_id` 截断处严格递增,同基金内从 0 开始;<br>② 建仓期(12周)剔除**严格锚定且仅作用于 `segment_id == 0`**,即使 `segment_0` 被完全物理抹除,后续段仍予保留;<br>③ `cumulative_net_value ≤ 0` 的行被剔除;<br>④ 异常值(单周涨跌幅绝对值 >50%)置 NULL,判定基准**必须基于“本周原始有值且上周原始有值”的真实相邻周**,`ffill` 填充值不参与判定;<br>⑤ **单测强卡控**:必须覆盖“`segment_0` 被建仓期完全吞噬后 `segment_1` 仍保留”及“长缺失 ffill 恢复首周免于 >50% 误杀”场景。 | 3天 |
9
| **W3** | **S2-03** | **存活期过滤与按年分区落盘**<br>统计各基金有效周数,剔除 <52 周,Polars 内按年切片写 Parquet,创建 DuckDB VIEW。 | 规约 1.2/1.3;FW-4/FW-5;CONF-09/10/11/14 | ① 存活期计算 = 该基金所有段有效周数之和,< 52 周整体剔除;<br>② `data/processed/` 下产出 `net_value_YYYY.parquet`(覆盖写入,不追加),显式指定 `row_group_size=100000`;<br>③ **落盘 Schema 绝对锁定**:仅含 4 列 `fund_id`(String), `net_value_date`(Date), `cumulative_net_value`(Float64), `segment_id`(UInt32),临时列 `fund_type` 落盘前必须被显式 `select` 丢弃;<br>④ `cumulative_net_value` 全链路强制映射为 `Float64`,**严禁使用 Decimal**;<br>⑤ `create_duckdb_view()` 严禁依赖持久化状态,必须动态扫描年份文件拼接生成 `v_net_value_processed`。 | 2天 |
10
| **W3** | **S2-04** | **数据血缘、审计日志与内存压测**<br>计算处理后 Hash,生成结构化审计 JSON,在实体机执行全量压测并记录内存峰值。 | 章程 M2 Done 标准;规约 7.3;CONF-04/05/12/13/16/17 | ① 落盘后即刻按年份文件逐个计算 SHA-256,产出 `data/metadata/processed_hash.json`;<br>② 产出 `data/metadata/data_audit.json`,**严格符合 5 大根节点 Schema**,拒绝任何自定义;`whitelist_retention_rate` 分母必须取原始 CSV 物理总行数(若为 0 返回 0.0),交付 `calc_rate` 工具函数(**禁止悬空代码**);<br>③ **压测环境**:必须在 64GB 实体机**裸跑**(不施加 cgroup 限制);压测日志需包含 DuckDB/Arrow 转换/Polars 状态机**三个维度的 `peak_memory_gb`**,且总峰值 ≤ 40GB;<br>④ **R-6 风险应对**:若真实触发 `retention_rate < 15%`,M2 标记“带风险通过”,必须在 Redmine 建立 High 级别 Bug 单拉起排查。 | 2天 |
11
| **W3** | **S2-05** | **Gitea `/docs` 数据契约文档与 Redmine 验收**<br>编写 `data_contract.md` 沉淀为技术真相源,在 Redmine 录入 M2 验收 CheckList。 | 架构基线 3 (双轨制);章程 M2;CONF-02/15 | ① `docs/data_contract.md` 沉淀完整 Parquet 4 列 Schema 定义、审计 JSON Schema 定义及 Float64 选型依据;<br>② 产出 ADR `002-s2-full-arrow-exception.md`,固化 FW-3 豁免边界、内存预估及下游禁用声明;<br>③ **Redmine 强卡控录入**:S2-01至S2-05任务卡片的自定义字段,必须按上述更新后的验收标准(含显式投影、段保留逻辑、压测三维度等)逐条填入;<br>④ CI 软预警检查通过(`src/` 变更已同步 `docs/` 变更)。 | 1天 |