docs(tasks): split AI studio implementation plan

This commit is contained in:
chengma
2026-07-11 11:10:43 +08:00
parent 1a2e010997
commit 9e4a6def92
12 changed files with 568 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
---
id: T-586
title: AI工场数据地基:项目、图片资产、异步任务与终选顺序 SQLite 模型
phase: 7
deps: [T-538]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
⑥ AI工场需要同时管理多个账号/商品、蝦皮原图、迭代生成图、多个在途 cmhub task、主图/详情图终选顺序和重启续查。只靠 `data/images/pool/<slug>/<item_id>/` 文件名无法可靠恢复来源、任务状态和排序,因此采用“SQLite 保存状态事实、目录保存图片字节”。完整产品口径见 Obsidian《图片精修-主图详情图生成方案》和 `docs/ui/tab6-ai-studio-v3.svg`。
## 方案
- `app/db.py` 增加 ad-hoc 兼容迁移和数据对象:
- `image_studio_projects`:账号、商品 ID、目标主图数/详情数、草稿提示词、项目状态、软删除/时间字段;同一账号+商品唯一。
- `image_studio_assets`:项目、类别(原图/生成主图/生成详情图)、远程 URL、本地路径、比例、父资产、生成提示词、可用/缺失状态。
- `image_studio_jobs`:资产候选、生成来源、task key/id、Provider、类型、状态、错误、重试和时间字段。
- `image_studio_selections`:项目、`main/detail`、连续 position、asset;类别+位置唯一,同一资产在同类别唯一。
- 新增独立 service 模块(命名按实现确定)封装 CRUD、事务排序、路径计算和状态转换,GUI 不直接写 SQL。
- 图片目录固定在 `data/images/pool/<slug>/<item_id>/{originals,generated,exports}/`,所有路径继续通过 `appconfig` 从 `data/` 解析。
- 数据写入顺序保证崩溃可恢复:先建 job/key,submit 后立即写 task_id,图片完整落盘后才创建/启用 asset。
## 验收要点
- 历史 DB 启动可自动补表/索引且不影响既有 tasks/batches/accounts。
- 同账号+商品重复创建返回已有项目;不同账号可绑定不同商品项目。
- 资产来源、父资产、比例和本地路径可完整读回;文件缺失可标记但不物理删记录。
- job 支持 `pending/submitted/running/succeeded/failed` 及 task key/id 生命周期,重启后可列出待续查任务。
- 终选位置连续、并发写入事务安全、同资产同类别不重复;允许同资产各出现一次 main/detail。
- 纯逻辑测试覆盖迁移、唯一约束、CRUD、状态转换、排序和路径隔离;运行全量 unittest、ruff、compileall、`git diff --check`。
## 边界(不改什么)
- 不做 GUI、CDP、网络下载、AI 请求、导出或蝦皮写操作。
- 不把图片 BLOB 写 SQLite,不采用目录扫描猜状态。
- 不提供本地图片导入,不物理删除项目历史。
## 执行记录
(完成后记录实现文件、迁移决策与验证结果。)
+39
View File
@@ -0,0 +1,39 @@
---
id: T-587
title: AI工场商品项目入口与 CDP 只读拉取蝦皮原主图 URL
phase: 7
deps: [T-586, T-563]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
AI工场以“账号 + 商品 ID”建立项目,并从该账号 Chrome 的商品详情页只读取得全部主图 URL。该流程必须复用已验证 CDP、登录检测、商品失效 toast 和 tab 清理纪律,不能另写页面选择器或修改蝦皮商品。
## 方案
- 新增项目入口服务:校验账号、商品 ID 和重复项目;重复时打开已有项目。
- 抽取/复用 `app.editor` 图片列表读取能力,返回有序 `{src, index}`,不要求上传 input,不下载图片、不改标题/图片。
- 按①采集的只读边界确保账号 Chrome 就绪:已打开复用,未打开才启动;只检测登录,不自动登录、不填密码。
- 商品页后台打开,不主动抢焦点;只关闭本轮自动新建 tab,复用用户已有 tab 不关闭。
- 详情页失效、无权限、未登录、CDP 超时继续上浮结构化中文原因和 Shopee 原始 toast。
- 抓取结果写项目的原图 URL 快照,刷新时按 URL/顺序更新,不创建本地 asset,下载留给 T-588。
## 验收要点
- mock 覆盖已开 Chrome 复用、未开启动、明确未登录、暂时不确定登录、商品失效和成功读 1..9 张 URL。
- 成功路径不调用标题修改、文件上传、拖拽或更新提交。
- URL 顺序与蝦皮主图顺序一致;重复刷新幂等。
- 新建失败 tab 清理、复用 tab 保留;`bring_to_front=False`。
- 涉及 CDP 变更时同步 `docs/04-architecture.md` 并在测试商品做只读实跑;不点击更新。
## 边界(不改什么)
- 不下载/显示图片,不做照片池 GUI,不写蝦皮。
- 不更改现有①采集和③更新行为。
- 不绕过登录、验证码、风控或权限检查。
## 执行记录
(完成后记录 mock、只读实跑与 tab 清理结果。)
+38
View File
@@ -0,0 +1,38 @@
---
id: T-588
title: AI工场远程缩略图与蝦皮原图进入照片池
phase: 7
deps: [T-587, T-546]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
拉取商品后要低成本浏览远程主图:缩略图只进内存,用户单击才下载原图落照片池。网络请求不能卡 GUI,失败不能阻断其他缩略图,也不能因为显示缩略图就把全部原图写盘。
## 方案
- 实现异步缩略图 loader(QNetworkAccessManager 或受控线程池+signal),含内存缓存、并发上限、取消、单图重试和占位状态。
- 实探并记录 Shopee CDN 缩略图尺寸后缀、Referer、Content-Type 和重定向事实;不可用时安全回退原 URL 的受限读取。
- 复用现有无系统代理、安全超时、大小上限和图片解码校验;只允许 http/https、公网地址。
- 单击蝦皮原图时下载原图到 `originals/`,先写临时文件并校验解码,再原子替换目标并创建原图 asset;重复单击幂等。
- 明确不增加“导入本地图片”入口;照片池来源仅蝦皮原图和后续 AI 生成图。
## 验收要点
- 缩略图加载不在 GUI 主线程,不落盘;单图失败/超时显示中文状态且其他图继续。
- 缓存命中不重复请求;切项目或关闭窗口可取消未完成加载。
- 单击后原图真实落盘、asset 可用;失败不留下半文件或可用 asset。
- 非图片、超限、内网 URL、坏图片和重定向边界有测试。
- CDN 两项事实有真实探查记录,测试不依赖公网。
## 边界(不改什么)
- 不做 AI 生成、终选、导出或蝦皮写操作。
- 不自动下载全部原图,不加入本地图片导入。
- 不在日志记录 Cookie、带敏感查询串的完整 URL 或图片字节。
## 执行记录
(完成后记录 CDN 实探、缓存和下载验证。)
+37
View File
@@ -0,0 +1,37 @@
---
id: T-589
title: AI工场独立提示词模板数据层与完整 CRUD
phase: 7
deps: [T-583]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
AI工场只有一个完整提示词框,不再区分“主提示词/每张动作词”,但需要较窄模板下拉和“新建、重命名、保存、删除”。模板不能与②封面模板混用,避免不同业务语义互相覆盖。
## 方案
- `appconfig` 增加 `image_studio_prompts_dir()`,固定为 `data/prompts/image_studio/`。
- 复用 T-583 通用模板 CRUD,不复制另一套文件名校验、重名保护或删除逻辑。
- 新建输入不重复名称;重命名只改名;保存把当前完整文本写入选中模板;删除二次确认。
- 不解析模板内容、不拆段、不按行生成;模板只是把完整文本载入编辑框。
- 当前项目草稿提示词由 T-586 项目字段保存,选择模板只覆盖编辑框/草稿,不自动改历史 job。
## 验收要点
- AI工场模板与标题/封面模板目录完全隔离,CRUD 和中文错误完整。
- 空名、非法路径、重名、目标不存在、删除最后模板均有确定行为。
- 选择模板返回原始完整文本;换行不触发任务拆分。
- 测试只用临时目录,不写真实 data;通用模板既有测试不回归。
## 边界(不改什么)
- 本任务只做路径/数据层,不做 GUI 和 AI 请求。
- 不复制②模板 CRUD,不引入本地图片或提示词自动补写。
- 不把 AI工场模板打成②封面模板的别名。
## 执行记录
(完成后记录模板路径、复用点和测试结果。)
+40
View File
@@ -0,0 +1,40 @@
---
id: T-590
title: AI工场托管模式多图异步生成编排与重启续查
phase: 7
deps: [T-586, T-564]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
AI工场一次可生成 N 张,且每张都要独立计费、失败、重试、停止和续查。T-564 只为普通 tasks 表的一张封面保存一组 task_id/key,不能承载同商品多轮、多源图、多候选任务,需要把 cmhub submit/poll/download 能力复用到 image_studio_jobs。
## 方案
- 抽取可复用的 cmhub 异步生图客户端/服务,以持久化回调或 job repository 注入 task key/id;既有②路径行为保持兼容。
- 对同一源 asset 和同一完整提示词创建 N 条 job:一次调用一张,不按行拆词、不自动补动作、不保证去重。
- 每条 job 在 submit 前落稳定 key,202 后立即落 task_id;poll 成功下载校验后创建 generated asset,记录 main/detail、比例、父 asset、提示词和计费元数据。
- 并发沿用当前最大 5 的 submit+poll/下载双池保护;逐条事件回调供 GUI 显示。
- 停止不删除已提交任务:未开始 job 取消,已提交 job 停止等待并保留 task_id,下次继续查询。
- 本任务只实现 cmhub 托管来源;数据结构预留 `generation_source/provider`,自定义模型由 T-594 解锁。
## 验收要点
- N=3 产生 3 个不同 job/key/task,使用完全相同 prompt/source;每个成功独立进池。
- submit 响应后、poll 前 task_id 已落库;重启续查不再次 POST、不重复扣点。
- 单张失败不回滚成功图;下载失败不重新提交生成。
- 停止、总预算超时、服务端 failed/expired、幂等冲突和点数不足生命周期正确。
- 计费事件按 job 记录;全程不阻塞 GUI 主线程。
- 既有② AI生成 T-564 路径全量测试不回归。
## 边界(不改什么)
- 不做 BYOK、自定义 Provider、自动去重或自动重生成。
- 不做 GUI、终选、导出、CDP 或蝦皮写操作。
- 不改变 cmhub 单次调用一张、预扣/失败退点契约。
## 执行记录
(完成后记录抽取边界、任务生命周期和回归测试。)
+41
View File
@@ -0,0 +1,41 @@
---
id: T-591
title: ⑥ AI工场主界面、照片池、大图预览与生成控制
phase: 7
deps: [T-588, T-589, T-590]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
需要把已完成的数据、拉图、模板和生成服务接入第六个 Tab。当前视觉口径是 `docs/ui/tab6-ai-studio-v3.svg`:左商品轨、中照片池、右生成设置、底部终选盘;本任务先完成主界面和照片池/生成,不实现终选拖放与导出细节。
## 方案
- 主窗口新增 `⑥ AI工场`,不缩小既有 Tab 可点击区域;更新必要的 routes/架构 UI 文档。
- 左轨支持项目切换/新增,顶部显示当前账号+商品、拉取主图、打开项目文件夹。
- 原主图抽屉异步显示;单击加入池,双击大图。
- 照片池显示原/主/详角标、比例、排队/生成/失败状态;单击设源图、双击大图、右键移除(引用中/任务中禁用并说明)。
- 右侧使用单一提示词框和较窄模板下拉,按钮为新建/重命名/保存/删除;程序不显示“主提示词/每张动作词”label。
- 类型、数量、比例、生成来源和计费区域按 v3;T-594 前自定义来源隐藏或明确禁用,不伪装可用。
- 所有网络/CDP/AI/图片解码走 worker/QThread 或异步 Qt API,主线程只更新 UI。
## 验收要点
- 六个 Tab 顺序和中文文案正确,在 1180×760、960×640 及 Windows 缩放下无重叠/截断。
- 任意原图/池图双击打开大图;单击仍执行区域业务动作,不冲突。
- 合并提示词、模板 CRUD、源图选择、N 张生成、停止、进度和逐图失败可用。
- 切项目不会串图片/任务/提示词;运行中关键控件禁用并可安全恢复。
- 不存在“导入本地图片”按钮或隐藏入口。
- GUI offscreen 测试覆盖 objectName、布局结构、信号和状态;人工截图与 SVG 对照。
## 边界(不改什么)
- 不实现终选拖放排序(T-592)、导出(T-593)或 BYOK(T-594)。
- 不自动上传蝦皮,不增加本地图片导入。
- 不在 widget 槽函数直接写 SQL 或做网络请求。
## 执行记录
(完成后记录 GUI 文件、视口截图和测试。)
+39
View File
@@ -0,0 +1,39 @@
---
id: T-592
title: AI工场主图/详情图终选拖放、插入排序与比例轻提示
phase: 7
deps: [T-591]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
照片池是候选集合,导出需要有序的主图和详情图集合。终选必须支持从池拖入、落在占用槽时插入顺延、槽内重排、移出终选和跨类别复用,同时保证数据库与 UI 顺序一致。
## 方案
- 底部全宽终选盘显示目标和当前数量,默认主图 9、详情 12,目标可配置。
- 从池拖到空槽直接放入;拖到占用槽按位置插入并顺延;满额时拒绝超出并提示。
- 槽内拖动原子重排;Delete/右键只移出终选,不删除 pool asset。
- 同一 asset 在同类别最多一次,可同时各用于一次 main/detail。
- 主图/详情图推荐比例不匹配显示黄色边框+tooltip,不硬拦。
- 所有槽位保持连续,无中间空洞;双击槽图查看大图。
- 使用 T-586 service 事务更新 selection,拖放失败时 UI 回滚到 DB 顺序。
## 验收要点
- empty insert、occupied insert+shift、same-list reorder、remove、满额和重复拖入均有测试。
- 跨 main/detail 允许,同类别重复拒绝;比例提示不阻止保存。
- 重启后顺序与退出前一致;并发/异常不产生重复 position 或空洞。
- 运行中图片尚未可用时不能拖入;文件缺失资产有明确禁用状态。
## 边界(不改什么)
- 不导出文件、不删除照片池资产、不上传蝦皮。
- 不自动裁剪、转比例或替用户决定主图/详情图。
- 不实现撤销历史;失败只恢复当前持久化顺序。
## 执行记录
(完成后记录拖放模型、事务和 GUI 测试。)
+42
View File
@@ -0,0 +1,42 @@
---
id: T-593
title: AI工场部分导出、JPEG 转码与已存在商品目录安全处理
phase: 7
deps: [T-592]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
用户可在主图/详情图未满目标数量时导出当前终选。导出要让用户选择父目录,再创建商品 ID 子目录;目标已存在不能简单合并,否则旧序号图片会残留,也不能递归清空可能包含用户文件的目录。
## 方案
- 点击导出用目录选择框选父目录,在其下创建 `<商品ID>/`。
- 按连续终选顺序实际转码并写:`商品ID_主图_1.jpg`、`商品ID_详情图_1.jpg`;质量沿用应用图片质量设置,透明图按已验证规则铺白底。
- 主/详情总数为 0 禁止;其他未满组合均允许,确认框显示 X/目标数。
- 导出前预检全部源文件和解码,使用 staging 写完整后再发布,失败不留下半套结果。
- 目标目录存在时只提供:
- 覆盖本软件导出的图片:仅匹配当前商品命名规则的旧主图/详情图文件,保留其他文件;默认仍需确认。
- 新建带时间目录:`商品ID_YYYYMMDD_HHMMSS/`。
- 取消(默认)。
- 不提供合并;成功后提示实际路径和数量,并提供打开目录。
## 验收要点
- 只主图、只详情、两类部分、满额和零图片场景均正确。
- PNG/WebP 真正输出可解码 JPEG,不是改后缀;序号与终选顺序一致。
- 已存在目录三选正确;覆盖只删除受管命名文件,用户其他文件保持字节不变。
- 某源图缺失/损坏时导出前失败,原目标不被部分改写。
- 路径穿越、非法商品 ID、只读目录、同秒时间目录冲突和文件锁有中文错误。
## 边界(不改什么)
- 不递归清空用户选择目录,不提供合并。
- 不要求达到 9/12,不上传或修改蝦皮。
- 不导出原始任务密钥、提示词、日志或 SQLite 数据。
## 执行记录
(完成后记录文件安全测试和人工导出验证。)
+46
View File
@@ -0,0 +1,46 @@
---
id: T-594
title: AI工场自定义模型(BYOK)授权代理与异步生图接入
phase: 7
deps: [T-590]
status: BLOCKED
created: 2026-07-11
---
## 问题 / 背景
cmhub 托管生图上游存在稳定性风险,AI工场正式发布前需要“自定义模型”逃生口。但自定义 Key 仍必须经过软件套餐/设备授权和 cmhub 异步任务代理,不能恢复客户端 direct 直连或同步长等待。
当前阻塞:cmhub 尚未完成《卡密设备绑定与套餐授权方案》V1.5 所定义的 device credential、BYOK Provider 白名单、加密 task secret、零点数使用记录和 submit/poll 契约。契约和测试环境落地前,本任务不编码、不猜字段。
## 解除阻塞条件
- cmhub 提供版本化 API 文档、错误码、至少一个受支持 Provider、测试凭证和 mock/测试环境。
- 明确 BYOK title/image 请求、task secret 生命周期、终态清理、幂等键和计费字段。
- 服务端确认 Key 不进入 request_payload、CallRecord、队列日志、遥测或异常监控。
## 方案
- ⑤/AI工场增加显式“cmhub托管/自定义模型”来源;不自动切换。
- 自定义 Key 本地使用 Windows DPAPI 保存,UI 仅掩码、替换、清除;不回显明文。
- 所有请求带 device credential/product,服务端先校验套餐和设备;BYOK `points_cost=0`,显示“费用由模型服务商收取”。
- 生图仍 submit→poll→下载,job task_id 持久化续查;不走同步长等待。
- 正式发行版禁用普通用户通过 config 开启 direct 后端。
## 验收要点
- 无有效套餐/设备时 BYOK submit 被服务端拒绝;普通 API Key/direct 配置不能绕过。
- Key 不出现在 DB 普通字段、任务快照、日志、命令行、错误或导出;DPAPI 文件复制到另一用户/设备不可直接解密。
- 托管失败不静默用 BYOK,BYOK 失败不扣 cmhub 点数。
- 自定义生图可重启续查、下载失败不重 submit;Provider/域名/参数严格白名单。
- 全部测试使用占位 Key,不提交真实密钥。
## 边界(不改什么)
- 阻塞解除前不实现临时兼容接口。
- 不允许任意上游 URL,不做客户端直连,不同步长等待。
- 不改 cmhub 托管预扣/退点账本。
## 执行记录
BLOCKED:等待 cmhub V1.5 授权与 BYOK 异步契约。
+40
View File
@@ -0,0 +1,40 @@
---
id: T-595
title: AI工场端到端集成、真实只读验收与产品文档收口
phase: 7
deps: [T-593, T-594]
status: TODO
created: 2026-07-11
---
## 问题 / 背景
AI工场横跨 DB、CDP、远程图片、cmhub 异步生成、GUI 拖放和本地导出。各子任务通过后仍需端到端验收,确认跨模块状态恢复、两种生成来源、部分导出和打包环境一致,并将提案文档升级为当前产品事实。
## 方案
- 串起:新增/恢复项目 → 只读拉原图 → 单击进池 → 设源图 → 同提示词 N 张生成 → 重启续查 → 拖入终选排序 → 部分导出 → 打开目录。
- 托管与自定义来源分别做 mock 全链和成本可控实测;只读 CDP 实跑不点击更新、不上传蝦皮。
- 验证程序强退/重启时 submitted/running job、下载中间态、终选和草稿提示词恢复。
- 核对 1180×760、960×640 和 Windows 缩放,生成 Playwright/Qt 截图与 `tab6-ai-studio-v3.svg` 对照。
- 更新 `docs/04-architecture.md`、`docs/routes.md`、`docs/api.md`、UI README、用户排障和打包说明;Obsidian 方案标记实现状态。
- 确认公开发行包不包含 data、真实 Key、测试图片或 direct 普通入口。
## 验收要点
- 完整闭环可由运营独立完成,所有失败均为中文且能继续/重试,不需要改 DB。
- 同项目多轮生成、多个项目切换和重启不串图、不重复扣费、不丢 task_id。
- 终选顺序与导出文件顺序一致;部分导出和已存在目录三选实测通过。
- 托管/BYOK 计费提示和授权边界准确,不静默切换。
- 现有五个 Tab、②生成、③更新、账号、设置、打包和全量单测不回归。
- 真实操作仅只读商品页和本地导出;CDP 自动回传不在本任务验收。
## 边界(不改什么)
- 不实现主图9张/详情图多媒体框自动回传蝦皮。
- 不加入本地图片导入、自动去重重生或自动动作词。
- 不以人工改 SQLite 作为验收步骤。
## 执行记录
(完成后记录端到端场景、真实只读验收、截图和全量回归。)