43 KiB
AirShelf 完整交接文档
文档日期:2026-08-12
代码基线:dev分支,f2114bc36ec1e2b472164145cb8d40660af01969
最新提交:fix: 修正模型超时与结果未知重放(2026-07-21)
文档性质:当前代码事实、历史资料、现场验证结果与待人工确认项的统一交接入口
安全声明:本文不包含真实密钥、密码、数据库连接值或用户数据
0. 如何使用这份文档
这份文档是 AirShelf 当前的主交接入口,用来替代对 2026-06-17 和 2026-06-24 旧交接报告的盲目依赖。旧报告仍有历史价值,但其后已新增 106 个提交和 23 个数据库迁移,“已完成/待办/默认模型/账号依赖”均可能过期。
事实优先级:
- 当前运行代码、数据迁移和部署配置。
- 后端架构 和 前端架构。
- 本文的基线、验证和风险清单。
- PRD 和 顶层架构决策:用于理解目标,不自动等于已实现。
- 历史交接、TODO、bug 和完成报告:用于追溯决策,不得单独当成当前状态。
本次不读取 .env、account.md、线上数据库和任何用户上传文件;运行时 Provider 开关、默认模型、余额和外部账号状态必须在管理后台和实际环境中二次确认。
1. 执行摘要
1.1 一句话定位
AirShelf 是一个面向中国电商卖家、运营团队和 MCN 的多租户 AI 内容生产平台:以商品为输入,通过脚本、基础资产、故事板、视频片段和导出五阶段流水线,生成可管理、可计费、可追溯的带货图片和短视频资产。
1.2 当前结论
- 项目已从静态设计稿进入真实 React + Django 产品化阶段。
- 商品、项目、脚本 Agent、资产、故事板、视频、自由创作、模特库、积分计费、通知和平台超管都有实作代码。
- 历史文档记录了商品到 Seedance 出片的真实端到端验证,但本次没有重跑线上 Provider 和生产数据。
- 当前代码可通过 Django system check、前端生产构建和最新模型路由核心测试,但后端全量测试尚未全绿。
- 当前最大的交接风险不是“没代码”,而是密钥管理、生产分支与 CI 不一致、测试环境仍依赖外部 Redis、缺少正式回滚/备份 Runbook,以及多个超大文件已进入高维护成本区。
1.3 基线数据
| 指标 | 当前值 |
|---|---|
| Django 业务 app | 9 |
| 扫描到的核心模型类 | 51 |
| Celery 任务 | 11 |
| 前端调用的 API 路径 | 约 153 |
前端 src 文件 |
71 |
| 后端 app Python 文件 | 221 |
| 数据库迁移文件 | 64 |
| 后端测试文件 | 30 |
| Django 发现的测试数 | 545 |
| settings 读取的环境变量 | 66 |
.env.example 未覆盖的已用变量 |
18 |
2. 产品范围与业务对象
2.1 用户与租户
- 一切业务数据以
Team为租户边界。 - 登录/注册采用“用户名 + 密码”,不使用邮箱作为主登录标识。
- 注册是邀请制,邀请码分为加入已有团队和创建新团队两类。
- 团队角色:
owner/admin/member/viewer。 - 平台超管是用户维度,与团队角色分离。
- 后端使用 DRF Token Authentication,不是 JWT,也没有 refresh token 轮换链路。
2.2 核心业务对象
Team
├─ User / TeamMember / Invitation
├─ CreditAccount / CreditLedger / CreditReservation / QuotaPolicy
├─ Product / ProductImage / ProductSellingPoint
├─ Model(模特库)
├─ Asset / AssetFile / AssetUsage / AssetReviewGroup
└─ Project
├─ ProjectStage
├─ ScriptVersion / ScriptSegment
├─ BaseAssetGroup
├─ StoryboardVersion / StoryboardShot / ShotVersion
├─ VideoSegment / VideoSegmentVersion
└─ Timeline / SubtitleTrack / BgmTrack / ExportJob
2.3 用户可见模块
| 模块 | 能力 | 主要代码 |
|---|---|---|
| 登录/注册 | 邀请码校验、Token 登录、记住我 | accounts、auth-screen.tsx |
| 工作台 | 概览、最近项目、资产与余额摘要 | dashboard.tsx |
| 商品库 | 创建、图片、卖点、详情、关联项目、垃圾桶 | products |
| 模特库 | 模特录入、立绘、三视图、审核、引用 | assets.Model、models.tsx |
| 视频项目 | 新建项目、五阶段生产管线 | projects、pipeline.tsx |
| 图片创作 | 自由生图、模特上身图、平台套图、会话与批次 | ai-tools.tsx |
| 自由视频 | 文/图/首尾帧/音频参考、任务轮询、重生、下载 | free-create.tsx |
| 资产库 | 图片、视频、项目资产包、收藏/入库 | library.tsx |
| 垃圾桶 | 商品、项目、资产、任务的恢复与最终删除 | trash.tsx |
| 账户/团队 | 积分、流水、成员、限额、邀请、登录设备 | billing、accounts |
| 消息/设置 | 生成失败、余额、登录等通知和用户偏好 | ops、settings.tsx |
| 平台超管 | 团队、用户、邀请、模型、提示词、资产审核、任务、计费、完整性 | adminpanel |
2.4 明确未形成闭环的商业能力
/api/billing/recharge/会直接根据人民币金额和积分汇率入账,当前是手动/内部充值语义,没有微信、支付宝或第三方支付回调校验。- 手机号注册和登录本期未实现。
- 没有完整的订单、发票、退款审批和支付对账子系统。
- 未发现 OpenAPI/Swagger 自动合同,前后端类型目前主要靠手工同步。
3. 代码仓库与资料地图
AirShelf/
├─ core/
│ ├─ frontend/ React 19 + Vite 7 + TypeScript 真实业务前端
│ ├─ backend/ Django + DRF + Celery 后端
│ ├─ qa/ 视觉对比和功能审计工具
│ ├─ docs/ 专项技术资料
│ └─ ARCHITECTURE.md 早期顶层架构决策,不等于当前实现
├─ 电商AI平台/ HTML 设计稿与视觉规范,不是真站业务代码
├─ k8s/ K8s/K3s 部署清单
├─ .gitea/workflows/ Gitea Actions 构建与部署
├─ docs/todo/ 可用的专项完成说明
├─ docs/bug_todo/ 详细实施/问题过程记录,不代表当前待办
├─ docs/agents_todo/ Agent 协同实施方案
├─ tools/architecture-sync/ 架构文档差异扫描和验证
├─ PRD.md 产品目标与验收定义
├─ AGENTS.md / CLAUDE.md 工程约定、设计铁律、Git 流程
└─ 本文 当前统一交接入口
重要边界:
- 真实开发只改
core/frontend和core/backend。 电商AI平台/*.html只是视觉标准答案,不在里面接 API 或开发新功能。- 涉及页面和 CSS 的任务,必须先阅读 设计规范,并对照同名 HTML 设计稿。
- AI Skill 必须放在
core/backend/skills/内,否则不在后端 Docker build context 中。
4. 系统架构
4.1 运行拓扑
浏览器
→ Traefik / HTTPS Ingress
→ airshelf-core-web(Nginx)
├─ /assets、/、SPA 路由 → React 静态资源
├─ /api/* → airshelf-core-api:8000
├─ /django-admin/* → airshelf-core-api:8000
└─ /static/* → airshelf-core-api:8000
airshelf-core-api
├─ MySQL:业务事实、任务、计费、资产元数据
├─ Redis DB0:Django cache
├─ Redis DB1:Celery broker
├─ Redis DB2:Celery result backend
├─ Redis DB3:业务锁
├─ TOS:图片、视频、封面、导出文件
├─ 火山 ARK / Assets / TTS
└─ OpenAI-compatible 中转 Provider
airshelf-core-worker
└─ Celery 并发 4,复用 API 镜像和同一数据库/配置
4.2 技术栈
| 层 | 当前实现 |
|---|---|
| 前端 | React 19.2、TypeScript 5.9、Vite 7.2/7.3、Lucide React |
| 路由 | 自研 History API 路由,未使用 React Router |
| 前端状态 | React state/effect,无 Redux/Zustand/TanStack Query |
| 请求层 | 原生 fetch 封装为 api / adminApi |
| 后端 | Python 3.12 镜像、Django 5.0–5.1、DRF 3.15 |
| 异步任务 | Celery 5 + Redis |
| 数据库 | MySQL;测试数据库可切 SQLite |
| 对象存储 | 火山 TOS,通过 boto3/S3 协议适配 |
| AI | 火山 ARK 直连 + OpenAI-compatible Provider + 火山 TTS |
| 媒体 | FFmpeg + Pillow + Noto CJK |
| API 容器 | Gunicorn:3 workers × 4 threads,300s timeout |
| Web 容器 | Node 20 构建,Nginx Alpine 托管 |
| 集群 | K3s/Kubernetes + Traefik + cert-manager |
| CI/CD | Gitea Actions + 火山镜像仓库 |
4.3 当前 K8s 容量
| Deployment | 副本 | 资源 |
|---|---|---|
airshelf-core-api |
1 | request 250m/512Mi,limit 1500m/2Gi |
airshelf-core-worker |
1 | request 100m/512Mi,limit 1000m/2Gi |
airshelf-core-web |
1 | request 20m/32Mi,limit 150m/128Mi |
当前 API、Worker、Web 都是单副本;Worker 没有按图片、视频、导出拆分队列,也没有独立 Celery Beat Deployment。
5. 后端架构
5.1 Django app 职责
| App | 职责 | 主要模型 |
|---|---|---|
common |
UUID/时间/团队归属基类、分页、健康检查 | UUIDModel、TimeStampedModel、TeamOwnedModel |
accounts |
用户、团队、成员、邀请码、偏好、会话、超管审计 | User、Team、TeamMember、Invitation、LoginSession |
products |
商品、商品图、卖点、软删除 | Product、ProductImage、ProductSellingPoint |
assets |
业务资产、TOS 文件、模特库、审核、标签、使用关系、自由资产 | Asset、AssetFile、Model、AssetReviewGroup |
projects |
项目和五阶段业务状态 | 脚本、资产组、故事板、视频版本、时间线、导出 |
ai |
Provider、模型、生成任务、真实调用审计、Agent、生图/生视频/TTS | ModelProvider、ModelConfig、AITask、AIModelAttempt |
billing |
积分账户、预留、扣费、释放、充值、限额、差异化定价 | CreditAccount、CreditLedger、CreditReservation、BillingConfig |
ops |
站内通知和通知补齐 | Notification |
adminpanel |
跨团队平台治理 API | 复用各业务模型 |
5.2 一级 API
/api/health/ 浅层健康检查
/api/auth/ 注册、登录、个人、会话、团队、邀请
/api/products/ 商品 CRUD、图片、素材、垃圾桶
/api/assets/ 资产、批次、分面、审核、入库、垃圾桶
/api/models/ 模特库、立绘、三视图
/api/projects/ 项目 CRUD 和五阶段所有 action
/api/billing/ 积分摘要、流水、充值、趋势、计价配置
/api/ai/ 生图、自由视频、任务、模型、图片会话
/api/ops/ 消息列表、已读/未读、归档
/api/admin/ 平台超管治理 API
/django-admin/ Django 自带后台
前端平台后台使用 /admin/*;Django Admin 已迁到 /django-admin/,不要改回 /admin/,否则会再次破坏 SPA 刷新。
5.3 项目流水线主要 action
- 脚本:
script-agent-stream、adopt-script、update/rerun/add/delete-script-segment。 - 实体:
extract-entities、extract-status。 - 基础资产:
generate-base-asset、pending-assets、adopt/attach/delete-base-asset、generate-triview。 - 审核:
poll-reviews、video-review-precheck。 - 故事板:
generate-storyboard、rerun-storyboard-shot、adopt-storyboard-shot-version、poll-storyboard、skip-storyboard。 - 视频:
submit/poll-video-segment、adopt-video-version、upload-video-segment。 - 后期:
generate-voiceover、upload-bgm、save-timeline、submit/poll-export。 - 生命周期:
trash、restore、purge。
5.4 Celery 任务
ai:
submit_ai_task
poll_ai_task
extract_entities_task
generate_base_asset_task
generate_triview_task
generate_model_triview_task
generate_standalone_image_task
poll_free_video_task
projects:
poll_video_segment_task
run_export_job_task
ops:
ensure_team_notifications_task
任务最终事实以 MySQL 中的 AITask、项目版本和资产为准,不能仅依赖 Celery result backend。
6. 五阶段生产链路
6.1 Stage 1:脚本
Product + 卖点 + 用户主题/改稿意图
→ 加载 core/backend/skills/ecommerce-video-script
→ 流式文本 Provider
→ 解析和归一化 ScriptDraft
→ ScriptVersion + ScriptSegment
→ 回填 project.metadata.script_entities
脚本 Agent 支持 auto / theme / revise 三种模式,也支持 target_index 精准只修某一镜。结构化脚本包含旁白、对白、说话人、画面、商品露出和实体引用。
SSE 事件会包含工具/进度、文本增量、草稿、保存结果、完成或错误。不同历史文档中对事件名的描述略有差异,前端和后端当前协议应以 script_agent.py、projects/views.py 和 api.ts 为准。
6.2 Stage 2:基础资产
- 实体提取将脚本中的角色、场景和商品转换为稳定 ID。
- 角色生成立绘和单张 16:9 三视图;商品和场景也可生成对应资产。
- 已采用基础资产通过
BaseAssetGroup与实体关联,供故事板和视频复用。 - 模特库
Model已与脚本角色解耦,模特是可跨项目复用的团队资产。
6.3 Stage 3:故事板
- 每个脚本镜头可生成多个
StoryboardShotVersion并选用一版。 - 参考图按
entity_refs组合角色、场景和商品,提示词中的@图N必须与参考图数组顺序一致。 - Provider 支持图片编辑时优先走多图编辑,不支持时才回退纯文生图。
6.4 Stage 4:视频
- 每个
VideoSegment可有多个版本,用户可重生和采用。 - 含真人参考的图片需先进入火山人像素材库,视频模型使用
asset://引用来避免真人直链被拒。 - 素材库与 Seedance 调用必须属于可互相解析的同一火山账号体系。
- 已取得远程任务 ID 后,只轮询真正提交成功的 Provider/模型,禁止因为本地等待超时而重复提交高价任务。
6.5 Stage 5:后期与导出
Timeline/TimelineClip保存片段排列。- 可配置字幕、BGM 和配音。
ExportJob交给 Celery,使用 FFmpeg 拼接并生成最终资产。- 后端镜像已安装 FFmpeg 和 Noto CJK,避免线上导出缺二进制或中文字体。
7. AI Provider、重试、Fallback 与审计
7.1 Provider 适配层
AIProvider Protocol
├─ VolcanoArkProvider 火山文本/图片/视频官方直连
├─ OpenAICompatibleProvider YunQi、TokenSSR 和其他 OpenAI-compatible 网关
├─ YunqiProvider 保留的 YunQi 特定适配
└─ VolcanoTtsProvider 火山配音
ModelProvider 保存供应商,ModelConfig 保存模型能力、价格、状态和路由元数据。业务代码不应假设某个固定模型永久默认;运行时结果以数据库和平台后台为准。
7.2 统一调用流程
用户选择模型 / 系统默认模型
→ 创建一个 AITask
→ 预留一次积分
→ 调用主模型
├─ 明确失败:按策略重试,再按模型 metadata 决定是否 Fallback
└─ 远程结果未知:立即停止重放和 Fallback
→ 每次真实请求写一条 AIModelAttempt
→ 成功:保存资产/版本,最终扣费一次
→ 失败或结果未知:释放原预留
7.3 当前默认策略
| 能力 | 重试 | 单次超时 | 总时限 |
|---|---|---|---|
| 文本 | 等待 1s / 3s,最多重试 2 次 | 普通 120s,流式 300s | 480s |
| 图片 | 等待 3s,重试 1 次 | 300s | 900s |
| 配音 | 等待 2s,重试 1 次 | 60s | 180s |
| 视频提交 | 拿到任务 ID 之前等待 3s,重试 1 次 | 120s | 300s |
| 视频轮询 | 不重提交 | 60s/次 | 以 Provider 终态为准 |
单个逻辑任务默认最多尝试 3 个模型、5 次真实请求。修改策略后必须同时重启 API 和 Worker。
7.4 结果未知保护
ReadTimeout、发送后断线、HTTP 502/504 或响应丢失可能意味着上游已经创建任务。当系统无法确认上游未处理时,必须停止重试和 Fallback,避免重复出片和重复平台成本。
7.5 调用审计
AIModelAttempt 与 AITask 是多对一关系,记录:
- 调用顺序,首次/重试/Fallback。
- Provider 和真实模型快照。
- 操作、状态、耗时、错误分类和上游任务 ID。
- 用量、平台成本、脱敏请求/响应摘要。
管理员可在 /admin/tasks 查看调用链;普通用户只看标准化错误,不暴露内部供应商、真实候选模型和原始错误。
详细说明见 模型调用与动态 Fallback 完成说明。
8. 资产、人像审核和删除生命周期
8.1 资产与文件分离
Asset保存团队归属、业务类型、审核和库状态。AssetFile保存 TOS object key、bucket、content type、文件大小、checksum、宽高、时长和预览信息。AssetUsage用于判断资产是否仍被商品、项目、模特或任务引用。
8.2 人像审核
需要审核的资产保存 review_status、review_remote_id、review_error。每个团队使用 AssetReviewGroup 关联火山资产组。
审核提交是 best-effort,但不允许将实际未提交成功的资产误标为 processing。前端会轮询状态并显示绿/红审核标记。
8.3 删除不等于删文件
删除链路需要区分:
- 业务记录软删除。
- 垃圾桶展示和恢复。
- 项目、商品、会话和模特引用解绑。
- ACTIVE 计费预留释放。
- 任务和审计记录保留。
- 确认无引用后才可最终删除 TOS 对象。
禁止为了“清理数据”直接删单表或单个 TOS 对象。
9. 积分、限额和计费
9.1 标准计费生命周期
报价
→ 检查团队/成员/项目/单任务限额
→ reserve_credit
→ 执行 AITask
├─ 成功:charge_reserved_credit
└─ 失败:release_credit
→ CreditLedger 留下预留/扣费/释放/调整记录
一次用户操作只有一个 AITask、一次预留和一次最终扣费或释放。Fallback 的多次上游请求会记为平台成本,不转换成用户多笔扣费。
9.2 限额维度
- 团队自然月限额。
- 成员每日、每月和累计总限额。
QuotaPolicy的月限额、项目限额和单任务限额。- 团队
price_multiplier:平台超管可为团队设置 0.10–10.00 价格系数。
9.3 平台计费配置
BillingConfig 当前提供:
points_per_yuan:人民币与积分的换算。video_margin_multiplier:视频平台毛利系数。video_reserve_buffer:视频预留 buffer。
参数可在平台后台修改,文档不应将当前数据库值当成永久商业规则。
9.4 运维兜底
sweep_stale_reservations:核对并处理超时预留。- 超管任务页可对异常任务执行重试或回收退款。
- 删除仍为 ACTIVE 的计费任务时,信号会尝试释放预留。
10. 前端架构与页面
10.1 主要路由
/login 登录
/register 注册
/dashboard 工作台
/products 商品库
/products/new 新建商品
/products/:id 商品详情
/models 模特库
/projects 视频项目
/projects/new 项目向导
/pipeline/:id 五阶段生产管线
/library 资产库
/asset-factory 图片创作
/image-optimize 模特上身图
/model-photo 模特图片模块
/platform-cover 平台套图
/free-create 自由视频
/account 账户与积分
/team 团队
/messages 消息中心
/settings 设置
/trash 垃圾桶
/admin/* 平台超管后台
10.2 全局状态和 API
App.tsx管理 Token 恢复、User/Team/Role、商品、项目、模型、余额、未读消息和页面分发。api.ts统一处理基础 URL、Token、JSON/FormData 和 DRF 错误转换。types.ts手工维护前后端数据契约。- 无统一服务端状态/缓存层,轮询、去重、刷新恢复分散在各页面。
10.3 当前复杂度中心
| 文件 | 约行数 | 风险 |
|---|---|---|
routes/pipeline.tsx |
4231 | 五阶段状态、轮询、交互和渲染集中 |
routes/ai-tools.tsx |
2831 | 图片会话、批次、生成、删除、恢复集中 |
App.tsx |
1111 | 全局状态和页面调度过重 |
api.ts |
1044 | 153 左右 API 路径集中在单文件 |
ai/services.py |
3614 | 多生成场景和计费/资产副作用集中 |
projects/views.py |
1239 | 五阶段 action 集中 |
拆分建议顺序:先提取领域 hook/服务、再提取轮询和恢复逻辑、再按阶段拆容器,最后才拆纯展示组件。
10.4 设计规范
- 正式共享 token/组件位于
core/frontend/src/design-restraint.css。 - 页面 CSS 全局生效,不是 CSS Modules;新类名必须有页面/组件前缀。
- 禁止在页面 CSS 重写
.btn、.pill、.modal、.input等共享类。 - 禁止新造颜色和修改基础 token。
public/exact和电商AI平台只用于视觉对照。
11. 配置与环境变量
11.1 配置分类
| 分类 | 关键变量名(不含值) |
|---|---|
| Django | DJANGO_SECRET_KEY、DJANGO_DEBUG、DJANGO_ALLOWED_HOSTS、DJANGO_CSRF_TRUSTED_ORIGINS、CORS_ALLOWED_ORIGINS |
| MySQL | DB_ENGINE、DB_NAME、DB_USER、DB_PASSWORD、DB_HOST、DB_PORT、DB_BIND_ADDRESS |
| Redis/Celery | REDIS_CACHE_URL、CELERY_BROKER_URL、CELERY_RESULT_BACKEND、REDIS_LOCK_URL、CELERY_TASK_ALWAYS_EAGER |
| TOS | TOS_ENDPOINT、TOS_BUCKET、TOS_ACCESS_KEY_ID、TOS_SECRET_ACCESS_KEY |
| 火山 ARK | VOLCANO_ARK_API_KEY、VOLCANO_ARK_BASE_URL、VIDEO_ARK_API_KEY |
| 人像资产库 | ASSETS_API_ENABLED、ASSETS_API_ACCESS_KEY、ASSETS_API_SECRET_KEY、ASSETS_API_PROJECT_NAME |
| YunQi | YUNQI_API_KEY、YUNQI_GPT_API_KEY、YUNQI_GEMINI_API_KEY、YUNQI_BASE_URL、YUNQI_API_VERSION |
| TokenSSR | TOKENSSR_API_KEY、TOKENSSR_BASE_URL |
| 火山 TTS | VOLC_TTS_APPID、VOLC_TTS_ACCESS_TOKEN、VOLC_TTS_CLUSTER、VOLC_TTS_BASE_URL |
| AI 路由 | MODEL_ROUTING_* 共 19 项左右,控制重试、超时、候选和后处理 |
| 功能开关 | MODEL_TRIVIEW_GENERATION_ENABLED、MODEL_TRYON_PROMPT_V2_ENABLED、MODEL_TRYON_PROMPT_V2_CANARY_TEAM_IDS |
| 业务参数 | DEFAULT_TRIAL_CREDITS、FREE_VIDEO_MAX_CONCURRENT |
11.2 .env.example 当前缺口
settings 当前读取 66 个环境变量,.env.example 只覆盖其中一部分。未覆盖的 18 项为:
ASSETS_API_ACCESS_KEY
ASSETS_API_ENABLED
ASSETS_API_PROJECT_NAME
ASSETS_API_SECRET_KEY
CELERY_TASK_ALWAYS_EAGER
CORS_ALLOWED_ORIGINS
DEFAULT_TRIAL_CREDITS
FREE_VIDEO_MAX_CONCURRENT
TOKENSSR_API_KEY
TOKENSSR_BASE_URL
VIDEO_ARK_API_KEY
VOLC_TTS_ACCESS_TOKEN
VOLC_TTS_APPID
VOLC_TTS_BASE_URL
VOLC_TTS_CLUSTER
YUNQI_API_VERSION
YUNQI_GEMINI_API_KEY
YUNQI_GPT_API_KEY
这意味着新人不能只复制 .env.example 就假设获得完整环境。应在不写入真实值的前提下补齐示例和用途。
11.3 密钥安全现状
core/backend/.env当前仍是 Git tracked 文件,并且历史上出现过真实供应商凭证。- 后端
.dockerignore会排除.env,所以密钥不是由 DockerCOPY直接烘进镜像。 - 但 Gitea Actions 会从 tracked
.env构造/tmp/core.env,再生成 K8s Secretairshelf-core-env。 - 长期正确做法是将真实凭证从 Git 当前版本和历史移除,改为 Gitea Secret / K8s Secret / 专用密钥管理。
- 移除之前必须先盘点和轮换全部已暴露凭证,不能只做
gitignore而不轮换。
12. 本地开发
12.1 前置依赖
- Python 3.12。
- Node.js 20+。
- MySQL(真实开发数据)或 SQLite(测试)。
- Redis:即使 Celery eager,当前 Django cache 仍是 Redis backend。
- FFmpeg:本地测试封面抽帧和导出时需要。
- 能够获取项目环境变量的安全渠道。
12.2 后端启动
Windows PowerShell:
cd core/backend
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
Copy-Item .env.example .env
# 通过安全渠道补齐环境变量,不从聊天或 Git 复制真实密钥
python manage.py migrate
python manage.py runserver 127.0.0.1:8010
Linux/macOS:
cd core/backend
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
python manage.py migrate
python manage.py runserver 127.0.0.1:8010
当前仓库中的 .venv 可能绑定创建它的本机 Python 路径,换机后应重建,不要修补虚拟环境中的 launcher。
12.3 Celery Worker
Windows:
cd core/backend
.\.venv\Scripts\python.exe -m celery -A airshelf.celery:app worker -l info -P threads -c 4
Linux/macOS:
cd core/backend
celery -A airshelf.celery:app worker -l info -c 4
Windows 不使用 prefork。-P solo 会将所有图片/视频任务串行化,仅适合特殊调试。
12.4 前端
cd core/frontend
npm install
npm run dev
Vite 开发端口默认是 5173,vite.config.ts 将 /api 代理到本地 Django。
12.5 常用管理命令
create_platform_admin 创建/更新平台超管
bootstrap_volcano_models 初始化火山模型
bootstrap_yunqi_models 初始化 YunQi 模型
seed_demo_models 生成演示模特
run_tryon_ab 模特上身图 A/B 验证
reconcile_video_timeouts 只读核对/可选恢复旧视频超时误判
sweep_stale_reservations 处理超时积分预留
audit_actor_model_migration 审计旧角色到模特的迁移
backfill_models 模特数据回填
migrate_saved_actors_to_models 将旧收藏角色迁移为模特
带 --apply 、回填、迁移或账务语义的命令不能在生产库盲跑;先用默认只读或帮助模式确认影响。
13. 测试与本次现场验证
13.1 推荐测试命令
cd core/backend
$env:DB_ENGINE='sqlite'
python manage.py check --settings=airshelf.settings.test
python manage.py makemigrations --check --dry-run --settings=airshelf.settings.test
python manage.py test --settings=airshelf.settings.test
cd core/frontend
npm run build
QA 工具:
- Visual Parity QA:Playwright + pixelmatch 视觉差异。
- Function Audit:遍历页面交互并发现死按钮。
13.2 2026-08-12 实际验证结果
| 检查 | 结果 |
|---|---|
manage.py check + test settings + SQLite |
通过,0 issues |
makemigrations --check --dry-run |
通过,No changes detected |
前端 npm run build |
通过 |
| 模型路由/重试/Fallback/错误分类 4 个测试模块 | 62/62 通过 |
| 后端全量测试 | 未全绿 |
前端构建产物:
- CSS 约 454.52 KB,gzip 约 65.76 KB。
- JS 约 882.00 KB,gzip 约 243.08 KB。
- Vite 警告主 chunk 超过 500 KB,应通过动态 import 或 manual chunks 渐进拆包。
13.3 当前测试红项
- 全量运行发现 545 项测试。
apps.projects.tests.ProjectApiTests.test_extract_entities_recovers_when_content_empty_uses_reasoning可稳定复现失败:期望 HTTP 200,实际 HTTP 400。airshelf.settings.test虽将数据库改为 SQLite 且 Celery eager,却没有将 Django cache 切换为 LocMem/Dummy cache;多个测试会尝试连接环境中的远程 Redis,导致大量环境性错误。- 这些 Redis 连接错误不等于同数量的业务缺陷,但说明当前“隔离测试”并未完全隔离。
优先修复顺序:先让 test settings 使用本地内存 cache,再处理实体提取 reasoning-only 回退测试,然后将 545 项全量测试跑到可重复全绿。
13.4 前端测试现状
core/frontend/package.json只有dev、build、preview。- 没有
test或lintscript,也没有前端*.test.*/*.spec.*单测文件。 - 视觉和交互自动化在
core/qa中独立运行,尚未并入主 CI 质量门禁。 visual-parity/package.json的部分 script 仍包含旧 macOS 绝对路径,换机不可直接复用。
14. 构建、发布和环境
14.1 当前 CI/CD 行为
Gitea Actions 工作流 当前会:
- 拉取推送分支。
- 构建三个镜像:设计稿静态站、真后端 API/Worker、真 React Web。
- 推送到火山镜像仓库,同时写入日期+SHA tag 和
latest。 - 从配置构造 K8s Secret。
- 替换镜像和域名占位符,apply K8s 清单。
- 重启 Web/API/Worker Deployment。
- 部署失败时向 Log Center 上报摘要。
14.2 环境与域名
| 上下文 | 当前工作流配置 |
|---|---|
dev |
测试镜像组织;真 React 站点 airshelf-web.test.airlabs.art |
master |
生产镜像组织;真 React 站点 airshelf-web.airlabs.art |
| 静态设计站 | 测试 airshelf.test.airlabs.art;生产 airshelf.airlabs.art |
本次未对上述 URL 执行线上可用性检查,表格只表示仓库当前配置。
14.3 生产分支严重不一致
AGENTS.md/CLAUDE.md明确写着:dev是开发分支,main是生产主分支。origin/HEAD也指向origin/main。- 但 Gitea 部署工作流只监听
dev和master,生产判断条件也是master。
在人工确定正确生产分支并修正文档或 CI 之前,不得假设合并到 main 会自动生产发布。这是 P0 交接项。
14.4 数据库迁移
- API 容器启动 Gunicorn 前执行
migrate和collectstatic。 - Worker 复用同一镜像,但入口脚本明确跳过迁移。
- MySQL 迁移通过
GET_LOCK('airshelf_migrate', 600)跨 Pod 串行化。 - 该锁是对 2026-07-07 多轮 rolling deployment 并发重放积分×10 数据迁移事故的修复。
- 数据变换迁移必须幂等,或在执行前有明确的一次性保护。
14.5 当前 CI 缺口
- 构建和部署之前没有 Django 测试门禁。
- 没有前端 lint/test 门禁,仅 Docker 构建间接执行 TypeScript + Vite build。
- 未看到明确的
kubectl rollout status或部署后业务冒烟。 - 未看到自动
rollout undo回滚。 - 当前工作流会同时构建静态设计站和真应用,接手人需明确两者域名,避免验收错站。
15. 运维与故障处理
15.1 当前可用的运维能力
- API liveness/readiness:
GET /api/health/。 - Worker liveness:
celery inspect ping。 - Gitea Actions 部署失败日志上报。
- 平台超管
/admin/tasks:查看任务、真实模型调用链、重试和回收。 - 站内消息:生成失败、余额和其他关键状态。
- 管理命令:视频超时恢复、超时预留处理、数据迁移审计。
15.2 健康检查局限
/api/health/ 只返回静态 JSON,不检查 MySQL、Redis、TOS 和 AI Provider。因此 Pod Ready 不等于业务链路可用。
建议将健康分成:
- liveness:进程是否存活,保持当前轻量。
- readiness:MySQL 和 Redis 的低成本检查。
- 独立运维探针:TOS/Provider 的限频、无扣费或最小成本校验。
15.3 尚未形成正式文档的 Runbook
未发现可直接交给值班人员的以下独立流程:
- MySQL 备份、恢复、RPO/RTO 和恢复演练。
- K8s 发布回滚和数据库迁移回退决策。
- Redis 不可用、Celery 队列积压和毒任务处理。
- TOS 访问失败、资产 URL 失效和误删恢复。
- Provider 大面积失败、欠费、模型下线和 Fallback 人工切换。
- 证书、域名、镜像仓库和第三方账号续期责任。
- 故障分级、值班人、联系方式和升级路径。
15.4 建议的最小发布检查
发布前:
- 确认目标分支、环境、镜像 tag 和变更范围。
- 运行 Django check、migration check、后端全量测试、前端 build。
- 审核所有数据迁移,对数据变换迁移准备备份与回滚策略。
- 确认 API 和 Worker 使用同版镜像和同一份模型路由策略。
发布后:
- 等待 Web/API/Worker rollout 完成。
- 检查浅层健康和日志。
- 冒烟登录、商品查询、图片上传和积分摘要。
- 至少冒烟文本、图片、配音、视频提交/轮询和
/admin/tasks调用链。 - 检查一次预留到扣费/释放的完整流水。
- 确认新增资产能入 TOS、能预览、能进垃圾桶并恢复。
16. 安全、权限与合规
16.1 已有保护
- Django 密码校验器。
- DRF 默认需要登录。
- 团队数据通过
TeamScopedViewSetMixin等服务端逻辑隔离。 - 平台超管和团队角色分离。
- 生产启用 secure cookie 和 forwarded HTTPS header。
- Nginx 设置
X-Content-Type-Options和Referrer-Policy。 - 人像素材审核和 Seedance
asset://引用。 - AI 原始错误与普通用户提示分离。
16.2 优先安全风险
- P0:真实密钥进入 Git 历史。 必须先轮换再清理。
- P0:凭证责任人和续期/吊销流程没有交接。
- P1:Basic Authentication 仍保留在 DRF 默认认证列表。 如无真实需求,应评估移除。
- P1:前端“记住我 7 天”主要是本地存储策略,DRF Token 本身不是自带 7 天过期的 JWT。 需确认后端会话撤销与 Token 失效语义是否符合产品要求。
- P1:无正式密钥扫描 CI 门禁。
- P1:没有专门安全文档、事故响应流程和外部依赖清单。
16.3 密钥治理建议
- 盘点 Git 当前版本和历史中的所有供应商凭证。
- 在各供应商后台创建新凭证,更新 Gitea/K8s Secret。
- 重启 API/Worker,按能力冒烟验证。
- 吊销旧凭证。
- 从 Git 当前版本移除
.env,再评估是否需清洗历史。 - 将
.env.example补齐为无密钥的变量契约。 - CI 增加 secret scanning,并建立定期轮换表。
17. 当前风险和待办优先级
P0:接手前必须确认
| 风险 | 影响 | 建议动作 |
|---|---|---|
main / master 生产分支矛盾 |
合并到 main 可能不部署,或团队误判生产流程 | 由仓库/部署负责人定调,统一 AGENTS、默认分支和 workflow |
真实 .env 被 Git 跟踪 |
供应商、TOS、数据库等凭证泄露 | 全量轮换,迁移到 Secret,清理当前版本与历史 |
| 缺少备份/恢复交接 | 数据迁移或人为误操后无法可控恢复 | 确认 MySQL/TOS 备份策略、RPO/RTO 和最近恢复演练 |
P1:建议第一周完成
| 风险 | 建议 |
|---|---|
| 后端全量测试不全绿 | 隔离 Redis cache,修复 reasoning-only 实体提取回退,将 545 项测试纳入 CI |
| CI 无测试/发布后验证/自动回滚 | 增加质量门禁、rollout status、冒烟与人工回滚指南 |
.env.example 缺 18 个配置 |
补齐变量、类型、必填性、默认值和重启影响 |
| 无 OpenAPI | 生成后端 schema,用于契约校验和前端类型生成 |
| 前端无 test/lint | 至少先补路由、API 错误、任务轮询和积分展示的测试 |
| 健康探针过浅 | 增加 readiness 的 MySQL/Redis 检查 |
P2:中期技术债
| 风险 | 建议 |
|---|---|
pipeline.tsx / ai-tools.tsx / services.py 过大 |
按领域边界渐进拆分,禁止一次性重写 |
| 单 API/Worker/Web 副本 | 对真实并发、可用性和成本做容量基线,再决定水平扩容 |
| 单 Worker 队列 | 视频/导出与图片任务可能互相饥饿,评估拆队列和资源限制 |
| 人工充值非真支付 | 若进入商用,需补支付单、签名回调、对账、退款和审计 |
| 缺少统一可观测平台 | 增加结构化日志、错误追踪、队列/任务/供应商指标和告警 |
已过期的旧交接项
- 旧报告中的
/admin/*刷新 404 已修复,Django Admin 已迁到/django-admin/。 - 旧报告对默认模型的写死描述已不可靠,当前存在数据库动态默认、路由 metadata、Retry 和 Fallback。
- 2026-07-09 的提交表示火山账号曾进行迁移,但本次没有读取运行时凭证;旧报告的“借用 AirDrama 账号”不应继续当成当前事实,需账号负责人人工确认。
18. 架构文档同步状态
2026-08-12 运行项目自带的架构扫描器,结果:
analysis_ready: true
requires_update: true
plan_id: arch-b47510754d10bb74309d
snapshot_id: f959a18ac43444340c4d
扫描发现两类影响:
core/backend/airshelf/settings/base.py增加统一模型路由策略和类型化环境变量读取,影响后端架构的3.1 Settings、3.3 鉴权。core/backend/apps/ai/models.py增加AIModelAttempt,影响4.6 ai。
当前 后端架构 正文已包含部分最新内容,但文档同步标记仍落后于 HEAD;前端架构 本次没有被扫描器判定为必须更新。
本文没有修改两份 ARCHITECTURE.md。若后续要同步,必须按 tools/architecture-sync/WORKFLOW.md 重新生成计划、获得用户确认并验证。
19. 接手清单
19.1 第 0 天:权限与人员
- 确认仓库管理员、生产发布负责人和最终业务验收人。
- 确认 Gitea、火山镜像仓库、K3s/K8s、MySQL、Redis、TOS、ARK、Assets API、TTS、YunQi 和 TokenSSR 的账号归属。
- 确认生产分支到底是
main还是master。 - 确认测试/生产数据库是否完全隔离。
- 获取备份策略、最近一次备份和最近一次恢复演练证据。
19.2 第 1 天:本地环境
- 重建 Python 3.12
.venv,不复用别人机器绑定的 launcher。 - 从安全渠道获得测试环境变量。
- 启动 MySQL/Redis/API/Worker/Web。
- 运行 Django check、migration check 和前端 build。
- 复现并记录当前后端测试红项。
19.3 第 2–3 天:业务冒烟
- 邀请码注册、登录、团队成员和角色。
- 商品创建、图片上传、详情、软删除和恢复。
- 新建项目,跑通脚本、实体、基础资产、故事板、视频和导出。
- 检查真人素材审核和
asset://视频引用。 - 检查图片创作、模特上身图、平台套图和自由视频。
- 检查预留、成功扣费、失败释放、限额和超管调整。
- 检查
/admin/tasks的 Retry/Fallback/AIModelAttempt 调用链。
19.4 第 1 周:工程收口
- 定调分支和发布流程。
- 轮换已入 Git 的全部真实凭证。
- 修复测试 Redis 隔离和实体提取回归。
- 将后端测试、前端 build 和基础 QA 加入 CI。
- 补全
.env.example。 - 产出《发布/回滚 Runbook》和《备份/恢复 Runbook》。
- 将本文中的待人工确认项转化为已签字的责任表。
20. 人工待确认责任表
| 事项 | 当前代码可确认的事实 | 需人工填写 |
|---|---|---|
| 产品负责人 | 仓库无可靠当前责任表 | 姓名、联系方式 |
| 技术负责人 | 仓库无可靠当前责任表 | 姓名、联系方式 |
| 生产发布 | workflow 目前按 master 处理生产 |
负责人、实际分支、审批人 |
| 数据库 | MySQL,迁移用 GET_LOCK 串行 | 管理员、备份位置、RPO/RTO |
| Redis | cache/broker/result/lock 四类用途 | 管理员、容量和告警 |
| TOS | 业务文件与导出存储 | 账号、bucket 负责人、生命周期规则 |
| 火山 ARK/Assets/TTS | 代码已集成 | 账号归属、额度、续费和吊销负责人 |
| YunQi/TokenSSR | OpenAI-compatible Provider | 账号归属、额度、备用策略 |
| 域名/证书 | Traefik + cert-manager | 负责人、续期/异常告警 |
| 故障值班 | 仓库未定义 | 值班表、P0/P1 升级路径 |
21. 资料索引
必读
AI 与生成链路
- AI 生成 Agent 化落地方案。
- AI Agent 历史交接。
- 脚本 Agent SSE 技术文档。
- 脚本 Agent 动态知识装配。
- 模型调用与动态 Fallback。
- 模特库与我的演员数据流。
QA 和审计
历史资料(不能单独作为当前状态)
- 2026-06-24 项目移交报告。
- 顶层技术架构方案。
docs/bug_todo/:专项问题和修复过程。docs/agents_todo/:Agent 协同方案和 TODO 计划。
22. 文档维护规则
发生以下变化时,应更新本交接文档:
- 生产/开发分支或部署域名变化。
- Django app、一级 API、核心模型或鉴权变化。
- 五阶段顺序、任务执行模型或资产生命周期变化。
- Provider、Retry/Fallback、计费或人像审核边界变化。
- MySQL、Redis、TOS、K8s 或 CI/CD 架构变化。
- 交接责任人、备份策略、回滚流程或密钥归属变化。
- 全量测试基线或主要已知红项变化。
更新时必须在文首同时记录日期、分支、完整 HEAD SHA 和实际验证结果;不允许只改“已完成”文案而没有可复现证据。
23. 本次未验证的外部状态
以下项目需有相应权限的接手人在第 0–3 天完成:
- 测试和生产站点当前是否可访问。
- 实际默认模型、Provider 状态、Fallback metadata 和供应商余额。
- 火山 ARK、Assets API、TTS、YunQi、TokenSSR 当前凭证和账号归属。
- MySQL/Redis/TOS 实际容量、备份、监控和告警。
- 线上商品到最终视频导出的最新端到端通过情况。
- 生产发布应从
main还是master触发。 - 所有已暴露凭证是否已经轮换或吊销。
文档于 2026-08-12 基于当前 dev HEAD、架构扫描、配置和部署文件、代码结构、历史完成说明以及本地隔离验证整理。未修改业务代码、配置、数据库、既有架构文档、Git 暂存区或远端状态。