docs: 补强 V1 数据与测试设计
- 扩展 SQLite schema:新增 batches、Excel 行定位、stage/status、时间戳和重试字段 - 明确 SQLite worker 并发规则:独立 connection、WAL、busy_timeout、短事务 - 调整 AI 接入顺序:先做模型清单后端,再接真实 ai.py,设置页复用后端 - 补充 unittest 测试基座要求和分层验证策略 - 敏感信息改为本地明文保存,配合 gitignore、UI 打码和日志脱敏
This commit is contained in:
+62
-21
@@ -41,7 +41,7 @@ Shopee 卖家中心页面 / 本地图片目录
|
||||
|
||||
## 二、流水线(核心)
|
||||
|
||||
每个任务(Excel 行)依次走过 5 个阶段,状态字段 `stage` 贯穿全程:
|
||||
每个任务(Excel 行)依次走过 4 个业务阶段,状态字段 `stage` 贯穿全程:
|
||||
|
||||
```text
|
||||
imported → collected → generated → applied
|
||||
@@ -74,7 +74,7 @@ imported → collected → generated → applied
|
||||
**存储(同一事实只存一处)**
|
||||
|
||||
- 应用配置(模型选择、生成参数、目录、Chrome 路径)→ `config.json`。
|
||||
- AI 模型清单(url/模型/密钥/类型/连接超时)→ `config/ai_models.json`(含密钥,必须 gitignore)。
|
||||
- AI 模型清单(url/模型/密钥/类型/连接超时)→ `config/ai_models.json`(API Key 本地明文保存,必须 gitignore,UI 打码显示)。
|
||||
- 业务数据(账号、任务、各阶段结果)→ SQLite `cmshopee.db`。
|
||||
- 图片(采集的旧封面、AI 生成的新封面)→ 本地图片目录(路径记在 DB)。
|
||||
- 提示词 → 标题提示词存单文件 `title_prompt.txt`;封面提示词存多模板 `prompts/cover/<名称>.txt`。
|
||||
@@ -116,7 +116,7 @@ imported → collected → generated → applied
|
||||
- `resolution`:当前分辨率,下拉 `512 / 1k / 2k / 4k`。
|
||||
- `resolution_timeouts`:分辨率 → **等待大模型返回超时(秒)** 的映射;用户选分辨率即自动套用,不单独填。
|
||||
- 模型本身的定义(url/key/类型/连接超时…)在 `config/ai_models.json`,见 5.1b。
|
||||
- 密钥不在 `config.json`:每个模型的 `api_key` 存于 `config/ai_models.json`,加密、打码、gitignore。
|
||||
- 密钥不在 `config.json`:每个模型的 `api_key` 存于 `config/ai_models.json`,本地明文保存、UI 打码、gitignore、不入日志。
|
||||
|
||||
### 5.1b AI 模型清单 `config/ai_models.json`
|
||||
|
||||
@@ -131,7 +131,7 @@ imported → collected → generated → applied
|
||||
"enabled": true,
|
||||
"url": "https://api.vectorengine.ai/v1/chat/completions",
|
||||
"model": "gemini-3.1-flash-image-preview", // 模型 ID
|
||||
"api_key": "***", // 密钥:加密存、UI 打码、不入日志、不进版本库
|
||||
"api_key": "***", // 密钥:本地明文存、UI 打码、不入日志、不进版本库
|
||||
"api_type": "auto", // chat | images_edits | auto —— 决定请求构造方式
|
||||
"connect_timeout_seconds": 30, // 连接该服务超时(每模型,默认 30)
|
||||
"timeout_seconds": 0, // 返回超时:0/留空 = 运行时按 resolution_timeouts 取值
|
||||
@@ -147,11 +147,21 @@ imported → collected → generated → applied
|
||||
- 约束:**至少各有一个 text 与一个 image 模型**;下拉默认最少一项、删到剩一项时禁用「删除」。
|
||||
- `connect_timeout_seconds`(连接超时)属于**模型**;返回超时由分辨率映射决定(不在模型上单设)。
|
||||
- `api_type` 反映不同 API 形状(`chat`/`images_edits`/`auto`),请求构造按它分支。
|
||||
- `name` 唯一;`api_key` 加密存、打码显示。
|
||||
- `name` 唯一;`api_key` 本地明文保存、打码显示。
|
||||
|
||||
### 5.2 SQLite `cmshopee.db`
|
||||
|
||||
```sql
|
||||
-- 批次(一次导入动作)
|
||||
CREATE TABLE batches (
|
||||
id TEXT PRIMARY KEY, -- batch_id,如 20260626_153000_xxxx
|
||||
source_files_json TEXT NOT NULL, -- 导入文件绝对路径列表(JSON)
|
||||
status TEXT NOT NULL DEFAULT 'active', -- active/done/partial/failed
|
||||
note TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- 账号(④ 账号管理)
|
||||
CREATE TABLE accounts (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@@ -161,44 +171,75 @@ CREATE TABLE accounts (
|
||||
slug TEXT UNIQUE NOT NULL, -- user-data-dir 子目录名 [a-z0-9_]
|
||||
user_data_dir TEXT NOT NULL,
|
||||
debug_port INTEGER NOT NULL,
|
||||
password_enc TEXT, -- 加密存,仅参考,不自动登录
|
||||
password TEXT, -- 本地明文,仅参考,不自动登录;UI 打码,gitignore
|
||||
note TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
last_login_at TEXT
|
||||
);
|
||||
|
||||
-- 任务 + 各阶段结果(贯穿流水线)
|
||||
CREATE TABLE tasks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
batch_id TEXT NOT NULL,
|
||||
source_file TEXT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
batch_id TEXT NOT NULL REFERENCES batches(id),
|
||||
-- Excel 回写定位
|
||||
source_file TEXT NOT NULL, -- 展示用原路径
|
||||
source_file_abs TEXT NOT NULL, -- 绝对路径,作为回写分组依据
|
||||
source_sheet TEXT NOT NULL, -- sheet 名
|
||||
source_row INTEGER NOT NULL, -- Excel 行号(1-based)
|
||||
row_key TEXT NOT NULL UNIQUE, -- batch/file/sheet/row 组成,防重复导入
|
||||
-- 输入列(Excel)
|
||||
account_name TEXT,
|
||||
alias TEXT NOT NULL,
|
||||
item_id TEXT NOT NULL,
|
||||
account_name TEXT,
|
||||
alias TEXT NOT NULL,
|
||||
item_id TEXT NOT NULL,
|
||||
-- 采集输出(程序写,改前快照)
|
||||
old_title TEXT,
|
||||
old_cover_path TEXT, -- 旧封面本地图片路径
|
||||
old_title TEXT,
|
||||
old_cover_path TEXT, -- 旧封面本地图片路径
|
||||
-- AI 输出
|
||||
new_title TEXT,
|
||||
new_cover_path TEXT, -- 新封面本地图片路径
|
||||
new_title TEXT,
|
||||
new_cover_path TEXT, -- 新封面本地图片路径
|
||||
-- 应用
|
||||
committed INTEGER DEFAULT 0, -- 是否成功点「更新」提交
|
||||
stage TEXT DEFAULT 'imported', -- imported/collected/generated/applied/failed/skipped
|
||||
error TEXT,
|
||||
updated_at TEXT
|
||||
committed INTEGER NOT NULL DEFAULT 0, -- 是否成功点「更新」提交
|
||||
stage TEXT NOT NULL DEFAULT 'imported', -- imported/collected/generated/applied
|
||||
status TEXT NOT NULL DEFAULT 'pending', -- pending/running/success/failed/skipped/cancelled
|
||||
last_error TEXT,
|
||||
collect_attempts INTEGER NOT NULL DEFAULT 0,
|
||||
generate_attempts INTEGER NOT NULL DEFAULT 0,
|
||||
apply_attempts INTEGER NOT NULL DEFAULT 0,
|
||||
imported_at TEXT NOT NULL,
|
||||
collected_at TEXT,
|
||||
generated_at TEXT,
|
||||
applied_at TEXT,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(batch_id, source_file_abs, source_sheet, source_row)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_tasks_batch_stage_status ON tasks(batch_id, stage, status);
|
||||
CREATE INDEX idx_tasks_alias ON tasks(alias);
|
||||
CREATE INDEX idx_tasks_item ON tasks(item_id);
|
||||
```
|
||||
|
||||
关键事实:
|
||||
|
||||
- `alias` 是账号↔任务**唯一关联键**;找不到账号 → stage=skipped,error=别名未匹配,最后弹窗汇总。
|
||||
- `account_name` 仅展示/参考;匹配以 `alias` 为准。
|
||||
- `source_file_abs/source_sheet/source_row` 是回写 Excel 的权威定位;即使商品 ID 重复,也按原行回写。
|
||||
- `row_key` 防止同一批次内重复导入同一行。
|
||||
- `old_title/old_cover_path`:程序**采集阶段抓取**的快照(输出)。
|
||||
- `new_title/new_cover_path`:**AI 生成**结果(输出),图片落本地;不设逐条确认阶段,生成即可进入 ③。
|
||||
- `stage` 表示已完成到哪个业务阶段;`status` 表示当前处理结果。失败时 `stage` 保持在最后成功阶段,`status=failed`,错误写 `last_error`。
|
||||
- `committed`:③ 用户确认批量更新弹窗后逐条点「更新」提交;该字段记录提交是否成功。
|
||||
- 各字段**每阶段处理完立即写回 SQLite**(实时落库);阶段结束后批量回写 Excel。
|
||||
|
||||
### 5.2b SQLite 并发与连接规则
|
||||
|
||||
- `db.connect()` 统一设置:`PRAGMA foreign_keys=ON`、`PRAGMA journal_mode=WAL`、`PRAGMA busy_timeout=5000`、`PRAGMA synchronous=NORMAL`。
|
||||
- SQLite connection 不跨线程共享;每个 PySide6 worker / 后台线程按需创建自己的 connection。
|
||||
- 写操作使用短事务:单条任务完成即提交,避免长时间占用写锁。
|
||||
- 写库遇到 locked/busy:按短间隔重试,超过 busy timeout 后返回明确错误并通过 signal 通知 GUI。
|
||||
- GUI 不直接缓存“事实状态”;写库成功后由 worker 发 `row_updated`,GUI 再刷新对应行。
|
||||
- Excel 回写以 SQLite 为事实来源;原 Excel 被锁时不回滚 SQLite,只提示关闭后重试或另存副本。
|
||||
|
||||
### 5.3 Excel 模板
|
||||
|
||||
| 列 | 含义 | 输入/输出 |
|
||||
@@ -328,7 +369,7 @@ cmshopee/
|
||||
- CDP 交互事实变化同步第七节。
|
||||
- 存储边界:应用设置→config.json,账号/任务/结果→SQLite,图片→本地目录并记路径于 DB,登录态→user-data-dir;同一事实只存一处。
|
||||
- 别名是账号↔任务唯一关联键。
|
||||
- 密码与 AI Key 加密存、不外传、不写日志;不自动登录。
|
||||
- 密码与 AI Key 本地明文保存、UI 打码、不外传、不写日志;不自动登录。
|
||||
- AI 生成内容直接进入 ③ 更新候选;③ 批量确认后提交,新图本地留档 + 回写 Excel 以备追溯。
|
||||
- 高风险模块先单独验证,再接入流水线。
|
||||
- GUI 只通过 signal/slot 接收 worker 进度;禁止后台线程直接操作 Qt widget 或共享 SQLite connection。
|
||||
|
||||
Reference in New Issue
Block a user