docs(tasks): commit T-662a/c/d scope-dialog redesign

Redesign per user requirement: pre-run scope dialogs in ①② replace
the status column/dropdown model; ③ keeps background interception
only. T-662b already landed in previous commit alongside the red
text alignment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
chengma
2026-07-18 16:19:34 +08:00
co-authored by Claude Fable 5
parent 21c72d0d93
commit b4250f36f8
3 changed files with 53 additions and 50 deletions
+13 -9
View File
@@ -26,8 +26,9 @@ created: 2026-07-18
- `unlisted`:未上架;
- `reviewing`:审核中;
- `unknown`:历史 NULL、DOM 检测失败或出现未识别状态横幅。
- `NULL` 和非法历史值统一按 `unknown` 读取;`unlisted/reviewing` 属于异常状态,`normal/unknown` 默认可继续后续流程。
- `NULL` 和非法历史值统一按 `unknown` 读取;只有 `normal` 表示本次检测未发现已知异常,可进入默认的采集、付费生成和更新候选;`unlisted/reviewing/unknown` 均不得被“只处理状态正常商品”策略放行。
- 文本归一化:trim、连续空白折叠、繁简白名单兼容;禁止依赖 `data-v-*`。
- 提供共享纯逻辑 helper,统一完成状态代码归一化、中文显示和任务分组,①②③不得各自复制状态判断。
## DOM 检测规则
@@ -37,7 +38,7 @@ created: 2026-07-18
- `您的商品未上架` → `unlisted`。
- 查询成功且没有 warning 横幅 → `normal`。
- 有 warning 横幅但没有白名单命中 → `unknown`,不得保留旧的 `normal` 或误判正常。
- DOM 查询抛错或返回结构非法 → `unknown`,但不使标题/封面采集失败;错误写脱敏诊断日志。
- DOM 查询抛错或返回结构非法 → `unknown`;错误写脱敏诊断日志。是否继续采集标题/封面由 T-662b 的本轮采集策略决定,状态探测本身不直接制造技术失败。
- 多横幅时跳过无关警告,取 DOM 顺序中第一个白名单命中项;没有命中则为 `unknown`。
- `product_status_note` 只保存归一化后的 title/desc 摘要,最多 2000 字符;`product_status_at` 记录本次检测时间。
- 现有 `PRODUCT_UNAVAILABLE_TEXT_MARKERS` 和商品失效 toast 逻辑保持不变。
@@ -49,9 +50,10 @@ created: 2026-07-18
- `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` 与当前检测时间。
- 新增独立、幂等的商品状态写入 API,使标题/封面被采集策略略过时仍能保存状态、note 和检测时间;扩展 `db.set_collected()` 时使用新增 keyword-only 参数,保持现有位置参数调用兼容。
- 编辑器提供可复用的商品状态探测步骤,并保证在读取标题、下载封面之前完成;完整采集成功时,标题、封面和本次状态快照在同一事务写入。
- 每次重新采集都必须重新打开页面检测状态,不得依据数据库旧快照提前略过,否则商品恢复正常后无法刷新状态。
- 状态探测返回 `unknown` 时保存当前快照;是否继续读取标题和封面由 T-662b 传入的本轮策略决定。
## 验收标准
@@ -59,13 +61,15 @@ created: 2026-07-18
- [ ] 无 warning 为 `normal`;未知 warning、DOM 异常和非法返回均为 `unknown`。
- [ ] 多横幅共存按约定选择,note 规范化且受长度限制。
- [ ] 旧库迁移幂等,历史 NULL 显示语义为「未知」。
- [ ] 重新采集覆盖状态、note 和时间;检测失败不阻断标题/封面采集。
- [ ] 只写商品状态时不伪造“采集成功”,也不清空既有标题和封面;完整采集可原子写入内容和状态。
- [ ] 重新采集始终重新检测并覆盖状态、note 和时间,不根据旧快照预过滤。
- [ ] 不改变商品失效判断、Chrome/CDP 页面打开关闭和 Shopee 更新逻辑。
## 测试与文档
- `tests/test_editor_login.py`:样本结构、无横幅、未知横幅、多横幅、异常降级与 collect 回归。
- `tests/test_db.py`:迁移幂等、NULL 语义、keyword-only 写入与重新采集覆盖。
- `tests/test_product_status.py`:状态归一化、中文显示、正常与非正常分组。
- `tests/test_editor_login.py`:样本结构、无横幅、未知横幅、多横幅、异常降级、探测顺序与 collect 回归。
- `tests/test_db.py`:迁移幂等、NULL 语义、独立状态写入、keyword-only 写入、既有内容保留与重新采集覆盖。
- 更新 `docs/04-architecture.md` 第七节和 `docs/api.md`;登记样本路径、选择器纪律和状态代码。
## 验证
@@ -80,7 +84,7 @@ git diff --check
## 非目标
- 不识别无样本的售罄、违规、禁卖等状态;未知横幅先归 `unknown`。
- 不识别无样本的售罄、违规、禁卖等状态;未知横幅先归 `unknown`,不得猜测为正常。
- 不新增 GUI,不过滤任务,不回写 Excel,不做定时刷新。
## 执行记录
+25 -23
View File
@@ -1,45 +1,46 @@
---
id: T-662c
title: AI生成异常商品默认排除与强制生成确认
title: AI生成范围确认与异常商品点数保护
status: TODO
phase: 7
deps: [T-662a]
created: 2026-07-18
---
# T-662c AI生成异常商品默认排除与强制生成确认
# T-662c AI生成范围确认与异常商品点数保护
## 问题 / 背景
未上架、审核中商品默认继续进入②会消耗 cmhub 点数。②当前点击「开始生成」会直接创建 `GenerateWorker`,没有通用生成确认框,因此不能把不存在的确认流程写成现状。
未上架、审核中或状态未知商品进入②会消耗 cmhub 点数。客户需要在每轮付费生成前明确选择范围,并让安全选项始终成为默认值;采集时选择“所有状态”只代表保存资料,不能自动授权后续扣点。
## 方案
- 现有「状态」标签改为「任务状态」,新增独立「商品状态」下拉,**放在「任务状态」label 左边**(需求定稿位置):
- `可生成(默认)`:`normal/unknown`;
- `全部`;
- `正常/未上架/审核中/未知`。
- 选项术语与平台原文对齐:「审核中」不用「未审核」、「未知」不用「其他」;默认档为复合的「可生成」而非单选「正常」,否则升级后历史批次(全为未知)会被整批拦住。
- 保留商品状态筛选前的基础范围快照,用于摘要计算,避免异常记录从模型隐藏后无法统计。
- 默认模式不把 `unlisted/reviewing` 传给 `GenerateWorker`,不创建 AI 请求、不消耗点数、不改 stage/status/Excel;摘要、状态栏和本轮日志说明排除数量及示例商品ID。
- `unknown` 默认可生成,避免历史数据和临时检测失败被整批拦住。
- 用户切换「全部」「未上架」或「审核中」后,如果本轮确实包含异常商品,弹一次中文高风险确认,列出数量、状态、示例商品ID和可能产生点数;默认取消。确认后才允许异常商品进入 worker。
- 正常任务不新增通用确认弹窗,保持现有一键开始流程。
- UI 可见筛选范围与最终 worker 列表必须分别记录;确认期间数据变化则取消旧计划并要求重新开始。
- 本任务不新增商品状态列或下拉框。点击「开始生成」后,先按现有批次、店铺、商品ID、任务状态、生成内容模式和“缺什么生成什么”规则构造真实候选;候选为空时保持现有提示,不弹范围框。
- 候选存在时按 T-662a 状态代码分组,弹出中文生成范围对话框:
- `只生成状态正常的商品`:默认按钮,仅包含 `normal`;
- `生成所有状态的商品`:红色文字,包含 `normal/unlisted/reviewing/unknown`;
- `取消`:不创建 Worker、不调用 cmhub、不产生点数和 DB 变化。
- 弹窗展示本轮真实候选总数及正常、未上架、审核中、未知数量;说明“生成所有状态”会让非正常状态商品也调用 AI,可能额外消耗点数。示例商品ID数量受限,日志不得泄露接口路径或密钥。
- 若现有价格目录能依据本轮生成标题/图片模式可靠计算,则显示“预计最多消耗 X 点”;无法可靠计算时只显示风险说明,不编造点数。
- 默认焦点和回车只允许触发“只生成状态正常的商品”;红色选项不能成为默认按钮,不记忆危险选择。没有非正常候选时禁用“生成所有状态的商品”。
- `normal_only` 下,`unlisted/reviewing/unknown` 不进入 `GenerateWorker`,不创建 cmhub 请求、不消耗点数、不改 stage/status/Excel;历史 NULL 按 `unknown` 排除并提示重新采集。
- `all` 只授权本轮付费生成,不改变数据库商品状态,也不授权③更新线上商品。
- 使用共享纯逻辑 planner 输出 `base_candidates/status_counts/execution_tasks`;计划冻结字段至少包含 `task_id/updated_at/product_status/new_title/new_cover_path/生成内容模式`。弹窗期间相关数据变化时废弃旧计划并要求重新开始。
- Worker 接收确认后的精确任务列表和稳定范围代码 `normal_only/all`;本轮日志记录所选范围、排除统计和实际入队数量,正常模式下非正常商品不得通过其他入口绕过预检。
## 验收标准
- [ ] 默认可生成模式排除未上架/审核中,正常和未知仍可生成。
- [ ] 默认排除记录不产生 worker 任务、cmhub 请求、点数或 DB 状态变化。
- [ ] 摘要与日志即使在异常记录被隐藏时仍能显示排除数量。
- [ ] 显式显示异常状态后,只有确认才可强制生成;取消不执行。
- [ ] 正常批次不增加额外弹窗;停止、进度、重试与现有增量生成不回归。
- [ ] 商品状态筛选与批次、店铺、商品ID、任务状态叠加正确。
- [ ] 真实候选为空时不弹范围框;有候选时弹窗数量与最终入队任务一致。
- [ ] 默认按钮、回车和普通确认只生成 `normal`;未上架、审核中、未知和历史 NULL 均不产生 cmhub 请求或点数。
- [ ] “生成所有状态”使用红色文字、非默认且不跨轮记忆;只有本轮明确选择后才能把非正常候选加入 Worker。
- [ ] 取消不创建 Worker、不调用 cmhub、不改 DB;计划数据变化时不能执行旧计划。
- [ ] 无非正常候选时危险按钮不可用;弹窗和日志使用中文并正确展示状态统计与可用的点数估算。
- [ ] 停止、进度、重试、增量生成、只生成标题/图片/图文和并发逻辑不回归。
## 测试与文档
- 纯逻辑 helper 覆盖默认排除、未知放行和显式包含。
- `tests/test_gui.py` 覆盖隐藏统计、强制确认、取消、worker 列表、点数不消耗边界和运行态。
- 纯逻辑 planner 覆盖四种状态、历史 NULL、两种范围、候选去重、点数估算和计划指纹。
- `tests/test_gui.py` 覆盖无候选、中文弹窗、默认焦点、回车、危险按钮样式/禁用、取消、数据变化、Worker 精确列表和点数不消耗边界。
- 更新 `docs/routes.md`、`docs/04-architecture.md` 和 `docs/api.md`。
## 验证
@@ -54,7 +55,8 @@ git diff --check
## 非目标
- 不修改 AI 接口、价格目录、并发、重试或普通任务的启动交互。
- 不修改 AI 接口、价格目录、并发和重试;不新增商品状态筛选控件。
- 不把“生成所有状态”视为线上更新授权。
## 执行记录
+15 -18
View File
@@ -1,45 +1,42 @@
---
id: T-662d
title: 更新蝦皮异常商品过滤与T-659预检整合
title: 更新蝦皮商品状态后台拦截与T-659预检整合
status: TODO
phase: 7
deps: [T-662a, T-659]
created: 2026-07-18
---
# T-662d 更新蝦皮异常商品过滤与T-659预检整合
# T-662d 更新蝦皮商品状态后台拦截与T-659预检整合
## 问题 / 背景
③需要在更新内容预检之外处理商品状态。商品状态是采集快照,不能取代 Shopee 执行时校验;同时「显示全部」只是查看范围,不能被误当成更新异常商品的授权。
③属于线上写操作。即使用户在①选择采集所有状态,或在②明确选择生成所有状态,也不能把该选择继承为线上更新授权。商品状态是采集快照,不能取代 Shopee 执行时校验,但已知非正常状态必须在创建 `ApplyWorker` 前被拦截。
## 方案
- 现有「状态」标签改为「任务状态」,新增独立「商品状态」下拉,**放在「任务状态」label 左边**(需求定稿位置):
- `可更新(默认)`:`normal/unknown`;
- `全部`;
- `正常/未上架/审核中/未知`。
- 选项术语与平台原文对齐:「审核中」不用「未审核」、「未知」不用「其他」;默认档为复合的「可更新」而非单选「正常」,未知默认放行,避免历史批次被整批拦住。
- 保留商品状态筛选前的基础范围快照,显示默认排除数量;即使表格隐藏异常记录,也能在摘要/确认中说明。
- 无论商品状态筛选选择什么,`unlisted/reviewing` 都不得传入 `ApplyWorker`;「全部」只用于查看,不构成强制线上更新授权。
- 扩展 T-659 结构化预检结果,分别保存:可执行、缺标题、缺封面、未上架、审核中;同一任务只计一次总跳过,但各原因统计可分别展示。
- 本任务不新增商品状态列、下拉框或“强制更新异常商品”入口;现有批次、店铺、商品ID、任务状态和更新内容模式保持不变。
- 扩展 T-659 结构化预检,先按共享状态 helper 分组,再检查标题/封面完整性:只有 `normal` 可进入可执行集合;`unlisted/reviewing/unknown`(含历史 NULL)全部从正式更新和 dry-run 的 Worker 列表剔除。
- 预检结果分别保存:可执行、缺标题、缺封面、未上架、审核中、状态未知;同一任务只计一次总跳过,但各原因统计可分别展示。明确原因优先级,保证汇总去重稳定。
- 确认框、状态栏与本轮日志显示异常状态排除数量、分类和示例商品ID。预检排除记录不计入 worker 的成功/略过/失败,不改 stage/status/Excel。
- 内容缺失和商品异常全部剔除后没有可执行任务时,按真实主因显示中文中止文案;全部异常时不得误报「更新内容未生成」。
- 「检查本轮更新」与正式更新使用同一计划;用户确认期间筛选或数据变化时废弃旧计划。
- `unknown` 默认允许更新;现有商品失效 toast、页面校验、账号预检和 T-659 内容校验继续作为执行层防线。
- 不能先因当前模型任务为空而返回通用文案;必须先读取商品状态筛选不存在时的当前基础范围并执行预检,确保全异常批次得到真实中止原因。
- 「检查本轮更新」与正式更新使用同一 planner 和计划指纹;用户确认期间 `task_id/updated_at/product_status/new_title/new_cover_path/更新模式` 变化时废弃旧计划。
- ①②弹窗选择仅影响各自本轮,③不读取或继承其范围策略。现有商品失效 toast、页面校验、账号预检、最终中文确认和 T-659 内容校验继续作为执行层防线。
## 验收标准
- [ ] 默认可更新模式排除未上架/审核中,正常和未知可进入内容预检。
- [ ] 切换「全部」能查看异常记录,但开始更新和 dry-run 仍剔除异常商品。
- [ ] 确认框正确合并内容缺失与商品状态原因,同一任务总数不重复。
- [ ] 未上架、审核中、未知和历史 NULL 均不能进入正式更新或 dry-run Worker;只有 `normal` 可继续内容预检。
- [ ] ①采集所有状态或②生成所有状态不会授权③更新非正常商品。
- [ ] 确认框正确合并内容缺失与三类商品状态原因,同一任务总数不重复。
- [ ] 全异常时显示商品状态中止原因;全缺内容时仍保持 T-659 文案。
- [ ] 被排除记录不进入 `ApplyWorker`,DB、Excel 和本轮 worker 统计不变。
- [ ] T-659 三种更新模式、账号就绪、分批、停止和真实更新确认不回归。
## 测试与文档
- `tests/test_gui.py` 覆盖默认排除、显示全部、原因去重、全异常中止、dry-run 一致性和 T-659 回归。
- 纯逻辑 planner 覆盖四类状态、历史 NULL、原因优先级、去重和计划指纹。
- `tests/test_gui.py` 覆盖状态硬拦截、全异常中止、内容缺失合并、确认期数据变化、dry-run 一致性和 T-659 回归。
- 更新 `docs/routes.md`、`docs/04-architecture.md` 和 `docs/api.md`。
## 验证
@@ -54,7 +51,7 @@ git diff --check
## 非目标
- 不根据采集快照自动修改蝦皮商品状态,不提供异常商品强制更新入口,不做实时状态刷新。
- 不新增商品状态 UI,不根据采集快照自动修改蝦皮商品状态,不提供非正常商品强制更新入口,不做实时状态刷新。
## 执行记录