docs: 交接文档三件套(接手总览+后端地图+差距路线图)+补全env模板
Some checks failed
Clover CI / backend (push) Has been cancelled
Clover CI / frontend (push) Has been cancelled
Clover CI / python-audit (push) Has been cancelled

- HANDOVER.md: 守印接手第一入口,全景+上手路径+文档地图
- backend/BACKEND_MAP.md: 后端接手地图(路由/模型/AI引擎/评分维度)
- 路线图.md: 现状vs目标差距(三视角×双目标矩阵+7/15倒排冲刺)
- .env.example x3: 补全 MODEL_VISION/CLAUDE_API_URL 及本地SSE示例

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
yangqianqian
2026-07-01 18:49:51 +08:00
parent e26f53608b
commit de6466737b
6 changed files with 576 additions and 0 deletions

View File

@@ -29,8 +29,12 @@ IMAGE_PROVIDER_FALLBACK=gemini
IMAGE_MODEL=gpt-image-2 IMAGE_MODEL=gpt-image-2
MODEL_IMAGE=gpt-image-2 MODEL_IMAGE=gpt-image-2
MODEL_TEXT=claude-opus-4-8 MODEL_TEXT=claude-opus-4-8
# Vision model used by verify_real_image script (leave empty to skip real-image checks).
MODEL_VISION=
APIPORTS_BASE_URL=https://www.apiports.com/v1 APIPORTS_BASE_URL=https://www.apiports.com/v1
CODEPROXY_BASE_URL= CODEPROXY_BASE_URL=
# Override only if calling Claude through a non-default gateway.
CLAUDE_API_URL=
GEMINI_API_URL=https://generativelanguage.googleapis.com/v1beta GEMINI_API_URL=https://generativelanguage.googleapis.com/v1beta
# Optional platform keys. Normal customer keys should be entered in the UI. # Optional platform keys. Normal customer keys should be entered in the UI.

165
HANDOVER.md Normal file
View File

@@ -0,0 +1,165 @@
# Clover 项目接手文档(守印必读第一篇)
> 本文是新同事接手 Clover 的**总入口**。先读完这一篇建立全局认知,再按“上手路径”逐步深入。
> 后端细节看 [`backend/BACKEND_MAP.md`](backend/BACKEND_MAP.md),部署看 [`README.md`](README.md),产品全貌看 [`Clover架构方案.md`](Clover架构方案.md)。
---
## 0. 一句话说清这是什么
Clover 是给**北哥团队**用的小红书**内容生产中台**:输入产品和卖点 → AI 生成文案3 套叙事)→ 生成配图 → 组长/管理员审核 → 打包下载给达人分发。核心链路已上线,正在两人协作迭代。
---
## 目录
1. [协作方式:你和倩倩姐怎么分工](#1-协作方式)
2. [代码仓库与基线](#2-代码仓库与基线)
3. [技术栈全景](#3-技术栈全景)
4. [5 分钟跑起来(本地开发)](#4-5-分钟跑起来)
5. [核心业务链路(先懂业务再看代码)](#5-核心业务链路)
6. [三层视角:产品要长成什么样](#6-三层视角)
7. [文档地图:什么问题看哪份文档](#7-文档地图)
8. [守印上手路径(按天走)](#8-守印上手路径)
9. [当前已知问题与红线](#9-当前已知问题与红线)
---
## 1. 协作方式
这是**两人协作开发**,不是单向交付:
| 人 | 负责 |
|---|---|
| 倩倩姐 | 梳理业务逻辑与框架、前端Next.js |
| 守印(你) | 后端FastAPI + Celery + 数据层) |
分工原则:**前端归倩倩姐、后端归守印**,各自在自己的分支开发,通过 API 契约对接(见 [`启动包/API契约.md`](启动包/API契约.md))。改动对方领域前先打招呼,避免撞车。
## 2. 代码仓库与基线
- **远程仓库**`http://192.168.0.101:3002/qianqian/beige`(公司内网 Gitea
- **基线分支**`main` = 2026-07-01 今天的上线版commit `e26f536`)。这是当前线上真实运行的代码,以它为准,不要参考更早的历史分支。
- **协作分支策略**
- `main`:稳定基线,只合并测过的代码,不直接在上面写
- 各自开 `feat/xxx``fix/xxx` 分支开发,完成后合回 `main`
- 守印后端相关分支建议前缀 `be/`,倩倩姐前端 `fe/`,一眼区分
- **克隆命令**
```bash
git clone http://192.168.0.101:3002/qianqian/beige.git
cd beige
```
## 3. 技术栈全景
| 层 | 技术 | 位置 |
|---|---|---|
| 前端 | Next.js 16 (App Router) + TypeScript + Tailwind + Zustand | `frontend/` |
| 后端 | FastAPI + SQLAlchemy | `backend/app/` |
| 异步任务 | Celery生文生图等耗时任务 | `backend/app/workers/` |
| 关系库 | MySQL业务数据 | `alembic/` 管迁移25 条 |
| 文档库 | MongoDB链路留痕/trace | via Motor |
| 缓存/队列 | RedisCelery broker + 缓存) | — |
| AI 引擎 | 生文/生图/评分/门禁 | `backend/app/services/ai_engine/` 约 20 模块 |
| 部署 | docker-compose + nginx 反代 | `docker-compose.prod.yml` |
**非 monorepo**`backend/` 和 `frontend/` 各自独立,没有 workspace 工具,分别装依赖、分别跑。
## 4. 5 分钟跑起来
> 目标本地把前后端跑起来。密钥用你自己的AI 中转 key / 本地数据库),不要用交接包里的示例值。
**准备环境变量**:复制 `.env.example` → `.env`,填你自己的值。三个位置:根目录、`backend/.env`、`frontend/.env.local`。关键字段 `FERNET_KEY`/`JWT_SECRET` 自己生成,数据库密码填本地库的。
**后端**
```bash
cd backend
pip install -r requirements.txt # 依赖已全部锁版本
alembic upgrade head # 建表25 条迁移)
python scripts/seed_data.py # 灌种子数据(见 启动包/种子数据.md
uvicorn app.main:app --reload --port 8000
```
**前端**
```bash
cd frontend
npm ci # 按 package-lock 精确安装
# .env.local 里务必设 NEXT_PUBLIC_SSE_BASE_URL=http://localhost:8000
npm run dev # 起在 :3000
```
**本地开发有个坑**:前端 :3000、后端 :8000 跨端口SSE实时进度推送不能走 Next.js dev proxy会缓冲 EventSource 导致进度不刷新)。必须在 `frontend/.env.local` 显式设 `NEXT_PUBLIC_SSE_BASE_URL=http://localhost:8000`。这条已写进 `frontend/.env.example` 注释。
## 5. 核心业务链路
先懂业务再看代码。操作员走完整条链路是这样的:
1. **开新任务** → 选产品(新建或从产品档案选)
2. **填产品信息** → 产品名/品类/品牌词/目标人群/风格调性/核心卖点 + 上传产品图(可标主图、标使用场景:上脸/使用/成分/包装)
3. **填今日主题** → 如"黄皮提亮"
4. **生成文案** → 固定 3 套叙事:**痛点先行 / 场景先行 / 成分背书**,每套可选生成几条
5. **评分去重** → AI 按 7 维门禁打分≥80 分才出现≥90 分标绿;相似度去重
6. **挑文案 + 改稿** → 操作员选文案,可改稿;改稿动作进**飞轮**留痕
7. **生成配图** → 每套配几张图(默认 6 张,可调),生图走部分并发(有先后逻辑不能全并发)
8. **组长/管理员审核** → 操作员本人不能审;不通过打回、可重申(重申写原因入飞轮)
9. **打包下载** → 图+文打包,分发给达人
10. **裂变扩散** → 已通过的笔记可再生成裂变版本1~5 套,图+文)
**三种权限**:管理员(管理台)/ 组长(审核)/ 操作员(生产)。
## 6. 三层视角
这是孙总定的产品设计准绳——产品不只是"能跑通链路",要撑起三层视角,价值感才拉满。守印做后端时,配置项/留痕/数据接口都要往这三层靠:
| 视角 | 面向谁 | 要什么 | 后端要提供 |
|---|---|---|---|
| L1 业务视角 | 所有人(最浅层) | 生文→生图→审核→打包链路 | 已有 |
| L2 中层视角 | 核心中层/技术把控 | 门禁**可见可配置**、飞轮可见、操作记录、素材库、看板 | 配置化 API、留痕查询、素材库 CRUD |
| L3 高管视角 | 高级管理层 | 数据/进度看板跑了什么、ROI | 数据聚合/统计 API |
**关键红线**(孙总原话):"门禁写死是最麻烦的"——7 维权重、80 分合格线目前是硬编码L2 要求把它们做成可配置。详见路线图。
## 7. 文档地图
接手期间遇到问题,按下表找文档,不用漫无目的翻:
| 想知道什么 | 看哪份 |
|---|---|
| 后端代码怎么组织、我要改X动哪里 | [`backend/BACKEND_MAP.md`](backend/BACKEND_MAP.md) ⭐ |
| 怎么部署上线、docker 怎么起 | [`README.md`](README.md) |
| 前后端 API 怎么对接(契约) | [`启动包/API契约.md`](启动包/API契约.md) |
| 产品整体架构设计 | [`Clover架构方案.md`](Clover架构方案.md) |
| 种子数据有哪些、怎么灌 | [`启动包/种子数据.md`](启动包/种子数据.md) |
| 项目所有约束、产品红线、拍板决策 | [`CLAUDE.md`](CLAUDE.md) ⭐ 开工必读 |
| 交付项核销状态(哪些做了哪些没) | [`交付核销表.md`](交付核销表.md) |
| 出线上问题怎么排 | [`docs/ops/troubleshooting.md`](docs/ops/troubleshooting.md) |
| FERNET_KEY 密钥托管与恢复 | [`docs/ops/fernet.md`](docs/ops/fernet.md) |
| 北哥的原始需求是什么 | [`北哥回填解读与落点.md`](北哥回填解读与落点.md) |
| 现状离目标还差什么、下一步做什么 | `路线图.md`(同目录,见第 9 节) |
## 8. 守印上手路径
建议按这个顺序,别一上来扎进代码:
- **第 1 步(了解全貌)**:读本文 + [`CLAUDE.md`](CLAUDE.md)。CLAUDE.md 是项目所有约束和产品红线的落盘,里面每条 🔴 都是踩过坑或拍过板的,务必读完。
- **第 2 步(跑起来)**:按第 4 节把本地环境跑通,用你自己的 key。能登录、能开一个任务、能看到生成就算上手了。
- **第 3 步(懂后端)**:读 [`backend/BACKEND_MAP.md`](backend/BACKEND_MAP.md),对着代码走一遍 API 路由和数据模型,重点看 `task_actions.py`(飞轮信号入口)、`stream.py`SSE ticket 机制、AI 引擎评分部分。
- **第 4 步(明确分工)**:读 `路线图.md`,看后端待办里哪些是你的活,和倩倩姐对齐优先级再动手。
## 9. 当前已知问题与红线
**几条必须知道的红线(详见 [`CLAUDE.md`](CLAUDE.md)**
- 🔴 **合格线=80 分,禁止擅改**`constants.py QUALITY_PASS_SCORE=80`)。提质量靠优化 prompt 顶分数,绝不靠降门槛。改这个值必须倩倩姐当面拍板。
- 🔴 **SSE 认证用一次性 ticket绝不把 JWT 放进 URL**。EventSource 不支持 headerSSE 连接前先用 JWT 换一张 30-60 秒的一次性 ticket。
- 🔴 **系统通用化,绝不内置写死任何具体产品**(素颜霜只是北哥一个客户的一个产品,产品靠上传才有)。
- 🔴 **飞轮 eval_score 留 NULL 铁律**AI 评分只做展示层,不当飞轮权重。真正影响下次生成的只认真实信号(选了哪张/改了什么/过审与否)。
- 🔴 **竞品数据监控 = 不做**(合规反爬红线,已砍)。
**当前已知待改(会议暴露,详见路线图)**
- 新建产品链路在线上跑失败(本地 OK产品表单逻辑割裂要梳理全。
- 文案数量配置语义待明确("生成几条文案"是每套还是总数)。
- 门禁 7 维权重、合格线硬编码L2 目标要求可配置化。
- 素材库、看板(业务看板 + 高管数据看板)待建。
- 裂变功能已做但缺直观感官呈现。
> 完整的"现状 vs 目标差距 + 开发路线图"见同目录 `路线图.md`。缺口清单会在倩倩姐与北哥对齐内容板块后进一步补充。

View File

@@ -14,8 +14,12 @@ IMAGE_PROVIDER_FALLBACK=gemini
IMAGE_MODEL=gpt-image-2 IMAGE_MODEL=gpt-image-2
MODEL_IMAGE=gpt-image-2 MODEL_IMAGE=gpt-image-2
MODEL_TEXT=claude-opus-4-8 MODEL_TEXT=claude-opus-4-8
# Vision model used by verify_real_image script (leave empty to skip real-image checks).
MODEL_VISION=
APIPORTS_BASE_URL=https://www.apiports.com/v1 APIPORTS_BASE_URL=https://www.apiports.com/v1
CODEPROXY_BASE_URL= CODEPROXY_BASE_URL=
# Override only if calling Claude through a non-default gateway.
CLAUDE_API_URL=
GEMINI_API_URL=https://generativelanguage.googleapis.com/v1beta GEMINI_API_URL=https://generativelanguage.googleapis.com/v1beta
APIPORTS_KEY= APIPORTS_KEY=
CODEPROXY_KEY= CODEPROXY_KEY=

283
backend/BACKEND_MAP.md Normal file
View File

@@ -0,0 +1,283 @@
# Clover 后端接手地图
> 受众:守印(新接手后端,不了解北哥产品背景)
> 最后更新2026-07-01
> 基于真实代码分析,所有文件名/类名/函数名/行号均来自实际代码,请直接跳转核实。
---
## 产品背景(守印必读)
Clover 是给北哥团队做的**小红书种草内容生产中台**,帮助运营团队批量生产高质量小红书笔记。
完整链路:
```
填产品卖点(产品档案)
→ 上传标杆笔记AI拆解爆款特征
→ 发起任务AI生成3套文案 × A痛点先行/B场景先行/C成分背书
→ 运营选文案 + 选配图(每步触发飞轮信号学偏好)
→ 组长审核(通过/打回带原因)
→ 打包下载 ZIP发给达人分发
→ 爆款笔记可触发"裂变"再出N套变体
```
**三个角色:**
- `operator`(运营):选文案/选图/改稿
- `supervisor`(组长):审核通过/打回
- `admin`(管理员):管用户/管词库/删候选
**两大特色机制:**
- **AI评分门禁**:文案必须 ≥80分才入库低分直接过滤不展示给运营
- **飞轮**:每次选择/改稿/打回都是信号,下次生成自动学偏好
---
## 目录
1. [整体目录结构与技术栈](#1-整体目录结构与技术栈)
2. [API 路由全清单](#2-api-路由全清单)
3. [数据模型](#3-数据模型)
4. [AI 引擎模块清单](#4-ai-引擎模块清单)
5. [Celery 异步任务](#5-celery-异步任务)
6. [飞轮机制](#6-飞轮机制)
7. [门禁可配置性现状](#7-门禁可配置性现状)
8. [鉴权与 SSE](#8-鉴权与-sse)
9. [改动快速索引](#9-改动快速索引)
---
## 1. 整体目录结构与技术栈
**技术栈:** FastAPI + Celery + PostgreSQL + RedisPython 3.11+Alembic 做迁移pytest 做测试。
```
backend/
├── app/
│ ├── api/v1/ # 路由层16个文件统一前缀 /api/v1/
│ ├── models/ # SQLAlchemy ORM 模型6个文件
│ ├── repositories/ # DB 查询封装Repository 模式)
│ ├── services/ # 业务逻辑层
│ │ ├── ai_engine/ # AI 引擎24个模块核心
│ │ ├── flywheel_service.py # 飞轮信号写入
│ │ ├── fission_service.py # 裂变任务创建
│ │ ├── fission_pipeline.py # 裂变执行主流程
│ │ └── fission_images.py # 裂变生图
│ ├── workers/ # Celery 任务层5个文件
│ ├── constants/
│ │ └── enums.py # 枚举定义(状态机、信号类型、角色等)
│ ├── core/
│ │ ├── config.py # 环境变量读取Settings 类)
│ │ ├── database.py # DB session 工厂
│ │ ├── security.py # JWT 签发/验证 + Fernet 加解密
│ │ └── sse_ticket.py # SSE 一次性票据Redis 存储)
│ └── middleware/
│ └── workspace_guard.py # 鉴权依赖注入4个级别
├── alembic/versions/ # 19 个数据库迁移文件
├── tests/ # 单元测试pytest
├── docker-compose.yml # 本地开发启动
└── requirements.txt # Python 依赖
```
---
## 2. API 路由全清单
所有路由统一挂在 `app/main.py`,前缀 `/api/v1/`。路由文件在 `app/api/v1/`
### auth.py — 认证
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/auth/login` | 用户名密码登录,返回 JWT access_token |
| POST | `/auth/change-password` | 修改密码(首次登录强制走此端点) |
| GET | `/auth/me` | 当前用户信息 + 所属 workspace + role |
### workspaces.py / users.py / api_keys.py
| 方法 | 路径 | 作用 |
|------|------|------|
| GET/POST | `/workspaces` | 查/建工作区 |
| GET/POST/PUT | `/users` | 成员管理admin |
| POST/GET/DELETE | `/api-keys` | API Key 录入/查看/删除(只返回 provider+last4不返密文 |
### products.py — 产品档案
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/products` | 新建产品档案 |
| GET | `/products` | 列出当前 workspace 产品 |
| GET | `/products/{id}` | 查单个产品(含参考图) |
| PUT | `/products/{id}` | 更新卖点/风格/角度等 |
| DELETE | `/products/{id}` | 软删除is_active=False |
### product_images.py — 产品多图R5规格
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/products/{id}/images` | 上传参考图,按 scene 分类primary/scene/texture/ingredient/model |
| GET | `/products/{id}/images` | 列出所有参考图 |
| DELETE | `/products/{id}/images/{img_id}` | 删除某张 |
### benchmarks.py — 标杆笔记链路第2环
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/products/{pid}/benchmarks/upload` | 上传截图10MB 限制magic bytes 校验) |
| GET | `/products/{pid}/benchmarks` | 列出该产品标杆笔记 |
| POST | `/benchmarks/{bid}/analyze` | 触发 AI 拆解8维爆款特征写入 features_json |
| GET/POST/PUT/DELETE | `/banned-words` | 违禁词 CRUD写操作需 admin |
| GET | `/products/export` | 产品档案 JSON 导出 |
| GET | `/benchmarks/export` | 标杆笔记 JSON/CSV 导出 |
### tasks.py — 任务查询层
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/tasks` | 发起生成任务(校验有无 key推入 Celery queue |
| GET | `/tasks` | 任务列表(多状态/日期/product_id 过滤 + 分页,可混入裂变条目) |
| GET | `/tasks/{task_id}` | 任务详情(含所有文案候选 + 图片候选) |
| DELETE | `/tasks/{task_id}` | 删除任务admin有成品转 archived无成品物理删 |
### task_actions.py — 任务操作层(飞轮信号入口)
> 所有飞轮信号都在这里触发,是行为核心。
| 方法 | 路径 | 作用 | 飞轮信号 |
|------|------|------|---------|
| POST | `/tasks/{id}/text-candidates/select` | 选文案(同套单选,清旧选) | text_select +3 |
| POST | `/tasks/{id}/image-candidates/select` | 选图(同套同角色单选) | image_select +3 |
| POST | `/tasks/{id}/import-text` | 导入外部文案(客户验证过的范本,最强信号) | text_import +8 |
| POST | `/tasks/{id}/generate-images` | 导入轨去生图(复用已导入文案,不重生文案) | 无 |
| POST | `/tasks/{id}/regenerate` | 重生成(支持整体/单套/单张 + custom_prompt | regenerate -1 |
| POST | `/tasks/{id}/submit-review` | 提交审核至少1文案+1图才能提 | 无 |
| GET | `/tasks/{id}/preference/context` | 查飞轮偏好上下文(前端展示"已学习N条信号" | 无 |
| POST | `/tasks/{id}/text-candidates/{cid}/edit` | 改稿(真改字,回写 content + edited=True | text_edit +5 |
| DELETE | `/tasks/{id}/text-candidates/{cid}` | 删文案候选admin | 无 |
| DELETE | `/tasks/{id}/image-candidates/{cid}` | 删图片候选admin | 无 |
### review.py — 审核路由supervisor 权限)
| 方法 | 路径 | 作用 | 飞轮信号 |
|------|------|------|---------|
| GET | `/review/queue` | 待审队列pending_review按时间升序 | 无 |
| POST | `/review/{task_id}/approve` | 通过状态→approved | approve +5 |
| POST | `/review/{task_id}/reject` | 打回(原因原文存 preference_events.reason | reject_with_reason -3 |
### stream.py — SSE 实时推送安全红线ticket 机制)
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/tasks/{id}/sse-ticket` | 用 JWT 换一次性 ticket60s 有效) |
| GET | `/tasks/{id}/stream?ticket=<ticket>` | SSE 流(断线重连支持 `?last_seq=` |
### fission.py — 裂变链路第11环
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/fission` | 触发裂变1套爆款→N套完整笔记包 |
| GET | `/fission/{id}` | 查进度x/N 完成) |
| GET | `/fission/{id}/notes` | 取 N 套完整笔记包 |
| GET | `/fission/{id}/download` | 下载裂变结果 zip |
| POST | `/fission/{id}/notes/{seq}/retry-images` | 对某套失败分镜补图 |
### delivery.py — 交付打包
| 方法 | 路径 | 作用 |
|------|------|------|
| POST | `/tasks/{id}/package` | 触发打包(异步 Celery |
| GET | `/tasks/{id}/package` | 查包状态 + 下载链接 |
---
## 3. 数据模型
模型文件在 `app/models/`,共 6 个文件。
### user.py
- `User``id, username(唯一), email(唯一), hashed_password, is_active, must_change_password(首登强制改密)`
- `LoginRecord`:登录记录,`user_id FK→users, ip, user_agent`
- `UserPreference`UI 设置,`preferences_json`Text 存 JSON
### workspace.py
- `Workspace``id, name, slug(唯一), is_active`
- `WorkspaceMember``workspace_id + user_id 联合唯一, role 枚举(admin/supervisor/operator)`
- `UserApiKey``user_id + workspace_id + provider 三联唯一, encrypted_key(Fernet 密文), key_last4`;绝不存明文
### product.py
- `Product``workspace_id FK, name, category, selling_points(JSON数组), style_tone, text_angles(JSON数组), custom_prompt, image_path(主图路径兼容旧), brand_keyword, target_audience, is_active`
- `ProductImage`R5多图`product_id FK, path(绝对路径), scene(primary/scene/texture/ingredient/model), is_primary, sort_order`
- `BenchmarkNote``workspace_id+product_id FK, screenshot_url, highlights(手填), link_url, features_json(AI解析8维), analyze_status(pending/analyzing/done/failed)`
- `BannedWord``workspace_id FK, word, level(auto_fix/soft_warn/hard_block), replacement, updatable`
### task.py
- `GenerationTask``workspace_id FK, product_id FK, operator_id FK, theme, text_count(1-20), image_count(1-20), track(ai/import), need_product_image, status 7态(见下), review_status, reviewer_id, reject_reason, source_fission_id`
- 状态机:`pending → generating → pending_selection → pending_review → approved/rejected`;另有 `archived`(有成品软删)、`failed`(重试耗尽终态)
- `TextCandidate``task_id FK, source(ai/import), angle_label, strategy(A/B/C), content(JSON含title/content/tags/imageBrief), score_json(7维评分), banned_word_status, eval_score(一期留NULL), is_selected, edited(改稿标记)`
- `ImageCandidate``task_id FK, role, url, strategy(A/B/C), seq(分镜序号), is_selected, is_regen, eval_score(一期留NULL), ai_visual_score(展示用不进飞轮权重)`
- `DeliveryPackage``task_id FK, status(pending/ready/downloaded), package_path, download_url, expires_at`
### flywheel.py
- `PreferenceEvent`preference_events 表):飞轮信号日志
- 关键字段:`workspace_id, product_id, task_id FK, user_id FK, signal_type, signal_weight, candidate_id, angle_label, reason(打回原因原文), signal_meta(JSON), data_ownership(固定=client_data数据归客户)`
- 索引:`(workspace_id, product_id, created_at)` 三联复合索引
- `AiCallLog`ai_call_logs 表):`key_id(不含明文), provider, model, call_type, prompt_tokens, completion_tokens, success, error_code, latency_ms`
### fission.py
- `FissionTask``workspace_id FK, source_note(源笔记JSON), source_task_id FK, reference_level(low/mid/high), fanout_count(默认3), status(pending/generating/done/failed)`
- `FissionNote``fission_id FK, workspace_id FK, seq(第几套), note_json(含title/content/tags/imagePlan/dimension), images_json(生图结果列表), score, passed(>=80), dimension(换角度/换痛点/换人群), status`
**表间主要外键:**
- workspace → products / generation_tasks / fission_tasks / preference_events / banned_wordsworkspace_id 隔离多租户)
- generation_task → text_candidates / image_candidates / delivery_packages / preference_events
---
## 4. AI 引擎模块清单
全部在 `app/services/ai_engine/`,共 24 个文件。
| 模块文件 | 一句话职责 |
|---------|----------|
| `constants.py` | 所有可调常量中心:违禁词默认库、评分权重、合格线(80)、叙事策略文本、图片重试参数、飞轮权重 |
| `_score_prompt.py` | AI评委 prompt 模板7维评判标准+输出格式约束JSON与 constants.py 三处同步 |
| `_scoring_dims.py` | 机械合规打分score_compliance用于轨B导入文案或AI评委降级兜底 |
| `llm_scorer.py` | AI评委入口调 LLM 打7维分合规机械硬拦两通道挂时抛 ScoringUnavailableError |
| `text_scoring.py` | 文案评分聚合:整合 AI 评委分 + 机械合规分,输出 score_json |
| `text_variants.py` | 按 A/B/C 三套叙事策略调 LLM 生成多条文案变体 |
| `_text_prompt.py` | 文案生成 prompt 模板(含叙事策略差异化段落) |
| `prompt_composer.py` | 组装最终文案生成 prompt拼飞轮片段+产品信息+标杆特征+叙事策略) |
| `storyboard.py` | 按图数和叙事策略规划分镜列表,返回 storyboard + base_prompt |
| `storyboard_templates.py` | 各套叙事策略的分镜模板数据 |
| `_storyboard_data.py` | 分镜角色的默认视觉参数 |
| `image_gen.py` | 生图主入口asyncio.gather 并发多张主备通道切换指数退避重试3次 |
| `image_postprocessor.py` | 图片去AI化后处理SynthID破除(缩2px裁1px边+亮度/饱和微调)+高保真重编码(jpeg q=100)+尺寸处理 |
| `image_scorer.py` | AI评图0-100分ai_visual_score+ai_visual_note仅展示不进飞轮权重 |
| `banned_word_checker.py` | 三级违禁词扫描auto_fix/soft_warn/hard_block优先 DB 词库,兜底默认词库 |
| `preference_aggregator.py` | 飞轮偏好聚合取最近50条 events → 按权重统计高频角度 → 拼 prompt 片段注入文案生成 |
| `benchmark_analyzer.py` | 标杆笔记爆款8维特征 AI 解析链路第2环 |
| `_benchmark_prompt.py` | 标杆分析 prompt 模板 |
| `fission_prompt.py` | 裂变专用 prompt一次 LLM 出 N 套笔记) |
| `fission_fallback.py` | 裂变引擎降级兜底逻辑 |
| `gemini_factory.py` | Gemini 客户端工厂(生图备用通道) |
| `package_exporter.py` | AI引擎层的素材包打包辅助 |
| `beige_color_grade.py` | 小红书米色调色滤镜去AI化可选后处理 |
### 评分维度详细7维 + 合规机械)
**AI评委7维**,定义在 `_score_prompt.py: SCORING_DIMENSIONS` 字符串 + `llm_scorer.py: _DIM_MAX` dict + `constants.py: AI_DIM_WEIGHTS` dict**三处必须同步**
| 维度 | 满分 | 核心判断标准 |
|-----|-----|------------|
| 痛点人群精准 | 16 | "说的就是我"——处境/困扰让目标用户对号入座 |
| 情绪张力 | 16 | 过去痛(后果)+ 未来好(成果)双向情绪 |
| 买点转化 | 16 | 卖点翻译成用户能感知的场景化利益(人话) |
| 开头钩子 | 13 | 第一句直击痛处/场景,让人停下来继续读 |
| 标题点击力 | 13 | 悬念/反差/疑问钩子 + 广覆盖不锁死窄人群 |
| 真实感 | 11 | 像真人分享前70%干货后30%软性推荐 |
| 标签精准度 | 10 | 精准购买意向埋词,非泛流量词 |
| 合规(机械) | 5 | 机械硬拦不进AI评委打分 |
| **合计** | **100** | |
**合格线**`constants.py` 第47行 `QUALITY_PASS_SCORE = 80`硬编码详见第7节

View File

@@ -2,3 +2,8 @@
# These are build-time variables. After changing them, rebuild the frontend image. # These are build-time variables. After changing them, rebuild the frontend image.
NEXT_PUBLIC_API_BASE_URL= NEXT_PUBLIC_API_BASE_URL=
NEXT_PUBLIC_SSE_BASE_URL= NEXT_PUBLIC_SSE_BASE_URL=
# Local development: the frontend runs on :3000 and the backend on :8000, so
# SSE cannot use Next.js dev proxy (it buffers EventSource). Set this explicitly:
# NEXT_PUBLIC_SSE_BASE_URL=http://localhost:8000
# and optionally NEXT_PUBLIC_API_BASE_URL=http://localhost:8000 in .env.local

115
路线图.md Normal file
View File

@@ -0,0 +1,115 @@
# Clover 现状 vs 目标 差距路线图
> 本文回答一个问题:**已上线版本做到了什么、离目标还差什么、下一步按什么优先级做。**
> 来源2026-07-01 内容中台研讨 + 界面设计讨论两场会议录音 + 代码现状盘点。
> 受众:守印(后端)+ 倩倩姐(前端/框架)协作用。
> ⚠️ 缺口清单会在倩倩姐与北哥对齐"内容板块"后进一步补充,本文标注 `[待北哥对齐]` 的项即等待确认。
---
## 目录
1. [两个目标别混淆(最重要)](#1-两个目标别混淆)
2. [三层视角标尺](#2-三层视角标尺)
3. [差距矩阵表(三视角 × 双目标)](#3-差距矩阵表)
4. [7-15 倒排冲刺清单](#4-倒排冲刺清单)
5. [高大上界面解法(孙总要求)](#5-高大上界面解法)
6. [不做清单(避免跑偏)](#6-不做清单)
7. [关键时间锚点](#7-关键时间锚点)
---
## 1. 两个目标别混淆
这个项目现在要同时交付**两个东西**,标准相反,动手前先分清:
| | 目标A给北哥真用的系统 | 目标B7/15 演示的"壳" |
|---|---|---|
| 本质 | 真跑通、能出可发布内容 | 卖希望、把愿景具象化 |
| 谁做 | 守印(后端)+倩倩姐(前端) | 倩倩姐配合孙总出框架/图 |
| 标准 | 质量过关、北哥认可 | 看起来高大上、老板视角 |
| 功能 | 每个按钮真能用 | 想到的功能可占位符先放,点进去不实现也行 |
| 进包? | ✅ 进守印开发包 | ❌ 不进开发包孙总7/1晚出框架 |
**守印的活集中在目标A的后端。** 目标B的壳是倩倩姐和孙总的活。
## 2. 三层视角标尺
孙总反复强调"逻辑要再往上一层",把产品价值拆成三层。这是判断"做到什么程度算够"的标尺:
- **L1 业务视角**(所有人能看见,最浅层):生文→生图→审核→打包的链路本身。
- **L2 中层视角**(核心中层/技术把控):门禁**可见可配置**、飞轮可见、操作留痕、素材库、看板。孙总:"写死是最麻烦的"。
- **L3 高管视角**(高级管理层):数据/进度看板——跑了什么、ROI 多少。
孙总原话:"当你有这三个视角的时候,整套东西价值感会拉满,通用性会很强。"
## 3. 差距矩阵表
**图例**:✅已完成 ⚠️部分/有缺陷 ❌未做 优先级 P0(冲刺必做)/P1(重要)/P2(后续)
| # | 视角 | 目标 | 能力项 | 现状 | 差距 | 优先级 | 谁做 | 验收标准 |
|---|---|---|---|---|---|---|---|---|
| 1 | L1 | A | 生文→生图→审核→打包主链路 | ✅ | 已上线 | — | — | 一条龙走通 |
| 2 | L1 | A | 新建产品链路 | ⚠️ | 线上跑失败(本地OK)、表单逻辑割裂 | **P0** | 守印 | 新建产品能完整跑完并进入生成 |
| 3 | L1 | A | 文案数量配置语义 | ⚠️ | "生成几条文案"是每套还是总数没对上UI措辞乱 | P1 | 倩倩姐+守印 | 措辞明确+前后端一致 |
| 4 | L2 | A | 门禁/评分可见可配置 | ⚠️ | 7维权重+80合格线硬编码无配置入口 | P1 | 守印 | 门禁维度/权重可通过配置调整(不改合格线值) |
| 5 | L2 | A | 违禁词可配置 | ✅ | 已有 banned-words CRUD | — | 守印 | 北哥可自改违禁词 |
| 6 | L2 | A | 飞轮可见(改稿留痕) | ⚠️ | 后端记录了,前端呈现不足 | P1 | 倩倩姐 | 生成/选择/改稿节点即时提示"已学习偏好" |
| 7 | L2 | A | 操作记录/留痕 | ⚠️ | 部分有trace未成体系 | P2 | 守印 | 关键操作可查 |
| 8 | L2 | A | 素材库 | ❌ | 缺文案库/图片库 | P1 | 守印+倩倩姐 | 生成物可入库、可检索复用 `[待北哥对齐]` |
| 9 | L2 | A | 业务看板 | ⚠️ | 有轻量board只读视图 | P2 | 倩倩姐 | 素材/任务前置展示 |
| 10 | L1 | A | 裂变扩散 | ⚠️ | 功能做了,缺直观感官呈现 | P1 | 倩倩姐 | 裂变过程/结果有直观感知 |
| 11 | L3 | A | 数据/进度看板 | ❌ | 完全没有 | P2 | 守印+倩倩姐 | 高管能看到跑了什么 `[待北哥对齐]` |
| 12 | — | A | 意图压制生成 | ❌ | 北哥提过,先跑一轮再上 | P2 | 守印 | `[待北哥对齐]` |
| 13 | — | B | 高大上外壳 | ❌ | 界面太寡淡 | P0(B线) | 孙总+倩倩姐 | 见第5节 |
> 说明:去水印(已完成✅)、POC验证(倩倩姐与北哥单独做,系统内不做)已从缺口中移除。素材打标/爆款逆向/数据投放闭环属俊达对标的"全自动化"方向,是更远期路线,暂不进本轮冲刺。
## 4. 倒排冲刺清单
**终点**7/15 孙总讲。**产品要"做出来"不是"定下来"**(孙总:"定下来就太晚了"),冻结点 7/10-7/12。
**可用工作日**7/2(四)、7/3(五)、7/6(一)、7/7(二)、7/8(三)、7/9(四)、7/10(五) = **7 个工作日**
| 时间 | 里程碑 | 关键动作 | 负责 |
|---|---|---|---|
| 7/1 今晚 | 框架就位 | 孙总出"壳"框架和逻辑(小红书先,跨境后);倩倩姐约北哥对内容板块 | 孙总/倩倩姐 |
| 7/1-7/2 | 内容板块对齐 | 倩倩姐与北哥对齐:还差什么、素材库要不要加、看板要不要加。对完告诉孙总"差什么" | 倩倩姐 |
| 7/2-7/3 | P0 修复 | 守印修新建产品链路(#2);文案数量语义对齐(#3 | 守印+倩倩姐 |
| 7/6-7/8 | P1 主攻 | 门禁可配置化(#4)、飞轮呈现(#6)、素材库(#8)、裂变体感(#10)——按北哥对齐结果定取舍 | 两人 |
| 7/8-7/9 | 壳套上 | 把高大上外壳套到真系统上见第5节 | 倩倩姐+孙总 |
| 7/10 | 冻结+联调 | 产品做出来,端到端跑通,北哥可访问测试 | 两人 |
| 7/11-7/12 | 演示准备 | 确定 7/15 是现场演示还是录视频;壳+PPT 方向定 | 孙总+倩倩姐 |
| 7/15 | 讲 | 孙总正式讲 | 孙总 |
> **占位符策略**(孙总认可):想到但来不及做的功能,先以占位符/禁用按钮放上去,"看起来丰满",后端能不能实现后面再说。这是撑"目标B壳"的合法手段,但**目标A真系统的按钮必须真能用**,两者别混。
## 5. 高大上界面解法(孙总要求)
来源:界面设计优化讨论。诊断——**界面太寡淡、太急于功能化,逻辑没错但不够亮眼、不饱满**。解法:
1. **按钮升级**:朴素小按钮 → "大的案例"式按钮,参照跨境那套。
2. **素材前置**:主要位置做成素材陈列/任务展示,**看板化概念**,把重要素材前置。
3. **满满当当**:整体看起来充实,让用户第一时间有感知——"就算一开始没那么好用,但感觉满满当当"。
4. **降低沟通成本**:第一时间有感知 → 降低系统后续沟通难度,用户愿意往下用。
**本质**(孙总+说话人C卖希望、把希望具象化、把图先做了、图看起来高大上是老板视角。"面子和里子都要,但没有面子不行"。
## 6. 不做清单
避免跑偏,这些明确**不做**
- ❌ 竞品笔记数据全监控/自动抓小红书(合规反爬红线,已砍)
- ❌ 系统内 POC 验证(倩倩姐与北哥单独做)
- ❌ 自动发布到小红书(只产出达人素材交付包,人工发)
- ❌ 内置写死任何具体产品(系统通用,产品靠上传)
- ❌ 积分中心/billing 页MVP 免费)
- ❌ 前端展示 Token 余额/用量
## 7. 关键时间锚点
- **7/1今天周三**:孙总晚上给壳框架;倩倩姐今天就约北哥
- **7/10周五**:产品做出来、可访问
- **7/12周日**:内容状态冻结、壳确定
- **7/15周二**:孙总正式讲
> 距 7/15 仅 2 周、7 个工作日。所有排期只在工作日白天,紧迫度决定"先跑通再精修"(纵切片优先,见 CLAUDE.md 建法铁律)。