Files
hot_comment_radar/docs/MVP-WorkOrders.md
T

1333 lines
46 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MVP 工单与版本推进计划
## 1. 文档目的
这份文档用于把后续开发从“零散修改”整理成“按工单推进”的节奏。
每个工单代表一组相关目标。一个工单可以包含多个小改动,但必须有清晰边界、验收标准和对应 commit。开发时优先把当前工单做稳定,不要频繁切换到不相关问题。
本项目当前最重要目标仍然是:让小红书 / 抖音热榜评论抓取工具在本机 Docker 环境下稳定跑通、页面可演示、报告可查看、数据可导出,最终达到可部署演示的产品化 MVP。
## 2. 当前版本状态
当前基线来自:
- `9bad7b6 feat: 提交热榜评论分析工具 MVP 基线`
已在 MVP-1 基线上追加的修复:
- `0a3477c fix: 修复报告摘要生成并稳定默认端口`
- 修复报告摘要 AI 未接入导致总是显示“总结生成失败”的问题。
- 评论级 AI 使用 JSON Array prompt。
- 报告摘要 AI 使用纯文本 prompt。
- 抖音评论支持分页,不再只取第一页 20 条。
- Docker Compose 固定项目名 `hot-comments-tool`,稳定使用 `8000` 端口。
- `b9291f9 fix: 增加任务详情自动刷新`
- 运行中任务详情页自动轮询任务状态。
- 任务成功或失败后自动刷新页面。
- 任务详情页“手动刷新”刷新当前页,不再跳回首页。
当前验证记录:
- 本地测试:`69 passed, 1 warning`
- Docker 入口:`http://localhost:8000`
- 健康检查:`GET /health -> {"status":"ok"}`
- 小红书 `1 × 1 × 10` 真实任务已跑通一次,抓到 9 条真实评论,报告摘要正常生成。
- 抖音默认参数 `5 × 5 × 50` 真实任务已跑通一次,但真实接口只返回 20 个可映射内容、237 条评论,未达到理论上限 25 个内容 / 1250 条评论。
## 3. 推荐开发流程
每次开始开发前,先确定当前要做的是哪一个工单。
推荐流程:
1. 选择一个工单。
2. 明确本轮只做该工单范围内的事情。
3. 写或更新测试。
4. 修改代码。
5. 跑本地测试。
6. 重建 Docker 并在 `http://localhost:8000` 手工验收。
7. 如果验收中发现同工单内 bug,继续修。
8. 如果发现不相关 bug,记录到“后续工单 / 新问题”,不要打断当前工单。
9. 工单达到验收标准后提交一个或几个 commit。
推荐命令:
```bash
pytest tests/unit tests/integration -q
docker compose up -d --build
curl -f http://localhost:8000/health
```
## 4. Commit 规则
一个工单可以对应一个 commit,也可以对应几个 commit。
适合一个 commit 的情况:
- 修改范围集中。
- 验收标准一次性通过。
- 回滚时希望整体回滚。
适合多个 commit 的情况:
- 一个工单里有多个清晰子目标。
- 某个子目标已经独立稳定。
- 后续问题修复和主要功能实现需要分开表达。
Commit 信息建议:
```text
feat: 优化任务状态与进度体验
fix: 修复报告页空状态展示
fix: 修复抖音评论分页停止条件
test: 补充真实任务状态轮询测试
docs: 更新 MVP 工单计划
```
Commit 原则:
- 不提交 `.env`、真实 API Key、真实 AI Key。
- 不提交运行数据库文件,例如 `data/*.db`
- 不把不相关问题混进同一个 commit。
- 每个 commit 信息要能回答:这次改动解决了什么目标。
## 5. 验收分层
每个工单完成前至少做以下验证:
### 5.1 自动化测试
必须跑:
```bash
pytest tests/unit tests/integration -q
```
如果改了报告、导出、平台抓取、AI 服务,应优先补对应测试。
### 5.2 Docker 验收
必须确认:
```bash
docker compose up -d --build
curl -f http://localhost:8000/health
```
浏览器打开:
```text
http://localhost:8000
```
### 5.3 真实任务验收
常用轻量验收:
- 小红书:`1 热点 × 1 内容 × 10 评论`
- 抖音:`1 热点 × 1 内容 × 10 评论`
默认规模验收:
- 小红书:`5 热点 × 5 内容 × 50 评论`
- 抖音:`5 热点 × 5 内容 × 50 评论`
注意:真实接口返回数量可能不足理论上限。验收时要区分:
- 任务是否成功。
- 是否有热点、内容、评论、报告入库。
- AI 成功率是否正常。
- 页面是否能展示和导出。
- 实际返回不足是否来自平台数据本身。
## 6. 审阅决策摘要
本节来自 `MVP-WorkOrders.md` 综合审阅报告最终版,作为后续执行的约束。
审阅来源:
- 双份独立审阅意见合并:全栈专家 INTJ + Kiro。
- 决策人:用户。
- 审阅报告定稿时间:2025-07-10。
### 6.1 高置信度共识
- 重试 / 容错逻辑是真实验收硬前提:429 指数退避重试 `1s -> 2s -> 4s`、单条失败隔离、当前条目失败后继续处理,必须在真实环境验收前具备。
- 单条异常不得导致任务级崩溃:每条评论 / 每个内容条目处理必须隔离异常;AI 失败写入 `ai_analysis_status=failed`,不因单条异常升级为任务级 failure。
- CSV 导出必须同时具备三重防护:公式注入防护、换行符替换、UTF-8-BOM 编码。
- 任务轮询必须有终止条件:任务进入 `success``failed` 后停止轮询,避免长期制造无意义请求。
- Docker SQLite WAL 必须挂载整个目录:使用 `./data:/app/data`,保证 `.db``.db-wal``.db-shm` 同目录持久化。
### 6.2 分歧决策
| 分歧项 | 决策 | 理由 |
|---|---|---|
| WO-03 与 WO-05 执行顺序 | 折中:WO-05 核心逻辑内联为 WO-03 前置步骤,WO-05 保留边界 case 压测 | 小规模真实验收不能裸奔,但不把所有压测提前 |
| `PRAGMA integrity_check` 配置开关 | 不加开关,MVP 阶段启动时始终执行 | YAGNI,MVP 数据量下成本可接受 |
| CSV 编码策略 | 统一 UTF-8-BOM | 优先保证 Windows Excel 中文不乱码 |
### 6.3 确认行动清单
| 序号 | 行动 | 对应工单 | 优先级 |
|---|---|---|---|
| 1 | 指数退避重试 `1s -> 2s -> 4s` 和单条 try-catch 隔离内联到小规模真实验收前置步骤 | WO-03 | 高 |
| 2 | WO-05 范围缩减为边界 case 压测:连续 429 超限、全部失败降级、并发请求竞争 | WO-05 | 中 |
| 3 | CSV 导出添加公式注入前缀,首字符为 `= + - @` 时添加 `'` | WO-07 | 高 |
| 4 | CSV 导出替换评论内容中的 `\n``\r` 为空格 | WO-07 | 高 |
| 5 | CSV 导出使用 UTF-8-BOM | WO-07 | 高 |
| 6 | 前端轮询在 `success` / `failed` 时停止 | WO-01 | 中 |
| 7 | Docker 挂载整个 `./data:/app/data` 目录 | WO-08 | 中 |
| 8 | AI 分析失败时 UI 展示空状态 / 默认文案,页面不返回 500 | WO-02 | 中 |
| 9 | 后台线程中使用同步 `httpx.Client`,禁止 `httpx.AsyncClient` | WO-03 / WO-05 | 高 |
| 10 | 每个内容条目处理完立即 commit,不持有长事务 | WO-03 / WO-04 | 中 |
| 11 | `PRAGMA integrity_check` 启动时始终执行,不加配置开关 | WO-06 | 低 |
### 6.4 保留的亮点
- 新问题处理规则保留:验收中发现不相关问题时先记录,不打断当前工单,防止范围蔓延。
- 文档工单化保留:用户操作说明作为独立 WO-09,不作为顺手补充,避免文档质量被压缩。
- 完成记录模板保留:每个工单完成后记录 commit、验证命令、真实任务 ID、验收结论和遗留问题。
- 导出安全意识保留:CSV 公式注入、换行和编码问题均纳入 WO-07 验收。
## 7. 工单总览
| 编号 | 工单 | 优先级 | 目标 |
|---|---|---|---|
| WO-01 | 任务状态与进度体验优化 | P0 | 让长任务不再像卡住,状态清晰可见 |
| WO-02 | 报告页和内容详情页产品化打磨 | P0 | 报告更像可演示产品,而不是工程输出 |
| WO-03 | 双平台真实小规模验收 | P0 | 带基础容错前置,小红书 / 抖音 `1×1×10` 都稳定跑通 |
| WO-04 | 双平台默认规模验收 | P0 | 小红书 / 抖音默认规模完成真实验收并记录限制 |
| WO-05 | 失败、限流和跳过边界压测 | P0 | 验证连续 429、全批失败、并发竞争等边界 |
| WO-06 | SQLite 数据库稳定性与恢复策略 | P0 | 避免数据库损坏、空表化和运行中任务误导 |
| WO-07 | 导出链路验收与文件质量优化 | P1 | CSV / Markdown 导出稳定、命名清晰、内容一致 |
| WO-08 | Docker 与部署前清理 | P1 | 固定启动方式、数据目录、环境变量和部署文档 |
| WO-09 | 文档与用户操作说明 | P1 | 让非开发者也能启动、创建任务、查看报告 |
| WO-10 | 发布候选版本验收 | P0 | 汇总所有验收,形成可演示 MVP 版本 |
## 8. 工单详情
### WO-01 任务状态与进度体验优化
优先级:P0
目标:
- 用户创建任务后,页面能持续反馈任务是否仍在运行。
- 任务成功、失败、中断后,页面能及时更新。
- 用户能看到进度,不会误以为系统卡死。
包含范围:
- 任务详情页自动刷新。
- 任务列表自动刷新。
- 任务进度条或进度百分比。
- 当前处理数量:成功 / 失败 / 总内容数。
- 失败原因展示:阶段、错误类型、错误消息。
- AI 成功率展示。
- 轮询终止条件:任务进入 `success``failed` 后停止轮询。
边界情况:
- `status=running` 且没有热点:显示“正在抓取热点数据”。
- `status=running` 且已有热点或内容:显示当前进度,不只显示加载中。
- `status=failed`:必须展示失败原因。
- 系统重启导致任务中断:展示“系统重启,任务被中断”。
- `analysis_status=insufficient`:任务仍可成功,但页面提示 AI 样本不足。
验收标准:
- 创建 `1×1×10` 任务后,任务详情页能自动从 running 变为 success 或 failed。
- 不刷新浏览器也能看到最终状态。
- 失败任务不再长期显示“正在抓取热点数据”。
- 运行中任务列表能自动更新状态。
- 任务终止后不继续轮询,不持续打 API。
建议 commit
```text
feat: 优化任务状态与进度体验
```
当前状态:
- 任务详情页自动刷新已完成。
- 任务列表自动刷新、进度条、AI 成功率突出展示仍待做。
### WO-02 报告页和内容详情页产品化打磨
优先级:P0
目标:
- 报告页面更适合演示和阅读。
- 用户能快速理解评论情绪、标签、典型评论和 AI 总结。
包含范围:
- 热点报告页布局优化。
- 内容详情页布局优化。
- AI 总结区域突出展示。
- 情绪分布展示更直观。
- Top 标签展示更清晰。
- 评论列表展示情绪、标签、点赞数。
- 报告尚未生成时的空状态。
- 报告生成失败时的提示。
- AI 分析失败或样本不足时的默认文案 / 空状态。
边界情况:
- 评论数量为 0。
- AI 总结失败。
- 报告记录不存在。
- 标签为空。
- AI 成功率低于 80%。
- 内容条目失败但同热点下其他内容成功。
- AI 分析失败时,页面不得返回 500。
验收标准:
- 热点报告页能清楚展示摘要、样本数、情绪、标签、典型评论。
- 内容详情页能清楚展示单条内容报告和评论明细。
- 没有报告时不是空白或 500。
- AI 失败或样本不足时有可读提示,不显示异常堆栈。
- Markdown 导出内容与页面报告一致。
建议 commit
```text
feat: 打磨报告页和内容详情页
```
### WO-03 双平台真实小规模验收
优先级:P0
目标:
- 在具备基础容错前提下,小红书和抖音都能用真实 TikHub、真实 AI 跑通 `1×1×10`
- WO-03 不允许裸奔进入真实环境,必须先确认基础重试、单条隔离和同步 HTTP client 约束。
包含范围:
- 前置内联:TikHub 429 指数退避重试 `1s -> 2s -> 4s`
- 前置内联:单条评论 / 单个内容条目异常隔离,失败记录后继续处理。
- 前置内联:后台任务只使用同步 `httpx.Client`,禁止 `httpx.AsyncClient`
- 前置内联:每个内容条目处理完立即 commit,不持有长事务。
- 小红书真实任务验收。
- 抖音真实任务验收。
- 记录任务 ID、状态、热点数、内容数、评论数、报告数、AI 成功率。
- 如果真实返回不足 10 条评论,记录实际返回数和原因判断。
边界情况:
- 平台返回 0 个热点。
- 热点搜索不到内容。
- 内容评论不足 10 条。
- AI 请求失败或解析失败。
- 报告摘要生成失败。
- 单条评论乱码或字段缺失。
- 单个内容条目失败,但后续内容仍应继续。
验收标准:
- 两个平台任务最终 `status=success`
- 至少有热点、内容、评论、报告入库。
- AI 成功率正常,或有明确不足提示。
- 页面能查看热点报告、内容详情和评论明细。
- 单条评论 / 单个内容条目异常不会导致整个任务崩溃。
- 后台线程中不存在 `httpx.AsyncClient` 使用。
建议 commit
```text
test: 记录双平台小规模真实验收
```
完成记录:
```text
完成日期:2026-07-03
相关 commit:test: 记录双平台小规模真实验收
验证命令:
- .venv/bin/python -m pytest tests/unit tests/integration -q
- .venv/bin/python -m pytest tests/unit tests/integration --cov=app --cov-branch --cov-report=term-missing
- docker compose up -d --build
- curl -f http://localhost:8000/health
真实任务 ID
- 小红书:8ae106f4-64dc-4675-a021-f78092926ce6
- 抖音:b295f4b2-d546-4121-99bc-48d166d86bf4
验收结论:
- 小红书 1×1×10status=success,热点 1,内容 1,评论 10,报告 2,AI 成功率 100%。
- 抖音 1×1×10status=success,热点 1,内容 1,评论 10,报告 2,AI 成功率 100%。
- 页面可查看任务详情、热点报告、内容详情和评论明细。
- 自动化测试补充了连续 429 的 1s→2s→4s 退避断言,以及单个内容条目失败后继续处理后续条目的容错测试。
- 代码中未发现 httpx.AsyncClient 使用。
遗留问题:无;进入 WO-04 默认规模验收。
```
### WO-04 双平台默认规模验收
优先级:P0
目标:
- 验证默认规模 `5×5×50` 在真实接口下的表现。
包含范围:
- 小红书默认规模真实验收。
- 抖音默认规模真实验收。
- 记录任务结果和真实接口限制。
- 区分“代码失败”和“平台返回不足”。
边界情况:
- 搜索每个热点返回内容不足 5 条。
- 部分内容评论不足 50 条。
- TikHub 429 限流。
- TikHub 超时。
- AI 调用耗时长。
- SQLite 写入压力增加。
验收标准:
- 任务能完成或给出明确失败原因。
- 成功内容条目都有报告。
- 热点级报告生成。
- AI 摘要不再出现批量兜底失败。
- 对未达到理论数量的原因有记录。
建议 commit
```text
test: 记录双平台默认规模真实验收
```
完成记录:
```text
完成日期:2026-07-03
相关 commit:test: 记录双平台默认规模真实验收
验证命令:
- docker compose up -d --build
- curl -f http://localhost:8000/health
- 通过 /api/tasks 创建小红书、抖音默认规模任务并轮询至终态
- 通过任务详情页、热点 CSV/Markdown 导出、内容详情页抽样确认页面主链路
真实任务 ID
- 小红书:4bdf36df-8ae4-4059-af98-602f4872dbaa
- 抖音:378b173a-a70f-4da1-b235-03e7632e614a
验收结论:
- 小红书 5×5×50status=success,热点 5,内容 25/25 成功,评论 119,报告 30AI 成功率 100%。
- 抖音 5×5×50status=success,热点 5,内容 20/20 成功,评论 285,报告 25AI 成功率约 82.46%。
- 两个平台均未达到理论上限 1250 条评论;原因判断为真实平台/接口返回内容与评论不足,而非任务失败。
- 页面可查看任务详情、热点报告、内容详情和评论明细;热点 Markdown、热点 CSV、内容 Markdown 抽样可导出。
遗留问题:
- 验收中观察到 Uvicorn 进程持有已删除的 SQLite WAL/SHM 文件句柄,导致独立脚本直读 /app/data/app.db 时暂时看不到新任务,但 Web/API 视图正常。归入 WO-06 处理。
```
### WO-05 失败、限流和跳过边界验证
优先级:P0
目标:
- 在 WO-03 已内联基础容错后,集中压测更极端的边界 case。
- 确认连续失败、全部失败、并发竞争等场景不会产生误导性状态或无意义 500。
包含范围:
- 连续 429 超过最大重试次数后的错误记录。
- 全部内容条目失败后的任务降级。
- AI 全批失败后的 `analysis_status=insufficient`
- 并发创建任务竞争:已有 running 时拒绝新任务。
- 评论分页中途失败处理。
- 报告摘要失败后使用默认文案,不阻断报告生成。
- 确认后台任务仍使用同步 `httpx.Client`
边界情况:
- 热点接口失败:任务失败。
- 内容搜索失败:当前热点内容失败或跳过。
- 评论接口失败:当前内容失败,其他内容继续。
- AI 失败:评论标记 failed,任务可继续。
- 报告摘要失败:报告仍创建。
- 连续 429 超限后:记录 `rate_limited`,不暴露 API Key。
- 所有内容失败后:任务 `status=failed`,错误原因可见。
- 同时发起两个任务:第二个应返回 400。
验收标准:
- mock 测试覆盖失败路径。
- 连续 429、全部失败、并发竞争均有测试覆盖。
- 页面能展示失败阶段和错误类型。
- 没有无意义的 500 页面。
建议 commit
```text
fix: 完善失败重试与跳过边界
```
完成记录:
```text
完成日期:2026-07-03
相关 commit:fix: 完善失败重试与跳过边界
验证命令:
- .venv/bin/python -m pytest tests/integration/test_failure_tolerance.py tests/unit/test_report_stats.py tests/integration/test_task_creation.py tests/unit/test_comment_pagination.py tests/unit/test_ai_schema.py -q
- .venv/bin/python -m pytest tests/unit tests/integration -q
- .venv/bin/python -m pytest tests/unit tests/integration --cov=app --cov-branch --cov-report=term-missing
- curl -f http://localhost:8000/health
验收结论:
- 连续 429 超限测试覆盖并断言退避序列 1s→2s→4s,错误类型为 rate_limited 且不泄露 API Key。
- 单个内容条目评论抓取失败时记录 failed item,后续内容继续处理,任务可成功。
- 所有内容条目失败时任务 status=failederror_stage/error_type/error_message 可见。
- AI 全批失败已有测试覆盖:评论标记 failed,任务 analysis_status=insufficient。
- 报告摘要失败时 item/hotspot 报告仍创建,并使用默认总结文案。
- 已有 running 任务时拒绝新建任务,返回 400。
- 未发现 httpx.AsyncClient 使用。
遗留问题:W04 发现的 SQLite WAL/SHM deleted 句柄问题转入 WO-06。
```
### WO-06 SQLite 数据库稳定性与恢复策略
优先级:P0
目标:
- 避免真实验收时出现数据库损坏、空表化、WAL 状态异常。
- 数据库异常时能明确提示,而不是页面随机 500。
包含范围:
- 启动时始终执行 `PRAGMA integrity_check`,不新增配置开关。
- 数据库损坏备份策略。
- WAL / SHM 文件处理策略。
- 运行中任务恢复逻辑。
- 数据目录说明。
- 验收库和正式库隔离建议。
边界情况:
- Docker 重启时任务正在运行。
- `data/app.db` 损坏。
- `app.db-wal` / `app.db-shm` 异常。
- 本地脚本和 Docker 同时访问同一个 SQLite 文件。
- 数据库为空但用户误以为历史数据还在。
- `PRAGMA integrity_check` 返回非 `ok`
验收标准:
- `PRAGMA integrity_check` 可执行。
- 启动时默认执行 integrity check,不需要 `DB_CHECK_ON_STARTUP` 之类的开关。
- Docker 重启后 running 任务被标记 failed,并显示明确原因。
- 数据库异常不会让用户误以为任务还在抓取。
- 文档说明如何重置本地验收数据库。
建议 commit
```text
fix: 增强 SQLite 数据库恢复与异常提示
```
完成记录:
```text
完成日期:2026-07-03
相关 commitfix: 增强 SQLite 数据库恢复与异常提示
验证命令:
- .venv/bin/python -m pytest tests/unit/test_db_stability.py tests/integration/test_task_recovery.py -q
- docker compose up -d --build
- curl -f http://localhost:8000/health
- docker compose exec -T app python 检查 PRAGMA integrity_check 与 wal_checkpoint(TRUNCATE)
- .venv/bin/python -m pytest tests/unit tests/integration -q
- .venv/bin/python -m pytest tests/unit tests/integration --cov=app --cov-branch --cov-report=term-missing
验收结论:
- 启动时执行 PRAGMA integrity_check,异常时抛出明确 RuntimeError,不新增配置开关。
- 启动建表后执行 PRAGMA wal_checkpoint(TRUNCATE),将 WAL 写入主库并截断 WAL 文件。
- Docker 重建后,独立脚本可读到 WO-04 默认规模任务 4bdf36df-8ae4-4059-af98-602f4872dbaa 与 378b173a-a70f-4da1-b235-03e7632e614a。
- Uvicorn 进程不再持有 deleted app.db-wal/app.db-shm 文件句柄。
- Docker 重启后 running 任务恢复逻辑仍通过测试。
遗留问题:
- 数据库损坏备份策略和本地重置说明需要在 WO-09 用户操作文档中补充。
```
### WO-07 导出链路验收与文件质量优化
优先级:P1
目标:
- CSV / Markdown 导出可用于演示和交付。
包含范围:
- 内容评论 CSV。
- 热点评论 CSV。
- 内容报告 Markdown。
- 热点报告 Markdown。
- 文件名安全处理。
- CSV 公式注入防护:首字符为 `=`, `+`, `-`, `@` 时添加单引号前缀。
- CSV 换行符处理:评论内容中的 `\n``\r` 替换为空格。
- CSV 编码:统一使用 UTF-8-BOM。
- 报告不存在时禁用导出或返回友好错误。
边界情况:
- 评论内容以 `=`, `+`, `-`, `@` 开头。
- 评论内容包含换行符或回车符。
- 中文文件名。
- 报告不存在。
- 内容条目失败。
- 评论为空。
验收标准:
- 浏览器点击导出能下载文件。
- 文件名可读且安全。
- Markdown 内容与页面一致。
- CSV 用 Windows Excel 打开中文不乱码。
- CSV 中公式注入内容不会被 Excel 当公式执行。
- CSV 中单条评论不会因换行破坏行结构。
建议 commit
```text
feat: 优化导出文件质量
```
完成记录:
```text
完成日期:2026-07-03
相关 commitfeat: 优化导出文件质量
验证命令:
- .venv/bin/python -m pytest tests/unit/test_export.py tests/integration/test_routes.py::test_result_pages_render_seeded_data tests/integration/test_routes.py::test_report_pages_render_empty_state_when_report_missing tests/integration/test_routes.py::test_export_routes_return_csv_and_markdown -q
- .venv/bin/python -m pytest tests/unit tests/integration -q
- docker compose up -d --build
- curl -f http://localhost:8000/health
- 抽样检查内容 CSV UTF-8-BOM、CSV 列数、Markdown 总结章节和页面 downloadExport 按钮
- .venv/bin/python -m pytest tests/unit tests/integration --cov=app --cov-branch --cov-report=term-missing
验收结论:
- CSV 导出已覆盖 =、+、-、@ 公式注入前缀防护。
- CSV 导出会替换 \n、\r、\r\n,避免单条评论破坏行结构。
- CSV 导出使用 UTF-8-BOM,抽样文件以 BOM 开头。
- 热点/内容报告和评论导出按钮使用 downloadExport,报告缺失时 Markdown 按钮置灰并提示“报告尚未生成”。
- Markdown 导出读取预生成 report.markdown_content,抽样包含“## 总结”章节。
遗留问题:评论为空时 CSV 仍返回只有表头的文件,后续可在 WO-09 文档说明空文件语义。
```
### WO-08 Docker 与部署前清理
优先级:P1
目标:
- 让启动、重建、部署方式稳定,不再出现端口混乱或多容器冲突。
包含范围:
- 固定 Docker Compose 项目名。
- 固定端口 `8000`
- 数据目录挂载说明。
- Docker Compose 挂载整个 `./data:/app/data` 目录,不挂载单个 `.db` 文件。
- `.env` / `.env.example` 检查。
- Docker 重建流程。
- 部署前清理临时数据库。
边界情况:
- 旧容器占用 8000。
- 不同项目名启动出两套容器。
- `.env` 缺少 API Key。
- Docker 容器内代码不是最新镜像。
- SQLite WAL 生成 `.db-wal``.db-shm` 文件。
验收标准:
- `docker compose up -d --build` 后只存在一个项目容器。
- `http://localhost:8000/health` 返回 200。
- 不再需要临时使用 8001。
- `docker-compose.yml` 使用 `./data:/app/data` 目录挂载,WAL 相关文件与主库同目录。
建议 commit
```text
chore: 整理 Docker 启动与部署配置
```
当前状态:
- 固定项目名和 8000 端口已完成。
- 部署文档和数据清理流程仍待补充。
完成记录:
```text
完成日期:2026-07-03
相关 commitchore: 整理 Docker 启动与部署配置
验证命令:
- .venv/bin/python -m pytest tests/unit/test_deployment_config.py -q
- docker compose ps
- curl -f http://localhost:8000/health
- .venv/bin/python -m pytest tests/unit tests/integration -q
验收结论:
- docker-compose.yml 固定 name: hot-comments-tool。
- 端口固定为 8000:8000,当前运行容器为 hot-comments-tool-app-1。
- docker-compose.yml 挂载 ./data:/app/data,未挂载单个 app.db 文件。
- 新增 docs/Deployment.md,说明启动、重建、端口占用、环境变量、数据目录和本地验收数据库重置流程。
遗留问题:无;WO-09 会继续补完整用户操作说明。
```
### WO-09 文档与用户操作说明
优先级:P1
目标:
- 让后续自己或其他人能按文档启动、验收、排查。
包含范围:
- 本地启动说明。
- Docker 启动说明。
- 创建任务说明。
- 小规模验收说明。
- 默认规模验收说明。
- 常见问题。
- 数据库重置说明。
边界情况:
- 端口占用。
- API Key 缺失。
- 任务长期 running。
- 报告摘要失败。
- 评论数量少于请求上限。
- 数据库损坏或空表。
验收标准:
- 按文档可以从零启动服务。
- 按文档可以完成一次小红书和抖音小规模验收。
- 常见问题能指导用户判断下一步。
建议 commit
```text
docs: 补充本地验收和部署说明
```
完成记录:
```text
完成日期:2026-07-03
相关 commit:docs: 补充本地验收和部署说明
验证命令:
- .venv/bin/python -m pytest tests/unit/test_docs.py -q
- .venv/bin/python -m pytest tests/unit tests/integration -q
- curl -f http://localhost:8000/health
验收结论:
- 新增 docs/UserGuide.md,覆盖启动、创建任务、小规模验收、默认规模验收、报告查看、导出、常见问题和数据库重置。
- 用户指南明确固定入口 http://localhost:8000,说明不要临时改 8001。
- 文档说明 API Key 缺失、任务长期 running、评论数量少于上限、报告摘要失败等排查方式。
- 新增文档测试,防止关键章节被误删。
遗留问题:无;进入 WO-10 发布候选验收。
```
### WO-10 发布候选版本验收
优先级:P0
目标:
- 在所有 P0 工单完成后,形成一个可演示、可部署的 MVP 发布候选版本。
包含范围:
- 全量测试。
- Docker 健康检查。
- 双平台小规模验收。
- 双平台默认规模验收。
- 页面主链路验收。
- 导出验收。
- 已知问题清单。
最终验收标准:
- 首页能创建任务。
- 任务运行状态清晰。
- 小红书和抖音都能跑通真实任务。
- 评论级 AI 情绪和标签正常。
- 热点报告和内容报告都有 AI 总结。
- 报告和评论页面可查看。
- CSV 和 Markdown 可导出。
- Docker 固定运行在 8000。
- 数据库异常和任务失败有明确提示。
- 文档说明如何启动、验收和排查。
建议 commit
```text
release: 标记 MVP 演示候选版本
```
完成记录:
```text
完成日期:2026-07-03
相关 commitrelease: 标记 MVP 演示候选版本
验证命令:
- .venv/bin/python -m pytest tests/unit tests/integration -q
- .venv/bin/python -m pytest tests/unit tests/integration --cov=app --cov-branch --cov-report=term-missing
- curl -f http://localhost:8000/health
- docker compose ps
- docker compose exec -T app python 检查 PRAGMA integrity_check 与 wal_checkpoint(TRUNCATE)
- 抽样检查任务详情页、热点报告页、内容详情页、CSV 导出、Markdown 导出
发布候选验收结论:
- 自动化测试:87 passed, 1 warning。
- 覆盖率:TOTAL 90%;重点模块 app/platforms/douyin.py 87%、app/platforms/xiaohongshu.py 83%、app/services/ai_service.py 95%、app/services/report_service.py 91%、app/services/export_service.py 92%。
- Dockerhot-comments-tool-app-1 运行在 http://localhost:8000health 返回 ok。
- 数据库:integrity_check=okwal_checkpoint(TRUNCATE)=True。
- 小红书小规模 1×1×108ae106f4-64dc-4675-a021-f78092926ce6success,内容 1/1AI 成功率 100%。
- 抖音小规模 1×1×10b295f4b2-d546-4121-99bc-48d166d86bf4success,内容 1/1AI 成功率 100%。
- 小红书默认规模 5×5×504bdf36df-8ae4-4059-af98-602f4872dbaasuccess,内容 25/25,评论 119,报告 30AI 成功率 100%。
- 抖音默认规模 5×5×50378b173a-a70f-4da1-b235-03e7632e614asuccess,内容 20/20,评论 285,报告 25AI 成功率约 82.46%。
- 页面主链路:任务详情、热点报告、内容详情均可访问并展示 AI 总结、情绪分布、标签、典型评论和评论明细。
- 导出链路:CSV 带 UTF-8-BOM 且列结构正常,Markdown 包含“## 总结”章节。
已知问题:
- 默认规模评论数低于理论上限 1250,原因判断为真实平台/接口返回不足,不是任务失败。
- app/platforms/base.py 覆盖率为 76%,低于 80%,但不在本轮重点模块清单内;后续可针对网络错误和解析边界继续补测。
```
## 9. 新问题处理规则
验收时发现新问题,先判断归属:
- 属于当前工单:直接修,和当前工单一起提交。
- 不属于当前工单:记录到对应工单或新建问题,不立即切换。
- 是阻塞主链路的问题:可以暂停当前工单,先开一个 `fix:` commit 处理。
示例:
- 当前做 WO-01,发现任务详情页不会刷新:属于当前工单,直接修。
- 当前做 WO-01,发现 CSV 乱码:记录到 WO-07,不要马上切走。
- 当前做任何工单,发现 Docker 起不来:阻塞验收,可先修 WO-08 相关问题。
## 10. 建议后续推进顺序
建议顺序:
1. WO-01 任务状态与进度体验优化
2. WO-02 报告页和内容详情页产品化打磨
3. WO-03 双平台真实小规模验收
4. WO-04 双平台默认规模验收
5. WO-05 失败、限流和跳过边界压测
6. WO-06 SQLite 数据库稳定性与恢复策略
7. WO-07 导出链路验收与文件质量优化
8. WO-08 Docker 与部署前清理
9. WO-09 文档与用户操作说明
10. WO-10 发布候选版本验收
原因:
- 先解决用户看得到的“卡住感”和状态透明。
- 再打磨核心报告页面。
- 再做带基础容错前置的小规模真实验收。
- 默认规模验收后,再用 WO-05 集中压测连续 429、全批失败、并发竞争等边界。
- 最后整理部署、文档和发布候选版本。
执行链路:
```text
WO-01 任务详情页 + 轮询终止
WO-02 数据可视化 + AI 失败空状态降级
WO-03 小规模真实验收
├── 前置内联:429 指数退避
├── 前置内联:单条 try-catch 隔离
└── 前置内联:httpx 同步 Client 确认
WO-04 默认规模验收
WO-05 边界 case 压测:连续 429 超限、全批失败降级、并发竞争
WO-06 SQLite WAL + integrity_check,不加开关
WO-07 导出:UTF-8-BOM + 公式注入防护 + 换行替换
WO-08 Docker Compose + 目录挂载
WO-09 文档与用户操作说明
WO-10 收尾与 P1 评估
```
## 11. 与 AGENTS.md 约束的对齐确认
本工单计划与 `AGENTS.md` 的关键约束兼容:
- MVP P0 功能不可裁剪:WO-03 内联基础容错,WO-05 保留边界压测。
- 后台任务使用同步 HTTPWO-03 / WO-05 明确禁止 `httpx.AsyncClient`
- 错误隔离:WO-03 要求单条评论 / 单个内容条目异常不升级为任务级崩溃。
- 报告预生成:WO-02 / WO-07 继续要求页面和导出读取同一份报告数据。
- 数据库与 DockerWO-06 / WO-08 明确 WAL 目录挂载和启动时 integrity check。
- 测试优先:每个工单验收前必须运行 `pytest tests/unit tests/integration -q`,涉及核心服务时补对应测试。
## 12. 每次工单完成后的记录模板
完成一个工单后,在该工单下补充记录:
```text
完成日期:
相关 commit
验证命令:
真实任务 ID
验收结论:
遗留问题:
```
示例:
```text
完成日期:2026-07-03
相关 commitb9291f9 fix: 增加任务详情自动刷新
验证命令:pytest tests/unit tests/integration -q
真实任务 IDba8c2bf1-ec69-408e-a328-f87db8e29f54
验收结论:小红书 1×1×10 跑通,页面显示已完成,报告摘要正常
遗留问题:任务列表自动刷新和进度条仍待做
```
---
## 13. MVP-2 新问题与产品化工单
本节记录 MVP 演示候选版本之后,用户在网页人工验收阶段发现的新问题和新增需求。
当前原则:
- 不覆盖 WO-01 到 WO-10 的完成记录。
- 新问题按 MVP-2 工单继续推进。
- 阻塞主链路的问题优先修复。
- 不清楚的产品决策必须先确认,不擅自替用户决定。
- 每个工单完成后继续按“完成日期 / commit / 验证命令 / 验收结论 / 遗留问题”记录。
### MVP-2 工单总览
| 编号 | 工单 | 优先级 | 目标 |
|---|---|---|---|
| WO-11 | 全站 Internal Server Error 排查与兜底 | P0 | 解决点击按钮或刷新页面出现 500 的阻塞问题 |
| WO-12 | 导出 Markdown / CSV 点击失效修复 | P0 | 恢复报告和评论导出主链路 |
| WO-13 | 抓取任务进度透明化与耗时预期 | P0 | 降低长任务黑盒感,让用户知道任务是否真的在推进 |
| WO-14 | Demo 数据保留与新任务并存体验 | P0 | 打开页面即可看 demo 数据,同时还能新跑完整流程 |
| WO-15 | 公网部署方案与上线验收 | P0 | 从本机 Docker 演示推进到可公网访问的部署 |
| WO-16 | UI 产品化改版 | P1 | 在不破坏主链路的前提下提升页面观感和演示质感 |
| WO-17 | 默认规模数据量解释与展示优化 | P1 | 把“未达到 1250”解释为真实内容/评论不足,并在 UI 中清楚呈现 |
### WO-11 全站 Internal Server Error 排查与兜底
优先级:P0
背景:
- 用户反馈:每次点击一个按钮或刷新页面时,页面可能显示 `Internal Server Error`
- 这是主链路阻塞问题,必须优先定位。
目标:
- 找出导致 500 的具体路由、异常堆栈和触发条件。
- 对可恢复异常提供友好页面或错误提示,不让普通点击直接暴露 500。
- 确保任务详情页、热点报告页、内容详情页、导出入口、刷新入口都不会因缺失数据直接崩溃。
包含范围:
- 查看 Docker / Uvicorn 日志,记录 500 对应的异常堆栈。
- 覆盖任务详情页刷新、任务列表刷新、热点报告页、内容详情页、导出入口等高频路由。
- 对缺失任务、缺失热点、缺失内容、缺失报告、数据库读取异常等场景增加兜底。
- 增加回归测试,覆盖已发现的 500 触发路径。
边界情况:
- 任务 ID 不存在。
- 报告记录不存在。
- 内容条目存在但评论为空。
- 任务处于 `running`,相关热点 / 内容 / 报告尚未生成。
- 数据库暂时不可读或记录字段为空。
- 浏览器重复刷新或重复点击按钮。
验收标准:
- 已知触发 500 的页面和按钮不再返回 `Internal Server Error`
- 真实异常在服务端日志中可定位,前端展示友好提示。
- `pytest tests/unit tests/integration -q` 通过。
- Docker 环境下手动刷新任务详情页、报告页、内容页不出现 500。
建议 commit
```text
fix: 修复页面刷新和按钮点击的 500 错误
```
待确认:
- 用户需要提供或复现最容易触发 500 的页面 URL 与按钮名称;如果无法提供,则开发时先从当前浏览器打开的任务详情页开始排查。
### WO-12 导出 Markdown / CSV 点击失效修复
优先级:P0
背景:
- 用户反馈:点击导出 Markdown 文档和导出 CSV 评论时,页面没有反应,像是按钮失效。
目标:
- 恢复热点报告 Markdown、内容报告 Markdown、热点评论 CSV、内容评论 CSV 的下载能力。
- 当报告尚未生成或数据为空时,按钮必须给出明确提示,而不是“点不动”。
包含范围:
- 检查导出按钮的前端事件绑定、HTMX / 普通链接行为、下载路由返回头。
- 检查导出路由是否返回正确的 `Content-Type``Content-Disposition`
- 检查浏览器端是否被 disabled 状态、JS 错误或 500 响应卡住。
- 报告缺失时提供友好提示。
- 评论为空时仍可下载只有表头的 CSV,或按用户决策改为提示无评论。
边界情况:
- 报告尚未生成。
- 评论数量为 0。
- 文件名包含中文或特殊字符。
- 浏览器拦截下载。
- 导出接口返回 404 / 500。
- 用户连续点击导出按钮。
验收标准:
- 页面点击导出后浏览器能下载文件,或看到明确的不可导出原因。
- CSV 可打开且含 UTF-8-BOM、公式注入防护、换行替换。
- Markdown 内容与页面报告一致。
- 导出失败不会造成整页 500。
建议 commit
```text
fix: 修复报告和评论导出点击失效
```
待确认:
- 评论为空时,用户希望“下载只有表头的 CSV”,还是“按钮禁用并提示暂无评论”。
### WO-13 抓取任务进度透明化与耗时预期
优先级:P0
背景:
- 用户反馈:开始抓取后虽然显示运行中,但不知道具体需要多少时间,也不知道系统是否真的在抓取。
- 当前体验仍有黑盒感,尤其是默认规模任务会等待较久。
目标:
- 让任务详情页清楚展示当前阶段、已完成数量、失败数量、最近更新时间和粗略耗时预期。
- 用户能判断任务是否仍在推进、是否卡住、卡在哪个阶段。
包含范围:
- 后端记录或计算任务阶段:
- 获取热点中
- 搜索内容中
- 抓取评论中
- AI 分析中
- 生成报告中
- 已完成 / 已失败
- 展示当前进度:
- 热点:已获取 / 目标
- 内容:已处理 / 总数
- 评论:已抓取数量
- AI:成功率 / 失败数
- 报告:已生成数量
- 展示任务开始时间、运行时长、最近更新时间。
- 给出非承诺式耗时提示,例如“小规模通常较快,默认规模可能需要数分钟,取决于 TikHub 与 AI 响应速度”。
- 如果一段时间没有进度更新,展示“可能仍在等待外部接口响应”的提示。
边界情况:
- 刚开始运行,热点还没入库。
- 已抓到热点但还没抓到内容。
- 某个内容失败但任务继续。
- 外部接口慢但未超时。
- AI 请求慢。
- Docker 重启导致任务中断。
验收标准:
- 创建任务后,任务详情页能看到阶段和进度数字变化。
- 用户不需要打开日志,也能知道任务大概处于哪个阶段。
- 任务长时间无变化时有提示,不再只显示“正在抓取热点数据,请稍候...”。
- 终态为 success / failed 后停止轮询。
建议 commit
```text
feat: 增强任务进度和运行阶段展示
```
待确认:
- 是否需要显示“预计剩余时间”。如果需要,建议第一版只显示粗略区间,不做精确倒计时,避免误导。
### WO-14 Demo 数据保留与新任务并存体验
优先级:P0
背景:
- 用户希望别人打开后既能看到已经跑通的 demo 数据,又能自己创建任务跑完整流程。
- 当前 `data/` 是本地运行数据,未纳入 Git,不能直接当作可交付 demo 数据方案。
目标:
- 设计一套可控的 demo 数据方案,让页面首次打开就有可展示内容。
- 同时保留用户创建新任务的能力。
可选方案:
| 方案 | 描述 | 优点 | 风险 |
|---|---|---|---|
| A | 保留本机 `data/app.db` 作为本地演示数据库,不提交 Git | 最快,适合自己电脑演示 | 换机器或公网部署时不可复现 |
| B | 提供脱敏 seed 数据脚本,部署时生成 demo 任务 | 可复现,适合交付和公网部署 | 需要额外开发 seed 脚本 |
| C | 提供 demo JSON / fixture,首次启动导入 | 可控、可版本化 | 需要确认哪些真实数据可以脱敏保存 |
包含范围:
- 首页展示 demo 任务和真实新任务。
- 标记 demo 数据来源,避免和真实新任务混淆。
- 提供重置 demo 数据或清空本地任务的说明。
- 确认不提交 API Key、用户隐私、敏感评论作者信息。
边界情况:
- demo 数据和新抓取任务混在同一个任务列表。
- 用户删除或重置数据库后 demo 数据消失。
- 公网部署时没有本地 data 目录。
- 真实评论内容可能包含敏感信息。
验收标准:
- 新用户打开页面能看到可点击的 demo 任务。
- 用户仍能创建新任务并进入运行中状态。
- demo 数据不依赖真实 API Key。
- demo 数据不包含敏感凭证。
建议 commit
```text
feat: 增加可复现 demo 数据
```
待确认:
- demo 数据使用真实抓取结果脱敏,还是使用模拟数据。
- 是否允许在公网演示中展示真实评论文本和作者昵称。
- demo 数据是否需要提供“一键恢复”能力。
### WO-15 公网部署方案与上线验收
优先级:P0
背景:
- 用户明确需要公网部署,而不仅是本机 Docker 访问。
目标:
- 选择并落地公网部署方式,提供可访问 URL。
- 确保环境变量、数据目录、端口、健康检查、重启策略清楚可靠。
包含范围:
- 确认部署目标:
- 云服务器 Docker Compose
- PaaS 平台
- 内网穿透 / 临时演示链接
- 配置环境变量和密钥管理。
- 配置持久化数据目录。
- 配置反向代理或公网端口。
- 配置健康检查和重启策略。
- 更新部署文档。
边界情况:
- API Key 不应暴露在仓库或页面。
- 公网访问可能产生额外抓取成本。
- 多人同时点击创建任务。
- SQLite 在公网多人使用下的并发限制。
- 没有登录权限时,任何知道地址的人都能创建抓取任务。
验收标准:
- 用户可以通过公网 URL 打开首页。
- 公网环境能查看 demo 数据。
- 公网环境能创建至少一个小规模任务。
- 健康检查可访问。
- 重启后数据不丢失,或文档明确说明数据生命周期。
建议 commit
```text
docs: 补充公网部署方案
```
或如果包含实际部署配置:
```text
chore: 增加公网部署配置
```
待确认:
- 部署平台选择。
- 是否需要访问密码 / 简单登录。
- 是否允许公网用户直接消耗真实 TikHub 和 AI Key。
- 是否需要限制同一时间只能运行一个任务。
### WO-16 UI 产品化改版
优先级:P1
背景:
- 用户明确希望后续修改 UI。
- 当前页面主链路可用,但仍需要提升产品化观感。
目标:
- 在不破坏功能的前提下,让首页、任务列表、任务详情、报告页、内容详情页更适合演示。
包含范围:
- 首页信息架构优化。
- 任务列表更像仪表盘。
- 任务详情页突出进度、阶段、失败原因、AI 成功率。
- 热点报告页和内容详情页优化阅读层次。
- 按钮状态更清楚:可点击、加载中、禁用、失败。
- 空状态更友好。
- 移动端基础适配。
边界情况:
- 文本过长。
- 评论列表很多。
- 无报告 / 无评论 / AI 失败。
- 默认规模任务 running 很久。
- 导出按钮不可用。
验收标准:
- 页面不会出现文字重叠、按钮挤压、信息难以扫描。
- 主要 CTA 明确。
- 运行中和失败态清楚。
- UI 改动不影响创建任务、查看报告和导出。
建议 commit
```text
feat: 优化 MVP 页面产品化体验
```
待确认:
- UI 风格方向:更偏数据仪表盘、内部工具,还是偏演示型产品页面。
- 是否需要提供简单品牌名 / Logo / 说明文案。
### WO-17 默认规模数据量解释与展示优化
优先级:P1
背景:
- 默认规模理论值是 `5×5×50=1250` 评论,但真实任务不一定达到。
- 用户判断这更可能是笔记 / 视频本身评论不足,而不是接口错误。
目标:
- 在 UI 和文档中清楚解释“目标上限”和“实际返回”的区别。
- 避免用户看到少于 1250 就误以为任务失败。
包含范围:
- 任务详情页展示:
- 配置目标:5 热点 × 5 内容 × 50 评论
- 实际结果:实际热点、实际内容、实际评论
- 不足原因提示:平台内容 / 评论不足、接口返回不足、部分内容失败
- 报告页展示样本数,避免将样本不足包装成完整全量分析。
- 文档补充默认规模解释。
边界情况:
- 某个热点只有少量内容。
- 某条内容本身评论不足 50。
- API 返回空评论但内容存在。
- 部分内容失败导致评论不足。
验收标准:
- 用户能区分“抓取上限”和“实际抓到数量”。
- 默认规模任务少于 1250 时,页面给出合理说明。
- 真实失败和自然不足有不同提示。
建议 commit
```text
feat: 展示默认规模目标与实际抓取差异
```
待确认:
- 是否需要在报告里显示“样本不足,不代表完整舆情”的提示。
## 14. MVP-2 推荐执行顺序
建议先处理阻塞主链路和演示可信度的问题:
```text
WO-11 全站 500 排查与兜底
WO-12 导出点击失效修复
WO-13 抓取进度透明化
WO-14 Demo 数据方案
WO-15 公网部署
WO-16 UI 产品化改版
WO-17 默认规模数据量解释优化
```
原因:
- 500 和导出失效会直接破坏验收,优先级最高。
- 进度透明化解决“黑盒运行”的核心体验问题。
- Demo 数据和公网部署强相关,应该在部署前明确。
- UI 改版适合在主链路稳定后进行,避免把 bug 和视觉修改混在一起。
## 15. MVP-2 待用户确认问题
以下问题需要用户确认后再进入对应工单开发:
1. 公网部署选择哪种方式:云服务器 Docker Compose、PaaS、还是临时内网穿透演示。
2. 公网访问是否需要密码 / 简单登录。
3. 公网用户是否允许直接消耗真实 TikHub 和 AI Key。
4. Demo 数据使用真实抓取结果脱敏,还是使用模拟数据。
5. 公网 demo 是否允许展示真实评论文本和作者昵称。
6. 评论为空时,CSV 导出是下载只有表头的文件,还是按钮禁用并提示暂无评论。
7. 任务进度是否需要显示预计剩余时间,还是只显示阶段、运行时长和最近更新时间。
8. UI 风格方向:内部数据仪表盘,还是更偏演示型产品页面。