You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
7.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 — RPAW2",
[
"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 | — |
**里程碑 M1Phase 0~4 完成)**`POST /quotes` L2 命中 `source=cache`TC-104、幂等TC-105、校验 400TC-201~204无需真实 RPA。
---
## 模块索引(按职能归类,非执行顺序)
| 模块 | Task ID | 数量 |
|------|---------|------|
| 数据库DB | 070073 | 4 |
| 基础设施Lib | 096098 | 3 |
| 缓存系统 | 030036, 035-ip | 8 |
| 用户系统Auth | 001005 | 5 |
| 加价系统Markup | 040044 | 5 |
| 查价核心Quote Engine | 010019, 092, 095, 109, 111 | 14 |
| API 路由 | 015018, 042043 | 6 |
| RPA 系统 | 020029, 093, 099100, 110 | 14 |
| 预警系统Alert | 050057, 094, 105 | 10 |
| 观测与指标 | 101102 | 2 |
| 前端 UI | 060080, 103104, 106 | 18 |
| 测试系统 | 081091, 112118 | 18 |
| **合计(可执行)** | | **~102** |
| **已废止** | 075078 | 4 |
## 技术栈约定
- Next.js 15 App Router + TypeScript
- MySQL 8.0 + Prisma ORM
- Redis 7 + BullMQ
- PlaywrightRPA Worker
- Tailwind CSS + shadcn/ui + phosphor-icons
## v1.1 口径冻结(对齐 PRD v0.4
| 决策 | 规则 | 任务影响 |
|------|------|----------|
| GD-11 嵌入形态 | 查价 UI 为**宿主内嵌组件**,中台仅 admin 管理端 | task-106 替代 075077task-064 仅 admin |
| §2.3 加价配置 | 中台**不提供**运营加价 UI由宿主调 API | task-078 **废止**task-042/043 保留 |
| 四档报价 | GD-1/TC-102 为准quotes=4TC-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 | 说明 |
|------|------|------|
| 新增 | 092118除重复编号 | 见各 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")