# AI Manga Platform AI 漫剧 / AI 写真视频生成平台。当前优先开发系统 A:原创小说 / 上传小说 -> 韩漫 / 漫剧生成系统。 ## 当前阶段 阶段 23:API 加密传输已完成,当前进入生产化补齐。AI 原创小说 3 集 MP4 与上传小说 1 集 MP4 两条闭环已跑通,并在 HTTPS 基础上叠加前后端应用层加密信封;真实图片/TTS/视频资产落库、OpenAI Sora 视频 Provider 驱动、后台用户高危操作审计、细粒度 RBAC 和审计导出已补齐。 当前已完成后端基础骨架、数据库 schema、JWT 认证、私有文件上传、项目创建流程、上传小说解析、AI 原创小说 mock、故事圣经、角色圣经、长篇记忆、分集计划、单集脚本和分镜、BullMQ 队列与任务状态流转、AI Provider 抽象层、真实 AI Provider 接入、真实图片/TTS/视频资产落库、Provider 成本阈值、worker 队列消费、TTS 音频、SRT 字幕、FFmpeg 视频合成、后台管理、用户端 H5 制作台、订单额度、内容审核、MVP 验收和 API 加密传输。后台管理已覆盖项目、任务、小说源、章节、角色资源、分镜资源、成品漫剧、订单额度、内容审核、Provider、成本、用户、素材、版权记录和审计日志,并补充资源详情/媒体预览、用户人工加余额、额度冲正、用户禁用/启用、改角色、重置密码和用户详情抽屉,高危用户操作带二次确认,后台接口按 admin/operator/finance/auditor 做细粒度权限校验。用户端已支持登录注册、项目创建、原创/上传入口、版权确认、故事/角色/记忆/分集/脚本/分镜/媒体生成、额度查看/冻结、内容审核、公开案例授权、进度查看和私有成品下载;当前内部测试不展示支付/套餐入口,额度由后台人工增加。AI Provider 已支持 OpenAI 真实调用,后台可配置 API Key、Base URL、模型、优先级、启停状态、单次成本上限和当日成本上限;API Key 使用服务端密钥加密落库,页面不回显明文。图片、TTS 和 OpenAI Sora 视频生产链路已能保存真实 Provider 返回的二进制素材,默认优先级仍可保持 mock,避免未确认成本前误消耗真实模型。 新手操作请先看 [OPERATION_GUIDE.md](./OPERATION_GUIDE.md),里面按用户端和后台分别说明从项目创建到成品视频、额度、审核、AI 接入和常见问题排查。产品内也已补充教程入口:后台左侧“使用教程”,用户端导航“教程”,并预留 `src/pages/help/tutorial` 独立页面。 ## 目录结构 ```text backend/ NestJS API 服务 admin/ Geeker-Admin 可接入的后台前端骨架 user-app/ uni-app 路由预留、H5 优先的用户端制作台 workers/ BullMQ / FFmpeg worker 入口 deploy/ 本地依赖、Docker、Nginx、部署脚本预留 docs/ 系统 A / B 需求和工程文档 storage/ 本地 mock 存储目录 ``` ## 本地启动 安装依赖: ```bash npm install ``` 后端启动会自动加载根目录 `.env` 和 `backend/.env`;系统环境变量优先级最高。`PROVIDER_SECRET_KEY` 必须长期保持稳定,用于解密后台保存的 AI Provider Key。 启动后端空服务: ```bash npm run dev:backend ``` 后端默认监听: ```text http://127.0.0.1:3000/api/health ``` 启动后台骨架: ```bash npm run dev:admin ``` 启动用户端 H5: ```bash npm run dev:user ``` ## 验证命令 ```bash npm run lint npm run typecheck npm test npm run build ``` ## API 加密传输 阶段 23 已实现前后端应用层加密信封,并保留 HTTPS 作为生产必需底座。阶段 23 补充了后台配置开关:测试默认关闭,上线后可在后台“配置管理”手动开启。 实现范围: - 前端先通过 `GET /api/client-config` 读取 `api_crypto_enabled`,默认不开启加密。 - 开关开启后,前端通过 `GET /api/crypto/handshake` 获取短期 ECDH 会话参数。 - 前端和后端使用 `ECDH P-256 + HKDF-SHA256` 派生会话 AES key。 - JSON API 请求体使用 `AES-256-GCM` 加密后发送。 - JSON API 响应体、异常响应体使用 `AES-256-GCM` 加密后返回。 - 用户端小说上传改为加密 JSON 文件 payload,不再裸传 multipart 正文。 - 私有素材下载在加密请求下返回加密 JSON 文件 payload,前端解密后再生成 Blob。 - 后台和用户端生产构建默认使用同源 `/api`;显式配置 `VITE_API_BASE_URL` 时生产环境禁止 `http://`。 - 后台管理新增“配置管理”,可维护 `security.api_crypto_enabled`。 - `API_CRYPTO_ENABLED=true/false` 可强制覆盖数据库配置;默认 `auto` 表示读取后台配置。 生产建议: ```bash NODE_ENV=production HTTPS_REQUIRED=true HTTPS_ALLOW_LOCAL_HTTP=false TRUST_PROXY=true CORS_ORIGINS=https://manga.example.com,https://admin.manga.example.com API_CRYPTO_ENABLED=auto API_CRYPTO_SESSION_TTL_SECONDS=900 VITE_API_CRYPTO_ENABLED=auto VITE_API_BASE_URL=/api ``` 开启方式: 1. 保持 `API_CRYPTO_ENABLED=auto` 和 `VITE_API_CRYPTO_ENABLED=auto`。 2. 用管理员账号进入后台“配置管理”。 3. 点击“开启 API 加密”,之后普通 API 会强制要求加密信封。 注意:应用层加密保护的是请求体和响应体内容。HTTP 方法、路径、域名和查询字符串不能被前端 JS 在应用层隐藏,所以生产环境仍必须使用 HTTPS,并应避免把敏感业务内容放进 query string。多实例部署时,当前内存态加密会话需要粘性会话或迁移到 Redis。 ## 数据库 阶段 02 选择 Prisma 作为 MySQL 8 ORM。原因是当前系统 A 表数量多、JSON 字段多、后续迁移频繁,Prisma 的 schema、migration 和类型生成更适合分阶段落地。 核心文件: ```text backend/prisma/schema.prisma backend/prisma/migrations/20260531093000_init_system_a/migration.sql backend/prisma/seed.ts ``` 常用命令: ```bash cp .env.example .env DATABASE_URL="mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga" npm run db:validate DATABASE_URL="mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga" npm run db:generate DATABASE_URL="mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga" npm run db:migrate DATABASE_URL="mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga" npm run db:deploy DATABASE_URL="mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga" npm run db:seed ``` `db:migrate` 用于开发环境生成/演进迁移,可能需要创建 shadow database 的权限。已有 migration 文件时,服务器环境优先使用 `db:deploy`。 ## 认证接口 阶段 03 已实现基础 JWT 认证: ```text POST /api/auth/register POST /api/auth/login POST /api/auth/logout GET /api/auth/profile GET /api/profile ``` `/api/auth/profile` 和 `/api/profile` 都需要 `Authorization: Bearer `。 ## 项目接口 阶段 05 已实现登录用户的项目创建、列表、详情、更新、取消和软删除流程: ```text POST /api/projects GET /api/projects GET /api/projects/:id PATCH /api/projects/:id POST /api/projects/:id/cancel DELETE /api/projects/:id ``` 要求: - 请求必须带 `Authorization: Bearer `。 - `input_mode` 当前支持 `ai_original` 和 `upload`,`admin_import` 预留给后台导入。 - 新项目默认进入 `source_selecting` 状态。 - `DELETE /api/projects/:id` 当前为软删除,会把可删除项目归档为 `archived`。 ## 文件上传 阶段 04 已实现私有资产上传。当前本机未启动 MinIO 时,默认使用本地 mock 私有存储;后续将 `STORAGE_DRIVER=minio` 并配置 `MINIO_*` 即可切换。 ```text POST /api/assets/upload POST /api/projects/:projectId/novel/upload GET /api/assets/:assetId GET /api/assets/:assetId/download ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 上传字段名为 `file`。 - 小说上传当前支持 `txt`、`md`、`docx` 和文本型 `pdf`。 - 上传资产默认 `visibility=private`。 - 普通 asset 查询只返回内部 asset 信息,不返回原始文件公网地址。 - `/api/assets/:assetId/download` 需要 Bearer Token,会校验资产归属后返回私有文件流,用户端成品下载和视频预览使用该接口。 ## 小说解析与版权 阶段 06 已实现上传小说解析链路: ```text POST /api/projects/:projectId/copyright/confirm GET /api/projects/:projectId/copyright POST /api/projects/:projectId/novel/paste POST /api/projects/:projectId/novel/parse GET /api/projects/:projectId/novel/parse-result PATCH /api/novel-chapters/:chapterId ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 上传小说解析前必须先确认版权,否则 `/novel/parse` 返回 400。 - `authorization_type` 支持 `author_self`、`licensed`、`public_domain`、`internal_test`。 - `/novel/parse` 支持从已上传 asset 解析,也支持从粘贴文本 source 解析。 - 解析会清洗常见广告/水印行,识别章节标题,失败时按字数切分。 - 解析结果写入 `novel_sources` 和 `novel_chapters`。 - 章节可手动编辑,编辑后状态标记为 `edited`。 ## AI 原创小说 Mock 阶段 07 已实现 AI 原创小说 mock 链路: ```text POST /api/projects/:projectId/original/idea POST /api/projects/:projectId/original/outline POST /api/projects/:projectId/original/chapters POST /api/projects/:projectId/original/self-check GET /api/projects/:projectId/original/result ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 项目 `input_mode` 必须为 `ai_original`,上传小说项目调用原创接口会返回 400。 - 当前实现为 deterministic mock,`parse_report.provider=mock_novel_provider`,不调用真实 AI Provider。 - 生成内容写入 `novel_sources` 和 `novel_chapters`。 - 默认按项目 `target_episode_count` 生成章节,MVP 场景通常为 3 章。 - 自检覆盖主角一致性、主线、冲突、可视化摘要和短视频钩子。 ## 故事圣经 阶段 08 已实现故事圣经链路: ```text POST /api/projects/:projectId/story-bible/generate GET /api/projects/:projectId/story-bible PATCH /api/projects/:projectId/story-bible POST /api/projects/:projectId/story-bible/confirm ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 生成前必须已有小说来源和章节,支持上传解析链路和 AI 原创 mock 链路。 - 生成结果写入 `story_bibles`,状态为 `waiting_confirm`。 - 编辑故事圣经会创建新版本,不覆盖旧版本。 - 确认后故事圣经状态变为 `confirmed`,项目状态变为 `story_confirmed`。 - `GET /story-bible?version=2` 可查询指定版本;不传 version 返回最新版本和版本列表。 ## 角色圣经 阶段 09 已实现角色圣经链路: ```text POST /api/projects/:projectId/characters/extract GET /api/projects/:projectId/characters POST /api/projects/:projectId/characters POST /api/projects/:projectId/characters/confirm PATCH /api/characters/:characterId DELETE /api/characters/:characterId ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 抽取角色前必须已有已确认故事圣经,否则 `/characters/extract` 返回 400。 - 角色抽取当前为 deterministic mock,从已确认故事圣经和小说章节生成主角、反派、配角等角色草稿。 - 角色数据写入 `characters` 表,支持列表、手动新增、编辑和软删除。 - 确认角色库会把 `draft`、`generated`、`edited` 状态角色锁定为 `locked`,项目状态变为 `character_confirmed`。 - `locked` 角色不可修改姓名、角色类型、性别、年龄、身份和核心外观字段;仍可补充服装规则、表情风格等非核心描述。 - 本阶段不生成角色图片、不生成 anchor 图,也不接入 ImageProvider 或队列。 ## 长篇记忆 阶段 10 已实现长篇记忆链路: ```text GET /api/projects/:projectId/plot-memories POST /api/projects/:projectId/plot-memories/generate POST /api/projects/:projectId/plot-memories PATCH /api/plot-memories/:memoryId GET /api/projects/:projectId/memory-context?episode_no=5 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 ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 生成长篇记忆前必须已有 confirmed 故事圣经和 locked 角色库。 - 记忆生成当前为 deterministic mock,会写入 `plot_memories`、`plot_threads` 和 `character_memories`。 - 剧情记忆支持手动新增、标记 resolved/archived、按类型/状态/分集筛选。 - 剧情线支持新增、查询、更新状态,类型覆盖主线、反派计划、悬疑线、角色成长线等。 - `GET /memory-context?episode_no=N` 会返回故事圣经、锁定角色、活跃剧情记忆、开放剧情线、前 3 集摘要和上一集结尾钩子,供后续分集/脚本生成使用。 - locked 角色的非核心资料补充会自动记录 `character_memories.profile_adjustment`。 - 连续性检查当前为规则版 mock,可发现角色未承接、伏笔未推进、上一集钩子未承接、缺少结尾钩子、开放剧情线未推进和明显破坏世界观的内容。 - 本阶段不接入 EmbeddingProvider、不做向量检索、不进队列,也不调用真实 AI Provider。 ## 分集计划 阶段 11 已实现分集计划链路: ```text POST /api/projects/:projectId/episodes/generate-plan GET /api/projects/:projectId/episodes PATCH /api/episodes/:episodeId POST /api/projects/:projectId/episodes/confirm ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 生成分集前必须已有 confirmed 故事圣经、locked 角色库、小说章节和 active 长篇记忆。 - 分集生成当前为 deterministic mock,会写入 `episodes` 表。 - 每集包含标题、剧情摘要、开头钩子、中段冲突、结尾悬念、关联章节和预计时长。 - 生成时项目状态流转为 `episode_planning`,完成后为 `waiting_episode_confirm`。 - 分集可在确认前编辑,编辑后状态为 `edited`。 - 确认分集会把 `draft`、`generated`、`edited` 状态分集锁定为 `confirmed`,项目状态变为 `episode_confirmed`。 - 已确认分集不可继续编辑;如需重做,后续会通过返工/修改申请流程处理。 - 本阶段不生成单集脚本、不生成分镜、不进队列,也不调用真实 AI Provider。 ## 脚本和分镜 阶段 12 已实现单集脚本和分镜链路: ```text 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 ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 生成单集脚本前必须已有 confirmed 分集、confirmed 故事圣经和 locked 角色库。 - 单集脚本当前为 deterministic mock,会写入 `episode_scripts`,包含脚本文本、旁白和结构化台词。 - 脚本生成后项目状态进入 `waiting_script_confirm`;确认后脚本状态为 `confirmed`,项目状态为 `script_confirmed`。 - 生成分镜前必须已有 confirmed 单集脚本。 - 分镜生成当前为 deterministic mock,会写入 `storyboard_shots`,默认每集 10 个镜头。 - 每个镜头包含画面描述、人物、场景、动作、台词/旁白、镜头运动、特效、2-5 秒时长、Prompt 和负面 Prompt。 - Prompt 会带入角色固定描述,并包含防混脸、年龄/发色漂移、复杂多人镜头等负面约束。 - 分镜可在确认前编辑、删除和重生 Prompt;确认后镜头状态为 `confirmed`,项目状态为 `storyboard_confirmed`。 - 本阶段不生成分镜图片、不接入 ImageProvider、不进队列,也不调用真实 AI Provider。 ## BullMQ 队列 阶段 13 已实现任务记录、幂等入队、管理员重试/取消/人工介入和队列监控: ```text POST /api/projects/:projectId/tasks GET /api/projects/:projectId/tasks GET /api/tasks/:taskId GET /api/admin/tasks POST /api/admin/tasks/recover-stale POST /api/admin/tasks/:taskId/retry POST /api/admin/tasks/:taskId/cancel POST /api/admin/tasks/:taskId/manual-required GET /api/admin/queues ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 普通用户只能操作自己的项目任务,admin 可查看和管理全部任务。 - 创建任务会先写入 `render_tasks`,再尝试入 BullMQ;Redis 或 BullMQ 不可用时,任务仍保留为 `pending` / `retrying`,接口返回 `queue_backend=bullmq_unavailable`。 - 幂等 key 默认由 `project_id + episode_id + shot_id + task_type + input_hash` 组成,`input_hash` 基于稳定 JSON 序列化生成。 - 已支持 novel、parse、story、character、episode、script、storyboard、image、audio、subtitle、video、qc、review、analytics 等队列映射。 - 默认重试次数按任务类型区分:文本类 2 次、图片类 3 次、视频 2 次、TTS/字幕 2 次、QC 1 次、人工审核 0 次。 - 管理员可把失败任务重试为 `retrying`,可取消任务为 `cancelled`,可标记为 `manual_required`,可恢复过久未完成的 `running` / `retrying` 任务。 - `/api/admin/queues` 会返回 BullMQ 每个队列的 waiting、active、delayed、failed、completed、paused 计数。 - worker 包已接入 BullMQ 消费器,会订阅全部队列并调用后端内部接口 `POST /api/internal/worker/tasks/:taskId/execute`,通过 `WORKER_SECRET` 鉴权。 - worker 执行失败时后端会按 `max_retry` 自动重入队;达到上限后把任务转为 `manual_required`,后台任务页可继续人工处理。 - worker 当前执行的是通用 Provider 任务委托:按任务类型映射到 Text/Novel/Image/Voice/Video/Moderation/QC/FileParse Provider;图片、音频、视频资产生成的业务接口仍保留同步链路。 ## AI Provider 抽象 阶段 14 已实现 mock-first Provider 抽象、管理员配置入口、执行日志和成本聚合;阶段 21 已补充 OpenAI / OpenAI 兼容真实驱动: ```text GET /api/admin/providers POST /api/admin/providers/bootstrap-mocks POST /api/admin/providers/bootstrap-openai POST /api/admin/providers/bootstrap-video POST /api/admin/providers/execute PATCH /api/admin/providers/:providerId PATCH /api/admin/providers/openai/runtime-config PATCH /api/admin/providers/:providerId/runtime-config POST /api/admin/providers/:providerId/test GET /api/admin/provider-logs GET /api/admin/costs ``` 要求: - 请求必须带 `Authorization: Bearer `;后台接口按 RBAC 权限校验,admin 拥有全部权限,operator/finance/auditor 只开放对应读写范围。 - 已声明 `TextProvider`、`NovelProvider`、`ImageProvider`、`VideoProvider`、`VoiceProvider`、`ModerationProvider`、`QualityCheckProvider`、`FileParseProvider`、`EmbeddingProvider`。 - `/bootstrap-mocks` 会写入或更新 9 个默认 mock provider 配置。 - `/bootstrap-openai` 会写入或更新 OpenAI real provider 配置,包含 Responses、Moderation、Embeddings、Image Generation、Sora Video 和 Text to Speech 驱动。 - 后台默认显示“OpenAI 统一接入”:运营只需填写一个 OpenAI API Key,`PATCH /admin/providers/openai/runtime-config` 会批量应用到全部 OpenAI 能力;未勾选“生产任务优先使用 OpenAI”时会把 OpenAI 优先级保持为 50,低于 mock,避免保存 Key 后立刻消耗真实额度。 - `GET /admin/providers/openai/connection-check` 只请求 OpenAI `/models` 检查 Key/网络,不生成文本、图片、语音或视频,不写 `provider_logs`。 - `/execute` 会从 `provider_configs` 选择启用 provider,执行 mock 或 real driver,写入 `provider_logs`。 - 如果传入 `task_id`,执行时会把对应 `render_tasks` 标记为 `running`,成功后回写 `success`、`provider_id`、`provider_request_id`、`cost_estimate` 和 `cost_actual`。 - primary provider 失败时会按 fallback provider 或同类型优先级继续尝试,并记录失败日志。 - provider 输入、配置输出和日志输出会拒绝/脱敏 `api_key`、`secret`、`token`、`password`、`credential` 等疑似密钥字段;后台运行配置接口会把 API Key 加密为 `api_key_secure` 后保存,列表只显示已配置状态。 - 真实 Provider 优先读取后台加密保存的 API Key;未配置时仍可回退读取 `OPENAI_API_KEY`。后台可配置 `base_url` 接入 OpenAI 兼容服务,也可修改模型名、优先级和启停状态。`PROVIDER_SECRET_KEY` 用于加密后台保存的 Provider 密钥,未设置时回退 `JWT_SECRET`;生产环境必须保持该值稳定,否则已保存 Key 无法解密,需要重新保存。 - 重复点击“初始化 OpenAI 接入”会刷新默认 Provider 定义,但会保留后台已加密保存的 API Key、Base URL、超时和成本阈值,避免误清空线上配置。 - 后台真实 Provider 的“付费测试”必须二次确认,后端 `/admin/providers/:providerId/test` 也要求 `confirm_paid_test=true`;真实视频 Provider 测试接口默认禁用,避免误触发高成本视频任务。 - Provider 可配置 `max_cost_per_call` 和 `daily_cost_limit` 成本阈值,也可通过 `PROVIDER_MAX_COST_PER_CALL`、`PROVIDER_DAILY_COST_LIMIT` 设置全局保护;超过阈值会在调用前拦截并写失败日志。 - `openai_image_generation`、`openai_video_generation` 和 `openai_audio_speech` 的日志只保存 URL/大小/hash 等元数据,不把 base64 图片、视频或音频字节写入 `provider_logs`;真实二进制只在业务生成链路中短暂返回,用于立即写入私有素材。 - OpenAI 图片、Sora 视频和 TTS real provider 默认优先级低于 mock;后台可提高优先级或禁用 mock 后让业务生产链路保存真实图片、真实视频或 TTS 音频资产。 - `openai_video_generation` 按 OpenAI Videos API 的异步流程执行:创建视频任务、轮询完成状态,业务链路需要二进制时再下载 MP4 并落库。可用 `OPENAI_VIDEO_MODEL` 覆盖默认 `sora-2`。 - 真人短剧链路已新增可替换 image-to-video Provider:`minimax_hailuo_23_fast`、`minimax_hailuo_23`、`alibaba_wan26_i2v_flash`、`alibaba_wan26_i2v`、`vidu_q3_turbo_reference`、`vidu_q3_pro`、`jimeng_seedance`、`runway-image-to-video`、`kling-image-to-video`。真实视频 Provider 默认禁用,用户端真实视频生成必须传 `confirm_real_video=true`,并受单片段成本上限、Provider 单次/每日成本阈值保护。 - `configurable_image_to_video` 驱动支持通用异步图生视频流程:创建任务、轮询任务、提取视频 URL;如果供应商只返回 `file_id`,可通过 `output_url_endpoint_template` 再取下载链接。MiniMax Hailuo、阿里 Wan、Vidu 和 Seedance 预设都走这类可配置模板,正式启用前应先用 1 个镜头小样核对字段、速度、质量和账单。 - `VideoProvider` 成本规则支持 `unit=video_seconds`、`price_per_second`、`price_per_clip`。后台配置真实视频价格后,用户端真人短剧面板会显示片段级成本预估。 ## 图片生成 Mock 阶段 15 已实现角色图、锚点图、分镜预览图和正式图的 mock 生成: ```text POST /api/characters/:characterId/generate-images GET /api/characters/:characterId/images POST /api/characters/:characterId/set-anchor POST /api/storyboard-shots/:shotId/images/generate GET /api/storyboard-shots/:shotId/images POST /api/episodes/:episodeId/shot-images/generate ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 角色图生成要求角色已 `locked`。 - 默认生成 `front_reference`、`anchor`、`expression_pack`,也可指定 `image_types`。 - 角色锚点会写入 `character_images.is_anchor=true`,并回写 `characters.anchor_asset_id`。 - 分镜图生成要求 `storyboard_shots.status=confirmed`。 - 分镜图 Prompt 会引用角色固定描述和 `anchor_asset_id`,降低混脸和漂移风险。 - 图片生成会创建 `render_tasks`,通过 `ImageProvider` 执行,写入 `provider_logs`,并保存本地/MinIO 私有图片资产。 - 生成结果写入 `character_images` 或 `shot_images`,图片资产写入 `assets`,`visibility=private`。 - 当 Provider 返回 `content_base64` 或可下载的 HTTP(S) `asset_url` 时,会保存真实位图;否则回退生成 SVG mock 占位图。图片任务会回填 `render_tasks.output_asset_id`,方便后台追踪产物。 ## TTS / 字幕 / FFmpeg 阶段 16 已实现单集音频、字幕和 FFmpeg 视频合成链路: ```text POST /api/episodes/:episodeId/audio/generate POST /api/episodes/:episodeId/subtitle/generate POST /api/episodes/:episodeId/video/render GET /api/episodes/:episodeId/media-assets ``` 要求: - 请求必须带 `Authorization: Bearer `。 - 音频生成要求已有 `confirmed` 单集脚本,会调用 `VoiceProvider`,写入 `render_tasks`、`provider_logs` 和私有音频资产;真实 TTS 返回 `content_base64` 或可下载 URL 时保存真实音频,否则回退静音 WAV。 - 字幕生成要求已有 `confirmed` 分镜,会按镜头时长生成 SRT cues,写入本地私有 `.srt` 资产。 - 视频渲染要求已有 `confirmed` 分镜和已生成的分镜图;默认会复用或自动生成最新音频和字幕。 - 视频渲染要求项目已支付或冻结额度,否则会返回错误;阶段 19 用户端会在合成前调用额度冻结。 - 视频渲染会调用 `VideoProvider` 记录 provider 执行日志;若启用 `openai-video`,后端会创建 Sora 视频任务、轮询完成并下载 MP4,随后直接保存 Provider 渲染出的 MP4;若 Provider 未返回二进制,则读取私有分镜图、音频和 SRT 字幕,使用 FFmpeg 生成本地私有 MP4 资产。 - 默认优先使用 FFmpeg,成功时返回 `ffmpeg_used=true` 和 `render_backend=ffmpeg`;传入 `prefer_ffmpeg=false` 或本机缺少 FFmpeg 时会走 mock fallback。 - 生成结果写入 `assets`,asset_type 分别为 `audio`、`subtitle`、`video`,`visibility=private`。 - 当前不生成真实 BGM;图片、TTS 和 Sora 视频可切换真实 Provider 落库,视频也可保留 FFmpeg 本地合成,音频、字幕和视频目前仍为同步接口执行,worker 消费器后续接入。 ## 后台管理 阶段 17 已实现后台管理 API 和可用的 Vue/Vite 管理端: ```text GET /api/admin/dashboard GET /api/admin/rbac/me GET /api/admin/projects GET /api/admin/projects/:projectId PATCH /api/admin/projects/:projectId/status 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 GET /api/admin/works GET /api/admin/copyright-records GET /api/admin/operation-logs GET /api/admin/operation-logs/export ``` 已接入已有管理接口: ```text GET /api/admin/tasks POST /api/admin/tasks/:taskId/retry POST /api/admin/tasks/:taskId/cancel POST /api/admin/tasks/:taskId/manual-required GET /api/admin/queues GET /api/admin/providers POST /api/admin/providers/bootstrap-mocks GET /api/admin/provider-logs GET /api/admin/costs GET /api/admin/orders GET /api/admin/quota-accounts GET /api/admin/users/:userId/detail POST /api/admin/users/:userId/quota/grant GET /api/admin/content-reviews PATCH /api/admin/content-reviews/:reviewId GET /api/admin/case-showcases PATCH /api/admin/case-showcases/:showcaseId GET /api/admin/system-configs PATCH /api/admin/system-configs/:configKey ``` 要求: - 请求必须带 `Authorization: Bearer `;后台支持 `admin`、`operator`、`finance`、`auditor` 角色,接口按 `projects/users/billing/reviews/tasks/providers/costs/settings/audit` 等权限校验。 - `npm run db:seed` 会创建或更新本地 `admin@example.com`,默认开发密码为 `Admin123!`,可用 `SEED_ADMIN_PASSWORD` 覆盖。 - 管理端默认运行在 `http://127.0.0.1:5175`,API 默认指向 `http://127.0.0.1:3000/api`,可用 `VITE_API_BASE_URL` 覆盖。 - 当前后台已支持登录、仪表盘、项目管理、项目详情、项目状态调整、小说源/章节管理、角色资源、分镜资源、成品漫剧、订单额度、内容审核、公开案例授权、任务重试/取消/转人工、队列统计、Provider 配置、Provider 成本阈值、成本日志、用户列表、用户详情抽屉、用户人工加余额、额度冲正、禁用/启用用户、改角色、重置密码、素材列表、版权记录、系统配置管理和审计日志导出;小说、章节、角色、分镜、素材和成品资源支持详情/预览,高危用户操作在页面上会弹出二次确认。 - 模板管理深水区留到后续对应阶段继续扩展。 ## 订单额度 阶段 19 已实现订单、额度账户和项目正式生成前冻结/扣减: ```text GET /api/billing/packages GET /api/billing/quota GET /api/billing/quota/logs GET /api/billing/orders POST /api/billing/orders POST /api/billing/orders/:orderId/mock-pay GET /api/projects/:projectId/quota/estimate POST /api/projects/:projectId/quota/freeze POST /api/projects/:projectId/quota/release ``` 要求: - `/api/billing/packages` 可公开查看,其他用户额度接口需要 Bearer Token。 - 当前为内部测试额度模式:用户端不展示支付/套餐入口,运营在后台用户管理中人工增加额度。历史 mock 支付接口仍保留用于接口回归,不作为当前用户端入口。 - 项目额度预估按输入模式、目标集数和默认每集 6 个镜头估算。 - `quota/freeze` 会扣减可用额度、增加冻结额度,并把项目 `payment_status` 标记为 `quota_frozen`。 - 视频合成成功后会把冻结额度扣为已用额度,并把项目 `payment_status` 标记为 `paid`。 - 管理端新增“订单额度”页,可查看订单和额度账户;用户管理页支持管理员手动给用户增加余额/额度和执行额度冲正,并写入额度流水和操作日志,用户详情抽屉可查看额度流水、订单、项目、素材和最近操作。 ## 内容审核 阶段 20 已实现文本、素材、成品视频和公开案例授权的审核闭环: ```text POST /api/projects/:projectId/reviews/text GET /api/projects/:projectId/reviews POST /api/assets/:assetId/review 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 ``` 要求: - 用户接口必须带 Bearer Token,并校验项目或素材归属。 - 文本审核会聚合项目中的小说、故事圣经、角色、分集、脚本和分镜文本,也支持请求体直接传入 `content`。 - 素材审核覆盖 image、video、audio、subtitle 和 document/text 类资产;用户端当前接入文本审核和成品视频审核按钮。 - 审核调用现有 `ModerationProvider`;未初始化真实 Provider 时使用 mock,初始化 OpenAI 接入并在后台保存 API Key 后会优先调用 `openai-moderation`,失败时回退 mock。 - 需要人工处理的审核会把项目状态标记为 `manual_required`,后台可执行通过、修改、驳回、屏蔽和转人工。 - 用户端可提交公开案例授权,后台可将案例授权、发布为 public 或驳回。 - 当前不接入真实内容安全平台,不做真实版权库比对;商业发布前仍需人工确认版权授权、平台规则和内容合规。 - mock moderation 会识别“不得/禁止/避免违法内容”这类安全规则提示,不再把合规约束本身误判为风险文本。 ## MVP 验收 阶段 22 已完成系统 A MVP 端到端验收: - AI 原创小说链路:原创构思、章节、故事圣经、角色、角色锚点、长篇记忆、3 集分集、脚本、分镜、正式分镜图、音频、字幕、FFmpeg MP4、私有下载、视频审核和案例授权。 - 上传小说链路:TXT 上传、版权确认、小说解析、故事圣经、角色、角色锚点、长篇记忆、1 集分集、脚本、分镜、正式分镜图、音频、字幕、FFmpeg MP4、私有下载、视频审核和案例授权。 - 验收用户 `mvp-1780243409631@example.com`,原创项目 ID `28`,上传项目 ID `29`。 - 原创 3 个 MP4 与上传 1 个 MP4 均通过私有下载校验,返回 `video/mp4`,文件大小均大于 300 KB。 - 额度流程通过 mock 支付、项目冻结、视频成功后扣减;验收后账户 `used_quota=196`、`available_quota=1004`。 - 验收时发现并修复 mock 文本审核误伤安全规则提示的问题;复审记录 `13`、`14` 均为 `passed`。 ## 用户端 H5 阶段 18 已实现 H5 优先、PC 自适应的用户端制作台,并保留 uni-app `pages.json`、`manifest.json` 和页面路由文件,后续微信小程序/App 可继续迁移: ```text 登录 / 注册 新建项目 我的项目 制作台 生成进度 成品漫剧 用户中心 ``` 要求: - 用户端 API 可用 `VITE_API_BASE_URL` 覆盖;未配置时,本机访问会请求 `http://127.0.0.1:3000/api`,外网 IP/域名访问会自动请求同主机的 `:3000/api`。 - 用户端默认运行在 `http://127.0.0.1:5174`。 - 公网调试访问需要服务器防火墙/安全组放行 TCP `5174` 和 `3000`;当前本机 firewalld 已放行这两个端口。 - H5 为主布局,移动端底部导航和单列长表单优先;PC 宽屏自动切换为左侧导航和两栏制作台。 - 当前用户端已接入真实 API:认证、项目列表/创建、AI 原创小说、上传小说粘贴/文件入口、版权确认、故事圣经、角色库、长篇记忆、分集计划、单集脚本、分镜、分镜图、音频、字幕、FFmpeg 视频合成、任务进度、私有视频预览和下载。 - 阶段 19 已接入额度中心;当前用户端隐藏套餐、模拟支付和订单入口,仅展示额度账户、项目额度预估和合成前冻结额度。 - 阶段 20 已接入内容审核中心:项目文本审核、成品视频审核、审核状态列表和公开案例授权。 - 微信小程序/App 的文件选择、下载保存、支付能力、分享能力留到后续平台适配阶段;当前内部测试不开放用户端支付入口,图片/TTS 生产链路可切换真实 Provider,视频默认仍可用 FFmpeg 本地合成。 ## 开发约束 - 按 `AGENTS.md` 和 `docs/system_a/21_Codex开发任务拆解文档.md` 分阶段开发。 - 真实 AI Provider 已接入执行层;原创小说、故事圣经、角色、记忆、分集、脚本、分镜等 deterministic 生成服务后续可逐步迁移到统一 Provider 调用。 - 密钥只放 `.env`,不要提交真实密钥。 - 用户上传小说和素材默认私有。 - 每个阶段完成后更新 `CODEX_PROGRESS.md`。