import re from pathlib import Path path = Path(r"x:\work\chajia\docs\查价系统-工程任务拆解-v1.1.md") text = path.read_text(encoding="utf-8") appendix_idx = text.find("## 附录 A") body_start = text.find("# 数据库系统") appendices = text[appendix_idx:] parts = re.split(r"(?=## (?:~~)?task-)", text[body_start:appendix_idx]) blocks: dict[str, str] = {} for part in parts: if not part.strip(): continue m = re.match(r"## (?:~~)?(task-[\w-]+)", part) if m: blocks[m.group(1)] = part.rstrip() + "\n" order = [ ("Phase 0 — 环境与底座", ["072", "073", "070", "071", "097", "030"]), ( "Phase 1 — 基础设施与缓存(W1)", ["096", "031", "032", "033", "034", "035", "035-ip", "036"], ), ("Phase 2 — 鉴权", ["001", "002", "003", "004", "005", "098"]), ("Phase 3 — 加价基础", ["040", "041", "044"]), ( "Phase 3 — 查价领域逻辑", ["010", "011", "012", "095", "111", "013", "019", "092", "109", "014"], ), ( "Phase 4 — API 层(里程碑:L1/L2 可通)", ["015", "016", "017", "042", "043", "018"], ), ( "Phase 5 — RPA(W2)", [ "020", "021", "022", "023", "024", "025", "026", "027", "028", "110", "029", "093", "099", "100", ], ), ( "Phase 6 — 预警 / 审计 / 管理 API", ["050", "051", "052", "053", "054", "055", "094", "105", "056", "057"], ), ("Phase 7 — 观测指标", ["101", "102"]), ( "Phase 8 — 前端基础与嵌入组件", ["060", "061", "062", "065", "066", "067", "068", "069", "106"], ), ( "Phase 8 — 管理端页面", ["063", "064", "079", "103", "104", "080"], ), ("已废止(v1.1 不实施)", ["075", "076", "077", "078"]), ( "Phase 9 — 测试与 CI(建议随模块并行,收尾全量回归)", [ "081", "082", "083", "084", "085", "086", "087", "112", "113", "114", "115", "116", "088", "089", "090", "117", "118", "091", ], ), ] body: list[str] = [] missing: list[str] = [] for title, tasks in order: body.append(f"# {title}\n\n") seq = " → ".join(f"task-{t}" for t in tasks) body.append(f"> 执行顺序:{seq}\n\n") for t in tasks: key = f"task-{t}" if key in blocks: body.append(blocks[key]) body.append("---\n\n") else: missing.append(key) if missing: raise SystemExit(f"Missing blocks: {missing}") new_header = """# 查价系统 工程任务拆解清单 v1.1 | 版本 | 日期 | 说明 | |------|------|------| | v1.0 | 2026-06-16 | 首版原子任务拆解 | | v1.1 | 2026-06-16 | 对照 Traceability Matrix 补齐;口径对齐 PRD v0.4 | | v1.1.1 | 2026-06-16 | **按推荐开发依赖顺序重排任务章节**(非 Task ID 数字序) | > **当前版本请使用本文件(v1.1.1 排序)。** v1.0 文件保留作历史对照。 > 配套文档:[查价系统-PRD.md](./查价系统-PRD.md) · [查价系统-技术设计.md](./查价系统-技术设计.md) · [查价系统-UI设计.md](./查价系统-UI设计.md) · [查价系统-Traceability-Matrix-v1.0.md](./查价系统-Traceability-Matrix-v1.0.md) > **完成本清单全部 Task(含「已废止」除外)= PRD v0.4 + 技术设计 v1.1 需求全覆盖。** --- ## 开发顺序总览(自上而下执行) | Phase | 名称 | Task 序列 | PRD 周次 | |-------|------|-----------|----------| | 0 | 环境与底座 | 072→073→070→071→097→030 | W1 | | 1 | 基础设施与缓存 | 096→031~036→035-ip | W1 | | 2 | 鉴权 | 001~005→098 | W1 | | 3 | 领域逻辑 | 040~044→010~014,092,095,109,111,019 | W1 | | 4 | API 层 | 015~017→042~043→018 | W1 里程碑 | | 5 | RPA | 020~029→110→093,099,100 | W2 | | 6 | 预警/审计 | 050~057→094→105 | W2~W3 | | 7 | 观测指标 | 101→102 | W3 | | 8 | 前端 | 060~069→106→063,064,079,103,104,080 | W3 | | 9 | 测试/CI | 081~118→091 | 贯穿+收尾 | | — | 已废止 | 075~078 | — | **里程碑 M1(Phase 0~4 完成)**:`POST /quotes` L2 命中 `source=cache`(TC-104)、幂等(TC-105)、校验 400(TC-201~204),无需真实 RPA。 --- ## 模块索引(按职能归类,非执行顺序) | 模块 | Task ID | 数量 | |------|---------|------| | 数据库(DB) | 070–073 | 4 | | 基础设施(Lib) | 096–098 | 3 | | 缓存系统 | 030–036, 035-ip | 8 | | 用户系统(Auth) | 001–005 | 5 | | 加价系统(Markup) | 040–044 | 5 | | 查价核心(Quote Engine) | 010–019, 092, 095, 109, 111 | 14 | | API 路由 | 015–018, 042–043 | 6 | | RPA 系统 | 020–029, 093, 099–100, 110 | 14 | | 预警系统(Alert) | 050–057, 094, 105 | 10 | | 观测与指标 | 101–102 | 2 | | 前端 UI | 060–080, 103–104, 106 | 18 | | 测试系统 | 081–091, 112–118 | 18 | | **合计(可执行)** | | **~102** | | **已废止** | 075–078 | 4 | ## 技术栈约定 - Next.js 15 App Router + TypeScript - MySQL 8.0 + Prisma ORM - Redis 7 + BullMQ - Playwright(RPA Worker) - Tailwind CSS + shadcn/ui + phosphor-icons ## v1.1 口径冻结(对齐 PRD v0.4) | 决策 | 规则 | 任务影响 | |------|------|----------| | GD-11 嵌入形态 | 查价 UI 为**宿主内嵌组件**,中台仅 admin 管理端 | task-106 替代 075–077;task-064 仅 admin | | §2.3 加价配置 | 中台**不提供**运营加价 UI,由宿主调 API | task-078 **废止**;task-042/043 保留 | | 四档报价 | GD-1/TC-102 为准(quotes=4);TC-601「2条」视为 PRD 笔误 | task-088/111 按 4 档验收 | | Fallback | 独立 FallbackOrchestrator 模块 | 新增 task-092 | | 管理端 RPA | §3.1 预警 + RPA/开发进度 | 新增 task-093, 103, 104 | | audit / metrics | §10.6 audit log + GD-4 三率 | 新增 task-094, 101, 102, 117 | ## v1.0 → v1.1 变更摘要 | 类型 | Task | 说明 | |------|------|------| | 新增 | 092–118(除重复编号) | 见各 Phase 章节 | | 修订 | 005, 014, 016, 018, 029, 050, 064, 065, 066, 079, 085, 091 | 补 RBAC/置信度/Fallback 引用等 | | 废止 | 075, 076, 077, 078 | PRD v0.4 口径下不交付 | | 替代 | 106 | 宿主内嵌查价组件(替代 075) | | 排序 | v1.1.1 | 正文按 Phase 0→9 开发顺序排列 | --- """ out = new_header + "".join(body) + appendices out = out.replace( "- **实现范围**:RPA成功 → 写L2(3min+jitter)+L3(30min) → UPDATE QuoteRecord(done) → 更新 quote_cache_meta → 偏差检测 → 写L1\n" "- **实现范围**:RPA成功 → 写L2(3min+jitter)+L3(30min) → UPDATE QuoteRecord(done) → 更新 quote_cache_meta → 偏差检测 → 写L1;**RPA失败 → 调用 task-092**", "- **实现范围**:RPA成功 → 写L2(3min+jitter)+L3(30min) → UPDATE QuoteRecord(done) → 更新 quote_cache_meta → 偏差检测 → 写L1;**RPA失败 → 调用 task-092**", ) path.write_text(out, encoding="utf-8") print(f"OK: {len(out.splitlines())} lines, {len(blocks)} blocks")