Files
yingqing/项目移交报告-2026-06-24.md
T
seaislee1209andClaude Opus 4.8 191cd1c3e5 docs: 移交报告再补 —— 产品视角/产品架构 + 功能模块间关系 + 脚本 Agent 运行机制
- 产品视角(§1.5):一句话定位(商品→可投放竖屏 AI 带货短视频的多租户 SaaS)+ 产品形态 +
  用户主路径 + 产品功能模块↔后端 app 对照 + 模块间数据/依赖关系图(Team 为根,实体→资产→引用主数据线)
- 脚本 Agent(§2.6):SSE 流式对话、skill 系统提示词、3 模式收敛结构化 ScriptDraft、工具卡+思考流事件、
  后端可靠抽 JSON、落库回填 script_entities 给下游、预扣额度+断连兜底、多模型

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:06:51 +08:00

356 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AirShelf 项目移交报告 · 2026-06-24
> 给接手的开发同学:这份是当前项目整体状况 + 我们这一程做了什么 + 还差什么的速览。
> 配合看仓库里已有的:[CLAUDE.md](CLAUDE.md)(工程约定/铁律)、[core/ARCHITECTURE.md](core/ARCHITECTURE.md)、[PRD.md](PRD.md)、[交接-AI生成Agent化-2026-06-17.md](交接-AI生成Agent化-2026-06-17.md)。
---
## 0. 一句话结论
**核心「商品 → 视频」生成全流程已经端到端跑通**(实测项目「电子吧唧 · 短视频 · v3」四段视频全部出片)。
所以**视频这条线暂时不用再投入**,可以先去做别的。下面第 5、6 节列了几个**已知小问题 + 临时依赖**,不阻塞主流程,回头清。
---
## 1. 项目是什么
- **AirShelf** —— AI 短视频带货生成平台。一条流水线把「一个商品」变成「可投放的竖屏带货短视频」。
- **真实开发目录在 [core/](core/)**(仓库根的 `电商AI平台/` 只是 UI 设计稿/视觉标准答案,不是运行代码):
- [core/frontend/](core/frontend/) —— React 19 + Vite + TS,真网站前端。
- [core/backend/](core/backend/) —— Django + DRF + Celery,后端 + 平台后台。
- [core/qa/](core/qa/) —— 截图对比测试。
- **部署**Gitea Actions[.gitea/workflows/deploy.yaml](.gitea/workflows/deploy.yaml))→ 打 Docker 镜像 → K8s。
- dev 分支 → **测试环境**:前端 `https://airshelf-web.test.airlabs.art`,推 dev 自动构建部署。
- 三个核心服务:`airshelf-core-api`Django)、`airshelf-core-worker`Celery)、`airshelf-core-web`nginx 托管 SPA + 反代 /api)。
### 生成流水线(5 阶段)
```
商品(选品) → 脚本(脚本 Agent 流式对话) → 实体提取(角色/场景) →
基础资产(人物立绘/三视图 · 场景图 · 商品三视图) → 故事板(分镜图) → 视频(Seedance 逐段出片)
```
### AI 链路(详见 CLAUDE.md「AI 生成 Agent 化架构」)
- **可插拔 Provider**:火山官方直连 `VolcanoArkProvider`(豆包/SeeDream/Seedance+ 通用中转站 `OpenAICompatibleProvider`yunqi/tokenssr)。分流在 [services.py](core/backend/apps/ai/services.py) `build_provider()`
- **默认模型**:图像 = `yunqi:gpt-image-2`;视频 = `doubao-seedance-2-0`;脚本/提取 = 豆包 doubao-seed-2.0-pro。
- **火山人像合规审核**:含人脸的素材(人物立绘/三视图/分镜图)自动送火山「人像素材库」审核,拿绿/红盾。
### 系统架构图
```
浏览器(SPA)
│ https
┌─────────────▼──────────────┐
│ airshelf-core-web (nginx) │ ← 托管打包好的 React 静态资源
│ ├─ /assets,/ → SPA(index.html, try_files 回落=客户端路由)
│ ├─ /api/ → 反代 Django
│ └─ /django-admin/,/static/ → 反代 Django(自带后台)
└───────┬──────────────┬──────┘
/api │ │ /api(异步任务也读写同库)
┌────────────────▼───┐ ┌──────▼─────────────────┐
│ airshelf-core-api │ │ airshelf-core-worker │
│ Django + DRF │ │ Celery(出图/出片/审核轮询)│
│ (gunicorn) │ │ │
└──┬────┬────┬───┬───┘ └──┬─────┬────────┬───────┘
│ │ │ │ │ │ │
MySQL │ TOS│ 火山│中转站 Redis MySQL 火山/中转站
(远程 │(对象│ ARK │(yunqi/ (broker)(同一库) (同上)
测试库)│存储)│直连 │ tokenssr)
│ │(豆包/ │
│ │ SeeDream/ │
│ │ Seedance) │
│ └─ 人像素材库 Assets API(审核 + asset:// 引用,与 Seedance 需同账号)
```
**后端 Django apps[core/backend/apps/](core/backend/apps/)**
`accounts`(团队/成员/邀请码/认证) · `products`(商品+商品图) · `projects`(项目/脚本/故事板/视频段/时间轴) ·
`assets`(资产+文件+模特库+审核) · `ai`(Provider/模型配置/AI任务/提示词模板/质量词/脚本Agent/各生成 service) ·
`billing`(团队账户余额/预扣/流水) · `adminpanel`(平台超管后台 API) · `common`(团队作用域 mixin/健康检查)。
**前端([core/frontend/src/](core/frontend/src/)**`App.tsx`(壳+路由) · `routes/pipeline.tsx`(5 阶段流水线主页,最大的文件) ·
`routes/admin/*`(平台后台) · `routes/products/projects/library`(商品/项目/成品库) · `components/`(共享组件) · `design-restraint.css`(设计 token/组件)。
> 数据/计费动作统一走「团队作用域」(`TeamScopedViewSetMixin`);生成统一「预扣额度 → 成功扣费 / 失败释放」。
---
## 1.5 产品视角:这到底是个什么产品 + 产品架构
### 一句话定位
**AirShelf 是一个「把一个商品,一键变成可直接投放的竖屏 AI 带货短视频」的多租户 SaaS 工具**。卖家上传商品图 + 填基本信息,平台用 AI 跑完「脚本 → 角色/场景/商品素材 → 分镜 → 视频」整条产线,产出带口播/音效的成片。按**团队**开户、按**额度(credit)**计费。
### 产品形态
- **多租户 SaaS**:邀请码注册 → 开团队(owner) → 拉成员(分角色/给额度) → 团队内共享商品/项目/素材/余额。
- **两层界面**:① 团队「工作台」(商品库 / 视频项目 / 图片创作 / 模特库 / 成品库);② 平台超管「治理后台」(`/admin`:邀请码/团队/用户/提示词/审核/任务/供应商/计费/额度/治理)。
### 用户主路径(产品流)
```
注册(邀请码) → 开/进团队 → 商品库传商品图 → 新建视频项目(选成片时长)
→ ① 脚本(脚本 Agent 对话出稿/改稿)
→ ② 提取角色·场景 → ③ 基础资产(立绘/三视图/场景图/商品三视图,过人像审核)
→ ④ 故事板(分镜图) → ⑤ 视频(Seedance 逐段出片) → 导出成片
```
### 产品功能模块(用户能看到的) ↔ 后端 app
| 用户模块 | 是什么 | 后端 app |
|---|---|---|
| 商品库 | 选品 + 商品图(一切素材的源头) | `products` |
| 视频项目(流水线) | 5 阶段把商品做成短视频 | `projects` + `ai` |
| 图片创作 | 模特上身图 / 平台套图 / 自由创作 | `assets` + `ai` |
| 模特库 | 复用的真人模特(立绘+三视图+声线) | `assets` |
| 成品库(资产库) | 所有产出图片/视频成品,按项目打包 | `assets` |
| 团队 & 计费 | 成员/角色/额度/余额/流水 | `accounts` + `billing` |
| 平台超管后台 | 跨团队治理 | `adminpanel` |
### 功能模块间的架构(数据/依赖关系)
```
Team(团队 · 一切的归属)
┌───────────────┬───────────────┬──────────────┬───────────────┐
billing.Account 成员/邀请码 Product(商品) Asset(资产库) Model(模特库)
余额/预扣 owner/admin/member └─ 商品图 图片/视频成品 立绘+三视图+声线
│ │(源头) ▲ ▲
│ 每次生成:预扣→扣费/释放 ▼ │ │ 引用
│ Project(视频项目)────────┘ │
│ ├ ScriptVersion → ScriptSegment(脚本/分镜:narration·dialogue·entity_refs)
│ ├ BaseAssetGroup(角色/场景/商品 基础资产,含人脸的送审)
│ ├ StoryboardVersion → StoryboardFrame(分镜图,送审)
│ ├ VideoSegment → VideoSegmentVersion(每段视频,可多版本)
│ └ Timeline(拼接导出,V2 再启)
└────────────────── ai.services 编排所有 AI 调用 ──────────────────┘
ModelConfig/Provider(火山/中转站) · AITask(每次生成一条,挂计费) · PromptTemplate(提示词) · 火山人像审核
```
- **一切挂在 Team 下**(团队作用域)。`Product` 是源头;`Project` 串起脚本/资产/故事板/视频;`ai` 模块编排所有 AI 调用并挂计费;`assets` 管资产+审核+模特库;`billing` 管钱。
-**产品的主数据线**:项目脚本提取出 `script_entities`(角色/场景/商品) → 决定要做哪些**基础资产** → 基础资产**过人像审核**拿 `asset://` 引用 → **故事板/视频**引用它**锁脸锁商品**。接手要懂的就是这一条「实体 → 资产 → 引用」贯穿始终。
---
## 2. 视频生成流程现状:✅ 顺畅,已跑通
实测 `电子吧唧 v3` 四段视频提交火山全部 ACCEPTED、正常出片。让它跑通的**关键认知**(接手必懂):
> **火山 Seedance 2.0 对「写实人脸」的原始图片直链会直接 400 拒**`InputImageSensitiveContentDetected`)。
> 含人脸的参考图(人物立绘、分镜图)**必须走「素材库引用」`asset://asset-xxx`**,而不是原始 TOS 直链。
> 素材库引用要求:① 资产已送审进库(有 `review_remote_id`processing 也行,不必等 active);② **素材库和 Seedance 必须同一个火山账号**(见第 5.2 节临时依赖)。
代码位置:[services.py](core/backend/apps/ai/services.py) `_seedance_ref_url()` / `_video_reference_images()`
### 视频提示词(admin 可改)
真正发给 Seedance 的正文长这样(admin「提示词」页的「视频」卡可改模板):
```
【设定】@图1是学生女主(角色),@图2是室友(角色),@图3是女生宿舍书桌(场景),@图4是商品(商品)。
【分镜】根据@图5分镜图生成「电子吧唧」短视频。
【脚本】画面:… / 台词:室友:… / 学生女主:…
电商带货短视频,商品露出清晰,节奏有转化感。不要字幕,不要背景音乐,但是要有音效,逼真的音效。
```
- 时长/比例(duration/ratio/resolution**是 API 参数单独传**,不写进正文。
- 对白带说话人、照脚本原样放(不再拍扁成一行口播)。
---
## 2.5 提示词体系(admin 6 条模板 + 数据结构/数组)
提示词**不再写死**:admin「提示词」页存「一段固定模板 + 几个 `{占位符}`」,生成时把角色/场景/商品/脚本等**自动塞进占位符**,拼成最终发给模型的正文。代码在 [services.py](core/backend/apps/ai/services.py) `render_prompt()` / `prompt_ratio_size()`(DB 模板覆盖代码写死默认;模板删了/停用就回落默认,零回归)。比例靠模板的 `ratio` 字段 → gpt-image 尺寸(`_RATIO_TO_SIZE`)。
### 6 条模板(DB 当前值)
| key | 名称 | 比例→尺寸 | 占位符 | 模板正文 |
|---|---|---|---|---|
| `person_portrait` | 人物立绘 | 竖2:3→1024×1536 | `{描述}` | 电商真人模特,氛围正面全身照,**{描述}**,自然妆容,柔和影棚光,真实质感,单人,纯色背景 |
| `person_triview` | 人物三视图 | 16:9→1536×864 | (无,靠参考图1) | 参考图1角色,生成角色三视图:胸像特写/全身正面/侧面/背面,白色背景 |
| `product_triview` | 商品三视图 | 16:9→1536×864 | `{商品}` `{补充}` | 参考图1是「**{商品}**」真实主图。严格参照生成三视图:正面/侧面/背面,纯白背景,**{补充}** |
| `scene` | 场景图 | 16:9→1536×864 | `{场景描述}` | **{场景描述}**(外层风格可在 admin 包) |
| `storyboard_frame` | 分镜图 | 竖2:3→1024×1536 | `{设定}{场景上下文}{时长}{脚本}{补充}` | **{设定}**根据脚本生成导演故事板…(保持各参考图同一张脸/同一商品);竖屏 9:16 |
| `video_segment` | 视频 | 竖屏(参数) | `{设定}{分镜}{脚本}{时长}` | **{设定}{分镜}**【脚本】**{脚本}**\n电商带货短视频…不要字幕/背景音乐,要逼真音效 |
> ⚠️ 占位符是「调用字段」,**改模板时别删它们**(删了运行时原样保留、不会崩,但就拼不进内容了)。视频的时长/比例是 **API 参数**(duration/ratio),不在正文。
### 关键数据结构(占位符背后的「数组」)
脚本 Agent 产出结构化 `ScriptDraft`,落 `ScriptVersion.metadata` + 逐镜 `ScriptSegment`,并回填 `project.metadata` 供下游:
- **`project.metadata.script_entities`** —— 提取出的角色/场景/商品实体数组(占位符 `{设定}`/参考图来源):
```json
[{"id":"c1","type":"character","name":"学生女主"},
{"id":"c2","type":"character","name":"室友"},
{"id":"p1","type":"product","name":"电子吧唧"},
{"id":"s1","type":"scene","name":"女生宿舍书桌"}]
```
- **`ScriptSegment.entity_refs`** —— 本镜引用的实体 id 数组:`["c1","c2","p1","s1"]`(决定本镜带哪些参考图)。
- **`ScriptSegment.dialogue`** —— 结构化对白数组(视频 `{脚本}` 的台词,照原样带说话人):
```json
[{"speaker":"c2","line":"你偷偷跟谁聊天呢?老实交代!"},
{"speaker":"c1","line":"哎呀你别瞎想!"}]
```
`speaker` 是实体 id,渲染时用 `script_entities` 解析成名字;另有扁平 `narration` 兜底。)
- **`ScriptSegment`** 其它:`visual_prompt`(画面)、`product_exposure`(商品露出)、`duration_seconds`、`sort_order`。
- **视频 `reference_images` 数组**(传给 Seedance,与提示词 `@图N` 顺序严格对齐):
`["asset://asset-…(角色)", "asset://asset-…(角色)", "https://…(场景)", "https://…(商品)", "asset://asset-…(分镜图)"]`
—— **含人脸的(角色/分镜图)走 `asset://` 素材库引用,无脸的(场景/商品)走原始直链**(见第 2 节)。
---
## 2.6 脚本 Agent 怎么运行(出稿 + 改稿一体,流式对话)
代码:[script_agent.py](core/backend/apps/ai/script_agent.py)。端点 `POST /api/projects/{id}/script-agent-stream/` → **SSE 流**`text/event-stream`DRF 必须挂 `ServerSentEventRenderer` 否则 406)。
**它不是「调一次函数返回 JSON」,而是一个边想边吐的流式 agent**:
1. **系统提示词 = 电商脚本 skill**:加载 [core/backend/skills/ecommerce-video-script/](core/backend/skills/ecommerce-video-script/) 的 `SKILL.md + references` 当领域知识(模型无关)。⚠️ **skill 必须在 `core/backend/` 内**,否则不在镜像构建上下文里 → 系统提示词为空 → 退化乱出(这就是之前线上提取/脚本翻车的根因之一)。
2. **3 种输入模式,收敛到同一份结构化 `ScriptDraft`**
- `auto` 全自动(只给商品 + 卖点)· `theme` 一句话主题 · `revise` 改稿(基于某个基准版)。
- 改稿带 `target_index` = **精准只改第 N 镜**,后端 `_merge_single_segment` **强制保留其余镜原样**`0` 是合法镜号,判断一律 `is None` 不用真值)。
3. **流式吐「工具卡 + 思考」给真 agent 体感**SSE 事件,见 script_agent.py 头部):
`tool`(加载skill→分析商品→生成分镜→提取实体)· `reasoning`(推理模型思考流,逐字、纯展示不进答案)· `delta`(自然语言前言)· `draft`(规范化后的稿)· `saved`(已落库)· `summary`(模型自己写的收尾交付语)· `done` / `error`。
> 其中 `reasoning` 是关键体验修复:推理模型出 JSON 前会先「想」很久,把思考逐字下发,避免前端「卡在生成分镜」假死。
4. **JSON 由后端可靠抽取,不靠模型排版**:`normalize_draft` / `_extract_json`(括号配平、字段模糊匹配 `_pick_field`、时长吸附到 `[15,30,60,90]`、抽实体)。模型排版再乱也能稳定拿到结构化稿。
5. **结构化 `ScriptDraft` 契约**`narration`(扁平口播兜底)+ `dialogue:[{speaker,line}]`(带说话人对白)+ `role/tone/product_exposure/entity_refs/total_duration`。
6. **落库 + 回填**`persist_script_draft`):写 `ScriptVersion.metadata`hook/tone/entities+ 逐镜 `ScriptSegment`,并把 `cast/scenes/script_entities` **回填 `project.metadata`** —— 下游(提取/资产/故事板/视频)全靠这份回填。
7. **计费 + 断连兜底**:走 `AITask` + 额度**预扣 → 成功扣费 / 失败释放**。客户端中途断连会抛 `GeneratorExit`(是 `BaseException`,普通 `except` 抓不到)→ 用 `try/finally` 释放预扣,**绝不冻结额度**。
8. **多模型可选**`model_config_id` 切不同脚本模型(默认豆包 doubao-seed-2.0-pro)。
> 一句话:**前端点「生成脚本」→ 后端起一个流式 agent,边加载 skill / 分析商品 / 出分镜,边把工具卡和思考推给前端;最后后端把模型输出可靠抽成结构化脚本、落库、回填给下游**。整条产线后续所有阶段都吃这份脚本回填的 `script_entities`。
---
## 3. 我们这一程做了什么(2026-06-22 ~ 06-24
按模块归类(完整见 `git log`,均带 Claude 署名):
**提取(角色/场景)**
- 实体提取改**异步 worker + 轮询**,根治线上 502 / 刷新丢 loading / 重复扣费。
- skills 随后端打进镜像(之前放仓库根 → 镜像里没有 → 系统提示词为空 → 提取吐散文解析失败)。
- 锁定豆包 2.0 Pro + 写死 JSON 输出契约兜底。
**视频(本程重点,让它跑通)**
- ⭐ **真人/分镜图走素材库 `asset://` 锁脸**,根治 Seedance「人物/场景全错」。
- 提交报错**接住返 JSON、不再 500 白屏**;分镜图 processing 态也能走 asset://。
- 视频卡交互反馈(重跑转圈、防连点双扣)、「全部重跑」真重跑已完成段、「共 N 版」入口。
- 视频卡用首帧当封面(`#t=0.1`),不再空白占位。
- 视频提示词:台词带说话人、时长/比例只走参数。
**故事板**
- 整张生成时每张分镜转圈(不全屏遮挡)、未生成占位回 2:3 竖屏。
- ⭐ 分镜图挂**火山人像审核盾** + 红盾可「重新送审」(审核超时是误判,重提即过)。
**商品**
- ⭐ 建商品改 **upload-first**(图先进桶拿 asset,创建时带 `cover_asset`+`images` 一块落库),根治「商品创建失败」。
- 商品图删除接通(之前叉子是纯 CSS 装饰没绑事件)+ 至少保留一张。
**图片比例 / admin**
- admin「提示词」页:视频线 6 条生图/视频提示词正文 + 比例**可在后台改,不再写死**。
- 真 16:9 支持(`1536x864`,原来误当 3:2);人物三视图/商品三视图/场景图默认设成 16:9(分镜图/立绘/视频保持竖屏)。
- 脚本按向导选的时长出(之前写死 60 秒)。
---
## 4. 怎么跑起来(接手速记)
**本地后端(连真测试库,不是隔离 sqlite)**
```bash
cd core/backend
DJANGO_SETTINGS_MODULE=airshelf.settings.development .venv/bin/python manage.py runserver 127.0.0.1:8010 --noreload
```
**本地前端**`cd core/frontend && npm run dev`5173HMR/api 走 8010)。
**跑测试**(远程库无建库权限,必须 sqlite)
```bash
cd core/backend
DB_ENGINE=sqlite DJANGO_SETTINGS_MODULE=airshelf.settings.test .venv/bin/python manage.py test
```
**部署**:推 dev → Gitea Actions 自动构建 + 跑迁移 + 滚动部署。**默认不推,改完即停,明确说推才推**(CLAUDE.md Git 铁律)。
> 注:本机用的是 python-build-standalone 的 CPython 3.12(系统自带 3.9 跑不了 Django 5),venv 在 `core/backend/.venv`。
---
## 5. 已知问题 / 待办(不阻塞主流程,回头清)
### 5.1 ⚠️ Admin 页刷新报「找不到网页」(404)—— 根因已定位,修法明确
**现象**:在 `/admin/...`(如 `/admin/prompts`)刷新页面 → 404。点链接进去没事(前端路由),一刷新就挂。
**根因**:路径冲突。
- React 平台后台用的是客户端路由 `/admin`、`/admin/prompts`、`/admin/teams` …
- 但 nginx[core/frontend/nginx.conf](core/frontend/nginx.conf))里有 `location /admin/ { proxy_pass …api }`,把 `/admin/` **反代给了 Django**
- Django[core/backend/airshelf/urls.py](core/backend/airshelf/urls.py))只有 `path("admin/", admin.site.urls)`(Django 自带后台),找不到 `/admin/prompts` → 404。
**推荐修法**(把 Django 自带后台挪开,让 `/admin/*` 回落 SPA):
1. `urls.py``path("admin/", admin.site.urls)` → `path("django-admin/", admin.site.urls)`
2. `nginx.conf``location /admin/` → `location /django-admin/`。
这样 `/admin/*` 落到底部 `try_files $uri $uri/ /index.html`SPA 路由),刷新就正常了。
> 约 10 分钟的小改。要的话可以直接做。
### 5.2 ⚠️ 临时借 AirDrama 火山账号(**待换自有,最该尽快处理的基建项**)
- **真人素材库审核** 用的是借来的 AirDrama 账号 AK/SK`.env` 的 `ASSETS_API_*`)。
- **视频 Seedance** 我们临时也指到 AirDrama 账号(`.env` 的 `VIDEO_ARK_API_KEY`,仅覆盖 video 能力,见 [services.py](core/backend/apps/ai/services.py) `build_provider`)—— 因为 `asset://` 素材库引用必须和 Seedance 同账号才解析得到。
- **终态**:等自有火山账号开通「人像素材库(Assets API)」后,把 `ASSETS_API_*` 换成自有账号 AK/SK,并删掉 `VIDEO_ARK_API_KEY` 这行(视频自动回落自有 `VOLCANO_ARK_API_KEY`)。CLAUDE.md 里记的「待张业昌换」就是这个。
### 5.3 视频封面:后端抽帧没产出 poster(前端已兜底)
- 后端 [services.py](core/backend/apps/ai/services.py) `_generate_video_poster` 本应抽视频首帧存成封面图,但当前环境**没产出 poster 文件**(大概率缺 ffmpeg/抽帧依赖)。
- 现在靠前端 `<video src=…#t=0.1>` 让浏览器渲染首帧当封面,已经能看。要更稳/要真 poster 再补后端抽帧依赖。
### 5.4 质量词页(admin)半接状态
- admin「质量词」页目前**只喂 `model_tryon`(模特上身)**一处;人物/故事板/视频的质量词已经不接了(提示词改走「提示词」页)。
- 现状不影响生成(质量词全空也不报错)。回头要么把它清成只留 model_tryon,要么并进「提示词」页统一管。
### 5.5 线上建商品(需接手同学复核一次)
- upload-first 修复已推 dev、线上 bundle 实测**含新代码**(旧「先建后传」drawer 已无)。
- 之前有同事报「线上还是失败」,排查下来最可能是**测试时部署没完成 / 浏览器开着旧标签缓存**。请接手后**硬刷新**Cmd/Ctrl+Shift+R)在 `airshelf-web.test.airlabs.art` 再建一次(记得拖图、等图转圈→完成再点创建)确认。若仍失败,开 F12 Network 看是 `/api/assets/upload/` 还是 `/api/products/` 挂、什么状态码。
---
## 6. 团队管理现状 + 缺什么
**这个项目是按团队 + 平台超管两层来管的,地基是齐的:**
已有([apps/accounts/models.py](core/backend/apps/accounts/models.py) + [apps/billing/](core/backend/apps/billing/) + admin 后台):
- **Team**(团队,有 owner、状态、通知偏好);
- **TeamMember**(成员,角色 owner/admin/member、状态、**每人月度额度** `monthly_credit_limit`);
- **Invitation**(邀请码:超管发「开团码」= 新用户注册即开新团队当 owner;团队 owner 发「入团码」);
- **计费**:每团队一个 billing `Account``balance` + `reserved_balance`),生成走**预扣 → 成功扣费 / 失败释放**(`CreditReservation` + 流水);
- **平台超管后台**`/admin`,分阶段已上线):概览 / 邀请码 / 团队 / 用户 / 提示词 / 质量词 / 资产审核 / 任务监控 / 模型供应商 / 计费审计 / 额度策略 / 治理。
> 💡 **团队管理这块可直接参考现有的 AirDrama 项目** —— 它的团队/成员/额度/计费这套已经成熟,照着补我们缺的部分即可,不用从零设计。
**可能缺 / 待复核(接手可以扫一遍确认):**
- **团队主自助管理**:团队 owner 在「前台」自助改团队名/管成员/看本团队用量的页面是否完整(很多管理动作目前集中在平台超管后台)。
- **充值/加额闭环**:团队余额怎么充?目前看到的是**注册发试用额度** + 超管手动调额;有没有「自助充值」入口要确认(可能本期不做)。
- **认证**:登录/注册是「用户名 + 密码 + 邀请码」,**有意不做邮箱**(CLAUDE.md 有定调:2026 中国市场);**手机号注册后续再做,本期未做**。
- **5.1 的 admin 刷新 404** 也属于团队/后台体验问题,建议先修。
---
## 7. 其他要提醒接手同学的点 / 风险
- **`.env` 进 git 且含真实密钥**`core/backend/.env` 被**有意放行进版本库 + 打进 CI 镜像**(`.gitignore` 里 `!core/backend/.env`),里面是真密钥(火山/TOS/中转站/TTS)。这是当前团队**有意为之**(就内部几人用)。移交时**提醒新人别外传仓库**,长期建议改走 K8s Secret / CI 注入。
- **关于「连远程库」和「跑测试」(澄清一个易混点)**:
- **应用本身**(本地 development / 线上)**直连远程测试 MySQL**,读写**现有库**没问题 —— 本报告里所有「真实数据验证 / 真跑 ARK·Seedance 接口」都是这么连着远程库做的。
- **但 Django 的单元测试运行器**(`manage.py test`)会**临时 CREATE 一个一次性测试库再删掉**,这一步需要 `CREATE DATABASE` 权限,而**这个 MySQL 账号没有该权限**(不是不能读写现有库,是不能建新库)。所以**单元测试走 `DB_ENGINE=sqlite`**(本地隔离、不碰远程库、跑得快)。两者不矛盾:一个是「用现有库」,一个是「建临时库」。
- 💡 **远程库 + 本地连接这套是你(之前那位小伙伴)搭的**,接手同学如需调连接/权限找你对齐。改远程库数据请小心(线上和本地共用同一套)。
- **skills 必须放 `core/backend/` 内**:镜像由 `./core/backend` 构建,skills 放仓库根会不在构建上下文 → 提示词加载为空。提取/脚本两套 skill 都在 [core/backend/skills/](core/backend/skills/)。
- **设计规范铁律**:改任何页面/CSS 前先读 [电商AI平台/design.md](电商AI平台/design.md),用现成组件、单橙锚点、8px 圆角、不写裸 hex。详见 CLAUDE.md。
- **审核超时**:含人脸素材送审后若长时间没人轮询(之前故事板趴不轮询)会被本地超时兜底标「未过审」——这是误判,红盾点「重新送审」即可(现已加故事板趴轮询)。
---
## 8. 已有文档索引(别重复造轮子)
| 文档 | 内容 |
|---|---|
| [CLAUDE.md](CLAUDE.md) | 工程约定 / 设计铁律 / AI 链路架构 / 认证定调(**接手必读**) |
| [core/ARCHITECTURE.md](core/ARCHITECTURE.md) | 后端架构 |
| [PRD.md](PRD.md) | 产品需求 |
| [交接-AI生成Agent化-2026-06-17.md](交接-AI生成Agent化-2026-06-17.md) · [AI生成-Agent化落地方案.md](AI生成-Agent化落地方案.md) | AI 生成 Agent 化的设计与落地 |
| [image调用参考.md](image调用参考.md) · [tokenssr接口文档.md](tokenssr接口文档.md) | 图像/中转站接口参考 |
| [性能审计报告-AirShelf-2026-06-19.md](性能审计报告-AirShelf-2026-06-19.md) · [UI还原对比报告-AirShelf-2026-06-19.md](UI还原对比报告-AirShelf-2026-06-19.md) | 性能 / UI 还原审计 |
| [电商AI平台/design.md](电商AI平台/design.md) | 设计规范 SSoT |
---
## 9. 给接手同学的建议优先级
1. **先确认主流程**:本地(或线上硬刷新后)走一遍 商品→脚本→提取→资产→故事板→视频,确认四段出片。
2. **修 5.1 admin 刷新 404**10 分钟,体验问题)。
3. **跟进 5.2 自有火山账号**(基建,影响长期;目前借号能跑,但要尽快换)。
4. 5.3 / 5.4 / 5.5 看排期清。
5. 视频线既然通了,可按团队安排去做**别的模块**(如团队自助管理 / 充值闭环 / 手机号注册等本期未做项)。
— 本报告由本程结束时整理(2026-06-24)。有不清楚的,仓库 `git log`(带 Claude 署名的提交)每条 message 都写了「改了什么 + 根治什么」,可逐条回看。