Files
ai-drama-platform/README.md
T

19 KiB
Raw Blame History

AI 短剧本地生产平台

这是一个面向私有部署和商业团队的本地化 AI 短剧/漫剧生产平台 MVP,不是单剧集页面。平台把组织、工作区、成员、角色、项目访问、剧本、角色锁、场景锁、道具锁、分镜、台词、生成任务、质检门、成本、合规、审计和剪辑交付放进同一个生产系统。

当前已经具备:

  • 三类产品入口:创作空间、管理员后台、系统设置控制面;分别服务创作者日常生产、组织治理和部署级配置。
  • 多组织:一个用户可以属于多个组织,组织之间的项目、成员、模型和审计数据隔离。
  • 多工作区:制作部、素材实验室、客户空间可以在同一组织下独立管理。
  • 多用户与角色:组织所有者、组织管理员、制片、编剧、资产美术、配音/字幕、审片、项目编辑和项目查看者。
  • 项目级访问控制:项目邀请使用受限 project_guest 工作区身份和 project-only 访问模式,只能看到显式授权项目,不会因加入工作区而继承全部项目或生成权限。
  • 真实 scope API:所有项目、任务、模型、审片、导出请求都经过 user → organization → workspace → project 检查。
  • 平台级系统治理:系统配置、功能开关、通知渠道、API 客户端、服务健康和队列运营;系统权限独立于组织管理员。
  • 实时运营概览:管理概览直接读取服务健康探针、Worker 心跳/队列和部署生产就绪度,不使用前端静态状态冒充在线运行状态。
  • 企业身份中心:TOTP MFA、登录策略、OIDC/SAML 提供商登记与发现探测、SCIM 目录令牌轮换和受令牌保护的用户同步接口。
  • 用户通知中心:按用户、组织、工作区隔离的通知收件箱、未读计数、单条/全部已读、组织级通知偏好和服务端收件人过滤。
  • 全局生产搜索:支持 ⌘/Ctrl + K 命令入口,在当前工作区或当前项目内定位项目、剧本、分集、镜头、资产、任务、生成任务和交付记录;结果由后端按租户作用域过滤。
  • 协作任务中心:项目内任务创建、负责人分派、优先级、截止时间、状态、本人任务更新、任务通知和审计记录。
  • 资产版本台账:资产版本不可覆盖,支持当前版本切换、历史版本恢复、锁定状态和镜头绑定审计。
  • 本地持久化:Node 24 内置 SQLite 自动初始化到 /Users/xz/Documents/daima/ai短剧/ai-drama-platform/data/platform.sqlite。
  • 本地模型优先:自有模型平台是主适配器,OpenAI-compatible / 自定义 HTTP JSON 可接入,ComfyUI 只是 optional adapter。
  • 本地执行器:API 启动时自动拉起 Worker,支持租约、并发限制、心跳、依赖阻塞、重试记录和管理员手动领取。

运行

cd /Users/xz/Documents/daima/ai短剧/ai-drama-platform
npm install
npm run dev

本地 API 服务:

cd /Users/xz/Documents/daima/ai短剧/ai-drama-platform
npm run api

需要保持两个进程:Vite 前端和本地 API。API 进程会自动启动本地 Worker;只有需要独立调试 Worker 时才单独使用 npm run worker。启动后访问:

前端:http://127.0.0.1:5173/
API:http://127.0.0.1:8787/api/health

完整回归(必须串行执行,共 32 项,避免 SQLite 写入竞争):

npm run smoke:all

API 默认每个令牌或匿名来源每分钟允许 120 次请求,可在系统配置中修改 api.rate_limit_per_minute;设置为 0 表示关闭限流。超限响应为 429 rate_limit_exceeded,并返回 Retry-After 与 X-RateLimit-* 响应头。当前本地模式使用单 API 进程内固定窗口计数,多实例部署应切换到 Redis/共享限流存储。

该命令覆盖租户隔离、MFA、OIDC、系统用户、商业配额、邀请、模型/Runner、API 客户端密钥轮换、任务队列、媒体证据、合成证据和项目生命周期;每个临时 smoke 用户、邀请和任务都会在成功或失败后清理。

API 默认地址:

http://127.0.0.1:8787/api/health
http://127.0.0.1:8787/api/project
http://127.0.0.1:8787/api/qa
POST http://127.0.0.1:8787/api/auth/login
GET  http://127.0.0.1:8787/api/auth/session
POST http://127.0.0.1:8787/api/auth/logout
GET  http://127.0.0.1:8787/api/auth/security-events
GET  http://127.0.0.1:8787/api/system/security-events?userId=<userId>
POST http://127.0.0.1:8787/api/auth/login/mfa
GET  http://127.0.0.1:8787/api/auth/mfa
POST http://127.0.0.1:8787/api/auth/mfa/setup
POST http://127.0.0.1:8787/api/auth/mfa/enable
POST http://127.0.0.1:8787/api/auth/mfa/disable
GET  http://127.0.0.1:8787/api/auth/sso/providers
GET  http://127.0.0.1:8787/api/auth/sso/start?providerId=:id&returnTo=/
GET  http://127.0.0.1:8787/api/auth/sso/callback
GET  http://127.0.0.1:8787/api/auth/sso/saml/metadata?providerId=:id
POST http://127.0.0.1:8787/api/auth/sso/saml/acs
POST http://127.0.0.1:8787/api/auth/sso/redeem
GET  http://127.0.0.1:8787/api/auth/sessions
POST http://127.0.0.1:8787/api/auth/sessions/:sessionId/revoke
POST http://127.0.0.1:8787/api/auth/sessions/revoke-others
POST http://127.0.0.1:8787/api/auth/password
GET  http://127.0.0.1:8787/api/context
GET  http://127.0.0.1:8787/api/search?q=雷雨&scope=workspace&limit=40
GET  http://127.0.0.1:8787/api/search?q=雷雨&scope=project&limit=40
GET  http://127.0.0.1:8787/api/tasks?status=all&assignedTo=me&limit=100
POST http://127.0.0.1:8787/api/tasks
PATCH http://127.0.0.1:8787/api/tasks/:taskId
GET  http://127.0.0.1:8787/api/notifications?limit=60&unreadOnly=1
PATCH http://127.0.0.1:8787/api/notifications/:notificationId
POST http://127.0.0.1:8787/api/notifications/read-all
GET  http://127.0.0.1:8787/api/notification-preferences
PATCH http://127.0.0.1:8787/api/notification-preferences/:category
GET  http://127.0.0.1:8787/api/organizations
GET  http://127.0.0.1:8787/api/organizations/:orgId
POST http://127.0.0.1:8787/api/organizations/:orgId/invitations
GET  http://127.0.0.1:8787/api/organizations/:orgId/members
PATCH http://127.0.0.1:8787/api/organizations/:orgId/members/:userId
GET  http://127.0.0.1:8787/api/invitations
POST http://127.0.0.1:8787/api/invitations/:invitationId/accept
GET  http://127.0.0.1:8787/api/workspaces
POST http://127.0.0.1:8787/api/workspaces
GET  http://127.0.0.1:8787/api/workspaces/:workspaceId/members
PATCH http://127.0.0.1:8787/api/workspaces/:workspaceId/members/:userId
GET  http://127.0.0.1:8787/api/projects
POST http://127.0.0.1:8787/api/projects
GET  http://127.0.0.1:8787/api/projects/:projectId/members
PATCH http://127.0.0.1:8787/api/projects/:projectId/members/:userId
GET  http://127.0.0.1:8787/api/usage
GET  http://127.0.0.1:8787/api/billing
GET  http://127.0.0.1:8787/api/audit
GET  http://127.0.0.1:8787/api/audit/:auditId
GET  http://127.0.0.1:8787/api/audit/export
GET  http://127.0.0.1:8787/api/system/health
GET  http://127.0.0.1:8787/api/system/worker
GET  http://127.0.0.1:8787/api/system/readiness
GET  http://127.0.0.1:8787/api/permissions
GET  http://127.0.0.1:8787/api/assets?kind=voice
POST http://127.0.0.1:8787/api/assets/upload
GET  http://127.0.0.1:8787/api/assets/:assetId/content
POST http://127.0.0.1:8787/api/assets/:assetId/versions
POST http://127.0.0.1:8787/api/assets/:assetId/versions/upload
POST http://127.0.0.1:8787/api/assets/:assetId/verify
POST http://127.0.0.1:8787/api/assets/:assetId/versions/:versionId/restore
POST http://127.0.0.1:8787/api/assets/:assetId/lock
POST http://127.0.0.1:8787/api/assets/:assetId/rights
POST http://127.0.0.1:8787/api/assets/:assetId/bindings
GET  http://127.0.0.1:8787/api/production/graph
GET  http://127.0.0.1:8787/api/production/catalog
POST http://127.0.0.1:8787/api/production/seasons
POST http://127.0.0.1:8787/api/production/episodes
PATCH http://127.0.0.1:8787/api/production/episodes/:episodeId
POST http://127.0.0.1:8787/api/production/script/import
POST http://127.0.0.1:8787/api/production/script/materialize
PATCH http://127.0.0.1:8787/api/production/bible
POST http://127.0.0.1:8787/api/production/shots
PATCH http://127.0.0.1:8787/api/production/shots/:shotId
POST http://127.0.0.1:8787/api/production/shots/:shotId/prompt-versions
GET  http://127.0.0.1:8787/api/production/reviews
POST http://127.0.0.1:8787/api/production/qa/run
POST http://127.0.0.1:8787/api/production/reviews/:reviewId/decision
POST http://127.0.0.1:8787/api/production/reviews/:reviewId/comments
GET  http://127.0.0.1:8787/api/production/deliveries
POST http://127.0.0.1:8787/api/production/deliveries
POST http://127.0.0.1:8787/api/production/deliveries/:deliveryId/approve
GET  http://127.0.0.1:8787/api/admin/queue
GET  http://127.0.0.1:8787/api/platform/models
POST http://127.0.0.1:8787/api/platform/models/register
PATCH http://127.0.0.1:8787/api/platform/models/:modelId
POST http://127.0.0.1:8787/api/platform/models/:modelId/probe
GET  http://127.0.0.1:8787/api/system/config
POST http://127.0.0.1:8787/api/system/config
GET  http://127.0.0.1:8787/api/system/health
GET  http://127.0.0.1:8787/api/system/readiness
GET  http://127.0.0.1:8787/api/system/backups
POST http://127.0.0.1:8787/api/system/backups
POST http://127.0.0.1:8787/api/system/health/:serviceKey/action
GET  http://127.0.0.1:8787/api/system/feature-flags
POST http://127.0.0.1:8787/api/system/feature-flags
GET  http://127.0.0.1:8787/api/system/notifications
POST http://127.0.0.1:8787/api/system/notifications
GET  http://127.0.0.1:8787/api/system/api-clients
POST http://127.0.0.1:8787/api/system/api-clients
PATCH http://127.0.0.1:8787/api/system/api-clients/:clientId
POST http://127.0.0.1:8787/api/system/api-clients/:clientId/rotate
GET  http://127.0.0.1:8787/api/jobs
GET  http://127.0.0.1:8787/api/jobs/:jobId
POST http://127.0.0.1:8787/api/jobs
POST http://127.0.0.1:8787/api/jobs/:jobId/run
POST http://127.0.0.1:8787/api/jobs/:jobId/retry
POST http://127.0.0.1:8787/api/jobs/:jobId/cancel
POST http://127.0.0.1:8787/api/jobs/:jobId/priority
POST http://127.0.0.1:8787/api/adapters/dry-run
POST http://127.0.0.1:8787/api/exports/write
GET  http://127.0.0.1:8787/api/system/worker
POST http://127.0.0.1:8787/api/system/worker/dispatch

前端模块支持 #creator-home、#factory、#script、#casting、#director、#jobs、#bible、#qa、#export、#admin-* 和 #system-* 深链接;移动端使用抽屉导航,不会把整套后台菜单堆在内容之前。

季 / 集主数据

系列 Bible 页面现在按商业剧集目录管理 series → seasons → episodes → shots:

  • 一个项目可以创建多季、多集,每集创建时自动初始化一个镜头草稿,避免空集无法进入生产。
  • 当前集选择会通过 episodeId 传给生产图谱;剧本版本、镜头、Prompt 和返回的图谱都按当前集隔离。
  • 分集状态支持草稿、制作中、审片中、已通过和已归档;标题、时长、开场钩子和结尾悬念都写入 SQLite 并记录审计日志。
  • 服务端创建季、创建集、修改集都经过 script:edit 权限检查,不能靠前端隐藏绕过。
  • npm run smoke:production-catalog 会验证目录读取、创建季、创建集、首个镜头初始化、集级图谱切换和分集更新;该脚本会清理自己的临时数据。

用户鉴权与访问边界

平台默认使用真实的邮箱 + 密码登录和 Bearer session。会话默认有效 12 小时,失败 5 次会暂时锁定;所有业务 API 都先解析 session,再执行用户 → 组织 → 工作区 → 项目 → 权限检查。浏览器端不会因为知道组织 ID 就获得跨组织访问权。

仅在本地接口调试或冒烟测试时,显式设置 AI_DRAMA_ALLOW_DEV_CONTEXT=1 才会启用请求头上下文 bypass;默认值是 session-only,正式部署应保持 AI_DRAMA_ALLOW_DEV_CONTEXT=0 或不设置。

认证接口:

POST http://127.0.0.1:8787/api/auth/login
GET  http://127.0.0.1:8787/api/auth/session
POST http://127.0.0.1:8787/api/auth/logout

本地演示账号统一密码:Demo@123456。

系统管理员:producer@local.test
组织管理员 / 制片:producer2@local.test
普通编剧:writer@local.test

访问范围:

  • 普通创作者:我的工作台,以及被授予的剧本、资产、导演、生成、审片或交付页面;未授权的入口、按钮和敏感数据会隐藏,API 同时返回 403。
  • 制片 / 组织管理员:本组织的组织、工作区、成员、项目、模型、队列、用量和审计能力,数据不会跨组织返回。
  • 系统管理员:在组织权限之上,额外管理部署、存储、全局生成策略、通知、API 客户端、功能开关和系统健康。

系统级权限单独记录在 system_admins 表。组织管理员不会因为组织角色自动获得全局部署策略权限。

API 客户端密钥:完整密钥只在创建或轮换成功响应中返回一次;SQLite 仅保存 SHA-256 摘要、版本号和不可用的前缀预览,客户端目录不会再次返回完整密钥。轮换会立即撤销旧密钥,撤销或暂停状态的客户端不能调用业务 API。

API 客户端 scope 由后端白名单强制执行:jobs:read 只能读取任务,jobs:write 才能创建/执行/重试/取消任务,models:read 只能读取连接器,models:write 才能登记/修改/探测连接器,audit:read 才能读取和导出审计日志。普通 Bearer session 不受 API 客户端 scope 规则影响。

平台管理页顶部的组织、工作区和项目切换器会实际刷新 API scope;邀请成员、创建工作区、创建项目和生成任务都会写入 SQLite,并产生审计/用量记录。

通知中心按当前用户和组织保存消息,工作区/项目消息会继续经过服务端作用域过滤。用户可以按生成任务、审片、交付、协作任务、组织访问、用量配额和系统通知分别关闭站内提醒;关闭偏好后,服务端不会继续写入该用户的对应收件箱。

协作任务中心与“我的待办”互通:项目负责人可以创建和分派任务,普通成员只能更新自己负责任务的状态,任务状态会回写到项目审计和站内通知。

账号安全页支持修改密码、查看最近登录设备、撤销单个其他会话、撤销其他全部会话和接受组织邀请;会话撤销操作由后端执行并写入审计日志。独立的 auth_security_events 台账记录登录成功/失败、账号锁定、MFA 挑战与验证、MFA 开关、会话创建/撤销/退出和密码变更;普通用户只能读取自己的事件,系统管理员可按用户读取全局事件,API 客户端不能读取个人安全事件。

系统设置中的“企业身份”页面支持保存登录策略、登记 OIDC/SAML 提供商、用 OIDC discovery 或 SAML 环境配置探测提供商、创建和轮换 SCIM 令牌。SAML 使用 HTTP-Redirect AuthnRequest + HTTP-POST ACS:IdP 证书只从服务端环境变量引用读取,断言必须通过签名、Audience、时间窗口和 InResponseTo 校验,再进入组织/工作区入组、MFA 和一次性 Bearer ticket。ACS 不接受前端提交的用户身份。SCIM 接口为 /scim/v2.0/:directoryId/Users,支持用户列表、新增、部分更新和停用;目录令牌只在创建或轮换响应中返回一次,数据库只保存哈希。MFA 密钥使用 AES-GCM 加密存储,可通过 AI_DRAMA_MFA_ENCRYPTION_KEY 指定独立加密密钥。

登录后入口读取当前用户有权访问的组织、工作区和项目;新组织或空工作区会进入空项目工厂,不会自动复制其他项目的角色、资产、镜头或任务。仓库内的《雷雨口》只用于本地种子数据和回归测试。当前平台不会主动调用任何云端或付费节点;生成适配器配置在:

/Users/xz/Documents/daima/ai短剧/ai-drama-platform/config/adapters.example.json

平台边界

  • 主适配器是用户自有模型平台,支持 HTTP、自定义 JSON、OpenAI-compatible 形态。
  • 已确认的音频生产链路走 NewAPI OpenAI-compatible 中转:IndexTTS-2.5 用于中文角色配音和情绪控制,paraformer-zh-long 用于中文 ASR、台词校验和字幕时间轴;密钥只从 NEWAPI_API_KEY 环境变量读取,不写入仓库。
  • ComfyUI 只是 optional adapter,用来复用旧的 Qwen/QwenEdit/H3 首尾帧桥接经验。
  • 一次生成只允许一张完整单画面;分镜图、接触表、边界表只能审核,不能喂回生成。
  • 声音作为独立资产锁定,不把 MiniMax H3 随机原生声音作为最终角色声线。
  • 当前平台底座已具备真实任务合同、队列、重试、取消、租约、并发控制和 HTTP Runner 执行接口;API 启动时自动运行本地 Worker,只会领取本地 ready 连接器任务。若未配置可用的自有图片/视频/TTS/ASR Runner,任务会明确显示 not-connected/blocked,不会伪称已经生成真实媒体成片。
  • 手动执行接口对已完成任务是幂等的:如果本地 Worker 已先完成任务,重复调用 POST /api/jobs/:jobId/run 会返回现有完成结果并标记 idempotent: true,不会再次调用模型或生成第二份媒体。
  • 流程模板已经是服务端版本化对象:全局内置模板可被组织 / 工作区新版本覆盖,生成队列支持“只生成计划”或“按步骤创建带依赖的 generation jobs”。
  • 媒体证据支持按项目 scope 读取原始图片、视频、音频以及实际首帧 / 末帧;审片中心使用文件级预览、SHA-256、FFprobe 和 QA 证据共同验收,不把路径字符串当作已生成事实。
  • 系统存储页支持保留周期和“仅清理无引用临时文件”的清理预览;回收动作只处理 outputs/frames/tmp/cache 中未被资产版本、媒体证据或合成清单引用的文件,并写入审计。
  • 模型协议、Worker 环境变量、状态字段和接口返回约定见 /Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/API_REFERENCE.md。
  • 本地验证脚本会修改 SQLite,因此多个 smoke 脚本应顺序执行;并行写入会触发 SQLite 的正常写锁保护。

私有商业部署

生产编排 profile 位于 /Users/xz/Documents/daima/ai短剧/ai-drama-platform/deploy/,包含 API、独立 Worker、Nginx 前端、PostgreSQL、Redis 和 MinIO/S3-compatible 对象存储。当前业务代码的数据库真源仍是 Node 24 SQLite;compose 会先把目标基础设施和连接契约部署起来,但不会伪称已经完成 PostgreSQL、Redis 或对象存储运行时切换。系统管理员可以在系统总览查看生产就绪度,并通过 /api/system/backups 创建可审计的 SQLite 快照。具体边界和启动命令见 /Users/xz/Documents/daima/ai短剧/ai-drama-platform/deploy/README.md。

NewAPI 音频请求格式见:

/Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/NEWAPI_AUDIO_WORKFLOW.md

商业平台研究

功能研究与本地版能力映射见:

/Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/MARKET_RESEARCH_2026.md
/Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/COMMERCIAL_PLATFORM_BLUEPRINT.md
/Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/MULTI_TENANT_DESIGN.md
/Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/superpowers/plans/2026-08-19-commercial-multitenant-platform.md

输出目录

/Users/xz/Documents/daima/ai短剧/ai-drama-platform/exports/<project-id>

每个项目单独拥有一个子目录,子目录对应 series bible、角色、场景、道具、分镜、配音、QA、剪辑工程和最终视频交付;服务端不会把一个项目的导出写进另一个项目目录。