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

69 lines
4.8 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-704
title: 兼容用户历史已处理任务的空商品状态
phase: 7
deps: [T-667, T-673]
status: DONE
created: 2026-07-27
---
# T-704 兼容用户历史已处理任务的空商品状态
## 问题 / 背景
商品状态字段上线前的用户数据可能继续保存在旧安装目录中,也可能在新版中重新导入。T-667 只按固定上线时间判断 `batches.created_at`,因此批次时间晚于该阈值、但任务已经采集或生成过内容的记录仍可能保持空 `product_status`。③「更新蝦皮」会把这些记录归为状态未知并全部拦截,用户无法继续使用已有新标题或新封面。
不能在③临时放宽空状态,也不能把所有空状态都视为架上商品,否则刚导入、尚未采集的记录会绕过商品状态安全边界。
## 方案
- 在 `db.init_db()` 增加第二层幂等兼容迁移,不再依赖批次创建时间,而是识别记录本身是否已有处理证据。
- 仅迁移活动批次、未软删除、`product_status` 为 NULL/空白,并满足以下任一条件的任务:
- `stage` 已进入 `collected/generated/applied`;
- `collected_at/generated_at/applied_at` 任一非空;
- `old_title/old_cover_path/new_title/new_cover_path` 任一存在有效内容。
- 命中后写入 `product_status=normal`、历史默认备注,保留 `product_status_at=NULL`,只更新 `updated_at`;不改阶段、处理结果、标题、封面、提交标记、Excel 或线上商品。
- 迁移前仅在存在真实候选且使用文件数据库时,通过 SQLite 一致性备份写入数据库同级 `backups/` 目录;内存数据库不创建备份。迁移在事务中完成,重复启动不重复改写,也不重复备份。
- 已保存的 `normal/unlisted/reviewing/unknown` 一律不覆盖;刚导入且没有任何采集、生成、更新证据的空状态任务继续保持拦截。
- ③预检和 `ApplyWorker` 仍只允许 `product_status=normal`,不新增“忽略商品状态”或人工修数据入口。
## 验收要点
- [x] 用户保留旧 `data/cmshopee.db` 后启动新版,批次日期晚于原固定阈值、但已有采集/生成/更新证据的空状态任务自动变为历史默认 `normal`。
- [x] 迁移前生成可打开的一致性数据库备份;重复初始化后不再新增备份,不重复修改 `updated_at`。
- [x] 仅 `stage=imported` 且没有标题、封面或阶段时间证据的空状态任务不迁移,③仍阻止更新。
- [x] 显式 `unknown/unlisted/reviewing/normal`、已软删除任务及已软删除批次不改动。
- [x] 迁移后的已生成记录可按既有标题/封面完整性规则进入③更新预检,不绕过内容完整性、账号登录或线上确认。
- [x] 不打开 Chrome、不访问商品页、不调用 AI、不修改 Excel、不提交线上商品。
## 测试与文档
- `tests/test_db.py` 覆盖晚于上线时间的处理证据、未处理导入记录、显式状态、软删除、备份及重复初始化。
- `tests/test_product_status.py` 或数据库测试覆盖迁移后③更新计划仍只接受正常且内容完整的任务。
- 更新 `docs/04-architecture.md` 与 `docs/api.md` 的历史商品状态兼容契约。
## 验证
```bash
py -3.10 -m unittest discover -s tests -p "test_db.py"
py -3.10 -m unittest discover -s tests -p "test_product_status.py"
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
```
## 边界(不改什么)
- 不把所有空商品状态全局解释为正常。
- 不恢复已移除的「重新检测商品状态」按钮。
- 不修改商品状态 DOM 识别、CDP、封面上传、更新确认或订阅逻辑。
## 执行记录
- `db.init_db()` 新增 T-704 幂等迁移:活动且未软删除的空商品状态任务,只在已有业务阶段、阶段时间或任一新旧标题/封面证据时写历史默认 `normal`;批次创建时间不再是这层兼容的判断依据。
- 文件数据库存在真实候选时,迁移前通过 SQLite backup API 在数据库同级 `backups/` 创建一致性备份;迁移成功后候选消失,重复启动不再备份或改写。
- 显式商品状态、未处理导入记录、软删除任务和软删除批次保持不变;③计划与 Worker 的 `normal` 防线未放宽。
- 更新架构/API 文档,并调整两处旧 GUI 测试,使异常状态场景使用显式 `unknown/reviewing`,不再把“已生成但状态为空”当作未迁移状态。
- 验证通过:`py -3.10 -m unittest discover -s tests -p "test_db.py"`(22 项)、`py -3.10 -m unittest discover -s tests -p "test_product_status.py"`(7 项)、`py -3.10 -m unittest discover -s tests`(703 项)、`py -3.10 -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check`。