Files
ai/CODEX_PROGRESS.md
T
2026-06-15 18:13:21 +08:00

12059 lines
482 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.
# CODEX_PROGRESS.md
## 当前项目阶段
当前阶段:生产化补齐进行中(真实图片/TTS/视频资产落库、国内/海外可替换真实视频 Provider 驱动、后台用户高危操作、成本阈值、队列 worker 消费、细粒度 RBAC、审计导出、单句 TTS 连续重试片段元数据保留、本地存储路径稳定化、成本优化策略硬落地、AI Router V1、Router 队列化 V1、爆款诊断 V1、Prompt Library / 题材套路库前台化 V1、模式库运营闭环 V1、真人视频小样预检 / 验收闭环 V1、真人小样测试台 V1、真人视频真实 Provider 小样验收脚本 V1、真人视频 Prompt Engine V1、MiniMax LipSyncProvider 占位接入、首条真人短剧一集压测用例整理、压测项目导入/Prompt准备和 Mock 全链路成片验收已完成)
## 已完成阶段
- 阶段 00:读取 docs 并输出开发计划
- 阶段 01:初始化项目骨架
- 阶段 02:数据库 schema
- 阶段 03:用户认证
- 阶段 04:文件上传和 MinIO
- 阶段 05:项目创建流程
- 阶段 06:上传小说解析
- 阶段 07AI 原创小说 mock
- 阶段 08:故事圣经
- 阶段 09:角色圣经
- 阶段 10:长篇记忆
- 阶段 11:分集计划
- 阶段 12:脚本和分镜
- 阶段 13BullMQ 队列
- 阶段 14AI Provider 抽象
- 阶段 15:图片生成 mock
- 阶段 16TTS / 字幕 / FFmpeg
- 阶段 17:后台管理
- 阶段 18uni-app 用户端
- 阶段 19:订单额度
- 阶段 20:内容审核
- 阶段 21:真实 AI Provider 接入
- 阶段 22MVP 验收
- 阶段 23API 加密传输
- 生产化优化:单句 TTS 连续重试片段元数据保留
- 生产化修复:后台视频预览本地存储路径稳定化
- 生产化优化:成本优化策略硬落地
- 生产化优化:AI Router V1 / 镜头评分 / 自动选模型
- 生产化优化:质检任务化 / Router 队列化 V1
- 生产化优化:爆款诊断 / 拉片分析 V1
- 生产化优化:Prompt Library / 题材套路库 / IP 设定宇宙前台化 V1
- 生产化优化:模式库运营闭环 V1
- 生产化优化:真人视频小样预检 / 验收闭环 V1
- 生产化优化:真人小样测试台 V1
- 生产化优化:真人视频真实 Provider 小样验收脚本 V1
- 生产化优化:真人视频 Prompt Engine V1
- 生产化优化:MiniMax LipSyncProvider 占位接入
- 生产化优化:首条真人短剧一集压测用例整理
- 生产化优化:首条真人短剧压测项目导入 / Prompt 准备
- 生产化优化:首条真人短剧 Mock 全链路成片验收
- 文档梳理:CURRENT_ARCHITECTURE 当前架构快照
## 正在进行
- 生产化上线补齐与验收
## 待开发阶段
- 生产环境真实 Key / 真实 Sora 付费调用 E2E 验收
- 更细的权限表 UI、权限配置页面和多租户数据范围策略
## 阶段记录
### 文档梳理:CURRENT_ARCHITECTURE 当前架构快照
完成时间:2026-06-15 18:13:00 CST
完成内容:
- 扫描后端、用户端、后台端、Worker、Prisma schema 和核心 AI 流水线实现。
- 生成当前系统整体架构图、核心模块、数据表关系、AI Provider 列表、Router 逻辑、Prompt Builder、Character Library、FFmpeg 流程、已完成功能、待优化功能和关键文件路径。
- 仅生成文档,不修改业务代码。
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
- `CURRENT_ARCHITECTURE.md`
运行命令:
- 未运行 lint/typecheck/test。本次为文档梳理,不涉及代码逻辑变更。
下一步:
- 继续围绕真人视频生产质量、真实 Provider 准入、角色一致性、BGM/SFX/字幕和队列化失败恢复做验收优化。
### 阶段 00:读取 docs 并输出开发计划
完成时间:2026-05-31 17:00:00 CST
完成内容:
- 读取并梳理 docs/system_a 核心文档。
- 明确系统 A MVP 为 AI 原创小说 3 集 MP4 与上传小说 1 集 MP4 两条闭环。
- 标记阶段编号、数据库补充字段、队列清单、上传格式、支付额度前置等待确认点。
修改文件:
-
新增文件:
-
运行命令:
- find docs/system_a -maxdepth 1 -type f
- wc -l docs/system_a/*.md
- rg 文档标题
- sed 阅读核心文档
测试结果:
- 只读阶段,无代码测试。
遗留问题:
- 当前目录不是 Git 仓库,无法执行 git status。
下一步建议:
- 进入阶段 01:初始化项目骨架。
### 阶段 01:初始化项目骨架
完成时间:2026-05-31 17:03:26 CST
完成内容:
- 创建 npm workspaces monorepo。
- 初始化 backend 为最小 NestJS API 服务。
- 初始化 admin 为 Geeker-Admin 可接入的 Vue/Vite 后台骨架。
- 初始化 user-app 为带 manifest/pages 配置的用户端 H5 骨架,保留后续 uni-app 接入位置。
- 初始化 workers 作为后续 BullMQ / FFmpeg worker 入口。
- 初始化 deploy 与本地 MySQL、Redis、MinIO docker-compose.dev.yml。
- 创建 .env.example、README.md、storage 占位目录。
修改文件:
- CODEX_PROGRESS.md
新增文件:
- package.json
- package-lock.json
- tsconfig.base.json
- .gitignore
- .env.example
- README.md
- backend/
- admin/
- user-app/
- workers/
- deploy/
- storage/
运行命令:
- node -v
- npm -v
- npm install
- npm run lint
- npm run typecheck
- npm test
- npm run build
- npm run dev:backend
- npm run dev:admin
- npm run dev:user
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5175
- curl -I http://127.0.0.1:5174
测试结果:
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 1 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后台骨架 HTTP 200
- 用户端 H5 骨架 HTTP 200
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm install 后 audit 提示 13 个依赖风险,暂未执行 npm audit fix --force,避免阶段 01 被破坏性升级影响。
- user-app 当前是可运行 H5 骨架,并保留 manifest/pages 配置;完整 uni-app 插件接入留到用户端阶段。
- 5173 端口已有其他 Node 进程占用,本阶段后台改用 5175。
下一步建议:
- 人工审核阶段 01。
- 审核通过后进入阶段 02:数据库 schema。
### 阶段 02:数据库 schema
完成时间:2026-05-31 17:17:57 CST
完成内容:
- 选择 Prisma 6.19.3 作为 MySQL 8 ORM。
- 根据 docs/system_a/05 及相关订单、Provider、审核、日志文档创建 30 张核心表模型。
- 覆盖 users、projects、novel_sources、novel_chapters、copyright_records、story_bibles、world_bibles、characters、character_images、character_memories、episodes、episode_scripts、storyboard_shots、shot_images、plot_memories、plot_threads、continuity_checks、assets、render_tasks、provider_configs、provider_logs、orders、quota_accounts、quota_logs、revision_requests、content_reviews、case_showcases、analytics_events、system_configs、operation_logs。
- 添加核心唯一约束和索引:用户邮箱/手机号、项目状态、章节顺序、角色类型、分集编号、分镜顺序、任务幂等 key、Provider 配置、订单号、额度账户等。
- 生成初始 migration.sql。
- 创建 seed.ts,包含管理员示例用户、mock TextProvider、系统阶段配置、示例额度账户。
- 在 README.md 补充数据库命令和 ORM 选择说明。
修改文件:
- package.json
- package-lock.json
- backend/package.json
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/prisma/schema.prisma
- backend/prisma/migrations/20260531093000_init_system_a/migration.sql
- backend/prisma/seed.ts
运行命令:
- npm view prisma@6 version --json
- npm install -w backend @prisma/client@6.19.3
- npm install -D -w backend prisma@6.19.3
- DATABASE_URL=... npm run db:validate
- DATABASE_URL=... npm run prisma:generate -w backend
- npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script --output prisma/migrations/20260531093000_init_system_a/migration.sql
- DATABASE_URL=... npm run prisma:migrate -w backend -- --name init_system_a --create-only
- npx tsc --noEmit --target ES2022 --module CommonJS --moduleResolution Node --esModuleInterop --skipLibCheck --strict backend/prisma/seed.ts
- npm run lint
- npm run typecheck
- npm test
- npm run build
测试结果:
- Prisma schema validate:通过
- Prisma Client generate:通过
- seed.ts TypeScript 编译检查:通过
- migration.sql 离线生成:通过,包含 30 张表
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 1 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
补充记录:2026-05-31 17:37:37 CST
- 已确认问题原因:`.env.example` 中的 `ai_manga` 是占位账号,之前尚未在 MySQL 中创建;Linux root 权限不等于 MySQL root 账号权限。
- 已从本机宝塔/aaPanel 配置读取 MySQL root 管理凭据,没有打印密码。
- 已创建 `ai_manga` 数据库和 `ai_manga` 本地用户。
- 已使用 `prisma migrate deploy` 应用现有 migration。
- 已执行 `npm run db:seed`
- 已验证库中存在 31 张表,其中 30 张业务表加 1 张 Prisma 迁移表。
下一步建议:
- 人工审核阶段 02。
- 提供可用 MySQL DATABASE_URL 后执行迁移和 seed。
- 审核通过后进入阶段 03:用户认证。
### 阶段 03:用户认证
完成时间:2026-05-31 17:28:53 CST
完成内容:
- 实现 PrismaService,供后续业务模块统一访问数据库。
- 实现 UsersModule 和 UsersService。
- 实现 AuthModule、AuthController、AuthService、JwtAuthGuard。
- 支持 POST /api/auth/register 用户注册。
- 支持 POST /api/auth/login 用户登录。
- 支持 POST /api/auth/logout 占位退出。
- 支持 GET /api/auth/profile 获取当前用户信息。
- 额外支持 GET /api/profile,兼容阶段指令中的 /profile 验收口径。
- 使用 bcryptjs 对密码哈希。
- 使用 JWT Bearer Token 鉴权。
- 用户表 role 字段预留 user/operator/admin 等后台权限。
- 增加 RequestIdMiddleware、ApiResponseInterceptor、AllExceptionsFilter。
- 全局成功响应格式为 `{ code, message, data, request_id }`
- 全局异常响应格式为 `{ code, message, data: null, request_id }`
- README.md 补充认证接口说明。
修改文件:
- backend/package.json
- backend/src/app.module.ts
- backend/src/app.controller.ts
- backend/src/app.controller.spec.ts
- README.md
- package-lock.json
- CODEX_PROGRESS.md
新增文件:
- backend/src/prisma/prisma.module.ts
- backend/src/prisma/prisma.service.ts
- backend/src/common/request-with-id.ts
- backend/src/common/request-id.middleware.ts
- backend/src/common/api-response.interceptor.ts
- backend/src/common/all-exceptions.filter.ts
- backend/src/users/user.types.ts
- backend/src/users/users.module.ts
- backend/src/users/users.service.ts
- backend/src/auth/auth.dto.ts
- backend/src/auth/auth.types.ts
- backend/src/auth/current-user.decorator.ts
- backend/src/auth/jwt-auth.guard.ts
- backend/src/auth/auth.service.ts
- backend/src/auth/auth.controller.ts
- backend/src/auth/auth.module.ts
- backend/src/auth/auth.service.spec.ts
- backend/src/auth/jwt-auth.guard.spec.ts
运行命令:
- npm install -w backend @nestjs/jwt bcryptjs
- npm install -D -w backend @types/express
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- curl -i http://127.0.0.1:3000/api/auth/profile
- curl -i http://127.0.0.1:3000/api/profile
测试结果:
- backend typecheck:通过
- backend test:通过,3 个测试文件,7 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 7 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- GET /api/health:返回统一成功响应
- GET /api/auth/profile 未带 token:返回 401 Missing bearer token
- GET /api/profile 未带 token:返回 401 Missing bearer token
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
补充记录:2026-05-31 17:37:37 CST
- 已重启后端并注入 DATABASE_URL。
- 已完成真实接口联调:POST /api/auth/register 成功,POST /api/auth/login 成功,GET /api/auth/profile 带 token 成功。
- 修复运行态 NestJS 依赖注入问题:为 AuthController、ProfileController、AuthService、JwtAuthGuard、UsersService 增加显式 `@Inject(...)`
- 新增 `db:deploy` / `prisma:deploy` 脚本,服务器已有 migration 时优先用 deploy,避免 `migrate dev` 需要 shadow database 权限。
- 重新运行 npm run lint、npm run typecheck、npm test、npm run build,全部通过。
下一步建议:
- 人工审核阶段 03。
- 提供可用 MySQL DATABASE_URL 后先执行 `npm run db:migrate``npm run db:seed`,再做真实注册登录接口联调。
- 审核通过后进入阶段 04:文件上传和 MinIO。
### 阶段 04:文件上传和 MinIO
完成时间:2026-05-31 17:44:38 CST
完成内容:
- 实现 AssetsModule、AssetsController、AssetsService、StorageService。
- 支持 POST /api/assets/upload 通用私有资产上传。
- 支持 POST /api/projects/:projectId/novel/upload 小说文件上传。
- 支持 GET /api/assets/:assetId 查询当前用户自己的私有资产。
- 上传接口全部受 JWT Bearer Token 保护。
- 小说上传当前支持 txt 和 md,pdf/docx 保留到后续解析阶段。
- 文件默认写入 `assets` 表,`visibility=private`
- 接口不返回原始文件公网 URL`file_url` 保持 null。
- 本机未启动 MinIO 时默认使用本地 mock 私有存储:`storage/private/...`
- StorageService 已预留 MinIO 客户端;设置 `STORAGE_DRIVER=minio` 并配置 `MINIO_*` 后可切换。
- `.env.example` 增加 `STORAGE_DRIVER=local`,并调整本地存储路径到仓库根 storage。
- README.md 补充上传接口说明。
- 增加资产上传单元测试。
修改文件:
- .env.example
- .gitignore
- README.md
- backend/package.json
- backend/src/app.module.ts
- backend/src/auth/auth.module.ts
- package-lock.json
- CODEX_PROGRESS.md
新增文件:
- backend/src/assets/asset.types.ts
- backend/src/assets/upload.dto.ts
- backend/src/assets/storage.service.ts
- backend/src/assets/assets.service.ts
- backend/src/assets/assets.controller.ts
- backend/src/assets/assets.module.ts
- backend/src/assets/assets.service.spec.ts
运行命令:
- npm install -w backend minio multer
- npm install -D -w backend @types/multer
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl POST /api/auth/register
- MySQL 插入阶段 04 测试项目
- curl POST /api/projects/:projectId/novel/upload -F file=@stage04-novel.txt
- MySQL 查询 assets 表
- curl GET /api/assets/:assetId
测试结果:
- backend typecheck:通过
- backend test:通过,4 个测试文件,10 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 10 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 真实注册测试用户成功
- 真实创建测试项目成功
- 真实上传 txt 小说成功,返回 asset_type=novel_textvisibility=privatestorage_backend=localnext_step=copyright_confirm
- assets 表记录 file_url 为 NULLfile_path 为 local:// 前缀
- 本地文件写入 storage/private/novels/YYYY-MM-DD
- 未登录访问 GET /api/assets/:assetId 返回 401
- 带 token 查询自己的 asset 成功
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- 本机没有 MinIO 9000/9001 服务监听,因此本阶段用本地 mock private 存储完成联调。
- docx/pdf 文件格式尚未开放,留到上传小说解析阶段处理。
- npm audit 仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
下一步建议:
- 人工审核阶段 04。
- 如要真实 MinIO 联调,先启动 MinIO 并设置 `STORAGE_DRIVER=minio`
- 审核通过后进入阶段 05:项目创建流程。
### 阶段 05:项目创建流程
完成时间:2026-05-31 17:49:49 CST
完成内容:
- 实现 ProjectsModule、ProjectsController、ProjectsService。
- 支持 POST /api/projects 创建登录用户项目。
- 支持 GET /api/projects 查询当前用户项目列表。
- 支持 GET /api/projects/:id 查询项目详情。
- 支持 PATCH /api/projects/:id 更新项目基础配置。
- 支持 POST /api/projects/:id/cancel 取消项目。
- 支持 DELETE /api/projects/:id 软删除项目,当前实现为归档到 `archived`
- 新项目默认状态为 `source_selecting`
- `input_mode` 当前开放 `ai_original``upload``admin_import` 预留后台导入。
- 根据创建模式填充默认风格、输出类型、质量档位、目标集数和版权状态。
- 增加项目所有权校验,用户只能访问自己的项目,管理员预留跨项目能力。
- 文件上传模块改为调用 ProjectsService 校验项目归属,避免给非项目所有者上传小说。
- README.md 补充项目接口说明。
- 增加项目服务单元测试。
修改文件:
- README.md
- backend/src/app.module.ts
- backend/src/assets/assets.module.ts
- backend/src/assets/assets.service.ts
- backend/src/assets/assets.service.spec.ts
- CODEX_PROGRESS.md
新增文件:
- backend/src/projects/project.types.ts
- backend/src/projects/project.dto.ts
- backend/src/projects/projects.service.ts
- backend/src/projects/projects.controller.ts
- backend/src/projects/projects.module.ts
- backend/src/projects/projects.service.spec.ts
运行命令:
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl POST /api/auth/register
- curl POST /api/projects
- curl GET /api/projects
- curl GET /api/projects/:id
- curl PATCH /api/projects/:id
- curl GET /api/projects/:id 使用另一个用户 token
- curl POST /api/projects/:id/cancel
- curl DELETE /api/projects/:id
测试结果:
- backend typecheck:通过
- backend test:通过,5 个测试文件,15 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 15 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 真实注册测试用户成功
- 真实创建 upload 项目成功,返回 status=source_selecting
- 真实查询项目列表成功,包含刚创建项目
- 真实查询项目详情成功
- 真实更新项目标题和目标集数成功
- 使用另一个用户 token 查询该项目返回 403 Project is private
- 真实取消项目成功,状态变为 cancelled
- 真实软删除项目成功,状态变为 archived
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
- 项目删除当前为软删除归档,不物理删除数据库记录和已上传文件。
- 本阶段只实现项目创建和基础流转,不做上传小说解析、AI 原创、队列或真实 Provider。
下一步建议:
- 人工审核阶段 05。
- 审核通过后进入阶段 06:上传小说解析。
### 阶段 06:上传小说解析
完成时间:2026-05-31 18:09:02 CST
完成内容:
- 安装 `mammoth``pdf-parse`,用于 docx 与文本型 pdf 抽取。
- StorageService 增加私有对象读取能力,支持读取 `local://``minio://` 路径。
- 小说上传白名单扩展为 txt、md、docx、文本型 pdf。
- 新增 NovelsModule、NovelsController、NovelsService、NovelParserService。
- 支持 POST /api/projects/:projectId/copyright/confirm 确认上传小说版权。
- 支持 GET /api/projects/:projectId/copyright 查询版权确认记录。
- 支持 POST /api/projects/:projectId/novel/paste 保存粘贴文本来源。
- 支持 POST /api/projects/:projectId/novel/parse 解析上传 asset 或粘贴 source。
- 支持 GET /api/projects/:projectId/novel/parse-result 查询解析结果。
- 支持 PATCH /api/novel-chapters/:chapterId 手动编辑章节。
- 解析前强制校验版权确认,未确认时返回 400。
- 解析流程写入 `novel_sources``novel_chapters`
- 文本清洗会处理 BOM、空行、部分广告/水印/链接噪声。
- 章节识别支持 `第1章``第一章``Chapter 1``001 标题``序章``楔子``番外` 等格式。
- 章节识别失败时按字数切分,并在 parse_report 中记录 warning。
- 解析成功后项目状态进入 `novel_uploaded`;解析失败时进入 `text_parse_failed`
- 手动编辑章节后状态标记为 `edited`
- README.md 补充小说解析与版权接口说明。
- 增加小说解析和小说服务单元测试。
修改文件:
- package.json
- package-lock.json
- backend/package.json
- README.md
- backend/src/app.module.ts
- backend/src/assets/assets.service.ts
- backend/src/assets/assets.service.spec.ts
- backend/src/assets/storage.service.ts
- backend/src/projects/project.types.ts
- backend/src/projects/projects.service.ts
- CODEX_PROGRESS.md
新增文件:
- backend/src/novels/novel.dto.ts
- backend/src/novels/novel.types.ts
- backend/src/novels/novel-parser.service.ts
- backend/src/novels/novel-parser.service.spec.ts
- backend/src/novels/novels.controller.ts
- backend/src/novels/novels.module.ts
- backend/src/novels/novels.service.ts
- backend/src/novels/novels.service.spec.ts
运行命令:
- git status --short
- npm view mammoth version
- npm view pdf-parse version
- npm install -w backend mammoth pdf-parse
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- Node fetch 真实接口联调:注册、创建项目、上传 txt、未确认版权解析、确认版权、解析、查结果、编辑章节、粘贴文本
测试结果:
- backend typecheck:通过
- backend test:通过,7 个测试文件,24 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 24 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 真实注册测试用户成功
- 真实创建 upload 项目成功
- 真实上传 txt 小说成功
- 未确认版权调用 POST /api/projects/:projectId/novel/parse 返回 400
- 确认版权成功,返回 next_step=novel_parse
- 真实解析上传 txt 成功,识别 2 个章节,parse_report.strategy=heading
- 清洗测试链接噪声成功,removed_line_count=1
- GET /api/projects/:projectId/novel/parse-result 返回 2 个章节
- PATCH /api/novel-chapters/:chapterId 成功,章节状态变为 edited
- POST /api/projects/:projectId/novel/paste 成功创建粘贴文本 source
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本机没有 MinIO 9000/9001 服务监听,因此 MinIO 读取路径只做代码预留,本阶段真实联调用本地 private 存储完成。
- pdf 当前仅支持文本型 PDF;扫描件 OCR 不在本阶段实现。
- 本阶段只做 deterministic 文本解析,不做 AI 改编、故事分析、任务队列或真实 Provider。
- 真实联调产生了测试用户、项目、资产、小说来源和章节数据,未清理。
下一步建议:
- 人工审核阶段 06。
- 审核通过后进入阶段 07:AI 原创小说 mock。
### 阶段 07AI 原创小说 mock
完成时间:2026-05-31 18:16:31 CST
完成内容:
- 新增 OriginalNovelsController 和 OriginalNovelMockService。
- 支持 POST /api/projects/:projectId/original/idea 生成 mock 故事创意。
- 支持 POST /api/projects/:projectId/original/outline 生成 mock 故事大纲和分章大纲。
- 支持 POST /api/projects/:projectId/original/chapters 生成 mock 章节正文。
- 支持 POST /api/projects/:projectId/original/self-check 执行 mock 自检。
- 支持 GET /api/projects/:projectId/original/result 查询原创小说 mock 结果。
- 原创接口强制要求项目 `input_mode=ai_original`,上传小说项目调用会返回 400。
- mock 结果写入 `novel_sources``source_type=ai_original`
- mock 章节写入 `novel_chapters`,状态为 `generated`
- mock 生成过程记录到 `parse_report``provider=mock_novel_provider`
- 生成 idea 后项目状态进入 `novel_generating`
- 生成章节后项目状态进入 `novel_uploaded`
- 自检结果写入 `parse_report.self_check`,通过后 source 状态为 `checked`
- 自检覆盖主角一致性、主线明确、冲突强度、可视化摘要、短视频钩子。
- README.md 补充 AI 原创小说 mock 接口说明。
- 增加原创小说 mock 单元测试。
修改文件:
- README.md
- backend/src/novels/novels.module.ts
- CODEX_PROGRESS.md
新增文件:
- backend/src/novels/original-novel.dto.ts
- backend/src/novels/original-novel.types.ts
- backend/src/novels/original-novel-mock.service.ts
- backend/src/novels/original-novel-mock.service.spec.ts
- backend/src/novels/original-novels.controller.ts
运行命令:
- git status --short
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- tail -n 80 /tmp/ai-manga-backend.log
- Node fetch 真实接口联调:注册、创建 upload 项目、验证 upload 项目调用原创接口被拒绝、创建 ai_original 项目、生成 idea、生成 outline、生成 chapters、自检、查询 result
测试结果:
- backend typecheck:通过
- backend test:通过,8 个测试文件,29 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 29 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认 original 路由全部映射成功
- 真实注册测试用户成功
- 真实创建 upload 项目成功,调用 original/idea 返回 400
- 真实创建 ai_original 项目成功
- POST /original/idea 成功,返回 source_id 和 mock idea
- POST /original/outline 成功,生成 3 个分章大纲
- POST /original/chapters 成功,生成 3 个章节并写入 `novel_chapters`
- POST /original/self-check 成功,self_check.passed=truescore=100
- GET /original/result 成功,返回 source、idea、outline、self_check 和 3 个章节
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本阶段只做 deterministic mock,不接真实 AI Provider,也不实现 Provider 抽象、队列或成本记录。
- 生成内容是固定模板拼装,质量只用于 MVP 流程联调,不代表最终小说质量。
- 真实联调产生了测试用户、项目、小说来源和章节数据,未清理。
下一步建议:
- 人工审核阶段 07。
- 审核通过后进入阶段 08:故事圣经。
### 阶段 08:故事圣经
完成时间:2026-05-31 18:25:56 CST
完成内容:
- 新增 StoryBiblesModule、StoryBiblesController、StoryBiblesService。
- 支持 POST /api/projects/:projectId/story-bible/generate 生成故事圣经。
- 支持 GET /api/projects/:projectId/story-bible 查询最新故事圣经和版本列表。
- 支持 GET /api/projects/:projectId/story-bible?version=N 查询指定版本。
- 支持 PATCH /api/projects/:projectId/story-bible 编辑故事圣经并创建新版本。
- 支持 POST /api/projects/:projectId/story-bible/confirm 确认故事圣经。
- 生成前要求项目已有小说来源和章节,可接上传解析结果或 AI 原创 mock 结果。
- 生成时从 `novel_sources.parse_report``novel_chapters.summary``novel_chapters.visual_summary` 提取故事要素。
- 故事圣经覆盖一句话简介、主线目标、核心冲突、核心卖点、风格基调、世界规则、时间线、伏笔、禁用设定和结局方向。
- 故事圣经写入 `story_bibles`,初始状态为 `waiting_confirm`
- 编辑不会覆盖旧记录,而是创建 version+1 的新版本。
- 确认时把当前版本状态改为 `confirmed`,并把同项目旧 confirmed 版本置为 `superseded`
- 生成时项目状态流转到 `story_bible_generating`,生成完成到 `waiting_story_confirm`
- 确认后项目状态流转到 `story_confirmed`
- README.md 补充故事圣经接口说明。
- 增加故事圣经服务单元测试。
修改文件:
- README.md
- backend/src/app.module.ts
- CODEX_PROGRESS.md
新增文件:
- backend/src/story-bibles/story-bible.dto.ts
- backend/src/story-bibles/story-bible.types.ts
- backend/src/story-bibles/story-bibles.controller.ts
- backend/src/story-bibles/story-bibles.module.ts
- backend/src/story-bibles/story-bibles.service.ts
- backend/src/story-bibles/story-bibles.service.spec.ts
运行命令:
- git status --short
- rg 故事圣经 / story-bible 相关文档和代码
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- tail -n 90 /tmp/ai-manga-backend.log
- Node fetch 真实接口联调:注册、创建无章节项目并验证生成被拒绝、创建 ai_original 项目、生成原创 idea/outline/chapters、生成故事圣经、查询、编辑 v2、确认、查询项目状态
测试结果:
- backend typecheck:通过
- backend test:通过,9 个测试文件,34 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 34 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认 story-bible 路由全部映射成功
- 无小说来源/章节时调用 story-bible/generate 被拒绝
- 真实 AI 原创 mock 生成章节成功
- 真实生成故事圣经成功,version=1status=waiting_confirm
- GET /story-bible 返回当前版本和版本列表
- PATCH /story-bible 成功创建 version=2
- POST /story-bible/confirm 成功,故事圣经状态变为 confirmed
- GET /projects/:id 确认项目状态为 story_confirmed
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本阶段故事圣经为 deterministic 提取/拼装,不调用真实 AI Provider。
- `world_bibles` 表暂未单独写入;世界规则先落在 `story_bibles.world_summary`,后续如拆 WorldBibleModule 再迁移。
- 真实联调产生了测试用户、项目、小说来源、章节和故事圣经数据,未清理。
下一步建议:
- 人工审核阶段 08。
- 审核通过后进入阶段 09:角色圣经。
### 阶段 09:角色圣经
完成时间:2026-05-31 18:34:22 CST
完成内容:
- 新增 CharactersModule、CharactersController、CharactersService。
- 支持 POST /api/projects/:projectId/characters/extract 从已确认故事圣经和小说章节抽取角色草稿。
- 支持 GET /api/projects/:projectId/characters 查询角色列表,默认不返回 deleted,可通过 include_deleted=true 包含软删除角色。
- 支持 POST /api/projects/:projectId/characters 手动新增角色。
- 支持 PATCH /api/characters/:characterId 编辑角色。
- 支持 DELETE /api/characters/:characterId 软删除未锁定角色。
- 支持 POST /api/projects/:projectId/characters/confirm 确认角色库并锁定角色。
- 抽取前要求项目已有 confirmed 故事圣经;未确认时返回 400。
- 角色抽取当前为 deterministic mock,默认生成主角、反派、配角 3 类角色。
- 抽取结果写入 `characters` 表,状态为 `generated`
- 手动新增角色状态为 `edited`,编辑未锁定角色后状态标记为 `edited`
- 确认角色库会把 `draft``generated``edited` 状态角色锁定为 `locked`
- 锁定后禁止修改姓名、角色类型、性别、年龄、身份和核心外观字段;允许继续补充服装规则、表情风格等非核心描述。
- 项目状态流转覆盖 `character_extracting``waiting_character_confirm``character_confirmed`
- README.md 补充角色圣经接口说明。
- 增加角色圣经服务单元测试。
修改文件:
- README.md
- CODEX_PROGRESS.md
- backend/src/app.module.ts
- backend/src/projects/project.types.ts
新增文件:
- backend/src/characters/character.dto.ts
- backend/src/characters/character.types.ts
- backend/src/characters/characters.service.ts
- backend/src/characters/characters.controller.ts
- backend/src/characters/characters.module.ts
- backend/src/characters/characters.service.spec.ts
运行命令:
- git status --short
- rg 角色圣经 / characters 相关文档和代码
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- tail -n 100 /tmp/ai-manga-backend.log
- Node fetch 真实接口联调:注册、创建未确认故事圣经项目并验证抽取被拒绝、创建 ai_original 项目、生成原创章节、生成并确认故事圣经、抽取角色、列表、编辑、手动新增、删除、确认锁定、验证 locked 限制、查询项目状态
测试结果:
- backend typecheck:通过
- backend test:通过,10 个测试文件,41 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 41 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认角色圣经路由全部映射成功
- 未确认故事圣经时调用 POST /characters/extract 返回 400
- 真实 AI 原创 mock 生成章节成功
- 真实生成并确认故事圣经成功,story_bible_id=3
- 真实抽取角色成功,生成 3 个角色,首个角色为林晚
- GET /projects/:projectId/characters 返回 3 个未删除角色
- PATCH 角色服装规则成功
- POST 手动新增配角顾南成功
- DELETE 手动角色成功,状态变为 deleted
- POST /characters/confirm 成功,抽取角色全部变为 locked
- locked 角色修改核心姓名字段返回 400
- locked 角色修改非核心服装规则成功,状态保持 locked
- GET /projects/:id 确认项目状态为 character_confirmed
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本阶段角色抽取为 deterministic mock / 模板生成,不调用真实 AI Provider。
- 本阶段不生成角色图片、不生成 anchor 图,也不接入 ImageProvider 或队列。
- `anchor_asset_id` 字段保留,但本阶段不写入。
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经和角色数据,未清理。
下一步建议:
- 人工审核阶段 09。
- 审核通过后进入阶段 10:长篇记忆。
### 阶段 10:长篇记忆
完成时间:2026-05-31 18:51:19 CST
完成内容:
- 新增 MemoriesModule、MemoriesController、MemoriesService。
- 支持 GET /api/projects/:projectId/plot-memories 查询剧情记忆,可按 memory_type、status、episode_id 过滤。
- 支持 POST /api/projects/:projectId/plot-memories/generate 从 confirmed 故事圣经、locked 角色库和小说章节/分集摘要生成长篇记忆。
- 支持 POST /api/projects/:projectId/plot-memories 手动新增剧情记忆。
- 支持 PATCH /api/plot-memories/:memoryId 更新剧情记忆,覆盖标记 resolved/archived 等人工维护场景。
- 支持 GET /api/projects/:projectId/memory-context?episode_no=N 获取分集生成前上下文。
- 支持 GET /api/characters/:characterId/memories 查询角色记忆。
- 支持 GET /api/projects/:projectId/plot-threads 查询剧情线。
- 支持 POST /api/projects/:projectId/plot-threads 手动新增剧情线。
- 支持 PATCH /api/plot-threads/:threadId 更新剧情线状态、预计/实际解决集数等。
- 支持 POST /api/episodes/:episodeId/continuity-check 执行规则版连续性检查。
- 记忆生成前要求项目已有 confirmed 故事圣经和 locked 角色库;否则返回 400。
- 生成结果写入 `plot_memories``plot_threads``character_memories`
- 默认剧情记忆覆盖章节事件、未解决冲突、伏笔、世界规则、人物关系变化、重要道具状态和下一集钩子。
- 默认剧情线覆盖主线目标、反派计划和角色成长线。
- `memory-context` 会聚合故事圣经、锁定角色、活跃剧情记忆、开放剧情线、前 3 集摘要和上一集结尾钩子,供下一阶段分集计划使用。
- locked 角色非核心资料补充时,会自动写入 `character_memories.profile_adjustment`
- 连续性检查可发现角色未承接、伏笔未推进、上一集钩子未承接、缺少结尾钩子、开放剧情线未推进和明显破坏世界观的内容。
- README.md 补充长篇记忆接口说明。
- 增加长篇记忆服务单元测试。
修改文件:
- README.md
- CODEX_PROGRESS.md
- backend/src/app.module.ts
- backend/src/characters/characters.service.ts
- backend/src/characters/characters.service.spec.ts
新增文件:
- backend/src/memories/memory.dto.ts
- backend/src/memories/memory.types.ts
- backend/src/memories/memories.service.ts
- backend/src/memories/memories.controller.ts
- backend/src/memories/memories.module.ts
- backend/src/memories/memories.service.spec.ts
运行命令:
- git status --short
- rg 长篇记忆 / memory / plot_memories / character_memories / continuity 相关文档和代码
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- tail -n 140 /tmp/ai-manga-backend.log
- Node fetch 真实接口联调:注册、创建未满足条件项目并验证记忆生成被拒绝、创建 ai_original 项目、生成原创章节、生成并确认故事圣经、验证未锁角色时记忆生成被拒绝、抽取并确认角色、生成剧情记忆、列表、手动新增/标记剧情记忆、剧情线新增/更新、locked 角色补充并记录角色记忆、直接插入测试分集、获取第 5 集记忆上下文、执行连续性检查、查询项目状态
测试结果:
- backend typecheck:通过
- backend test:通过,11 个测试文件,48 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 48 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认长篇记忆路由全部映射成功
- 未确认故事圣经时调用 POST /plot-memories/generate 返回 400
- 已确认故事圣经但未锁定角色时调用 POST /plot-memories/generate 返回 400
- 真实生成长篇记忆成功,生成 plot_memories=11、character_memories=12、plot_threads=3
- GET /projects/:projectId/plot-memories 成功返回剧情记忆列表
- 手动新增剧情记忆成功,PATCH 标记 resolved 成功
- GET /projects/:projectId/plot-threads 成功返回剧情线列表
- 手动新增剧情线成功,PATCH 更新为 progressing 成功
- locked 角色补充服装规则成功,并在 GET /characters/:characterId/memories 中看到 profile_adjustment
- GET /projects/:projectId/memory-context?episode_no=5 成功返回前 3 集摘要和上一集结尾钩子
- POST /episodes/:episodeId/continuity-check 成功发现“突然觉醒超能力”世界观冲突,result_status=fail
- GET /projects/:id 确认项目状态保持 character_confirmed,下一阶段可进入分集计划
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本阶段长篇记忆为 deterministic mock / 规则生成,不调用真实 AI Provider。
- 本阶段不接入 EmbeddingProvider、不做向量检索、不进 BullMQ 队列,也不记录 Provider 成本。
- 分集接口尚未实现;真实联调中的第 2-5 集测试数据通过 Prisma 直接插入,用于验证 memory-context 和 continuity-check。
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经、角色、剧情记忆、剧情线、角色记忆、分集和连续性检查数据,未清理。
下一步建议:
- 人工审核阶段 10。
- 审核通过后进入阶段 11:分集计划。
### 阶段 11:分集计划
完成时间:2026-05-31 18:58:23 CST
完成内容:
- 新增 EpisodesModule、EpisodesController、EpisodesService。
- 支持 POST /api/projects/:projectId/episodes/generate-plan 生成分集计划。
- 支持 GET /api/projects/:projectId/episodes 查询项目分集列表。
- 支持 PATCH /api/episodes/:episodeId 编辑确认前分集。
- 支持 POST /api/projects/:projectId/episodes/confirm 确认分集计划。
- 分集生成前要求项目已有 confirmed 故事圣经、locked 角色库、小说章节和 active 长篇记忆;缺失时返回 400。
- 分集生成当前为 deterministic mock,从故事圣经、角色圣经、长篇记忆、剧情线和小说章节生成分集。
- 每集写入 `episodes` 表,包含标题、剧情摘要、开头钩子、中段冲突、结尾悬念、关联章节和预计时长。
- 生成分集时项目状态先进入 `episode_planning`,生成完成后进入 `waiting_episode_confirm`
- 编辑分集会把分集状态标记为 `edited`,并让项目保持 `waiting_episode_confirm`
- 确认分集前校验集数连续、每集具备标题/摘要/钩子/冲突/预计时长。
- 确认分集会把 `draft``generated``edited` 状态分集更新为 `confirmed`,项目状态变为 `episode_confirmed`
- 已 confirmed 分集不可继续编辑,后续返工留给修改申请/返工流程。
- README.md 补充分集计划接口说明。
- 增加分集计划服务单元测试。
修改文件:
- README.md
- CODEX_PROGRESS.md
- backend/src/app.module.ts
- backend/src/projects/project.types.ts
新增文件:
- backend/src/episodes/episode.dto.ts
- backend/src/episodes/episode.types.ts
- backend/src/episodes/episodes.service.ts
- backend/src/episodes/episodes.controller.ts
- backend/src/episodes/episodes.module.ts
- backend/src/episodes/episodes.service.spec.ts
运行命令:
- git status --short
- rg 分集计划 / episodes / episode_planning 相关文档和代码
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- tail -n 180 /tmp/ai-manga-backend.log
- Node fetch 真实接口联调:注册、创建 ai_original 项目、验证缺少上下文时分集生成被拒绝、生成原创章节、生成并确认故事圣经、抽取并确认角色、验证缺少长篇记忆时分集生成被拒绝、生成长篇记忆、生成 3 集分集计划、查询分集、编辑第 1 集、确认分集、验证 confirmed 分集禁止编辑、查询项目状态
测试结果:
- backend typecheck:通过
- backend test:通过,12 个测试文件,55 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 55 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认分集计划路由全部映射成功
- 缺少故事圣经/角色/记忆上下文时调用 POST /episodes/generate-plan 返回 400
- 已确认故事圣经和角色但缺少 active 长篇记忆时调用 POST /episodes/generate-plan 返回 400
- 真实生成 3 集分集计划成功,每集都有 opening_hook、middle_conflict 和 ending_hook
- GET /projects/:projectId/episodes 成功返回 3 集
- PATCH /episodes/:episodeId 成功编辑第 1 集,状态变为 edited
- POST /projects/:projectId/episodes/confirm 成功,3 集全部变为 confirmed
- confirmed 分集继续 PATCH 返回 400
- GET /projects/:id 确认项目状态为 episode_confirmed
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本阶段分集计划为 deterministic mock / 规则生成,不调用真实 AI Provider。
- 本阶段不生成单集脚本、不生成分镜、不进 BullMQ 队列,也不记录 Provider 成本。
- 分集确认后暂不支持重排/拆分/合并/返工;后续通过修改申请或返工流程补充。
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经、角色、长篇记忆、剧情线和分集数据,未清理。
下一步建议:
- 人工审核阶段 11。
- 审核通过后进入阶段 12:脚本和分镜。
### 阶段 12:脚本和分镜
完成时间:2026-05-31 19:07:37 CST
完成内容:
- 新增 ScriptsModule、ScriptsController、ScriptsService。
- 支持 POST /api/episodes/:episodeId/script/generate 生成单集脚本。
- 支持 GET /api/episodes/:episodeId/script 查询最新脚本和版本列表。
- 支持 PATCH /api/episodes/:episodeId/script 编辑未确认脚本。
- 支持 POST /api/episodes/:episodeId/script/confirm 确认单集脚本。
- 支持 POST /api/episodes/:episodeId/storyboard/generate 生成分镜。
- 支持 GET /api/episodes/:episodeId/storyboard 查询分镜镜头列表。
- 支持 PATCH /api/storyboard-shots/:shotId 编辑未确认镜头。
- 支持 DELETE /api/storyboard-shots/:shotId 删除未确认镜头。
- 支持 POST /api/episodes/:episodeId/storyboard/confirm 确认分镜。
- 支持 POST /api/storyboard-shots/:shotId/regenerate-prompt 重生未确认镜头 Prompt。
- 脚本生成前要求分集已 confirmed,且项目已有 confirmed 故事圣经和 locked 角色库;缺失时返回 400。
- 脚本写入 `episode_scripts`,包含 `script_text``narration_text``dialogue_json`、version 和 status。
- 脚本生成时项目状态进入 `script_generating`,生成完成后进入 `waiting_script_confirm`
- 脚本确认后状态为 `confirmed`,项目状态变为 `script_confirmed`,旧 confirmed 版本会标记为 `superseded`
- 分镜生成前要求已有 confirmed 单集脚本;未确认脚本时返回 400。
- 分镜写入 `storyboard_shots`,默认每集生成 10 个镜头。
- 每个镜头包含场景名、地点、角色 JSON、画面描述、动作描述、台词/旁白、镜头运动、特效、2-5 秒时长、Prompt 和负面 Prompt。
- Prompt 会带入角色固定年龄段、脸型、发型、服装范围,并加入防混脸、年龄/发色漂移、复杂多人镜头等负面约束。
- 分镜生成时项目状态进入 `storyboard_generating`,生成完成后进入 `waiting_storyboard_confirm`
- 分镜确认前校验每个镜头必须有画面、动作、时长、Prompt 和负面 Prompt。
- 分镜确认后镜头状态变为 `confirmed`,项目状态变为 `storyboard_confirmed`
- 已 confirmed 脚本和分镜不可继续编辑/删除/重生 Prompt。
- README.md 补充脚本和分镜接口说明。
- 增加脚本和分镜服务单元测试。
修改文件:
- README.md
- CODEX_PROGRESS.md
- backend/src/app.module.ts
- backend/src/projects/project.types.ts
新增文件:
- backend/src/scripts/script.dto.ts
- backend/src/scripts/script.types.ts
- backend/src/scripts/scripts.service.ts
- backend/src/scripts/scripts.controller.ts
- backend/src/scripts/scripts.module.ts
- backend/src/scripts/scripts.service.spec.ts
运行命令:
- git status --short
- rg 脚本 / 分镜 / storyboard / episode_scripts / storyboard_shots / Prompt 相关文档和代码
- npm run typecheck -w backend
- npm test -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- tail -n 200 /tmp/ai-manga-backend.log
- Node fetch 真实接口联调:注册、创建 ai_original 项目、生成原创章节、生成并确认故事圣经、抽取并确认角色、生成长篇记忆、生成并确认分集计划、验证未确认脚本时分镜生成被拒绝、生成脚本、查询脚本、编辑脚本、确认脚本、验证 confirmed 脚本禁止编辑、生成 10 个分镜镜头、查询分镜、编辑镜头、重生 Prompt、确认分镜、验证 confirmed 镜头禁止编辑、查询项目状态
测试结果:
- backend typecheck:通过
- backend test:通过,13 个测试文件,63 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 63 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认脚本和分镜路由全部映射成功
- 未确认脚本时调用 POST /storyboard/generate 返回 400
- 真实生成单集脚本成功,脚本文本包含结构化脚本段落
- GET /episodes/:episodeId/script 成功返回最新脚本和版本列表
- PATCH /episodes/:episodeId/script 成功编辑旁白,状态变为 edited
- POST /episodes/:episodeId/script/confirm 成功,脚本状态变为 confirmed
- confirmed 脚本继续 PATCH 返回 400
- POST /episodes/:episodeId/storyboard/generate 成功生成 10 个镜头
- 每个镜头都有 visual_desc、duration 和 prompt_text
- GET /episodes/:episodeId/storyboard 成功返回 10 个镜头
- PATCH /storyboard-shots/:shotId 成功编辑镜头,状态变为 edited
- POST /storyboard-shots/:shotId/regenerate-prompt 成功,Prompt 包含“高质量韩漫风”
- POST /episodes/:episodeId/storyboard/confirm 成功,10 个镜头全部 confirmed
- confirmed 镜头继续 PATCH 返回 400
- GET /projects/:id 确认项目状态为 storyboard_confirmed
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 本阶段脚本和分镜为 deterministic mock / 规则生成,不调用真实 AI Provider。
- 本阶段不生成分镜图片、不接入 ImageProvider、不进 BullMQ 队列,也不记录 Provider 成本。
- 分镜确认后暂不支持返工;后续通过修改申请或返工流程补充。
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经、角色、长篇记忆、剧情线、分集、脚本和分镜数据,未清理。
下一步建议:
- 人工审核阶段 12。
- 审核通过后进入阶段 13:BullMQ 队列。
### 阶段 13BullMQ 队列
完成时间:2026-05-31 19:39:54 CST
完成内容:
- 安装 backend / workers 的 `bullmq``ioredis` 依赖。
- 新增 QueuesModule、QueuesController、QueuesService。
- 新增任务类型、任务状态、队列名、任务类型到队列映射、默认重试次数配置。
- 支持 POST /api/projects/:projectId/tasks 创建项目任务。
- 支持 GET /api/projects/:projectId/tasks 查询项目任务。
- 支持 GET /api/tasks/:taskId 查询单个任务及队列归属。
- 支持 GET /api/admin/tasks 管理员查询任务。
- 支持 POST /api/admin/tasks/:taskId/retry 管理员重试 failed / manual_required 任务。
- 支持 POST /api/admin/tasks/:taskId/cancel 管理员取消任务,并尽量移除该任务所有 attempt job。
- 支持 POST /api/admin/tasks/:taskId/manual-required 管理员标记任务进入人工介入状态。
- 支持 POST /api/admin/tasks/recover-stale 恢复过久未完成的 running / retrying 任务。
- 支持 GET /api/admin/queues 查询 BullMQ 各队列 waiting、active、delayed、failed、completed、paused 计数。
- 创建任务先落 `render_tasks`,再入 BullMQ;入队失败时不丢 DB 任务,返回 `queue_backend=bullmq_unavailable`
- 默认幂等 key 使用 `project_id + episode_id + shot_id + task_type + input_hash`
- `input_hash` 基于稳定 JSON 序列化后 SHA-256 生成,字段顺序不同但内容相同会命中同一幂等任务。
- 校验项目 owner/admin 权限,校验 episode_id / shot_id 必须属于项目。
- 管理员接口要求 JWT 中 role 为 `admin`
- worker 入口状态输出已包含 BullMQ 后端、Redis URL 脱敏展示和完整队列清单。
- 发现并修复 BullMQ v5 自定义 jobId 不允许冒号的问题,改为 `task-<id>-attempt-<n>` 格式。
- README.md 补充 BullMQ 队列接口说明。
- 增加队列服务单元测试。
修改文件:
- package-lock.json
- backend/package.json
- workers/package.json
- backend/src/app.module.ts
- workers/src/main.ts
- workers/src/main.spec.ts
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/queues/task.types.ts
- backend/src/queues/task.dto.ts
- backend/src/queues/queues.service.ts
- backend/src/queues/queues.controller.ts
- backend/src/queues/queues.module.ts
- backend/src/queues/queues.service.spec.ts
运行命令:
- redis-cli ping
- npm install -w backend bullmq ioredis
- npm install -w workers bullmq ioredis
- npm run typecheck -w backend
- npm test -w backend -- queues.service.spec.ts
- npm test -w workers
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- Node BullMQ debug 入队验证
- Node fetch 真实接口联调:注册普通用户、创建项目、创建任务、重复幂等创建、查询任务、注册并提升 admin、管理员重试、取消、人工介入、管理员任务列表、队列统计
测试结果:
- redis-cli pingPONG
- backend typecheck:通过
- backend 队列服务单测:通过,6 个测试通过
- workers test:通过,1 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 14 个测试文件,69 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认队列路由全部映射成功
- 真实联调创建任务成功写入 `render_tasks`,入队 `story_queue` 成功,job_id 为 `task-3-attempt-0`
- 相同 input_json 字段顺序不同的重复创建命中同一任务,返回 `idempotent=true`
- 管理员重试 failed 任务成功,状态变为 `retrying`retry_count 变为 1job_id 为 `task-3-attempt-1`
- 管理员取消任务成功,状态变为 `cancelled`,当前 job 移除成功
- 管理员标记人工介入成功,状态变为 `manual_required`error_code 为 `NEEDS_OPERATOR`
- GET /api/admin/queues 成功返回队列统计,novel_queue、parse_queue、story_queue 状态均为 ok
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- worker 当前只声明队列清单和状态输出,还未启动真实消费者处理图片、音频、字幕、视频或 QC 任务。
- 本阶段不接入真实 AI Provider,不记录真实 Provider 成本,不扣减额度。
- 真实联调产生了测试用户、项目和 render_tasks 数据,未清理。
- 修复 BullMQ jobId 格式前曾产生一次 `bullmq_unavailable` 测试任务记录,保留为联调痕迹。
下一步建议:
- 跳过人工审核后进入阶段 14:AI Provider 抽象。
### 阶段 14AI Provider 抽象
完成时间:2026-05-31 19:56:25 CST
完成内容:
- 新增 ProvidersModule、ProvidersController、ProvidersService。
- 新增 Provider 类型、模式、日志状态、安全输出类型和默认 mock provider 配置。
- 支持 TextProvider、NovelProvider、ImageProvider、VideoProvider、VoiceProvider、ModerationProvider、QualityCheckProvider、FileParseProvider、EmbeddingProvider。
- 支持 GET /api/admin/providers 查询 Provider 配置。
- 支持 POST /api/admin/providers/bootstrap-mocks 写入或更新 9 个默认 mock Provider。
- 支持 POST /api/admin/providers/execute 执行指定类型 Provider。
- 支持 PATCH /api/admin/providers/:providerId 更新 Provider 配置。
- 支持 POST /api/admin/providers/:providerId/test 测试指定 Provider。
- 支持 GET /api/admin/provider-logs 查询 Provider 请求/响应/失败日志。
- 支持 GET /api/admin/costs 聚合 Provider 成本。
- Provider 执行会从 `provider_configs` 选择启用配置,按 priority 排序,primary 失败后支持 fallback。
- Provider 执行会写入 `provider_logs`,包含 provider、task、project、request、response、input_size、output_size、cost、status、错误信息和时间。
- 传入 `task_id` 时会回写 `render_tasks`:执行前 running,成功后 success,并记录 provider_id、provider_request_id、cost_estimate、cost_actual。
- 当前 real mode 不会调用外部模型,会返回 `REAL_PROVIDER_NOT_CONFIGURED` 并触发 fallback。
- mock driver 支持文本、小说、图片占位、视频占位、TTS 占位、内容审核、质量检查、文件解析和 embedding 向量占位。
- Provider 输入和配置更新会拒绝 `api_key``secret``token``password``credential` 等疑似密钥字段。
- Provider 配置和日志输出会对疑似密钥字段脱敏。
- `backend/prisma/seed.ts` 更新为写入 9 个默认 mock Provider。
- README.md 补充 AI Provider 抽象接口说明。
- 增加 Provider 服务单元测试。
修改文件:
- backend/prisma/seed.ts
- backend/src/app.module.ts
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/providers/provider.types.ts
- backend/src/providers/provider.dto.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.controller.ts
- backend/src/providers/providers.module.ts
- backend/src/providers/providers.service.spec.ts
运行命令:
- rg Provider / provider / AI Provider 相关文档和代码
- npm run typecheck -w backend
- npx tsc --noEmit --target ES2022 --module CommonJS --moduleResolution Node --esModuleInterop --skipLibCheck --strict backend/prisma/seed.ts
- npm test -w backend -- providers.service.spec.ts
- DATABASE_URL=... npm run db:seed
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- Node fetch 真实接口联调:注册并提升 admin、bootstrap mock providers、查询 providers、执行 TextProvider、创建 render_task 后执行 ImageProvider、指定 provider test、验证疑似密钥字段拒绝、查询 provider logs、查询 costs
测试结果:
- backend typecheck:通过
- seed.ts TypeScript 编译检查:通过
- backend Provider 服务单测:通过,6 个测试通过
- db:seed:通过,已写入或更新默认 mock Provider 配置
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 15 个测试文件,75 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 后端日志确认 Provider 路由全部映射成功
- 真实联调 POST /api/admin/providers/bootstrap-mocks 成功,返回 9 个 mock Provider
- GET /api/admin/providers 成功,确认 TextProvider 和 ImageProvider 均为 mock
- POST /api/admin/providers/execute 执行 TextProvider 成功,写入 success provider_log
- POST /api/admin/providers/execute 执行 ImageProvider 成功,返回 `mock://image/...png`
- ImageProvider 执行传入 task_id 后,对应 render_task 状态变为 success,并写入 provider_id 和 provider_request_id
- POST /api/admin/providers/:providerId/test 成功执行指定 Provider
- 传入 `input_json.api_key` 被拒绝,返回 400
- GET /api/admin/provider-logs 成功返回日志
- GET /api/admin/costs 成功返回 mock 成本聚合,总成本为 0
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 当前 Provider 全部为 deterministic mock,不调用真实 AI Provider。
- 真实 Provider、真实限流、真实计费、额度扣减和外部错误码映射留到后续阶段。
- 前面已实现的原创小说、故事圣经、角色、记忆、分集、脚本和分镜仍是各自服务内的 deterministic mock,尚未逐步迁移为统一 Provider 调用。
- 真实联调产生了测试 admin、项目、render_task 和 provider_logs 数据,未清理。
下一步建议:
- 跳过人工审核后进入阶段 15:图片生成 mock。
### 阶段 15:图片生成 mock
完成时间:2026-05-31 20:15:52 CST
完成内容:
- 新增 ImagesModule、ImagesController、ImagesService。
- 新增图片 DTO、安全输出类型、角色图类型和分镜图类型。
- 支持 POST /api/characters/:characterId/generate-images 生成角色候选图、锚点图和表情图。
- 支持 GET /api/characters/:characterId/images 查询角色图片。
- 支持 POST /api/characters/:characterId/set-anchor 设置角色锚点图。
- 支持 POST /api/storyboard-shots/:shotId/images/generate 生成单个分镜 preview / final 图片。
- 支持 GET /api/storyboard-shots/:shotId/images 查询单个分镜图片。
- 支持 POST /api/episodes/:episodeId/shot-images/generate 批量生成某集 confirmed 分镜图片。
- 角色图片生成要求角色状态为 locked。
- 分镜图片生成要求 storyboard_shots.status=confirmed。
- 角色图 Prompt 组合角色姓名、角色类型、性别、年龄、身份、外貌、脸型、发型、眼睛、体型、服装和道具规则。
- 分镜图 Prompt 组合项目、镜头、场景、地点、画面、动作、台词、旁白、运镜、特效和锁定角色描述。
- 分镜图 Prompt 会引用角色 `anchor_asset_id`,用于后续真实 ImageProvider 做角色一致性约束。
- 每次图片生成都会创建 `render_tasks`,调用 `ImageProvider` mock,写入 `provider_logs`
- mock 图片会保存为本地私有 SVG 文件,写入 `assets`asset_type=imagevisibility=private。
- 角色图片写入 `character_images`,分镜图片写入 `shot_images`
- 设置锚点图会更新 `character_images.is_anchor``characters.anchor_asset_id`
- 项目状态会随图片阶段更新为 `character_image_generated``preview_images_generated``final_images_generated`
- README.md 补充图片生成 mock 接口说明。
- 增加图片服务单元测试。
修改文件:
- backend/src/app.module.ts
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/images/image.dto.ts
- backend/src/images/image.types.ts
- backend/src/images/images.service.ts
- backend/src/images/images.controller.ts
- backend/src/images/images.module.ts
- backend/src/images/images.service.spec.ts
运行命令:
- rg 图片 / ImageProvider / 角色图 / 锚点 / shot_images / character_images 相关文档和代码
- npm run typecheck -w backend
- npm test -w backend -- images.service.spec.ts
- npm run lint
- npm test
- npm run build
- Node fetch 真实接口联调:注册用户、创建项目、准备 locked 角色、准备 confirmed 分集和分镜、生成角色图、设置锚点图、查询角色图、生成分镜 preview 图、查询分镜图、批量生成 episode final 图、验证 assets / render_tasks / provider_logs
测试结果:
- backend typecheck:通过
- backend 图片服务单测:通过,5 个测试通过
- npm run lint:通过
- npm test:通过,backend 16 个测试文件,80 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 真实联调生成角色图片 2 张,自动设置 anchor_asset_id
- GET /characters/:id/images 返回 2 张角色图,图片 asset_path 为 local private SVG
- POST /storyboard-shots/:id/images/generate 成功生成 preview 图
- GET /storyboard-shots/:id/images 返回分镜图
- POST /episodes/:id/shot-images/generate 成功批量生成 final 图
- 真实联调项目写入 4 个 image assets、4 个 image render_tasks、4 条 ImageProvider provider_logs
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 当前图片是 SVG mock 占位图,不是真实模型生成图片。
- 图片质检仅预留字段 `quality_score=92`,尚未接入 QualityCheckProvider。
- 图片生成目前同步执行 Provider mock,尚未由 worker 消费 image_queue。
- 真实联调产生了测试用户、项目、角色、分集、分镜、assets、render_tasks、provider_logs 数据,未清理。
下一步建议:
- 跳过人工审核后进入阶段 16:TTS / 字幕 / FFmpeg。
### 阶段 16TTS / 字幕 / FFmpeg
完成时间:2026-05-31 20:30:10 CST
完成内容:
- 新增 MediaModule、MediaController、MediaService。
- 新增音频生成、字幕生成和视频渲染 DTO 与安全输出类型。
- 支持 POST /api/episodes/:episodeId/audio/generate 生成单集旁白音频。
- 支持 POST /api/episodes/:episodeId/subtitle/generate 生成单集 SRT 字幕。
- 支持 POST /api/episodes/:episodeId/video/render 渲染单集视频。
- 支持 GET /api/episodes/:episodeId/media-assets 查询单集音频、字幕和视频资产。
- 音频生成要求已有 confirmed 单集脚本,会组合脚本旁白、分镜旁白和台词作为 TTS 输入。
- 音频生成通过 `VoiceProvider` mock 执行,写入 `render_tasks``provider_logs` 和本地私有 WAV 资产。
- 字幕生成要求已有 confirmed 分镜,会按镜头时长生成 SRT cues,并写入本地私有 `.srt` 资产。
- 视频渲染要求已有 confirmed 分镜和 generated 分镜图,缺少分镜图时返回 400。
- 视频渲染默认复用最新音频和字幕;不存在时会自动生成。
- 视频渲染通过 `VideoProvider` mock 记录执行日志,默认使用 FFmpeg 读取私有分镜图、音频和字幕并写入本地私有 MP4 资产。
- `prefer_ffmpeg=false` 或本机缺少 FFmpeg 时保留 mock fallback。
- 项目状态随媒体阶段更新为 `audio_generated``subtitle_generated``video_rendered`
- README.md 补充 TTS / 字幕 / FFmpeg 接口说明。
- 增加媒体服务单元测试。
修改文件:
- backend/src/app.module.ts
- backend/src/projects/project.types.ts
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/media/media.dto.ts
- backend/src/media/media.types.ts
- backend/src/media/media.service.ts
- backend/src/media/media.controller.ts
- backend/src/media/media.module.ts
- backend/src/media/media.service.spec.ts
运行命令:
- command -v ffmpeg
- npm run typecheck -w backend
- npm test -w backend -- media.service.spec.ts
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- Node fetch 真实接口联调:注册用户、创建项目、准备 confirmed 单集脚本、confirmed 分镜、generated 分镜图,生成 audio、subtitle、video,并验证 assets / render_tasks / provider_logs
测试结果:
- 阶段完成时本机 `ffmpeg` 未安装,因此阶段 16 当次视频联调使用 mock fallback。
- backend typecheck:通过
- backend 媒体服务单测:通过,5 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 17 个测试文件,85 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查返回 code=0status=ok
- 真实联调 POST /episodes/:episodeId/audio/generate 成功生成 audio assetmime_type 为 audio/wavtask_status 为 success
- 真实联调 POST /episodes/:episodeId/subtitle/generate 成功生成 subtitle assetmime_type 为 application/x-subrip,生成 1 条 SRT cue
- 真实联调 POST /episodes/:episodeId/video/render 成功生成 video assetmime_type 为 video/mp4status 为 mock`ffmpeg_used=false`
- 真实联调 GET /episodes/:episodeId/media-assets 返回 3 个媒体资产
- 真实联调写入 1 个 audio asset、1 个 subtitle asset、1 个 video asset
- 真实联调写入 `audio_generate``subtitle_generate``video_render` 各 1 个 success render_task
- 真实联调写入 VoiceProvider 和 VideoProvider success provider_log 各 1 条
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 当前 TTS 为静音 WAV mock,不调用真实 TTS Provider。
- 当前 TTS 为静音 WAV mock,但视频已切换为真实 FFmpeg 合成。
- 音频、字幕和视频目前同步执行 Provider mock,尚未由 worker 消费 audio/subtitle/video 队列。
- 未接入 BGM、音效、字幕样式、封面图和真实视频编码参数。
- 真实联调产生了测试用户、项目、分集、分镜、assets、render_tasks、provider_logs 数据,未清理。
下一步建议:
- 跳过人工审核后进入阶段 17:后台管理。
补充记录:2026-05-31 20:40:04 CST
- 已在 AlmaLinux 9.7 上安装 RPM Fusion free 仓库和 FFmpeg。
- 已安装 `ffmpeg-5.1.9-2.el9.x86_64``ffmpeg-libs-5.1.9-2.el9.x86_64` 及相关音视频依赖。
- 已验证 `ffmpeg -version` 可用,`libx264``aac` 编码器可用。
- 已用 FFmpeg 生成 1 秒 smoke test MP4,并用 `ffprobe` 验证输出文件时长和大小。
- 注意:此时阶段 16 业务代码仍生成 MP4 placeholder;后续如需真实合成,需要改造 `MediaService.createVideoBuffer` 使用 FFmpeg 拼接分镜图、音频和字幕。
补充记录:2026-05-31 20:46:04 CST
- 已将 `MediaService.createVideoBuffer` 从 FFmpeg mock 改为真实 FFmpeg 合成。
- 默认视频渲染会读取私有分镜图资产、WAV 音频资产和 SRT 字幕资产,写入临时目录后用 FFmpeg 生成 1080x1920 MP4。
- 每个分镜图会按 `storyboard_shots.duration` 生成视频片段,再通过 concat demuxer 合并。
- 字幕通过 FFmpeg `subtitles` filter 烧录进画面,音频转码为 AAC。
- `prefer_ffmpeg=false` 仍保留 mock fallbackFFmpeg 不存在时仍返回 `mock_ffmpeg_unavailable`
- FFmpeg 合成失败或输入资产无法读取时,会把 `video_render` 任务标记为 `failed`,并写入 `VIDEO_RENDER_FAILED`
- 真实联调成功生成 active video asset,返回 `ffmpeg_used=true``render_backend=ffmpeg`
- `ffprobe` 验证输出包含 1080x1920 H.264 视频流和 AAC 音频流,时长 4 秒。
- 真实联调写入 1 个 image asset、1 个 audio asset、1 个 subtitle asset、1 个 active video asset。
- 真实联调写入 `shot_image_generate``audio_generate``subtitle_generate``video_render` 各 1 个 success render_task。
- 真实联调写入 ImageProvider、VoiceProvider、VideoProvider success provider_log 各 1 条。
- 补充验证:`npm run lint``npm run typecheck``npm test``npm run build` 均通过;backend 17 个测试文件,85 个测试通过。
### 阶段 17:后台管理
完成时间:2026-05-31 21:04:26 CST
完成内容:
- 新增 AdminModule、AdminController、AdminService。
- 新增后台 DTO 和安全输出辅助。
- 支持 GET /api/admin/dashboard 查询仪表盘指标。
- 支持 GET /api/admin/projects 查询项目列表,包含 owner、episode/asset/task 计数和最近任务。
- 支持 GET /api/admin/projects/:projectId 查询项目详情,包含小说源、章节、故事圣经摘要、角色、分集、素材、任务、Provider 日志、版权记录和成本。
- 支持 PATCH /api/admin/projects/:projectId/status 调整项目状态,并写入 operation_logs。
- 支持 GET /api/admin/users 查询用户列表和项目/素材计数。
- 支持 GET /api/admin/assets 查询素材列表。
- 支持 GET /api/admin/novel-sources 查询小说源列表,包含项目和章节数量。
- 支持 GET /api/admin/novel-chapters 查询章节列表,支持项目、小说源和状态筛选。
- 支持 GET /api/admin/characters 查询角色资源列表,包含项目、图片数量和长篇记忆数量。
- 支持 GET /api/admin/storyboard-shots 查询分镜资源列表,包含项目、分集、图片数量和最新分镜图 asset。
- 支持 GET /api/admin/works 查询成品漫剧列表,按 video asset 汇总项目、用户、分集和渲染任务。
- 支持 GET /api/admin/copyright-records 查询版权确认记录。
- 后台接口统一要求 admin 角色。
- admin 前端从静态骨架升级为可登录、可请求真实 API 的 Vue/Vite 控制台。
- 前端支持仪表盘、项目管理、小说管理、角色资源、分镜资源、成品漫剧、任务管理、AI Provider、成本日志、用户管理、素材管理和版权记录视图。
- 前端接入已有任务接口,支持失败任务重试、取消、转人工。
- 前端接入已有 Provider 接口,支持初始化 mock providers、查看 Provider 配置和 Provider 日志。
- `backend/prisma/seed.ts` 改为生成真实 bcrypt 管理员密码,默认本地账号 `admin@example.com` / `Admin123!`,支持 `SEED_ADMIN_PASSWORD` 覆盖。
- README.md 补充后台管理接口、资源管理入口、管理端地址和本地管理员账号说明。
- 增加后台服务单元测试。
修改文件:
- backend/prisma/seed.ts
- backend/src/app.module.ts
- backend/src/projects/project.types.ts
- admin/src/App.vue
- admin/src/styles.css
- .env.example
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.types.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.module.ts
- backend/src/admin/admin.service.spec.ts
- admin/src/api/client.ts
运行命令:
- rg / sed 阅读后台管理设计文档、验收文档、现有 admin/API 代码
- npm run typecheck -w backend
- npm test -w backend -- admin.service.spec.ts
- npm run typecheck -w admin
- npm run build -w admin
- DATABASE_URL=... npm run db:seed
- curl http://127.0.0.1:3000/api/health
- Node fetch 真实接口联调:admin 登录、仪表盘、项目列表、项目详情、任务列表、队列统计、Provider 列表、成本、用户列表、素材列表、版权记录
- Node fetch 真实资源联调:小说源列表、章节列表、角色资源、分镜资源、成品漫剧
- Node fetch 真实任务操作联调:创建 failed render_task,调用 retry、manual-required、cancel
- npx tsc --noEmit ... backend/prisma/seed.ts
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:5175
测试结果:
- backend typecheck:通过
- backend Admin 服务单测:通过,4 个测试通过
- admin typecheck:通过
- admin build:通过
- db:seed:通过,已更新本地 admin@example.com 为可登录 admin 用户
- 后端健康检查返回 code=0status=ok
- 后台真实联调 admin 登录成功,role=admin
- GET /api/admin/dashboard 成功返回 total_users、total_projects、failed_tasks、queue_backlog、ai_cost_actual 等指标
- GET /api/admin/projects 成功返回项目列表
- GET /api/admin/projects/:projectId 成功返回项目详情和关联计数
- GET /api/admin/tasks、/admin/queues、/admin/providers、/admin/costs、/admin/users、/admin/assets、/admin/copyright-records 均通过真实联调
- GET /api/admin/novel-sources、/admin/novel-chapters、/admin/characters、/admin/storyboard-shots、/admin/works 均通过真实联调
- 成品漫剧联调成功返回阶段 16 生成的 video asset,并关联项目、分集和 render_task
- 任务操作真实联调成功:failed 任务 retry 后进入 retrying,随后可转 manual_required,再取消为 cancelled
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 18 个测试文件,89 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- admin dev server 已在 `http://127.0.0.1:5175` 返回 200,并热更新到新后台页面
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 后台当前是轻量 Vue/Vite 控制台,还不是完整 Geeker-Admin 二开工程。
- 内容审核、订单额度、模板管理仅保留入口方向,具体业务留到后续阶段。
- 用户管理当前只读,未做禁用用户、改角色、重置密码等高危操作。
- 项目状态调整已写 operation_logs,但完整操作日志查询页尚未实现。
- 真实联调产生了一个 stage17 测试 render_task 及操作痕迹,未清理。
下一步建议:
- 跳过人工审核后进入阶段 18:uni-app 用户端。
### 阶段 18uni-app 用户端
完成时间:2026-05-31 21:36:00 CST
完成内容:
- 将 user-app 从静态 H5 骨架升级为可连接真实 API 的用户端制作台。
- 用户端支持登录、注册、退出和本地 token 恢复。
- 支持新建 AI 原创 / 上传小说改编项目,并可查看和切换我的项目。
- 支持 AI 原创小说一键生成:idea、outline、chapters、self-check。
- 支持上传小说入口:粘贴文本、H5 文件选择、版权确认和解析。
- 支持故事圣经生成和确认。
- 支持角色抽取、角色锚点图生成入口和角色库确认。
- 支持长篇记忆生成,补齐分集计划前置依赖。
- 支持分集计划生成、分集选择和分集确认。
- 支持单集脚本生成/确认、分镜生成/确认、分镜图生成、音频字幕生成和 FFmpeg 视频合成。
- 支持项目任务进度、失败任务数量和任务错误信息查看。
- 支持成品视频列表、私有视频预览和私有 MP4 下载。
- 用户端样式按 H5 优先设计,移动端为底部导航和单列流程,PC 宽屏为左侧导航和两栏制作台。
- 保留 uni-app `pages.json``manifest.json` 和页面路由文件,后续微信小程序/App 可继续迁移。
- 后端新增 `GET /api/assets/:assetId/download` 私有下载接口,校验 asset 归属后返回文件流。
- 全局 API 响应拦截器支持跳过 `StreamableFile`,避免下载流被 JSON envelope 包裹。
- README.md 补充用户端 H5、私有下载接口和阶段状态说明。
修改文件:
- backend/src/assets/assets.controller.ts
- backend/src/assets/assets.service.ts
- backend/src/assets/assets.service.spec.ts
- backend/src/common/api-response.interceptor.ts
- user-app/manifest.json
- user-app/pages.json
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- README.md
- CODEX_PROGRESS.md
新增文件:
- user-app/src/api/client.ts
- user-app/src/workflow.ts
- user-app/src/pages/auth/login.vue
- user-app/src/pages/projects/create.vue
- user-app/src/pages/projects/source-select.vue
- user-app/src/pages/projects/original-setting.vue
- user-app/src/pages/projects/upload-novel.vue
- user-app/src/pages/projects/copyright.vue
- user-app/src/pages/projects/story-bible.vue
- user-app/src/pages/projects/characters.vue
- user-app/src/pages/projects/episodes.vue
- user-app/src/pages/projects/storyboard.vue
- user-app/src/pages/projects/progress.vue
- user-app/src/pages/projects/result.vue
- user-app/src/pages/user/projects.vue
- user-app/src/pages/user/profile.vue
运行命令:
- git status --short
- rg / sed 阅读用户端阶段文档、现有 user-app、后端 API controller / dto / service
- npm view @dcloudio/uni-app version
- npm run typecheck -w backend
- npm run typecheck -w user-app
- npm test -w backend -- assets.service.spec.ts
- npm run build -w user-app
- Node fetch 真实用户端流程联调:注册用户、创建原创项目、原创小说、故事圣经、角色、长篇记忆、分集、脚本、分镜、分镜图、音频、字幕、视频合成、私有下载
- curl http://127.0.0.1:5174
- npm run lint
- npm run typecheck
- npm test
- npm run build
测试结果:
- backend typecheck:通过
- user-app typecheck:通过
- backend Assets 服务单测:通过,4 个测试通过
- user-app build:通过
- 用户端 dev server 已在 `http://127.0.0.1:5174` 返回 200,并热更新到新页面
- 真实用户端流程联调成功:临时用户创建 1 集原创项目,生成 video asset `29`
- 真实联调 FFmpeg 返回 `ffmpeg_used=true``render_backend=ffmpeg`
- 私有下载接口返回 `content-type=video/mp4``content-length=222085`MP4 头部探测为 `ftypisom`
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 18 个测试文件,90 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 当前用户端仍以 Vue/Vite H5 可运行版本为主,没有正式切换到 `@dcloudio/vite-plugin-uni` 构建链。
- 微信小程序/App 的文件选择、下载保存、分享、支付、登录授权等平台能力尚未适配。
- 用户端当前不提供深度编辑页;故事圣经、角色、分集、脚本和分镜的编辑能力仍主要在 API / 后台侧。
- 订单额度、支付冻结和正式生成前扣费尚未接入。
- 真实联调产生了一个 stage18 测试用户、项目、任务、素材和 MP4 资产,未清理。
补充记录:2026-05-31 21:46:00 CST
- 用户反馈用户端访问异常。
- 已确认用户端 dev server 正常监听 `0.0.0.0:5174`,后端正常监听 `0.0.0.0:3000`
- Vite 当前外网访问地址为 `http://152.53.37.118:5174/`
- 修复用户端默认 API 地址:外网 IP/域名访问时自动请求同主机 `:3000/api`,避免浏览器把 `127.0.0.1:3000` 当作用户本机。
- README.md 已同步说明动态 API 默认行为。
补充记录:2026-05-31 21:52:00 CST
- 用户再次反馈无法访问前端页面。
- 已定位本机 firewalld 未放行 TCP `5174``3000`,公网访问会被防火墙挡住。
- 已执行 `firewall-cmd --add-port=5174/tcp --add-port=3000/tcp` 和 permanent 持久化后 reload。
- 已验证 firewalld 查询 `5174/tcp``3000/tcp` 均为 yes。
- 已验证 `http://152.53.37.118:5174/` 返回 HTTP 200`http://152.53.37.118:3000/api/health` 返回后端健康检查成功。
- README.md 已补充公网调试访问需放行 TCP `5174``3000`
下一步建议:
- 跳过人工审核后进入阶段 19:订单额度。
### 阶段 19:订单额度
完成时间:2026-05-31 22:08:00 CST
完成内容:
- 新增 BillingModule、BillingController、BillingService。
- 基于现有 `orders``quota_accounts``quota_logs` 表实现套餐、订单、额度账户和额度流水。
- 支持 GET /api/billing/packages 公开查看 4 个套餐:试用版、标准短剧版、连载测试版、高端定制版。
- 支持 GET /api/billing/quota 查询当前用户额度账户,不存在时自动创建 0 额度账户。
- 支持 GET /api/billing/quota/logs 查询当前用户额度流水。
- 支持 GET /api/billing/orders 查询当前用户订单。
- 支持 POST /api/billing/orders 创建 pending 订单。
- 支持 POST /api/billing/orders/:orderId/mock-pay 模拟支付,订单标记 paid,并写入 recharge 额度流水。
- 支持 GET /api/projects/:projectId/quota/estimate 估算项目生成额度。
- 支持 POST /api/projects/:projectId/quota/freeze 冻结项目额度,项目 `payment_status` 变为 `quota_frozen`
- 支持 POST /api/projects/:projectId/quota/release 释放项目冻结额度。
- 视频合成前校验项目必须已冻结额度或已支付。
- 视频合成成功后自动扣减冻结额度,写入 deduct 额度流水,项目 `payment_status` 变为 `paid`
- 支持 GET /api/admin/orders 管理员查看订单。
- 支持 GET /api/admin/quota-accounts 管理员查看额度账户。
- 支持 POST /api/admin/users/:userId/quota/grant 管理员手动赠送额度。
- 用户端新增“额度”导航和额度中心,支持套餐、模拟支付、订单、额度账户和项目预估。
- 用户端制作台新增支付/额度卡片,视频合成前会自动尝试冻结额度。
- 管理端新增“订单额度”页面,展示订单和额度账户。
- README.md 补充订单额度接口、视频合成额度约束和阶段状态。
修改文件:
- backend/src/app.module.ts
- backend/src/media/media.module.ts
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- admin/src/App.vue
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/billing/billing.dto.ts
- backend/src/billing/billing.types.ts
- backend/src/billing/billing.service.ts
- backend/src/billing/billing.controller.ts
- backend/src/billing/billing.module.ts
- backend/src/billing/billing.service.spec.ts
运行命令:
- git status --short
- rg / sed 阅读订单额度设计文档、现有 Prisma 表、媒体合成服务和用户端页面
- npm run typecheck -w backend
- npm test -w backend -- billing.service.spec.ts media.service.spec.ts
- npm run typecheck -w user-app
- npm run build -w user-app
- npm run typecheck -w admin
- Node fetch 真实接口联调:套餐、注册用户、创建项目、创建订单、模拟支付、额度冻结、额度流水
- Node fetch 真实生成联调:未冻结时视频合成拒绝,模拟支付和冻结后视频合成成功并扣减额度
- Node fetch 管理员接口联调:admin/orders、admin/quota-accounts
测试结果:
- backend typecheck:通过
- billing + media 单测:通过,2 个测试文件,11 个测试通过
- user-app typecheck:通过
- user-app build:通过
- admin typecheck:通过
- 真实订单额度联调成功:标准短剧版 mock 支付后可用额度 120,1 集项目预估 69,冻结后可用额度 51、项目状态 `quota_frozen`
- 真实生成联调成功:未冻结时 `/video/render` 返回 `Project quota must be frozen before formal video render`
- 冻结后视频合成成功生成 video asset `42`,项目 `payment_status=paid`
- 扣减后额度账户:available=51、frozen=0、used=69
- 额度流水顺序包含 deduct、freeze、recharge
- 管理员订单和额度账户接口均通过真实联调
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 19 个测试文件,96 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端、用户端、管理端本地 HTTP 均返回 200
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 当前支付为 mock,不接入微信支付、支付宝、Stripe 或真实回调验签。
- 套餐暂为代码常量,未做后台可配置套餐表。
- 额度预估按默认每集 6 个镜头估算,后续可结合实际分镜数量动态重算。
- 系统失败后的冻结额度自动释放/重试占用策略尚未细化,目前成功扣减、手动 release 可释放。
- 真实联调产生了 stage19 测试用户、订单、额度流水、项目、任务和素材资产,未清理。
下一步建议:
- 跳过人工审核后进入阶段 20:内容审核。
### 阶段 20:内容审核
完成时间:2026-05-31 22:32:40 CST
完成内容:
- 新增 ReviewsModule、ReviewsController、ReviewsService。
- 基于现有 `content_reviews` 表实现项目文本审核、素材审核、用户审核记录列表和管理员审核处理。
- 基于现有 `case_showcases` 表实现用户公开案例授权、用户案例列表、管理员案例列表和发布/驳回处理。
- 支持 POST /api/projects/:projectId/reviews/text,对项目文本或请求体 `content` 执行内容审核。
- 支持 GET /api/projects/:projectId/reviews 查询当前项目审核记录。
- 支持 POST /api/assets/:assetId/review,对 image/video/audio/subtitle/document 等素材执行审核。
- 支持 POST /api/projects/:projectId/showcase/authorize 提交公开案例授权。
- 支持 GET /api/projects/:projectId/showcase 查看项目公开案例授权记录。
- 支持 GET /api/admin/content-reviews 管理员查询审核队列。
- 支持 PATCH /api/admin/content-reviews/:reviewId 管理员通过、修改、驳回、屏蔽或转人工。
- 支持 GET /api/admin/case-showcases 管理员查看公开案例授权。
- 支持 PATCH /api/admin/case-showcases/:showcaseId 管理员授权、发布或驳回公开案例。
- 内容审核复用阶段 14 的 `ModerationProvider` mock,命中敏感关键词时写入 `manual_required`,否则写入 `passed`
- 需要人工处理的审核会把项目状态标记为 `manual_required`
- 后台管理新增“内容审核”页,支持筛选审核状态、处理审核项、发布/驳回公开案例。
- 用户端新增“审核”导航和制作台审核卡片,支持文本审核、成品视频审核、审核状态查看和公开案例授权。
- README.md 补充内容审核接口、后台能力、用户端接入和当前阶段状态。
修改文件:
- backend/src/app.module.ts
- backend/src/admin/admin.service.ts
- admin/src/App.vue
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- README.md
- CODEX_PROGRESS.md
新增文件:
- backend/src/reviews/review.dto.ts
- backend/src/reviews/review.types.ts
- backend/src/reviews/reviews.controller.ts
- backend/src/reviews/reviews.service.ts
- backend/src/reviews/reviews.module.ts
- backend/src/reviews/reviews.service.spec.ts
运行命令:
- git status --short
- rg / sed 阅读内容审核、后台管理、Codex 阶段文档、现有 Prisma schema、Provider mock、后台和用户端页面
- npm run typecheck -w backend
- npm test -w backend -- reviews.service.spec.ts
- npm run typecheck -w admin
- npm run typecheck -w user-app
- npm run lint
- npm run typecheck
- npm test
- npm run build
- Node fetch 真实内容审核联调:注册用户、创建项目、文本审核、敏感文本触发人工、上传素材、素材审核、公开案例授权、管理员审核通过、管理员发布案例
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5174
- curl -I http://127.0.0.1:5175
测试结果:
- backend typecheck:通过
- reviews 单测:通过,1 个测试文件,8 个测试通过
- admin typecheck:通过
- user-app typecheck:通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 20 个测试文件,104 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 真实内容审核联调成功:clean 文本 `passed`,含“违规”的文本 `manual_required`,管理员更新后 `passed`
- 真实资产审核联调成功:上传 document asset `43` 后审核 `passed`
- 真实公开案例联调成功:用户授权后后台发布为 `published/public`
- 真实联调项目 `26` 共写入 4 条审核记录和 1 条公开案例记录
- 后端健康检查返回 code=0,用户端 H5 和管理端 HTTP 均返回 200
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
- 当前内容审核为 mock moderation,不接入真实内容安全平台、版权库、OCR/ASR/视频抽帧审核或人工工单系统。
- 管理员通过审核不会自动恢复此前因风险被标记为 `manual_required` 的项目状态,后续可结合完整人工审核工作流细化状态回滚。
- 公开案例授权和发布当前只记录授权状态与可见性,未做真实前台案例广场。
- 真实联调产生了 stage20 测试用户、项目、素材、审核记录和公开案例记录,未清理。
下一步建议:
- 跳过人工审核后进入阶段 21:真实 AI Provider 接入。
### 阶段 21:真实 AI Provider 接入
完成时间:2026-05-31 22:58:00 CST
完成内容:
- 使用 OpenAI 官方文档确认 Responses API、Image API、Moderation、Embeddings 和 Text to Speech 的当前接入形态。
- 新增 `DEFAULT_OPENAI_PROVIDER_CONFIGS`,支持一键初始化 OpenAI real provider 配置。
- 新增 `POST /api/admin/providers/bootstrap-openai`
- `ProvidersService` 支持 `real` 模式,按 `config_json.driver` 调用:
- `openai_responses` -> `/v1/responses`
- `openai_moderation` -> `/v1/moderations`
- `openai_embeddings` -> `/v1/embeddings`
- `openai_image_generation` -> `/v1/images/generations`
- `openai_audio_speech` -> `/v1/audio/speech`
- Provider 配置只保存 `api_key_env` 这类环境变量引用,不保存真实密钥;原始 `api_key``token``secret` 等字段仍会被拒绝或脱敏。
- 真实图片和 TTS 调用日志只保存 URL/大小/hash 等元数据,不把 base64 图片或音频字节写入 `provider_logs`
- OpenAI 图片和 TTS real provider 默认优先级低于 mock,避免现有 mock 图片/本地音频生产链路在未接真实资产落库前误消耗真实模型。
- 后台 AI Provider 页面支持初始化 OpenAI Provider、查看 driver、指定 provider 测试并展示测试结果。
- README 补充真实 Provider 环境变量、接口和当前边界说明。
修改文件:
- backend/src/providers/provider.types.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.controller.ts
- backend/src/providers/providers.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- README.md
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm test -w backend -- providers.service.spec.ts
- npm run lint
- npm run typecheck
- npm test
- npm run build
- curl http://127.0.0.1:3000/api/health
- Node fetch 真实接口冒烟:admin 登录、bootstrap OpenAI Provider、查询 Provider、指定 OpenAI TextProvider 执行并在无 `OPENAI_API_KEY` 时 fallback 到 mock
测试结果:
- backend typecheck:通过
- admin typecheck:通过
- backend Provider 单测:通过,10 个测试通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 20 个测试文件 108 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 后端健康检查:通过
- 真实接口冒烟:`bootstrap-openai` 返回 6 个 OpenAI Provider;指定 `openai-responses-text` 时因未配置 `OPENAI_API_KEY` 记录 failed attempt,并成功 fallback 到 `mock-text`
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- 本机未配置真实 `OPENAI_API_KEY`,因此本阶段只做了 mock fetch 单测和配置/路由验证;未向 OpenAI 发起真实付费调用。
- 原创小说、故事圣经、角色、记忆、分集、脚本和分镜仍是各自服务内 deterministic 生成逻辑,后续可逐步迁移到统一 Provider。
- 图片/TTS real provider 已能测试调用,但现有图片、音频、视频生产链路仍默认 mock/本地合成,真实图片和音频资产落库需要后续阶段接入。
- VideoProvider 暂无 OpenAI 视频生成真实驱动,仍保持 mock。
下一步建议:
- 进入 MVP 验收,按原创小说 3 集 MP4 与上传小说 1 集 MP4 两条链路做端到端检查。
### 阶段 22MVP 验收
完成时间:2026-06-01 00:15:00 CST
完成内容:
- 使用本机 API 跑通系统 A 两条 MVP 闭环。
- AI 原创小说 3 集链路:注册验收用户、mock 支付充值、创建原创项目、生成原创构思/大纲/章节、自检、故事圣经、角色、角色锚点图、长篇记忆、3 集分集计划、3 集脚本、3 集分镜、30 张正式分镜图、3 集音频、3 集字幕、3 个 FFmpeg MP4、私有下载校验、成品视频审核和公开案例授权。
- 上传小说 1 集链路:TXT 文件上传、版权确认、小说解析、故事圣经、角色、角色锚点图、长篇记忆、1 集分集计划、脚本、分镜、10 张正式分镜图、音频、字幕、FFmpeg MP4、私有下载校验、成品视频审核和公开案例授权。
- 后台详情校验项目、素材和任务数量。
- 验收发现并修复 mock 文本审核误伤安全规则提示的问题:`不得生成违法、低俗、仇恨、侵权...` 这类合规约束不再被 `违法` 关键词误判;真实风险词仍会进入 `manual_required`
- 更新 README 当前阶段、版权授权枚举、MVP 验收结果和 mock moderation 说明。
验收数据:
- 验收用户:`mvp-1780243409631@example.com`,用户 ID `30`
- AI 原创项目:项目 ID `28`3 集,状态 `video_rendered`,支付状态 `paid`
- 上传小说项目:项目 ID `29`1 集,状态 `video_rendered`,支付状态 `paid`
- 原创 MP4 asset`112``115``118`,私有下载均为 `video/mp4`,大小分别约 367 KB、386 KB、375 KB
- 上传 MP4 asset`135`,私有下载为 `video/mp4`,大小约 399 KB
- 额度账户:`total_quota=1200``used_quota=196``available_quota=1004``frozen_quota=0`
- 原创文本复审:review `13``passed`
- 上传文本复审:review `14``passed`
- 视频审核:原创 3 条和上传 1 条均 `passed`
修改文件:
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- README.md
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- curl http://127.0.0.1:3000/api/health
- Node fetch MVP 验收脚本:AI 原创 3 集、上传小说 1 集、私有 MP4 下载、审核、额度和后台详情校验
- npm test -w backend -- providers.service.spec.ts
- npm run typecheck -w backend
- npm run lint
- npm run typecheck
- npm test
- npm run build
测试结果:
- AI 原创 3 集 MP4:通过
- 上传小说 1 集 MP4:通过
- 私有下载校验:4 个视频均返回 `video/mp4`,大小均大于 300 KB
- 视频审核:通过
- 文本复审:通过
- backend Provider 单测:通过,11 个测试通过
- backend typecheck:通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 20 个测试文件 109 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- MVP 验收使用 mock 支付、mock 图片、mock TTS 和本地 FFmpeg 合成;真实图片/TTS 资产落库、真实支付、真实内容安全平台仍需生产化阶段接入。
- 因本机未配置 `OPENAI_API_KEY`,文本/视频审核的 OpenAI moderation real provider 会先记录 `OPENAI_API_KEY_NOT_CONFIGURED` 失败 attempt,再 fallback 到 mock moderation。
- 第一轮验收产生了项目 `27` 的半成品数据,第二轮完整验收项目为 `28``29`,未清理历史测试数据。
- 公开案例授权当前为用户提交 `pending/authorized` 流程,未做真实前台案例广场。
下一步建议:
- 规划生产化阶段:真实图片/TTS 资产落库、OpenAI key 配置策略、真实支付、worker 异步消费、审核工单和微信小程序/App 适配。
### 阶段 23API 加密传输
完成时间:2026-06-01 00:32:22 CST
完成内容:
- 保留并完善 HTTPS 强制策略:生产默认要求 HTTPS,支持反向代理 `X-Forwarded-Proto=https`,生产 CORS 改为显式白名单。
- 新增 `GET /api/crypto/handshake`,使用短期内存会话完成 ECDH P-256 握手。
- 前后端使用 `ECDH P-256 + HKDF-SHA256` 派生 AES-256-GCM 会话密钥。
- 后端新增加密请求中间件:识别加密信封,解密 JSON 请求体后再进入原有 Controller/Service。
- 后端响应包装和异常过滤器支持加密返回:JSON 成功响应、业务异常响应都会在加密请求上下文中返回 AES-GCM 密文。
- 后台管理和用户端 API Client 支持按配置启用加密信封:开启后请求前加密业务 payload,收到响应后解密再渲染。
- 用户端小说文件上传改为先转 base64 文件 payload,再作为加密 JSON 请求发送。
- 私有素材下载在加密请求下返回加密 JSON 文件 payload,前端解密后生成 Blob,避免成品 MP4 以明文业务响应返回。
- 前端生产环境默认同源 `/api`,显式 `VITE_API_BASE_URL` 禁止使用 `http://`
- API 加密新增后台开关 `security.api_crypto_enabled`,测试默认关闭,上线后可在后台“配置管理”手动开启。
- 新增 `GET /api/client-config`,前端启动请求前读取加密开关;`API_CRYPTO_ENABLED=true/false``VITE_API_CRYPTO_ENABLED=true/false` 可强制覆盖。
- 补充 `.env.example`、README 和 Nginx HTTPS 部署示例。
修改文件:
- .env.example
- README.md
- CODEX_PROGRESS.md
- backend/src/app.module.ts
- backend/src/main.ts
- backend/src/assets/assets.controller.ts
- backend/src/common/all-exceptions.filter.ts
- backend/src/common/api-response.interceptor.ts
- backend/src/common/api-crypto.controller.ts
- backend/src/common/api-crypto.service.ts
- backend/src/common/encrypted-request.middleware.ts
- backend/src/common/secure-transport.middleware.ts
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.types.ts
- backend/prisma/seed.ts
- admin/src/App.vue
- admin/src/api/crypto.ts
- admin/src/api/client.ts
- user-app/src/api/crypto.ts
- user-app/src/api/client.ts
- deploy/README.md
新增文件:
- backend/src/common/api-crypto.controller.ts
- backend/src/common/api-crypto.service.ts
- backend/src/common/api-crypto.service.spec.ts
- backend/src/common/encrypted-request.middleware.ts
- backend/src/common/secure-transport.middleware.spec.ts
- admin/src/api/crypto.ts
- user-app/src/api/crypto.ts
- deploy/nginx.https.example.conf
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm run typecheck -w user-app
- npm run lint
- npm run typecheck
- npm test
- npm run build
- PORT=3010 HTTPS_REQUIRED=false npm run start -w backend
- Node fetch 加密握手 + 加密 GET /api/health 冒烟
- PORT=3011 API_CRYPTO_ENABLED=auto HTTPS_REQUIRED=false npm run start -w backend
- curl http://127.0.0.1:3011/api/client-config
- curl http://127.0.0.1:3011/api/health
- PORT=3012 API_CRYPTO_ENABLED=true HTTPS_REQUIRED=false npm run start -w backend
- curl http://127.0.0.1:3012/api/client-config
- curl -i http://127.0.0.1:3012/api/health
- Node fetch 强制开启下的加密 GET /api/health 冒烟
测试结果:
- backend typecheck:通过
- admin typecheck:通过
- user-app typecheck:通过
- npm run lint:通过
- npm run typecheck:通过
- npm test:通过,backend 22 个测试文件 113 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
- npm run build:通过
- 加密 API 冒烟:`GET /api/crypto/handshake` 成功,带 `x-api-encrypted: v1``GET /api/health` 返回加密信封,Node 客户端解密后得到 `code=0``status=ok`
- 默认关闭冒烟:`API_CRYPTO_ENABLED=auto` 且数据库配置不可用/未开启时,`GET /api/client-config` 返回 `api_crypto_enabled=false`,普通 `GET /api/health` 明文 JSON 正常返回。
- 强制开启冒烟:`API_CRYPTO_ENABLED=true` 时,普通 `GET /api/health` 返回 400;带加密 headers 的 `GET /api/health` 返回加密信封并可解密为 `status=ok`
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- 应用层加密保护请求体和响应体;HTTP 方法、路径、域名和 query string 仍属于传输元数据,生产必须继续使用 HTTPS,且不要把敏感内容放进 query。
- 加密会话当前保存在单进程内存中;多实例部署需要粘性会话,或把 session 私钥/盐迁移到 Redis 等共享存储。
- 当前前端加密实现面向 H5 浏览器 WebCrypto;微信小程序/App 需要后续补平台 crypto adapter。
- 后台开关只对 `API_CRYPTO_ENABLED=auto` 生效;如果环境变量显式设置为 `true``false`,会覆盖数据库配置。
下一步建议:
- 进入生产化安全补强:敏感 query 改 POST body、加密会话 Redis 化、CSP/XSS 防护、真实证书部署、微信小程序/App 加密适配。
### MVP 易用性修复:后台中文说明 / 额度页排版 / AI Provider 配置入口
完成时间:2026-06-01 12:34 CST
完成内容:
- 后台仪表盘、项目、小说、角色、分镜、成品、订单额度、审核、任务、Provider、成本、用户、素材、配置、版权等页面的 status/type/key 展示改为 `英文码(中文说明)` 或对应中文说明。
- 后台 AI Provider 页面新增“AI 接入配置”说明区,明确真实 OpenAI/兼容 Provider 的密钥填写在后端环境变量,不在后台保存明文。
- Provider 表格补充模型环境变量、密钥环境变量和接口地址列,方便运营和部署人员定位配置项。
- 用户端额度/支付区域改为更稳定的自适应网格,套餐卡、额度数字、订单行在 H5/PC 窄宽度下不再互相挤压。
- 用户端额度、订单、审核、素材等常见状态展示改为中文短标签,减少 raw code 撑破布局。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w admin
- npm run typecheck -w user-app
- npm run build -w admin
- npm run build -w user-app
测试结果:
- admin typecheck:通过
- user-app typecheck:通过
- admin build:通过
- user-app build:通过
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- 后台 Provider 页现在显示应填的环境变量名;真实密钥仍需要在服务器后端运行环境或 backend/.env 中填写,并重启后端。
下一步建议:
- 填入 OPENAI_API_KEY 后,在后台 AI Provider 页面点击“初始化 OpenAI Provider”和“测试”,验证真实模型链路。
### 后台运营体验优化:资源预览 / 中文展示 / AI 接入后台配置
完成时间:2026-06-01 13:52 CST
完成内容:
- 后台状态、类型、风险、授权、任务等字段对运营显示中文,不再默认展示英文枚举码。
- 小说源、章节、角色、分镜、素材、成品漫剧增加预览入口;图片、视频、音频、文本类资源可在后台抽屉内预览或下载。
- 后端 admin 资源接口补充小说文本预览、章节正文预览、角色设定详情、分镜提示词/动作/旁白等预览字段。
- AI Provider 增加后台运行配置接口 `PATCH /api/admin/providers/:providerId/runtime-config`,支持后台配置 API Key、Base URL、模型、超时、启停和优先级。
- API Key 不再要求运营修改服务器环境变量;后台输入后,后端用 AES-256-GCM 加密保存到 Provider 配置中,列表只显示已配置/未配置,不回显明文。
- README 和 `.env.example` 补充 `PROVIDER_SECRET_KEY` 说明。
修改文件:
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.types.ts
- backend/src/providers/provider.dto.ts
- backend/src/providers/providers.controller.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- admin/src/api/client.ts
- admin/src/api/crypto.ts
- admin/src/App.vue
- admin/src/styles.css
- README.md
- .env.example
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm test -w backend -- providers.service.spec.ts
- npm run build -w backend
- npm run build -w admin
- npm test -w backend
- 重启 3000 后端 dist 进程
- curl http://127.0.0.1:3000/api/health
- 登录 admin 后 GET /api/admin/providers
测试结果:
- backend typecheck:通过
- admin typecheck:通过
- providers.service.spec.ts:通过,12 个测试通过
- backend build:通过
- admin build:通过
- backend 全量测试:通过,22 个测试文件 114 个测试通过
- 后端 3000 已重启到新构建,健康检查返回 `status=ok`
- 后台页面 5175 返回 200`GET /api/admin/providers` 返回 15 条 Provider 配置
遗留问题:
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
- 生产环境建议显式设置 `PROVIDER_SECRET_KEY`;否则 Provider 密钥加密会回退使用 `JWT_SECRET`
- 后台预览依赖已有私有素材下载接口;如果素材实体缺失或文件在本地/MinIO 不存在,预览会提示下载失败。
下一步建议:
- 在后台 AI 接入页初始化 OpenAI 接入,选择目标 Provider 点“配置”,填入 API Key 后测试真实模型链路。
### 后台用户管理:人工加余额
完成时间:2026-06-01 14:10 CST
完成内容:
- 用户管理页新增“人工加余额”操作区,运营可选择用户、填写增加额度和备注后提交。
- 用户列表新增总额度、可用额度和快捷“加余额”操作,直接复用当前表单额度与备注。
- 后台页面调用现有 `POST /api/admin/users/:userId/quota/grant` 接口,额度变更会进入后端额度账户和额度流水。
- 切换到用户管理页时同步刷新用户列表与额度账户,避免运营看到旧余额。
- README 补充后台用户人工加余额入口说明。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w admin
- npm run build -w admin
测试结果:
- admin typecheck:通过
- admin build:通过
遗留问题:
- 当前只实现“增加额度/余额”,未做扣减、冻结调整、禁用额度账户等高风险操作。
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
下一步建议:
- 后台用户管理可继续补“额度流水明细/最近订单/最近项目”抽屉,方便运营核对加余额原因。
### 后台运营闭环:用户详情抽屉 / 内部额度模式 / 上线验收
完成时间:2026-06-01 22:36 CST
完成内容:
- 修复后台用户管理页“人工加余额”区域在中等宽度下重叠的问题,改为稳定的多列栅格和移动端单列布局。
- 新增 `GET /api/admin/users/:userId/detail` 后台接口,返回用户基础信息、额度账户、额度流水、订单记录、最近项目、最近素材和最近操作。
- 后台用户管理列表新增“详情”按钮,打开用户详情抽屉;抽屉内可核对额度流水、项目、订单、素材和操作记录,素材可继续走预览入口。
- 用户端 H5 隐藏套餐、模拟支付和订单展示;当前内部测试模式只展示额度账户、项目预估和冻结额度,余额由后台人工增加。
- README 更新为“内部测试额度模式”,补充用户详情接口和后台运营说明。
- 后端 dist 服务已重启到新构建,当前监听 `0.0.0.0:3000`
修改文件:
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- user-app/src/pages/index/index.vue
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm run typecheck -w user-app
- npm test -w backend -- admin.service.spec.ts
- npm run typecheck
- npm test
- npm run lint
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
- npm run build
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5175
- curl -I http://127.0.0.1:5174
- Node fetch 验收:管理员登录、用户列表、用户详情、注册测试用户、创建项目、额度预估、后台人工加额度、用户侧查余额
测试结果:
- backend/admin/user-app/workers 全量 typecheck:通过
- backend/admin/user-app/workers 全量 lint:通过
- backend 全量测试:通过,22 个测试文件 115 个测试通过
- admin 测试:无测试文件,按 `--passWithNoTests` 通过
- user-app 测试:无测试文件,按 `--passWithNoTests` 通过
- workers 测试:通过,1 个测试通过
- Prisma schema validate:通过(需要带 `DATABASE_URL`
- 全 workspace build:通过
- 后端健康检查:通过,`status=ok`
- 后台 5175:返回 200
- 用户端 5174:返回 200
- 后台用户详情真实接口:通过,测试用户详情返回 `project_count=2``asset_count=59``quota_log_count=5`
- 内部额度真实接口:通过,新注册测试用户 `launch-check-1780324339354@example.com`,项目 `31`,后台加 10 额度后用户侧可用额度为 `10`
上线验收结论:
- 内部测试 / 自己人试用:可以继续使用。当前链路支持后台加额度、用户端按额度生成、后台查看用户详情和资源预览。
- 正式公网商业上线:暂不能宣布已达标。真实图片/TTS/视频 Provider 的生产调用、资产落库、失败重试、成本控制、内容安全平台、支付/开票或彻底移除支付域模型、用户禁用/改角色/重置密码/额度冲正等后台高风险操作还需要按生产标准补齐。
遗留问题:
- 当前用户端不展示支付入口;历史 mock 支付接口保留用于回归测试,后续如果对外收费,需要重新按真实支付网关设计。
- 图片/TTS/视频链路已有抽象和本地合成,但生产环境仍需切换真实 Provider 调用、成本记录、失败重试和资产一致性验收。
- 后台用户管理已具备详情和加余额,但扣减/冲正、禁用用户、改角色、重置密码、操作二次确认与审计策略尚未实现。
- API 加密开关仍按测试默认关闭;正式环境需要 HTTPS、`PROVIDER_SECRET_KEY``JWT_SECRET``API_CRYPTO_ENABLED` 和后台配置同步完成。
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
下一步建议:
- 进入正式上线补齐阶段:先做真实图片/TTS/视频 Provider 生产链路和资产落库验收,再补后台用户高危操作与额度冲正审计。
### 生产化补齐:真实图片 / TTS / 视频二进制资产落库
完成时间:2026-06-02 00:26 CST
完成内容:
- Provider 执行结果新增内部 `return_binary` 开关:业务生成链路可拿真实二进制,后台 Provider 测试默认不返回大体积 base64。
- OpenAI 图片 Provider 返回的 `b64_json` 会作为短暂 `content_base64` 交给图片生成服务;`provider_logs` 只记录 URL、字节数、hash、prompt 等摘要,不写入 base64。
- OpenAI TTS Provider 返回的音频 buffer 会作为短暂 `content_base64` 交给音频生成服务;`provider_logs` 只记录音频字节数、hash、mime、voice 等摘要。
- 图片生成链路改为优先保存 Provider 返回的真实图片字节,或下载 HTTP(S) `asset_url`;拿不到真实素材时才回退 SVG mock 占位图。
- 图片生成成功后回填 `render_tasks.output_asset_id`,后台可从任务追到真实图片资产。
- TTS 链路改为优先保存真实音频字节或下载音频 URL;拿不到真实素材时才回退静音 WAV。
- 视频渲染链路支持 Provider 返回 `content_base64` 时直接保存 Provider MP4;否则继续用 FFmpeg 读取分镜图、音频和字幕合成本地 MP4。
- README 更新图片、TTS、视频生产链路说明。
修改文件:
- backend/src/providers/provider.dto.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- backend/src/images/images.service.ts
- backend/src/images/images.service.spec.ts
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm test -w backend -- images.service.spec.ts media.service.spec.ts providers.service.spec.ts
- npm test -w backend
- npm run build -w backend
- 重启 3000 后端 dist 进程
- curl http://127.0.0.1:3000/api/health
测试结果:
- backend typecheck:通过
- 定向测试:通过,3 个测试文件 27 个测试通过
- backend 全量测试:通过,22 个测试文件 120 个测试通过
- backend build:通过
- 后端 3000 已重启到新构建,健康检查返回 `status=ok`
上线验收结论:
- 图片/TTS 资产落库链路已具备真实 Provider 生产能力:后台配置真实 Provider 并调高优先级后,业务生成会保存真实图片/音频私有资产。
- 视频链路已支持 Provider 二进制 MP4 落库;当前默认仍可使用 FFmpeg 本地合成,VideoProvider 真实驱动仍需按所选视频模型另接。
遗留问题:
- 本机未配置真实 OpenAI Key,本轮未发起真实付费调用;已通过 mock fetch 单测验证 OpenAI 图片/TTS 二进制进入业务链路。
- 图片质量检查、失败自动重试、队列 worker 异步消费和真实视频 Provider 驱动仍需继续生产化。
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
下一步建议:
- 继续补后台用户高危操作与额度冲正审计,或先接入指定真实视频 Provider 驱动并做一次真实付费 E2E 验收。
### 生产化补齐:后台用户高危操作与额度冲正审计
完成时间:2026-06-02 00:45 CST
完成内容:
- 新增后台用户状态管理接口:`PATCH /api/admin/users/:userId/status`,支持启用/停用用户,禁止管理员停用自己。
- 新增后台用户角色管理接口:`PATCH /api/admin/users/:userId/role`,支持普通用户 / 管理员角色切换,禁止管理员移除自己的 admin 角色。
- 新增后台重置密码接口:`POST /api/admin/users/:userId/reset-password`,可输入新密码或自动生成临时密码;操作日志不保存明文密码。
- 新增后台额度冲正接口:`POST /api/admin/users/:userId/quota/adjust`,支持正向补额度和反向扣减可用额度,扣减时校验可用余额。
- 后台人工加余额和额度冲正都会写入额度流水,并额外写入 `operation_logs` 审计记录。
- 用户详情抽屉新增“运营操作”区,运营可在同一处执行状态、角色、密码、额度冲正操作并查看最新流水和最近操作。
- 修复后台用户管理“人工加余额”区域在中等宽度下的重叠风险,改成 `auto-fit` 自适应栅格。
- README 更新后台用户运营能力和内部额度模式说明。
修改文件:
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- backend/src/billing/billing.controller.ts
- backend/src/billing/billing.dto.ts
- backend/src/billing/billing.service.ts
- backend/src/billing/billing.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w admin
- npm test -w backend -- admin.service.spec.ts billing.service.spec.ts
- npm run lint
- npm test
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
- npm run build
- 重启 3000 后端 dist 进程
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5175
- curl -I http://127.0.0.1:5174
- Node fetch 烟测:管理员登录、新注册测试用户、人工加额度、额度冲正、用户禁用/恢复、角色变更/恢复、重置密码后登录、用户详情审计查询
测试结果:
- backend typecheck:通过
- admin build:通过
- 定向测试:通过,2 个测试文件 19 个测试通过
- 全 workspace lint/typecheck:通过
- backend 全量测试:通过,22 个测试文件 128 个测试通过
- admin 测试:无测试文件,按 `--passWithNoTests` 通过
- user-app 测试:无测试文件,按 `--passWithNoTests` 通过
- workers 测试:通过,1 个测试通过
- Prisma schema validate:通过
- 全 workspace build:通过
- 后端 3000 已重启到 PID `3698670`,健康检查返回 `status=ok`
- 后台 5175:返回 200
- 用户端 5174:返回 200
- 真实接口烟测通过:测试用户 `ops-smoke-1780331993114@example.com`,最终 `quota_available=15``status=active``role=user`,重置密码后登录成功;用户详情返回 `admin_correction_deduct` / `admin_grant` 额度流水和状态、角色、密码、冲正操作日志。
遗留问题:
- 高危操作暂未加二次确认弹窗和细粒度 RBAC;目前统一由 admin 角色执行并记录审计日志。
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
下一步建议:
- 跑全量验收并重启服务;随后继续补生产级失败重试、成本阈值、队列 worker 消费和真实视频 Provider 驱动。
### 生产化补齐:失败重试 / 成本阈值 / 队列 worker 消费
完成时间:2026-06-02 01:00 CST
完成内容:
- Provider 运行配置新增成本保护字段:`max_cost_per_call``daily_cost_limit`,后台 AI 接入页可直接填写单次成本上限和当日成本上限。
- Provider 执行前会按 `cost_rule_json` 和环境变量 `PROVIDER_MAX_COST_PER_CALL` / `PROVIDER_DAILY_COST_LIMIT` 做成本预检,超过阈值会拦截调用并写入 failed provider log。
- Provider 执行后会再次检查实际估算成本和输出大小,防止输出超出 Provider 成本规则。
- 新增 worker 内部接口 `POST /api/internal/worker/tasks/:taskId/execute`,使用 `WORKER_SECRET` 鉴权。
- QueuesService 新增 `executeQueuedTask`,按任务类型映射到 Text/Novel/Image/Voice/Video/Moderation/QC/FileParse Provider。
- worker 包从占位状态升级为 BullMQ 消费器:订阅全部队列,收到 job 后调用后端内部执行接口。
- worker 执行失败时,后端会按任务 `max_retry` 自动重入队;达到上限后转为 `manual_required`,后台可继续人工介入。
- 后台用户详情中的状态、角色、重置密码、额度冲正操作增加二次确认弹窗。
- README 更新 worker、成本阈值和后台能力说明。
修改文件:
- backend/src/providers/provider.dto.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- backend/src/queues/queues.module.ts
- backend/src/queues/queues.service.ts
- backend/src/queues/queues.service.spec.ts
- backend/src/queues/worker-tasks.controller.ts
- workers/src/main.ts
- workers/src/main.spec.ts
- admin/src/App.vue
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w workers
- npm test -w backend -- providers.service.spec.ts queues.service.spec.ts
- npm test -w workers
- npm run build -w admin
- npm run lint
- npm test
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
- npm run build
- 重启 3000 后端 dist 进程
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5175
- curl -I http://127.0.0.1:5174
- Node fetch 烟测:新建项目任务、调用内部 worker 执行接口、Provider 成本阈值拦截与恢复
测试结果:
- backend typecheck:通过
- workers typecheck:通过
- Provider / Queue 定向测试:通过,2 个测试文件 25 个测试通过
- workers 测试:通过,1 个测试通过
- admin build:通过
- 全 workspace lint/typecheck:通过
- backend 全量测试:通过,22 个测试文件 133 个测试通过
- admin 测试:无测试文件,按 `--passWithNoTests` 通过
- user-app 测试:无测试文件,按 `--passWithNoTests` 通过
- workers 测试:通过,1 个测试通过
- Prisma schema validate:通过
- 全 workspace build:通过
- 后端 3000 已重启到 PID `3741838`,健康检查返回 `status=ok`
- 后台 5175:返回 200
- 用户端 5174:返回 200
- 真实内部 worker 烟测通过:测试用户 `worker-smoke-1780332971727@example.com`,项目 `32`,任务 `135` 通过 `/api/internal/worker/tasks/135/execute` 执行后状态为 `success`provider_log 为 `success`
- 真实成本阈值烟测通过:临时把 `mock-text` 设置为 `flat_cost=2``max_cost_per_call=1`,执行被 503 拦截,错误为 `PROVIDER_COST_LIMIT_EXCEEDED`;随后已恢复 `mock-text` 成本规则为 `{ flat_cost: 0, unit: 'mock' }`
遗留问题:
- worker 当前是通用 Provider 任务消费,图片/音频/视频资产生成业务接口仍保留同步链路;后续可把具体业务生成步骤逐步改成完全异步编排。
- 真实视频 Provider 驱动仍需按选定视频模型单独接入。
- 细粒度 RBAC 仍未做权限表和角色矩阵,目前高危后台接口仍统一要求 admin。
下一步建议:
- 跑全量验收并重启服务;随后接真实视频 Provider 驱动或补 RBAC/审计导出。
### 生产化补齐:真实视频 Provider 驱动 / 细粒度 RBAC / 审计导出
完成时间:2026-06-02 01:18 CST
完成内容:
- 新增 OpenAI Sora 视频 Provider 默认配置 `openai-video``/api/admin/providers/bootstrap-openai` 会写入 `VideoProvider` real provider。
- 重复初始化 OpenAI Provider 时会保留已加密保存的 API Key、Base URL、超时和成本阈值,避免误清空线上配置。
- Provider 执行层新增 `openai_video_generation` 驱动:按 OpenAI Videos API 异步流程创建视频任务、轮询状态,业务链路需要二进制时下载 MP4。
- `openai_video_generation``provider_logs` 只记录视频 ID、状态、字节数、hash、mime 等摘要,不把 `content_base64` 写入日志。
- 视频生产链路继续复用阶段 16 能力:Provider 返回 MP4 二进制时直接落私有视频资产,否则回退 FFmpeg 本地合成。
- 新增 RBAC helper,后台按 `admin/operator/finance/auditor``admin:read``users:write``billing:write``providers:write``audit:export` 等权限做后端强校验。
- 后台新增 `/api/admin/rbac/me`,前端按权限显示菜单和高危按钮;非 admin 角色不再只能靠页面隐藏。
- 新增审计日志列表和导出接口 `/api/admin/operation-logs``/api/admin/operation-logs/export`,导出操作本身也写入 `operation_logs`
- 后台新增“审计日志”页面,支持按动作、对象类型、操作角色和时间筛选,并可导出 CSV。
- 后台用户角色可调整为 `user/admin/operator/finance/auditor`
- README 和 `.env.example` 补充 `OPENAI_VIDEO_MODEL`、RBAC、Sora Video Provider 和审计导出说明。
修改文件:
- .env.example
- README.md
- CODEX_PROGRESS.md
- backend/src/auth/rbac.ts
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- backend/src/billing/billing.service.ts
- backend/src/providers/provider.types.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- backend/src/queues/queues.service.ts
- backend/src/reviews/reviews.service.ts
- admin/src/App.vue
- admin/src/styles.css
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm run typecheck -w workers
- npm test -w backend
- npm run lint
- npm test
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
- npm run build
- npm test -w backend -- providers.service.spec.ts
- npm test -w backend -- admin.service.spec.ts
- npm run build -w backend
- 重启 3000 后端 dist 进程
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5175
- curl -I http://127.0.0.1:5174
- Node fetch 烟测:admin 登录、RBAC 权限查询、OpenAI Video Provider 存在性、审计导出、普通用户访问后台 RBAC 被拒绝
测试结果:
- backend typecheck:通过
- admin typecheck:通过
- workers typecheck:通过
- backend 全量测试:通过,22 个测试文件 136 个测试通过
- 全 workspace lint/typecheck:通过
- 全 workspace 测试:通过,backend 136 个测试、workers 1 个测试、admin/user-app 无测试文件按 `--passWithNoTests` 通过
- Prisma schema validate:通过
- 全 workspace build:通过
- 后端 3000 已重启到 PID `3816243`,健康检查返回 `status=ok`
- 后台 5175:返回 200
- 用户端 5174:返回 200
- 真实接口烟测通过:OpenAI Provider 列表包含 `openai-video`,驱动为 `openai_video_generation`;审计导出文件名为 `operation-logs-2026-06-02.csv`;普通用户访问 `/api/admin/rbac/me` 返回 403。
遗留问题:
- 本机未配置真实 `OPENAI_API_KEY`,本轮未发起真实 Sora 付费调用;已用 mock fetch 单测验证创建、轮询、下载 MP4 和日志脱敏。
- 当前 RBAC 为代码内角色矩阵,尚未做可配置权限表、权限配置 UI 和数据范围隔离。
下一步建议:
- 跑全 workspace 验收、重启后端和前端服务;随后在生产 Key 配好后做一次真实 Sora 视频小样 E2E 验收。
### 后台体验优化:OpenAI 统一接入
完成时间:2026-06-02 01:39 CST
完成内容:
- 后台 AI 接入默认改为“OpenAI 统一接入”,运营只需要填写一个 OpenAI API Key。
- 新增 `PATCH /api/admin/providers/openai/runtime-config`,批量把同一个 Key、Base URL、超时、成本阈值应用到全部 OpenAI Provider。
- 高级 Provider 配置不删除,默认折叠,只给技术人员单独调整模型、优先级、mock/real 切换和兼容服务。
- 统一配置支持“生产任务优先使用 OpenAI”,勾选后批量把 OpenAI Provider 优先级调到 220。
- 增加测试覆盖,确认统一 Key 批量保存时不会把明文写入配置。
修改文件:
- backend/src/providers/provider.dto.ts
- backend/src/providers/providers.controller.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm test -w backend -- providers.service.spec.ts
- npm run build -w admin
- npm run build -w backend
- 重启 3000 后端 dist 进程
- curl http://127.0.0.1:3000/api/health
- Node fetch 烟测:admin 登录后调用 `/api/admin/providers/openai/runtime-config`
测试结果:
- backend typecheck:通过
- admin typecheck:通过
- Provider 定向测试:通过,18 个测试通过
- admin build:通过
- backend build:通过
- 后端 3000 已重启到 PID `3856864`,健康检查返回 `status=ok`
- 统一 OpenAI 配置烟测通过:批量更新 7 个 OpenAI ProviderProvider 列表仍包含 `openai-video`
遗留问题:
- 本机仍未配置真实 OpenAI Key,未做真实付费调用。
下一步建议:
- 运营在后台“AI 接入”页只填统一 OpenAI Key;确认要真实生成时再勾选“生产任务优先使用 OpenAI”并做一次小样验收。
### OpenAI Key 防误耗额度保护
完成时间:2026-06-02 02:04 CST
完成内容:
- 后台“OpenAI 统一接入”的测试按钮改为“检查连接(不生成内容)”,只调用 `/api/admin/providers/openai/connection-check`
- 新增 OpenAI 连接检查接口:仅请求 OpenAI `/models` 检查 Key/网络,不生成文本、图片、语音或视频,不写 `provider_logs`
- 保存 OpenAI 统一配置时,未勾选“生产任务优先使用 OpenAI”会把全部 OpenAI Provider 优先级保持为 50,低于 mock,避免保存 Key 后自动切到真实模型。
- 高级 Provider 的真实测试增加前端二次确认;真实视频 Provider 测试按钮禁用。
- 后端 `/api/admin/providers/:providerId/test` 增加硬保护:真实 Provider 必须带 `confirm_paid_test=true`,真实视频 Provider 测试直接拒绝。
- 连接检查遇到 `PROVIDER_SECRET_DECRYPT_FAILED` 时返回中文提示,说明需要保持 `PROVIDER_SECRET_KEY/JWT_SECRET` 稳定或重新保存 Key,且不触发生成。
修改文件:
- backend/src/providers/provider.dto.ts
- backend/src/providers/providers.controller.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- README.md
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run typecheck -w admin
- npm test -w backend -- providers.service.spec.ts
- npm run build -w admin
- npm run build -w backend
- 重启 3000 后端 dist 进程
- Node fetch 安全烟测:admin 登录、OpenAI Provider 优先级检查、真实测试接口拦截、连接检查、provider_logs 总数对比
测试结果:
- backend typecheck:通过
- admin typecheck:通过
- Provider 定向测试:通过,22 个测试通过
- admin build:通过
- backend build:通过
- 后端 3000 已重启到 PID `3921216`,健康检查返回 `status=ok`
- 安全烟测通过:OpenAI Provider 共 7 个,优先级均为 50;已配置 Key 的 Provider 为 7 个;真实文本测试未带确认返回 `REAL_PROVIDER_TEST_CONFIRMATION_REQUIRED`;真实视频测试返回 `REAL_VIDEO_PROVIDER_TEST_DISABLED`;连接检查 `billed=false``provider_logs` 总数保持 147 不变。
遗留问题:
- 当前已保存的后台 Key 在本次重启环境下返回 `PROVIDER_SECRET_DECRYPT_FAILED`,说明保存 Key 时使用的 `PROVIDER_SECRET_KEY/JWT_SECRET` 与当前启动环境不一致;需要用同一服务密钥启动后端,或在当前稳定服务密钥下重新保存 OpenAI API Key。
- 本轮未调用任何文本/图片/TTS/视频生成接口,未做真实付费生成验收。
下一步建议:
- 固定生产 `PROVIDER_SECRET_KEY` 后重新保存一次 OpenAI API Key,再只点“检查连接(不生成内容)”确认 Key 可用;确认成本策略后再手动勾选“生产任务优先使用 OpenAI”做受控小样。
### 后端环境变量稳定加载
完成时间:2026-06-02 14:09 CST
完成内容:
- 新增后端 `.env` 加载器,后端入口会在加载 `AppModule` 前读取根目录 `.env``backend/.env`
- 加载优先级为:系统环境变量优先,其次 `.env` 文件;避免重启后 `DATABASE_URL``JWT_SECRET``PROVIDER_SECRET_KEY` 丢失。
- 创建本机 `.env`,写入本地数据库地址、端口、CORS、JWT 密钥和 `PROVIDER_SECRET_KEY`;未写入 OpenAI API Key。
- 用裸 `node backend/dist/main.js` 重启后端,验证不再需要手动在启动命令注入 `DATABASE_URL`
- README 补充 `.env` 自动加载和 `PROVIDER_SECRET_KEY` 必须长期稳定的说明。
修改文件:
- .env
- backend/src/config/load-env.ts
- backend/src/main.ts
- README.md
- CODEX_PROGRESS.md
运行命令:
- git status --short(当前目录不是 Git 仓库)
- npm run typecheck -w backend
- npm run build -w backend
- npm test -w backend -- providers.service.spec.ts
- 重启 3000 后端 dist 进程:`setsid -f node backend/dist/main.js ...`
- Node fetch 烟测:admin 登录、profile、Provider 列表、OpenAI 连接检查、provider_logs 总数对比
测试结果:
- backend typecheck:通过
- backend build:通过
- Provider 定向测试:通过,22 个测试通过
- 后端 3000 已重启到 PID `1309062`,健康检查返回 `status=ok`
- 裸启动烟测通过:`admin@example.com` 登录成功,`/api/auth/profile` 返回 adminProvider 列表可读,OpenAI Provider 仍为 7 个且优先级均为 50。
- 连接检查未触发生成:返回 `billed=false``provider_logs` 总数保持 147 不变。
遗留问题:
- 旧的后台 OpenAI Key 仍返回 `PROVIDER_SECRET_DECRYPT_FAILED`,因为无法知道保存当时使用的服务加密密钥;现在已固定新的 `PROVIDER_SECRET_KEY`,需要在后台重新保存一次 OpenAI Key。
下一步建议:
- 在后台 AI 接入页重新保存 OpenAI API Key,然后只点击“检查连接(不生成内容)”;通过后再决定是否勾选“生产任务优先使用 OpenAI”。
### OpenAI Key 重新保存与连接确认
完成时间:2026-06-02 14:11 CST
完成内容:
- 用户已在后台重新保存 OpenAI API Key。
- 重新执行后台 OpenAI 连接检查,只调用 `/api/admin/providers/openai/connection-check`
- 连接检查返回 `ok=true`OpenAI `/models` 可访问,Key 能在当前稳定 `PROVIDER_SECRET_KEY` 下解密。
- OpenAI Provider 仍保持优先级 50,默认低于 mock,不会自动切到真实生成。
运行命令:
- Node fetch 安全烟测:admin 登录、Provider 列表、OpenAI 连接检查、provider_logs 总数对比
测试结果:
- OpenAI Provider7 个
- 已配置 Key7 个
- OpenAI Provider 优先级:50
- 连接检查:`ok=true``billed=false``endpoint=/models``model_count=118`
- `provider_logs` 总数前后保持 147 不变,确认未触发文本/图片/TTS/视频生成。
遗留问题:
- 当前仍未做真实生成小样;这是有意保留,避免未确认成本策略前消耗额度。
下一步建议:
- 保持当前状态继续用 mock 做业务验收;如果要做真实 AI 小样,先设置单次/当日成本上限,再手动勾选“生产任务优先使用 OpenAI”,只跑一个受控小样。
### 小白使用手册补齐
完成时间:2026-06-02 14:24 CST
完成内容:
- 新增根目录 `OPERATION_GUIDE.md`,不修改 `docs/` 需求文档目录。
- 手册按小白视角解释项目、故事圣经、角色圣经、锚点图、长篇记忆、分集计划、单集脚本、分镜、分镜图、TTS、字幕和视频。
- 补充用户端从注册/登录、新建项目、AI 原创/上传小说、版权确认、故事圣经、角色、分集、脚本、分镜、图片、音频、字幕、视频、下载的一整套操作流程。
- 补充后台运营流程:仪表盘、项目、小说、角色资源、分镜资源、成品漫剧、用户管理、额度、审核、任务、AI 接入、成本日志、系统配置和审计日志。
- 明确说明“场景”当前不是独立场景库,而是 AI 在分集/脚本/分镜中生成的场景名、地点、画面和动作字段,确认前可编辑。
- 增加“哪些内容 AI 生成,哪些需要人确认”的表格,以及常见问题排查表。
- README 增加 `OPERATION_GUIDE.md` 入口。
修改文件:
- OPERATION_GUIDE.md
- README.md
- CODEX_PROGRESS.md
运行命令:
- ls -la
- rg 阅读当前 README、进度记录、用户端和后台页面入口
测试结果:
- 本阶段为纯文档补齐,未调用 OpenAI、未运行真实生成、未消耗额度。
- 未运行代码测试;本次未修改业务代码。
遗留问题:
- 用户端页面本身仍缺少内嵌引导文案和步骤提示;当前先以独立手册形式补齐。
- 后续可把手册内容拆成后台“帮助/操作说明”页面和用户端流程提示。
下一步建议:
- 先按 `OPERATION_GUIDE.md` 用 mock 流程完整走一遍,熟悉每个确认点;确认操作理解后,再决定是否做真实 AI 小样。
### 产品内教程页补齐
完成时间:2026-06-02 14:42 CST
完成内容:
- 后台新增左侧“使用教程”页面,展示后台使用流程、故事圣经/角色圣经/场景/额度等概念说明、从小说到成品的操作顺序、后台常见排查和人工确认点。
- 用户端新增“教程”导航页,登录后可直接查看新手概念、一集从头到尾的步骤、角色/场景/额度等常见问题和新手建议。
- 用户端登录页增加“先看教程”折叠入口,未开始建项目前也能先理解基础流程。
- 用户端新增并注册 `src/pages/help/tutorial` 独立教程页面,给后续 uni-app 小程序/App 路由迁移预留。
- README 更新产品内教程入口说明。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- user-app/src/pages/index/index.vue
- user-app/src/pages/help/tutorial.vue
- user-app/src/styles.css
- user-app/pages.json
- README.md
- CODEX_PROGRESS.md
运行命令:
- git status --short
- npm run typecheck -w admin
- npm run typecheck -w user-app
- npm run build -w admin
- npm run build -w user-app
测试结果:
- 当前目录不是 git 仓库,`git status --short` 返回 `fatal: not a git repository`
- 后台类型检查通过。
- 用户端类型检查通过。
- 后台生产构建通过。
- 用户端生产构建通过。
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
遗留问题:
- 当前教程为产品内摘要版,详细长文仍保留在根目录 `OPERATION_GUIDE.md`
- 当前 Vite H5 入口仍以首页内导航为主;`pages.json` 的独立教程页为后续 uni-app 多端路由预留。
下一步建议:
- 让运营和测试先按用户端“教程”页走一遍 mock 流程;如果仍有不懂的字段,再把对应字段旁边补成就地提示。
### 上传小说解析 400 排查与前端保护
完成时间:2026-06-02 14:51 CST
问题现象:
- 用户端请求 `POST /api/projects/33/novel/parse` 返回 `400 Bad Request`
排查结论:
- 项目 `33` 是上传小说项目,当前 `copyright_status=pending`,项目状态 `source_selecting`
- 项目 `33` 已有粘贴小说源 `source_id=16`,但 `copyright_records` 数量为 `0`
- 后端解析接口要求上传小说必须先完成版权确认,因此返回 `Copyright must be confirmed before parsing novel`
完成内容:
- 用户端上传小说区新增解析前置判断:未完成版权确认时禁用“解析小说”按钮。
- 用户端上传小说区新增提示文案:先保存/上传小说,再在下方完成版权确认,最后解析小说。
- 用户端版权确认按钮在已确认后显示“已确认”并禁用,避免重复点击。
- 用户端 API Client 增加常见英文错误的中文映射,后端返回英文 BadRequest 时前端显示中文可理解提示。
修改文件:
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- rg 定位 `novel/parse` 前后端调用链
- mysql 查询项目 `33`、小说源、素材、版权记录和章节状态
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 对项目 `33`:先在用户端点击“版权确认”的“确认”,再点击“解析小说”。
### 上传小说解析结果就地反馈
完成时间:2026-06-02 14:59 CST
问题现象:
- 用户端点击“解析小说”后按钮只闪一下,页面附近没有明确显示是否成功,用户不知道下一步做什么。
排查结论:
- 项目 `33` 实际已解析成功,数据库中最新小说源 `parse_status=parsed`,章节已生成。
- 用户端只有顶部全局 `解析小说完成` 提示,上传小说卡片内没有解析结果、章节数、字数和下一步提示。
完成内容:
- 上传小说卡片内新增解析状态行:小说源 ID、解析状态、章节数、字数。
- 解析按钮新增动态文案:`解析中``解析小说``重新解析`
- 解析成功后在上传小说卡片内固定显示:已拆出章节数、字数,以及下一步“故事圣经 -> 生成”。
- 点击解析后立即接收接口返回的 `source``chapters` 写入页面状态,再刷新工作台,避免用户只看到按钮闪烁。
- 粘贴小说且版权已确认时,自动解析返回结果也会同步到页面状态。
修改文件:
- user-app/src/pages/index/index.vue
- CODEX_PROGRESS.md
运行命令:
- mysql 查询项目 `33`、小说源、章节状态
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 用户解析成功后,直接看上传小说卡片里的绿色提示;下一步点击“故事圣经”的“生成”。
### 用户端全流程下一步指引
完成时间:2026-06-02 15:04 CST
问题现象:
- 用户端点击“故事圣经 -> 生成”后虽然已生成,但页面没有明确告诉用户下一步应该“检查并确认故事圣经”,后续流程容易迷路。
完成内容:
- 用户端制作页新增顶部“当前下一步”提示卡,会根据项目当前数据自动显示下一步动作。
- 故事圣经卡片新增就地指引:未生成、生成中、待确认、已确认时分别提示下一步。
- 角色库卡片新增就地指引:提示抽取角色、生成锚点图、确认角色库和进入长篇记忆。
- 长篇记忆卡片新增就地指引:提示角色确认后生成记忆,完成后进入分集计划。
- 分集计划卡片新增就地指引:提示生成、检查摘要/钩子、确认分集,以及下一步生成脚本。
- 脚本和分镜卡片新增就地指引:提示生成脚本、确认脚本、生成分镜、确认分镜,以及下一步生成素材。
- 图片/音频/视频卡片新增就地指引:提示分镜图、音频字幕、合成视频的顺序。
- 内容审核卡片新增就地指引:提示合成视频后做文本/视频审核,审核通过后去成品页。
修改文件:
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 继续按用户端顶部“当前下一步”和各卡片绿色/灰色提示操作;如果某个字段仍看不懂,再补字段级说明。
### 用户端结果阅览与媒体任务反馈优化
完成时间:2026-06-02 15:19 CST
问题现象:
- 上传小说解析后刷新页面,输入框为空,用户感觉上传内容“全清空”,只有提示,看不到已保存/已解析的小说内容。
- “图片、音频和视频”区域点击分镜图、音频字幕、合成后,缺少成功/失败/进行中状态和错误提示。
- 媒体生成后没有明显的结果预览入口,用户不知道每一步到底生成了什么。
- 用户确认刚才生成链路是否使用了真实 OpenAI。
排查结论:
- 项目 `33` 已成功生成 10 张分镜图、1 个音频、1 个字幕和 1 个 MP4。
- Provider 日志显示项目 `33` 使用的是 `mock-image``mock-voice``mock-video`,成本均为 `0.0000`,没有真实 OpenAI 调用。
完成内容:
- 上传小说区刷新后会展示已保存小说信息:小说源、标题、作者、来源、解析状态和保存时间。
- 上传小说区新增章节预览列表,展示章节号、标题、字数、状态和正文片段。
- 上传小说文本框增加占位提示:已保存内容在下方预览,如需替换可重新粘贴。
- “图片、音频和视频”区域新增分步骤任务状态卡:分镜图、音频、字幕、视频。
- 每个媒体步骤展示成功/失败/进行中/未开始、成功数量、失败错误原因和下一步动作。
- 媒体素材列表新增预览/下载按钮。
- 新增通用素材预览区,支持图片、音频、视频内嵌预览;其他文件提示下载查看。
- 媒体流程下一步判断改为结合任务状态和素材结果,避免已生成后仍提示“下一步点分镜图”。
修改文件:
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- mysql 查询项目 `33` 的项目状态、小说源、章节、任务、Provider 日志和素材。
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 项目 `33` Provider 汇总:`mock-image` 10 次、`mock-voice` 1 次、`mock-video` 1 次,成本均为 `0.0000`
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 用户端继续补字段级“这是什么”说明,尤其是故事圣经、角色字段、分镜字段和媒体任务字段。
### 下一步提示高亮与 mock 上线策略确认
完成时间:2026-06-02 15:27 CST
完成内容:
- 用户端“当前下一步”提示卡改成红色边框和红色标题,提升用户注意力。
- 核查当前 Provider 配置:mock Provider 9 个启用,优先级 100real OpenAI Provider 7 个启用,优先级 50。
- 确认当前业务链路默认仍走 mock,不会因为已配置 OpenAI Key 就自动消耗真实额度。
- 确认后台已经有“生产任务优先使用 OpenAI”开关;勾选后会把 OpenAI Provider 优先级提高到 220。
上线策略建议:
- 不建议删除 mock Provider。mock 是内部测试、演示、回归测试、故障降级和成本保护的兜底能力。
- 不建议把 mock/real 勾选放到普通用户前端。普通用户看到这个会困惑,也可能误选真实生成导致成本不可控。
- 建议上线时由后台“AI 接入”统一控制:测试默认 mock;准备真实生产时由管理员在后台勾选“生产任务优先使用 OpenAI”,并设置单次/当日成本阈值。
- 对外用户端只展示业务流程和结果,不展示 Provider 模式。
修改文件:
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- rg 查询用户端样式、后台 OpenAI 统一接入、Provider 逻辑。
- mysql 查询 Provider 配置模式、启用状态和优先级。
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 真正上线前不要删除 mock;先在后台设置 OpenAI 成本阈值,再勾选“生产任务优先使用 OpenAI”,用 1 个测试项目跑小样验收。
### 角色锚点图 400 排查与流程顺序修正
完成时间:2026-06-02 15:34 CST
问题现象:
- 用户端请求 `POST /api/characters/36/generate-images` 返回 `400 Bad Request`
- 用户以为真实 OpenAI 图片生成失败。
排查结论:
- 角色 `36` 当前状态是 `generated`,还不是 `locked`
- 项目 `35` 当前状态是 `waiting_character_confirm`,也就是角色库还未确认。
- 后端 `generateCharacterImages` 明确要求 `character.status === locked`,否则返回 `Locked character is required before image generation`
- 这次 400 发生在调用 ImageProvider 之前,项目 `35` 没有新增 Provider 日志,因此没有触发 OpenAI,也没有产生图片成本。
- 当前 ImageProvider 配置为 `openai-image` real 优先级 `220``mock-image` 优先级 `100`;角色确认后再点锚点图会走真实 OpenAI 图片生成。
完成内容:
- 用户端 API Client 增加错误中文映射:`Locked character is required before image generation` -> `请先确认角色库,再生成角色锚点图。`
- 用户端角色流程提示修正为:先抽取角色 -> 检查角色 -> 确认角色库 -> 生成锚点图。
- 用户端“锚点图”按钮改为只有角色库确认后才可点击。
- 用户端点击锚点图时增加前置保护,未确认角色库会直接提示中文错误。
- 用户端角色状态增加 `locked` 中文展示为“已锁定”。
- 用户端下一步提示增加“真实 OpenAI 模式下锚点图会产生图片生成成本”的提醒。
修改文件:
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- CODEX_PROGRESS.md
运行命令:
- rg 定位 `generate-images` 前后端调用链。
- mysql 查询角色 `36`、项目 `35`、ImageProvider 优先级和项目 Provider 日志。
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 对项目 `35`:先点“确认角色库”,确认角色被锁定后,再点“锚点图”。因为当前 ImageProvider 已经是 OpenAI 优先,锚点图会走真实图片生成并产生成本。
### 角色锚点图耗时说明与悬浮下一步提示
完成时间:2026-06-02 15:42 CST
完成内容:
- 用户端角色锚点图生成中提示补充预计耗时:真实 OpenAI 通常每个角色约 20-90 秒;如果超时,当前后端约 60 秒后会回退 mock。
- 用户端角色锚点图生成成功后显示明确成功文案:`角色锚点图生成完成:已处理 N 个角色。`
- 用户端锚点图按钮会在未确认角色库、无待生成角色时给出中文提示,避免用户误点。
- 用户端“下一步”红色提示从页面内卡片改为固定悬浮提示,位于底部导航上方,可点击关闭;当下一步内容变化时会重新出现。
修改文件:
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端生产构建通过。
- 用户端 H5 返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段只改前端提示和文档,未调用 OpenAI、未运行真实生成、未消耗额度。
下一步建议:
- 如果正式生产不允许 mock fallback,需要再把图片 Provider 策略改成“真实 Provider 失败即失败并提示”,而不是自动回退 mock。
### 生产链路禁用 mock 自动回退
完成时间:2026-06-02 15:52 CST
问题结论:
- 正式上线不能出现“OpenAI 超时失败,但系统自动回退 mock 并把任务标成成功”的行为。
- mock 只应保留给内部测试、演示和熟悉流程;生产优先 OpenAI 时,真实 Provider 失败必须让任务失败并提示原因。
完成内容:
- 图片生成调用 ImageProvider 时显式设置 `allow_fallback: false`,真实 OpenAI 超时不会再自动回退 `mock-image`
- TTS、视频、内容审核和队列 worker 的 Provider 调用也统一改为 `allow_fallback: false`
- 后台单个 Provider 测试接口改为只测试选中的 Provider,不允许真实 Provider 测试失败后 fallback mock。
- 图片 Provider 成功但没有返回 `content_base64` 或可下载图片 URL 时,不再生成 mock SVG,占位资产不会落库。
- TTS Provider 成功但没有返回音频内容时,不再生成静音 mock 音频。
- 视频 Provider 没有返回真实视频内容且 FFmpeg 不可用时,不再生成 mock MP4。
- 用户端新增中文错误提示:OpenAI 超时、图片/TTS/视频 Provider 没返回真实内容时会明确说明“真实素材未生成”。
- 已重新构建并重启后端,当前后端进程为 `1508518``/api/health` 正常。
修改文件:
- backend/src/images/images.service.ts
- backend/src/media/media.service.ts
- backend/src/providers/providers.service.ts
- backend/src/queues/queues.service.ts
- backend/src/reviews/reviews.service.ts
- backend/src/images/images.service.spec.ts
- backend/src/media/media.service.spec.ts
- backend/src/queues/queues.service.spec.ts
- user-app/src/api/client.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm test -w backend
- npm run build -w backend
- npm run build -w user-app
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5174
测试结果:
- 后端类型检查通过。
- 后端全量单测通过:22 个测试文件、144 个测试通过。
- 后端构建通过。
- 用户端构建通过。
- 后端 health 返回 `status=ok`
- 用户端 H5 返回 `200 OK`
- 本阶段没有调用真实 OpenAI,没有消耗额度。
下一步建议:
- 重新点一次角色锚点图时,如果 OpenAI 仍超时,前端会显示失败;需要从后台调高 OpenAI 图片 Provider 超时时间,或检查服务器到 OpenAI 的网络连通性。
### 角色锚点图预览与重生成流程
完成时间:2026-06-02 16:03 CST
问题结论:
- 角色锚点图生成后不能只显示任务成功,必须能预览当前锚点图、查看候选图、不满意时重生成或切换锚点。
- 后端已有角色图片列表、设为锚点和强制重生成能力,主要缺少用户端/后台运营入口。
完成内容:
- 用户端新增角色图片列表拉取:刷新项目时自动加载每个角色的锚点图和候选图。
- 用户端角色卡片展示当前锚点状态、候选图数量、候选图列表。
- 用户端支持点击“预览锚点”“预览候选图”“下载候选图”。
- 用户端支持从候选图中点击“设为锚点”。
- 用户端支持对单个角色点击“重生成”,会强制生成新锚点图并设为当前锚点。
- 用户端素材预览面板从媒体区内联面板改成全局浮层,角色区、媒体区、成品区预览都能立即弹出。
- 后台“角色资源”列表操作栏新增“锚点图”按钮,运营可直接预览角色锚点素材。
修改文件:
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- admin/src/App.vue
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w user-app
- npm run build -w user-app
- npm run typecheck -w admin
- npm run build -w admin
- curl -I http://127.0.0.1:5174
- curl -I http://127.0.0.1:5175
- curl http://127.0.0.1:3000/api/health
测试结果:
- 用户端类型检查通过。
- 用户端构建通过。
- 后台类型检查通过。
- 后台构建通过。
- 用户端 H5 返回 `200 OK`
- 后台返回 `200 OK`
- 后端 health 返回 `status=ok`
- 本阶段没有调用真实 OpenAI,没有消耗额度。
下一步建议:
- 如果要允许修改锁定角色的核心外貌字段,需要新增“角色回退编辑/重新确认”流程;当前后端只允许锁定后补充服装、道具、禁用规则等非核心字段,避免破坏后续角色一致性。
### OpenAI 图片超时配置调整
完成时间:2026-06-02 16:10 CST
问题现象:
- 角色锚点图真实 OpenAI 请求返回 `503 OPENAI_REQUEST_TIMEOUT`
- 最新 ImageProvider 日志显示 `openai-image``2026-06-02 08:05:08.979` 等到 `08:06:08.981`,约 60 秒后超时。
排查结论:
- 当前数据库里所有 OpenAI Provider 的 `timeout_ms` 都被后台统一配置保存成了 `60000`
- 生产链路已经禁用 mock fallback,所以真实 OpenAI 超时后会正确失败,不再生成 mock 占位图。
完成内容:
- 将当前数据库所有 `openai-*` Provider 的 `timeout_ms``60000` 更新为 `180000`
- 后台“OpenAI 统一接入”默认超时时间改为 `180000`
- 后台单个 Provider 高级配置的超时占位改为 `180000`
- 后端 `openai-image` 默认初始化配置改为 `180000`
- 重新构建并重启后端,当前后端进程为 `1538959`
修改文件:
- backend/src/providers/provider.types.ts
- admin/src/App.vue
- CODEX_PROGRESS.md
运行命令:
- mysql 查询/更新 provider_configs
- npm run typecheck -w backend
- npm run build -w backend
- npm run typecheck -w admin
- npm run build -w admin
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5175
测试结果:
- 数据库确认所有 `openai-*` Provider 超时为 `180000`
- 后端类型检查通过。
- 后端构建通过。
- 后台类型检查通过。
- 后台构建通过。
- 后端 health 返回 `status=ok`
- 后台返回 `200 OK`
- 本阶段没有调用真实 OpenAI,没有消耗额度。
下一步建议:
- 重新生成角色锚点图时会最多等待 180 秒;如果仍然超时,需要检查服务器到 OpenAI 的网络延迟/代理,或降低图片质量、尺寸后重试。
### 长任务可见进度提示
完成时间:2026-06-02 16:16 CST
问题现象:
- 用户点击单个角色“重生成”后,只有按钮变灰,没有明显 loading、耗时和下一步反馈;非技术用户会误以为页面卡住。
完成内容:
- 用户端所有 `runAction` 动作新增计时器,展示已等待时间。
- 用户端顶部新增当前动作提示条,例如“正在生成角色锚点图 / 已等待 N 秒”。
- 用户端新增全局悬浮进度提示,展示当前动作、已等待时长和长任务说明。
- 角色卡片中新增单角色重生成提示,明确显示“正在重生成某角色的锚点图”。
- 角色锚点生成文案更新为:真实 OpenAI 通常 1-3 分钟,180 秒超时直接失败,不回退 mock。
修改文件:
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w user-app
- npm run build -w user-app
- curl -I http://127.0.0.1:5174
- mysql 查询 ImageProvider 最近日志
测试结果:
- 用户端类型检查通过。
- 用户端构建通过。
- 用户端 H5 返回 `200 OK`
- 最近 ImageProvider 日志仍为旧 60 秒超时记录,180 秒配置后暂无新的图片生成日志。
- 本阶段没有调用真实 OpenAI,没有消耗额度。
下一步建议:
- 更生产化的做法是把图片生成彻底改为后台队列任务:前端提交任务后轮询任务状态,用户可离开页面,完成后站内提示和自动刷新候选图。
### 视频合成 503 修复:默认走 FFmpeg 成片合成
完成时间:2026-06-02 16:46 CST
问题现象:
- 用户端调用 `POST /api/episodes/25/video/render` 返回 `503 Service Unavailable`
- 数据库任务和 Provider 日志显示 `VideoProvider openai-video` 失败,错误为 `Invalid value: '40'. Supported values are: '4', '8', '12', '16', and '20'.`
根因:
- `/video/render` 是“把分镜图、音频、字幕合成为最终 MP4”的接口,但当前真实 OpenAI 优先后误先调用了 `openai-video`
- OpenAI Sora 视频生成的 `seconds` 不是任意成片时长,40 秒被 Provider 拒绝。
- 当前项目的分镜图和 TTS 真实生成日志是成功的,失败点只在最终视频合成误走视频生成 Provider。
完成内容:
- `MediaService.renderEpisodeVideo` 改为:默认 `prefer_ffmpeg !== false` 时直接走本地 FFmpeg 合成,不调用 `VideoProvider`
- 只有显式传 `prefer_ffmpeg:false` 时才调用 `VideoProvider`,用于未来单独的 AI 视频生成/小样流程。
- 默认 FFmpeg 合成仍使用已有分镜图、音频和字幕,生产模式下 FFmpeg 不可用会失败,不生成 mock 成片。
- 新增单测锁定默认行为:本地 FFmpeg 合成不会调用 `VideoProvider`
修改文件:
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm test -w backend -- media.service.spec.ts
- npm test -w backend
- npm run build -w backend
- ffmpeg -version
- curl http://127.0.0.1:3000/api/health
测试结果:
- 后端类型检查通过。
- `media.service` 单测通过:10 tests passed。
- 后端完整测试通过:22 files / 145 tests passed。
- 后端构建通过。
- 本机 FFmpeg 可用:5.1.9。
- 后端已重启,新进程 PID `1605147`health 返回 `status=ok`
- 本阶段没有调用真实 OpenAI,没有消耗额度。
下一步建议:
- 用户端重新点击“合成”后应走 FFmpeg 成片合成;如果素材齐全,应生成 MP4。
- 真正的 OpenAI/Sora 视频生成应单独做“AI 视频小样”入口,并限制 `seconds` 为 Provider 支持值,不再复用最终成片合成接口。
### 视频体验核查:声音 / 中文字幕 / Sora 成本说明
完成时间:2026-06-02 17:03 CST
问题现象:
- 用户合成后发现最终成片仍是图片加解说,不是人物真实动态视频。
- 用户反馈字幕没有正常显示,画面上出现两排小方框。
- 用户反馈播放时没有声音,并观察到 OpenAI 消费约 0.8 美金。
核查结论:
- 第 25 集最新视频任务 `184` 为 FFmpeg 本地合成成功,输出视频资产 `180`,没有调用 Sora。
- 当前产物确实是“分镜图 + TTS + 字幕”的剪辑成片,不是 Sora 这类 AI 动态视频。
- 视频文件内存在 AAC 音轨,时长 40 秒;`ffmpeg volumedetect` 检测到正常音量,文件层面不是无音轨/静音。
- 字幕小方框根因是服务器缺少中文字体,且代码强制 `FontName=Arial`Arial 不覆盖中文。
- 第 25 集本地 provider_logs 里项目成功日志包含 13 次 `openai-image` 和 1 次 `openai-tts`,系统内部成本字段仍为 0;用户在 OpenAI Dashboard 看到的约 0.8 美金应来自真实图片生成和 TTS,而不是 FFmpeg 合成或 Sora。
完成内容:
- 服务器安装 `google-noto-sans-cjk-ttc-fonts`,并刷新字体缓存。
- FFmpeg 字幕样式改为 `Noto Sans CJK SC`,字号从 24 提升到 52,底部边距和描边同步优化。
- FFmpeg 音频合成增加 `loudnorm` 标准响度处理,并把 AAC 码率提升到 128k。
- 用户端点击“合成”改为传 `force:true`,便于重新生成已存在的 FFmpeg 成片;该动作复用已存在图片/音频/字幕,不额外调用 OpenAI。
- 用现有 SRT 做 1 秒 FFmpeg dry-run,确认新字体字幕过滤器可运行。
修改文件:
- backend/src/media/media.service.ts
- user-app/src/api/client.ts
- CODEX_PROGRESS.md
运行命令:
- dnf install -y google-noto-sans-cjk-ttc-fonts
- fc-cache -fv
- fc-list :lang=zh
- ffprobe 检查第 25 集视频和音频文件
- ffmpeg volumedetect 检测最终 MP4 音轨
- npm run typecheck -w backend
- npm run build -w backend
- npm run typecheck -w user-app
- npm run build -w user-app
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5174
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- 用户端类型检查通过。
- 用户端构建通过。
- 后端已重启,新进程 PID `1643780`health 返回 `status=ok`
- 用户端 H5 返回 `200 OK`
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
下一步建议:
- 让用户重新点击“合成”,拿到新字体字幕版本。
- 若要人物真实运动,需要新增“AI 动态视频 / Sora 分镜视频”独立流程:按 4-20 秒短镜头生成动态视频,再做最终剪辑合成。
- 上线前需要在后台清楚区分“低成本剪辑成片”和“高成本动态视频”,并在每一步显示预计费用。
### 视频字幕字号回调
完成时间:2026-06-02 17:11 CST
问题现象:
- 用户反馈新字体字幕过大,已经超出视频画面。
完成内容:
- FFmpeg 字幕 `FontSize` 从 52 回调到 36。
- 字幕描边从 3 回调到 2。
- 字幕增加 `MarginL=90``MarginR=90``MarginV=130`,减少横向溢出和底部贴边。
- 重新执行 FFmpeg 字幕 dry-run,确认过滤器可正常运行。
修改文件:
- backend/src/media/media.service.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w backend
- ffmpeg 字幕 dry-run
- curl http://127.0.0.1:3000/api/health
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- FFmpeg 字幕 dry-run 通过。
- 后端已重启,新进程 PID `1654039`health 返回 `status=ok`
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
### 视频字幕手机屏幕尺寸二次回调
完成时间:2026-06-02 17:17 CST
问题现象:
- 用户反馈字幕仍然偏大,需要按手机竖屏观看尺寸处理。
完成内容:
- FFmpeg 字幕 `FontSize` 从 36 继续下调到 24。
- 去掉字幕阴影,保留 2px 描边,减少大字压迫感。
- 字幕边距调整为 `MarginL=80``MarginR=80``MarginV=120`,适配 1080x1920 手机竖屏底部字幕。
修改文件:
- backend/src/media/media.service.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w backend
- ffmpeg 字幕 dry-run
- curl http://127.0.0.1:3000/api/health
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- FFmpeg 字幕 dry-run 通过。
- 后端已重启,新进程 PID `1666467`health 返回 `status=ok`
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
### 视频字幕手机屏幕尺寸三次回调
完成时间:2026-06-02 17:20 CST
问题现象:
- 用户反馈字幕仍需再小一点,并希望左右两边留出更多空隙。
完成内容:
- FFmpeg 字幕 `FontSize` 从 24 继续下调到 20。
- 字幕左右边距从 80 提升到 150,增加手机竖屏两侧留白。
- 保留中文字体 `Noto Sans CJK SC`、2px 描边和底部 `MarginV=120`
修改文件:
- backend/src/media/media.service.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w backend
- ffmpeg 字幕 dry-run
- curl http://127.0.0.1:3000/api/health
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- FFmpeg 字幕 dry-run 通过。
- 后端已重启,新进程 PID `1672854`health 返回 `status=ok`
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
### 视频字幕字号 12 与分镜文字伪影修复
完成时间:2026-06-02 17:27 CST
问题现象:
- 用户反馈字幕仍很大并超出边框,希望字号改成 12。
- 本地预览发现画面中的大方框并非 FFmpeg 字幕,而是原始分镜图本身生成了漫画气泡/乱码文字。
完成内容:
- 视频合成时不再直接把 SRT 交给 FFmpeg `subtitles` 样式缩放。
- 新增 SRT -> ASS 转换,写入 `PlayResX=1080``PlayResY=1920`,保证字幕字号按手机竖屏固定生效。
- ASS 字幕样式固定为 `Noto Sans CJK SC``Fontsize=12`、左右边距 180、底部边距 120。
- 未来角色图和分镜图 prompt 增加强约束:禁止画面内可见文字、字幕、漫画气泡、对话框、乱码方块;台词只通过表情和动作表达。
- 明确:旧分镜图中的方框已经在图片像素里,重新合成不能移除;需要重新生成分镜图才会消失。
修改文件:
- backend/src/media/media.service.ts
- backend/src/images/images.service.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w backend
- npm test -w backend -- media.service.spec.ts images.service.spec.ts
- ffmpeg 生成 ASS 字幕预览帧
- curl http://127.0.0.1:3000/api/health
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- 图片/媒体相关单测通过:2 files / 17 tests passed。
- ASS 字幕字号 12 预览帧生成成功。
- 后端已重启,新进程 PID `1687323`health 返回 `status=ok`
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
下一步建议:
- 重新点“合成”可获得真正字号 12 的底部字幕。
- 若要去掉画面里的大方框,需要在新 prompt 规则生效后重新生成分镜图;这会产生新的图片生成成本,应由用户确认后再执行。
### 视频无声兼容性修复
完成时间:2026-06-02 17:34 CST
问题现象:
- 用户反馈最新成片前端预览没有声音。
- 检测旧成片资产 `185`:文件内存在 AAC 音轨,平均音量正常,但音频参数为 `96000 Hz / mono`,存在 H5/手机播放器兼容风险。
完成内容:
- FFmpeg 成片合成音频输出固定为更通用的 `AAC 48kHz stereo`
- 保留 `loudnorm` 音量标准化,避免 TTS 音量过低。
- 已用现有图片、音频、字幕重新合成第 25 集成片,未调用 OpenAI。
修改文件:
- backend/src/media/media.service.ts
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w backend
- POST /api/episodes/25/video/render
- ffprobe 音视频流检测
- ffmpeg volumedetect 音量检测
- curl http://127.0.0.1:3000/api/health
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- 后端已重启,新进程 PID `1699032`health 返回 `status=ok`
- 新成片资产 `186` 生成成功,`ffmpeg_used=true`
- 新成片音轨检测通过:`aac``48000 Hz``stereo`、时长 40 秒。
- 新成片音量检测通过:平均音量约 `-20.1 dB`,不是静音。
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
下一步建议:
- 前端点“同步/预览”刷新到最新成片资产 `186` 后再试听。
- 若旧预览 Blob 仍停留在浏览器缓存里,关闭预览后重新点最新 MP4 的“预览”。
### 视频无声二次兼容与自动预览
完成时间:2026-06-02 17:41 CST
问题现象:
- 用户反馈资产 `186` 在电脑播放仍然没有声音。
- 复核 `186` 的磁盘文件和接口下载文件:均存在 AAC 音轨,音量非静音,但用户实际播放仍无声。
完成内容:
- FFmpeg 成片音频进一步改为更保守的 `AAC 44.1kHz stereo`
- 音轨显式标记为默认音轨,并写入中文语言标记 `chi`
- 音频响度从 `I=-16` 调整为 `I=-15` 并叠加 `volume=3dB`,提升电脑播放可感知音量。
- 用户端“合成视频”完成后会清空旧预览,并自动预览本次接口返回的新视频资产,避免继续播放旧 Blob。
- 用现有素材重新合成第 25 集,生成新成片资产 `187`,未调用 OpenAI。
修改文件:
- backend/src/media/media.service.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- CODEX_PROGRESS.md
运行命令:
- npm run typecheck -w backend
- npm run build -w backend
- npm run typecheck -w user-app
- npm run build -w user-app
- POST /api/episodes/25/video/render
- GET /api/assets/187/download
- ffprobe 音视频流检测
- ffmpeg volumedetect 音量检测
- curl http://127.0.0.1:3000/api/health
- curl -I http://127.0.0.1:5174
测试结果:
- 后端类型检查通过。
- 后端构建通过。
- 用户端类型检查通过。
- 用户端构建通过。
- 后端已重启,新进程 PID `1714706`health 返回 `status=ok`
- 用户端 H5 返回 `200 OK`
- 新成片资产 `187` 生成成功,`ffmpeg_used=true`
- `187` 接口下载文件检测通过:`aac``44100 Hz``stereo`、默认音轨、时长 40 秒。
- `187` 音量检测通过:平均音量约 `-16.2 dB`,最大音量约 `-0.8 dB`,不是静音。
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
下一步建议:
- 前端重新点最新成片 `187` 的“预览”或“下载”试听;合成按钮后续会自动打开新成片。
- 如果电脑本地播放器仍无声,请优先用浏览器或 VLC 打开 `video-187.mp4` 交叉验证,因为文件层面已确认音轨存在且可解码。
### AI 真人短剧 mock 模式
完成时间:2026-06-02 18:26 CST
背景:
- 用户明确当前图片漫剧链路不是抖音真人短剧效果,需要新增 `live_action_ai` 输出模式。
- 本阶段只实现 mock 数据流,不接真实 Runway/Kling/Sora/OpenAI 视频模型,不产生真实 AI 成本。
完成内容:
- `projects` 新增 `output_mode``visual_mode``video_generation_level`
- `storyboard_shots` 新增真人短剧字段:`live_action_desc``actor_action``camera_instruction``performance_instruction``video_prompt``keyframe_asset_id``video_clip_asset_id``video_status`
- 新增 `actor_profiles` 表,保存真人演员定妆设定。
- 新增 `video_clips` 表,记录每个分镜的视频片段、Provider、输入关键帧、输出素材、状态和成本。
- 后端新增 LiveAction 模块:
- `GET/POST /projects/:projectId/live-action/actor-profiles`
- `GET/POST /episodes/:episodeId/live-action/shots`
- `POST /episodes/:episodeId/live-action/keyframes/generate`
- `GET/POST /episodes/:episodeId/live-action/video-clips`
- `POST /episodes/:episodeId/live-action/render`
- 关键帧生成显式使用 `mock-image` Provider。
- 视频片段生成显式使用 `mock-video` Provider,并生成可预览的 1080x1920 H.264 MP4 mock 片段。
- 真人短剧合成使用 FFmpeg concat,把视频片段合成为最终 mock MP4。
- 用户端新建项目增加生成类型选择:图片漫剧版、动态漫画版、AI 真人短剧版。
- 用户端真人短剧项目新增“AI 真人短剧”面板:演员定妆、真人分镜、关键帧、视频片段、合成。
- 后台项目详情展示生成类型、演员定妆数量、视频片段数量,并列出 actor profiles / video clips。
- 操作文档新增“生成类型要先选清楚”和真人短剧 mock 流程说明。
新增文件:
- backend/prisma/migrations/20260602095000_live_action_ai_mode/migration.sql
- backend/src/live-action/live-action.controller.ts
- backend/src/live-action/live-action.dto.ts
- backend/src/live-action/live-action.module.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.types.ts
修改文件:
- backend/prisma/schema.prisma
- backend/src/app.module.ts
- backend/src/admin/admin.service.ts
- backend/src/projects/project.dto.ts
- backend/src/projects/project.types.ts
- backend/src/projects/projects.service.ts
- backend/src/*/*.spec.ts 相关 Project/StoryboardShot 测试工厂
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/workflow.ts
- admin/src/App.vue
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
运行命令:
- DATABASE_URL=... npm run db:validate
- npm run db:generate
- DATABASE_URL=... npm run db:deploy
- npm run typecheck -w backend
- npm run typecheck -w user-app
- npm run typecheck -w admin
- npm run build -w backend
- npm run build -w user-app
- npm run build -w admin
- curl http://127.0.0.1:3000/api/health
- live_action_ai 最小项目 API 烟测
- ffprobe mock video clip / final live-action mock MP4
测试结果:
- Prisma schema validate 通过。
- Prisma migration deploy 通过,已应用 `20260602095000_live_action_ai_mode`
- 后端类型检查通过。
- 用户端类型检查通过。
- 后台类型检查通过。
- 后端构建通过。
- 用户端构建通过。
- 后台构建通过。
- 后端已重启,新进程 PID `1797918`health 返回 `status=ok`
- API 烟测创建 `live_action_ai` 项目 `36`,插入最小角色/分集/分镜数据后跑通:
- actor profile 1 条
- live action shot 1 条
- keyframe asset `188`
- video clip asset `189`
- final mock video asset `190`
- `ffprobe` 确认 `189` / `190` 均为 1080x1920、4 秒 H.264 MP4。
- Provider 日志确认仅调用 `ImageProvider/mock-image``VideoProvider/mock-video``cost_actual=0`
- 本阶段未调用任何真实 OpenAI/视频生成接口,没有新增 AI 消耗。
遗留问题:
- `live_action_ai` 当前仍是 mock 视频片段,不是真人会动的真实 AI 视频。
- 动态漫画版 `motion_comic` 仅预留入口,尚未实现局部动效链路。
- 真人短剧最终音频/口型/BGM/字幕还未并入 live-action render,本阶段只拼接视频片段。
- 真实视频 Provider 已完成可替换驱动和受控入口;真实生成仍需配置并显式确认后才会调用。
下一步建议:
- 先用用户端新建 `AI 真人短剧版` 项目熟悉 mock 流程。
- mock 流程确认后,可在后台启用 Runway/Kling 等真实视频 Provider 做受控小样。
### 真实可替换 VideoProvider / 成本预估 / 重试 / 片段质检
完成时间:2026-06-02
完成内容:
- 新增可替换 `VideoProvider` 预设:`runway-image-to-video``kling-image-to-video`
- 两个真实视频 Provider 默认 `is_enabled=false`,不会因为配置 Key 或初始化而自动扣费。
- 后台新增“初始化视频接入”按钮,可写入 Runway/Kling 配置;真实视频 Provider 后台测试仍禁用。
- Provider 服务新增 `runway_image_to_video` / `kling_image_to_video` 驱动:
- 创建 image-to-video 任务。
- 轮询任务状态。
- 提取视频下载 URL。
- 下载 MP4/WebM/MOV 二进制并交给业务层落库。
- Provider 日志会打码 data URI/base64 大字段,避免图片原文写入日志。
- `VideoProvider` 成本规则支持 `unit=video_seconds`,可按 `price_per_second``price_per_clip` 做估算和成本阈值拦截。
- 真人短剧用户端新增:
- 视频 Provider 选择。
- 成本估算。
- 单片段成本上限。
- 真实视频生成确认勾选。
- 强制重生成。
- 片段重试。
- 片段质检。
- 真人短剧后端新增接口:
- `GET /api/live-action/video-providers`
- `GET /api/episodes/:episodeId/live-action/video-clips/cost-estimate`
- `POST /api/live-action/video-clips/:clipId/retry`
- `POST /api/live-action/video-clips/:clipId/quality-check`
- `video_clips` 新增质检字段:`quality_status``quality_score``quality_issues`
- 真实视频 Provider 未带 `confirm_real_video=true` 时直接返回 `REAL_VIDEO_GENERATION_CONFIRMATION_REQUIRED`,不会发起外部 API 调用。
- 后台项目详情展示视频片段成本和质检结果。
修改文件:
- backend/prisma/schema.prisma
- backend/src/providers/provider.types.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.controller.ts
- backend/src/live-action/live-action.dto.ts
- backend/src/live-action/live-action.controller.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.types.ts
- backend/src/admin/admin.service.ts
- admin/src/App.vue
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
新增文件:
- backend/prisma/migrations/20260602112000_real_video_provider_qc/migration.sql
运行命令:
- `set -a; source .env; set +a; npm run db:validate`
- `set -a; source .env; set +a; npm run db:deploy`
- `set -a; source .env; set +a; npm run db:generate`
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm run typecheck -w admin`
- `npm run build -w backend`
- `npm run build -w user-app`
- `npm run build -w admin`
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
- `curl http://127.0.0.1:3000/api/health`
- live-action mock-only API 烟测
- `ffprobe` 检查 mock MP4
测试结果:
- Prisma schema validate 通过。
- Prisma migration deploy 通过,已应用 `20260602112000_real_video_provider_qc`
- 后端、用户端、后台 typecheck 全部通过。
- 后端、用户端、后台 build 全部通过。
- 后端已重启,新进程 PID `1949213`health 返回 `status=ok`
- 安全烟测结果:
- `GET /live-action/video-providers` 返回启用的 `mock-video`
- `GET /episodes/28/live-action/video-clips/cost-estimate?provider_code=mock-video` 返回 `estimated_cost=0`
- 未确认真实 Runway 生成返回 `400 REAL_VIDEO_GENERATION_CONFIRMATION_REQUIRED`
- mock 片段生成成功,新增 video_clip `2`、asset `191``cost_actual=0`
- mock 质检成功,`quality_status=passed``quality_score=94`
- Provider 日志仅新增 `VideoProvider/mock-video``QualityCheckProvider/mock-qc`,未调用 Runway/Kling/OpenAI 真实视频接口。
- `ffprobe` 确认 asset `191` 为 H.264、1080x1920、4 秒 MP4。
遗留问题:
- Runway/Kling 真实付费小样尚未开启验证;需要你确认 Provider、填写 Key、设置价格和成本阈值后再跑。
- 真实视频要求关键帧为 PNG/JPG/WebP;当前真人关键帧 mock 是 SVG,真实视频小样前需要用真实图片 Provider 产出栅格关键帧或提供外部参考图。
- 真人短剧最终合成仍是拼接视频片段,音频、口型、字幕、BGM 和音效还未并入 live-action 成片。
下一步建议:
- 后台 AI 接入页初始化视频接入后,只启用一个视频 Provider,先填 `price_per_second` 和每日成本上限。
- 用 1 个镜头做真实 image-to-video 小样;确认质量、耗时和账单后再扩大到整集。
### 国内可替换 VideoProviderHailuo / Wan / Vidu / Seedance
完成时间:2026-06-02
完成内容:
- 新增通用 `configurable_image_to_video` 驱动,支持可配置异步图生视频流程:
- 创建视频任务。
- 轮询任务状态。
- 从任务结果提取视频 URL。
- 供应商只返回 `file_id` 时,可通过 `output_url_endpoint_template` 再取下载链接。
- 下载真实视频二进制后交给业务层落私有资产。
- 新增国内/短剧向视频 Provider 预设,全部默认禁用:
- `minimax_hailuo_23_fast`
- `minimax_hailuo_23`
- `alibaba_wan26_i2v_flash`
- `alibaba_wan26_i2v`
- `vidu_q3_turbo_reference`
- `vidu_q3_pro`
- `jimeng_seedance`
- `bootstrap-video` 现在会写入 9 个视频 Provider:上述 7 个国内/短剧向 Provider,加 Runway、Kling。
- 重复初始化视频 Provider 时会继续保留已配置的 API Key、Base URL、超时、endpoint、body_style、headers、成本阈值等运行字段,避免覆盖运营配置。
- 后台 AI 接入页补充“可配置图生视频”中文驱动名和 Hailuo/Wan/Vidu/Seedance 说明。
- 用户端真人短剧生成保护增强:
- 指定真实 Provider 但 Provider 未启用时返回 `LIVE_ACTION_VIDEO_PROVIDER_DISABLED`
- 指定真实 Provider 且未确认时返回 `REAL_VIDEO_GENERATION_CONFIRMATION_REQUIRED`
- 不再因为已有旧 mock 片段就绕过真实 Provider 守卫。
- 小白手册补充真实视频小样建议:先测 MiniMax Hailuo 2.3 Fast,再对比 Wan、Vidu、Seedance、Kling/Runway。
修改文件:
- backend/src/providers/provider.types.ts
- backend/src/providers/providers.service.ts
- backend/src/live-action/live-action.service.ts
- admin/src/App.vue
- README.md
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
新增文件:
- backend/prisma/migrations/20260602130000_domestic_video_providers/migration.sql
运行命令:
- `set -a; source .env; set +a; npm run db:validate`
- `set -a; source .env; set +a; npm run db:deploy`
- `set -a; source .env; set +a; npm run db:generate`
- `npm run typecheck`
- `npm test`
- `npm run build`
- `curl http://127.0.0.1:3000/api/health`
- admin 登录后接口烟测:`bootstrap-video`、Provider 列表、用户端 Provider 列表、成本估算、禁用真实 Provider 保护、Provider 日志查询
测试结果:
- Prisma schema validate 通过。
- Prisma migration deploy 通过,已应用 `20260602130000_domestic_video_providers`
- Prisma Client generate 通过。
- 全量 typecheck 通过:backend、admin、user-app、workers。
- 全量 test 通过:backend 22 个测试文件 145 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过。
- 全量 build 通过:backend、admin、user-app、workers。
- 后端已重启,新进程 PID `1989678`health 返回 `status=ok`
- `bootstrap-video` 返回 9 个视频 Provider。
- 后台 VideoProvider 总数为 11,国内 7 个 Provider 均存在,`is_enabled=false`driver 均为 `configurable_image_to_video`
- 用户端 `/live-action/video-providers` 仍只返回启用的 `mock-video`,不会把未启用真实 Provider 暴露给用户。
- MiniMax Hailuo 2.3 Fast 成本估算接口可返回预估:第 28 集当前 1 个片段、4 秒、估算 0.1268 USDProvider 仍为 disabled。
- 使用禁用的 `minimax_hailuo_23_fast` 强制生成会返回 `400 LIVE_ACTION_VIDEO_PROVIDER_DISABLED`,不会回落 mock,也不会调用外部接口。
- Provider 日志确认本次无新增真实国内视频调用;最近视频日志只有 mock 和旧的 OpenAI 视频失败记录,成本为 0。
遗留问题:
- 国内 Provider 的真实付费小样尚未执行;需要你确认使用哪家、填 Key、启用 Provider、设置价格和成本阈值后,先跑 1 个镜头。
- 阿里 Wan、Seedance/即梦不同开通渠道和网关字段差异较大,当前作为可配置模板;正式启用前必须用 1 个镜头核对请求字段、返回 URL、耗时和账单。
- 真实视频仍要求关键帧为 PNG/JPG/WebP 或外部可访问 URLmock SVG 关键帧不能直接作为真实图生视频输入。
下一步建议:
- 后台只启用 `minimax_hailuo_23_fast`,填 Key、Base URL、单次/每日成本上限和真实单价,用 1 个镜头做真实小样。
- 小样验收维度:人物一致性、面部表情、动作自然度、镜头语言、中文短剧感、生成耗时、失败率、实际扣费。
### 系统 B 文档升级:V3 真人动态视频版
完成时间:2026-06-02
完成内容:
- 系统 B 文档从 V2「真人照片 -> 写真图集 / 图片纪念视频」升级为 V3「真人动态视频版」。
- 新增 V3 升级说明,明确系统 B 不推翻旧设计,而是在原照片、主题、世界、场景、视频合成、隐私授权基础上新增真人动态视频链路。
- 新增 V3 主需求文档,明确 4 档输出模式:
- 高清写真图集。
- 图片纪念视频。
- 动态写真视频。
- AI 真人动态视频。
- 高端真人纪念片作为人工报价和多轮精修套餐。
- 明确系统 B 和系统 A 的核心差异:
- 系统 A 是虚构小说角色转真人短剧。
- 系统 B 是真实用户照片转真人动态纪念视频,更强调本人相似度、肖像权、隐私、未成年人和公开授权。
- 主需求、功能清单、技术架构、数据库、API、用户端、后台、AI 流水线、Prompt、成本、队列、合规、测试和 Codex 拆解均补充 V3 增量。
- 新增或强化设计对象:
- `IdentityAnchor`
- `MotionTemplate`
- `VideoClip`
- `LipSyncTask`
- `FaceIdentityProvider`
- `FaceConsistencyProvider`
- `MotionPortraitProvider`
- `LipSyncProvider`
- 明确国内短剧向 VideoProvider 策略:MiniMax Hailuo、阿里 Wan、Vidu、Seedance/即梦、Kling、Runway、MockVideoProvider。
- 明确真实视频 Provider 默认禁用,必须成本预估、用户确认、后台启用、阈值保护后才能调用;失败不能回落 mock 假成功。
- README 和 manifest 已更新为 V3 文档包入口。
修改文件:
- docs/system_b/02_需求文档修改v2.md
- docs/system_b/03_功能清单_页面清单_状态流转设计.md
- docs/system_b/04_技术架构设计_模块拆分.md
- docs/system_b/05_数据库表结构设计.md
- docs/system_b/06_API接口设计文档.md
- docs/system_b/07_uniapp用户端页面交互文档.md
- docs/system_b/08_GeekerAdmin后台管理设计.md
- docs/system_b/09_AI生成流水线_Provider抽象设计.md
- docs/system_b/10_Prompt模板_世界观模板规范.md
- docs/system_b/11_订单支付_额度_成本控制设计.md
- docs/system_b/12_任务队列_错误重试_稳定性设计.md
- docs/system_b/13_隐私授权_内容审核_合规设计.md
- docs/system_b/15_测试用例_验收标准.md
- docs/system_b/16_Codex开发任务拆解文档.md
- docs/system_b/README.md
- docs/system_b/manifest.json
- CODEX_PROGRESS.md
新增文件:
- docs/system_b/00_系统B升级说明_真人动态视频.md
- docs/system_b/01_系统B总需求文档_v3_真人动态视频版.md
运行命令:
- 读取用户粘贴的系统 B 升级建议。
- `find docs -maxdepth 3 -type f`
- `rg` 检索系统 B、VideoProvider、真人动态视频相关文档。
- `sed` 检查系统 B README、主需求、AI 流水线、数据库、合规、测试、拆解等文档。
测试结果:
- 文档更新完成,无代码改动。
- 未运行构建和单测。
下一步建议:
- 按 V3 文档先做系统 B 独立开发计划,优先落地:输出模式、照片上传要求、身份锚点、本人相似度质检、动态写真 mock、真实视频单镜头小样。
### 后台新增 AI 平台入口页
完成时间:2026-06-02
完成内容:
- 后台新增“AI 平台入口”菜单页,方便运营集中查看和开户注册各大 AI 平台。
- 页面整理了已接入或预留接入的平台:
- OpenAI
- MiniMax / Hailuo
- 阿里云百炼 / DashScope
- Vidu
- 火山方舟 / Seedance
- Runway
- Kling
- 内部 Mock / 本地 FFmpeg
- 每个平台展示:
- 官网。
- 控制台/注册入口。
- 文档入口。
- 对应 Provider 编码。
- 后台应填写的 Key 名称。
- 接入状态。
- 费用提醒。
- 运营备注。
- 页面提示运营顺序:先注册/主体认证/充值,再回“AI 接入”页保存 Key;真实视频先做单镜头小样,避免误扣费。
- Kling 标注为“渠道待核”,避免运营误以为接口已完全确认。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- 官方入口检索:OpenAI、MiniMax、阿里百炼/DashScope、Vidu、Runway、火山方舟/Seedance、Kling。
- `npm run typecheck -w admin`
- `npm run build -w admin`
- `curl -I http://127.0.0.1:5175`
测试结果:
- 后台 typecheck 通过。
- 后台 build 通过。
- 后台 dev 服务仍在 5175 运行,HTTP 200。
- 本次未调用任何真实 AI Provider,没有产生 AI 成本。
### 后台 AI 平台入口接入配置跳转
完成时间:2026-06-02
完成内容:
- “AI 平台入口”页新增 Hailuo 快速配置卡片,直接说明 MiniMax / Hailuo 的注册、Key 获取、后台配置路径和推荐默认值。
- 平台入口清单新增“后台配置”列,展示每个平台对应 Provider 的配置状态:
- 未初始化。
- 待配置 Key,未启用。
- 已保存 Key,未启用。
- 已配置并启用。
- 点击“去配置”会自动进入“AI 接入”页并展开高级配置。
- 如果视频 Provider 还没初始化,点击“去配置”会先初始化视频 Provider,再打开对应配置表单。
- Hailuo 默认打开 `minimax_hailuo_23_fast`,便于运营先做低成本单镜头小样。
- 初始化视频 Provider 的提示文案改为“视频 Provider 已初始化,真实接入默认未启用”,避免误解只支持 Runway/Kling。
- 本次只做配置入口和后台 UI 优化,不调用真实 AI,不产生 AI 成本。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
运行命令:
- `npm run typecheck -w admin`
- `npm run build -w admin`
- `curl -I --max-time 5 http://127.0.0.1:5175`
- `git status --short`
测试结果:
- 后台 typecheck 通过。
- 后台 build 通过。
- 后台 dev 服务仍在 5175 运行,HTTP 200。
- 当前目录不是 git 仓库,`git status --short` 返回 `fatal: not a git repository`
### 全局角色资产库 / 跨项目角色复用
完成时间:2026-06-03
完成内容:
- 新增全局角色资产库,用于沉淀可跨项目复用的主角、配角、反派和声音/服装配置。
- 新增数据库表:
- `global_characters`
- `global_character_assets`
- `characters` 表新增复用字段:
- `global_character_id`
- `wardrobe_variant`
- `voice_provider_code`
- `voice_model`
- `voice_id`
- `voice_style`
- `performance_style`
- 后端新增后台接口:
- `GET /api/admin/global-characters`
- `POST /api/admin/global-characters`
- `PATCH /api/admin/global-characters/:globalCharacterId`
- `POST /api/admin/characters/:characterId/bind-global`
- 后台新增“角色资产库”菜单页:
- 可创建/编辑全局角色。
- 可配置锚点素材 ID、固定外观、默认服装、声音 Provider、Voice ID、声音风格、表演风格和授权范围。
- 可查看全局角色被多少项目角色绑定。
- 后台“角色资源”页新增:
- 全局角色绑定显示。
- 下拉选择全局角色并绑定/解绑。
- 角色详情预览展示全局角色、声音、服装变体和表演风格。
- 项目角色创建/更新支持绑定 `global_character_id`
- 绑定全局角色时,如果项目角色缺少锚点、声音或默认服装,会自动带入全局角色资产;项目角色已有差异化设置不强行覆盖。
- 图片 Prompt、分镜 Prompt、真人演员定妆 Prompt 增加全局角色 ID、服装变体、角色声音/表演风格提示,给后续真实图片/视频 Provider 做一致性约束。
- 用户端 `SafeCharacter` 类型同步新增全局角色、服装和声音字段。
- `OPERATION_GUIDE.md` 新增“全局角色资产库”小白说明。
- 已创建一个内部测试全局角色资产:`内部测试女主模板`,用于后台页面联调,不调用 AI、不产生 AI 成本。
修改文件:
- backend/prisma/schema.prisma
- backend/prisma/migrations/20260603093000_global_character_library/migration.sql
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.service.ts
- backend/src/characters/character.dto.ts
- backend/src/characters/character.types.ts
- backend/src/characters/characters.service.ts
- backend/src/images/images.service.ts
- backend/src/scripts/scripts.service.ts
- backend/src/live-action/live-action.service.ts
- backend/src/*/*.spec.ts 相关测试夹具
- admin/src/App.vue
- admin/src/styles.css
- user-app/src/api/client.ts
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
运行命令:
- `set -a; . ./.env; set +a; npm run prisma:validate -w backend`
- `set -a; . ./.env; set +a; npm run prisma:generate -w backend`
- `npm run typecheck -w backend`
- `npm run typecheck -w admin`
- `npm run typecheck -w user-app`
- `set -a; . ./.env; set +a; npm run prisma:deploy -w backend`
- `npm test -w backend`
- `npm run build -w admin`
- `npm run build -w backend`
- `npm run build -w user-app`
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
- Node 脚本真实联调后台登录、创建/更新/读取全局角色资产。
测试结果:
- Prisma schema validate 通过。
- Prisma Client generate 通过。
- 数据库迁移已成功应用。
- 后端 typecheck 通过。
- 后台 typecheck 通过。
- 用户端 typecheck 通过。
- 后端测试 22 个测试文件、145 个测试全部通过。
- 后台 build 通过。
- 后端 build 通过。
- 用户端 build 通过。
- 后端已重启,新 PID4072726。
- 后端健康接口正常。
- 后台 dev 服务仍在 5175 运行,HTTP 200。
- 本次未调用任何真实 AI Provider,没有产生 AI 成本。
遗留问题:
- TTS 当前仍是单集音频生成接口为主,已经有角色级声音数据基础;下一步需要把脚本对白拆成按角色声线合成,再混音成最终音轨。
- 全局角色资产的图片/声音上传和预览目前依赖素材 ID;后续应加“从素材库选择/上传”的弹窗。
- 全局角色版本管理、角色授权到期提醒、批量换装/换声线还未做。
下一步建议:
- 进入“角色级 TTS / 多角色对白混音”阶段:按角色 voice_id 生成对白,旁白独立声线,最后混音并与字幕时间轴对齐。
### 角色级 TTS / 多角色对白混音
完成时间:2026-06-03
完成内容:
- `POST /api/episodes/:episodeId/audio/generate` 默认升级为 `dialogue_mode: mixed` 多角色音频模式。
- 音频生成会按已确认分镜顺序拆分:
- 分镜旁白片段。
- 分镜对白片段。
- 支持识别 `角色名:台词` 格式。
- 无角色名前缀时,从分镜 `characters_json` 推断角色;再兜底到主角/领衔角色。
- 角色对白优先使用项目角色/全局角色里的声音字段:
- `voice_provider_code`
- `voice_model`
- `voice_id`
- `voice_style`
- 旁白使用 `narration_voice` 或默认 `coral`
- 每个片段独立调用 `VoiceProvider`,真实 TTS 会产生多次调用成本;任务 input_json 会记录片段摘要、角色、voice 和 speaker。
- 多个 TTS 片段会用 FFmpeg 转码并 concat 成整集 `dialogue-mix.wav`
- FFmpeg 不可用且全是 mock 片段时,会兜底生成静音 mock wav;真实片段混音必须有 FFmpeg。
- 保留旧单段旁白模式:请求体传 `{ "dialogue_mode": "narration" }`
- 用户端“音频字幕”按钮改为“多角色音频”,并显式传 `dialogue_mode: mixed`
- `OPERATION_GUIDE.md` 增加多角色音频说明和真实 TTS 成本提醒。
修改文件:
- backend/src/media/media.dto.ts
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
运行命令:
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm run typecheck -w admin`
- `npm test -w backend -- src/media/media.service.spec.ts`
- `npm test -w backend`
- `npm run build -w backend`
- `npm run build -w user-app`
- `npm run build -w admin`
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
测试结果:
- 媒体服务单测 10 个全部通过,覆盖默认多角色混音路径。
- 后端测试 22 个测试文件、145 个测试全部通过。
- 后端 typecheck 通过。
- 用户端 typecheck 通过。
- 后台 typecheck 通过。
- 后端 build 通过。
- 用户端 build 通过。
- 后台 build 通过。
- 后端已重启,新 PID4090999。
- 3000、5174、5175 端口均在监听,健康接口正常。
- 本次未调用任何真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 当前混音是按片段顺序 concat,尚未按镜头时间轴精确对齐到每个分镜起止时间。
- 字幕仍按镜头生成,还未拆到每句对白级时间码。
- 后台还需要增加角色声音试听、voice_id 校验、真实 TTS 成本预估和片段级失败重试 UI。
下一步建议:
- 继续做“对白级字幕 / 音频时间轴对齐”:生成每句台词的 SRT cue,并让音频片段按分镜时间轴铺到对应位置。
### 对白级字幕 / 音频时间轴对齐
完成时间:2026-06-03
完成内容:
- `POST /api/episodes/:episodeId/audio/generate` 的多角色音频片段新增时间轴字段:
- `start_seconds`
- `end_seconds`
- `target_duration`
- 多角色 TTS 不再只按顺序 concat;现在会用 FFmpeg 按每段 `start_seconds` 延迟铺轨,输出一条与分镜时间轴对齐的整集 WAV。
- 音频接口返回 `timeline_warnings`,真实 TTS 超出分配时长时会标出超长片段,方便运营缩短台词、加长镜头或调语速。
- `POST /api/episodes/:episodeId/subtitle/generate` 默认升级为 `subtitle_mode: dialogue`
- 对白级字幕会把每句旁白/台词生成独立 SRT cue,并与多角色音频共用同一套分镜时间轴。
- 保留旧版分镜级字幕:请求体传 `{ "subtitle_mode": "shot" }`
- 用户端“图片、音频和视频”区域文案更新为“多角色音频 / 对白级字幕”。
- `OPERATION_GUIDE.md` 更新小白说明:解释多角色音频、对白级字幕、时间轴告警和旧版字幕参数。
修改文件:
- backend/src/media/media.dto.ts
- backend/src/media/media.types.ts
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
运行命令:
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm run typecheck -w admin`
- `npm test -w backend -- src/media/media.service.spec.ts`
- `npm test -w backend`
- `npm run build -w backend`
- `npm run build -w user-app`
- `npm run build -w admin`
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
测试结果:
- 后端 typecheck 通过。
- 用户端 typecheck 通过。
- 后台 typecheck 通过。
- 媒体服务单测 11 个全部通过,覆盖默认多角色音频时间轴和默认对白级字幕。
- 后端测试 22 个测试文件、146 个测试全部通过。
- 后端 build 通过。
- 用户端 build 通过。
- 后台 build 通过。
- 后端已重启,新 PID4109378。
- 3000、5174、5175 端口均在监听,健康接口正常。
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 尚未做前端逐句字幕/音频片段预览和单句重试 UI。
- 真实 TTS 语速控制仍依赖 Provider 能力;后续需要把“超时长台词”在前端明显提示出来。
- 视频最终仍是分镜图 + 音频 + 字幕的 FFmpeg 合成,不是人物真实动态视频。
下一步建议:
- 继续补片段级运营闭环:逐句音频试听、逐句字幕预览、单句重试、超时长台词红色提示,以及真实 TTS 成本预估。
### 片段级音频字幕预览 / 超时提示 / TTS 成本提示
完成时间:2026-06-03
完成内容:
- `GET /api/episodes/:episodeId/media-assets` 保留旧字段:
- `task_type`
- `task_id`
- `asset`
- 同时新增任务详情和媒体摘要:
- `task`
- `timeline`
- `stats`
- 音频资产行会返回:
- 多角色音频 `segments`
- `timeline_warnings`
- 片段数、声音数、总字符数、总时长、告警数量
- TTS 成本提示:按字符/Provider usage 估算,最终以 Provider 日志和平台账单为准
- 字幕资产行会读取私有 SRT 文件并返回 `cues`,用于前端展开预览。
- 多角色音频任务成功后会把实际片段时长、mock 标记、超时告警写回 `render_tasks.input_json`,刷新页面后仍可查看。
- 用户端“图片、音频和视频”新增“音频字幕时间轴”面板:
- 展示每句旁白/对白。
- 展示镜头号、说话人、起止秒、目标时长、实际 TTS 时长、voice。
- 超时句子红色边框提示。
- 支持试听整集音频、下载字幕。
- 支持展开查看前 20 条字幕 cue。
- 工作流任务中文标签从“旁白音频”改为“多角色音频”。
- `OPERATION_GUIDE.md` 补充时间轴面板、超时处理和成本提示说明。
修改文件:
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- user-app/src/workflow.ts
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
运行命令:
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm run typecheck -w admin`
- `npm test -w backend -- src/media/media.service.spec.ts`
- `npm test -w backend`
- `npm run build -w backend`
- `npm run build -w user-app`
- `npm run build -w admin`
测试结果:
- 后端 typecheck 通过。
- 用户端 typecheck 通过。
- 后台 typecheck 通过。
- 媒体服务单测 12 个全部通过,覆盖 media-assets 时间轴返回。
- 后端测试 22 个测试文件、147 个测试全部通过。
- 后端 build 通过。
- 用户端 build 通过。
- 后台 build 通过。
- 后端已重启,新 PID4144718。
- 3000、5174、5175 端口均在监听,健康接口正常。
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 逐句“只重试这一句 TTS”还未做,当前是先展示和定位问题。
- 逐句音频裁切试听还未做,当前试听的是整集音频。
- 成本提示是字符级/Provider usage 提醒,还不是根据具体 Provider 价格换算成美元。
下一步建议:
- 继续做单句 TTS 重试:选择某句、指定 voice/语速、重新合成该句并重新铺轨;同时把真实 Provider 价格规则接入前端美元预估。
### 单句 TTS 重试 / 片段文件保存
完成时间:2026-06-03
完成内容:
- 新增接口 `POST /api/episodes/:episodeId/audio/segments/:segmentIndex/retry`
- 单句重试支持参数:
- `voice`
- `voice_style`
- `speech_speed`,范围 0.6 到 1.4
- 多角色音频生成时会把每句 TTS 的原始音频片段单独保存到私有存储 `generated-audio-segments`
- `render_tasks.input_json.segment_results` 会记录每句片段的:
- 实际时长
- mock 标记
- MIME
- 私有片段路径
- hash/size
- 单句重试时,后端只调用一次 `VoiceProvider` 生成目标句;其它句从私有片段文件读取,然后重新按时间轴混成整集音频。
- 单句重试会创建新的整集音频资产,旧音频资产保留;后续合成视频会使用最新音频。
- 老版本音频缺少片段文件时,不会偷偷整集重跑;接口会提示先重生成整集多角色音频一次。
- 用户端时间轴每句新增“重试此句”按钮。
- 点开后可填写声音 ID、语速、语气说明。
- 如果当前音频不支持单句重试,用户端会显示“重生成音频”按钮和费用提醒。
- 错误文案补充中文提示,避免运营看到英文异常。
- `OPERATION_GUIDE.md` 补充单句重试说明。
修改文件:
- backend/src/media/media.dto.ts
- backend/src/media/media.controller.ts
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- OPERATION_GUIDE.md
- CODEX_PROGRESS.md
运行命令:
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm run typecheck -w admin`
- `npm test -w backend -- src/media/media.service.spec.ts`
- `npm test -w backend`
- `npm run build -w backend`
- `npm run build -w user-app`
- `npm run build -w admin`
测试结果:
- 后端 typecheck 通过。
- 用户端 typecheck 通过。
- 后台 typecheck 通过。
- 媒体服务单测 13 个全部通过,覆盖单句 TTS 重试只调用一次 VoiceProvider。
- 后端测试 22 个测试文件、148 个测试全部通过。
- 后端 build 通过。
- 用户端 build 通过。
- 后台 build 通过。
- 后端已重启,新 PID4174180。
- 3000、5174、5175 端口均在监听,健康接口正常。
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 单句重试后字幕文本未改动;如果要改台词内容,需要后续做“改句文本 + 重写 SRT cue”。
- 逐句音频裁切试听还未做,当前仍试听整集音频。
- 真实 Provider 价格规则还未换算成前端美元预估。
下一步建议:
- 继续做“单句文本编辑 + 字幕 cue 更新 + 单句音频试听裁切”,让运营能在一个抽屉里完成台词、字幕、声音的一句级修正。
### 单句 TTS 连续重试片段元数据保留
完成时间:2026-06-03 16:40:34 CST
完成内容:
- 修复深度验收发现的问题:单句 TTS 重试后,新音频任务只保留被重试片段的 `segment_file_path`,其它复用片段的文件路径丢失,导致无法稳定继续做第二次单句重试。
- `loadStoredAudioSegmentFiles` 读取旧片段时,现在会带回原始 `filePath``size``hash`
- `readTaskAudioSegmentResults` 新增读取 `segment_size``segment_hash`
- 单句重试后写回新的 `render_tasks.input_json.segment_results` 时,所有片段都会保留私有片段文件路径。
- 媒体服务单测补充断言:重试后的 `segment_results` 每个片段都必须有 `segment_file_path`,并保留旧片段 size/hash。
修改文件:
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm test -w backend -- src/media/media.service.spec.ts`
- `npm run lint`
- `npm run typecheck`
- `npm test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 媒体服务单测 13 个全部通过。
- `npm run lint` 通过。
- `npm run typecheck` 通过。
- `npm test` 通过:后端 22 个测试文件、148 个测试通过;workers 1 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- `npm run build` 通过:backend、admin、user-app、workers 均构建成功。
- 后端已重启,新 PID:47233。
- `GET /api/health` 健康检查通过。
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 还未重新跑一次完整端到端连续两次单句重试实机验收;当前已有单测覆盖元数据保留。
- 单句重试后字幕文本未改动;如果要改台词内容,需要后续做“改句文本 + 重写 SRT cue”。
- 逐句音频裁切试听还未做,当前仍试听整集音频。
下一步建议:
- 补一次真实 API E2E:生成多角色音频后连续重试两次不同句子,确认 `media-assets` 始终返回 `segment_retry_ready=true`
- 继续做“单句文本编辑 + 字幕 cue 更新 + 单句音频试听裁切”。
### 后台视频预览本地存储路径稳定化
完成时间:2026-06-03 16:52:23 CST
完成内容:
- 修复后台预览视频时报错:`ENOENT: no such file or directory, open '../storage/private/rendered-videos/2026-06-03/e86eb917-111d-4969-b505-585319fd5e23.mp4'`
- 根因:`.env``LOCAL_STORAGE_ROOT=../storage` 是相对路径,后端从 `/www/wwwroot/ai` 启动时会写入 `/www/wwwroot/storage`,从 `/www/wwwroot/ai/backend` 启动时会读取 `/www/wwwroot/ai/storage`,导致同一条 `local://...` 资产路径在不同启动目录下指向不同磁盘位置。
- `StorageService` 现在会把相对 `LOCAL_STORAGE_ROOT` 固定按 backend 包目录解析,避免启动目录不同导致文件分裂。
- 已将历史目录 `/www/wwwroot/storage/private` 下的本地私有文件按不覆盖方式复制到规范目录 `/www/wwwroot/ai/storage/private`
- 已确认报错资产 `asset_id=221` 对应文件存在于规范目录,并可通过 `GET /api/assets/221/download` 正常返回。
修改文件:
- backend/src/assets/storage.service.ts
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `find /www/wwwroot -path '*e86eb917-111d-4969-b505-585319fd5e23.mp4'`
- `cp -an /www/wwwroot/storage/private/. /www/wwwroot/ai/storage/private/`
- `npm run typecheck -w backend`
- `npm test -w backend`
- `npm run build -w backend`
- `npm run lint`
- `npm run typecheck`
- `npm test`
- `npm run build`
- `curl http://127.0.0.1:3000/api/health`
- 管理员登录后请求 `GET /api/assets/221/download`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端 typecheck 通过。
- 后端测试 22 个测试文件、148 个测试通过。
- 后端 build 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm test` 通过:后端 148 个测试通过;workers 1 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- 后端已重启,新 PID:65044。
- `GET /api/health` 健康检查通过。
- `GET /api/assets/221/download` 返回 HTTP 200`content-type=video/mp4`,大小 `210697` 字节,MP4 header 为 `ftyp`
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 服务器上仍保留旧目录 `/www/wwwroot/storage/private` 作为历史文件来源,暂未删除,避免误删仍被其它进程引用的文件。
- 当前修复覆盖 local 存储;MinIO 模式不受此相对路径问题影响。
下一步建议:
- 后续部署脚本中建议显式配置绝对路径 `LOCAL_STORAGE_ROOT=/www/wwwroot/ai/storage`,进一步减少运维误启动风险。
### 扩展 AI 平台接入骨架
完成时间:2026-06-09 17:22:49 CST
完成内容:
- 新增“扩展 AI Provider”默认预设,后续开通账号后可在后台填写 Key、Base URL、模型名、成本阈值并启用。
- 扩展预设全部默认 `is_enabled=false`,不会自动调用真实外部接口,不会自动扣费。
- 已预置 Google Gemini/Imagen/Veo、Anthropic Claude、DeepSeek、Qwen、Kimi、智谱 GLM、百度千帆、腾讯混元、讯飞星火、豆包/火山方舟文本、MiniMax 文本/TTS、Baichuan、StepFun、SenseNova、360、Mistral、Cohere、xAI、OpenRouter、Together、Fireworks、Perplexity、Azure OpenAI、AWS Bedrock 兼容网关、Stability、Replicate、fal.ai、Ideogram、Leonardo、ElevenLabs、Luma、Pika 等 Provider 配置位。
- 新增真实 driver
- `openai_compatible_chat`
- `anthropic_messages`
- `google_gemini_generate_content`
- `cohere_chat`
- `configurable_image_generation`
- `configurable_text_to_speech`
- `configurable_async_asset_generation`
- `google_veo_video_generation`
- 后台新增 `POST /api/admin/providers/bootstrap-extended-ai`,用于初始化扩展 AI 接入。
- 后台“AI 平台入口”补充扩展平台开户注册/控制台/文档/Key 名称/运营备注。
- 后台“AI 接入”高级工具栏新增“初始化扩展 AI 接入”按钮。
- 已将当前数据库写入 45 个扩展 Provider 预设,全部保持 disabled。
修改文件:
- backend/src/providers/provider.types.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.controller.ts
- backend/src/providers/providers.service.spec.ts
- admin/src/App.vue
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm test -w backend -- providers.service.spec.ts`
- `npm run typecheck -w backend`
- `npm run typecheck -w admin`
- `npm run lint`
- `npm run test`
- `npm run build`
- 使用 Prisma Client 初始化当前数据库扩展 Provider 预设
- 使用 Prisma Client 抽样核验扩展 Provider 列表
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 单测通过:`27` 个测试通过。
- 后端 typecheck 通过。
- 后台 typecheck 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- 当前数据库扩展 Provider 初始化结果:`extended_ai_providers_upserted=45`
- 抽样核验 Google、Claude、DeepSeek、Qwen、Kimi、GLM、ElevenLabs、Stability、Replicate、Luma、Pika 等 Provider 均存在且为 `disabled`
- 后端已重启到新版本,新 PID`3474791``GET /api/health` 健康检查通过。
- 本阶段未配置真实 API Key,未调用真实 AI Provider,没有产生 AI 成本。
遗留问题:
- 部分平台接口、模型名和鉴权方式会随账号渠道变化,当前按可配置模板或 OpenAI-compatible 通道预置;正式启用前仍必须用 1 次小样验证 endpoint、返回字段、耗时和实际账单。
- AWS Bedrock 原生 SigV4、部分国内平台 HMAC 签名通道未在本阶段实现,当前预设优先服务兼容网关/可配置接入。
- 视频类扩展 Provider 成本较高,仍应保持默认禁用并设置单次/每日成本阈值。
下一步建议:
- 先挑 3 条低风险链路做真实 Key 联调:DeepSeek/Qwen 文本、ElevenLabs TTS、Google Gemini 文本。
- 视频真实小样仍建议从 Hailuo Fast 或 Seedance 单镜头开始,不要一次性启用多个真实视频 Provider。
### 后台生产驾驶舱 UI 兼容融合
完成时间:2026-06-09 18:28:16 CST
完成内容:
- 已查看参考图 `/www/wwwroot/dc16513b-fdaf-4721-8091-7fde3a523492.png`,确认可与当前后台兼容融合。
- 后台“仪表盘”改为深色 AI 生产驾驶舱风格,融合参考图中的 KPI 顶栏、系统模块、漫剧生成工作流、AI 平台选择策略、平台对比和成本分析。
- 新仪表盘继续使用现有 `/admin/dashboard``/admin/queues``/admin/providers` 数据,不新增后端接口,不改变 Provider、任务队列、成本控制和权限逻辑。
- 首页加载时同步读取 Provider 列表,用于展示平台预置/启用/Key 配置状态。
- 保留任务状态、项目状态、队列状态等原始运营信息,并增加移动端单列兼容布局。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w admin`
- `npm run build -w admin`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后台 typecheck 通过。
- 后台单独 build 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
- 后台预览服务已确认可访问:`http://127.0.0.1:5175/`
- 后端已用 `setsid node backend/dist/main.js` 守护式启动,PID`3603810``GET /api/health` 健康检查通过。
遗留问题:
- 本阶段是后台仪表盘 UI 融合,没有做真实浏览器截图验收;如需像素级贴近参考图,可继续启动后台预览并按实际窗口微调间距、字号和色彩。
- 平台质量评分仍按真实配置状态展示,没有引入虚假的模型评分。
下一步建议:
- 后台启动预览后人工看一眼仪表盘首屏,确认是否继续把同一视觉风格扩展到“AI 平台入口”和“AI 接入”两个页面。
### AI 平台入口 / AI 接入深色运营台风格接入
完成时间:2026-06-09 20:28:58 CST
完成内容:
- 已将后台深色生产驾驶舱风格继续扩展到“AI 平台入口”和“AI 接入”两个页面。
- `dashboard / aiPlatforms / providers` 三个 section 共享 cockpit 深色外壳、侧边栏和工作区视觉。
- “AI 平台入口”保留开户注册入口、Hailuo 快速配置、平台清单、开户注册顺序,同时统一为深色面板、深色表格、亮色链接按钮和状态 Badge。
- “AI 接入”保留 OpenAI 统一配置、高级 Provider 配置、初始化按钮、Provider 列表、测试结果,同时统一为深色表单、深色输入框、深色工具栏和 Provider 配置面板。
- 本阶段只改后台展示层,不新增接口,不修改真实 Provider 调用逻辑,不写入 API Key。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w admin`
- `npm run build -w admin`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后台 typecheck 通过。
- 后台单独 build 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
遗留问题:
- 本阶段未做浏览器截图级微调;实际观感还需人工打开后台确认列表密度、表格宽度、色彩对比是否满意。
下一步建议:
- 打开后台 `http://127.0.0.1:5175/`,依次查看“仪表盘 / AI 平台入口 / AI 接入”三页,确认是否继续把“成本日志 / 任务管理”也统一到这套运营台风格。
### 任务管理 / 成本日志深色运营台风格接入
完成时间:2026-06-09 20:36:49 CST
完成内容:
- 已将后台“任务管理”和“成本日志”继续接入深色运营台风格。
- 任务管理页新增任务运行概览卡片,展示当前列表任务数、执行中、失败、人工处理和累计重试信息。
- 任务管理页筛选栏、任务表格、刷新任务按钮统一为深色运营台视觉。
- 成本日志页新增 Provider 成本概览卡片,展示总成本、日志数、成功调用、异常调用。
- 成本日志页 Provider 日志表格、刷新成本按钮统一为深色运营台视觉。
- 本阶段只改后台展示层,不修改任务队列、成本统计、Provider 调用和后端接口。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w admin`
- `npm run build -w admin`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后台 typecheck 通过。
- 后台单独 build 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
遗留问题:
- 未做浏览器截图级细调,任务/成本页表格列宽和首屏信息密度仍建议人工预览确认。
下一步建议:
- 人工打开后台依次查看“任务管理 / 成本日志”两页;若整体满意,可继续把“内容审核 / 项目管理 / 成品漫剧”统一成同一套后台风格。
### 全项目 UI 深色运营台风格统一
完成时间:2026-06-09 20:41:36 CST
完成内容:
- 已将后台端所有 section 扩展为统一深色运营台外壳,不再只限制在仪表盘、AI 接入、任务和成本页面。
- 后台补充全局深色覆盖:面板、表格、表单、按钮、状态 Badge、额度卡片、操作区、预览抽屉、JSON 预览、提示消息等统一风格。
- 用户端 `user-app` 增加全局深色生产主题:登录页、底部/侧边导航、项目创建、项目列表、工作台、进度、结果、额度、审核、教程、个人中心、素材预览弹窗等常用组件统一为深色运营台风格。
- 本阶段只改 UI 展示层,不修改后端接口、任务队列、Provider、成本统计、登录鉴权和业务流程。
修改文件:
- admin/src/App.vue
- admin/src/styles.css
- user-app/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w admin`
- `npm run typecheck -w user-app`
- `npm run build -w admin`
- `npm run build -w user-app`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后台 typecheck 通过。
- 用户端 typecheck 通过。
- 后台单独 build 通过。
- 用户端单独 build 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
遗留问题:
- 本阶段为全局风格统一,未做逐页浏览器截图级微调;个别长表格、移动端密集表单和预览弹窗仍建议人工打开确认视觉密度。
下一步建议:
- 人工打开后台和用户端各跑一遍主流程,重点看移动端按钮换行、表格横向滚动、弹窗预览和长文本卡片是否需要精修。
### 成本优化策略硬落地
完成时间:2026-06-09 21:51:16 CST
完成内容:
- 真人动态视频镜头生成增加 Provider 子片段限制:真实/Provider 单次镜头按最多 10 秒拆分,超长镜头自动拆成多个 10 秒以内子片段后用 FFmpeg 拼接回一个镜头资产。
- 真人动态视频成本预估改为按 Provider 子片段计算,任务输入记录 `provider_clip_count``provider_clip_durations`,镜头任务完成后记录预估成本和实际成本。
- TTS 增加同用户私有缓存复用:同文本、同 voice、同 Provider code、同模型、同声音风格、同语速、同片段类型命中时,直接读取历史 `generated-audio-segments` 私有文件,不再调用 TTS Provider。
- 多角色/分段 TTS 已接入缓存与批量适配入口;普通旁白单段 TTS 也已接入同一套缓存元数据。
- ProviderService 新增 `executeProviderBatch` 批量适配层,当前支持统一批量入口和不支持原生批量时的逐条 fallback。
- 音频任务元数据新增 `audio_cache_key``cache_hit``cached_segments``generated_segments`,方便后台后续展示缓存命中和成本节省。
- 本阶段未调用任何真实 AI Provider,没有产生真实 AI 成本;未修改 `docs/` 目录。
修改文件:
- backend/src/live-action/live-action.service.ts
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- backend/src/providers/providers.service.ts
- backend/src/providers/providers.service.spec.ts
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- media.service.spec.ts providers.service.spec.ts`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 目标单测通过:`media.service.spec.ts``providers.service.spec.ts``42` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`155` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- `executeProviderBatch` 当前已实现批量入口和顺序 fallback;具体真实 Provider 的原生合并请求能力还需要按平台 API 单独接驱动,不能默认把所有模型强行合并。
- TTS 缓存按同用户项目范围复用,暂不做全局跨用户缓存,避免私有内容和声音素材串用。
- 真人视频镜头拆分依赖 FFmpeg 拼接;生产机需要保证 FFmpeg 可用。
下一步建议:
- 把后台任务/成本页面补一个“缓存命中 / 拆分片段 / 预估节省”展示,让运营能直观看到哪些镜头或 TTS 片段省了钱。
- 选择一个真实 TTS Provider 和一个真实视频 Provider 做小样,把平台原生批量/异步批量能力接到 `executeProviderBatch` 的 native 分支。
### AI Router V1 / 镜头评分 / 自动选模型
完成时间:2026-06-09 22:21:32 CST
完成内容:
- `storyboard_shots` 新增镜头路由字段:`scene_type``importance_score``emotion_score``action_score``route_tier`
- 新增 `AiRouterModule` / `AiRouterService`,支持按语言、任务类型、镜头评分、Provider 可用状态、预算和降级链自动选择视频 Provider。
- 新增默认 `ai.router.v1` 系统配置:中文普通真人视频镜头优先 `minimax_hailuo_23_fast`,高价值镜头优先 `kling-image-to-video`,降级链为 `kling -> hailuo -> jimeng -> mock`
- Router 会自动给镜头打标签和评分:普通对话、情绪戏、动作戏、远景转场等会得到不同 `scene_type` 与分数。
- 真人短剧分镜准备阶段会写入镜头评分和 `route_tier`;历史镜头缺字段时也会在准备或生成时补齐。
- 真人视频片段生成在未传 `provider_code` 时自动走 Router,不再默认固定 mock;人工 `provider_code` override 仅允许 admin 角色用于测试。
- 视频片段任务 `input_json` 记录完整 `router_decision`,包含候选 Provider、降级原因、评分、route tier、预估成本和最终 provider。
- 用户端真人视频 Provider 默认改为“自动路由”,生成/估算时不再强制传 `mock-video`;仍保留下拉供后续管理员/调试场景使用。
- 本阶段未调用任何真实 AI Provider,没有产生真实 AI 成本;未修改 `docs/` 目录。
修改文件:
- backend/prisma/schema.prisma
- backend/prisma/migrations/20260609220500_ai_router_v1_shot_scores/migration.sql
- backend/prisma/seed.ts
- backend/src/ai-router/ai-router.module.ts
- backend/src/ai-router/ai-router.service.ts
- backend/src/ai-router/ai-router.service.spec.ts
- backend/src/ai-router/ai-router.types.ts
- backend/src/admin/admin.service.ts
- backend/src/live-action/live-action.module.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.service.spec.ts
- backend/src/live-action/live-action.types.ts
- backend/src/images/images.service.spec.ts
- backend/src/media/media.service.spec.ts
- backend/src/scripts/scripts.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- CODEX_PROGRESS.md
新增文件:
- backend/prisma/migrations/20260609220500_ai_router_v1_shot_scores/migration.sql
- backend/src/ai-router/ai-router.module.ts
- backend/src/ai-router/ai-router.service.ts
- backend/src/ai-router/ai-router.service.spec.ts
- backend/src/ai-router/ai-router.types.ts
- backend/src/live-action/live-action.service.spec.ts
运行命令:
- `git status --short`
- `npm run prisma:generate -w backend`
- `npm run typecheck -w backend`
- `npm test -w backend -- ai-router.service.spec.ts media.service.spec.ts images.service.spec.ts scripts.service.spec.ts`
- `npm test -w backend -- ai-router.service.spec.ts live-action.service.spec.ts`
- `npm run prisma:deploy -w backend`
- `set -a; . ./.env; set +a; npm run prisma:deploy -w backend`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Prisma Client 生成通过。
- 首次 `npm run prisma:deploy -w backend` 失败:Prisma CLI 未读取到 `DATABASE_URL`
- 加载根目录 `.env``prisma migrate deploy` 成功,已应用 `20260609220500_ai_router_v1_shot_scores`
- 后端单独 typecheck 通过。
- Router / media / images / scripts 目标单测通过:`33` 个测试通过。
- Router / live-action 集成目标单测通过:`5` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`160` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- Router V1 当前只接入真人视频片段 Provider 自动选择;文本、图片、TTS 的自动路由还未统一接入。
- Router 规则目前用 `SystemConfig` JSON 管理,后台还没有专门的可视化规则编辑器。
- 质量评分低于阈值后的“自动重试一次、再切换 Provider、再进人工”闭环还未做。
- 多语言仅预留 `language` 输入,尚未建立 story/episode/shot translation 表和多语言生产线。
下一步建议:
- 做“Router 质检闭环 V1”:`score < 80` 自动原 Provider 重试一次,再按 fallback 切换 Provider,第三次失败进入人工处理。
- 后台任务/成本页展示 `router_decision`:镜头评分、route tier、候选 Provider、降级原因和预估节省。
### Router 质检闭环 V1
完成时间:2026-06-09 23:15 CST
完成内容:
- 真人视频片段质检入口支持 `auto_repair``min_quality_score``confirm_real_video``max_cost_per_clip`
- 默认质检阈值为 `80` 分;低于阈值时进入自动修复闭环。
- 首次低分:自动沿用当前 Provider 重新生成一次。
- 已重试仍低分:按 Router `fallback_chain` 切换下一个可用 Provider。
- 自动修复超过上限、无可用 fallback、或真实/非 mock Provider 未确认费用时,自动标记为 `manual_required`
- 关闭自动修复时,只标记 `needs_retry`,不误进人工处理。
- 自动修复生成任务会把 `repair_context` 写入 `render_tasks.input_json`,包含源片段、修复动作、Provider、fallback chain、阈值和上一轮质检分数。
- 用户端点击“质检”默认开启自动修复,并根据返回结果提示“通过 / 同 Provider 重试 / 切换 Provider / 人工处理”。
- 单测覆盖:
- `score < 80` 后同 Provider 自动重试并通过。
- 已重试片段再次低分后切换到 fallback Provider 并通过。
修改文件:
- backend/src/live-action/live-action.dto.ts
- backend/src/live-action/live-action.controller.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- live-action.service.spec.ts ai-router.service.spec.ts`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- Router / live-action 目标单测通过:`7` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`162` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- Router 质检闭环 V1 只覆盖真人视频片段;图片、TTS、字幕、整集成片质检还未纳入同一闭环。
- 人工处理队列目前通过 `quality_status=manual_required``video_status=quality_manual_required` 标记,后台尚未做专门的人工处理工作台。
- `repair_context` 已记录在任务输入里,但后台还未可视化展示每次修复链路和节省/新增成本。
下一步建议:
- 做“后台 Router/质检审计视图”:展示镜头评分、Provider 决策、fallback 链、修复次数、质检分数、人工处理原因和成本变化。
### 后台 Router / 质检审计视图
完成时间:2026-06-09 23:35 CST
完成内容:
- 新增后台审计 API`GET /api/admin/router-audits`
- 审计 API 汇总真人视频片段、分镜评分、Provider 配置、生成任务 `router_decision``repair_context` 和质检结果。
- 支持筛选:
- `project_id`
- `episode_id`
- `provider_code`
- `quality_status`
- `route_tier`
- `limit`
- API 返回统计摘要:
- 当前片段数
- 质检通过数
- 建议重试数
- 人工处理数
- 未质检数
- 低分数
- 自动修复数
- 切换 Provider 数
- 预估成本、实际成本、修复新增成本
- 平均质检分
- API 返回明细:
- 项目 / 分集 / 镜头信息
- `scene_type``importance_score``emotion_score``action_score``route_tier`
- 选中 Provider、Provider 模式、模型名
- Router 决策原因、候选 Provider 数、fallback chain、是否人工 override
- 质检状态、分数、人工处理原因
- 自动修复动作、来源片段、上一轮质检状态和分数
- 预估成本、实际成本、成本差额、修复新增成本
- 对应生成任务状态
- 后台新增导航页:“Router 审计”。
- 后台审计页新增统计卡、筛选工具条和明细表格。
- 后台审计页沿用深色运营台风格,并对大表格做横向滚动。
- 单测覆盖 Router 审计 API 能正确解析路由、fallback、修复动作、人工原因和成本差额。
修改文件:
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- admin.service.spec.ts live-action.service.spec.ts ai-router.service.spec.ts`
- `npm run typecheck -w admin`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 后台单独 typecheck 通过。
- Admin / live-action / router 目标单测通过:`20` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`163` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- Router 审计当前是只读视图,还没有从审计页直接触发“重新质检 / 进入人工处理 / 指定 Provider 重试”等操作。
- 审计汇总基于当前查询列表,不是全库长期统计报表;后续如果要做日报/周报,需要单独做聚合表或分析接口。
- 当前只覆盖真人视频片段,图片、TTS、整集视频的 Router/质检审计还未纳入。
下一步建议:
- 做“Router 审计操作闭环”:在审计页对 `manual_required``needs_retry`、低分片段提供重新质检、指定 Provider 重试、确认人工通过/驳回等后台操作。
### Router 审计操作闭环
完成时间:2026-06-09 23:51 CST
完成内容:
- 后台 Router 审计页新增“审计操作参数”面板:
- 指定 Provider Code
- 单片段成本上限
- 是否允许真实/非 Mock Provider 付费修复或重试
- 人工原因
- 人工分数
- 审计明细每行新增操作:
- 重新质检
- 指定 Provider 重试
- 人工通过
- 人工驳回
- “重新质检”复用现有 `POST /api/live-action/video-clips/:clipId/quality-check`
- 默认 `auto_repair=true`
- 默认阈值 `80`
- 只有勾选确认后才允许真实/非 Mock Provider 自动修复。
- “指定 Provider 重试”复用现有 `POST /api/live-action/video-clips/:clipId/retry`
- 使用后台填写的 Provider Code。
- 支持单片段成本上限。
- 真实/非 Mock Provider 会二次确认,并仍受后端确认和成本阈值保护。
- 新增后台人工质检接口:`PATCH /api/admin/router-audits/video-clips/:clipId/quality`
- 人工质检接口支持:
- `passed`
- `rejected`
- `manual_required`
- `needs_retry`
- 人工通过会把低分片段提升到至少 `80` 分,避免仍被统计为低分。
- 人工通过/驳回会同步更新 `storyboard_shots.video_status`
- `quality_passed`
- `quality_rejected`
- `quality_needs_retry`
- `quality_manual_required`
- 人工通过/驳回会写入 `operation_logs`
- 操作人
- 原质检状态
- 新质检状态
- 原分数
- 新分数
- 项目、分集、镜头、片段 ID
- 人工原因
- 权限策略:
- 重新质检 / 指定重试:`tasks:write`
- 人工通过 / 人工驳回:`reviews:write`
- 审计员和财务角色保持只读。
- 单测覆盖人工通过写入 video_clip、storyboardShot 和 operation_log。
修改文件:
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm run typecheck -w admin`
- `npm test -w backend -- admin.service.spec.ts live-action.service.spec.ts ai-router.service.spec.ts`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 后台单独 typecheck 通过。
- Admin / live-action / router 目标单测通过:`21` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`164` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 重新质检和指定重试目前是同步接口;如果未来真实视频生成耗时很长,需要把这两个动作改成后台队列任务。
- 人工通过/驳回只覆盖真人视频片段;图片、TTS、整集视频还没有统一人工质量操作入口。
- Router 审计页还没有展示操作日志时间线;目前操作日志已写入,可在审计日志页查。
下一步建议:
- 做“Router 审计时间线 / 操作历史”:在审计页展开单个片段,显示每次质检、重试、Provider 切换、人工处理、成本变化的完整时间线。
### Router 审计时间线 / 操作历史
完成时间:2026-06-10 00:07 CST
完成内容:
- 新增后台 Router 片段时间线接口:`GET /api/admin/router-audits/video-clips/:clipId/timeline`
- 时间线接口聚合现有数据,不新增表、不改 Prisma schema
- 当前片段审计行
- 同镜头相关 `video_clips`
- 相关 `render_tasks`
- 相关 `provider_logs`
- 相关 `operation_logs`
- 时间线事件覆盖:
- Router 自动选模型
- 视频生成任务创建 / 完成
- Provider 生成调用
- 质检 Provider 调用
- 自动修复策略
- 片段生成记录
- 片段质检状态
- 后台人工质检处理
- 时间线摘要展示:
- 事件数量
- 相关片段数量
- 任务数量
- Provider 调用数量
- 人工操作数量
- Provider 成本
- 最新质检状态和分数
- 后台 Router 审计表每行新增“时间线”按钮。
- 新增右侧 Router 时间线抽屉:
- 顶部摘要卡片
- 事件链路
- 关联任务
- 人工操作
- 时间线节点显示:
- 事件类型
- 状态
- 时间
- Provider Code
- 任务 ID
- 片段 ID
- 成本
- 结构化详情 JSON
- 权限策略:沿用 Router 审计只读权限,仍要求 `admin:read`
- 单测覆盖 Router 时间线聚合,验证路由、修复、Provider、质检、人工操作事件进入同一时间线。
修改文件:
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- admin.service.spec.ts`
- `npm run typecheck -w admin`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 后台单独 typecheck 通过。
- `admin.service.spec.ts` 通过:`15` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`165` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 时间线目前按已有数据库记录聚合;重新质检 / 指定重试这类 live-action 操作本身还没有单独写 `operation_logs`,所以时间线主要通过任务、Provider 日志和片段状态体现。
- 质检 Provider 调用没有 `task_id`,当前通过 `purpose` / `clip_id` 文本匹配归属片段;后续可把质检也任务化,让链路更精确。
- 时间线目前是只读复盘;操作仍在表格行内完成。
下一步建议:
- 做“Router 操作日志增强”:给重新质检、指定 Provider 重试、自动修复触发点补充 `operation_logs`,让时间线能完整区分是谁、什么时候、为什么触发了每一次动作。
### Router 操作日志增强
完成时间:2026-06-10 00:40 CST
完成内容:
- 给后台重新质检入口补充 `operation_logs`
- action`router_audit_quality_recheck`
- target`video_clip`
- metadata 记录项目、分集、镜头、片段、是否自动修复、最低质检分、成本上限、是否确认真实 Provider、原质检状态、原质检分。
- 给指定 Provider 重试入口补充 `operation_logs`
- action`router_audit_manual_provider_retry`
- target`video_clip`
- metadata 记录 Provider Code、成本上限、是否确认真实 Provider、原质检状态、原质检分、重试次数。
- 给低分后的自动修复触发点补充 `operation_logs`
- action`router_audit_auto_repair_triggered`
- target:源 `video_clip`
- metadata 记录修复动作、目标 Provider、触发原因、fallback 链、上一轮质检状态/分数、最低质检分、成本上限。
- 自动修复动作支持进入时间线:
- `retry_same_provider`
- `switch_provider`
- Admin 时间线标题增强:
- `router_audit_quality_recheck` 显示为“后台重新质检”
- `router_audit_manual_provider_retry` 显示为“后台指定 Provider 重试”
- `router_audit_auto_repair_triggered` 显示为“Router 自动修复触发”
- 后台中文标签同步补充上述三个 action。
- 现在 Router 时间线能完整看到:
- 谁触发了重新质检
- 谁指定 Provider 重试
- 系统为什么自动重试或切 Provider
- 每次动作对应的片段、Provider、成本阈值和质检阈值
- 单测补充:
- 指定 Provider 重试会写操作日志。
- 重新质检会写操作日志。
- 自动同平台重试会写操作日志。
- 自动切 Provider 会写操作日志。
修改文件:
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.service.spec.ts
- backend/src/admin/admin.service.ts
- admin/src/App.vue
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- live-action.service.spec.ts admin.service.spec.ts`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 目标单测通过:`live-action.service.spec.ts` + `admin.service.spec.ts``19` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`166` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 质检 Provider 调用仍然没有独立 `task_id`,时间线目前通过 `purpose` / `clip_id` 文本匹配归属片段。
- 重新质检、指定重试目前仍是同步接口;真实视频 Provider 耗时较长时,后续应改成队列任务。
- 自动修复日志记录的是触发点和原因;如果需要“修复完成/失败”的独立人工可读节点,后续可以在生成完成后再写一条结果日志。
下一步建议:
- 做“质检任务化 / Router 队列化”:把重新质检、自动修复、指定 Provider 重试改成后台任务,给每个质检和修复动作分配 `task_id`,让时间线从“可复盘”升级成“可恢复、可重跑、可追踪队列状态”。
### 质检任务化 / Router 队列化 V1
完成时间:2026-06-10 01:08 CST
完成内容:
- 新增真人 Router 队列任务类型:
- `live_action_keyframe_generate`
- `live_action_video_clip_generate`
- `live_action_video_clip_retry`
- `live_action_video_clip_quality_check`
- `live_action_video_render`
- 队列映射补齐:
- 关键帧进入 `image_queue`
- 视频片段生成、指定重试、成片合成进入 `video_queue`
- 片段质检进入 `qc_queue`
- `QueuesService` 新增内部任务创建入口,支持业务服务创建 `render_tasks` 后直接进入队列。
- worker 执行链路支持分发真人 Router 业务任务:
- `live_action_video_clip_retry`
- `live_action_video_clip_quality_check`
- 后台“重新质检”改为创建质检队列任务,返回 `task_id` 与队列信息。
- 后台“指定 Provider 重试”改为创建视频队列任务,返回 `task_id` 与队列信息。
- 保留无队列注入时的同步 fallback,便于单测和极端场景兜底。
- 质检 Provider 调用补充 `task_id`,时间线可以更准确串联到对应质检任务。
- 自动修复触发日志补充父级质检 `task_id`,修复来源可以追溯。
- Router 审计 / 时间线任务查询补充新的真人队列任务类型。
- 后台提示文案更新为“任务已创建”,显示任务 ID 和队列名。
修改文件:
- backend/src/queues/task.types.ts
- backend/src/queues/queues.module.ts
- backend/src/queues/queues.service.ts
- backend/src/queues/queues.service.spec.ts
- backend/src/live-action/live-action.module.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.service.spec.ts
- backend/src/admin/admin.service.ts
- admin/src/App.vue
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- live-action.service.spec.ts queues.service.spec.ts admin.service.spec.ts`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 目标单测通过:`live-action.service.spec.ts``queues.service.spec.ts``admin.service.spec.ts``29` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`167` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 自动修复目前仍在质检任务内部闭环执行;子级修复生成已记录 `repair_context` 和父级质检任务,但还没有拆成独立子任务树。
- `live_action_keyframe_generate``live_action_video_clip_generate``live_action_video_render` 已预置任务类型和队列映射,但本阶段只先把重新质检和指定 Provider 重试任务化。
- Redis 不可用时队列适配器会返回 `enqueued=false`,任务仍会落库;后续可在任务详情页提供重新入队操作。
下一步建议:
- 做“爆款诊断 / 拉片分析 V1”:把创作型产品里有价值的拆片、套路、角色关系、反转节奏沉淀成可复用数据,用来反哺 Story Bible、Prompt Library 和后续自动生成质量。
### 爆款诊断 / 拉片分析 V1
完成时间:2026-06-10 13:29 CST
完成内容:
- 新增爆款拉片数据模型:
- `hit_analysis_cases`:爆款样本、来源平台、题材、指标、拉片文本、诊断结果。
- `hit_analysis_segments`:分段拆解,记录钩子、冲突、情绪、反转、视觉策略、Prompt 种子和镜头评分。
- `creative_patterns`:可复用题材套路 / 角色套路 / 视觉 Prompt / 集节奏模式库。
- 新增后台 API
- `GET /api/admin/hit-analyses`
- `POST /api/admin/hit-analyses`
- `POST /api/admin/hit-analyses/:caseId/analyze`
- `POST /api/admin/hit-analyses/:caseId/patterns`
- `GET /api/admin/creative-patterns`
- 新增规则化诊断 V1
- 按拉片文本自动切分 5-10 秒生产友好的段落。
- 基于本地关键词规则给出钩子、冲突、反转、情绪、视觉、生产复用评分。
- 输出 `key_takeaways``story_bible_seeds``character_archetypes``prompt_keywords``route_hints`
- 不接真实 AI,不消耗 Provider 成本,后续可替换为 TextProvider/Router 驱动分析。
- 新增“沉淀模式”能力:
- 从已诊断样本生成 `opening_hook``reversal_loop``character_archetype``visual_prompt``episode_rhythm` 五类模式。
- 模式记录结构 JSON、Prompt 模板、负面 Prompt、标签和有效性评分。
- 后台新增“爆款诊断”菜单页:
- 录入拉片样本。
- 查看诊断分、核心维度分、拉片结论、分段拆解。
- 对样本重新诊断。
- 一键沉淀模式库。
- 查看可复用模式库。
- 操作日志补充:
- `admin_create_hit_analysis_case`
- `admin_analyze_hit_case`
- `admin_promote_hit_analysis_patterns`
- 已应用本地数据库 migration:`20260610011500_hit_analysis_v1`
修改文件:
- backend/prisma/schema.prisma
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- backend/src/admin/admin.types.ts
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
- backend/prisma/migrations/20260610011500_hit_analysis_v1/migration.sql
运行命令:
- `git status --short`
- `npm run prisma:generate -w backend`
- `npm run typecheck -w backend`
- `npm test -w backend -- admin.service.spec.ts`
- `npm run typecheck -w admin`
- `set -a; . ./.env; set +a; npm run prisma:deploy -w backend`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Prisma Client generate:通过。
- 本地数据库 migration deploy:通过,已应用 `20260610011500_hit_analysis_v1`
- 后端单独 typecheck 通过。
- 后台单独 typecheck 通过。
- 目标单测通过:`admin.service.spec.ts``17` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`169` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 诊断 V1 是本地规则化分析,不调用真实 TextProvider;优点是稳定、零成本,缺点是语义理解不如真实模型。
- 模式库目前已入库并后台可见,但还没有自动接入 Story Bible / 分镜生成 / Prompt Library 的生成上下文。
- 目前不做竞品视频下载或自动转写,拉片文本需要人工粘贴;后续可接素材上传、ASR 或外部数据导入。
下一步建议:
- 做“Prompt Library / 题材套路库 / IP 设定宇宙前台化 V1”:把 `creative_patterns`、Story Bible、角色资产库串起来,让新项目创建和脚本/分镜生成能直接选择并复用这些生产资产。
### Prompt Library / 题材套路库 / IP 设定宇宙前台化 V1
完成时间:2026-06-10 13:45:05 CST
完成内容:
- 新增项目与题材套路绑定表 `project_creative_patterns`,支持一个项目绑定多个 `creative_patterns`,并保留创建时的套路快照。
- 新增用户端 API
- `GET /api/projects/creative-patterns/library`
- `GET /api/projects/:id/creative-patterns`
- `PATCH /api/projects/:id/creative-patterns`
- 新项目创建支持传入 `creative_pattern_ids`,创建后自动绑定已启用的模式库条目,并增加对应 `usage_count`
- Story Bible 生成已接入项目绑定的题材套路:
- `selling_points` 增加题材套路库摘要。
- `tone` 增加已选套路风格。
- `world_summary` 增加套路 / Prompt 规则。
- `taboo_rules` 增加模式库负向禁区。
- 单集脚本生成已接入题材套路,脚本文本新增 `【题材套路库】` 区块,旁白也会吸收套路描述。
- 分镜生成与单镜头 Prompt 重生成已接入题材套路:
- 正向 Prompt 增加 `题材套路/视觉Prompt参考`
- 负向 Prompt 增加 `题材套路禁区`
- 开场镜头吸收 `opening_hook`,结尾镜头吸收 `episode_rhythm`
- 用户端新建项目页新增“题材套路 / IP 设定宇宙”选择器,可从爆款诊断沉淀的模式库选择生产资产。
- 用户端项目工作台新增已绑定套路摘要,方便人工确认当前项目使用了哪些生产模式。
- 已应用本地数据库 migration:`20260610133500_project_creative_patterns_v1`
修改文件:
- backend/prisma/schema.prisma
- backend/src/projects/project.dto.ts
- backend/src/projects/project.types.ts
- backend/src/projects/projects.controller.ts
- backend/src/projects/projects.service.ts
- backend/src/projects/projects.service.spec.ts
- backend/src/story-bibles/story-bibles.service.ts
- backend/src/story-bibles/story-bibles.service.spec.ts
- backend/src/scripts/scripts.service.ts
- backend/src/scripts/scripts.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
新增文件:
- backend/prisma/migrations/20260610133500_project_creative_patterns_v1/migration.sql
运行命令:
- `git status --short`
- `npm run prisma:generate -w backend`
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm test -w backend -- projects.service.spec.ts story-bibles.service.spec.ts scripts.service.spec.ts`
- `bash -lc 'set -a; source .env; set +a; npm run prisma:deploy -w backend'`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Prisma Client generate:通过。
- 本地数据库 migration deploy:通过,已应用 `20260610133500_project_creative_patterns_v1`
- 后端单独 typecheck 通过。
- 用户端单独 typecheck 通过。
- 目标单测通过:`projects.service.spec.ts``story-bibles.service.spec.ts``scripts.service.spec.ts``22` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`173` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 现有项目可以通过 API 更新绑定,但用户端当前只在“新建项目”阶段提供选择器;已有项目的可视化编辑入口建议下一阶段补。
- 模式库来源仍依赖后台“爆款诊断 / 沉淀模式”,用户端暂不创建新模式,避免普通用户污染生产资产库。
- 当前是本地规则化生成链路吸收题材套路;后续接真实 TextProvider 时,需要把这些模式作为 Provider Prompt 上下文继续传递。
下一步建议:
- 做“模式库运营闭环 V1”:后台支持模式编辑、上架/停用、项目效果回流、使用次数和 ROI 统计;用户端补已有项目的模式调整入口,但要限制普通用户只能选择已审核上架的模式。
### 模式库运营闭环 V1
完成时间:2026-06-10 14:05:33 CST
完成内容:
- 后台模式库从“只读列表”升级为“可运营资产”:
- 支持编辑模式类型、标题、题材、语言、描述、Prompt 模板、负向 Prompt、标签、结构 JSON、效果分和状态。
- 支持模式上架、停用、归档。
- 支持从项目效果数据回流并重算 `effectiveness_score`
- 新增后台 API
- `PATCH /api/admin/creative-patterns/:patternId`
- `PATCH /api/admin/creative-patterns/:patternId/status`
- `POST /api/admin/creative-patterns/:patternId/refresh-metrics`
- `GET /api/admin/creative-patterns` 现在返回每条模式的运营指标:
- 绑定项目数、完成项目数、活跃项目数。
- 视频产物数、Provider 日志数、任务数、analytics 事件数。
- 成本、收入估算、ROI 估算。
- 平均质检分、平均完播率、播放数、点赞数。
- ROI / 效果回流 V1 统计口径:
- 成本优先取成功 `provider_logs.cost_actual`,没有 Provider 成本时用 `render_tasks` / `video_clips` 兜底。
- 收入估算取项目已支付订单金额,加上 `analytics_events.metric_json` 里的 `revenue` / `income` / `amount` / `gmv`
- 播放、点赞、完播率从 `analytics_events.metric_json` 读取。
- 质量分从 `video_clips.quality_score` 读取。
- 效果分回流会按使用项目数、完成项目数、质量分、完播率、ROI、播放和点赞综合折算,不再只靠人工主观分。
- 新增操作日志:
- `admin_update_creative_pattern`
- `admin_update_creative_pattern_status`
- `admin_refresh_creative_pattern_metrics`
- 后台“爆款诊断 / 拉片分析”页的模式库区域新增:
- 模式库汇总指标卡。
- 模式编辑表单。
- 选中模式指标侧栏。
- 表格 ROI / 成本 / 播放 / 完播展示。
- 每行“编辑”“回流”操作。
修改文件:
- backend/src/admin/admin.controller.ts
- backend/src/admin/admin.dto.ts
- backend/src/admin/admin.service.ts
- backend/src/admin/admin.service.spec.ts
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm test -w backend -- admin.service.spec.ts`
- `npm run typecheck -w admin`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 后台单独 typecheck 通过。
- 目标单测通过:`admin.service.spec.ts``20` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`176` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 本阶段没有新增长期效果快照表,模式 ROI 是按当前项目绑定和现有日志动态计算;后续如果 analytics 事件量很大,应单独做日级汇总表。
- 收入估算依赖订单和 `analytics_events.metric_json`,真实发布平台数据未接入前,ROI 仍是内部估算口径。
- 用户端已有项目的模式可视化调整入口仍未做,本阶段优先补后台运营闭环。
下一步建议:
- 做“已有项目模式调整 / 生成上下文重跑 V1”:用户端和后台都能给已有项目调整模式绑定,并选择是否重新生成 Story Bible、脚本或分镜,使模式库运营结果真正反哺存量项目。
### 真人视频小样预检 / 验收闭环 V1
完成时间:2026-06-10 17:06:26 CST
完成内容:
- 开发重心切回仿真人视频测试验收,模式库后续再验证。
- 新增真人视频生成前预检接口:
- `GET /api/episodes/:episodeId/live-action/video-clips/preflight`
- 预检报告不会生成视频、不消耗 Provider 成本,只读取项目、分镜、关键帧、Provider、Router 和成本配置。
- 预检报告输出:
- `ready`
- `next_step`
- `blockers`
- `warnings`
- `summary`
- `breakdown`
- 预检可提前发现:
- 未确认分镜。
- 未执行真人分镜改写。
- 缺关键帧。
- 真实视频 Provider 需要 PNG/JPG/WebP 关键帧,但当前仍是 mock SVG。
- 真实视频生成未勾选确认。
- Provider 不存在或未启用。
- 预估费用超过单片段上限。
- 超过 10 秒镜头会自动拆分成多个 5-10 秒子片段。
- 用户端 AI 真人短剧区域接入预检:
- 工作台刷新时自动加载预检报告。
- 原“估算”按钮升级为“预检”,同时刷新成本和预检。
- 生成视频片段前强制再跑一次预检,不通过则阻断生成并显示第一条原因。
- 页面展示预检状态、下一步、阻断/警告、Router 决策 Provider、拆片数量和预估成本。
- 预检保持和实际生成一致的判断口径:
-`mock-video` Provider 或 real mode Provider 需要真实视频确认。
- 真实视频 Provider 必须使用 raster 关键帧。
- 普通用户选择 Provider 不会强制 override,预检会提示最终仍走 Router;管理员保留 override 用于测试。
修改文件:
- backend/src/live-action/live-action.controller.ts
- backend/src/live-action/live-action.dto.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm test -w backend -- live-action.service.spec.ts`
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- 用户端单独 typecheck 通过。
- 目标单测通过:`live-action.service.spec.ts``8` 个测试通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`179` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 当前预检已经覆盖真实视频开跑前的关键安全阀,但还没有做完整“一键跑 1 个镜头小样”的独立测试台。
- 用户端真实关键帧目前仍主要来自 mock SVG;要测试真实 Hailuo/Kling 等图生视频,需要先接入真实图片关键帧或上传 raster 关键帧。
- 后台 Router 审计已有质检/重试操作,但还没有把“预检报告”并入后台审计时间线。
下一步建议:
- 继续围绕仿真人视频做“小样测试台 V1”:后台或用户端选择 1 个镜头,执行预检 -> 生成关键帧/上传关键帧 -> 生成单片段 -> 质检 -> 预览 -> 人工通过/驳回,形成上线前真实 Provider 验收标准流程。
### 真人小样测试台 V1
完成时间:2026-06-10 17:26:53 CST
完成内容:
- 继续聚焦仿真人视频测试优化验收,暂不推进模式库后续验证。
- 后端新增按单个 shot 执行小样验收的能力:
- 预检接口支持 `shot_id`,可只返回当前测试镜头的 Router 决策、阻断原因、关键帧状态和成本。
- 新增绑定上传 raster 关键帧接口:`POST /api/episodes/:episodeId/live-action/shots/:shotId/keyframe`
- 新增单镜头视频片段生成接口:`POST /api/episodes/:episodeId/live-action/shots/:shotId/video-clip/generate`
- 新增人工验收接口:`POST /api/live-action/video-clips/:clipId/manual-review`
- 单镜头生成复用现有 `generateSingleVideoClip`,不会产生一套和批量生成不同的逻辑。
- 单镜头生成前强制执行该 shot 的预检,不通过则按阻断码直接拒绝。
- 上传关键帧复用现有加密资产上传,再绑定到 shot:
- 只接受当前用户/管理员可访问资产。
- 只接受当前项目资产。
- 只接受 `image/png``image/jpeg``image/webp`
- 绑定后清空该 shot 旧的 `video_clip_asset_id`,避免旧片段被误认为当前关键帧产物。
- 人工验收会写回:
- `video_clips.quality_status`
- `video_clips.quality_score`
- `video_clips.quality_issues`
- `storyboard_shots.video_status`
- `operation_logs`
- 用户端 AI 真人短剧区域新增“真人小样测试台”:
- 可选择一个真人镜头。
- 可单镜头预检。
- 可上传 PNG/JPG/WebP 关键帧并绑定到该镜头。
- 可只生成该镜头的小样视频。
- 可预览关键帧和小样视频。
- 可对当前小样执行质检。
- 可人工通过或驳回当前小样。
- 显示当前 shot 的重要度、情绪、动作评分、route tier、Provider、拆片数量和预计成本。
- 分集切换时同步刷新真人资源,避免小样测试台仍显示上一集的 shot/clip。
- 补充小样测试台样式,适配现有深色运营台风格和移动端单列布局。
修改文件:
- backend/src/live-action/live-action.controller.ts
- backend/src/live-action/live-action.dto.ts
- backend/src/live-action/live-action.service.ts
- backend/src/live-action/live-action.service.spec.ts
- user-app/src/api/client.ts
- user-app/src/pages/index/index.vue
- user-app/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm test -w backend -- live-action.service.spec.ts`
- `npm run typecheck -w backend`
- `npm run typecheck -w user-app`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 目标单测通过:`live-action.service.spec.ts``12` 个测试通过。
- 后端单独 typecheck 通过。
- 用户端单独 typecheck 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 真实 Hailuo/Kling 等 Provider 的账号、Key 和真实返回体还未接入,本阶段仍保持 mock-first 和可替换 Provider 架构。
- 上传关键帧目前通过用户端通用资产上传完成,后台端暂未新增独立小样测试页。
- 人工验收备注为当前小样级备注,后续可扩展为结构化问题标签:脸漂、手崩、口型、动作跳切、画质、违规等。
下一步建议:
- 继续做“真人视频真实 Provider 小样验收脚本 V1”:用 1 个固定项目、1 个固定镜头、1 张真实 PNG/JPG 关键帧,按 Provider 分别跑 Hailuo/Kling/mock,记录首帧、片段、质检分、成本和失败原因,形成上线前 Provider 准入标准。
### 真人视频真实 Provider 小样验收脚本 V1
完成时间:2026-06-10 17:52:03 CST
完成内容:
- 新增可重复执行的真人视频 Provider 小样验收脚本:
- `npm run live-action:acceptance -w backend`
- 根目录别名:`npm run live-action:acceptance`
- 脚本通过 Nest application context 调用现有服务,不绕过业务链路:
- `AssetsService`
- `LiveActionService`
- `ProvidersService`
- `PrismaService`
- 脚本输入固定项目、固定分集、固定镜头和真实 PNG/JPG/WebP 关键帧。
- 脚本会按 Provider 矩阵逐个执行:
- 单镜头预检。
- 可选上传并绑定 raster 关键帧。
- 单镜头视频片段生成。
- 即时质检。
- 成本、质量分、失败原因、输出资产记录。
- 默认 Provider 矩阵:
- `hailuo` -> `minimax_hailuo_23_fast`
- `kling` -> `kling-image-to-video`
- `mock` -> `mock-video`
- 脚本默认安全:
- 没有 `LIVE_ACTION_ACCEPTANCE_CONFIRM_REAL_VIDEO=true` 时,真实 Provider 只做预检并跳过生成。
- 真实 Provider 默认不自动启用,除非显式设置 `LIVE_ACTION_ACCEPTANCE_FORCE_ENABLE_PROVIDERS=true`
- 真实生成仍会走现有 `confirm_real_video`、Provider enabled、raster keyframe、成本上限等保护。
- 关键帧上传细节:
- 上传使用项目 owner 身份,避免管理员上传后用户端无法预览私有素材。
- Provider override、验收和日志仍使用管理员身份。
- 脚本输出验收报告:
- JSON 报告。
- Markdown 报告。
- 默认路径:`storage/private/live-action-acceptance/YYYY-MM-DD/`
- 报告字段包含:
- Provider code / label。
- preflight ready / next step。
- blockers / warnings。
- clip id。
- output asset id。
- `/api/assets/:assetId/download` 预览下载路径。
- actual cost。
- quality status / score。
- repair action。
- error message。
- passed / failed / skipped 汇总。
- 支持失败门禁:
- `LIVE_ACTION_ACCEPTANCE_FAIL_ON_REJECT=true` 时,只要有 Provider 未通过,脚本退出码为 1,后续可接 CI 或上线前检查。
示例命令:
```bash
LIVE_ACTION_ACCEPTANCE_PROJECT_ID=123 \
LIVE_ACTION_ACCEPTANCE_EPISODE_ID=456 \
LIVE_ACTION_ACCEPTANCE_SHOT_ID=789 \
LIVE_ACTION_ACCEPTANCE_KEYFRAME_PATH=/www/wwwroot/ai/storage/test-keyframe.png \
LIVE_ACTION_ACCEPTANCE_PROVIDERS=hailuo,kling,mock \
LIVE_ACTION_ACCEPTANCE_CONFIRM_REAL_VIDEO=true \
LIVE_ACTION_ACCEPTANCE_MAX_COST_PER_CLIP=1 \
npm run live-action:acceptance -w backend
```
修改文件:
- package.json
- backend/package.json
- backend/src/live-action/live-action-provider-acceptance.ts
- CODEX_PROGRESS.md
新增文件:
- backend/src/live-action/live-action-provider-acceptance.ts
运行命令:
- `git status --short`
- `npm run typecheck -w backend`
- `npm run live-action:acceptance -w backend`
- `npm run typecheck`
- `npm run lint`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单独 typecheck 通过。
- `npm run live-action:acceptance -w backend` 可正常拉起脚本,并在未传必填环境变量时安全失败:`LIVE_ACTION_ACCEPTANCE_PROJECT_ID is required`
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run test` 通过:
- 后端 `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 本阶段只实现验收脚本,不实际调用 Hailuo/Kling 付费接口;真实调用需要先在后台配置真实 Key、启用 Provider,并显式设置确认环境变量。
- 报告为文件型报告,后台端暂未做 Provider 准入报告列表页。
- 当前质量检查仍走 mock-qc;后续可接真实视觉 QA Provider,对脸部漂移、手部异常、动作跳切、口型等做更细评分。
下一步建议:
- 做“真人 Provider 准入报告后台化 V1”:后台读取 `storage/private/live-action-acceptance` 报告,按 Provider 展示质量分、成本、失败原因、输出视频预览,并标记“准入/禁用/待复测”。
### 前端 H5/PC 流程视觉验收与重叠修复 V1
完成时间:2026-06-10 18:34:37 CST
完成内容:
- 新增 Playwright 视觉巡检脚本,覆盖用户端 PC/H5 与后台 PC/H5 的关键登录态页面。
- 用户端覆盖:新建、项目、制作、额度、审核、进度、成品、教程、我的。
- 后台覆盖:仪表盘、项目管理、任务管理、Router 审计、爆款诊断、AI 平台入口、AI 接入、成本日志、审计日志。
- 修复用户端 H5 NEXT 浮动提示遮挡/重叠问题:
- H5 端不再显示浮动 NEXT 提示,避免压住输入框、按钮和底部导航。
- PC 端保留浮动提示,并限制高度、字号和长文本省略。
- H5 顶部长项目标题字号下调,降低长标题换行造成的视觉压迫。
- 修复后台 AI 平台入口 PC 表格右侧状态列被裁切问题:
- 平台入口清单增加专用表格类。
- 宽屏下使用固定表格布局和列宽,内容允许换行。
- 巡检脚本支持识别合法的 line-clamp/ellipsis 省略,避免把正常省略号误报为 UI 溢出。
- 最终视觉报告生成在 `storage/private/frontend-visual-audit/report.json`,截图生成在 `storage/private/frontend-visual-audit/*.png`
修改文件:
- user-app/src/styles.css
- admin/src/App.vue
- admin/src/styles.css
- CODEX_PROGRESS.md
新增文件:
- tools/frontend-visual-audit.mjs
运行命令:
- `git status --short`
- `npx -y playwright@1.49.1 --version`
- `npx -y playwright@1.49.1 install chromium`
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-visual-audit.mjs`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Playwright Chromium 安装成功,视觉巡检脚本可执行。
- 最终视觉巡检共覆盖 `36` 个页面步骤,汇总结果:
- 横向页面溢出:`0`
- 文本异常溢出:`0`
- 交互元素重叠:`0`
- console/page error`0`
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 本次是自动化视觉巡检 + 关键截图人工抽查,不等同于全部业务动作真实提交验收;真实流程仍建议按“创建项目 -> 生成 -> 任务队列 -> 预览/下载”逐条人工点一遍。
- Playwright 目前通过 `npx` 缓存路径配合 `NODE_PATH` 运行,尚未写入项目依赖或 npm script。
- H5 端关闭了浮动 NEXT 提示,后续如果要恢复,需要改成非固定布局或页面内提示,不能再用固定浮层压操作区。
下一步建议:
- 做“前端真实业务动作 E2E V1”:用 Playwright 不只截图,而是实际走创建项目、版权确认、生成 mock、查看任务、预览成品、后台审计的完整点击链路,并把失败点输出成报告。
### 前端真实业务动作 E2E V1
完成时间:2026-06-10 18:48:50 CST
完成内容:
- 新增真实业务动作 E2E 脚本,覆盖“上传小说改编 -> mock 生成 -> 成品预览 -> 后台核查”的完整主链路。
- E2E 使用 Playwright 打开真实用户端和后台端页面,关键业务动作通过 UI 点击执行,API 仅用于登录、额度准备和结果断言。
- 用户端真实点击链路:
- 打开制作台。
- 新建“上传小说改编 / 图片漫剧版”项目。
- 准备 mock 支付额度。
- 粘贴小说正文。
- 版权确认。
- 解析小说。
- 生成并确认故事圣经。
- 抽取并确认角色库。
- 生成长篇记忆。
- 生成并确认分集计划。
- 生成并确认脚本。
- 生成并确认分镜。
- 生成分镜图。
- 生成多角色音频和字幕。
- 合成 MP4。
- 自动预览合成结果。
- 文本审核、视频审核。
- 成品页再次预览。
- 后台真实点击链路:
- 打开任务管理。
- 打开内容审核。
- 打开审计日志。
- E2E 产出 JSON 与 Markdown 报告,并保存关键截图。
- 最终通过样本:
- project_id`48`
- episode_id`34`
- video_asset_id`272`
- 任务数:`13`
- 后台内容审核记录:`2`
- 失败任务:`0`
修改文件:
- CODEX_PROGRESS.md
新增文件:
- tools/frontend-business-e2e.mjs
运行命令:
- `git status --short`
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-business-e2e.mjs`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 最终 E2E 报告:
- `storage/private/frontend-business-e2e/report-20260610104646.json`
- `storage/private/frontend-business-e2e/report-20260610104646.md`
- `storage/private/frontend-business-e2e/latest-report.json`
- `storage/private/frontend-business-e2e/latest-report.md`
- 最终 E2E 汇总:
- 总步骤:`9`
- 通过步骤:`9`
- 失败步骤:`0`
- 失败数:`0`
- 截图数:`11`
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- E2E 记录了一个非阻断 UI warning:`有 8 句 TTS 超出分配时长`。音频、字幕、视频仍生成成功,但说明当前 mock 剧本台词时长与镜头时长存在节奏不匹配,后续应优化脚本/分镜时长分配或 TTS 语速策略。
- 后台 `operation_logs` 对普通用户生成动作没有 project 维度日志,E2E 标记为 warning;当前后台仍能通过任务管理和内容审核查到本项目生成与审核结果。
- Playwright 仍通过 `npx` 缓存路径配合 `NODE_PATH` 运行,尚未写入项目依赖或 npm script。
下一步建议:
- 做“E2E 问题闭环 V1”:针对 TTS 超时 warning,优化脚本分镜生成约束,让每句台词预估时长不超过镜头时长;同时评估是否需要为普通用户关键生成动作补充 operation_logs 或生成流水线审计日志。
### PC 制作页额度余额遮挡修复 V1
完成时间:2026-06-10 18:53:40 CST
完成内容:
- 修复用户端 PC 制作页额度余额卡片在双列布局下宽度不足导致的标题、额度信息和按钮挤压遮挡问题。
-`.quota-inline` 在桌面制作页中设置为横跨整行,让“额度余额 / 可用 / 冻结 / 预估 / 状态 / 查看额度 / 冻结额度”有稳定展示空间。
- 为额度卡片单独补充标题换行、按钮对齐、720px 以上三列布局、1080px 以上桌面整行布局,保留 H5 纵向堆叠。
- 重新运行前端视觉巡检,PC/H5 用户端和后台端共 36 个页面状态均无页面溢出、文本溢出、交互元素重叠、控制台错误。
修改文件:
- user-app/src/styles.css
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-visual-audit.mjs`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 前端视觉巡检通过:
- 报告:`storage/private/frontend-visual-audit/report.json`
- PC 制作页截图:`storage/private/frontend-visual-audit/user-pc-studio.png`
- 36 个页面状态全部 `pageOverflow=0``textOverflow=0``overlaps=0``consoleErrors=0`
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 本次只修复 PC 制作页额度卡片遮挡;此前 E2E 记录的 TTS 超时 warning 和普通用户生成动作缺少 project 维度 operation_logs 仍待后续阶段处理。
下一步建议:
- 继续围绕“仿真人视频完美落地”,优先处理真实业务 E2E 报告中的 TTS 节奏分配和生成流水线日志可追踪性。
### E2E 非阻断问题闭环 V1
完成时间:2026-06-10 20:27:28 CST
完成内容:
- 修复真实业务 E2E 中的两个非阻断 warning
- `8` 句 TTS 超出分配时长。
- 普通用户生成动作缺少 project 维度 `operation_logs`
- TTS 节奏优化:
- mock VoiceProvider 生成的单句音频按当前片段 `target_duration` 参与时间轴,避免 mock Provider 粗略时长导致假阳性超时 warning。
- 真实 VoiceProvider 请求增加 `target_duration` 输入。
- 台词预估时长超过镜头分配时,自动写入建议 `speech_speed`,后续真实 Provider 可按语速约束生成。
- 保留原有 TTS 缓存策略:同文本 + 同音色 + 同 voice 配置复用;mock 缓存命中时按当前片段目标时长参与验收。
- 生成流水线日志补强:
- `audio_generate``subtitle_generate``video_render` 创建任务时写入 `target_type=project``operation_logs`
- 日志 metadata 记录 `task_id``episode_id``shot_id``task_type``input_hash`,后台审计页可按项目查到普通用户生成动作。
- 新增/更新 MediaService 单元测试,覆盖 mock TTS 不再产生时间轴 warning、媒体任务创建写 project 维度操作日志。
- 重新 build 后端并重启 `127.0.0.1:3000` 后台服务,确保 E2E 跑到最新代码。
修改文件:
- backend/src/media/media.service.ts
- backend/src/media/media.service.spec.ts
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm --workspace backend run test -- src/media/media.service.spec.ts`
- `npm --workspace backend run build`
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-business-e2e.mjs`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
- `curl -fsS http://127.0.0.1:3000/api/client-config`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `backend/src/media/media.service.spec.ts` 单测通过:`14` 个测试通过。
- 真实业务动作 E2E 通过:
- 报告:`storage/private/frontend-business-e2e/report-20260610122518.json`
- Markdown`storage/private/frontend-business-e2e/report-20260610122518.md`
- project_id`50`
- episode_id`36`
- video_asset_id`298`
- 总步骤:`9`
- 通过步骤:`9`
- 失败步骤:`0`
- warning`0`
- user_task_count`13`
- admin_task_count`13`
- admin_review_count`2`
- operation_log_count`3`
- failed_tasks`0`
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- 后端服务已重启,`/api/client-config` 健康检查通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 当前闭环验证仍基于 mock Provider 和 FFmpeg 合成,真实 Hailuo / Kling / MiniMax 等 Provider 还需要小样准入验收。
- E2E 只验证主链路,不代表所有异常分支、任务恢复分支、真实 Provider 失败回退分支已经完全覆盖。
下一步建议:
- 回到“仿真人视频完美落地”主线,做真实 Provider 小样准入验收:固定项目、固定镜头、真实 PNG/JPG 关键帧,分别跑 Mock / Hailuo / Kling,记录画面、成本、质检分和失败原因,形成 Provider 准入标准。
### 真实 Provider 小样准入验收 V1
完成时间:2026-06-10 20:36:42 CST
完成内容:
- 进入“固定项目 / 固定镜头 / 真实 raster 关键帧 / Provider 矩阵”验收阶段。
- 选定固定样本:
- project_id`36`
- episode_id`28`
- shot_id`134`
- 镜头:`雨夜病房惊醒`
- 时长:`4`
- 原镜头关键帧是 mock SVG,不满足真实 Provider PNG/JPG/WebP 要求;本阶段上传并绑定真实 PNG 关键帧:
- keyframe_asset_id`301`
- mime_type`image/png`
- 来源文件:`storage/private/generated-images/2026-06-02/557d05bf-2b86-48d0-a427-f0171d7038ce.png`
- 执行 Provider 准入矩阵:
- `mock-video`
- `minimax_hailuo_23_fast`
- `kling-image-to-video`
- Mock Provider 实际生成单镜头小样:
- clip_id`4`
- output_asset_id`302`
- 视频:H.264 / 1080x1920 / 4 秒
- cost_actual`0`
- quality_status`passed`
- quality_score`94`
- Hailuo / Kling 未调用外部接口,未产生真实成本;准入报告标记为 `skipped`
- HailuoProvider 未启用、未显式确认真实视频费用、`MINIMAX_API_KEY` 未配置。
- KlingProvider 未启用、未显式确认真实视频费用、`KLING_API_KEY` 未配置。
- 增强 `live-action-provider-acceptance` 验收脚本:
- 增加 Provider 准入预检字段:enabled、mode、api_key_env、api_key_configured。
- 未启用 / 缺 Key / 未确认真实费用时标记 `skipped`,避免和真实生成失败混淆。
- Markdown 表格增加 Enabled / Key 列。
- 默认报告目录改为项目根目录 `storage/private/live-action-acceptance`,从 backend workspace 执行时不再落到 `backend/storage`
- 控制台摘要增加 enabled/key 状态。
修改文件:
- backend/src/live-action/live-action-provider-acceptance.ts
- CODEX_PROGRESS.md
新增文件:
-
运行命令:
- `git status --short`
- `npm run live-action:acceptance`
- `npm run typecheck -w backend`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
- `ffprobe -v error -show_entries stream=codec_type,codec_name,width,height,duration -show_entries format=duration,size -of json /www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-10/33fcb7ed-75ac-4306-9735-89ca58d62b44.mp4`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 准入报告:
- JSON`storage/private/live-action-acceptance/2026-06-10/live-action-acceptance-project-36-episode-28-shot-134-20260610123444.json`
- Markdown`storage/private/live-action-acceptance/2026-06-10/live-action-acceptance-project-36-episode-28-shot-134-20260610123444.md`
- 报告汇总:
- passed`1`
- failed`0`
- skipped`2`
- Provider 结果:
- `mock-video`passedclip_id=`4`output_asset_id=`302`quality_score=`94`cost_actual=`0`
- `minimax_hailuo_23_fast`skipped,未启用,`MINIMAX_API_KEY` 未配置,未确认真实费用。
- `kling-image-to-video`skipped,未启用,`KLING_API_KEY` 未配置,未确认真实费用。
- 视频资产验证:
- asset_id`302`
- mime_type`video/mp4`
- codec`h264`
- 分辨率:`1080x1920`
- duration`4.000000`
- size`11704`
- 提取首帧用于画面记录:
- `storage/private/live-action-acceptance/2026-06-10/frames/mock-clip-4-first-frame.png`
- 该首帧为 mock 占位画面,只验证流水线,不代表真实 Provider 画质。
- 后端单独 typecheck 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- Hailuo / Kling 尚未真实生成,因为后台 Provider 仍是 disabled,且 `.env` 未配置 `MINIMAX_API_KEY` / `KLING_API_KEY`
- 本轮 Mock 小样首帧是占位色块,只能证明“任务、关键帧、片段、质检、成本、报告”链路打通,不能作为真实画质判断。
- 当前质量检查仍是 mock-qc;真实 Provider 准入后,还需要引入真实视觉 QA 或人工小样评分标准。
下一步建议:
- 开通并配置 MiniMax Hailuo 账号后,只启用 `minimax_hailuo_23_fast`,设置 `MINIMAX_API_KEY`、单次成本上限和每日成本上限,再用同一个 `project_id=36 / episode_id=28 / shot_id=134 / keyframe_asset_id=301` 跑一次真实 Hailuo 小样;Kling 放在 Hailuo 通过后再对比。
### Live Action 白底风格修复 V1
完成时间:2026-06-10 20:50:15 CST
完成内容:
- 修复用户端制作页 `Live Action / AI 真人短剧` 区块内部白底不匹配问题。
- 给真人短剧区域增加 `live-action-panel` 专属 class,避免依赖不存在的 `.app-dark` 选择器。
- 为真人视频预检框、小样测试台、小样卡片、预检 breakdown 增加深色运营台风格兜底。
- 修复 `强制重生成` checkbox 原生白色方块问题,统一成深色小控件,并覆盖通用 input padding 导致的尺寸撑大。
修改文件:
- `user-app/src/pages/index/index.vue`
- `user-app/src/styles.css`
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-visual-audit.mjs`
- 定点 Playwright 截图检查 Live Action 区块 PC/H5 背景色与 checkbox 尺寸
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 完整前端视觉巡检通过:
- 报告:`storage/private/frontend-visual-audit/report.json`
- 用户端 PC/H5 与后台 PC/H5 共 `36` 个页面状态全部为 `pageOverflow=0 / textOverflow=0 / overlaps=0 / consoleErrors=0`
- Live Action 定点截图:
- PC`storage/private/frontend-visual-audit/live-action-panel-pc.png`
- H5`storage/private/frontend-visual-audit/live-action-panel-h5.png`
- 定点样式读取结果:
- `.live-action-panel .sample-panel` 背景为 `rgba(10, 19, 33, 0.78)`
- `.live-action-panel input[type="checkbox"]` 背景为 `rgb(7, 20, 38)`,尺寸为 `18x18``padding=0px`
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`183` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
遗留问题:
- 本轮只修复 Live Action 制作区白底/checkbox 风格问题,没有改动真人视频生成业务逻辑。
- Hailuo / Kling 真实 Provider 仍未启用,真实画质验收待 API Key 和费用确认后继续。
下一步建议:
- 继续围绕真人视频真实 Provider 小样验收,先启用 Hailuo 单 Provider 跑固定镜头,再和 Mock/Kling 做成本、画质、失败原因对比。
### MiniMax Hailuo 超时保存修复 V1
完成时间:2026-06-10 22:02:39 CST
完成内容:
- 修复后台保存 MiniMax/Hailuo Provider 配置时报 `timeout_ms must be an integer between 1000 and 180000` 的问题。
- 原因是 Hailuo/Wan/Vidu/Seedance 等异步视频 Provider 默认需要 `300000ms` 级别长轮询超时,但通用 Provider 保存接口只允许到 `180000ms`
- 将通用 Provider 运行配置保存上限放宽到 `600000ms`,OpenAI 统一配置的独立上限暂不改变。
- 新增单元测试覆盖 `minimax_hailuo_23_fast` 保存 `timeout_ms=300000` 的场景。
- 重新构建并用 systemd 临时服务 `ai-backend.service` 启动后端,使修复立即生效。
修改文件:
- `backend/src/providers/providers.service.ts`
- `backend/src/providers/providers.service.spec.ts`
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- `npm run test -w backend -- src/providers/providers.service.spec.ts`
- `npm run typecheck -w backend`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
- `systemd-run --unit=ai-backend ... node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
- 后台 API 验证 `minimax_hailuo_23_fast` 保存 `timeout_ms=300000`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 单测通过:`src/providers/providers.service.spec.ts``29` 个测试通过。
- 后端 `npm run typecheck -w backend` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`184` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- 后端 `ai-backend.service` 状态为 `active``/api/health` 返回 `status=ok`
- 实际接口验证通过:
- Provider`minimax_hailuo_23_fast`
- 保存后 `timeout_ms=300000`
- `enabled=false`
- `key_status=none`
遗留问题:
- 本轮没有替用户保存 MiniMax API Key,也没有启用真实 Hailuo,避免误触发真实扣费。
- 用户需要重新在后台保存 MiniMax Key;保存成功后再手动启用 `minimax_hailuo_23_fast`
下一步建议:
- 重新保存 MiniMax API Key,超时填 `300000`;第一轮只启用 `minimax_hailuo_23_fast`,单次成本上限 `1 USD`,当日上限 `10 USD`,先跑 1 个固定镜头小样。
### AI Provider 同公司 Key 同步与列表筛选 V1
完成时间:2026-06-10 22:20:56 CST
完成内容:
- 修复 AI 接入体验问题:同一家公司同一个 API Key 不再需要在 Text / Novel / Image / Video / TTS 中反复保存。
- 后端 `updateProviderRuntimeConfig` 在保存新 `api_key` 时,默认按相同 `config_json.api_key_env` 同步密钥到其它真实 Provider。
- 同步只写入密钥,不自动启用其它 Provider,不修改优先级和成本阈值,避免误触发真实扣费。
- 后台单 Provider 配置表单新增“保存新 Key 时同步同公司接入”开关,并显示当前 Key 分组。
- 后台 AI 接入列表新增关键词、类型、密钥状态、启用状态筛选,增加 Key 分组列,减少长列表翻找成本。
- 新增单元测试覆盖保存 `deepseek-text` 时同步到 `deepseek-novel`,但不影响其它公司 Provider 的场景。
- 对当前数据库做了一次安全回填:复用已加密保存的 `minimax_hailuo_23_fast` Key,同步到 `minimax_hailuo_23``minimax-text``minimax-tts`;未启用这些 Provider。
修改文件:
- `backend/src/providers/provider.dto.ts`
- `backend/src/providers/providers.service.ts`
- `backend/src/providers/providers.service.spec.ts`
- `admin/src/App.vue`
- `admin/src/styles.css`
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- `npm run test -w backend -- src/providers/providers.service.spec.ts`
- `npm run typecheck -w backend`
- `npm run lint`
- `npm run typecheck`
- `npm run test`
- `npm run build`
- `systemctl restart ai-backend.service`
- `curl http://127.0.0.1:3000/api/health`
- DeepSeek `/models` 轻量连接检查
- 当前 MiniMax 同分组加密 Key 回填检查
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 单测通过:`src/providers/providers.service.spec.ts``30` 个测试通过。
- 后端 `npm run typecheck -w backend` 通过。
- 全项目 `npm run lint` 通过。
- 全项目 `npm run typecheck` 通过。
- 全项目 `npm run test` 通过:
- backend `24` 个测试文件、`185` 个测试通过。
- workers `1` 个测试通过。
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
- 全项目 `npm run build` 通过。
- 后端 `ai-backend.service` 重启成功,`/api/health` 返回 `status=ok`
- DeepSeek 轻量连接检查通过:
- `deepseek-text`Key 已保存,已启用,`/models=200`
- `deepseek-novel`Key 已保存,已启用,`/models=200`
- MiniMax 当前 Key 状态:
- `minimax_hailuo_23_fast`Key 已保存,已启用。
- `minimax_hailuo_23`Key 已保存,未启用。
- `minimax-text`Key 已保存,未启用。
- `minimax-tts`Key 已保存,未启用。
遗留问题:
- MiniMax TTS/Text 和标准 Hailuo 只是补齐 Key,仍需按真实测试计划单独启用和限制成本阈值。
- 本轮没有触发任何真实生成任务,没有进行 Hailuo 视频扣费测试。
下一步建议:
- 后台人工刷新 AI 接入页,确认筛选、Key 分组和同步开关显示正常;然后进入真人视频固定镜头小样,只启用 `minimax_hailuo_23_fast` 先跑 1 条。
### AI 接入后受控验收测试 V1
完成时间:2026-06-10 23:06:00 CST
完成内容:
- 执行 DeepSeek 真实文本/小说小样测试,未触发真实视频生成。
- 执行一轮用户端 Mock 漫剧生产 API E2E
- 注册测试用户。
- 创建 AI 原创项目。
- mock 支付标准包并冻结额度。
- 生成原创创意、大纲、章节、自检。
- 生成并确认故事圣经。
- 抽取并确认角色。
- 生成剧情记忆。
- 生成并确认分集计划。
- 生成并确认单集脚本。
- 生成并确认分镜。
- 生成角色锚点图与 10 张分镜图。
- 生成混合 TTS、字幕。
- 使用 FFmpeg 合成 1080x1920 MP4。
- 检查后台任务、Provider 日志、成本日志、项目详情、磁盘文件和 `ffprobe` 元数据。
- 本轮没有触发 Hailuo / Kling / Sora 等真实视频扣费。
测试对象:
- 测试用户:`codex-e2e-20260610150239@example.com`
- 项目 ID`51`
- Episode ID`37`
- Audio Asset ID`314`
- Subtitle Asset ID`315`
- Video Asset ID`316`
- 视频文件:`local://rendered-videos/2026-06-10/c04807a9-99eb-4a9e-a847-e8f7ba3a6ad0.mp4`
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
- 本轮生成业务测试资产和私有存储文件,无新增代码文件。
运行命令:
- `git status --short`
- `curl http://127.0.0.1:3000/api/health`
- 后台 Provider 状态检查脚本。
- DeepSeek Provider 小样测试脚本。
- 用户端 Mock 漫剧生产 E2E 脚本。
- 续跑音频/字幕/FFmpeg 视频合成脚本。
- Prisma 数据核验脚本。
- `ffprobe` 检查音频和视频文件。
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `/api/health` 正常。
- DeepSeek Provider 小样通过:
- `deepseek-text` 真实调用成功。
- `deepseek-novel` 真实调用成功。
- Mock 生产流程最终通过:
- 项目状态:`video_rendered`
- 支付状态:`paid`
- 小说章节:`3`
- 角色:`3`
- 分镜:`10`
- 项目资产:`14`
- RenderTask`14`,成功 `14`,失败 `0`
- ProviderLog`23`
- Provider 成本:mock 图像和 mock 语音为 `0`
- FFmpeg 合成通过:
- 视频编码:`h264`
- 音频编码:`aac`
- 分辨率:`1080x1920`
- 时长:`40s`
- 文件大小:`239746 bytes`
- 文件存在性检查通过:
- 音频 WAV 存在。
- 字幕 SRT 存在。
- MP4 成片存在且可被 `ffprobe` 读取。
- Operation Logs
- 已记录 `user_audio_generate`
- 已记录 `user_subtitle_generate`
- 已记录 `user_video_render`
发现问题:
- 第一次音频生成测试脚本使用 `max_segments=8` 时失败:实际混合 TTS 段数为 `12`,错误为 `audio segment count 12 exceeds max_segments 8`
- 续跑时改为 `max_segments=20` 后音频生成通过,且 timeline warnings 为 `0`
- 用户端当前没有传 `max_segments`,后端默认上限是 `80`,所以这不是现有用户端默认阻断问题;但测试台/高级参数不要再默认填 `8`
- 普通用户早期流程如项目创建、故事圣经、角色、分镜生成的 operation_logs 还不是全量覆盖;当前关键生成动作已有日志,但审计完整性仍可增强。
遗留问题:
- 真实 Hailuo 小样尚未触发,仍需用户明确确认后单独跑 1 条固定镜头。
- 前端人工点击路径尚未在浏览器里逐屏复测;本轮是 API E2E 和文件级验收。
- TTS 测试脚本/高级配置中的 `max_segments=8` 对 10 镜头短剧偏低,后续测试建议不传或设置 `20` 以上。
下一步建议:
- 先把真实 Provider 小样脚本里的 TTS 参数规范化:混合配音不要写死 `max_segments=8`
- 再做前端 PC/H5 人工点击复测,确认制作页、任务页、预览页展示不重叠。
- 最后进入真实 Hailuo 固定镜头小样准入测试。
## 每阶段记录模板
### 公版经典小说仿真人视频完整流程验收 V1
完成时间:2026-06-10 23:43 CST
完成内容:
- 选择公版经典《聊斋志异·画皮》作为测试题材,避开现代版权作品和受保护改编版本。
- 使用 imagegen 生成 photorealistic 竖屏关键帧,内容为雨夜旧宅、王生持灯、神秘女子立于门内。
- 通过系统正式服务跑通一条完整链路:
- 创建真人短剧项目
- 版权确认:`public_domain`
- 粘贴并解析公版测试片段
- 创建 Story Bible
- 创建角色:王生、神秘女子
- 创建 Actor Profile
- 创建分集、脚本、分镜
- 上传 photorealistic PNG 关键帧
- 绑定关键帧到分镜
- Hailuo Fast 真实图生视频
- 质检任务化
- 真人短剧最终合成
- 生成结果:
- project`52`
- novel_source`33`
- story_bible`25`
- episode`38`
- shot`225`
- keyframe_asset`318`
- video_clip`8`
- Hailuo clip asset`319`
- final rendered asset`320`
- Hailuo provider log`374`
- video task`323`
- quality task`324`
- render task`325`
- 成本:
- Hailuo Fast 真实视频成本:`0.1902 USD`
- 质检 mock 成本:`0`
- 质量结果:
- clip `8``generated`
- quality_status`passed`
- quality_score`94`
- 文件级验收:
- 片段资产 `319``local://live-action-video-clips/2026-06-10/282b13ae-a03a-4063-ab13-da0b256417fc.mp4`
- 最终成片 `320``local://rendered-videos/2026-06-10/99244ee5-fc01-424e-850c-9620ef222302.mp4`
- 编码:`h264`
- 分辨率:`768x1364`
- 帧率:`24fps`
- 时长:`5.875s`
- 片段大小:`920552 bytes`
- 成片大小:`920592 bytes`
- 抽帧预览:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-10/classic-liaozhai-final-midframe.jpg`
- 画面可见真人古风雨夜场景,无黑屏、无水印、无明显跑题。
修改文件:
- `CODEX_PROGRESS.md`
新增测试文件:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-10/classic-liaozhai-keyframe.png`
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-10/classic-liaozhai-final-midframe.jpg`
运行命令:
- `git status --short`
- `curl http://127.0.0.1:3000/api/health`
- imagegen 生成关键帧
- Nest 服务脚本执行经典小说真人短剧流程
- `ffprobe` 检查 clip asset `319`
- `ffprobe` 检查 final asset `320`
- Prisma 数据核验脚本
- `ffmpeg` 抽取最终成片中帧
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端健康检查正常。
- 公版版权记录创建成功。
- 小说粘贴和解析成功,章节数 `1`
- Hailuo Fast 真实视频生成成功。
- 质检任务化路径成功。
- 最终合成成功。
- 后台可通过素材 ID 观看:
- 关键帧:`318`
- Hailuo 片段:`319`
- 最终成片:`320`
遗留问题:
- 最终成片 asset `320``status` 当前为 `mock`,原因是 `renderLiveActionEpisode` 旧逻辑统一把合成资产写成 `mock`;实际源片段 `319` 是 Hailuo 真实输出。后续应根据源 clip 是否真实 Provider 输出,把最终资产状态写为 `active` 或增加 `source_mode` 字段。
- 最终成片没有音轨;本次测试重点是仿真人画面生成链路,不包含 TTS/对白/配乐合成。
- Hailuo 输出分辨率是 `768x1364`,不是系统元数据里常用的 `1080x1920`;后续正式合成阶段需要统一转码/补边/缩放到目标竖屏规格。
- 质检仍使用 `mock-qc`,真实画面质量最终仍需要视觉质检 Provider 或人工准入标准。
下一步建议:
- 修复真人合成资产状态:真实 Provider 片段合成出的最终 asset 不应标记为 `mock`
- 增加真人成片转码规格化:统一输出 `1080x1920`、H.264、可选 AAC 音轨。
- 增加真人视频小样测试台:直接展示 keyframe、clip、final、Provider、真实成本、质检分和预览入口。
### Hailuo Fast 真人视频真实小样验收 V1
完成时间:2026-06-10 23:25 CST
完成内容:
- 按固定样本 `project_id=36 / episode_id=28 / shot_id=134 / keyframe_asset_id=301` 运行 MiniMax Hailuo 2.3 Fast 单镜头真实小样。
- 第一次真实调用失败原因已定位并可审计:MiniMax 返回 `base_resp_status_code=2013`,原因是 `MiniMax-Hailuo-2.3-Fast` 不支持 `4s`,只支持 `6s / 10s`
- Provider 执行层新增外部 Provider 返回摘要:失败日志现在记录 `base_resp_status_code``base_resp_status_msg``task_id``file_id`、顶层字段列表等,不再只有泛化的 `TASK_ID_MISSING`
- Hailuo Fast/标准 Provider 新增 `allowed_durations` 配置;通用图生视频驱动会把业务镜头时长自动归一到 Provider 支持档位。当前 4 秒镜头会按 Hailuo Fast 6 秒请求生成,后续合成阶段再裁切/对齐。
- 真人 Provider 验收脚本修复:现在能识别后台保存的加密 API Key,不再只检查 `.env` 环境变量。
- 真实 Hailuo Fast 第二次复测通过:
- clip`7`
- output_asset`317`
- 文件:`local://live-action-video-clips/2026-06-10/ddb89e25-4b51-4450-975f-9b5cf1ae2221.mp4`
- 真实成本记录:`0.1902 USD`
- 验收报告:`storage/private/live-action-acceptance/2026-06-10/live-action-acceptance-project-36-episode-28-shot-134-20260610152252.md`
- MP4 文件级检查通过:
- 编码:`h264`
- 分辨率:`768x1152`
- 帧率:`24fps`
- 时长:`5.875s`
- 文件大小:`1363391 bytes`
- 质检任务化路径跑通:
- quality task`322`
- QualityCheckProvider`mock-qc`
- clip `7` 质检结果:`passed`
- 质检分:`94`
修改文件:
- `backend/src/providers/providers.service.ts`
- `backend/src/providers/provider.types.ts`
- `backend/src/providers/providers.service.spec.ts`
- `backend/src/live-action/live-action-provider-acceptance.ts`
- `CODEX_PROGRESS.md`
运行命令:
- `git status --short`
- `npm test -- providers.service.spec.ts`
- `npm run typecheck`
- `npm test`
- `npm run lint`
- `npm run build`
- `systemctl restart ai-backend.service`
- `curl http://127.0.0.1:3000/api/health`
- `npm run live-action:acceptance`,仅跑 `minimax_hailuo_23_fast`
- `ffprobe` 检查 Hailuo 输出 MP4
- `ffmpeg` 抽取中帧预览图
- 质检队列任务脚本执行 clip `7`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端单测:`187 passed`
- 后端 lint/typecheck:通过。
- 后端 build:通过。
- 后端服务重启后 `/api/health` 正常。
- MiniMax Hailuo Fast 真实单镜头:通过,生成真实 MP4 并落库。
- 成本阈值生效:单片段成本 `0.1902 USD`,低于 `0.5 USD` 上限。
- Provider 失败审计增强有效:真实失败原因可以在 provider log 看到 `base_resp_status_msg`
遗留问题:
- 当前关键帧 `301` 视觉上偏韩漫/插画,不是真人照片质感;本轮证明真实 Hailuo Provider 接入、任务、成本、落库、预览文件和质检路径跑通,但不能代表最终“仿真人照片级”画质验收。
- 业务镜头时长仍是 `4s`Hailuo 实际输出 `~6s`;后续合成真人短剧时需要在 FFmpeg 拼接阶段裁切到业务时长,或在分镜层把真实视频镜头统一约束到 `6/10s` 档位。
- 质检仍使用 `mock-qc`,真实画面质量判断还需要后续接入视觉质检 Provider 或人工验收标准。
下一步建议:
- 上传或生成真正 photorealistic PNG/JPG 关键帧,再用同一套 Hailuo Fast 小样验收一次,重点看真人质感、脸部一致性、手部和动作。
- 在真人视频合成阶段补“Provider 输出时长 > 业务镜头时长时自动裁切”的 FFmpeg 规则。
- 后台小样测试台展示 Provider 支持时长档位、实际请求时长、业务裁切时长和真实成本,避免运营误以为 4 秒直接送给 Hailuo。
### 阶段名称
真人最终成片资产状态修复 V1
完成时间:
- 2026-06-10 23:48:34 CST
完成内容:
- 修复真人短剧最终合成 MP4 资产状态写死为 `mock` 的问题。
- 新规则:合成前读取所有源片段资产;只要任一源片段资产为 `active`,最终成片资产状态就标记为 `active`,文件名使用 `live-action-real.mp4`;全部源片段都是 `mock` 时才保留 `mock`
- `renderTask.input_json` 新增 `rendered_asset_status``rendered_asset_mode`,方便后续后台审计。
- 已将本次公版经典小样的最终成片 `asset 320``mock` 校正为 `active`;源片段 `asset 319` 保持 `active`
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
运行命令:
- `git status --short`
- `npm test -- live-action.service.spec.ts`
- `npm run typecheck`
- `npm test`
- `npm run lint`
- `npm run build`
- Prisma 脚本检查并更新 `asset 320`
- `systemctl restart ai-backend.service`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 真人模块单测:`14 passed`
- 后端全量测试:`189 passed`
- 后端 lint/typecheck:通过。
- 后端 build:通过。
- 后端健康检查:通过,`/api/health` 返回 `status: ok`
- 数据校正后:`asset 319``active``asset 320``active`
遗留问题:
- 旧数据里如果还有其它“真实源片段合成但最终资产误标 mock”的成片,需要按同样规则批量审计;本轮只修正了已确认的 `asset 320`
下一步建议:
- 继续真人视频验收时,重点补 FFmpeg 裁切规则:真实 Provider 输出时长大于业务镜头时长时,合成前自动裁切到分镜目标时长。
### 阶段名称
真人视频片段时长标准化 / FFmpeg 自动裁切 V1
完成时间:
- 2026-06-11 00:02:14 CST
完成内容:
- 真人短剧最终合成前新增片段标准化流程,不再直接把 Provider 原始 MP4 丢进 concat。
- 每个源片段会先通过 `ffprobe` 读取真实时长,再按分镜 `shot.duration` 判断是否需要裁切。
- 裁切规则:
- `source_duration > target_duration + 0.3s` 时自动裁切。
- 普通对话镜头默认居中裁切。
- 动作类镜头优先从头部保留,避免切掉关键动作起始。
- 标准化输出使用临时文件,不修改原始 Hailuo / Kling / Mock 资产。
- 标准化片段统一转为竖屏 `1080x1920``24fps`、H.264、`yuv420p`,降低不同 Provider 输出参数导致的拼接风险。
- `renderTask.input_json` 新增 `clip_normalization`,记录每个镜头的:
- `target_duration`
- `source_duration`
- `final_duration`
- `trimmed`
- `trim_strategy`
- `trim_start`
- `trim_tolerance`
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
运行命令:
- `git status --short`
- `npm test -- live-action.service.spec.ts`
- `npm run typecheck`
- `npm run lint`
- `npm run build`
- `npm test`
- 临时脚本调用真实 Hailuo 源片段 `asset 319` 做 4 秒标准化测试
- `systemctl restart ai-backend.service`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 真人模块单测:`14 passed`
- 后端全量测试:`189 passed`
- 后端 typecheck/lint:通过。
- 后端 build:通过。
- 后端健康检查:通过,`/api/health` 返回 `status: ok`
- 临时真实文件验证:
- 源片段:`asset 319`
- 源时长:`5.875s`
- 模拟业务目标时长:`4s`
- 输出时长:`4.000s`
- 输出规格:`1080x1920``24fps`
- 裁切策略:`center`
- 裁切起点:`0.938s`
遗留问题:
- 当前 V1 只处理“源片段过长自动裁切”;如果源片段短于分镜目标时长,暂不做冻结帧/慢放/补帧延长。
- 真实小样 `shot 225` 目前分镜时长为 `6s`Hailuo 输出 `5.875s`,不会触发裁切;本轮用同一个真实文件模拟了 `4s` 目标时长来验证裁切路径。
下一步建议:
- 后台 Router/任务审计页展示 `clip_normalization`,让运营能看到每个镜头是否被裁切、裁切前后时长和裁切策略。
- 后续如果要更细,可以增加“AI 最佳裁切点”或“动作峰值裁切”,但现在 V1 规则已经足够支撑生产验收。
### 阶段名称
后台 Router 审计展示合成裁切 V1
完成时间:
- 2026-06-11 00:10:28 CST
完成内容:
- 后台 Router 审计列表新增“合成裁切”展示列。
- 后端 `listRouterAudits` 新增关联最终合成任务 `live_action_video_render`,从 `input_json.clip_normalization` 中提取当前镜头的标准化/裁切记录。
- 每条审计行新增 `render_normalization`,包含:
- `task_id`
- `output_asset_id`
- `shot_id`
- `target_duration`
- `source_duration`
- `final_duration`
- `trimmed`
- `trim_strategy`
- `trim_start`
- `trim_tolerance`
- Router 审计汇总新增:
- `normalized_clip_count`
- `trimmed_clip_count`
- `trimmed_seconds_total`
- Router 时间线新增 `clip_normalization` 事件,打开片段时间线可以看到“合成片段标准化 / 合成片段自动裁切”的详细 JSON。
- 前端 Router 审计页新增中文映射:`clip_normalization``trimmed``normalized``center``head``none`
- 对经典小样第 38 集执行了一次只走 FFmpeg 的强制重新合成,不重新调用 Hailuo:
- 新最终成片 asset`321`
- 新合成任务 task`326`
- 标准化记录:源片段 `5.875s`,目标 `6s`,最终 `5.875s``trimmed=false`
修改文件:
- `backend/src/admin/admin.service.ts`
- `backend/src/admin/admin.service.spec.ts`
- `admin/src/App.vue`
- `admin/src/styles.css`
- `CODEX_PROGRESS.md`
运行命令:
- `git status --short`
- `npm test -- admin.service.spec.ts`
- `npm run typecheck`
- `npm test`
- `npm run lint`
- `npm run build`
- `cd admin && npm run build`
- 服务层强制重新合成 episode `38`
- 后台服务层查询项目 `52` Router 审计
- `systemctl restart ai-backend.service`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端 Admin 单测:`20 passed`
- 后端全量测试:`189 passed`
- 后端 typecheck/lint/build:通过。
- 后台前端 build:通过。
- 后端健康检查:通过,`/api/health` 返回 `status: ok`
- 真实数据验证:
- 项目 `52` Router 审计 summary 返回 `normalized_clip_count=1``trimmed_clip_count=0`
- 片段 `8` 返回 `render_normalization.task_id=326``output_asset_id=321`
遗留问题:
- 目前只有新合成任务会有 `clip_normalization`;旧合成任务不会回填。需要展示旧数据时,需要重新合成或做一次历史任务回填。
- 当前真实小样目标时长为 `6s`,源片段 `5.875s`,所以展示为“未裁切”。真正的“已裁切”展示已通过后端单测和临时真实文件测试覆盖。
下一步建议:
- 后台可以继续补一个“只重新合成/刷新裁切审计”的按钮,方便不重新生成 Provider 片段的情况下刷新最终成片与裁切记录。
### 阶段名称
全海螺 30 秒仿真人数字人跨屏样片验收 V1
完成时间:
- 2026-06-11 00:44:23 CST
完成内容:
- 按“高价值镜头 / 宣传级样片 / Router Premium 验收样片”思路,完成一条 30 秒全 Hailuo 真人视频小样。
- 题材:深夜程序员桌面,仿真人 AI 数字女性从笔记本屏幕进入现实世界,并说“你终于找到我了”。
- 使用 imagegen 生成 5 张真实 PNG 关键帧,并复制到项目私有目录:
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-01-screen-appear.png`
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-02-touch-screen.png`
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-03-hand-through.png`
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-04-step-out.png`
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-05-real-world.png`
- 新建测试项目:
- project`53`
- episode`39`
- keyframe assets`322-326`
- storyboard shots`226-230`
- 全部 5 个镜头均使用 `minimax_hailuo_23_fast` 真实 Provider 生成:
- shot 1clip `9`asset `327`,成本 `0.1902 USD`
- shot 2clip `10`asset `328`,成本 `0.1902 USD`
- shot 3clip `11`asset `329`,成本 `0.1902 USD`
- shot 4clip `12`asset `330`,成本 `0.1902 USD`
- shot 5clip `13`asset `331`,成本 `0.1902 USD`
- 合成最终成片:
- final asset`332`
- render task`332`
- 文件:`local://rendered-videos/2026-06-10/4ddc1e08-d336-4fe3-93e9-7301079f99e5.mp4`
- 跑通 Router 审计:
- `total_estimated_cost=0.9510`
- `total_actual_cost=0.9510`
- `normalized_clip_count=5`
- `trimmed_clip_count=0`
- `avg_quality_score=94`
- 跑通质检记录:
- clips `9-13` 均为 `passed`
- 质检分均为 `94`
- 当前质检 Provider 为 `mock-qc`
- 抽帧验收文件:
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-frames/final-contact-sheet.jpg`
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-frames/final-midframe.jpg`
修改文件:
- `CODEX_PROGRESS.md`
生成/新增数据:
- 数据库项目、故事圣经、分集、5 个镜头、5 个关键帧资产、5 个 Hailuo 视频片段、1 个最终成片资产。
- 私有关键帧 PNG 与抽帧 JPG。
运行命令:
- `git status --short`
- Provider 配置检查脚本
- imagegen 生成关键帧
- Prisma 脚本创建项目/分镜/关键帧资产
- 服务层逐镜头调用 `generateShotVideoClip`
- 服务层调用 `renderLiveActionEpisode`
- `ffprobe` 检查最终 MP4
- `ffmpeg` 抽帧和生成 contact sheet
- 服务层调用 `checkVideoClipQuality`
- 后台服务层查询 Router 审计
- `npm test -- live-action.service.spec.ts`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Hailuo 真实生成:5/5 成功。
- Hailuo 真实成本:`0.9510 USD`
- 最终 MP4 文件级检查:
- 编码:`h264`
- 分辨率:`1080x1920`
- 帧率:`24fps`
- 实际时长:`29.375s`
- 文件大小:`10241260 bytes`
- 5 个片段标准化记录正常:源时长均 `5.875s`,目标均 `6s`,未触发裁切。
- 后端真人模块单测:`14 passed`
- 后端健康检查:通过,`/api/health` 返回 `status: ok`
人工视觉观察:
- 第 1-4 镜整体效果成立:屏幕中出现、触屏、手穿屏、从笔记本中出来的视觉逻辑清楚。
- 第 3/4 镜“跨屏”动作可读性不错,符合全海螺先做准入测试的目标。
- 第 5 镜出现轻微服装一致性变化,从高领科技服偏成白色连衣裙;这是全海螺复杂连续镜头的可见瑕疵,后续如果做宣传片级别,建议只重跑第 5 镜或等 Kling 开通后重跑第 3-5 镜。
遗留问题:
- 当前质检仍是 `mock-qc`,分数只能证明流程闭环,不等同于真实视觉质检。
- 第 5 镜服装一致性需要人工复核,必要时单独重跑。
- 最终成片实际时长 `29.375s`,业务记录为 `30s`,这是 Hailuo 6 秒档实际输出约 `5.875s` 导致,属于可接受范围;如要求严格 30 秒,后续可做尾帧补齐或轻微延长。
下一步建议:
- 人工打开后台预览 `asset 332`,重点看第 3-5 镜人物一致性和跨屏动作。
- 如果要做更接近宣传片的一版,保留第 1-4 镜,优先重跑第 5 镜;Kling 开通后再重跑第 3/4 镜做对照。
### 阶段名称
真人视频后期音频层修复 / 30 秒样片重新验收 V1
完成时间:
- 2026-06-11 01:10:27 CST
完成内容:
- 将上一版 `asset 332` 按发布标准判定为失败:只有视频流,没有音频流、字幕和 BGM;第 5 镜嘴型也不能证明中文台词同步。
- 真人 `renderLiveActionEpisode` 增加后期层:
- 默认准备对白音频、字幕和 BGM。
- 新增 `live_action_audio_generate``live_action_subtitle_generate``live_action_bgm_generate` 三类任务。
-`storyboard_shots.dialogue_text/narration_text` 直接生成真人小样对白段,不再强依赖已确认 `episode_script`
- 最终 `live_action_video_render``input_json.post_production` 记录 audio/subtitle/bgm asset、task、Provider、warning。
- 真人 FFmpeg 合成升级:
- 先拼接 Hailuo 视频片段。
- 再混入 TTS 人声和 BGM。
- 再烧录 ASS 字幕。
- 输出 AAC 立体声音轨。
- BGM V1
- 支持指定 `bgm_asset_id`
- 未指定时生成版权安全的低音量氛围底音 `system_ambient_bed_v1`,用于测试和保底,不作为最终商业音乐库。
- Provider 修复:
- 修复 MiniMax TTS 返回 `data.audio` 十六进制音频串被误当 base64 解码的问题。
- `decodeProviderAudioPayload` 自动识别 hex/base64。
- 开启已有 Key 的 `minimax-tts` Provider
- `provider_code=minimax-tts`
- `is_enabled=true`
- `priority=180`
- 重新合成 30 秒有声样片:
- audio asset`333`
- subtitle asset`334`
- bgm asset`335`
- final video asset`336`
- final render task`337`
- 文件:`local://rendered-videos/2026-06-10/5b300243-c635-42d3-9d13-c0f73f449b87.mp4`
- 抽帧验收:
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-frames/final-asset-336-subtitle-frame-25s.jpg`
- 25 秒帧已确认字幕“你终于找到我了。”烧录成功。
修改文件:
- `backend/src/live-action/live-action.dto.ts`
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `backend/src/providers/providers.service.ts`
- `CODEX_PROGRESS.md`
新增文件:
- 无源码新增文件。
生成/新增数据:
- `render_tasks`
- `334``live_action_audio_generate` 成功,真实 `minimax-tts`
- `335``live_action_subtitle_generate` 成功
- `336``live_action_bgm_generate` 成功
- `337``live_action_video_render` 成功
- `333`:修复前失败的 TTS 任务,保留为问题追踪记录
- `assets`
- `333`:真人对白混音 WAV
- `334`SRT 字幕
- `335`BGM WAV
- `336`:最终有声 MP4
- `provider_logs`
- `389``minimax-tts` 成功,`audio_available=true``audio_bytes=23674`
运行命令:
- `git status --short`
- `npm test -- live-action.service.spec.ts`
- `npm test -- providers.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run build --workspace backend`
- `npm run lint --workspace backend`
- MiniMax TTS debug 脚本
- `renderLiveActionEpisode` 重合成 episode `39`
- `ffprobe` 检查 `asset 336`
- `ffmpeg volumedetect` 检查音量
- `ffmpeg` 抽字幕帧
- Prisma 查询任务、素材、Provider 日志
- 重启后端 `node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端真人单测:`14 passed`
- Provider 单测:`32 passed`
- 后端 typecheck:通过
- 后端 build:通过
- 后端 lint:通过
- 后端已重启加载新 `dist`,健康检查通过
- `asset 336` 文件级验收:
- 容器:MP4
- 视频:H.264`1080x1920``24fps`
- 音频:AAC LC`44100 Hz`stereo`159 kb/s`
- format duration`30.000s`
- audio duration`30.000s`
- video stream duration`29.375s`
- 文件大小:`11093467 bytes`
- 音量验收:
- `mean_volume=-16.0 dB`
- `max_volume=-1.0 dB`
- 不是静音文件。
- 字幕验收:
- 25 秒抽帧可见“你终于找到我了。”
- TTS 验收:
- `minimax-tts` 真实成功。
- 修复后音频字节头为合法 MP3 `ID3`
分项验收结论:
- 真实 Hailuo 视频片段:通过,可跑通但第 5 镜服装一致性仍有瑕疵。
- 视频合成:通过,最终 MP4 可生成。
- 对白音轨:通过,已接真实 MiniMax TTS 并混入最终 MP4。
- BGM:流程通过,但当前是系统氛围底音 V1;商业发布前建议接入可运营的 BGM 素材库/上传授权库。
- 字幕:通过,已烧录进画面。
- 音量:通过,文件层面非静音,音量在可播放范围。
- 嘴型同步:不通过。当前第 5 镜只是 Hailuo prompt 生成的说话表情,不是由真实中文音频驱动的 lip-sync。
- 视觉质检:不通过生产级。当前 `mock-qc=94` 只能证明流程,不代表真实画面质检。
- 人工审核/发布:未验收。本阶段只到成片文件和后台任务链路。
遗留问题:
- 第 5 镜嘴型仍不是生产级中文口型。适合中景/轻微开口,不适合正脸近景强台词。
- BGM 还不是正式音乐库,只是版权安全氛围底音保底。
- 真实视觉 QA 仍未接入,`mock-qc` 不能作为发布依据。
- `provider_logs.cost_actual` 对 MiniMax TTS 仍为 `0`,因为当前按 `provider_usage_metadata` 记录,后续要按字符/供应商账单补精确成本。
- 修复前失败的 `live_action_audio_generate` task `333` 保留在任务表中,后台需要能清楚显示失败原因和后续成功任务。
下一步建议:
- 做“发布验收清单 V1”:后台成片页明确显示视频流、音频流、字幕、BGM、真实 TTS Provider、mock/real QA、lip-sync 风险。
- 做“台词镜头策略 V1”:正脸近景台词默认标记 `lip_sync_required`,没有 lip-sync Provider 时自动改成旁白/字幕/轻微开口中景,避免上线露馅。
- 做 BGM 素材库/授权库 V1:不要长期依赖系统氛围底音。
### 阶段名称
台词镜头策略 V1 / Lip-Sync 风险自动降级
完成时间:
- 2026-06-11 09:30:12 CST
完成内容:
- 针对真人视频发布级风险补了台词镜头策略:正脸、近景、带台词、说话/开口类镜头会自动判定为 `lip_sync_required`
- 不新增数据库字段,先用 Provider 配置和任务 `input_json` 落地策略,避免当前阶段频繁迁移核心表。
- 新增 lip-sync Provider 可用性判断:检测已启用的视频 Provider 配置中是否声明 `config_json.supports_lipsync=true`
- 没有 lip-sync Provider 时,系统保留对白给后期 TTS 和字幕,但会自动把视频生成提示词降级为:
- 中景或三分之二侧脸;
- 轻微开口/自然表情;
- 避免正脸嘴部特写;
- 禁止生成清晰中文口型;
- 通过旁白、字幕、画面反应承接台词。
- `prepareLiveActionShots` 会在生成分镜 prompt 时写入 lip-sync 风险策略。
- `generateSingleVideoClip` 会对已有旧 prompt 动态补策略,避免旧项目重跑时漏掉降级规则。
- 真人视频片段生成任务、后期合成任务都会记录 `lip_sync_policy`,方便后续后台审计和发布验收。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
新增文件:
- 无。
运行命令:
- `git status --short`
- `npm test -- live-action.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run build --workspace backend`
- `npm run lint --workspace backend`
- 重启后端 `node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端真人单测:`15 passed`
- 后端 typecheck:通过
- 后端 build:通过
- 后端 lint:通过
- 后端已重启加载新 `dist`,健康检查通过
- 本阶段未额外重跑 Hailuo 真实视频,未新增真实视频费用。
分项验收结论:
- 台词镜头风险识别:通过。单测已覆盖近景台词镜头自动判定高风险。
- 无 lip-sync Provider 降级:通过。单测已确认 prompt 会写入 `post_tts_subtitle_light_mouth`、中景、侧脸、避免清晰口型等约束。
- 旧 prompt 动态补策略:通过。片段生成时会再次计算并注入策略。
- 任务审计记录:通过。render/post-production 任务 `input_json` 会记录 `lip_sync_policy`
- 真实画面效果:未验收。本阶段只做策略和链路,不烧真实 Provider 额度。
遗留问题:
- 目前还没有真实 lip-sync Provider Adapter,系统只能自动降级风险镜头,不能做到真实中文口型驱动。
- 旧成片 `asset 336` 的画面不会自动改变,嘴型问题仍然存在;后续重新生成相关镜头才会套用新策略。
- 后台 Router/发布验收页还没有展示 `lip_sync_policy`,运营人员暂时需要查任务 JSON。
下一步建议:
- 重跑第 5 镜台词镜头,验证 Hailuo 在“中景轻口型 + TTS/字幕后期”策略下是否明显更稳。
- 做“发布验收清单 V1”:后台成片页展示音频、字幕、BGM、真实/Mock QA、lip-sync 风险和是否已降级。
- 后续接入真实 lip-sync Provider 后,把高风险正脸台词镜头路由到 lip-sync Provider。
### 阶段名称
真人第 5 镜台词镜头重跑验收 / Hailuo + 轻口型降级策略
完成时间:
- 2026-06-11 12:04:06 CST
完成内容:
- 按台词镜头策略 V1,重跑项目 `53`、episode `39`、第 5 镜 `shot 230`
- 本次只重跑 1 条 6 秒 Hailuo 真实视频,前 4 镜不重跑。
- Hailuo Provider 配置确认:
- `minimax_hailuo_23_fast` 已启用;
- `mode=real`
- `supports_lipsync=false`
- 已配置 `MINIMAX_API_KEY`
- 单条 6 秒预估/记录成本 `0.1902 USD`
- 新片段生成成功:
- `video_clip.id=14`
- `asset.id=337`
- 文件:`local://live-action-video-clips/2026-06-11/9f435b34-34a4-4f56-a0e6-ef8932ecffa9.mp4`
- 质量状态:`passed`
- mock 质检分:`94`
- 新片段任务 `338` 已记录 lip-sync 策略:
- `lip_sync_required=true`
- `high_risk_dialogue=true`
- `provider_available=false`
- `strategy=post_tts_subtitle_light_mouth`
- `visual_fallback=true`
- 新片段 prompt 已注入风险规避指令:
- 后期 TTS + 字幕承接对白;
- 不生成清晰中文口型;
- 嘴部保持闭合或轻微移动;
- 避免正脸嘴部特写;
- 优先中景、三分之二侧脸或反应镜头。
- 重新合成 30 秒成片,使用新第 5 镜片段:
- `asset.id=341`
- 文件:`local://rendered-videos/2026-06-11/74a7acdd-dbdc-4774-9cd0-a59985eec25c.mp4`
- 片段列表:`327, 328, 329, 330, 337`
- TTS asset`338`
- 字幕 asset`339`
- BGM asset`340`
- render task`342`
- 抽帧验收:
- 第 5 镜联系表:`storage/private/live-action-acceptance/2026-06-11/shot-230-rerun-frames/contact-sheet.jpg`
- 成片 25 秒字幕帧:`storage/private/live-action-acceptance/2026-06-11/asset-341-frames/subtitle-frame-25s.jpg`
- 成片 27 秒字幕帧:`storage/private/live-action-acceptance/2026-06-11/asset-341-frames/subtitle-frame-27s.jpg`
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
- 无源码新增文件。
生成/新增数据:
- `video_clips`
- `14`:第 5 镜 Hailuo 真实重跑片段
- `assets`
- `337`:第 5 镜新 Hailuo 片段
- `338`:真人对白混音 WAV
- `339`SRT 字幕
- `340`BGM WAV
- `341`:重新合成后的 30 秒有声 MP4
- `render_tasks`
- `338``live_action_video_clip_generate` 成功
- `339``live_action_audio_generate` 成功
- `340``live_action_subtitle_generate` 成功
- `341``live_action_bgm_generate` 成功
- `342``live_action_video_render` 成功
- `provider_logs`
- `390``minimax_hailuo_23_fast` 成功,真实视频可用,成本 `0.1902`
运行命令:
- `git status --short`
- Prisma 查询 episode/shot/provider/clip/task
- `npm run live-action:acceptance`
- `ffprobe` 检查第 5 镜新片段
- `ffmpeg` 抽第 5 镜联系表
- Nest application context 调用 `renderLiveActionEpisode`
- `ffprobe` 检查最终成片 `asset 341`
- `ffmpeg volumedetect` 检查最终成片音量
- `ffmpeg` 抽 25 秒、27 秒字幕帧
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Hailuo 第 5 镜真实重跑:通过。
- Provider acceptance 报告:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-11/live-action-acceptance-project-53-episode-39-shot-230-20260611040048.json`
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-11/live-action-acceptance-project-53-episode-39-shot-230-20260611040048.md`
- 新片段 `asset 337`
- 视频:H.264
- 分辨率:`768x1364`
- 帧率:`24fps`
- 时长:`5.875s`
- 文件大小:`545522 bytes`
- 无音轨,符合单镜头视频片段设计。
- 新成片 `asset 341`
- 容器:MP4
- 视频:H.264`1080x1920``24fps`
- 视频流时长:`29.375s`
- 音频:AAC LC`44100 Hz`stereo`159 kb/s`
- 音频流时长:`30.000s`
- format duration`30.000s`
- 文件大小:`10854047 bytes`
- 音量验收:
- `mean_volume=-15.8 dB`
- `max_volume=-1.0 dB`
- 非静音,音量在可播放范围。
- 字幕验收:
- 25 秒、27 秒抽帧均可见“你终于找到我了。”
- 后端健康检查:通过。
分项验收结论:
- 台词镜头降级策略:通过。任务 JSON 和 Provider prompt 均记录并执行了 `post_tts_subtitle_light_mouth`
- 嘴型风险规避:阶段性通过。抽帧显示人物为中景/轻口型/表情反应,未出现明显正脸大幅口型对不上。
- TTS:通过。最终成片有真实 `minimax-tts` 音轨。
- 字幕:通过。字幕已烧录入最终成片。
- BGM:流程通过。仍是系统氛围底音 V1,不是正式音乐素材库。
- 合成:通过。最终 MP4 30 秒、有音轨、有字幕、有 BGM。
- 发布级结论:比上一版明显更接近可发布,但仍需人工完整播放审核;本阶段无法替代真实 lip-sync 供应商,也没有真实视觉 QA。
遗留问题:
- 第 5 镜并不是真正 lip-sync,只是通过中景、轻口型、字幕和 TTS 规避风险。
- Hailuo 返回片段为 `5.875s`,目标为 `6s`,在 `0.3s` 容差内没有裁切,最终 format 仍为 30 秒。
- BGM 仍需后续接入素材库/授权库,才能进入正式商用发布标准。
- `live_action_audio_generate.cost_actual` 仍为 `0`MiniMax TTS 真实成本需要后续按字符或账单回填。
- mock 质检分 `94` 不能代表真实视觉 QA,仍需补真实画面审核能力。
下一步建议:
- 做“发布验收清单 V1”,把音轨、字幕、BGM、lip-sync 降级、mock/real QA、人工审核状态集中显示。
- 做“真人成片人工验收台 V1”,让后台能直接预览 `asset 341` 并人工通过/驳回。
- 接入正式 BGM 素材库/授权库,替代系统氛围底音。
### 阶段名称
真人成片音频噪声 / 台词时间轴修复 V1
完成时间:
- 2026-06-11 12:14:22 CST
问题反馈:
- 用户验收 `asset 341` 后反馈:
- 成片里全是“呼呼”的噪音;
- 语音先到,说完后画面嘴型/表情才开始动。
原因分析:
- “呼呼声”不是 MiniMax TTS 的问题,也不是 Hailuo 视频的问题,而是系统兜底 BGM 问题:
-`system_ambient_bed_v1``anoisesrc=color=pink` 生成粉噪声氛围底音;
- 最终混音后又做整条 loudnorm,把背景噪声进一步抬高;
- 结果听感像风噪/底噪,不适合发布。
- “语音先到”不是单纯 AI 平台质量问题,而是当前流水线时间轴问题叠加无 lip-sync Provider
- Hailuo 不是音频驱动 lip-sync
- 旧策略把第 5 镜对白放在镜头开头 `24.55s`
- 画面里的轻口型/表情动作出现在镜头中后段,导致听感错位。
完成内容:
- 系统兜底 BGM 从粉噪声改为静音保底:
- `bgm_source``system_ambient_bed_v1` 调整为 `system_silent_bed_v1`
- 不再用粉噪声伪装 BGM
- 正式发布用 BGM 后续必须接授权素材库/上传素材库。
- 混音策略修复:
- 默认 `LIVE_ACTION_DEFAULT_BGM_VOLUME``0.16` 降到 `0.08`
- `bgm_volume` 参数现在真正参与混音;
- voice+BGM 混合后不再对整条音轨做 loudnorm,避免把背景噪声拉响;
- 混合后改用 `alimiter` 做安全限幅。
- 台词时间轴修复:
- `visual_fallback=true` 且是 dialogue 的镜头,TTS/字幕不再默认 `0.55s` 入声;
- 6 秒台词镜头会延后到约 `2.04s` 入声;
- 本次第 5 镜全片时间从旧 `24.55s` 延后到 `26.04s`
- 新增单测:
- 验证无 lip-sync 的台词镜头会延后进声;
- 验证混音滤镜不会再把 BGM 通过整体 loudnorm 拉响。
- 重新合成新版 30 秒成片:
- `asset.id=345`
- 文件:`local://rendered-videos/2026-06-11/38a399bd-4550-4684-9855-0ae02e90e59c.mp4`
- 使用已有 Hailuo 视频片段,不再重跑 Hailuo。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
新增文件:
- 无源码新增文件。
生成/新增数据:
- `assets`
- `342`:新版真人对白混音 WAV
- `343`:新版 SRT 字幕
- `344`:新版静音 BGM 保底 WAV
- `345`:新版最终成片 MP4
- `render_tasks`
- `343``live_action_audio_generate` 成功,台词 `start_seconds=26.04`
- `344``live_action_subtitle_generate` 成功,字幕 `start_seconds=26.04`
- `345``live_action_bgm_generate` 成功,`bgm_source=system_silent_bed_v1`
- `346``live_action_video_render` 成功,`bgm_volume=0`
运行命令:
- `git status --short`
- `npm test -- live-action.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run build --workspace backend`
- `npm run lint --workspace backend`
- Nest application context 调用 `renderLiveActionEpisode`
- `ffprobe` 检查新版成片
- `ffmpeg volumedetect` 检查新版音频
- `ffmpeg` 抽 25 秒、27 秒画面帧
- 重启后端 `node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端真人单测:`17 passed`
- 后端 typecheck:通过
- 后端 build:通过
- 后端 lint:通过
- 后端已重启,PID `4060680`,健康检查通过。
- 新版成片 `asset 345`
- 容器:MP4
- 视频:H.264`1080x1920``24fps`
- format duration`30.000s`
- audio duration`30.000s`
- 音频:AAC LC`44100 Hz`stereo
- 文件大小:`10291399 bytes`
- 新版音量:
- `mean_volume=-37.0 dB`
- `max_volume=-7.8 dB`
- 相比旧版 `mean_volume=-15.8 dB`,背景底噪已明显压下。
- 新版字幕/台词时间:
- 第 5 镜台词和字幕从 `26.04s` 开始;
- 旧版是 `24.55s`
- 抽帧:
- `storage/private/live-action-acceptance/2026-06-11/asset-345-frames/frame-25s.jpg`
- `storage/private/live-action-acceptance/2026-06-11/asset-345-frames/frame-27s.jpg`
分项验收结论:
- 呼呼噪声:代码层面已修复。新版使用静音保底 BGM,且混音不再拉响背景。
- 语音抢跑:代码层面已修复。visual fallback 台词镜头会延后到镜头中后段。
- 真 lip-sync:仍未实现。当前方案是“规避嘴型风险”,不是音频驱动口型。
- BGM 发布标准:仍未完成。正式发布需要授权 BGM 素材库,不能依赖系统兜底音。
遗留问题:
- `asset 345` 是无正式 BGM 版本,只解决噪声和台词时间轴,不代表最终配乐发布标准。
- Hailuo 仍不是 lip-sync Provider;正脸强台词仍要接入真实 lip-sync 或改变镜头设计。
- 用户需要人工完整播放 `asset 345`,确认实际听感是否过关。
下一步建议:
- 后台增加“发布验收清单 V1”:显示是否有正式 BGM、是否静音保底、TTS 起止时间、lip-sync 策略、人工通过/驳回。
- 做 BGM 素材库/授权库 V1,支持上传可商用 BGM 并控制音量。
- 对正脸强台词镜头继续优先使用旁白/字幕/背影/反应镜头,直到接入真实 lip-sync Provider。
### 阶段名称
LipSyncProvider 接入 V1 / 真人后期口型同步 Provider 抽象
完成时间:
- 2026-06-11 13:44:28 CST
完成内容:
- 新增独立 Provider 类型:`LipSyncProvider`
- 新增 mock Provider
- `mock-lipsync`
- 默认禁用;
- 只用于测试链路;
- 明确标记 `mock_passthrough`,不伪装成真实口型同步能力。
- 新增真实通用 Provider 预设:
- `generic-lipsync`
- 默认禁用;
- driver`configurable_lip_sync`
- 默认 env`LIPSYNC_API_KEY`
- 默认请求字段:`video``audio``text`
- 支持 Provider 返回 `video_url``content_base64` 后落盘为私有视频片段。
- 真人视频 DTO 增加:
- `include_lip_sync`
- `lip_sync_provider_code`
- 真人后期链路新增 lip-sync 阶段:
- 位置:TTS 生成后、最终 FFmpeg 合成前;
- 输入:原视频片段 + 对应对白音频片段 + 台词文本 + 时间信息;
- 输出:新的 lip-sync 视频片段;
- 合成时优先使用 lip-sync 后的新片段。
- Provider 选择策略:
- 默认只自动使用已启用的真实 `LipSyncProvider`
- mock 不会被当成生产可用能力;
- 后台/测试可显式指定 `lip_sync_provider_code=mock-lipsync` 验证链路。
- 审计记录:
- 新增任务类型 `live_action_lip_sync_generate`
- `live_action_video_render.input_json.post_production` 记录 `lip_sync_clip_count``lip_sync_clips`
- 每个 lip-sync clip 记录 source asset、output asset、task、provider、成本和策略。
- 安全处理:
- 视频/音频 data URI 只进入 Provider 调用;
- render task 不保存大 base64
- provider logs 已走媒体字段脱敏。
- Provider 配置已落库:
- `71 LipSyncProvider:mock-lipsync enabled=false mode=mock`
- `72 LipSyncProvider:generic-lipsync enabled=false mode=real`
修改文件:
- `backend/src/live-action/live-action.dto.ts`
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `backend/src/providers/provider.types.ts`
- `backend/src/providers/providers.service.ts`
- `backend/prisma/seed.ts`
- `CODEX_PROGRESS.md`
新增文件:
- 无。
运行命令:
- `git status --short`
- `npm test -- live-action.service.spec.ts`
- `npm test -- providers.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run build --workspace backend`
- `npm run lint --workspace backend`
- Prisma upsert `LipSyncProvider` 配置
- 重启后端 `node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
- Prisma 查询 `LipSyncProvider` 配置
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 单测:`32 passed`
- 真人服务单测:`18 passed`
- 后端 typecheck:通过
- 后端 build:通过
- 后端 lint:通过
- 后端已重启,PID `31253`,健康检查通过。
- 数据库确认:
- `mock-lipsync` 已存在,默认禁用;
- `generic-lipsync` 已存在,默认禁用;
- 未写入任何真实 API Key。
分项验收结论:
- Provider 抽象:通过。`LipSyncProvider` 已成为独立能力类型。
- mock 链路:通过。单测已验证指定 `mock-lipsync` 时,会创建 `live_action_lip_sync_generate` 任务、调用 `LipSyncProvider`、保存新片段。
- 真实 Provider 预留:通过。`configurable_lip_sync` 支持通用 JSON 请求和 URL/base64 视频输出。
- 生产默认策略:通过。没有真实启用的 LipSyncProvider 时,不会误把 mock 当成可发布口型能力。
- 成本/审计:通过。任务和 Provider log 已能记录 lip-sync 调用。
遗留问题:
- 目前还没有开通真实 lip-sync 平台账号,`generic-lipsync` 只是通用适配器配置。
- 不同厂商可能要求 multipart/form-data、文件先上传或异步任务轮询;当前 V1 优先支持 JSON data URI + video_url/base64 输出。
- 后台 UI 还没有把 `LipSyncProvider` 单独分组展示,也没有发布验收页展示 `lip_sync_clips`
- 尚未用真实 lip-sync Provider 重跑第 5 镜,所以真实口型效果还未验收。
下一步建议:
- 选定真实 lip-sync 平台后,按其 API 调整 `generic-lipsync``base_url/create_endpoint/video_field/audio_field/text_field`,填写 Key 后启用。
- 做后台“LipSyncProvider 配置/测试”入口,避免和普通 VideoProvider 混在一起。
- 用第 5 镜真实跑一次 lip-sync 小样,比较 `asset 345` 和 lip-sync 后版本的口型效果。
### 阶段名称
LipSync 成本闸门 V1 / 镜头级按需口型同步
完成时间:
2026-06-11 14:14 Asia/Shanghai
完成内容:
- 明确落地“单镜头级 lip-sync,不做整片默认 lip-sync”的生产策略。
- `LiveActionGenerateDto` 新增 `lip_sync_max_seconds`,用于限制单集最多进入真实 lip-sync Provider 的秒数。
- 真人后期合成前新增 lip-sync 预算计划:
- 默认每集最多 `18s`
- 上限硬限制 `120s`
-`route_tier``importance_score``action_score``emotion_score` 优先保留高价值镜头;
- 超出预算的高风险台词镜头自动降级为 `post_tts_subtitle_light_mouth`,不调用 lip-sync Provider。
- 实际 Provider 调用条件改为只处理 `lip_sync_strategy=provider_lipsync`,避免仅“需要口型同步但被预算跳过”的镜头误触发二次视频处理。
- 后期任务 `input_json.post_production` 增加:
- `lip_sync_budget`
- `lip_sync_policy.segments[].skip_reason`
- `lip_sync_skip_reason`
- 单测新增“两个高风险台词镜头只同步高价值镜头,普通镜头预算跳过并降级”的覆盖。
- 单测新增“显式关闭 lip-sync 时也走轻口型/字幕安全降级”的覆盖,避免关闭后仍按 `provider_lipsync` 排时序。
修改文件:
- `backend/src/live-action/live-action.dto.ts`
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
新增文件:
- 无。
运行命令:
- `git status --short`
- `npm test --workspace backend -- live-action.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run lint --workspace backend`
- `npm run build --workspace backend`
- `npm test --workspace backend`
- 重启后端 `setsid -f node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 真人服务单测:`20 passed`
- 后端 typecheck:通过
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`24 passed / 195 passed`
- 后端已重启,PID `94928`,健康检查通过。
遗留问题:
- 真实 lip-sync Provider 还没有开通并验收,当前只是把成本闸门和调用策略先做生产级保护。
- `lip_sync_max_seconds` 目前通过接口参数控制,后续后台可以做成项目级/单集级配置项。
- 后台审计页还未展示 `lip_sync_budget.skipped`,运营人员暂时需要查看任务 JSON。
下一步建议:
- 选一个真实 lip-sync 平台做小样准入,优先阿里 VideoRetalk。
- 后台增加 lip-sync 预算档位配置与审计展示:已同步秒数、跳过镜头、跳过原因、节省成本。
- 继续用第 5 镜或 30s 打破次元壁样片做真实 Provider 对比验收。
### 阶段名称
LipSync 多平台 Adapter V1 / 阿里 VideoRetalk 可执行接入
完成时间:
2026-06-11 14:35 Asia/Shanghai
完成内容:
- 新增 `configurable_async_lip_sync` Provider 驱动,用于“提交任务 -> task_id 轮询 -> 下载结果视频”的 lip-sync 平台。
- 阿里云百炼 VideoRetalk 接入为可执行 Adapter
- provider_code`alibaba-videoretalk-lipsync`
- model`videoretalk`
- base_url`https://dashscope.aliyuncs.com`
- create_endpoint`/api/v1/services/aigc/video-generation/video-retalk`
- task_endpoint_template`/api/v1/tasks/{task_id}`
- 请求体:`model + input.video_url/audio_url/text`
- 请求头:`X-DashScope-Async: enable`
- 默认禁用。
- 新增默认禁用 lip-sync Provider 配置:
- `alibaba-videoretalk-lipsync`
- `heygen-lipsync`
- `sync-labs-lipsync`
- `fal-veed-lipsync`
- `volcengine-doubao-lipsync`
- `generic-lipsync`
- 豆包/火山 lip-sync 先接后台占位,默认禁用;当前未确认稳定“已有视频+音频口型替换”公开 API,不硬写不确定 endpoint。
- live-action 调用 lip-sync Provider 时,除了 data URI,也会传入已有公网 `video_url/audio_url`;阿里这类要求公网 URL 的平台在没有公网 URL 时会明确报错。
- Provider bootstrap 保留 `video_field``text_field``requires_public_urls``parameters_json` 等厂商字段,避免后台改完后被初始化覆盖。
- 数据库已 upsert 当前 `LipSyncProvider` 列表,全部保持 `is_enabled=false`,未写入任何真实 API Key。
修改文件:
- `backend/src/providers/provider.types.ts`
- `backend/src/providers/providers.service.ts`
- `backend/src/providers/providers.service.spec.ts`
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
新增文件:
- 无。
运行命令:
- `git status --short`
- `npm test --workspace backend -- providers.service.spec.ts`
- `npm test --workspace backend -- live-action.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run lint --workspace backend`
- `npm run build --workspace backend`
- `npm test --workspace backend`
- Prisma upsert `LipSyncProvider` 配置
- Prisma 查询 `LipSyncProvider` 配置
- 重启后端 `setsid -f node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 单测:`33 passed`
- 真人服务单测:`20 passed`
- 后端 typecheck:通过
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`24 passed / 196 passed`
- 数据库确认:
- `mock-lipsync`:禁用
- `generic-lipsync`:禁用
- `alibaba-videoretalk-lipsync`:禁用,`0.08 CNY/s`
- `heygen-lipsync`:禁用
- `sync-labs-lipsync`:禁用
- `fal-veed-lipsync`:禁用
- `volcengine-doubao-lipsync`:禁用占位
- 后端已重启,PID `130104`,健康检查通过。
遗留问题:
- 阿里 VideoRetalk 官方要求公网可访问的 `video_url/audio_url`;当前项目存储层仍以私有本地/MinIO 为主,还需要补“临时公开 URL / 预签名 URL / OSS 中转”才能真实跑阿里。
- HeyGen、Sync Labs、fal/VEED 已有默认禁用配置,但具体账号版本、endpoint 和响应字段需要开通后用小样校准。
- 豆包/火山 lip-sync 只做默认禁用占位,等控制台确认正式 API 后再补准确 endpoint。
下一步建议:
- 先补“lip-sync 素材临时公网 URL”能力,优先 MinIO presigned URL 或 OSS 中转。
- 阿里百炼开通后填 `ALIBABA_DASHSCOPE_API_KEY`,启用 `alibaba-videoretalk-lipsync`,用第 5 镜跑 6 秒真实小样。
- 后台 Provider 列表增加 LipSyncProvider 分组和“需要公网素材 URL”提示,避免运营误启用。
### 阶段名称
ProviderAssetBridge V1 / LipSync 临时公网素材 URL
完成时间:
2026-06-11 14:58 Asia/Shanghai
完成内容:
- 新增后端签名临时素材 URL 能力,兼容本地私有存储和 MinIO 私有存储:
- `StorageService.createTemporaryPublicUrl`
- `StorageService.readTemporaryPublicFile`
- 默认有效期 `3600s`
- 最短 `60s`,最长 `24h`
- 需要配置 `PUBLIC_ASSET_BASE_URL`
- 签名密钥优先读取 `PUBLIC_ASSET_SIGNING_SECRET`,可回退 `JWT_SECRET`
- 新增无登录公开临时下载入口:
- `GET /api/public-temp-assets/:token`
- 只读下载,过期失效
- `Cache-Control: no-store`
- 真人 lip-sync 调用新增素材桥接:
- Provider 配置 `requires_public_urls=true` 时,自动把私有视频片段生成临时 `video_url`
- 单句 TTS 音频如果没有公网 URL,先写入私有临时对象,再生成临时 `audio_url`
- 传给 Provider 的 input 同时保留 data URI,兼容 fal/通用 Provider
- 任务 JSON 记录 `asset_bridge` 审计摘要,不记录真实 URL token。
- Provider 日志脱敏:
- `video_url/audio_url` 如果包含 `/public-temp-assets/`,日志中写为 `[REDACTED_TEMP_PUBLIC_ASSET_URL]`
- Provider 默认配置新增并保留:
- `public_url_expires_seconds`
- `asset_url_expires_seconds`
- 数据库已同步 LipSyncProvider 配置,阿里/HeyGen/Sync/fal/火山占位继续保持默认禁用。
修改文件:
- `backend/src/assets/storage.service.ts`
- `backend/src/assets/storage.service.spec.ts`
- `backend/src/assets/public-temp-assets.controller.ts`
- `backend/src/assets/assets.module.ts`
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `backend/src/providers/provider.types.ts`
- `backend/src/providers/providers.service.ts`
- `CODEX_PROGRESS.md`
新增文件:
- `backend/src/assets/storage.service.spec.ts`
- `backend/src/assets/public-temp-assets.controller.ts`
运行命令:
- `git status --short`
- `npm test --workspace backend -- storage.service.spec.ts`
- `npm test --workspace backend -- live-action.service.spec.ts`
- `npm test --workspace backend -- providers.service.spec.ts`
- `npm test --workspace backend -- live-action.service.spec.ts storage.service.spec.ts providers.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run lint --workspace backend`
- `npm run build --workspace backend`
- `npm test --workspace backend`
- Prisma upsert `LipSyncProvider` 配置
- 重启后端 `setsid -f node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Storage 单测:`2 passed`
- Provider 单测:`33 passed`
- 真人服务单测:`21 passed`
- 相关单测合计:`3 passed / 56 passed`
- 后端 typecheck:通过
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`25 passed / 199 passed`
- 数据库同步:
- `alibaba-videoretalk-lipsync`:禁用,`public_url_expires_seconds=3600`
- `heygen-lipsync`:禁用,`public_url_expires_seconds=3600`
- `sync-labs-lipsync`:禁用,`public_url_expires_seconds=3600`
- `fal-veed-lipsync`:禁用,`public_url_expires_seconds=3600`
- `volcengine-doubao-lipsync`:禁用,`public_url_expires_seconds=3600`
- 后端已重启,PID `171746`,健康检查通过。
遗留问题:
- 真实阿里 VideoRetalk 运行前需要配置公网可访问的 `PUBLIC_ASSET_BASE_URL`,这个地址必须能从阿里云侧访问到本服务器。
- 生产环境建议单独设置高强度 `PUBLIC_ASSET_SIGNING_SECRET`,不要长期依赖 `JWT_SECRET` 回退。
- MinIO 直签 / OSS 中转还没做;当前 V1 使用后端签名下载入口,足够先跑小样。
下一步建议:
- 配置 `PUBLIC_ASSET_BASE_URL=https://你的域名``PUBLIC_ASSET_SIGNING_SECRET`
- 开通阿里百炼后填 `ALIBABA_DASHSCOPE_API_KEY`,启用 `alibaba-videoretalk-lipsync`,用第 5 镜跑真实口型小样。
- 后台 Provider 页增加“需要公网素材 URL / 临时 URL 有效期 / 当前是否配置 PUBLIC_ASSET_BASE_URL”的提示。
### 阶段名称
真人视频 Prompt Engine V1 / Provider Profile / 镜头模板库
完成时间:
2026-06-11 17:52 Asia/Shanghai
完成内容:
- 新增真人视频 Prompt Engine V1
- 支持 `generic``hailuo``kling``mock` 四种 Provider Profile。
- 支持按 `scene_type` 选择镜头模板:`dialog``conflict``reveal``dimensional_break``xianxia_transformation``action`
- 输出结构化 `prompt_components`,包含角色、场景、主动作、运镜、灯光、特效、后期音效提示、口型策略、负面提示词。
- Hailuo Profile 增加方括号运镜指令,例如 `[推进]``[拉远]``[环绕]``[跟拍]``[固定]`
- Hailuo Profile prompt 控制在 `1800` 字符以内,预留给平台上限和后续追加字段。
- 真人分镜准备阶段改为用 Prompt Engine 生成通用版 `video_prompt`
- 真人视频真实生成阶段改为根据 Router 选出的 `provider_code` 重新生成 Provider 专属 prompt。
- `live_action_video_clip_generate` 任务输入新增审计字段:
- `prompt_version`
- `prompt_profile`
- `prompt_components`
- `negative_prompt`
- 保留原有 lip-sync 降级策略文案,避免没有 lip-sync Provider 时出现正脸口型翻车。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `backend/src/live-action/live-action.module.ts`
- `CODEX_PROGRESS.md`
新增文件:
- `backend/src/live-action/prompt-builder.service.ts`
- `backend/src/live-action/prompt-builder.service.spec.ts`
运行命令:
- `git status --short`
- `npm test --workspace backend -- prompt-builder.service.spec.ts live-action.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run lint --workspace backend`
- `npm test --workspace backend`
- `npm run build --workspace backend`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Prompt Engine + 真人服务目标测试:`2 passed / 23 passed`
- 后端 typecheck:通过
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`26 passed / 201 passed`
遗留问题:
- Prompt Engine V1 先以内置模板落地,暂未做后台可编辑 Prompt 模板库。
- 音效/BGM 目前只作为 `sound_cue` 写入 prompt 组件和审计;真实混音仍走后期音频/BGM 流程,不依赖视频 Provider 直接出声。
- Kling/Veo/Sora 等 Provider 专属模板后续需要真实小样回测再细化。
下一步建议:
- 用现有 Hailuo Key 重跑“打破次元壁 30 秒小样”,比较 Prompt Engine V1 前后的画面稳定性、动作清晰度和失败原因。
- 后台 Router 审计页展示 `prompt_profile``prompt_version``prompt_components`
- 第二阶段再把 Prompt Engine 模板前台化,做可编辑的 Prompt Library / 运镜库 / 特效库。
### 阶段名称
MiniMax LipSyncProvider 占位接入
完成时间:
2026-06-11 18:15 Asia/Shanghai
完成内容:
- 确认 MiniMax/Hailuo 体系已经在项目中区分为:
- `VideoProvider`:Hailuo 图生视频/文生视频方向。
- `VoiceProvider`MiniMax TTS。
- `LipSyncProvider`:已有视频 + 音频口型替换方向。
- 新增 `minimax-lipsync` 默认禁用 Provider 占位:
- `provider_type=LipSyncProvider`
- `provider_code=minimax-lipsync`
- `api_key_env=MINIMAX_API_KEY`
- `driver=configurable_async_lip_sync`
- `requires_public_urls=true`
- `public_url_expires_seconds=3600`
- `create_endpoint/task_endpoint_template` 暂留空,等待 MiniMax 控制台或官方文档确认。
- 数据库已同步该 Provider
- `id=78`
- `is_enabled=false`
- 未写入真实 API Key。
修改文件:
- `backend/src/providers/provider.types.ts`
- `backend/src/providers/providers.service.spec.ts`
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- `npm test --workspace backend -- providers.service.spec.ts`
- `npm run typecheck --workspace backend`
- `npm run lint --workspace backend`
- `npm test --workspace backend`
- `npm run build --workspace backend`
- Prisma upsert `minimax-lipsync`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 单测:`34 passed`
- 后端 typecheck:通过
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`26 passed / 202 passed`
- 数据库同步:`minimax-lipsync` 已创建,默认禁用。
遗留问题:
- MiniMax 开放平台当前未确认稳定“已有视频+音频口型替换”的公开 API endpoint;该 Provider 不能直接启用。
- 若 MiniMax 控制台开通后提供 endpoint,需要补齐:
- `create_endpoint`
- `task_endpoint_template`
- 请求体字段映射
- 输出视频字段
- 真实计费规则
下一步建议:
- 继续以 DeepSeek + Hailuo + MiniMax TTS + FFmpeg 跑可发布样片。
- lip-sync 仍按策略只给高风险正脸台词镜头使用,不做全片 lip-sync。
- 若要优先真实测试 lip-sync,当前更稳的是阿里 VideoRetalkMiniMax 等官方 endpoint 确认后再启用。
### 阶段名称
MiniMax Lip Sync 公开 API 验证
完成时间:
2026-06-11 18:23 Asia/Shanghai
完成内容:
- 读取 MiniMax 官方 `llms.txt` 文档索引和 OpenAPI 规格。
- 官方 API 索引当前只确认:
- Text / Responses
- TTS / 异步 TTS
- Voice Clone / Voice Design
- Image Generation
- Video Generation
- Video Agent / Template Generation
- File Management
- 官方 OpenAPI 当前只检索到以下视频/音频相关路径:
- `/v1/t2a_async_v2`
- `/v1/query/t2a_async_query_v2`
- `/v1/video_generation`
- `/v1/video_template_generation`
- `/v1/query/video_template_generation`
- 对常见 MiniMax lip-sync 路径做无密钥存在性探测,全部返回 `404 page not found`
- `/v1/lip_sync`
- `/v1/lipsync`
- `/v1/video/lip_sync`
- `/v1/video/lipsync`
- `/v1/video_generation/lipsync`
- `/v1/video/lip-sync`
- 检查本机环境变量:
- `MINIMAX_API_KEY`:未配置
- `MINIMAX_GROUP_ID`:未配置
- `MINIMAX_BASE_URL`:未配置
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- `curl https://platform.minimax.io/docs/llms.txt`
- `curl https://platform.minimax.io/docs/api-reference/openapi.json`
- 多个 MiniMax lip-sync 猜测 endpoint 的 `POST {}` 404 探测
- `.env` MiniMax 相关变量存在性检查
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 官方文档 / OpenAPI:未发现稳定公开“已有视频+音频口型替换” Lip Sync API。
- 猜测 endpoint 探测:全部 404。
- 本机未配置 MiniMax Key,无法做鉴权后的真实调用。
结论:
- `minimax-lipsync` 保持默认禁用占位是正确的。
- 当前不能把 MiniMax 当作已可用稳定 LipSyncProvider。
- MiniMax 仍可继续用于 Hailuo 视频生成和 MiniMax TTSlip-sync 优先测试阿里 VideoRetalk / HeyGen / Sync Labs / fal VEED 等已经有明确 lip-sync API 形态的平台。
下一步建议:
- 若 MiniMax 控制台或商务支持提供正式 lip-sync endpoint,再补齐 `minimax-lipsync` 的 endpoint、请求体和输出字段。
- 当前真人短剧流程继续采用“非正脸台词 + TTS + 字幕 + 少量高风险镜头 lip-sync”的低成本策略。
### 阶段名称
首条真人短剧一集压测用例整理
完成时间:
2026-06-11 18:32 Asia/Shanghai
完成内容:
- 将用户提供的《我送外卖时,继承了百亿集团》整理为系统可用的一集真人短剧测试用例。
- 输出机器可读 JSON
- 项目配置
- 故事圣经
- 3 个角色
- 2 个场景
- 第 1 集剧情
- 10 个分镜
- Router 预期
- 口型策略
- 输出要求
- 验收标准
- 输出人工审核 Markdown,方便先看剧情、镜头和验收点。
- 当前只整理用例,不触发 DeepSeek / Hailuo / FFmpeg 真实生成。
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
- `storage/private/live-action-testcases/takeaway-heir-episode-001.json`
- `storage/private/live-action-testcases/takeaway-heir-episode-001.md`
运行命令:
- `git status --short`
- `node -e` JSON 解析与时长/镜头数/角色数/场景数校验
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- JSON 校验通过:
- 镜头:10 个
- 总时长:53 秒
- 角色:3 个
- 场景:2 个
- normal 镜头:5 个
- premium 镜头:5 个
遗留问题:
- 还未导入数据库。
- 还未跑 DeepSeek 剧本生成、Prompt Builder、Hailuo 视频、TTS、字幕、BGM、FFmpeg 合成。
- 该用例目前作为“第一集压测 fixture”,不是最终成片。
下一步建议:
- 人工先确认剧情和 10 个镜头是否满意。
- 确认后新增导入脚本,把该 JSON 导入为真实项目/角色/分集/分镜。
- 再按低风险顺序执行:先 Mock 全链路,再 Hailuo 单镜小样,再 Hailuo 全 10 镜。
### 阶段名称
首条真人短剧压测项目导入 / Prompt 准备
完成时间:
2026-06-11 20:18 Asia/Shanghai
完成内容:
- 新增真人短剧测试用例导入脚本:
- 支持默认读取 `storage/private/live-action-testcases/takeaway-heir-episode-001.json`
- 支持 `--replace=true` 清理同一 `testcase_id` 的旧导入项目
- 创建 Project / CopyrightRecord / StoryBible / WorldBible / Character / ActorProfile / Episode / EpisodeScript / StoryboardShot / OperationLog
- 不触发真实 AI Provider,不生成视频,不产生外部成本
- 已执行一次导入:
- `project_id=54`
- `episode_id=40`
- `owner_user_id=1`
- `shot_id=231-240`
- 总时长 `53s`
- 已执行 `prepareLiveActionShots`
- 10 个镜头全部生成 `video_prompt`
- 项目状态更新为 `live_action_shots_prepared`
- 下一步为 `live_action_keyframes_generate`
修改文件:
- `backend/package.json`
- `CODEX_PROGRESS.md`
新增文件:
- `backend/src/live-action/import-live-action-testcase.ts`
运行命令:
- `git status --short`
- `npm run typecheck --workspace backend`
- `npm run lint --workspace backend`
- `npm run build --workspace backend`
- `npm test --workspace backend`
- `npm run live-action:testcase:import --workspace backend -- --replace=true`
- Prisma 查询校验导入结果
- Nest ApplicationContext 调用 `LiveActionService.prepareLiveActionShots`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- 后端 typecheck:通过
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`26 passed / 202 passed`
- 数据库导入校验:
- 角色:3
- ActorProfile3
- 分镜:10
- 总时长:53 秒
- Premium 镜头:5
- `video_prompt`10/10 已生成
遗留问题:
- 还未生成关键帧。
- 还未跑 Mock 视频全链路。
- 还未调用 Hailuo 真实视频。
- 还未生成 TTS / 字幕 / BGM / 最终 `episode_001.mp4`
下一步建议:
- 先跑 Mock 关键帧和 Mock 视频全链路,确认 10 镜合成、字幕、BGM、审计视图都能走通。
- 再挑 1 个 premium 镜头,用真实 PNG/JPG 关键帧跑 Hailuo 单镜小样。
- 单镜合格后再跑全 10 镜真实 Hailuo,严格限制成本上限。
### 阶段名称
首条真人短剧 Mock 全链路成片验收
完成时间:
2026-06-11 20:24 Asia/Shanghai
完成内容:
- 对项目 `54` / 第 `40` 集执行 Mock 全链路:
- Mock 关键帧生成
- Mock 视频片段生成
- Mock TTS 音频
- 字幕生成
- BGM 生成
- FFmpeg 最终合成
- 生成最终成片资产:
- `asset_id=373`
- `file_path=local://rendered-videos/2026-06-11/e83438a3-ef14-4ef5-89f4-2a8511bcfe19.mp4`
- 本地路径:`storage/private/rendered-videos/2026-06-11/e83438a3-ef14-4ef5-89f4-2a8511bcfe19.mp4`
- 发现并修复验收差异:
- 测试用例要求 `30FPS`
- 旧 live-action 渲染常量为 `24FPS`
- 已将 `LIVE_ACTION_RENDER_FPS``24` 改为 `30`
- 重新渲染后 ffprobe 确认输出为 `30/1`
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- Nest ApplicationContext 调用:
- `generateKeyframes`
- `generateVideoClips`
- `renderLiveActionEpisode`
- `ffprobe` 检查最终 MP4
- `npm run typecheck --workspace backend`
- `npm test --workspace backend -- live-action.service.spec.ts`
- `npm run lint --workspace backend`
- `npm test --workspace backend`
- `npm run build --workspace backend`
- 重启后端 `node dist/main.js`
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Mock 关键帧:`10/10`
- Mock 视频片段:`10/10`
- 最终成片:成功
- ffprobe
- 视频编码:`h264`
- 分辨率:`1080x1920`
- 帧率:`30/1`
- 视频时长:`53.000000s`
- 音频编码:`aac`
- 音频时长:`53.000000s`
- 后端 typecheck:通过
- 真人服务单测:`21 passed`
- 后端 lint:通过
- 后端 build:通过
- 后端全量测试:`26 passed / 202 passed`
- 后端已重启,PID `784440`,健康检查通过。
遗留问题:
- 当前成片是 Mock 视频,不能评价真实画面质量。
- 当前口型策略为 TTS + 字幕 + 轻口型规避,未启用真实 lip-sync。
- 真实 Hailuo 单镜还未跑。
下一步建议:
- 在后台打开资产 `373` 或项目 `54` 的结果页,人工先看 Mock 流程预览和字幕/BGM节奏。
- 选择一个 premium 镜头做真实 Hailuo 单镜小样,建议优先镜头 `235`(劳斯莱斯停靠 + 王伯鞠躬)或镜头 `240`(车门关闭反击)。
- 单镜通过后再跑全 10 镜真实 Hailuo。
## 2026-06-11 真实 Hailuo 单镜小样验收
完成时间:
2026-06-11 20:36 Asia/Shanghai
完成内容:
- 对项目 `54` / 第 `40` 集 / 镜头 `235` 跑真实 Hailuo 单镜小样。
- 先将镜头 `235` 的 mock SVG 关键帧替换为可供真实视频接口使用的 PNG 关键帧:
- `keyframe_asset_id=374`
- `file_path=local://image/2026-06-11/84761003-b42a-43b5-8e46-b3ba8a1f5f62.png`
- 真实视频 Provider 预检通过:
- Provider`minimax_hailuo_23_fast`
- 模式:`real`
- 预计成本:`0.1902 USD`
- 关键帧:`image/png`
- 阻断项:无
- 发起真实 Hailuo 图生视频调用并成功回收视频:
- `video_clip_id=25`
- `output_asset_id=375`
- `provider_id=19`
- `provider_request_id=408077018386698`
- 实际成本:`0.1902 USD`
- 文件:`storage/private/live-action-video-clips/2026-06-11/cb0fd951-657a-4d07-b3c7-661a1d8cfa93.mp4`
- 执行队列化质检任务:
- `task_id=376`
- Provider`mock-qc`
- 结果:`passed`
- 分数:`94`
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- Nest ApplicationContext 调用:
- `preflightVideoClips`
- `generateShotVideoClip`
- `checkVideoClipQuality`
- `executeQueuedRouterTask`
- `ffprobe` 检查真实 Hailuo MP4
- `ffmpeg` 抽帧检查中间画面
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Provider 密钥状态:
- `.env` 未设置 `MINIMAX_API_KEY`
- 后台 Provider 已保存加密托管密钥,且已同步到 Hailuo / MiniMax TTS / MiniMax Text
- Hailuo 单镜生成:成功
- 质检闭环:成功
- ffprobe 原始 Provider 输出:
- 视频编码:`h264`
- 分辨率:`768x1364`
- 帧率:`24/1`
- 时长:`5.875000s`
- 音频:无
- 人工抽帧观感:
- 雨夜、豪车、管家鞠躬、男主站位均符合镜头意图。
- 该片段是无声单镜,需要进入 TTS / 字幕 / BGM / FFmpeg 合成后才可作为完整成片验收。
遗留问题:
- Hailuo Fast 原始输出不是 `1080x1920 / 30FPS / 6s`,最终成片必须依赖 FFmpeg 归一化。
- 资产表当前记录的是目标尺寸 `1080x1920 / 6s`,但真实原始文件为 `768x1364 / 5.875s`;后续后台审计页应同时展示 Provider 原始媒体参数和归一化参数。
- 当前只验证了单镜真实视频,没有验证 10 镜真实 Hailuo 全集生成和最终音画合成。
下一步建议:
- 进入 10 镜真实 Hailuo 全集小样,但在全量扣费前先批量准备 PNG/JPG 关键帧。
- 真实全集跑完后,执行 TTS / 字幕 / BGM / FFmpeg 合成,重点验收音画节奏、字幕、BGM、镜头时长归一化。
- 后台 Router 审计页补充 Provider 原始输出参数展示,避免 `768x1364/24fps` 和最终 `1080x1920/30fps` 混淆。
## 2026-06-11 真实 Hailuo 全 10 镜小样验收
完成时间:
2026-06-11 20:59 Asia/Shanghai
完成内容:
- 对项目 `54` / 第 `40` 集执行真实 Hailuo 全 10 镜小样。
- 因当前没有启用真实 ImageProvider,先为除第 5 镜外的 9 个镜头生成基础构图 PNG 关键帧,用于真实视频链路压测:
- 镜头 `231` -> `keyframe_asset_id=376`
- 镜头 `232` -> `keyframe_asset_id=377`
- 镜头 `233` -> `keyframe_asset_id=378`
- 镜头 `234` -> `keyframe_asset_id=379`
- 镜头 `236` -> `keyframe_asset_id=380`
- 镜头 `237` -> `keyframe_asset_id=381`
- 镜头 `238` -> `keyframe_asset_id=382`
- 镜头 `239` -> `keyframe_asset_id=383`
- 镜头 `240` -> `keyframe_asset_id=384`
- 整集真实 Hailuo 预检通过:
- 镜头数:`10`
- 关键帧:`10/10` 均为 PNG
- Provider`minimax_hailuo_23_fast`
- 预估成本:`1.6801 USD`
- 阻断项:无
- 补跑剩余 9 条真实 Hailuo 视频片段:
- 镜头 `231` -> `video_clip_id=26` / `asset_id=385`
- 镜头 `232` -> `video_clip_id=27` / `asset_id=386`
- 镜头 `233` -> `video_clip_id=28` / `asset_id=387`
- 镜头 `234` -> `video_clip_id=29` / `asset_id=388`
- 镜头 `236` -> `video_clip_id=30` / `asset_id=389`
- 镜头 `237` -> `video_clip_id=31` / `asset_id=390`
- 镜头 `238` -> `video_clip_id=32` / `asset_id=391`
- 镜头 `239` -> `video_clip_id=33` / `asset_id=392`
- 镜头 `240` -> `video_clip_id=34` / `asset_id=393`
- 结合已完成的镜头 `235`
- 10 条真实 Hailuo 视频片段全部成功。
- 10 条片段质检全部通过,分数均为 `94`
- 强制重新合成整集:
- `render_task_id=398`
- `output_asset_id=397`
- 文件:`storage/private/rendered-videos/2026-06-11/69f4335a-cbe5-4a80-99ff-dbbcb7f32741.mp4`
- 状态:`active`
- 后期资产:
- TTS`audio_task_id=395` / `audio_asset_id=394`
- VoiceProvider`minimax-tts`
- `audio_is_mock=false`
- 字幕:`subtitle_task_id=396` / `subtitle_asset_id=395`
- BGM`bgm_task_id=397` / `bgm_asset_id=396`
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- `git status --short`
- Nest ApplicationContext / dist 脚本调用:
- PNG 关键帧上传并回写镜头
- `preflightVideoClips`
- `generateShotVideoClip`
- `checkVideoClipQuality`
- `executeQueuedRouterTask`
- `renderLiveActionEpisode`
- `ffprobe` 检查最终 MP4
- `ffmpeg` 抽帧与接触图检查
测试结果:
- `git status --short`:失败,当前目录不是 Git 仓库。
- Hailuo 视频生成:
- 成功:`10/10`
- 失败:`0`
- 单条耗时约 `64s-88s`
- 每条实际成本:`0.1902 USD`
- 总视频成本:`1.902 USD`
- Hailuo 成本估算差异:
- 系统预估 `5s` 镜头为 `0.1585 USD`
- 实际 Hailuo Fast 仍按 `6s` 档返回/扣费,实际为 `0.1902 USD`
- 后续成本模型应按 Provider 档位估算,而不是简单按秒线性估算。
- 最终成片 ffprobe
- 视频编码:`h264`
- 分辨率:`1080x1920`
- 帧率:`30/1`
- 视频流时长:`52.600000s`
- 音频编码:`aac`
- 音频流时长:`53.000000s`
- 容器时长:`53.000000s`
- clip_normalization
- 5 秒业务镜头均从 Hailuo 原始 `5.875s` 裁切到 `5s`
- 6 秒业务镜头保留约 `5.867s`
- 合成后总时长对齐到 `53s`
- TTS
- 已走真实 `minimax-tts`
- 发现第 1 个音频片段超时:
- 目标:`2.85s`
- 实际:`4s`
- 超出:`1.15s`
- 人工抽帧 / 接触图观感:
- 画面已经是真人短剧风格,字幕烧录位置基本正常。
- 第 4 镜黑卡、雨夜车、管家、人物近景等主要叙事元素可识别。
- 由于 9 个关键帧是临时构图图,不是真实定妆图,角色一致性和服装一致性仍不足。
- 当前 BGM 是 `system_silent_bed_v1`,只能算底噪/铺底,不是正式都市逆袭音乐。
遗留问题:
- 这版证明真实 Hailuo + MiniMax TTS + 字幕 + FFmpeg 合成链路跑通,但不能直接判定为发布级成片。
- 发布级还缺真实角色定妆图 / 角色锚点图,否则人物脸和服装会漂。
- 成本估算需要按 Hailuo `6s/10s` 档位修正。
- 第 1 镜台词过长,TTS 超出分配时长,需要脚本压缩或镜头延长。
- BGM 还不是正式音乐,需要接音乐素材库或 BGM Provider。
- 质检仍是 `mock-qc`,还没有真实视觉质检模型。
下一步建议:
- 优先做“真人定妆图 / 角色锚点图小样 V1”:先固定林凡、陈雪、王伯三个人的真实头像和服装,再重跑 2-3 个关键镜头验证角色一致性。
- 修复 Hailuo 成本估算:按 Provider 配置的 duration 档位向上取整到 `6s/10s`
- 优化 TTS 节奏:台词超时自动压缩、分拆或延长镜头。
- 给 BGM 增加正式素材或 Provider,替换 `system_silent_bed_v1`
## 2026-06-11 公版热门故事《画皮》30 秒质量定位
完成时间:
2026-06-11 21:39 Asia/Shanghai
完成内容:
- 停止继续使用《我送外卖时,继承了百亿集团》做画质判断,改用公版热门故事《聊斋志异·画皮》做 30 秒质量定位。
- 新增内部测试用例:
- `storage/private/live-action-testcases/painted-skin-episode-001.json`
- 6 镜头,每镜 `5s`
- 总时长 `30s`
- 风格:古风悬疑真人短剧
- 导入新测试项目:
- `project_id=55`
- `episode_id=41`
- `shot_id=241-246`
- 运行现有 Prompt Builder 准备真人分镜提示词:
- 6/6 镜头已进入 `prepared`
- 使用 Codex 内置图片生成能力生成三张真人定妆图,并上传为项目私有资产:
- 王生:`character_id=79` / `anchor_asset_id=398`
- 画皮女子:`character_id=80` / `anchor_asset_id=399`
- 老道士:`character_id=81` / `anchor_asset_id=400`
- 已写入:
- `characters.anchor_asset_id`
- `actor_profiles.anchor_asset_id`
- `actor_profiles.reference_asset_ids`
- `character_images`
- 只跑 3 个关键镜头真实 Hailuo 小样,未跑整集:
- 镜头 `242` 女子求助:`video_clip_id=35` / `asset_id=401`
- 镜头 `244` 道士警告:`video_clip_id=36` / `asset_id=402`
- 镜头 `245` 窗外窥视:`video_clip_id=37` / `asset_id=403`
- 新增真实视频成本:
- `0.1902 USD * 3 = 0.5706 USD`
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
- `storage/private/live-action-testcases/painted-skin-episode-001.json`
运行命令:
- `npm run live-action:testcase:import --workspace backend -- --file=/www/wwwroot/ai/storage/private/live-action-testcases/painted-skin-episode-001.json --replace=true`
- Nest ApplicationContext / dist 脚本调用:
- `prepareLiveActionShots`
- 上传角色锚点图到资产库
- 回写角色 / ActorProfile / CharacterImage
- `preflightVideoClips`
- `generateShotVideoClip`
- `ffmpeg` 抽帧生成三镜头接触图:
- `/tmp/painted-skin-sample/contact.jpg`
测试结果:
- 30 秒故事结构明显比上一版更清楚:
- 夜巷初遇
- 女子求助
- 书斋收留
- 道士警告
- 窗外窥视
- 画皮真相一闪
- 三张角色定妆图质量可用:
- 服装、年龄、气质、古风身份都基本符合设定。
- 三条 Hailuo 关键镜头生成均成功。
- 人工抽帧结论:
- 角色脸和服装比临时构图图稳定得多。
- 但直接把“人物肖像图”作为 Hailuo 首帧,会导致视频更像人物肖像动图,而不是完整场景动作。
- Hailuo 对首帧构图继承很强,首帧不是场景图,后续很难自然生成复杂动作和双人互动。
关键结论:
- 不应该继续用“纯角色头像”直接跑整集 Hailuo。
- 正确流程应升级为:
- 角色锚点图
- 生成每个镜头的场景关键帧
- 场景关键帧中已经包含角色、服装、场景、动作起手式
- 再送 Hailuo 图生视频
- 也就是说,角色锚点图是必要条件,但不是视频首帧本身。
下一步建议:
- 做“场景关键帧 V1”:用角色锚点图约束人物,再为镜头 `242 / 244 / 245` 各生成一张真正的场景关键帧。
- 只重跑这 3 个镜头,不跑整集,确认动作和场景是否改善。
- 如果 3 个镜头可用,再补全 30 秒整集;如果仍不行,先改 Prompt Builder 和关键帧生成策略,不再继续烧视频额度。
## 2026-06-11 《画皮》场景关键帧 V1 验证
完成时间:
2026-06-11 22:04 Asia/Shanghai
完成内容:
- 基于项目 `55` / 第 `41` 集,继续验证“角色锚点图 -> 场景关键帧 -> Hailuo 图生视频”的正确链路。
- 使用 Codex 内置图片生成能力生成 3 张场景关键帧:
- 镜头 `242` 女子求助:`asset_id=404`
- 镜头 `244` 道士警告:`asset_id=405`
- 镜头 `245` 窗外窥视:`asset_id=406`
- 将三张场景关键帧替换为对应镜头的 `keyframe_asset_id`
- 重跑 3 条真实 Hailuo 视频:
- 镜头 `242` -> `video_clip_id=38` / `asset_id=407`
- 镜头 `244` -> `video_clip_id=39` / `asset_id=408`
- 镜头 `245` -> `video_clip_id=40` / `asset_id=409`
- 3 条新片段全部通过 mock-qc:
- `clip_id=38` -> `94`
- `clip_id=39` -> `94`
- `clip_id=40` -> `94`
- 将这 3 条片段合成 15 秒小样:
- `render_asset_id=413`
- 文件:`storage/private/rendered-videos/2026-06-11/3c388019-7ac4-4699-ba52-f9d4f0260eb1.mp4`
- 包含真实 MiniMax TTS、字幕、BGM 铺底。
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
-
运行命令:
- Codex 内置图片生成:3 张场景关键帧
- Nest ApplicationContext / dist 脚本调用:
- 上传场景关键帧
- 回写 `StoryboardShot.keyframe_asset_id`
- `preflightVideoClips`
- `generateShotVideoClip`
- `checkVideoClipQuality`
- `executeQueuedRouterTask`
- `renderLiveActionEpisode`
- `ffprobe` 检查 15 秒小样
- `ffmpeg` 抽帧和生成对比图
测试结果:
- 三条 Hailuo 生成全部成功:
- 成本:`0.1902 USD * 3 = 0.5706 USD`
- 单条耗时约 `76s-97s`
- 15 秒小样 ffprobe
- 视频编码:`h264`
- 分辨率:`1080x1920`
- 帧率:`30/1`
- 视频时长:`15.000000s`
- 音频编码:`aac`
- 音频时长:`15.000000s`
- TTS
- Provider`minimax-tts`
- `audio_is_mock=false`
- 无 TTS 超时警告
- clip_normalization
- Hailuo 原始 `5.875s`
- 每条裁切到目标 `5s`
人工观感结论:
- 场景关键帧版明显优于头像首帧版。
- 镜头 `242` 能看到女子、王生、伞、夜巷、红灯笼,求助关系成立。
- 镜头 `244` 能看到老道士、王生、竹杖拦路、街市口,警告关系成立。
- 镜头 `245` 能看到王生窗外窥视、屋内烛光和模糊白衣女子,悬疑关系成立。
- 这说明“先生成场景首帧,再送 Hailuo”是正确方向。
遗留问题:
- 当前场景关键帧由 Codex 图片生成能力手动生成,还未进入后台自动化流程。
- 角色锚点图没有被真实 ImageProvider 以多图参考方式自动消费,仍是人工 prompt 对齐。
- Hailuo 图生视频仍无原生音频,音频必须靠后期 TTS/字幕/BGM。
- BGM 仍是系统铺底,不是正式古风悬疑音乐。
- 成本估算仍需按 Hailuo `6s/10s` 档位修正。
下一步建议:
- 把“场景关键帧生成”做成后台正式流程:
- 输入:镜头分镜 + 角色锚点图 + 场景设定
- 输出:`ShotImage(image_type=scene_keyframe)` + `StoryboardShot.keyframe_asset_id`
- 然后再进入 Hailuo 视频生成
- 继续补齐《画皮》剩余 `241 / 243 / 246` 三个镜头的场景关键帧,再跑完整 30 秒。
- 之后再走前端 E2E,因为现在核心质量方向已经明确。
## 2026-06-11 《画皮》30 秒完整真人小样验收
完成时间:
2026-06-11 22:31 Asia/Shanghai
完成内容:
- 继续基于项目 `55` / 第 `41` 集,补齐剩余三个镜头的场景关键帧:
- 镜头 `241` 夜巷初遇:`keyframe_asset_id=414`
- 镜头 `243` 书斋收留:`keyframe_asset_id=416`
- 镜头 `246` 画皮真相一闪:`keyframe_asset_id=418`
- 分别使用真实 Hailuo 生成三条新片段:
- 镜头 `241` -> `video_clip_id=41` / `asset_id=415`
- 镜头 `243` -> `video_clip_id=42` / `asset_id=417`
- 镜头 `246` -> `video_clip_id=43` / `asset_id=419`
- 合并前 3 条已验证片段:
- 镜头 `242` -> `video_clip_id=38` / `asset_id=407`
- 镜头 `244` -> `video_clip_id=39` / `asset_id=408`
- 镜头 `245` -> `video_clip_id=40` / `asset_id=409`
- 合成完整 30 秒成片:
- `render_asset_id=423`
- 文件:`storage/private/rendered-videos/2026-06-11/1511d944-273b-493f-a860-dae29249a0c5.mp4`
- 包含真实 MiniMax TTS、字幕、静音 BGM 占位。
修改文件:
- `CODEX_PROGRESS.md`
新增文件:
- `storage/private/live-action-testcases/painted-skin-episode-001.json`
运行命令:
- Codex 内置图片生成:补齐 3 张场景关键帧。
- `npm run live-action:acceptance --workspace backend`
- 逐条跑 `241 / 243 / 246`
- Provider`minimax_hailuo_23_fast`
- `confirm_real_video=true`
- Nest `dist` ApplicationContext
- `renderLiveActionEpisode`
- `ffprobe`
- 验证最终成片视频/音频流
- `ffmpeg`
- 抽帧检查 6 镜头时间线
- `volumedetect` 检查最终音频电平
- `curl http://127.0.0.1:3000/api/health`
测试结果:
- Hailuo 本轮新增 3 条均成功:
- `clip_id=41` / `42` / `43`
- 成本:`0.1902 USD * 3 = 0.5706 USD`
- mock 质检:均 `94`
- 《画皮》6 条 Hailuo 片段合计:
- 成本:`0.1902 USD * 6 = 1.1412 USD`
- 约合人民币按汇率浮动约 `8 元` 左右。
- 30 秒成片规格:
- 视频:`h264`
- 分辨率:`1080x1920`
- 帧率:`30fps`
- 视频时长:`30.000000s`
- 音频:`aac`
- 音频时长:`30.000000s`
- 文件大小:约 `14.8MB`
- 后期:
- TTS Provider`minimax-tts`
- `audio_is_mock=false`
- `audio_warnings=[]`
- 字幕 cue`6`
- BGM`system_silent_bed_v1`,当前只是静音占位,不是正式音乐。
- clip_normalization
- 6 条 Hailuo 原始视频均约 `5.875s`
- 合成前全部自动裁切到目标 `5s`
- 最终总时长准确为 `30s`
- 后端健康检查:
- `/api/health` 返回 `status=ok`
人工观感结论:
- 这版明显优于之前“外卖继承百亿”和“头像首帧直接跑 Hailuo”的结果。
- 6 个镜头都与剧情相关,没有出现蜡烛图、无关画面或明显断片。
- 叙事链路基本成立:
- 夜巷初遇
- 女子求助
- 书斋收留
- 道士警告
- 窗外窥视
- 画皮揭露
- 字幕位置没有挡脸,画面和字幕节奏基本可读。
- 当前还不能判定为“可直接上架发布”,但已经证明质量问题的主因不是 Hailuo 单点,而是前置关键帧和 Prompt Builder。
遗留问题:
- 角色一致性仍未达到生产级:
- 王生服装在蓝袍、灰袍之间漂移。
- 人脸一致性比纯文字 prompt 好,但还不够稳定。
- 场景关键帧目前仍是人工生成,尚未自动接入后台 ImageProvider。
- 当前 BGM 是静音占位,不能满足正式发布的音乐需求。
- 旁白/对白已经存在,但未做真实 lip-sync,正脸对白仍应继续走“中景轻口型 + 字幕 + 旁白”策略,或后续接 lip-sync Provider。
- mock 质检只验证流程,不能替代人工画面审片。
关键结论:
- 后续真人短剧流水线必须改为:
- 故事/分镜
- 角色锚点图
- 场景关键帧生成
- Hailuo 图生视频
- TTS/字幕/BGM
- clip_normalization
- 人工审片
- 不建议再用“纯文字 prompt -> Hailuo”或“纯人物头像 -> Hailuo”跑整集。
下一步建议:
- 优先做“场景关键帧自动化 V1”:
-`scene_keyframe` 作为正式中间资产。
- 后台能看到每个镜头的关键帧、视频片段、最终成片对比。
- 角色锚点图作为关键帧生成输入,而不是直接作为视频首帧。
- 同时补“正式 BGM 资产/模板 V1”:
- 都市逆袭、古风悬疑、情感虐恋、修仙爆点各一套。
- 允许后台上传或选择 BGM。
- 质量通过后再走前端 E2E,避免继续在低质量画面上验 UI 流程。
## 2026-06-11 仿真人发布级质感 V1
完成时间:
2026-06-11 23:03 Asia/Shanghai
完成内容:
- 围绕“像抖音真人拍摄短剧”的差距,先补合成层的发布包装能力,不继续盲目烧 Hailuo 额度。
- 后端真人视频最终合成新增轻量影视包装:
- 轻对比
- 轻降饱和
- 轻暗角
- 细颗粒
- 后端默认 BGM 从静音占位升级为系统低频悬疑氛围底:
- `system_silent_bed_v1` -> `system_cinematic_bed_v1`
- 使用 FFmpeg 合成低频 pad,不再是完全静音轨。
- `live_action_video_render.input_json` 新增 `video_polish` 审计字段:
- `version=live-action-video-polish-v1`
- 记录使用的后期包装项。
- 基于已有《画皮》6 条 Hailuo 片段重做导演剪辑版:
- 不重新调用 Hailuo
- 不增加视频生成成本
- 将平均 `5s * 6 = 30s` 改为更短更快的 `18.9s`
- 缩短旁白/对白,避免正脸长对白。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/dist/**`
- `CODEX_PROGRESS.md`
数据调整:
- 项目 `55` / 第 `41` 集《画皮》测试集:
- 镜头 `241``3s`
- 镜头 `242``3.8s`
- 镜头 `243``2.7s`
- 镜头 `244``3.2s`
- 镜头 `245``2.8s`
- 镜头 `246``3.4s`
- 台词压缩:
- `女子:公子,救我。`
- `道士:她不是人。`
- `王生:不可能。`
新增成片:
- 导演剪辑版 asset
- `render_asset_id=431`
- 文件:`storage/private/rendered-videos/2026-06-11/6e44c8a9-6d22-438c-ba36-73da0ac230e0.mp4`
- 时长:`18.9s`
测试结果:
- `npm run typecheck --workspace backend`:通过。
- `npm run build --workspace backend`:通过。
- `npm run test --workspace backend -- live-action.service.spec.ts`
- `21 passed`
- FFmpeg BGM 表达式验证:通过。
- 成片 ffprobe
- 视频:`1080x1920`
- 帧率:`30fps`
- 视频时长:`18.900000s`
- 音频:`aac`
- 音频时长:`18.900000s`
- 音频电平:
- `mean_volume=-18.6 dB`
- `max_volume=-2.4 dB`
- render task 审计:
- `audio_warnings=[]`
- `video_polish.version=live-action-video-polish-v1`
- `bgm_volume=0.18`
- 后端重启并验证:
- 新进程:`node dist/main.js`
- 父进程:`1`
- `/api/health` 返回 `status=ok`
人工观感结论:
- 导演剪辑版比 30 秒平均镜头版节奏更接近短视频。
- 字幕更短,读起来更干净。
- 合成层统一调色、颗粒、暗角后,画面少了一点“AI直出平铺感”。
- 但它仍不是最终发布级,原因不是合成层能完全解决的:
- 角色一致性仍会漂。
- 真人表演感仍不足。
- 镜头内动作还不够像真实演员自然运动。
- 真实环境声、脚步声、雨声、衣料声、转场音效还没系统化。
- 未接真实 lip-sync,正脸对白仍不能大量使用。
关键结论:
- “发布级仿真人”不是单纯 Hailuo 重跑,而是需要进入导演工艺层:
- 短镜头节奏
- 更短台词
- 避免正脸长对白
- 真实声音设计
- 人工挑片
- 角色一致性约束
- 关键镜头多候选择优
下一步建议:
- 做“候选片段择优 V1”:
- 每个关键镜头允许生成 2-3 个候选。
- 后台人工选择最像真人的一条作为 `video_clip_asset_id`
- 不通过的候选保留成本和失败原因。
- 做“音效轨 V1”:
- 雨声、脚步、门响、心跳、低频转场、惊悚 sting。
-`scene_type/effect_type` 自动铺音效。
- 做“角色一致性强化 V1”:
- 场景关键帧自动生成时必须消费角色锚点图。
- 后台显示锚点图、场景关键帧、视频中帧三栏对比。
## 2026-06-12 候选片段择优 V1 + 音效轨 V1
本阶段目标:
- 让关键镜头可以一次生成 `2-3` 条候选,后台人工选择最像真人的一条。
- 给真人短剧后期增加独立 SFX 音效轨,先解决“画面有了但不像真实拍摄环境”的声音缺口。
完成内容:
- `LiveActionGenerateDto` 新增:
- `candidate_count`
- `include_sfx`
- `sfx_volume`
- 单镜头真人视频生成支持候选片段:
- `candidate_count` 限制为 `1-3`
- 多候选生成时,默认第 1 条自动绑定到 `StoryboardShot.video_clip_asset_id`
- 第 2/3 条只作为候选保留在 `video_clips`,不会覆盖当前 active clip。
- render task 的 `input_json` 记录:
- `candidate_index`
- `candidate_count`
- `auto_select_clip`
- 新增候选选择接口:
- `POST /api/live-action/video-clips/:clipId/select-candidate`
- 选择后更新分镜:
- `video_clip_asset_id = clip.output_asset_id`
- `video_status = video_clip_candidate_selected`
- 写入 `operation_logs`
- `live_action_video_clip_candidate_selected`
- 记录旧 asset、新 asset、质量分、成本、选择原因。
- 真人后期新增 SFX 音效轨:
- 新 task 类型:`live_action_sfx_generate`
- 新系统音效源标识:`system_scene_sfx_v1`
- 自动按镜头文本/分数生成 cue
- `rain`
- `footstep`
- `door`
- `heartbeat`
- `sting`
- SFX 独立生成 audio asset,最终和 BGM / TTS 分轨混音。
- `post_production` 审计新增:
- `include_sfx`
- `sfx_asset_id`
- `sfx_task_id`
- `sfx_volume`
- `sfx_cue_count`
- `sfx_cues`
- SFX 音量策略:
- 默认 `sfx_volume=0.45`
- SFX 总线增加总增益和限幅,避免“有音效但听不见”。
改动文件:
- `backend/src/live-action/live-action.dto.ts`
- `backend/src/live-action/live-action.controller.ts`
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
测试结果:
- `npm run typecheck --workspace backend`:通过。
- `npm run lint --workspace backend`:通过。
- `npm run test --workspace backend -- live-action.service.spec.ts`
- `24 passed`
- `npm run build --workspace backend`:通过。
- 后端重启并验证:
- `/api/health` 返回 `status=ok`
实测验收:
- 复用项目 `55` / 第 `41` 集《画皮:书生夜遇美人》。
- 未重新触发 Hailuo 视频生成。
- 使用参数:
- `force=true`
- `include_audio=false`
- `include_subtitle=false`
- `include_bgm=true`
- `include_sfx=true`
- `bgm_volume=0.055`
- 生成最终验证版:
- `render_asset_id=440`
- 文件:`storage/private/rendered-videos/2026-06-12/78e1b854-c177-41e9-9622-b05146933e69.mp4`
- 时长:`18.9s`
- 分辨率:`1080x1920`
- 帧率:`30fps`
- 音频:`aac / 44100Hz / stereo`
- SFX 审计:
- `render_task_id=435`
- `sfx_task_id=434`
- `sfx_asset_id=439`
- `sfx_volume=0.45`
- `sfx_cue_count=14`
- SFX 文件:`storage/private/generated-audio/2026-06-12/f5ea97b2-29d5-420d-892d-d0baeeab0b24.wav`
- 音量检测:
- 最终成片:`mean_volume=-37.7 dB``max_volume=-24.0 dB`
- SFX 源轨:`mean_volume=-35.5 dB``max_volume=-20.1 dB`
当前结论:
- 候选片段择优的后端闭环已经具备,下一步需要后台 UI 把同一 shot 的候选并排预览出来。
- SFX 音效轨已可自动生成、落库、审计、混音;对惊悚、雨夜、反转类镜头会明显提升“像真实后期”的感觉。
- 这一步仍不解决角色漂移和真人表演不自然,后续还要继续做:
- 后台候选片段并排挑选 UI。
- 角色锚点图参与关键帧/视频 prompt。
- 关键镜头候选的人工评分和失败原因回流。
- 台词镜头仅给必要镜头接 lip-sync,其他继续走旁白/字幕/中景策略。
## 2026-06-12 导演分镜 V1 / 连续剪辑优化
问题复盘:
- 《画皮:书生夜遇美人》目标时长是 `30s`,但当前实际分镜总时长只有 `18.9s`
- 当前 6 个镜头分别只有 `2.7-3.8s`,节奏更像“AI 图片快切预告”,不是“真人导演拍摄的一场戏”。
- 主要问题不是单纯 6 秒不够,而是:
- 场景跳转太大。
- 每个镜头都像独立生成。
- 缺少建立镜头、动作衔接、反应镜头、插入镜头的剪辑组合。
- 缺少 eyeline / match-on-action / sound bridge 一类连续剪辑信息。
完成内容:
- 新增导演分镜计划:
- `LIVE_ACTION_DIRECTOR_PLAN_VERSION=live-action-director-plan-v1`
- 每个镜头自动标记:
- `establishing`
- `movement`
- `dialogue`
- `reaction`
- `insert`
- `reveal`
- 真人分镜准备阶段新增目标时长分配:
-`episode.target_duration` 分配镜头时长。
- 单镜头限制在 `2.5-8s`
- 建立镜头、对白镜头、揭示镜头权重更高。
- 插入镜头、反应镜头相对更短。
- 对 episode 41 的 6 镜头测试数据,导演分镜计划会把总时长分配到 `30s`,不是旧版 `18.9s`
- 新增连续剪辑字段进入生成提示词:
- `scene_group_id`
- `shot_role`
- `shot_size`
- `blocking`
- `continuity_in`
- `continuity_out`
- `edit_intent`
- `sound_bridge`
- Prompt Builder 升级:
- Hailuo 中文 prompt 中加入:
- `导演分镜`
- `剪辑目的`
- `连续性`
- `声音桥`
- `场景组`
- 英文/generic prompt 中加入:
- director beat
- editing intent
- continuity in/out
- sound bridge
- negative prompt 增加:
- `montage slideshow look`
- `unmotivated time jump`
- `new location jump cut`
- `prepareLiveActionShots(force=true)` 会写入更强的:
- `duration`
- `actor_action`
- `camera_instruction`
- `performance_instruction`
- `live_action_desc`
- `video_prompt`
- 导演分镜重写时会清空旧的 `video_clip_asset_id`,避免新分镜继续误用旧短片。
- 真人视频生成阶段新增 active clip 复用保护:
- 只复用当前 shot 绑定的 `video_clip_asset_id`
- 只复用时长仍匹配当前分镜目标时长的片段。
- 如果旧片段只有约 `3s`、新导演分镜要求 `5-8s`,会强制重新生成,不再混入旧素材。
改动文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/prompt-builder.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `backend/src/live-action/prompt-builder.service.spec.ts`
- `CODEX_PROGRESS.md`
测试结果:
- `npm run typecheck --workspace backend`:通过。
- `npm run lint --workspace backend`:通过。
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
- `28 passed`
- `npm run build --workspace backend`:通过。
- 后端重启并验证:
- `/api/health` 返回 `status=ok`
注意事项:
- 没有直接把现有《画皮》旧素材重合成为 `30s`
- 原因:
- 旧 Hailuo 视频片段本身只有约 `3s` 一条。
- 只改分镜目标时长、不重新生成视频,会造成素材时长和目标时长不一致。
- 正确验证方式是:下一条真实小样先重新执行 `prepareLiveActionShots(force=true)`,再按新时长重新生成视频片段。
下一步建议:
- 用《画皮》或新的 30 秒测试集重新跑一版真实 Provider:
- 2 个场景以内。
- 6-8 个镜头。
- 总时长严格接近 `30s`
- 每个镜头都带导演分镜计划。
- 后台增加导演分镜审计视图:
- 显示 shot_role、duration、continuity_in/out、edit_intent、sound_bridge。
- 后续继续做:
- 角色锚点图参与关键帧。
- 候选片段并排挑选 UI。
- 真实 SFX 素材库替换当前系统合成音效。
## 2026-06-12 《画皮》导演分镜版 30 秒真实 Hailuo 小样
完成时间:
2026-06-12 20:05 Asia/Shanghai
目标:
- 继续使用公版《聊斋志异·画皮》,但不沿用旧版“夜巷 -> 街市 -> 书斋”跨场景快切结构。
- 新版只做一场戏:王生深夜隔窗窥见画皮真相。
- 验证:
- 导演分镜 V1
- Hailuo 图生视频
- FFmpeg 自动裁切
- MiniMax TTS
- 字幕
- BGM
- SFX 音效轨
- 质检任务化闭环
完成内容:
- 新增测试用例:
- `storage/private/live-action-testcases/painted-skin-director-episode-001.json`
- 5 个镜头,总目标时长 `30s`
- 结构:
- 建立镜头:雨夜书斋窗外
- 窥视镜头:王生从窗缝看向屋内
- 插入镜头:铜镜、画笔、人皮轮廓暗示
- 反应镜头:王生屏息后退
- 揭示镜头:铜镜中女子发现窗外有人
- 导入新测试项目:
- `project_id=57`
- `episode_id=43`
- `shot_id=248-252`
- 执行导演分镜准备:
- 镜头时长重新分配为:
- `7.66s`
- `4.08s`
- `7.09s`
- `4.08s`
- `7.09s`
- 合计约 `30s`
- 为新项目复制并绑定旧《画皮》场景 PNG 关键帧:
- `441-445`
- 仅用于低成本验证导演分镜和后期链路,未重新生成全新导演级首帧。
- 使用真实 Hailuo 生成 5 个视频片段:
- `clip_id=44` / `asset_id=446` / `0.317 USD`
- `clip_id=45` / `asset_id=447` / `0.1902 USD`
- `clip_id=46` / `asset_id=448` / `0.317 USD`
- `clip_id=47` / `asset_id=449` / `0.1902 USD`
- `clip_id=48` / `asset_id=450` / `0.317 USD`
- 合成最终成片:
- `render_asset_id=455`
- 文件:`storage/private/rendered-videos/2026-06-12/e2cdb72c-d6d0-45e8-b3c5-ca8de2cd488d.mp4`
- `render_task_id=450`
验收结果:
- Hailuo 生成:
- 成功:`5/5`
- 失败:`0/5`
- 真实视频成本合计:`1.3314 USD`
- 最终成片规格:
- 视频:H.264
- 分辨率:`1080x1920`
- 帧率:`30fps`
- 视频时长:`30.000000s`
- 音频:AAC stereo
- 音频时长:`30.000000s`
- 文件大小:约 `11.8MB`
- 音频检测:
- `mean_volume=-19.3 dB`
- `max_volume=-2.9 dB`
- 不再是静音成片。
- 后期层:
- `audio_is_mock=false`
- `audio_provider_codes=["minimax-tts"]`
- `subtitle_cue_count=5`
- `sfx_cue_count=13`
- `include_bgm=true`
- `include_sfx=true`
- `audio_warnings=[]`
- FFmpeg 裁切:
- 5 个 Hailuo 原始片段全部按分镜目标时长裁切。
- `10.125s` 原始片段裁为约 `7.1-7.67s`
- `5.875s` 原始片段裁为约 `4.07s`
- 质检任务补跑:
- `clip_id=44``passed / 94`
- `clip_id=45``passed / 94`
- `clip_id=46``passed / 94`
- `clip_id=47``passed / 94`
- `clip_id=48``needs_retry / 72`
- 第 5 镜被 mock-qc 的恐怖/画皮关键词打低分,原因包含 `mock_quality_keyword``AUTO_REPAIR_DISABLED`
人工抽帧观感:
- 对比旧版 `18.9s` 快切,节奏明显更接近“一场戏”:
- 建立镜头 -> 窥视 -> 插入 -> 反应 -> 揭示
- 字幕、音轨、雨声、心跳和 sting 已经形成完整后期层。
- 仍未达到发布级:
- 第 2/4 镜复用了同一张窗外关键帧,画面重复感明显。
- 第 3/5 镜复用了同一张揭示关键帧,结尾缺少真正“镜中抬眼”的新动作起点。
- 关键帧不是为新版 5 镜专门生成,所以视频仍像“旧素材重新导演剪辑”,不是完整专业拍摄。
- 第 5 镜需要人工看画面决定是否接受,当前系统质检状态是 `needs_retry`
修改文件:
- `storage/private/live-action-testcases/painted-skin-director-episode-001.json`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `jq empty storage/private/live-action-testcases/painted-skin-director-episode-001.json`:通过。
- `npm run live-action:testcase:import --workspace backend -- --file=/www/wwwroot/ai/storage/private/live-action-testcases/painted-skin-director-episode-001.json --replace=true`:通过。
- Nest ApplicationContext 调用:
- `prepareLiveActionShots(force=true)`
- 复制并绑定关键帧资产
- `preflightVideoClips`
- `generateShotVideoClip`
- `renderLiveActionEpisode`
- `executeQueuedRouterTask` 补跑质检任务
- `ffprobe`:通过,最终视频/音频均为 `30s`
- `ffmpeg volumedetect`:通过,非静音。
- `npm run typecheck --workspace backend`:通过。
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
- `28 passed`
- `npm run lint --workspace backend`:通过。
- `npm run build --workspace backend`:通过。
- `/api/health`:返回 `status=ok`
当前结论:
- “继续用画皮”是合适的,因为它能稳定暴露古风真人短剧的关键问题:角色、场景、镜头连续性、惊悚后期和揭示镜头质量。
- 导演分镜 V1 有效,30 秒成片节奏比旧快切版更顺。
- 但这版不能算最终 PASS,原因不是 Hailuo 接入失败,而是关键帧不够精细:
- 必须为每个镜头单独生成“导演级场景首帧”。
- 不能复用同一张关键帧承担不同剪辑功能。
下一步建议:
- 继续围绕《画皮》做“导演级关键帧 V1”:
-`248-252` 每个镜头重新生成专属首帧。
- 第 5 镜单独生成“铜镜中女子抬眼”的首帧。
- 再只重跑第 2/4/5 镜,先不全片重跑。
- 后台增加关键帧验收:每个镜头生成视频前先人工确认首帧是否符合导演分镜。
## 2026-06-12 《画皮》导演级关键帧 V1 / 局部重跑
完成时间:
2026-06-12 20:25 Asia/Shanghai
目标:
- 继续优化 `project_id=57` / `episode_id=43` 的《画皮:书斋窥真》导演分镜版。
- 不全片重跑,只针对上一版问题最明显的镜头重新生成导演级首帧并重跑:
- 第 2 镜:窗缝窥看
- 第 4 镜:王生反应
- 第 5 镜:铜镜回望反转
- 验证是否能降低“复用旧关键帧导致的重复镜头感”。
完成内容:
- 使用 `imagegen` 生成 3 张新 PNG 首帧:
- 第 2 镜:over-the-shoulder 窗缝窥看,明确王生视线和屋内女子空间关系。
- 第 4 镜:王生中近景反应,独立于第 2 镜,不再复用同构窗外画面。
- 第 5 镜:铜镜中女子抬眼回望,作为真正的结尾反转首帧。
- 上传并绑定新关键帧:
- `shot_id=249` -> `asset_id=456`
- `shot_id=251` -> `asset_id=457`
- `shot_id=252` -> `asset_id=458`
- 只重跑 3 条 Hailuo 真实片段:
- `shot_id=249` -> `clip_id=49` / `asset_id=459` / `0.1902 USD`
- `shot_id=251` -> `clip_id=50` / `asset_id=460` / `0.1902 USD`
- `shot_id=252` -> `clip_id=51` / `asset_id=461` / `0.317 USD`
- 新增真实视频成本:
- `0.6974 USD`
- 重新合成最终成片:
- `render_asset_id=466`
- 文件:`storage/private/rendered-videos/2026-06-12/5785a058-7ebf-423f-8822-80c3ce4bdcdc.mp4`
- `render_task_id=461`
验收结果:
- 最终成片规格:
- 视频:H.264
- 分辨率:`1080x1920`
- 帧率:`30fps`
- 视频时长:`30.000000s`
- 音频:AAC stereo
- 音频时长:`30.000000s`
- 文件大小:约 `12MB`
- 音频检测:
- `mean_volume=-19.5 dB`
- `max_volume=-1.4 dB`
- 音轨正常,非静音。
- 质检结果:
- `clip_id=49``passed / 94`
- `clip_id=50``passed / 94`
- `clip_id=51``needs_retry / 72`
- 第 5 镜仍被 mock-qc 按“画皮/揭示”关键词打低分,当前不自动重跑,等待人工看画面决定。
- FFmpeg 裁切:
- 新片段均按业务分镜时长裁切:
- 第 2 镜:`5.875s -> 4.067s`
- 第 4 镜:`5.875s -> 4.067s`
- 第 5 镜:`10.125s -> 7.1s`
人工抽帧观感:
- 明显改善:
- 第 2 镜和第 4 镜不再是同一张窗外窥视图的重复。
- 第 2 镜承担“视线关系 / 王生看见屋内”的功能。
- 第 4 镜承担“王生反应 / 控制恐惧”的功能。
- 第 5 镜变成真正的“镜中凝视 / 被发现”反转镜头。
- 仍未达到最终发布级:
- 第 3 镜仍沿用旧“贴脸画皮”图,和新版第 5 镜空间衔接略硬。
- 第 3 镜应该改成真正的插入特写:画笔、铜镜边缘、苍白纸/面皮轮廓、女子手部,而不是人物正面恐怖动作。
- 第 5 镜质检状态仍是 `needs_retry`,需要人工观看实际视频后决定是否接受或再生成 1 条候选。
新增 / 变更资产:
- 新关键帧:
- `456``local://image/2026-06-12/1c4de6c5-a187-43e0-baa2-8d0f52d799eb.png`
- `457``local://image/2026-06-12/de392947-fc73-4ad4-b8cc-0f96cdfe8548.png`
- `458``local://image/2026-06-12/acd2eea1-094a-4ab4-a5a7-2dda68e7fe16.png`
- 新视频片段:
- `459`
- `460`
- `461`
- 新最终成片:
- `466`
修改文件:
- `CODEX_PROGRESS.md`
运行 / 验证:
- `ffprobe`:通过,最终视频/音频均为 `30s`
- `ffmpeg volumedetect`:通过,非静音。
- 抽帧接触图:
- `/tmp/painted-skin-director/final-asset-466/contact.jpg`
- `/tmp/painted-skin-director/final-asset-466/frame-27s.jpg`
当前结论:
- “导演级首帧”方向是有效的。
- 后续系统不应该只写 prompt 后直接生成视频,而应该多一步:
- 分镜角色:establishing / POV / insert / reaction / reveal
- 每种角色生成对应首帧
- 首帧人工确认
- 再进入 Hailuo / Kling 视频生成
- 下一步最适合补第 3 镜“插入特写首帧”,只重跑第 3 镜和最终合成,不全片重跑。
## 2026-06-12 法相天地 10 秒爆点样片 / Hailuo 真实生成
完成时间:
2026-06-12 20:55 Asia/Shanghai
背景:
- 用户暂停《画皮》优化,要求按提供的“法相天地三段分镜提示词”做一条 10 秒样片,对比抖音强视觉爆点效果。
- 本轮不做剧情完整性,只验证:
- 强动作
- 强运镜
- 仙侠 VFX
- 音效冲击
- Hailuo 对高价值爆点镜头的表现
完成内容:
- 新增法相天地测试用例:
- `storage/private/live-action-testcases/faxiang-tiandi-episode-001.json`
- 项目名:`法相天地:千臂法身`
- `project_id=58`
- `episode_id=44`
- 镜头:
- `shot_id=253`:浴血惊鸿,`3s`
- `shot_id=254`:繁花结印,`3s`
- `shot_id=255`:法身降临,`4s`
- 生成 3 张专属关键帧:
- 浴血落地
- 手部结印 + 紫色光球
- 低机位千臂法身
- 上传并绑定关键帧:
- `asset_id=467`
- `asset_id=468`
- `asset_id=469`
- 扩展真人后期 SFX 规则:
- 新增 `wind`
- 新增 `debris`
- 新增 `electric`
- 新增 `impact`
- 用于法相、灵力、电流、碎石、轰鸣、低频冲击类镜头。
- 使用真实 Hailuo 生成 3 条视频片段:
- `clip_id=52` / `asset_id=470` / `0.1902 USD`
- `clip_id=53` / `asset_id=471` / `0.1902 USD`
- `clip_id=54` / `asset_id=472` / `0.1902 USD`
- 第一次合成:
- `asset_id=475`
- 文件:`storage/private/rendered-videos/2026-06-12/36971308-23f7-4bc8-8db5-dfb3a8be8484.mp4`
- 因音效电平偏弱,未重跑 Hailuo,只重新合成更大声 SFX/BGM 版:
- `asset_id=478`
- 文件:`storage/private/rendered-videos/2026-06-12/84977037-fe9b-4211-8e7e-c92a63de2d9b.mp4`
验收结果:
- Hailuo 生成:
- 成功:`3/3`
- 失败:`0`
- 真实视频成本:`0.5706 USD`
- 质检:
- `clip_id=52``passed / 94`
- `clip_id=53``passed / 94`
- `clip_id=54``passed / 94`
- 最终成片规格:
- 分辨率:`1080x1920`
- 帧率:`30fps`
- 时长:`10.000000s`
- 视频编码:H.264
- 音频编码:AAC
- 字幕:无
- TTS:无
- BGM:有
- SFX:有
- FFmpeg 裁切:
- 3 条 Hailuo 原始片段均约 `5.875s`
- 分别裁切到 `3s / 3s / 4s`
- SFX
- 生成 `15` 个音效点。
- 包含:
- `wind`
- `debris`
- `electric`
- `impact`
- `heartbeat`
- `sting`
- 音量检测:
- 第一版 `asset_id=475`
- `mean_volume=-28.8 dB`
- `max_volume=-16.9 dB`
- 增强版 `asset_id=478`
- `mean_volume=-25.2 dB`
- `max_volume=-12.6 dB`
人工抽帧观感:
- 整体比《画皮》更接近抖音爆点视频。
- 第 3 镜“法身降临”效果最好:
- 低机位仰拍成立。
- 千臂法身规模感明显。
- 白裙女仙和巨大法身的比例关系有压迫感。
- 第 2 镜“繁花结印”稳定:
- 手部和紫色光球清晰。
- 适合做中段能量聚集。
- 第 1 镜“浴血惊鸿”首帧强,但后续仍需人工看完整视频判断动作幅度:
- 如果动作偏小,下一步只重跑第 1 镜,生成 2 条候选,选落地/推眼动作更强的一条。
- 当前仍未达到商业发布级的原因:
- 系统合成 SFX 不如真实商业音效库炸裂。
- 三镜之间仍偏“高级概念镜头拼接”,还不是完整武指/剪辑师调过的动作连续段。
- Hailuo 对复杂千臂法身能保住大画面,但细看手臂细节可能仍有 AI 感。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `storage/private/live-action-testcases/faxiang-tiandi-episode-001.json`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `jq empty storage/private/live-action-testcases/faxiang-tiandi-episode-001.json`:通过。
- `npm run test --workspace backend -- live-action.service.spec.ts`
- `27 passed`
- `npm run typecheck --workspace backend`:通过。
- `npm run lint --workspace backend`:通过。
- `npm run build --workspace backend`:通过。
- `ffprobe`:通过,最终视频/音频均为 `10s`
- `ffmpeg volumedetect`:通过,非静音。
- 抽帧接触图:
- `/tmp/faxiang-tiandi/final-asset-478/contact.jpg`
- `/tmp/faxiang-tiandi/final-asset-478/frame-8_5s.jpg`
当前结论:
- 对比《画皮》,法相天地这种强 VFX 题材更容易获得“第一眼爆点”。
- 现有流水线已经能生成 10 秒高冲击仙侠样片,但要接近抖音成熟爆款,还需要:
- 关键镜头候选片段择优。
- 商业音效库 / 音乐素材库。
- Motion Director Prompt V1,把每镜内部 0-1s / 1-2s / 2-3s 动作节奏写进 prompt。
## 2026-06-12 法相天地 Motion Director Prompt V1 / 动作导演层
完成时间:
2026-06-12 21:08 Asia/Shanghai
背景:
- 用户反馈当前法相天地样片质量与抖音热门“法相天地”差距很大:
- 热门动作没有。
- 结印手法没有。
- 镜头仍偏静态概念图运动,缺少武指 / 动作导演 / 剪辑节奏。
- 公开搜索 `sholi888` / 抖音法相天地相关结果时,抖音详情页无法稳定直接观看,但能确认该类爆点视频的核心不是单纯“法相出现”,而是:
- 明确手部结印动作。
- 睁眼 / 爆光 / 抬头 / 展臂等强动作卡点。
- 低机位、快速推进、拉远显规模。
- 音效与动作同步卡点。
- 本轮不继续消耗真实 Hailuo 额度,先修系统 Prompt Engine。
完成内容:
- 在真人视频 Prompt Engine 中新增 `motion_director` 结构化组件:
- `motion_version`
- `beat_style`
- `action_technique`
- `time_beats`
- `camera_rhythm`
- `vfx_timing`
- `sound_hits`
- `negative_motion`
-`xianxia_transformation` 增加 3 类动作导演模板:
- 浴血落地 / 抬头爆眼:
- 凌空翻身落地。
- 手掌和膝盖触地。
- 碎石震开。
- 镜头极速推进到眼部。
- 繁花结印 / 紫色光球:
- 手部特写。
- 食指中指并拢交错。
- 手腕翻转。
- 拇指扣成莲花印。
- 紫色光球随第二次手印出现,最后双掌震出爆亮。
- 千臂法身 / 法相降临:
- 女仙双臂像凤凰展翅一样展开。
- 透明法身从地面升起。
- 千只巨手一层层展开并结印。
- 地裂、碎石上浮、粉化按时间递进。
- Hailuo / Kling / Generic / Mock prompt 均会输出动作导演字段。
- `negative_prompt` 自动加入动作禁忌,例如:
- `random hand waving`
- `blurred fingers`
- `static magical orb only`
- `tiny dharma body`
- `static statue behind actor`
- 修正识别优先级:
- 出现 `法相 / 法身 / 千臂 / 巨手` 时优先走“法身降临”模板。
- 避免因为“千只巨手结印”被误判为普通手部结印镜头。
修改文件:
- `backend/src/live-action/prompt-builder.service.ts`
- `backend/src/live-action/prompt-builder.service.spec.ts`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `npm run test --workspace backend -- prompt-builder.service.spec.ts`
- `4 passed`
- `npm run test --workspace backend -- live-action.service.spec.ts`
- `27 passed`
- `npm run typecheck --workspace backend`:通过。
- `npm run lint --workspace backend`:通过。
- `npm run build --workspace backend`:通过。
当前结论:
- 这轮没有重跑真实视频,没有新增 Hailuo 成本。
- 之前样片质量差的根因已定位为:
- 不是单纯 Provider 不行。
- 也不是分镜秒数问题本身。
- 而是 Prompt Engine 缺少“动作导演层”,没有把 3-4 秒内的热门动作拆成模型可执行的时间节奏。
- 下一步建议只重跑第 2 镜“繁花结印”和第 3 镜“法身降临”:
- 使用新版 Motion Director Prompt。
- 默认每镜只生成 1 条,控制成本。
- 如果仍达不到标准,再考虑关键镜头候选片段择优。
## 2026-06-12 法相天地 BGM Director V1 / 剧情驱动配乐
完成时间:
2026-06-12 21:24 Asia/Shanghai
背景:
- 用户指出当前法相天地样片缺少 BGM 音乐带来的情绪推进:
- 没有音乐,爆点效果少一半。
- BGM 需要根据剧情和镜头插入,而不是简单铺一条环境底音。
- 本轮不重跑 Hailuo 视频片段,先升级后期合成系统,并用已有真实 Hailuo 片段重新合成验证。
完成内容:
- 新增 BGM Director V1
- `LiveActionBgmCue`
- `LiveActionBgmCueType`
- `buildLiveActionBgmCues`
- `createLiveActionCueBgmTrack`
- 系统会根据分镜自动生成 BGM cue:
- `urban_drama`:普通都市剧情底乐。
- `suspense_tension`:悬疑 / 惊悚 / 高情绪张力。
- `xianxia_tension`:仙侠开场压迫、废墟、狂风、浴血。
- `xianxia_build_up`:结印、聚能、光球、电流。
- `xianxia_epic`:法相 / 法身 / 千臂 / 威压 / 史诗爆发。
- 法相天地 3 镜自动识别为:
- `0-3s``xianxia_tension`
- `3-6s``xianxia_build_up`
- `6-10s``xianxia_epic`
- `live_action_bgm_generate` 任务会记录:
- `cue_count`
- `cues`
- `bgm_source`
- `duration_seconds`
- `live_action_video_render``post_production` 审计新增:
- `bgm_cue_count`
- `bgm_cues`
- BGM / SFX 默认音量改为自动策略:
- 有对白:BGM 自动压低,避免盖住人声。
- 无对白仙侠爆点:BGM / SFX 自动提高,适合测试强视觉爆点。
- 仍保留 `bgm_volume` / `sfx_volume` 人工 override。
生成验证:
- 未重跑 Hailuo,未新增真实视频 Provider 成本。
- 用已有真实片段重新合成两版:
- `asset_id=481`
- 文件:`storage/private/rendered-videos/2026-06-12/67809a8c-3bac-44ea-9c63-d5134f9b680b.mp4`
- `bgm_volume=0.32`
- `sfx_volume=0.85`
- `mean_volume=-25.7 dB`
- `max_volume=-11.3 dB`
- `asset_id=484`
- 文件:`storage/private/rendered-videos/2026-06-12/f372bfb3-fdb4-4fee-a212-353f73d3bbf0.mp4`
- `bgm_volume=0.55`
- `sfx_volume=0.95`
- `mean_volume=-22.1 dB`
- `max_volume=-7.7 dB`
- 当前建议优先查看 `asset_id=484`,这是无对白爆点测试更接近短视频观感的一版。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
- `32 passed`
- `npm run typecheck --workspace backend`:通过。
- `npm run lint --workspace backend`:通过。
- `npm run build --workspace backend`:通过。
- `ffprobe asset_id=484`
- `10.000000s`
- `1080x1920`
- `30fps`
- `H.264 + AAC`
- `ffmpeg volumedetect asset_id=484`
- `mean_volume=-22.1 dB`
- `max_volume=-7.7 dB`
当前结论:
- 系统后期从“有无 BGM”升级为“按分镜剧情自动配乐”。
- 对法相天地这类测试片,后续不需要前端手动传音量也能获得更强的默认音乐冲击。
- 下一步可以进入低成本视频质量复测:
- 用新版 Motion Director Prompt 重跑第 1 镜 / 第 2 镜 / 第 3 镜。
- 每镜默认 1 条,继续控制成本。
- 对比 `asset_id=484` 的后期版本,看问题是否主要剩在画面动作本身。
## 2026-06-12 法相天地 Motion Director 真实重跑 / Hailuo 三镜复测
完成时间:
2026-06-12 21:36 Asia/Shanghai
背景:
- 用户确认测试优化阶段可以继续重跑,只要系统质量有进步。
- 本轮目标:
- 用新版 Motion Director Prompt 重跑第 1 / 2 / 3 镜。
- 每镜只生成 1 条,控制成本。
- 用 BGM Director V1 自动配乐重新合成。
- 检查动作导演提示词是否真实进入 Hailuo 请求。
执行内容:
- 固定真实 Provider
- `minimax_hailuo_23_fast`
- `confirm_real_video=true`
- `max_cost_per_clip=0.3`
- `candidate_count=1`
- 重跑镜头:
- 第 1 镜 `shot_id=253`:浴血惊鸿
- 第 2 镜 `shot_id=254`:繁花结印
- 第 3 镜 `shot_id=255`:法身降临
- 新生成片段:
- `clip_id=55` / `asset_id=485` / `0.1902 USD`
- `clip_id=56` / `asset_id=486` / `0.1902 USD`
- `clip_id=57` / `asset_id=487` / `0.1902 USD`
- 本轮新增真实视频成本:
- `0.5706 USD`
- 队列质检任务:
- `task_id=481`
- `task_id=483`
- `task_id=485`
- 由于 worker 未实时消费,手动通过正式 `executeQueuedRouterTask` 执行 3 个 pending 质检任务。
- 质检结果:
- `clip_id=55``passed / 94`
- `clip_id=56``passed / 94`
- `clip_id=57``passed / 94`
关键 Prompt 验收:
- 第 1 镜真实请求已包含:
- `凌空翻身`
- `手掌和膝盖触地滑停`
- `碎石被冲击震开`
- `镜头极速推进到眼部特写`
- `瞳孔金光爆亮`
- 第 2 镜真实请求已包含:
- `食指中指并拢交错`
- `手腕快速翻转`
- `拇指扣成莲花印`
- `双掌向外一震`
- `紫色光球在第二次手印后出现`
- 第 3 镜真实请求已包含:
- `女仙双臂像凤凰展翅一样猛然后扫`
- `身后千臂法身随动作拔地而起`
- `每一层巨手依次结出不同仙印`
- `地裂 / 碎石失重上浮 / 粉化三层递进`
最终成片:
- `asset_id=490`
- 文件:
- `storage/private/rendered-videos/2026-06-12/24e4df88-0041-4547-bdfd-30249093c08e.mp4`
- 规格:
- `10.000000s`
- `1080x1920`
- `30fps`
- `H.264 + AAC`
- 音量检测:
- `mean_volume=-22.1 dB`
- `max_volume=-7.7 dB`
- 后期:
- `BGM cue_count=3`
- `SFX cue_count=15`
- `bgm_volume=0.55`
- `sfx_volume=0.95`
- 裁切:
- Hailuo 原片均约 `5.875s`
- 合成时裁到 `3s / 3s / 4s`
- `trim_strategy=head`
- 抽帧接触图:
- `/tmp/faxiang-tiandi/final-asset-490/contact.jpg`
人工抽帧观感:
- 对比上一版,进步明显:
- 第 1 镜已经能看到落地、撑地、尘土和身体动作。
- 第 2 镜有清晰手部近景和结印动作构图。
- 第 3 镜法身规模、爆光和压迫感增强。
- 仍未达到顶级抖音爆款的原因:
- 手指结印虽然有构图,但是否精确到“漂亮手法”还要看完整视频动态。
- Hailuo 对复杂手部动作和千臂细节仍可能有 AI 变形风险。
- 目前还缺商业级真实音乐库 / 打击音效库,系统生成音频已经能铺情绪,但不是最终商用音效品质。
运行 / 验证:
- `git status --short`:失败,当前目录不是 Git 仓库。
- `ffprobe asset_id=490`:通过。
- `ffmpeg volumedetect asset_id=490`:通过。
- 抽帧接触图人工检查:通过。
- 目标测试在上一阶段已通过:
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
- `32 passed`
- `typecheck / lint / build` 均通过。
当前结论:
- 本轮验证 Motion Director Prompt 已真实进入 Hailuo 请求。
- 法相天地样片从“静态概念图拼接”提升到“有动作层级的爆点片段”。
- 现在最值得人工打开 `asset_id=490` 看完整动态:
- 如果第 2 镜手势动态仍不够漂亮,下一步不要继续调普通 prompt,而应做“手部结印关键帧 / 手势参考图 V1”。
- 如果第 3 镜法身动作仍不够炸,下一步考虑只给第 3 镜开候选 2 条,或等 Kling / Vidu / Wan 真实账号接入后做横向 Provider 对比。
## 2026-06-12 法相天地 10 秒一镜到底 / Hailuo 真实生成
完成时间:
2026-06-12 21:56 Asia/Shanghai
背景:
- 用户指出 3 段式法相天地仍然割裂:
- 切镜太多,像图片拼接。
- 翻滚落地、结印手法、法身爆发不够像抖音热门作品。
- Hailuo 支持 10s,不应继续把 6s 片段裁成 3s/3s/4s。
- 本轮目标:
- 把“浴血落地 -> 抬头觉醒 -> 双手结印 -> 紫色光球 -> 展臂 -> 千臂法身”压成 10 秒一镜到底。
- 验证真实 Hailuo API 是否按 10s 返回。
- 检查 Prompt Engine 是否把完整动作节奏写进请求。
代码改动:
- `backend/src/live-action/prompt-builder.service.ts`
- Hailuo 9 秒以上镜头 prompt 上限从 `1800` 提升到 `2400`
- 新增 10 秒一镜到底仙侠爆点 Motion Director
- `0.0-2.0s` 受伤落地 / 撑地 / 碎石冲击
- `2.0-3.0s` 抬头 / 眼部金光 / 快速推进
- `3.0-5.0s` 双手胸前结印 / 莲花印动作
- `5.0-6.5s` 紫色光球聚能
- `6.5-8.0s` 凤凰展臂 / 千臂法身拔地
- `8.0-10.0s` 法身完全展开 / 爆光定格
- `backend/src/live-action/prompt-builder.service.spec.ts`
- 新增 Hailuo 10 秒一镜到底 prompt 测试。
测试数据:
- 项目:
- `project_id=58`
- 新建测试集:
- `episode_id=45`
- `episode_no=2`
- 标题:`法相天地 10秒一镜到底测试`
- 新建测试镜头:
- `shot_id=256`
- `duration=10`
- `scene_type=xianxia_transformation`
- `route_tier=premium`
- `importance/emotion/action = 10/10/10`
- 关键帧:`asset_id=467`
真实 Provider 执行:
- Provider
- `minimax_hailuo_23_fast`
- `confirm_real_video=true`
- `candidate_count=1`
- `max_cost_per_clip=0.5`
- 真实片段:
- `clip_id=58`
- `output_asset_id=491`
- `provider_log.id=535`
- `request_input.duration=10`
- `response.duration=10`
- `cost_actual=0.317 USD`
- 结论:
- Hailuo 本次确实返回 10 秒视频。
- 不再发生 6 秒片段被裁成 3 秒/4 秒的问题。
质检与合成:
- 队列质检任务:
- `task_id=490`
- `live_action_video_clip_quality_check`
- 手动执行队列质检:
- `status=success`
- `quality_status=passed`
- `quality_score=94`
- `issues=[]`
- 最终成片:
- `asset_id=494`
- 文件:
- `storage/private/rendered-videos/2026-06-12/ca7b56a7-1995-4197-9dc5-ca4e45dad14a.mp4`
- 规格:
- `10.000000s`
- `1080x1920`
- `30fps`
- `H.264 + AAC`
- 裁切:
- `trimmed=false`
- `source_duration=10.125`
- `final_duration=10.134`
- `target_duration=10`
- 后期:
- `BGM cue_count=1`
- `SFX cue_count=6`
- `bgm_volume=0.55`
- `sfx_volume=0.95`
- 音量检测:
- `mean_volume=-27.2 dB`
- `max_volume=-13.9 dB`
- 抽帧接触图:
- `/tmp/faxiang-tiandi/final-asset-494/contact.jpg`
人工抽帧观感:
- 明显改善:
- 人物、服装、废墟空间在 10 秒内基本连续。
- 镜头从受伤跪地、眼部发光、手部聚能、法身爆发有完整递进。
- 千臂法身最后 2 秒的画面冲击比三段式更完整。
- 仍未达到抖音头部爆款:
- “凌空翻滚落地”被 Hailuo 弱化成跪地/滑落/撑地,缺少真正空中翻身动作。
- 结印有近景和手部动作,但还不像专业武术/舞蹈手诀。
- BGM/SFX 已进入合成,但本轮音量偏低,发布级还需要更强音乐和打击音量。
- 这说明单纯调文字 prompt 有上限;下一步若继续冲击热门质感,应加“动作参考 / 姿势关键帧 / Provider 横向对比”。
运行 / 验证:
- `git status --short`
- 失败:当前目录不是 Git 仓库。
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
- 通过:`33 passed`
- `npm run typecheck --workspace backend`
- 通过
- `npm run lint --workspace backend`
- 通过
- `npm run build --workspace backend`
- 通过
当前结论:
- 系统层面:
- 10 秒单镜头 Hailuo 流程已跑通。
- Prompt Engine 可以按 10 秒动作节奏发送真实请求。
- 真实 Provider、质检任务、FFmpeg 合成、音效轨、审计记录均可闭环。
- 质量层面:
- 10 秒一镜到底方向比 3 段裁切更适合法相天地这类爆点镜头。
- 但 Hailuo 对“凌空翻滚 + 精准结印 + 巨型法身复杂动作”的可控性仍不足。
- 后续不建议继续无脑烧 Hailuo 多次重跑;更优先做动作/姿势参考输入和 Kling/Vidu/Wan 横向 Provider 小样。
## 2026-06-12 后台 AI 平台 10 秒成本展示
完成时间:
2026-06-12 22:15 Asia/Shanghai
背景:
- 用户希望后台 AI 平台接入列表能直接展示各平台成本,按视频生产常用口径换算为“每 10 秒多少钱”。
- 当前系统已有 `cost_rule_json`,但运营需要看 JSON 或只看到单次/当日阈值,不方便比较 Hailuo / Seedance / Kling / Wan / Vidu。
完成内容:
- 后端 Provider 安全返回结构新增 `cost_summary`
- `estimated_cost_10s_label`
- `estimated_cost_10s / min / max`
- `currency`
- `price_per_second`
- `max_cost_per_call`
- `daily_cost_limit`
- `pricing_basis`
- `needs_manual_pricing`
- `note`
- `price_per_second=0` 不再被当作免费:
- 视为未回填正式账单价。
- 可使用展示估算价,但会标记 `needs_manual_pricing=true`
- 后台页面:
- “AI 平台入口”费用提醒列新增主成本展示。
- “AI 接入列表”新增“10秒成本”列。
- 成本单元格使用换行样式,避免 PC/H5 表格中文字和按钮挤压重叠。
当前抽样成本展示:
- `minimax_hailuo_23_fast`
- `10秒约 $0.3170`
- `minimax_hailuo_23`
- `10秒约 $0.4670`
- `alibaba_wan26_i2v_flash`
- `10秒约 $0.2150`
- `vidu_q3_turbo_reference`
- `10秒约 $0.5000`
- `kling-image-to-video`
- `10秒约 $0.7500`
- 显示估算,需开通后用实际账单回填。
- `jimeng_seedance`
- `10秒约 ¥1.72-¥3.46`
- 显示估算,需开通后用实际账单回填。
改动文件:
- `backend/src/providers/provider.types.ts`
- `backend/src/providers/providers.service.spec.ts`
- `admin/src/App.vue`
- `admin/src/styles.css`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`
- 失败:当前目录不是 Git 仓库。
- `npm run test --workspace backend -- providers.service.spec.ts`
- 通过:`35 passed`
- `npm run typecheck --workspace backend`
- 通过
- `npm run lint --workspace backend`
- 通过
- `npm run build --workspace backend`
- 通过
- `npm run build --workspace admin`
- 通过
- 数据库抽样脚本确认 Provider 成本摘要可正常生成。
当前结论:
- 后台已经可以按“每 10 秒多少钱”查看视频 Provider 成本。
- 后续开通 Kling / Seedance / Runway 等账号后,只需要把 `cost_rule_json.price_per_second` 或 10 秒估算字段回填,后台会自动更新展示。
- Router 后续也可以直接复用 `cost_summary` 做预算路由、降级和成本审计展示。
## 2026-06-12 AI 视频测试踩坑记录 V1
完成时间:
2026-06-12 22:25 Asia/Shanghai
背景:
- 用户确认当前仍是测试阶段,核心不是马上上线,而是把真人/漫剧视频流水线磨合好。
- 前面已遇到多类问题:
- Hailuo 对复杂修仙动作、凌空翻滚、精准结印控制不足。
- 3 秒碎切导致镜头像图片拼接,缺少电影感。
- 无声音、无字幕、无 BGM 的样片不可发布。
- 正脸台词无 lip-sync 时容易嘴型错位。
- mock-qc 分数不能代表真实人工观感。
- 成本必须按 10 秒、Provider、候选数进行前置估算。
- 需要形成长期记录,后续接入 Kling / Seedance / Wan / Vidu / Runway / Veo 时避免重复踩坑。
完成内容:
- 新增根目录测试手册:
- `AI_VIDEO_TEST_LESSONS.md`
- 内容覆盖:
- 当前阶段定位。
- Hailuo 已验证适用场景。
- Hailuo 不适合硬扛的镜头。
- 分镜时长经验。
- 10 秒一镜到底结论。
- Prompt Engine 经验。
- 角色锚点/定妆图经验。
- BGM/SFX/字幕经验。
- lip-sync 策略。
- 成本控制策略。
- Provider Router 经验。
- 新 Provider 准入测试标准。
- 人工验收标准。
- 不要重复踩的坑。
- 下一步建议。
关键沉淀:
- Hailuo 做低成本都市量产,不再默认硬扛法相/打斗/复杂手诀。
- 复杂动作失败 1-2 次后,优先切 Provider 或补动作参考/姿势关键帧,不继续无脑烧钱。
- 复杂动作/爆点镜头优先 8-10 秒一镜到底,普通都市镜头可 5-6 秒。
- 没有声音、字幕、BGM 的视频判定为失败。
- 无 lip-sync Provider 时,正脸台词自动改中景/旁白/字幕/轻口型。
- 候选片段默认 1 条,只有封面级/爆点/人工验收才允许 2 条。
- 新 Provider 必须用同一项目、同一角色锚点、同一关键帧、同一镜头横向测试。
改动文件:
- `AI_VIDEO_TEST_LESSONS.md`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`
- 失败:当前目录不是 Git 仓库。
- 本次仅新增/更新 Markdown 测试记录,没有改动业务代码,未重新运行 lint/typecheck/test。
当前结论:
- 测试阶段经验已形成可复用记录。
- 后续每接一个新 AI 视频平台,都应该按 `AI_VIDEO_TEST_LESSONS.md` 的 Provider 准入测试标准记录质量、成本、失败率和人工观感。
## 2026-06-13 都市退婚神豪短剧 5x10 秒导演版测试用例
完成时间:
2026-06-13 14:35 Asia/Shanghai
背景:
- 用户提供《被未婚妻退婚后,我成了首富》第一季和第 1 集设定。
- 用户明确要求:
- 要连贯性,不要一个个突破拼接。
- 看起来像真人拍摄。
- 有专业运镜、专业剪辑、专业配音、高潮 BGM。
- Hailuo 只有 6s 或 10s,因此按 10s 每镜设计。
完成内容:
- 新增测试用例:
- `storage/private/live-action-testcases/urban-heir-engagement-director-episode-001.json`
- 结构:
- 5 个导演长镜头。
- 每镜固定 `10s`
- 总时长 `50s`
- 场景只保留两个场景组:
- 酒店订婚宴会厅。
- 酒店外雨夜街道。
- 5 个镜头:
- 镜头 1:订婚宴开场到林雨薇挽周浩入场。
- 镜头 2:林雨薇当众退婚。
- 镜头 3:周浩羞辱与顾辰沉默。
- 镜头 4:顾辰雨夜离场。
- 镜头 5:劳斯莱斯与顾氏继承权反转。
系统优化:
- 后端真人导演计划上限从 `8s` 调整为 `10s`
- `LIVE_ACTION_DIRECTOR_MAX_SHOT_SECONDS = 10`
- 导演时长分配规则支持 5 个 10 秒镜头完整保留。
- 新增都市高潮 BGM 类型:
- `urban_climax`
- 用于退婚、羞辱、打脸、首富、继承权、黑金卡、劳斯莱斯等短剧高潮段落。
- 修复镜头类型误判:
- 原规则中只要出现“手”就会误判为 `insert`,导致“手里的戒指盒”被压成 5 秒。
- 已改为只有“手部/手指/手掌/手腕/手势”等明确手部特写词才算 `insert`
- 台词镜头优先判定为 `dialogue`,避免“避免嘴部特写”里的“特写”把镜头误判为 `insert`
导入结果:
- 已导入后台项目:
- `project_id=61`
- `episode_id=48`
- 分镜:
- `shot_id=262` / 镜头 1 / `10s`
- `shot_id=263` / 镜头 2 / `10s`
- `shot_id=264` / 镜头 3 / `10s`
- `shot_id=265` / 镜头 4 / `10s`
- `shot_id=266` / 镜头 5 / `10s`
- 已执行 `prepareLiveActionShots`
- 5 个镜头均为 `video_status=prepared`
- 5 个镜头均保留 `duration=10`
- 5 个镜头 Prompt 均包含 `10秒`
Hailuo Fast 成本预估:
- Provider
- `minimax_hailuo_23_fast`
- 总镜头数:
- `5`
- 总时长:
- `50s`
- 每镜:
- `10s`
- 每镜预估:
- `$0.317`
- 总预估:
- `$1.585`
踩坑记录同步:
- 已更新 `AI_VIDEO_TEST_LESSONS.md`
- 新增 Hailuo 时长设计规则。
- 明确真人短剧主流程优先按 10 秒长镜头设计。
- 明确 prepare 阶段不得把 10 秒镜头压缩成 5 秒或 8 秒。
- 明确负面约束和“手里的道具”不能误触 insert 特写。
改动文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `storage/private/live-action-testcases/urban-heir-engagement-director-episode-001.json`
- `AI_VIDEO_TEST_LESSONS.md`
- `CODEX_PROGRESS.md`
运行 / 验证:
- `git status --short`
- 失败:当前目录不是 Git 仓库。
- JSON 校验:
- 通过,5 镜共 `50s`
- `npm run test --workspace backend -- live-action.service.spec.ts`
- 通过:`29 passed`
- `npm run typecheck --workspace backend`
- 通过
- `npm run lint --workspace backend`
- 通过
- `npm run build --workspace backend`
- 通过
- 导入测试用例:
- 通过
- prepare 真人镜头:
- 通过,5 个镜头全部保持 10 秒。
当前结论:
- 这集已经按 Hailuo 真实 10 秒规格重排成导演连续版。
- 当前尚未调用真实 Hailuo 生成视频,避免直接扣费。
- 下一步如果用户确认,可以先跑 Mock 全流程,再选择是否用 Hailuo Fast 跑 5 条真实 10 秒小样。
## 2026-06-13 都市退婚神豪短剧 Mock 全链路验收
完成时间:
2026-06-13 14:40 Asia/Shanghai
背景:
- 用户要求继续推进上一步 5x10 秒导演版测试。
- 本轮目标不是评价真实 Hailuo 画面质量,而是验证:
- 5 个 10 秒长镜头是否能完整进入生成链路。
- 关键帧、Mock 视频片段、TTS、字幕、BGM、SFX、最终合成是否完整落库。
- 后台预览资产是否存在,避免再次出现文件不存在类问题。
执行对象:
- `project_id=61`
- `episode_id=48`
- `shot_id=262-266`
执行流程:
1. `preflightVideoClips`
- 初始结果:未就绪。
- 阻断原因:5 个镜头均缺关键帧。
- 统计:
- `shot_count=5`
- `prepared_shot_count=5`
- `keyframe_count=0`
- `provider_clip_count=5`
- `total_seconds=50`
2. `generateKeyframes`
- 生成关键帧资产:5 个。
3. 再次 `preflightVideoClips`
- 结果:就绪。
- 阻断项:0。
- 统计:
- `keyframe_count=5`
- `provider_clip_count=5`
- `total_seconds=50`
4. `generateVideoClips`
- Provider`mock-video`
- 生成片段:
- clip `59` / shot `262` / asset `500` / `10s`
- clip `60` / shot `263` / asset `501` / `10s`
- clip `61` / shot `264` / asset `502` / `10s`
- clip `62` / shot `265` / asset `503` / `10s`
- clip `63` / shot `266` / asset `504` / `10s`
- 真实视频费用:`0`
5. `renderLiveActionEpisode`
- `include_audio=true`
- `include_subtitle=true`
- `include_bgm=true`
- `include_sfx=true`
- `include_lip_sync=false`
输出资产:
- 对白/TTS 混音:
- asset `505`
- `local://generated-audio/2026-06-13/d6b4f222-a5f5-4619-9851-762c2fe03f47.wav`
- `duration=49.55s`
- `status=active`
- 字幕:
- asset `506`
- `local://generated-subtitles/2026-06-13/7acf1a1b-81bc-4daf-bd8d-2dbc31484843.srt`
- `duration=50s`
- `status=active`
- BGM
- asset `507`
- `local://generated-audio/2026-06-13/82bc90e6-0959-4ec2-8c0b-bed3bfd46a68.wav`
- `duration=50s`
- `status=active`
- SFX
- asset `508`
- `local://generated-audio/2026-06-13/37b8e5d6-9729-4cc3-8b1c-b1b3b6f22e2c.wav`
- `duration=50s`
- `status=active`
- 最终成片:
- asset `509`
- `local://rendered-videos/2026-06-13/c7163cfe-0be3-4014-baad-1fe81eacb586.mp4`
- `duration=50s`
- `size=2130857`
- `status=mock`
后期策略记录:
- BGM cue
- 5 个镜头均生成 BGM cue。
- 镜头 1、2、3、5 使用 `urban_climax`
- 镜头 4 使用 `suspense_tension`
- `bgm_volume=0.14`
- SFX cue
-`22` 个。
- 包含 `rain``footstep``door``heartbeat``sting``impact`
- `sfx_volume=0.45`
- 字幕 cue
-`5` 个。
- lip-sync
- 本轮关闭真实 lip-sync。
- 策略记录中 `required_count=2`,但 `lip_sync_clip_count=0`
- 代表系统能识别关键台词镜头,但当前按“中景轻口型 + TTS + 字幕”降级。
FFprobe 验证:
- 文件:
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/c7163cfe-0be3-4014-baad-1fe81eacb586.mp4`
- 视频流:
- `h264`
- `1080x1920`
- `50.000000s`
- 音频流:
- `aac`
- `50.000000s`
- 音量:
- `mean_volume=-18.8 dB`
- `max_volume=-1.2 dB`
- 抽帧联系表:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-mock-asset-509-contact.jpg`
重要发现:
- 本轮没有调用真实 Hailuo,真实视频费用为 `0`
- 但音频链路使用了已配置并启用的 `minimax-tts`,因此严格意义上不是“全零成本 Mock”。
- 这对发布级验收是好事,因为可以顺便验证真实 TTS、字幕、BGM、SFX 混音。
- 如果后续只想做零成本流程测试,应显式指定 `voice_provider_code=mock-voice` 或关闭 `include_audio`
当前结论:
- 5x10 秒导演版 Mock 全链路已跑通。
- 关键帧、视频片段、音频、字幕、BGM、SFX、最终成片均已落库。
- 成片存在可预览文件,不存在 `ENOENT` 类文件缺失问题。
- Mock 画面是占位色块,只能证明流程,不能代表真实画面质量。
- 下一步适合用这 5 个镜头跑真实 Hailuo Fast,验收真人画面连贯性、角色一致性和真实镜头观感。
## 2026-06-13 都市退婚神豪短剧 Hailuo 真实 5x10 秒小样
完成时间:
2026-06-13 17:30 Asia/Shanghai
背景:
- 用户确认下一步跑真实 Hailuo 5 条 10 秒镜头。
- 目标:
- 验证真实 Hailuo Fast 是否能按 10 秒镜头跑通。
- 验证真实片段能否进入后期合成。
- 初步判断真人画面、镜头连贯、角色一致性。
真实 Provider 前置检查:
- Provider
- `minimax_hailuo_23_fast`
- 模式:`real`
- 状态:启用
- 初次 preflight 结果:
- 未通过。
- 原因:5 个关键帧均为 Mock SVG。
- 阻断码:`LIVE_ACTION_KEYFRAME_RASTER_REQUIRED`
- 结论:真实视频 Provider 必须使用 PNG/JPG/WebP,不能把 Mock SVG 发给 Hailuo。
临时真人关键帧处理:
- 使用 `imagegen` 生成 5 张真人摄影风关键帧。
- 统一转为 `1080x1920 PNG`
- 本地目录:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-keyframes-normalized/`
- 联系表:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-keyframes/contact.jpg`
- 绑定资产:
- shot `262` -> keyframe asset `510`
- shot `263` -> keyframe asset `511`
- shot `264` -> keyframe asset `512`
- shot `265` -> keyframe asset `513`
- shot `266` -> keyframe asset `514`
- 再次 preflight
- 通过。
- `raster_keyframe_count=5`
- `provider_clip_count=5`
- `total_seconds=50`
- `estimated_cost=$1.585`
Hailuo 真实生成结果:
- 开始:
- `2026-06-13T09:18:15.268Z`
- 完成:
- `2026-06-13T09:27:18.180Z`
- 总耗时:
- 约 9 分钟
- 生成方式:
- 5 条顺序生成。
- 每条 `10s`
- `candidate_count=1`,未生成候选,避免成本翻倍。
- 片段:
- clip `64` / shot `262` / asset `515` / cost `$0.317`
- clip `65` / shot `263` / asset `516` / cost `$0.317`
- clip `66` / shot `264` / asset `517` / cost `$0.317`
- clip `67` / shot `265` / asset `518` / cost `$0.317`
- clip `68` / shot `266` / asset `519` / cost `$0.317`
- 总成本记录:
- `$1.585`
真实成片合成结果:
- 成片 asset
- `524`
- 文件:
- `local://rendered-videos/2026-06-13/d5a3f566-48fe-4f67-a5d7-4e6929e9eba5.mp4`
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/d5a3f566-48fe-4f67-a5d7-4e6929e9eba5.mp4`
- 状态:
- `active`
- 时长:
- `50s`
- 大小:
- `26412374`
- 后期资产:
- TTS/audio asset `520`
- subtitle asset `521`
- BGM asset `522`
- SFX asset `523`
- render task
- `518`
- status `success`
FFprobe 验证:
- 视频:
- `h264`
- `1080x1920`
- `50.000000s`
- 音频:
- `aac`
- `50.000000s`
- 音量:
- `mean_volume=-18.9 dB`
- `max_volume=-2.3 dB`
抽帧验收文件:
- 5 秒间隔联系表:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-hailuo-asset-524/contact.jpg`
- 2 秒间隔联系表:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-hailuo-asset-524/contact-2s.jpg`
初步人工观感:
- 明显优于 Mock 和之前碎切测试。
- Hailuo 在都市酒店、雨夜、车灯、人物中景上表现可用。
- 5x10 秒长镜头比 3-6 秒碎切更像短剧段落。
- 字幕、TTS、BGM、SFX 均进入成片。
- 仍存在生产级问题:
- 男主在室内和雨夜之间脸有漂移。
- 部分镜头更像关键帧慢推,表演调度还不够“真实拍摄”。
- 台词镜头仍依赖 TTS + 字幕,口型不做强同步。
- 第 4/5 镜头画面质感较好,但角色锚点还不够稳。
当前结论:
- Hailuo Fast 真实 5x10 秒都市短剧链路已跑通。
- 技术链路 PASS
- raster keyframe -> Hailuo -> 视频片段落库 -> FFmpeg 合成 -> 字幕/TTS/BGM/SFX -> active 成片。
- 质量链路进入下一轮:
- 需要“角色锚点图 / 同脸参考 / 定妆图 V1”。
- 需要把关键帧生成也纳入系统 Provider,而不是临时手动生成。
- 需要后台把真实 Provider 耗时、成本、关键帧类型、人工观感评分记录到审计页。
## 2026-06-13 角色锚点图 / 定妆图 V1 与 1/3/5 镜重跑
完成时间:
2026-06-13 18:50 Asia/Shanghai
背景:
- 用户确认下一步做“角色锚点图 / 定妆图 V1”。
- 目标:
- 固定顾辰、林雨薇、周浩、老管家四个角色的脸、服装、年龄气质。
- 写入系统 `actor_profiles`
- 用锚点图约束重做第 1、3、5 镜关键帧。
- 只重跑第 1、3、5 镜 Hailuo,避免全片重复烧成本。
锚点图生成:
- 使用 `imagegen` 生成 4 张角色半身定妆图。
- 角色:
- 顾辰
- 林雨薇
- 周浩
- 老管家
- 本地目录:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-actor-anchors/`
- 联系表:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-actor-anchors/contact.jpg`
锚点资产落库:
- 顾辰:
- actor_profile `27`
- character `99`
- anchor asset `525`
- 林雨薇:
- actor_profile `28`
- character `100`
- anchor asset `526`
- 周浩:
- actor_profile `29`
- character `101`
- anchor asset `527`
- 老管家:
- actor_profile `31`
- character `103`
- anchor asset `528`
- 已写入:
- `actor_profiles.anchor_asset_id`
- `actor_profiles.reference_asset_ids`
- `characters.anchor_asset_id`
- 锚点角色状态:
- `status=locked`
锚点关键帧重做:
- 重做镜头:
- shot `262` / 镜头 1
- shot `264` / 镜头 3
- shot `266` / 镜头 5
- 本地目录:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-keyframes/`
- 归一化目录:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-keyframes-normalized/`
- 联系表:
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-keyframes/contact.jpg`
- 绑定资产:
- shot `262` -> keyframe asset `529`
- shot `264` -> keyframe asset `530`
- shot `266` -> keyframe asset `531`
- preflight
- 3 个镜头均通过。
- 每镜 `10s`
- 每镜预估 `$0.317`
- 本轮预计 `$0.951`
Hailuo 真实重跑:
- 重跑镜头:
- 第 1、3、5 镜。
- Provider
- `minimax_hailuo_23_fast`
- 生成结果:
- clip `69` / shot `262` / input asset `529` / output asset `532` / cost `$0.317`
- clip `70` / shot `264` / input asset `530` / output asset `533` / cost `$0.317`
- clip `71` / shot `266` / input asset `531` / output asset `534` / cost `$0.317`
- 本轮真实视频成本:
- `$0.951`
- 生成耗时:
- `2026-06-13T10:42:14.256Z``2026-06-13T10:47:30.345Z`
- 约 5 分 16 秒
锚点增强版成片:
- 使用:
- 新第 1 镜 asset `532`
- 旧第 2 镜 asset `516`
- 新第 3 镜 asset `533`
- 旧第 4 镜 asset `518`
- 新第 5 镜 asset `534`
- 成片 asset
- `539`
- 文件:
- `local://rendered-videos/2026-06-13/b3e3faa4-f320-42b6-9e08-f4c80935d427.mp4`
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/b3e3faa4-f320-42b6-9e08-f4c80935d427.mp4`
- 状态:
- `active`
- 时长:
- `50s`
- render task
- `526`
- status `success`
FFprobe 验证:
- 视频:
- `h264`
- `1080x1920`
- `50.000000s`
- 音频:
- `aac`
- `50.000000s`
- 音量:
- `mean_volume=-19.0 dB`
- `max_volume=-0.5 dB`
抽帧验收:
- 5 秒间隔:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-rerun-asset-539/contact.jpg`
- 2 秒间隔:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-rerun-asset-539/contact-2s.jpg`
人工观感:
- 有改善:
- 第 1 镜空间关系更稳定,顾辰和入场二人组关系更明确。
- 第 3 镜羞辱动作更清楚,周浩拍肩、顾辰低头拿戒指盒更像剧情动作。
- 第 5 镜老管家、豪车、递文件动作更明确,反转感比上一版强。
- 仍有问题:
- 第 2、4 镜没有重跑,因此全片同脸一致性还没有完全统一。
- Hailuo 运动过程中仍会轻微改脸,尤其侧脸和低头动作。
- 目前只把锚点图用于关键帧生成,没有真正把多角色参考图直接传给 Hailuo,因为当前 Hailuo Fast 配置是单首帧图生视频。
当前结论:
- 角色锚点图 / 定妆图 V1 方向有效。
- 比临时关键帧版更适合进入生产流程。
- 但要达到可上架,还需要:
- 关键帧生成必须系统化,而不是临时 `imagegen` 手工生成。
- 需要把第 2、4 镜也用锚点重做一次,得到全片统一版本。
- 后续 Provider 若支持 character reference / 多参考图,应优先用于高价值镜头。
## 2026-06-13 真人短剧多角色对白 / 多声线 TTS V1
目标:
- 修复真人短剧成片里“所有人像同一个解说在读”的问题。
- 同一镜头内多个人说话时,按 `角色名:台词` 自动拆成多个 TTS 段。
- 每个角色优先使用 Character 表里的 `voice_provider_code` / `voice_id` / `voice_style`
本次代码改动:
- `backend/src/live-action/live-action.service.ts`
- `prepareLiveActionPostProductionAssets` 增加项目角色加载。
- `buildLiveActionAudioSegments` 支持一镜多说话人拆分。
- 新增角色声音映射:
- `buildLiveActionCharacterVoiceMap`
- `resolveLiveActionSegmentVoice`
- `defaultLiveActionVoiceId`
- TTS Provider 输入增加:
- `voice_id`
- `speaker`
- `instructions`
- 音频任务记录增加:
- `voice_id`
- `voice_style`
- `character_id`
- `backend/src/live-action/live-action.service.spec.ts`
- 新增单测:同一镜头中 `林雨薇 / 顾辰 / 周浩` 三人对白拆成 3 个独立 TTS 段。
当前项目 61 声线配置:
- 顾辰 / character `99`
- Provider`minimax-tts`
- voice_id`Chinese (Mandarin)_Sincere_Adult`
- 林雨薇 / character `100`
- Provider`minimax-tts`
- voice_id`Arrogant_Miss`
- 周浩 / character `101`
- Provider`minimax-tts`
- voice_id`Chinese (Mandarin)_Reliable_Executive`
- 老管家 / character `103`
- Provider`minimax-tts`
- voice_id`Chinese (Mandarin)_Gentle_Senior`
重合成结果:
- 新成片 asset
- `544`
- 文件:
- `local://rendered-videos/2026-06-13/4a42aeea-5e5e-489b-a724-c098f06a2042.mp4`
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/4a42aeea-5e5e-489b-a724-c098f06a2042.mp4`
- 状态:
- `active`
- 时长:
- `50s`
- render task
- `531`
- audio task
- `527`
音频分段对比:
- 旧版 audio task `522`
- `segment_count=5`
- 每个镜头一段,多个角色被合成同一个 TTS 文本。
- 新版 audio task `527`
- `segment_count=10`
- 每个人独立发声:
- 主持人:`Chinese (Mandarin)_News_Anchor`
- 顾辰:`Chinese (Mandarin)_Sincere_Adult`
- 林雨薇:`Arrogant_Miss`
- 周浩:`Chinese (Mandarin)_Reliable_Executive`
- 旁白:`Chinese (Mandarin)_News_Anchor`
- 老管家:`Chinese (Mandarin)_Gentle_Senior`
FFprobe 验证:
- 视频:
- `h264`
- `1080x1920`
- `30fps`
- `50.000000s`
- 音频:
- `aac`
- `stereo`
- `50.000000s`
- 音量:
- `mean_volume=-19.3 dB`
- `max_volume=-0.3 dB`
验证命令:
- `npm run test --workspace backend -- live-action.service.spec.ts`
- 30 passed
- `npm run typecheck --workspace backend`
- passed
- `npm run lint --workspace backend`
- passed
- `npm run build --workspace backend`
- passed
当前结论:
- “多人对白被一个声音读完”的问题已修复。
- 后台/API 已重启到新版代码。
- 这一步只解决多角色声音,不等于解决严格口型同步。
- 如果要发布级正脸对白,仍需要后续接 lip-sync Provider 或继续采用中景轻口型策略。
## 2026-06-13 老管家声线纠偏
问题:
- 多角色对白版 asset `544` 比上一版明显改善。
- 但第 5 镜老管家听感偏女声。
- 原因:
- 老管家绑定了 `Chinese (Mandarin)_Gentle_Senior`
- 实际听感不适合“中老年男性管家”。
修复:
- `backend/src/live-action/live-action.service.ts`
- 老管家 / 王伯 / elder 类默认 MiniMax 声线从:
- `Chinese (Mandarin)_Gentle_Senior`
- 改为:
- `Chinese (Mandarin)_Gentleman`
- `backend/src/live-action/live-action.service.spec.ts`
- 新增单测:
- 管家对白默认使用 `Chinese (Mandarin)_Gentleman`
- 数据库:
- project `61`
- character `103`
- 老管家 voice_id 已改为 `Chinese (Mandarin)_Gentleman`
- voice_style 已改为:
- `中老年男性,沉稳、正式、低沉,像忠诚管家汇报重要消息。`
重合成结果:
- 新成片 asset
- `549`
- 文件:
- `local://rendered-videos/2026-06-13/70c30ded-2a9e-4b19-9ed0-5873dc2c8feb.mp4`
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/70c30ded-2a9e-4b19-9ed0-5873dc2c8feb.mp4`
- 音频 task
- `532`
- 音频 asset
- `545`
- segment_count
- `10`
- 老管家分段:
- segment `9`
- voice_id`Chinese (Mandarin)_Gentleman`
- segment `10`
- voice_id`Chinese (Mandarin)_Gentleman`
验证:
- `npm run test --workspace backend -- live-action.service.spec.ts`
- 31 passed
- `npm run typecheck --workspace backend`
- passed
- `npm run lint --workspace backend`
- passed
- `npm run build --workspace backend`
- passed
- 后端 API 已重启,`/api/health` 正常。
当前结论:
- 管家女声问题已修复为男声候选。
- 是否最终采用 `Gentleman` 还要人工听感确认。
- 如果仍觉得太年轻或不够稳,下一轮可横测:
- `Chinese (Mandarin)_Male_Announcer`
- `Chinese (Mandarin)_Reliable_Executive`
- `Chinese (Mandarin)_Humorous_Elder`
## 2026-06-13 Hailuo 2.3 Fast vs 标准版第 5 镜 A/B 小样
目标:
- 验证当前海螺质量问题是否主要来自 Fast 模型档位。
- 只测试第 5 镜“劳斯莱斯与继承权反转”,避免整集烧钱。
A 版本:
- clip
- `71`
- asset
- `534`
- Provider
- `minimax_hailuo_23_fast`
- 模型:
- `MiniMax-Hailuo-2.3-Fast`
- 分辨率:
- `768P`
- 目标时长:
- `10s`
- 实际时长:
- `10.125s`
- 成本:
- `$0.317`
- 文件:
- `/www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-13/52538a5b-5cb0-4c26-a42d-003cb7662739.mp4`
B 版本:
- clip
- `72`
- asset
- `550`
- Provider
- `minimax_hailuo_23`
- 模型:
- `MiniMax-Hailuo-2.3`
- 分辨率:
- `1080P`
- 目标时长:
- `6s`
- 实际时长:
- `5.875s`
- 成本:
- `$0.2802`
- 生成耗时:
- 约 4 分 20 秒
- 文件:
- `/www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-13/a2b99754-4447-46a4-8c74-e150ef54b31b.mp4`
测试保护:
- 临时启用 `minimax_hailuo_23`
- 生成完成后已恢复为关闭状态,避免后台误点烧更高成本。
- 第 5 镜 `video_clip_asset_id` 已还原为原 Fast asset `534`
- 原整集成片不受本次 A/B 影响。
对比产物:
- 抽帧图:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/hailuo-standard-ab-shot5/fast-vs-standard-contact.jpg`
- 并排视频:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/hailuo-standard-ab-shot5/fast-vs-standard-side-by-side.mp4`
初步观感:
- 标准版 1080P 的清晰度、车灯、雨夜质感略优于 Fast。
- 但两个版本动作结构仍接近:
- 基于同一首帧缓慢推进。
- 老管家递卡和顾辰反应仍不够像真实剧组调度。
- 没有产生明显“电影拍摄感”的质变。
- 结论:
- Fast 不是唯一问题。
- 更大的瓶颈是:
- 单首帧图生视频。
- 缺少中间/结束关键帧。
- 缺少可控动作参考。
- 高价值反转镜头需要更强 Provider 或多关键帧流程。
下一步建议:
- 不建议直接把整集切到 Hailuo 标准版。
- 建议继续做:
- 第 5 镜三关键帧流程:
- 起始:车灯照亮顾辰和管家。
- 中段:管家递黑金卡。
- 结束:顾辰震惊看卡。
- 横测 Kling / Seedance / Wan / Vidu。
- 同一镜头只比较一个变量,建立 Provider 准入表。
## 2026-06-13 动作节拍链式生成 V1
目标:
- 解决高价值镜头“单首帧图生视频像图片慢慢动”的问题。
- 不默认增加全片成本,只在显式开启 `action_beat_mode=true` 时启用。
- 用上一段视频的结尾帧作为下一段首帧,降低动作断裂和模型自由发挥。
本次代码改动:
- `backend/src/live-action/live-action.dto.ts`
- `LiveActionGenerateDto` 新增:
- `action_beat_mode`
- `action_beat_count`
- `LiveActionPreflightQueryDto` 新增同名字段。
- `backend/src/live-action/live-action.service.ts`
- 新增动作节拍子片段规划:
- `buildLiveActionProviderClipSegments`
- `liveActionActionBeatPrompts`
- `resolveLiveActionActionBeatProviderDuration`
- 生成流程支持:
- 第 1 段使用原始 `keyframe_asset_id`
- 第 2 段开始使用上一段视频结尾帧作为新首帧。
- 新增尾帧抽取入库:
- `storeLiveActionSegmentEndFrameAsset`
- 同步写入 `shot_images.image_type=action_beat_end_N`
- 多段拼接后会裁回目标镜头时长:
- `trimLiveActionGeneratedClipBuffer`
- preflight 已同步显示 action beat 后的真实:
- `provider_clip_count`
- `provider_clip_durations`
- `estimated_cost`
- `backend/src/live-action/live-action.service.spec.ts`
- 新增单测:
- 开启 `action_beat_mode` 后,第 5 镜拆为 2 段。
- 第 2 段使用 `previous_segment_end_frame`
第 5 镜测试:
- 镜头:
- shot `266`
- `劳斯莱斯与继承权反转`
- Provider
- `minimax_hailuo_23_fast`
- 模式:
- `action_beat_mode=true`
- `action_beat_count=2`
- 分段:
- beat 1
- 原始关键帧 asset `531`
- 6s
- 管家撑伞走近、递黑金卡和文件袋。
- beat 2
- 使用 beat 1 结尾帧作为首帧。
- 6s
- 顾辰看卡、抬眼震惊。
- 生成结果:
- clip `73`
- asset `552`
- task `538`
- 成本 `$0.3804`
- 生成耗时约 2 分 47 秒
- 文件:
- `/www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-13/4843e97d-52ba-47ea-ba4d-6cccf32eedbc.mp4`
对比产物:
- 三版本抽帧:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/action-beat-shot5/fast-standard-actionbeat-contact.jpg`
- 三版本并排视频:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/action-beat-shot5/fast-standard-actionbeat-side-by-side.mp4`
- action beat 后半段抽帧:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/action-beat-shot5/actionbeat-second-half-contact.jpg`
系统保护:
- 本次测试没有替换正式成片镜头。
- shot `266` 当前 `video_clip_asset_id` 已还原为原 Fast asset `534`
- action beat 生成的 asset `552` 作为候选样片保留。
预检验证:
- action beat preflight
- `provider_clip_count=2`
- `provider_clip_durations=[6,6]`
- `estimated_cost=$0.3804`
- warning
- `动作节拍模式会拆成 2 个连续子片段,并使用上一段尾帧承接下一段。`
人工观感:
- 有明显进步:
- 后半段能看到顾辰低头看卡、再抬眼震惊。
- 黑金卡和手套道具更清楚。
- 比单首帧慢推更像一个连续动作链。
- 仍有问题:
- 第 1 段到第 2 段仍可能有轻微跳切。
- 这是“链式尾帧”方案,不等于真正的三关键帧/首尾帧 Provider。
- 成本从单条 Fast `$0.317` 增加到 `$0.3804`
当前结论:
- action beat 链式生成 V1 方向有效,值得保留到系统。
- 默认不能全量开启,应只用于:
- 反转镜头
- 封面级镜头
- 爆点镜头
- 高价值动作镜头
- 下一步应该在后台给高价值镜头加开关:
- 普通模式:单条生成。
- 动作节拍模式:2 段链式生成。
- 真正多关键帧模式:待接支持 start/end/reference 的 Provider 后启用。
## 2026-06-13 第一集 action beat 版重合成
目标:
- 使用第 5 镜 action beat 候选 asset `552` 重合成完整第一集。
- 验证动作节拍链式生成放进整集后的观感。
- 不重新烧 1-4 镜真实视频。
合成策略:
- 第 1 镜:
- asset `532`
- 第 2 镜:
- asset `516`
- 第 3 镜:
- asset `533`
- 第 4 镜:
- asset `518`
- 第 5 镜:
- 临时替换为 action beat asset `552`
- 合成完成后:
- shot `266` 当前指针已恢复为原 asset `534`
- 本次新成片 asset `557` 保留用于预览对比
生成结果:
- 新成片 asset
- `557`
- 文件:
- `local://rendered-videos/2026-06-13/6d4980e3-f4f7-49f7-a4b1-986319d3e059.mp4`
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/6d4980e3-f4f7-49f7-a4b1-986319d3e059.mp4`
- render task
- `543`
- 使用 clip_asset_ids
- `[532,516,533,518,552]`
- post production
- `segment_count=10`
- 状态:
- `active`
- 时长:
- `50s`
验证:
- FFprobe
- video`h264`
- size`1080x1920`
- fps`30`
- duration`50.000000s`
- audio`aac stereo`
- 音量:
- `mean_volume=-20.0 dB`
- `max_volume=-0.2 dB`
- 抽帧:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-actionbeat-render-557/contact-5s.jpg`
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-actionbeat-render-557/contact-2s.jpg`
人工观感:
- 第 5 镜整体比旧版更像动作链:
- 管家递卡更明确。
- 顾辰低头看卡、再抬眼震惊更清楚。
- 黑金卡道具更突出。
- 整集仍有短板:
- 第 2、4 镜仍是旧单首帧素材。
- 前半段表演和镜头调度仍偏 AI 生成感。
- 角色一致性和真实拍摄感还没有达到可发布标准。
当前结论:
- action beat 放进整集后有效,值得用于反转/爆点镜头。
- 下一步如果继续优化第一集,应优先重做:
- 第 2 镜退婚对峙
- 第 4 镜雨夜离场
- 这两镜若也走“更短动作节拍 + 明确反应 + 更少动作目标”,整集观感会明显提升。
## 2026-06-13 第一集全镜头 action beat 版生成
目标:
- 5 个镜头全部用 `action_beat_mode=true` 重新生成。
- 验证动作节拍链式生成放到整集后,是否能改善“单首帧慢推 / 图片动”的整体观感。
预检:
- 镜头数:
- `5`
- provider
- `minimax_hailuo_23_fast`
- provider 子片段数:
- `10`
- 每镜:
- `2`
- 每段 `6s`
- 最终裁回每镜 `10s`
- 预计视频成本:
- `$1.902`
- 阻断:
-
生成结果:
| 镜头 | clip | asset | 成本 | 用时 |
| --- | --- | --- | --- | --- |
| 第 1 镜 订婚宴开场到破局 | `74` | `559` | `$0.3804` | `148s` |
| 第 2 镜 当众退婚 | `75` | `561` | `$0.3804` | `155s` |
| 第 3 镜 富二代羞辱与顾辰沉默 | `76` | `563` | `$0.3804` | `148s` |
| 第 4 镜 雨夜离场 | `77` | `565` | `$0.3804` | `156s` |
| 第 5 镜 劳斯莱斯与继承权反转 | `78` | `567` | `$0.3804` | `146s` |
视频生成成本:
- 合计:
- `$1.902`
新整集成片:
- asset
- `572`
- 文件:
- `local://rendered-videos/2026-06-13/01824074-610e-4b34-8742-3948ebf38c9d.mp4`
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/01824074-610e-4b34-8742-3948ebf38c9d.mp4`
- render task
- `553`
- 使用 clip_asset_ids
- `[559,561,563,565,567]`
- post production
- `segment_count=10`
- 渲染耗时:
- `55s`
当前镜头指针:
- 第 1 镜:
- asset `559`
- 第 2 镜:
- asset `561`
- 第 3 镜:
- asset `563`
- 第 4 镜:
- asset `565`
- 第 5 镜:
- asset `567`
文件验证:
- FFprobe
- `h264`
- `1080x1920`
- `30fps`
- `50.000000s`
- audio `aac stereo`
- 音量:
- `mean_volume=-20.1 dB`
- `max_volume=-0.3 dB`
抽帧:
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-full-actionbeat-render-572/contact-5s.jpg`
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-full-actionbeat-render-572/contact-2s.jpg`
人工观感:
- 有改善:
- 第 1 镜人物推进和男主正脸更明显。
- 第 2 镜退婚对峙比旧版更有连续表演感。
- 第 3 镜羞辱和男主反应更连贯。
- 第 4 镜雨夜情绪转场更完整。
- 第 5 镜递卡、顾辰看卡反应比单首帧版更明确。
- 新问题:
- 第 5 镜中段管家道具出现比例异常,像大文件夹/牌匾,黑金卡不够真实。
- action beat 全量开启后,每镜有潜在轻微跳切风险。
- 角色脸部仍会有轻微漂移,尤其中近景和侧脸转换时。
- 仍没有真正 lip-sync,正脸对白仍只能靠中景轻口型规避。
当前结论:
- 全镜头 action beat 版比旧版更能看出完整效果。
- 方向有效,但不能盲目全片默认开启。
- 更合理的生产策略:
- 普通对话:
- 单条或轻量 action beat。
- 情绪反应 / 转折:
- 2 段 action beat。
- 反转道具 / 爆点:
- 必须加“道具关键帧 / 结束关键帧”,否则容易道具变形。
- 正脸对白:
- 仍需 lip-sync 或继续规避口型。
下一步建议:
- 优化第 5 镜道具策略:
- 黑金卡单独生成清晰道具参考图。
- prompt 禁止文件夹/大牌匾。
- 第 5 镜只保留黑金卡,不同时递文件袋。
- 后台应增加镜头级开关:
- `单条生成`
- `动作节拍`
- `道具锁定`
- `角色锁定`
- `需要 lip-sync`
## 2026-06-14 Live-action Character Lock V1
触发原因:
- 第一集 action beat 整集样片虽然动作连续性更好,但用户复看后确认不是单点问题:
- 整集人物都有换脸感。
- 同名角色跨镜头像不同演员。
- 这会直接破坏真人短剧发布观感。
问题定位:
- 数据库已经有:
- `characters.anchor_asset_id`
- `character_images`
- `actor_profiles.anchor_asset_id`
- `actor_profiles.reference_asset_ids`
- 但真实视频生成阶段重新 build provider prompt 时,没有按本镜头角色重新加载 actor profile。
- prepare 阶段的 `actorHints` 也存在把全项目角色混入单镜 prompt 的风险。
- 结果:
- 第 1 镜可能带入非本镜角色描述。
- 第 5 镜也可能缺少顾辰/管家明确同脸锁定。
- Hailuo 只能吃首帧图生视频时,缺少稳定的角色文字锁定,模型更容易自由换脸。
本阶段完成:
- 新增 `LiveActionActorLockContext`
- 解析本镜头 `characters_json`
- 只加载本镜出现角色的 `ActorProfile`
- 组装 `actor_hints`
- 角色描述。
- 外貌锁定。
- 服装锁定。
- 表演方式。
- 同名角色禁止换脸/换年龄/换演员。
- 收集:
- `anchor_asset_ids`
- `reference_asset_ids`
- `missing_actor_profile_character_ids`
- `missing_anchor_character_ids`
- 真实视频生成任务 `input_json` 记录:
- `actor_lock`
- `character_reference_asset_ids`
- Provider prompt 现在会注入本镜头角色一致性规则。
- 如果未来 Provider 支持多角色参考图:
- 自动把角色参考图转成 `reference_images` 传入。
- 当前 Hailuo 配置仍显示 `supports_character_reference=false`,所以主要靠首帧 + prompt 锁定。
- 修复 prepare 阶段:
- 不再把全项目 actor profiles 混进单镜 prompt。
- 只按本镜出现角色注入演员提示。
- mock prompt 也显示 `演员一致性 / actor_consistency`,方便本地验收和后台审计。
修改文件:
- `backend/src/live-action/live-action.service.ts`
- `backend/src/live-action/prompt-builder.service.ts`
- `backend/src/live-action/live-action.service.spec.ts`
- `CODEX_PROGRESS.md`
验证:
- `npm run test --workspace backend -- live-action.service.spec.ts`
- 33 tests passed
- `npm run typecheck --workspace backend`
- passed
- `npm run lint --workspace backend`
- passed
- `npm run build --workspace backend`
- passed
- 后端已重启:
- `ai-backend.service`
- PID `4003094`
- `http://127.0.0.1:3000/api/health` 返回 `ok`
当前结论:
- 整集换脸问题已在流程层补上第一道防线。
- 但这不是最终锁脸方案:
- Hailuo 当前不是强角色参考模型。
- 仍需要先做角色定妆图/锚点图,并用锚点图生成每个镜头首帧。
- 发布级样片建议重跑第 1、3、5 镜验证,再决定是否整集重跑。
下一步建议:
- 先不要再全量重跑整集。
- 先做:
- 顾辰 / 林雨薇 / 周浩 / 管家 4 个角色锚点图检查。
- 用 Character Lock V1 重跑第 1、3、5 镜。
- 对比旧版抽帧,看是否仍明显换脸。
- 如果仍严重换脸,再接 Kling / Vidu / Seedance 这类更适合角色参考的 Provider 做横测。
## 2026-06-15 Git 提交前数据/代码整理
触发问题:
- 准备提交 Git 前,需要区分:
- 哪些是代码和默认初始化数据,应该提交。
- 哪些是服务器测试/生产运行数据,不应该提交。
- AI 平台配置是否能通过初始化生成。
检查结果:
- 当前 `/www/wwwroot/ai` 还不是 Git 仓库:
- `git status` 返回 `fatal: not a git repository`
- 当前目录总大小约:
- `2.3G`
- 主要运行时数据:
- `storage``1.8G`
-`node_modules``264M`
- `backend/node_modules``235M`
- `backend/dist``admin/dist``user-app/dist``workers/dist` 为构建产物
- 当前数据库存在大量测试/运行数据:
- 用户 `44`
- 项目 `59`
- 小说源 `36`
- 章节 `75`
- 故事圣经 `33`
- 角色 `96`
- 分镜 `280`
- 任务 `594`
- Provider 调用日志 `676`
- 视频片段 `78`
- 素材 `604`
- 当前启用 Provider
- mock 系列默认 Provider
- `deepseek-text`
- `deepseek-novel`
- `minimax-tts`
- `minimax_hailuo_23_fast`
判断:
- 数据库里的项目、任务、素材、调用日志、用户、额度、真实 Provider 启用状态和 Key 配置都属于当前服务器运行数据,不提交 Git。
- `storage/private/**` 下的图片、音频、视频、小说上传、Hailuo 测试片段都是运行时私有素材,不提交 Git。
- `.env` 包含数据库、JWT、Provider Key 等本地/生产配置,不提交 Git。
- AI Provider 默认模板已经在代码中:
- `backend/src/providers/provider.types.ts`
- `backend/prisma/migrations/20260602130000_domestic_video_providers/migration.sql`
- `backend/prisma/seed.ts`
- 后台保存后的真实 Key 和启用状态应保留在数据库或 `.env`,不进入 Git。
本阶段完成:
- 加固 `.gitignore`,防止误提交:
- `node_modules`
- `dist`
- `.vite`
- `.output`
- `coverage`
- `.env`
- 日志文件
- runtime storage
- zip/tar/sql/dump/bak
- sqlite/db 本地数据库
修改文件:
- `.gitignore`
- `CODEX_PROGRESS.md`
提交建议:
- 应提交:
- 源码:`backend/src``admin/src``user-app/src``workers/src`
- Prisma`backend/prisma/schema.prisma``backend/prisma/migrations``backend/prisma/seed.ts`
- 配置模板:`.env.example`
- 包管理:`package.json``package-lock.json`、各 workspace `package.json`
- 运维模板:`deploy`
- 根说明文档和进度文档
- 不提交:
- `.env`
- `storage/private/**`
- `backend/storage/**`
- `*.log`
- `dist`
- `node_modules`
- 服务器数据库导出、zip 包、运行备份
验证:
- 本阶段只调整 Git 忽略规则和进度记录,没有修改业务代码。
- 未运行 lint/typecheck/test。
## 2026-06-14 用户端制作页单列流程 / 下一步自动滚动
触发问题:
- 用户反馈前端制作页面 PC 端是双列,流程不好看。
- 希望制作页改成一列纵向流程,并且每次完成当前动作后自动滚动到下一步对应位置。
本阶段完成:
- 用户端制作页外层增加 `studio-flow`,仅影响“制作”页。
- PC 端制作页不再使用双列卡片流,强制改为一列往下跑:
- 进度
- 额度
- 来源
- 版权
- 故事圣经
- 角色库
- 长篇记忆
- 分集计划
- 脚本和分镜
- AI 真人短剧
- 图片/音频/视频
- 内容审核
- 制作页内部表单在 `studio-flow` 下也改为单列,减少 PC/H5 字段和按钮挤压。
- 给制作页关键步骤增加锚点:
- `source`
- `copyright`
- `story`
- `characters`
- `memory`
- `episodes`
- `script`
- `live-action`
- `render`
- `review`
- 新增下一步定位逻辑:
- 动作成功后根据当前项目状态自动判断下一步。
- 自动滚动到对应步骤卡片。
- AI 原创项目未生成正文时,优先回到“来源”。
- 真人短剧项目在最终成片前,优先回到“AI 真人短剧”面板。
- 排除不应该滚动的局部操作:
- 恢复会话
- 视频预检刷新
- 小样预检刷新
- 单张锚点重生成
- 单张锚点切换
- 素材预览
- 成品下载
修改文件:
- `user-app/src/pages/index/index.vue`
- `user-app/src/styles.css`
- `CODEX_PROGRESS.md`
验证:
- `npm run typecheck --workspace user-app`
- passed
- `npm run lint --workspace user-app`
- passed
- `npm run test --workspace user-app`
- passed, no test files
- `curl -I http://152.53.37.118:5174/`
- `200 OK`
下一步建议:
- 人工打开 PC/H5 制作页,点一遍“版权确认 -> 解析小说 -> 故事圣经 -> 角色 -> 分集 -> 脚本/分镜 -> 真人视频/合成”,确认自动滚动位置是否符合操作习惯。
- 如果仍觉得步骤太长,可以再加一个右侧/顶部“当前流程目录”,点击可跳到任一步。
## 2026-06-14 前端真人视频流程同步 / Action Beat 控制
触发问题:
- 用户询问 `http://152.53.37.118:5174/` 前端按流程生成视频时,到底是 mock 还是同步了最近真实 Hailuo 测试步骤。
问题定位:
- 前端普通主流程的“生成视频/合成”仍是系统 A 常规 FFmpeg 合成链路,不等于真人 Hailuo 视频片段生成链路。
- 前端已有“AI 真人短剧”面板,能执行演员定妆、真人分镜、关键帧、视频片段、合成。
- 后端已支持 `action_beat_mode/action_beat_count`,但用户端没有暴露开关,导致无法在前端明确控制“默认 1 条”还是“复杂动作拆成 2-3 个子片段”。
本阶段完成:
- 用户端真人视频表单新增:
- `动作节拍`
- `节拍段数`
- 默认关闭动作节拍,保持单镜头默认 1 条,避免默认成本翻倍。
- 开启动作节拍后,前端预检、小样生成、整集片段生成、片段重试都会带上:
- `action_beat_mode`
- `action_beat_count`
- 统一真人视频前端参数构造,减少小样和整集口径不一致。
- `UserApiClient` 的真人视频 preflight/generate/retry 类型和 query/body 增加 action beat 参数。
修改文件:
- `user-app/src/pages/index/index.vue`
- `user-app/src/api/client.ts`
- `CODEX_PROGRESS.md`
验证:
- `npm run typecheck --workspace user-app`
- passed
- `npm run lint --workspace user-app`
- passed
- `npm run test --workspace user-app`
- passed, no test files
- `curl -I http://152.53.37.118:5174/`
- `200 OK`
当前判断:
- 前端普通流程的“多角色音频”会按当前 Provider 配置走真实 MiniMax 或 mock。
- 前端普通流程的“生成视频/合成”是 FFmpeg 合成,不会直接调用 Hailuo 生成真人视频。
- 前端“AI 真人短剧”面板里的“视频片段/小样视频片段”才是 Hailuo/Kling/Jimeng/Mock 真实视频 Provider 链路。
- 选择真实 Hailuo Provider 并勾选真实费用确认后,才会调用真实 Hailuo;不选 Provider 时走 RouterRouter 可能因为配置/可用性落到 Mock。
- 后端 Character Lock V1 已自动生效,但前端目前只使用它,不单独展示 actor_lock 审计明细。
下一步建议:
- 把前端“普通生成视频”和“真人视频片段生成”视觉上再拆清楚,避免误点普通合成却以为在跑 Hailuo。
- 后台/前端补 actor_lock、关键帧来源、clip_normalization 的可视化,让每个片段是否锁脸、是否裁切、是否动作节拍拆段一眼可见。
## 2026-06-14 TTS / Upload Blocking Fix
触发问题:
- 用户端点击“多角色音频”报:
- `MINIMAX_TTS_EMPTY_AUDIO`
- 上传小说时报:
- `request entity too large`
问题定位:
- 最近失败的 `minimax-tts` ProviderLog 显示:
- 多角色音频把 `voice=coral` 发给了 MiniMax。
- `coral` 是 OpenAI TTS 声音名,不是 MiniMax voice_id。
- `runConfigurableSpeechProvider` 解析 JSON 响应时,没有先检查 MiniMax `base_resp.status_code`,会把业务拒绝误报成 `MINIMAX_TTS_EMPTY_AUDIO`
- 上传小说的后端文件限制为 20MB。
- 加密上传会把文件转成 base64 放入 JSONNest 默认 body parser 限制会先拦截,导致 `request entity too large`
本阶段完成:
- MiniMax TTS 兼容:
- `body_style=minimax_tts` 时,如果输入是 OpenAI voice 名(如 `coral`),自动降级为 MiniMax 配置默认 `voice_id`
- MiniMax JSON 响应先检查 `base_resp.status_code`,真实业务错误会显示 `MINIMAX_TTS_PROVIDER_REJECTED`,不再误报空音频。
- JSON 无音频时带上安全摘要,方便后台排查。
- Media 多角色音频 provider input 增加 `voice_id` 字段,方便 Provider 适配。
- 上传限制:
- 小说/素材上传默认上限从 20MB 提高到 100MB。
- 新增 `MAX_UPLOAD_BYTES` 环境变量支持。
- Nest body parser 改为显式配置:
- 默认 `REQUEST_BODY_LIMIT=160mb`
- 支持 `MAX_REQUEST_BODY_SIZE`
- 兼容 encrypted JSON/base64 上传。
- 用户端错误文案:
- 增加 `MINIMAX_TTS_EMPTY_AUDIO`
- 增加 `MINIMAX_TTS_PROVIDER_REJECTED`
- 增加 `request entity too large`
修改文件:
- `backend/src/providers/providers.service.ts`
- `backend/src/providers/providers.service.spec.ts`
- `backend/src/media/media.service.ts`
- `backend/src/assets/assets.controller.ts`
- `backend/src/main.ts`
- `user-app/src/api/client.ts`
- `CODEX_PROGRESS.md`
验证:
- `npm run test --workspace backend -- providers.service.spec.ts media.service.spec.ts assets.service.spec.ts`
- 55 tests passed
- `npm run typecheck --workspace backend`
- passed
- `npm run lint --workspace backend`
- passed
- `npm run build --workspace backend`
- passed
- `npm run typecheck --workspace user-app`
- passed
- `npm run test --workspace user-app`
- passed, no test files
- MiniMax TTS smoke
- `text=测试。`
- `voice=coral`
- provider `minimax-tts`
- status `success`
- returned `audio/mpeg`
- audio bytes `18485`
- 大 body 上传 smoke
- 1MB base64 JSON 上传不再返回 413
- 未登录场景返回正常 `401 Missing bearer token`
- 后端已重启:
- `ai-backend.service`
- PID `4097583`
- `/api/health` 返回 `ok`
注意:
- 如果上传通过公网 Nginx/宝塔代理仍报 413,还需要同步调高 Nginx `client_max_body_size`
- 当前应用层已经放开到默认 100MB 文件 / 160MB JSON body。