# 07 — 完整校验 CSV 并固化逐行明细

**What to build:** Worker 可以领取待处理批量任务，下载完整 CSV 后先完成全部文件结构和行数校验，再批量解析资产并一次性持久化所有数据行。文件级错误使任务失败且不产生订单；文件有效时每个原始数据行都有稳定行号、解析结果、失败信息和幂等键，可供后续恢复处理。

**Blocked by:**

- `.scratch/ur36-bulk-package-purchase/issues/01-batch-unique-asset-resolution.md` — 01 — 统一资产标识的批量唯一解析
- `.scratch/ur36-bulk-package-purchase/issues/03-real-dependency-integration-harness.md` — 03 — 建立批量任务真实依赖的集成测试 Harness
- `.scratch/ur36-bulk-package-purchase/issues/06-idempotent-bulk-purchase-creation.md` — 06 — 幂等创建批量订购任务

**Status:** ready-for-agent

**架构通道:** 主通道为 Application，辅助通道为 Infrastructure。

**完整业务边界:** 本票收口任务领取、CSV 文件级校验、公共资产批量解析、文件内判重和明细初始化。明确不执行套餐订购、不扣钱包、不创建订单、不支持 Excel 或单行重试。

- [ ] Worker 仅领取待处理或租约已过期的处理中任务，终态任务不会重新解析；源对象下载失败按安全任务错误进入失败终态。
- [ ] CSV 仅接受 UTF-8 或 UTF-8 BOM、LF 或 CRLF、唯一单列表头 `资产标识`；空文件、只有表头、非法编码、引号语法错误、缺列、多列、重复或未知列均为文件级错误。
- [ ] 实际文件不得超过 10MB，数据行不得超过 1000；Worker 在任何订单写入前读完整文件并确认第 1001 行不存在。
- [ ] 文件有效后每个数据行都持久化并保留原始行号和原始标识；空值、控制字符、未命中及多命中作为行级失败计数，不被省略。
- [ ] 文件内重复在公共解析成功后按 `资产类型 + 资产ID` 判断；首次出现行继续处理，后续行失败并指出首次 CSV 行号，不同标识指向同一资产也能识别。
- [ ] 明细具有 `(任务, 行号)` 和稳定 `bulk_purchase:{task_id}:{row_no}` 幂等约束，并保存公共行处理状态、租约和安全失败码。
- [ ] 文件验证与明细初始化完成后，Worker 重启直接读取已有明细，不重新生成行号或幂等键；汇总从明细事实聚合。
- [ ] 真实 S3 和 PostgreSQL 测试覆盖编码、换行、表头、10MB、1000/1001 行、伪装 Excel、空字段、控制字符、资产歧义和跨标识重复。

