# AI 短剧本地生产平台 这是一个面向私有部署和商业团队的本地化 AI 短剧/漫剧生产平台 MVP,不是单剧集页面。平台把组织、工作区、成员、角色、项目访问、剧本、角色锁、场景锁、道具锁、分镜、台词、生成任务、质检门、成本、合规、审计和剪辑交付放进同一个生产系统。 当前已经具备: - 三类产品入口:创作空间、管理员后台、系统设置控制面;分别服务创作者日常生产、组织治理和部署级配置。 - 多组织:一个用户可以属于多个组织,组织之间的项目、成员、模型和审计数据隔离。 - 多工作区:制作部、素材实验室、客户空间可以在同一组织下独立管理。 - 多用户与角色:组织所有者、组织管理员、制片、编剧、资产美术、配音/字幕、审片、项目编辑和项目查看者。 - 真实 scope API:所有项目、任务、模型、审片、导出请求都经过 user → organization → workspace → project 检查。 - 平台级系统治理:系统配置、功能开关、通知渠道、API 客户端、服务健康和队列运营;系统权限独立于组织管理员。 - 企业身份中心:TOTP MFA、登录策略、OIDC/SAML 提供商登记与发现探测、SCIM 目录令牌轮换和受令牌保护的用户同步接口。 - 用户通知中心:按用户、组织、工作区隔离的通知收件箱、未读计数、单条/全部已读、组织级通知偏好和服务端收件人过滤。 - 协作任务中心:项目内任务创建、负责人分派、优先级、截止时间、状态、本人任务更新、任务通知和审计记录。 - 资产版本台账:资产版本不可覆盖,支持当前版本切换、历史版本恢复、锁定状态和镜头绑定审计。 - 本地持久化:Node 24 内置 SQLite 自动初始化到 `/Users/xz/Documents/daima/ai短剧/ai-drama-platform/data/platform.sqlite`。 - 本地模型优先:自有模型平台是主适配器,OpenAI-compatible / 自定义 HTTP JSON 可接入,ComfyUI 只是 optional adapter。 - 本地执行器:API 启动时自动拉起 Worker,支持租约、并发限制、心跳、依赖阻塞、重试记录和管理员手动领取。 ## 运行 ```bash cd /Users/xz/Documents/daima/ai短剧/ai-drama-platform npm install npm run dev ``` 本地 API 服务: ```bash cd /Users/xz/Documents/daima/ai短剧/ai-drama-platform npm run api ``` 需要保持两个进程:Vite 前端和本地 API。API 进程会自动启动本地 Worker;只有需要独立调试 Worker 时才单独使用 `npm run worker`。启动后访问: ```text 前端:http://127.0.0.1:5173/ API:http://127.0.0.1:8787/api/health ``` 完整回归(必须串行执行,共 25 项,避免 SQLite 写入竞争): ```bash 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 默认地址: ```text 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= 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/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/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` 或不设置。 认证接口: ```text 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`。 ```text 系统管理员: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` 指定独立加密密钥。 登录后入口读取当前用户有权访问的组织、工作区和项目;新组织或空工作区会进入空项目工厂,不会自动复制其他项目的角色、资产、镜头或任务。仓库内的《雷雨口》只用于本地种子数据和回归测试。当前平台不会主动调用任何云端或付费节点;生成适配器配置在: ```text /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 环境变量、状态字段和接口返回约定见 `/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 音频请求格式见: ```text /Users/xz/Documents/daima/ai短剧/ai-drama-platform/docs/NEWAPI_AUDIO_WORKFLOW.md ``` ## 商业平台研究 功能研究与本地版能力映射见: ```text /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 ``` ## 输出目录 ```text /Users/xz/Documents/daima/ai短剧/ai-drama-platform/exports/ ``` 每个项目单独拥有一个子目录,子目录对应 series bible、角色、场景、道具、分镜、配音、QA、剪辑工程和最终视频交付;服务端不会把一个项目的导出写进另一个项目目录。