Files
cmshoppe/docs/tasks/T-666.md
T

66 lines
6.3 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.
---
id: T-666
title: 历史批次商品状态重检与更新引导
status: DONE
phase: 7
deps: [T-662a, T-662b, T-662d]
created: 2026-07-18
---
# T-666 历史批次商品状态重检与更新引导
> 后续变更:T-667 已按产品决策移除本任务新增的状态重检入口,改为对商品状态功能上线前的活动历史批次自动默认「架上商品」。本任务保留为历史实现记录。
## 问题 / 背景
商品状态字段在 T-662a 才加入 SQLite。此前已采集、已生成新标题或新封面的历史任务,其 `product_status/product_status_at` 均为 NULL。T-662d 正确地将 NULL 归为状态未知并阻止③更新,避免未经状态确认的商品被提交线上;但③现有提示“回到①重新确认商品状态”无法执行,因为 `CollectWorker` 只处理 `stage=imported`,历史 `stage=generated/applied` 任务不会进入采集 Worker。直接把历史 NULL 批量写成 `normal` 没有页面事实依据,不能作为修复方案。
## 方案
- 在①导入采集增加独立批处理入口「重新检测商品状态」,作用于当前筛选结果中未软删除的任务,允许 `imported/collected/generated/applied/failed/skipped` 等已有阶段参与;运行中禁用与采集相同的筛选及批处理控件。
- 点击后先显示中文确认,明确本次只打开商品详情页读取并保存状态,不读取/覆盖旧标题、旧封面、新标题、新封面,不改变 `stage/status/committed`、Excel、生成结果或线上商品;取消不创建 Worker、不打开 Chrome。
- 新建专用状态重检 Worker/编辑器入口,复用①已验证的账号 Chrome 就绪、登录检测、详情页打开、状态 DOM 读取、自动新建 tab 关闭和诊断日志能力;不得复用会调用 `db.set_collected()` 的完整采集路径。
- 逐条成功时仅调用 `db.set_product_status(task_id, status, note, detected_at)`;保留现有任务阶段、结果、标题、封面、提交标记和 Excel。执行期间及完成后刷新①/②/③表格。
- 技术失败(账号未就绪、登录失败、打开详情页失败、CDP/DOM 异常)不把任务假设为 `normal`,不覆盖已有有效状态快照,不改变任务主流程状态;在本轮运行日志、汇总和本地脱敏诊断中记录失败原因。只有详情页状态读取成功时才写入 `normal/unlisted/reviewing/unknown` 快照。
- ③预检继续严格拦截 `unlisted/reviewing/unknown` 和历史 NULL;禁止新增“强制更新异常商品”或“忽略状态”选项。对原始 `product_status` 为 NULL/空的记录单独显示“尚未检测商品状态”,与已检测但结果为 `unknown` 的“状态未知”分开统计;中止文案明确引导到①「重新检测商品状态」。
- 完成重检后,状态为 `normal` 且更新内容完整的历史生成任务可按现有③预检进入更新;未上架、审核中、真实未知仍保持拦截。①正常采集继续在首次采集时写状态,重检仅补历史/需复核任务,不记忆为全局策略。
- 运行日志使用独立 `run_type=status_recheck` 或等价稳定标识,记录当前范围、状态分类计数、成功/失败/取消数量和示例商品 ID;不记录 Cookie、token 或页面 HTML 明文。
## 验收标准
- [ ] 历史 `generated` 批次的 NULL 状态任务可在①重检,成功后只更新 `product_status/product_status_note/product_status_at/updated_at`,新标题、新封面、阶段、结果、提交标记和 Excel 均不变。
- [ ] ③对未重检的历史 NULL 显示“尚未检测商品状态”并阻止更新;重检为正常后可进入原有标题/封面预检;未上架、审核中、真实未知仍不可更新。
- [ ] 账号、登录、商品页或 DOM 技术失败不会把记录写成正常,也不会覆盖已有有效状态快照或改变主流程状态。
- [ ] 新建 tab 的关闭、复用用户 tab 不关闭、账号就绪逻辑、取消、运行日志和诊断脱敏符合①既有约定。
- [ ] 不新增状态强制更新入口,不改 cmhub、AI生成、封面上传、Excel 回写、CDP 选择器或③真实提交逻辑。
## 测试与文档
- `tests/test_workers.py` 覆盖历史 `generated` 重检、仅状态字段写入、四类状态、技术失败保留旧快照、取消和运行日志汇总。
- `tests/test_gui.py` 覆盖当前筛选范围、确认/取消、控件禁用、Worker 参数、③历史 NULL 与真实未知的不同中文引导、重检后可更新。
- 更新 `docs/routes.md`、`docs/04-architecture.md`、`docs/api.md`;如新增运行日志类型,同步更新 `app/db.py` 的中文显示映射和文档合约。
## 验证
```bash
py -3.10 -m unittest tests.test_workers tests.test_gui tests.test_product_status
py -3.10 -m unittest discover -s tests
py -3.10 -m ruff check app tests main.py
py -3.10 -m compileall app main.py
git diff --check
```
## 非目标
- 不根据历史标题、封面、生成时间或人工猜测把 NULL 自动迁移成 `normal`。
- 不重新下载旧封面、不重新生成内容、不回写 Excel、不改变线上商品、不提供“跳过状态检查后更新”。
## 执行记录
- 新增 `StatusRecheckWorker` 与①「重新检测商品状态」入口:针对当前筛选的历史任务复用账号/登录/只读详情页状态检测,仅成功调用 `db.set_product_status()`;不改任务阶段、处理结果、标题、封面、提交标记或 Excel,并记录独立 `run_type=status_recheck`。
- 新增 `editor.recheck_product_status()`,状态 DOM 读取异常作为技术失败处理,仍按只读 tab 规则关闭本轮自动新建页面;失败保留既有状态快照和主流程字段。
- ③预检将原始 NULL/空状态单列为「尚未检测商品状态」,真实 `unknown` 继续显示「状态未知」,前者直接引导①重检;两类记录均保持安全拦截。
- 已更新 `docs/routes.md`、`docs/04-architecture.md`、`docs/api.md`,并补 worker、GUI、状态规划及编辑器测试。
- 验证通过:`py -3.10 -m unittest discover -s tests`(624 项)、`py -3.10 -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check`。
- 2026-07-20:T-667 替代本任务的产品方案,移除重检入口及专用流程;历史批次改为数据库初始化时按上线时间迁移默认状态。