feat: add style kit production standards
This commit is contained in:
+186
-9
@@ -247,6 +247,8 @@ function seedRoles() {
|
||||
["task:view", "查看项目协作任务"],
|
||||
["task:manage", "创建、分派和管理项目协作任务"],
|
||||
["task:complete", "更新本人负责的协作任务状态"],
|
||||
["style:read", "查看组织、工作区和项目风格生产标准"],
|
||||
["style:manage", "管理风格标准、品牌规范和项目绑定"],
|
||||
["script:edit", "编辑剧本和对白"],
|
||||
["script:read", "查看剧本、分集和镜头"],
|
||||
["asset:edit", "编辑角色、场景和道具锁"],
|
||||
@@ -283,17 +285,17 @@ function seedRoles() {
|
||||
org_admin: [
|
||||
"organization:manage", "organization:members:invite", "workspace:create", "workspace:manage",
|
||||
"workspace:members:manage", "project:create", "project:manage", "project:members:manage",
|
||||
"workflow:manage", "task:view", "task:manage", "task:complete", "model:manage", "model:approve", "usage:view", "billing:manage", "quota:manage", "qa:review", "delivery:approve", "delivery:view", "compliance:manage", "audit:view", "queue:manage", "voice:approve",
|
||||
"workflow:manage", "task:view", "task:manage", "task:complete", "style:read", "style:manage", "model:manage", "model:approve", "usage:view", "billing:manage", "quota:manage", "qa:review", "delivery:approve", "delivery:view", "compliance:manage", "audit:view", "queue:manage", "voice:approve",
|
||||
"system:settings:view", "service:health:view", "organization:roles:manage"
|
||||
],
|
||||
producer: ["project:create", "project:manage", "project:members:manage", "workflow:manage", "task:view", "task:manage", "task:complete", "script:read", "job:create", "job:prioritize", "usage:view", "delivery:approve", "delivery:view", "voice:approve"],
|
||||
writer: ["script:read", "script:edit", "task:view", "task:complete", "job:create"],
|
||||
art_director: ["asset:edit", "prompt:edit", "task:view", "task:complete", "job:create"],
|
||||
voice_editor: ["voice:edit", "voice:approve", "task:view", "task:complete", "job:create"],
|
||||
reviewer: ["script:read", "task:view", "task:complete", "qa:review", "voice:approve", "delivery:view"],
|
||||
project_guest: ["script:read", "task:view", "delivery:view"],
|
||||
project_editor: ["script:read", "script:edit", "asset:edit", "prompt:edit", "voice:edit", "task:view", "task:manage", "task:complete", "job:create", "delivery:view"],
|
||||
project_viewer: ["script:read", "task:view", "delivery:view"]
|
||||
producer: ["project:create", "project:manage", "project:members:manage", "workflow:manage", "task:view", "task:manage", "task:complete", "style:read", "style:manage", "script:read", "job:create", "job:prioritize", "usage:view", "delivery:approve", "delivery:view", "voice:approve"],
|
||||
writer: ["script:read", "script:edit", "task:view", "task:complete", "style:read", "job:create"],
|
||||
art_director: ["asset:edit", "prompt:edit", "task:view", "task:complete", "style:read", "style:manage", "job:create"],
|
||||
voice_editor: ["voice:edit", "voice:approve", "task:view", "task:complete", "style:read", "job:create"],
|
||||
reviewer: ["script:read", "task:view", "task:complete", "style:read", "qa:review", "voice:approve", "delivery:view"],
|
||||
project_guest: ["script:read", "task:view", "style:read", "delivery:view"],
|
||||
project_editor: ["script:read", "script:edit", "asset:edit", "prompt:edit", "voice:edit", "task:view", "task:manage", "task:complete", "style:read", "job:create", "delivery:view"],
|
||||
project_viewer: ["script:read", "task:view", "style:read", "delivery:view"]
|
||||
};
|
||||
for (const [roleKey, permissionKeys] of Object.entries(rolePermissions)) {
|
||||
for (const permissionKey of permissionKeys) {
|
||||
@@ -362,6 +364,7 @@ function commercialEntitlementDefaults(billing = {}) {
|
||||
["limit.workspaces", "工作区数量", "tenant", 8, "个", 1, "block", { commercialGate: "workspace:create" }],
|
||||
["limit.projects", "项目数量", "production", 36, "个", 1, "block", { commercialGate: "project:create" }],
|
||||
["limit.generation_jobs_monthly", "月度生成任务", "production", clipLimit, "job", 1, "block", { commercialGate: "generation_job:create" }],
|
||||
["limit.style_kits", "风格生产标准", "production", 24, "套", 1, "block", { commercialGate: "style_kit:create" }],
|
||||
["limit.storage_gb", "存储容量", "storage", storageGb, "GB", 1, "block", { commercialGate: "storage:write" }],
|
||||
["limit.model_connectors", "模型连接器", "modelops", 16, "个", 1, "block", { commercialGate: "model_connector:create" }],
|
||||
["limit.api_clients", "API 客户端", "system", 8, "个", 1, "block", { commercialGate: "api_client:create" }],
|
||||
@@ -604,6 +607,179 @@ function seedModelRoutes() {
|
||||
}
|
||||
}
|
||||
|
||||
function seedStyleKits() {
|
||||
const timestamp = now();
|
||||
const kits = [
|
||||
{
|
||||
id: "stylekit-studio-guoman-vertical",
|
||||
organizationId: "org-studio-lab",
|
||||
workspaceId: "ws-local-aidrama",
|
||||
projectId: null,
|
||||
scopeMode: "workspace",
|
||||
name: "星河国漫竖屏生产标准",
|
||||
description: "工作区默认商用风格标准:原创国漫 2D、9:16、固定字幕与声线策略,所有关键帧强制单画面。",
|
||||
status: "active",
|
||||
visualProfile: {
|
||||
styleFamily: "国产漫画 / 国漫 2D 动画",
|
||||
linework: "干净线稿、清晰轮廓、轻赛璐璐阴影",
|
||||
colorScript: "雷雨青绿、暖肤色、低饱和环境光",
|
||||
cameraLanguage: "稳定中景、反应镜头、环境插入镜头优先",
|
||||
continuityLocks: ["character", "costume", "location", "prop", "weather", "camera"]
|
||||
},
|
||||
subtitlePreset: {
|
||||
language: "zh-CN",
|
||||
fontFamily: "PingFang SC / Noto Sans SC",
|
||||
position: "bottom-safe-area",
|
||||
maxCharsPerLine: 18,
|
||||
style: "白字深色描边,避免遮挡人物脸部和关键道具"
|
||||
},
|
||||
voicePolicy: {
|
||||
finalVoiceMode: "fixed-reference-required",
|
||||
forbidRandomNativeVoice: true,
|
||||
ttsPreference: "local-or-owned-first",
|
||||
fallbackMouthPlan: ["侧脸", "背影", "低头", "远景", "反应镜头", "环境插入镜头"]
|
||||
},
|
||||
deliverySpec: {
|
||||
aspectRatio: "9:16",
|
||||
resolution: "1080x1920",
|
||||
fps: 24,
|
||||
clipDurationSec: [5, 10],
|
||||
exportFormat: "mp4",
|
||||
projectFolder: "exports/{projectId}"
|
||||
},
|
||||
promptRules: {
|
||||
positivePrefix: "ONE SINGLE COMPLETE 9:16 CHINESE ANIMATION FRAME, one continuous scene, one complete image.",
|
||||
negativeTerms: ["split-screen", "comic panel", "collage", "contact sheet", "storyboard", "多格", "拼图", "分屏", "故事板拼图"],
|
||||
renderNotes: ["角色服装、道具、天气和机位必须继承 continuity ledger", "每次图片生成 batch size 固定为 1"]
|
||||
},
|
||||
singleFramePolicy: {
|
||||
enabled: true,
|
||||
imageOutputCount: 1,
|
||||
batchSize: 1,
|
||||
forbiddenTerms: ["split-screen", "comic panel", "collage", "contact sheet", "storyboard", "多格", "拼图", "分屏", "多时间点"],
|
||||
requiredPhrase: "one single complete frame"
|
||||
},
|
||||
namingRules: {
|
||||
shotPattern: "{projectId}/S{season}E{episode}/shot-{shotNumber}-{assetKind}-{version}",
|
||||
subtitlePattern: "{episodeId}-{voiceLineId}.srt",
|
||||
deliveryPattern: "{projectName}-{episodeId}-{releaseVersion}"
|
||||
},
|
||||
qaPolicy: {
|
||||
gates: ["single-frame", "continuity", "voice-rights", "subtitle-asr-alignment", "clip-transition"],
|
||||
minimumReviewScore: 90,
|
||||
requireLockedAssets: true
|
||||
},
|
||||
metadata: {
|
||||
source: "seed://style-kits/studio-guoman-vertical",
|
||||
commercialReference: "brand-kit-style-guide-production-standard"
|
||||
},
|
||||
bindProjectId: "thunder-mouth",
|
||||
bindingNotes: "《雷雨口》商用 MVP 默认继承工作区国漫竖屏生产标准。"
|
||||
},
|
||||
{
|
||||
id: "stylekit-northstar-fog-pilot",
|
||||
organizationId: "org-northstar",
|
||||
workspaceId: "ws-northstar-main",
|
||||
projectId: "northstar-pilot",
|
||||
scopeMode: "project",
|
||||
name: "北辰雾境试播标准",
|
||||
description: "北辰内容厂牌专用试播标准,用于验证跨组织隔离和项目级风格绑定。",
|
||||
status: "active",
|
||||
visualProfile: {
|
||||
styleFamily: "原创国漫 2D 奇幻",
|
||||
linework: "偏硬朗线条、雾中高反差边缘光",
|
||||
colorScript: "冷雾灰、青铜色、少年角色暖色点光",
|
||||
cameraLanguage: "稳定中景与环境压迫感,禁止多格构图",
|
||||
continuityLocks: ["character", "location", "prop", "weather", "camera"]
|
||||
},
|
||||
subtitlePreset: {
|
||||
language: "zh-CN",
|
||||
fontFamily: "PingFang SC",
|
||||
position: "bottom-safe-area",
|
||||
maxCharsPerLine: 16,
|
||||
style: "白字深描边"
|
||||
},
|
||||
voicePolicy: {
|
||||
finalVoiceMode: "fixed-reference-required",
|
||||
forbidRandomNativeVoice: true,
|
||||
ttsPreference: "local-runner-only",
|
||||
fallbackMouthPlan: ["远景", "侧脸", "反应镜头"]
|
||||
},
|
||||
deliverySpec: {
|
||||
aspectRatio: "9:16",
|
||||
resolution: "1080x1920",
|
||||
fps: 24,
|
||||
clipDurationSec: [5, 8],
|
||||
exportFormat: "mp4",
|
||||
projectFolder: "exports/{projectId}"
|
||||
},
|
||||
promptRules: {
|
||||
positivePrefix: "ONE SINGLE COMPLETE 9:16 CHINESE ANIMATION FRAME, fantasy fog gate, one scene only.",
|
||||
negativeTerms: ["split-screen", "comic panel", "collage", "contact sheet", "storyboard", "多格", "分屏"],
|
||||
renderNotes: ["不得串用星河实验室角色或道具", "首尾帧必须来自当前项目"]
|
||||
},
|
||||
singleFramePolicy: {
|
||||
enabled: true,
|
||||
imageOutputCount: 1,
|
||||
batchSize: 1,
|
||||
forbiddenTerms: ["split-screen", "comic panel", "collage", "contact sheet", "storyboard", "多格", "拼图", "分屏"],
|
||||
requiredPhrase: "one single complete frame"
|
||||
},
|
||||
namingRules: {
|
||||
shotPattern: "{projectId}/pilot/shot-{shotNumber}-{version}",
|
||||
subtitlePattern: "{projectId}-{voiceLineId}.srt",
|
||||
deliveryPattern: "{projectName}-pilot-{releaseVersion}"
|
||||
},
|
||||
qaPolicy: {
|
||||
gates: ["single-frame", "cross-org-isolation", "continuity", "clip-transition"],
|
||||
minimumReviewScore: 92,
|
||||
requireLockedAssets: true
|
||||
},
|
||||
metadata: {
|
||||
source: "seed://style-kits/northstar-fog-pilot",
|
||||
commercialReference: "tenant-isolated-production-standard"
|
||||
},
|
||||
bindProjectId: "northstar-pilot",
|
||||
bindingNotes: "北辰试播项目强制使用项目级雾境风格标准。"
|
||||
}
|
||||
];
|
||||
for (const kit of kits) {
|
||||
insertIgnore(
|
||||
`INSERT OR IGNORE INTO style_kits(
|
||||
id, organization_id, workspace_id, project_id, scope_mode, name, description, status,
|
||||
visual_profile_json, subtitle_preset_json, voice_policy_json, delivery_spec_json,
|
||||
prompt_rules_json, single_frame_policy_json, naming_rules_json, qa_policy_json,
|
||||
metadata_json, created_by, created_at, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'u-owner', ?, ?)`,
|
||||
[
|
||||
kit.id,
|
||||
kit.organizationId,
|
||||
kit.workspaceId,
|
||||
kit.projectId,
|
||||
kit.scopeMode,
|
||||
kit.name,
|
||||
kit.description,
|
||||
kit.status,
|
||||
JSON.stringify(kit.visualProfile),
|
||||
JSON.stringify(kit.subtitlePreset),
|
||||
JSON.stringify(kit.voicePolicy),
|
||||
JSON.stringify(kit.deliverySpec),
|
||||
JSON.stringify(kit.promptRules),
|
||||
JSON.stringify(kit.singleFramePolicy),
|
||||
JSON.stringify(kit.namingRules),
|
||||
JSON.stringify(kit.qaPolicy),
|
||||
JSON.stringify(kit.metadata),
|
||||
timestamp,
|
||||
timestamp
|
||||
]
|
||||
);
|
||||
insertIgnore(
|
||||
"INSERT OR IGNORE INTO project_style_kit_bindings(id, organization_id, workspace_id, project_id, style_kit_id, enforcement, notes, created_by, created_at, updated_at) VALUES (?, ?, ?, ?, ?, 'strict', ?, 'u-owner', ?, ?)",
|
||||
[`binding-${kit.bindProjectId}-style-kit`, kit.organizationId, kit.workspaceId, kit.bindProjectId, kit.id, kit.bindingNotes, timestamp, timestamp]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function seedKnowledgeLibrary() {
|
||||
const timestamp = now();
|
||||
const content = [
|
||||
@@ -1068,6 +1244,7 @@ withTransaction(() => {
|
||||
seedModels();
|
||||
seedModelCatalog();
|
||||
seedModelRoutes();
|
||||
seedStyleKits();
|
||||
seedSystemGovernance();
|
||||
seedWorkflowTemplates();
|
||||
seedProductionGraph();
|
||||
|
||||
Reference in New Issue
Block a user