Files
ai-drama-platform/docs/MULTI_TENANT_DESIGN.md

108 lines
6.5 KiB
Markdown
Raw Permalink 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.
# 商业化多组织、多工作区设计
## 目标
`ai-drama-platform` 的商业形态不是“一个剧集的生产页面”,而是一个可以私有部署、承载多个内容公司的 AI 短剧/漫剧生产中台。所有生产数据都必须从组织和工作区上下文开始,任务、资产、审片和交付都不能脱离租户边界。
本地 MVP 使用 Node 24 内置 `node:sqlite`,已经接入邮箱 + 密码登录、scrypt 密码哈希和 Bearer session。仅在显式设置 `AI_DRAMA_ALLOW_DEV_CONTEXT=1` 的本地调试场景下,才允许请求头模拟上下文;默认运行模式是 session-only。后续替换为 SSO/OIDC 时,只需要替换身份解析层,不改变业务表和 scope 查询。
## 产品层级
```text
用户 User
└── 组织 Organization(公司 / 内容厂牌 / 客户租户)
├── 组织成员 Organization Member
├── 套餐、账单、配额、策略
└── 工作区 Workspace(制作部 / 项目组 / 客户空间)
├── 工作区成员 Workspace Member
├── 项目 Project(系列 / 模板 / 客户项目)
│ ├── 季 / 集 / 剧本 / 资产锁 / 分镜
│ ├── 生成任务 / 尝试记录 / 审片 / 合规
│ └── 交付版本 / 发布渠道
└── 模型连接器、Runner、资产存储策略
```
组织解决客户和计费隔离,工作区解决团队协作隔离,项目解决内容访问和交付隔离。一个用户可以加入多个组织,在同一组织中进入多个工作区;普通工作区成员默认可以访问工作区项目,项目级邀请则使用 `workspace_members.access_mode = project-only` 和 `project_guest` 角色,只能进入显式授权的项目。
## 角色模型
| 作用域 | 角色 | 典型能力 |
| --- | --- | --- |
| 组织 | `org_owner` | 组织设置、成员、账单、模型策略、全项目可见 |
| 组织 | `org_admin` | 成员、工作区、模型和审计管理 |
| 工作区 | `producer` | 建项目、排队、批次、成本、交付审批 |
| 工作区 | `writer` | 剧本、分集、对白、镜头草稿 |
| 工作区 | `art_director` | 角色/场景/道具锁、参考图、prompt、连续性 |
| 工作区 | `voice_editor` | 声线锁、TTS、字幕、ASR 对齐 |
| 工作区 | `reviewer` | QA、审片意见、通过/驳回 |
| 工作区 | `project_guest` | 只进入被授权项目,不继承工作区其他项目和生成权限 |
| 项目 | `project_editor` | 指定项目内容编辑 |
| 项目 | `project_viewer` | 只读查看、下载被授权的交付物 |
权限不是写死在前端。API 根据 `organization_members`、`workspace_members`、`project_members` 合并角色权限,并在每个项目、任务、模型、交付接口执行检查。前端显示权限矩阵只是帮助用户理解,不能作为安全边界。
## 数据表
### 身份和租户
- `users`:用户身份、显示名、邮箱、状态。
- `organizations`:租户、slug、部署模式、所有者。
- `organization_members`:用户加入组织的角色、邀请状态。
- `workspaces`:组织下的生产空间。
- `workspace_members`:工作区角色和访问范围;`access_mode=project-only` 只允许显式 `project_members` 项目。
- `projects`:工作区下的系列、模板或客户项目。
- `project_members`:项目级额外授权。
- `invitations`:待接受邀请,不把邀请误当作已加入成员。
### 生产和中台
- `series`、`seasons`、`episodes`:剧集结构。
- `assets`、`asset_versions`:角色、场景、道具、参考图、首尾帧、音频和视频资产版本。
- `shots`:分镜、首帧/末帧、镜头状态和 continuity lock 引用。
- `generation_jobs`、`job_attempts`:任务、重试、取消、执行器和输出。
- `reviews`、`review_comments`:审片 lane、QA gate、意见和决策。
- `model_connectors`:自有模型平台、HTTP JSON、OpenAI-compatible、ComfyUI optional adapter。
- `deliveries`:剪辑清单、字幕、封面、master 和发布渠道。
### 商业治理
- `billing_accounts`:套餐、席位、存储、片段额度和云连接策略。
- `quota_allocations`、`usage_events`:配额和按任务的用量计量。
- `compliance_records`:原创/IP、肖像权、声音权、参考素材来源、单画面检查。
- `audit_logs`:谁在什么组织/工作区/项目中做了什么操作,以及结果和元数据。
## 请求上下文
本地调试 bypass 使用以下请求头,缺省时使用种子账号和种子工作区;真实浏览器请求必须携带登录后的 Bearer session:
```text
x-user-id: u-owner
x-organization-id: org-studio-lab
x-workspace-id: ws-local-aidrama
x-project-id: thunder-mouth
```
真实部署必须由登录会话或网关注入用户身份,禁止让客户端直接提交任意组织 ID 后绕过 membership 检查。API 的最小检查顺序是:
1. 用户存在且状态为 active。
2. 用户是组织成员,且组织状态可用。
3. 工作区属于当前组织,用户拥有工作区 membership。
4. 项目属于当前工作区,用户拥有项目 membership 或工作区角色允许继承访问。
5. 当前角色拥有该动作所需权限。
6. 记录 audit log,涉及生成、下载、模型调用和导出时记录 usage event。
## AI 短剧生产的业务硬门
这些约束属于组织策略或项目策略,不能只放在 prompt 文本里:
- `single_frame_only`:每个图片生成任务只能输出一张连续完整画面,拒绝 split-screen、漫画多格、storyboard、collage、contact sheet。
- `continuity_lock_required`:角色、服装、道具、场景、天气、镜头角度、声线必须有 lock 和 ledger。
- `actual_last_frame_chain`:后续视频优先引用上一段真实末帧,不能只引用描述性文本。
- `voice_lock_required`:对白使用固定声线;MiniMax H3 随机原生声音不作为最终角色声线。
- `mouth_safe_shot_policy`:口型不稳定时优先侧脸、背影、低头、远景、反应镜头或环境插入镜头。
- `local_runner_only`:默认只允许本地/自有模型;云端节点必须显式审批并留下审计记录。
## MVP 与后续
当前可运行 MVP 先交付真实的租户、成员、权限、项目 scope、邀请、审计、用量和模型注册接口,生产资产表和任务表已经预留。下一阶段可以把认证、Redis/BullMQ 队列、对象存储、ffmpeg 合成和真实 Runner 接入,不需要重做组织模型。