# 实施方案：生图带产品参考图 + 禁止降级 + 产品库

> 倩倩姐 2026-06-08 拍板：①上传产品图按钮做必填项（需产品图场景）②建任务时用户选"本次要不要产品入镜"③这轮一起做产品库（内置+上传）

## 一、现状（已查清）

**已存在、能用的**：
- 产品图上传接口 `POST /products/{id}/upload-image` ✅
- 前端上传组件 `ProductImageUpload`（在配置页产品管理里）✅
- worker 读参考图 → 传 generate_storyboard_images 的链路 ✅
- 产品表已有 `source enum('preset','custom')` 字段（产品库内置/自建早有预留）✅
- 主备生图通道（本轮已修，apiports 503 自动切 codeproxy）✅

**缺口/坑**：
1. 无图时 worker 默默降级纯文生图，无任何阻断（核心要堵）
2. 产品图存/读用**相对路径**，api 容器 cwd 与 worker cwd=`/` 不一致 → worker 可能读不到（隐患，需改绝对路径）
3. 建任务时用户看不到"产品有没有图"、也没有"要不要产品入镜"的选择
4. 产品库目前只有 1 个 preset 产品、无图；没有产品库浏览/选择 UI
5. `ProductCreate` DTO 无 image_path，建产品时无法带图

## 二、产品决策落地（按倩倩姐拍板）

- 建任务页加开关 **「本次产品是否入镜」**（need_product_image，默认"是"）
  - 选"是" → 该产品**必须有参考图**才能点"生成"，否则按钮置灰提示"请先上传产品图"
  - 选"否" → 允许纯文生图（氛围/科普/话题类内容）
- 产品来源：**内置产品库 + 上传**，靠 `source` 字段区分

## 三、改动清单（分纵切片，逐块可验收）

### 切片 A：路径修稳（最高优先，不修后面全是空中楼阁）
- `products.py` upload-image：存**绝对路径**（`/app/uploads/...`）进 image_path，不存相对路径
- `pipeline_io.py` 读参考图：用绝对路径校验 + 读取
- 验收：上传一张图 → worker 日志出现"产品参考图已加载 N bytes"

### 切片 B：后端禁降级 + 建任务字段
- `task.py` 模型 + migration：GenerationTask 加 `need_product_image: bool default True`
- `CreateTaskRequest` DTO 加 `need_product_image: bool = True`
- `task_service` 建任务时：若 need_product_image=True 且产品无 image_path → 直接拒绝（422，"该产品未上传参考图"）
- `image_gen.py`：`ALLOW_TEXT_ONLY_IMAGE` 改由任务的 need_product_image 驱动；need=True 时无参考图**硬报错**不降级
- 验收：无图产品 + 需入镜 → 建任务被拒；有图 → 生图带参考图

### 切片 C：前端建任务页
- NewTaskForm 加「产品是否入镜」开关 + 展示当前产品图缩略图/未上传状态
- 需入镜且无图 → "生成"按钮置灰 + 提示"请先到产品库上传参考图"
- 验收：浏览器走一遍，无图拦住、有图放行

### 切片 D：产品库（内置+上传）
- 后端：`GET /products` 支持按 source 筛选；预置 2-3 个常用内置产品（带图）入库 seed
- 前端：配置页产品管理区分"内置库/我的产品"，支持从内置库选用、上传自己的
- `ProductCreate` DTO 加 image_path（建产品即可带图）
- 验收：产品库能看到内置产品、能上传新产品、建任务能选到

## 四、风险/待北哥确认
- **内置产品库放哪些产品+图**：需北哥给真实产品图素材，否则内置库是空壳。先搭框架+占位，图等北哥给。
- 合规：产品图入镜后，gpt-image-2 仍可能把功效词画进图（[[clover-image-gen-compliance-risk]]），需北哥合规 prompt 方案。

## 五、建议执行顺序
A（路径）→ B（后端禁降级）→ C（前端建任务）→ D（产品库）
每切片做完即验收，A+B+C 通了"禁降级"主线就闭环，D 是产品库增强。
