Files
cmshoppe/docs/tasks/T-662a.md
T

89 lines
4.2 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-662a
title: 商品状态领域模型、数据库迁移与采集检测
status: TODO
phase: 7
deps: []
created: 2026-07-18
---
# T-662a 商品状态领域模型、数据库迁移与采集检测
## 问题 / 背景
编辑页仍可打开的「未上架」「审核中」商品当前会被当作普通商品采集,后续可能继续消耗 AI 点数或进入更新流程。真实证据见:
- `docs/html/未上架商品提示.html`
- `docs/html/审核中商品提示.html`
两份样本均使用 Shopee EDS alert 组件;原「审核中」样本文件名尾部空格已移除,后续文档和测试统一使用无空格路径。
## 状态契约
- 新增共享领域模块 `app/product_status.py`,作为①②③唯一状态事实来源,避免各 Tab 重复定义枚举、显示文字和异常判断。
- SQLite 保存稳定代码,不保存中文枚举:
- `normal`:未发现已知异常横幅;界面显示「正常」,**不宣称一定在售**;
- `unlisted`:未上架;
- `reviewing`:审核中;
- `unknown`:历史 NULL、DOM 检测失败或出现未识别状态横幅。
- `NULL` 和非法历史值统一按 `unknown` 读取;`unlisted/reviewing` 属于异常状态,`normal/unknown` 默认可继续后续流程。
- 文本归一化:trim、连续空白折叠、繁简白名单兼容;禁止依赖 `data-v-*`。
## DOM 检测规则
- 编辑页就绪后一次读取 `.eds-alert.eds-alert--warning` 下的 `.eds-alert-title` 与 `.eds-alert-desc`,返回结构化文本列表,不保存整段 HTML。
- 白名单:
- `審核中` / `审核中` → `reviewing`;
- `您的商品未上架` → `unlisted`。
- 查询成功且没有 warning 横幅 → `normal`。
- 有 warning 横幅但没有白名单命中 → `unknown`,不得保留旧的 `normal` 或误判正常。
- DOM 查询抛错或返回结构非法 → `unknown`,但不使标题/封面采集失败;错误写脱敏诊断日志。
- 多横幅时跳过无关警告,取 DOM 顺序中第一个白名单命中项;没有命中则为 `unknown`。
- `product_status_note` 只保存归一化后的 title/desc 摘要,最多 2000 字符;`product_status_at` 记录本次检测时间。
- 现有 `PRODUCT_UNAVAILABLE_TEXT_MARKERS` 和商品失效 toast 逻辑保持不变。
## 数据模型与采集接入
- `tasks` additive 新增:
- `product_status TEXT NULL`;
- `product_status_note TEXT NULL`;
- `product_status_at TEXT NULL`。
- `db.init_db()` 使用幂等原位迁移;`Task` dataclass 暴露三字段。
- 扩展 `db.set_collected()` 时使用新增 keyword-only 参数,保持现有位置参数调用兼容;标题、封面与商品状态在同一事务写入。
- `editor.collect()` 在同一编辑页会话中读取状态,返回状态快照;CollectWorker 透传到 DB。重新采集覆盖三字段。
- 状态检测失败时仍可成功采集标题/封面,保存 `unknown` 与当前检测时间。
## 验收标准
- [ ] 两份真实样本分别识别为 `unlisted/reviewing`;title 尾部空格与繁简不影响结果。
- [ ] 无 warning 为 `normal`;未知 warning、DOM 异常和非法返回均为 `unknown`。
- [ ] 多横幅共存按约定选择,note 规范化且受长度限制。
- [ ] 旧库迁移幂等,历史 NULL 显示语义为「未知」。
- [ ] 重新采集覆盖状态、note 和时间;检测失败不阻断标题/封面采集。
- [ ] 不改变商品失效判断、Chrome/CDP 页面打开关闭和 Shopee 更新逻辑。
## 测试与文档
- `tests/test_editor_login.py`:样本结构、无横幅、未知横幅、多横幅、异常降级与 collect 回归。
- `tests/test_db.py`:迁移幂等、NULL 语义、keyword-only 写入与重新采集覆盖。
- 更新 `docs/04-architecture.md` 第七节和 `docs/api.md`;登记样本路径、选择器纪律和状态代码。
## 验证
```bash
py -3.10 -m unittest tests.test_editor_login tests.test_db
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
```
## 非目标
- 不识别无样本的售罄、违规、禁卖等状态;未知横幅先归 `unknown`。
- 不新增 GUI,不过滤任务,不回写 Excel,不做定时刷新。
## 执行记录
- 待实现。