Files
waoowaoo/prisma/schema.sqlit.prisma

830 lines
31 KiB
Plaintext
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.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model Account {
id String @id @default(uuid())
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@index([userId])
@@map("account")
}
model CharacterAppearance {
id String @id @default(uuid())
characterId String
appearanceIndex Int
changeReason String
description String?
descriptions String?
imageUrl String?
imageUrls String?
selectedIndex Int?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
previousImageUrl String?
previousImageUrls String?
previousDescription String? // 上一次的描述词(用于撤回)
previousDescriptions String? // 上一次的描述词数组(用于撤回)
imageMediaId String?
imageMedia MediaObject? @relation("CharacterAppearanceImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
character NovelPromotionCharacter @relation(fields: [characterId], references: [id], onDelete: Cascade)
@@unique([characterId, appearanceIndex])
@@index([characterId])
@@index([imageMediaId])
@@map("character_appearances")
}
model LocationImage {
id String @id @default(uuid())
locationId String
imageIndex Int
description String?
imageUrl String?
isSelected Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
previousImageUrl String?
previousDescription String? // 上一次的描述词(用于撤回)
imageMediaId String?
imageMedia MediaObject? @relation("LocationImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
location NovelPromotionLocation @relation(fields: [locationId], references: [id], onDelete: Cascade)
@@unique([locationId, imageIndex])
@@index([locationId])
@@index([imageMediaId])
@@map("location_images")
}
model NovelPromotionCharacter {
id String @id @default(uuid())
novelPromotionProjectId String
name String
aliases String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
customVoiceUrl String?
customVoiceMediaId String?
customVoiceMedia MediaObject? @relation("NovelPromotionCharacterVoiceMedia", fields: [customVoiceMediaId], references: [id], onDelete: SetNull)
voiceId String?
voiceType String?
profileData String?
profileConfirmed Boolean @default(false)
introduction String? // 角色介绍(身份、关系、称呼映射,如"我"对应此角色)
sourceGlobalCharacterId String? // 🆕 来源全局角色ID复制时记录
appearances CharacterAppearance[]
novelPromotionProject NovelPromotionProject @relation(fields: [novelPromotionProjectId], references: [id], onDelete: Cascade)
@@index([novelPromotionProjectId])
@@index([customVoiceMediaId])
@@map("novel_promotion_characters")
}
model NovelPromotionLocation {
id String @id @default(uuid())
novelPromotionProjectId String
name String
summary String? // 场景简要描述(用途/人物关联)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
sourceGlobalLocationId String? // 🆕 来源全局场景ID复制时记录
images LocationImage[]
novelPromotionProject NovelPromotionProject @relation(fields: [novelPromotionProjectId], references: [id], onDelete: Cascade)
@@index([novelPromotionProjectId])
@@map("novel_promotion_locations")
}
model NovelPromotionEpisode {
id String @id @default(uuid())
novelPromotionProjectId String
episodeNumber Int
name String
description String?
novelText String?
audioUrl String?
audioMediaId String?
audioMedia MediaObject? @relation("NovelPromotionEpisodeAudioMedia", fields: [audioMediaId], references: [id], onDelete: SetNull)
srtContent String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
speakerVoices String?
clips NovelPromotionClip[]
novelPromotionProject NovelPromotionProject @relation(fields: [novelPromotionProjectId], references: [id], onDelete: Cascade)
shots NovelPromotionShot[]
storyboards NovelPromotionStoryboard[]
voiceLines NovelPromotionVoiceLine[]
editorProject VideoEditorProject?
@@unique([novelPromotionProjectId, episodeNumber])
@@index([novelPromotionProjectId])
@@index([audioMediaId])
@@map("novel_promotion_episodes")
}
// 视频编辑器项目 - 存储剪辑数据
model VideoEditorProject {
id String @id @default(uuid())
episodeId String @unique
projectData String // JSON 存储编辑项目数据
renderStatus String? // pending | rendering | completed | failed
renderTaskId String?
outputUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
episode NovelPromotionEpisode @relation(fields: [episodeId], references: [id], onDelete: Cascade)
@@map("video_editor_projects")
}
model NovelPromotionClip {
id String @id @default(uuid())
episodeId String
start Int?
end Int?
duration Int?
summary String
location String?
content String
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
characters String?
endText String?
shotCount Int?
startText String?
screenplay String?
episode NovelPromotionEpisode @relation(fields: [episodeId], references: [id], onDelete: Cascade)
shots NovelPromotionShot[]
storyboard NovelPromotionStoryboard?
@@index([episodeId])
@@map("novel_promotion_clips")
}
model NovelPromotionPanel {
id String @id @default(uuid())
storyboardId String
panelIndex Int
panelNumber Int?
shotType String?
cameraMove String?
description String?
location String?
characters String?
srtSegment String?
srtStart Float?
srtEnd Float?
duration Float?
imagePrompt String?
imageUrl String?
imageMediaId String?
imageMedia MediaObject? @relation("NovelPromotionPanelImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
imageHistory String?
videoPrompt String?
firstLastFramePrompt String?
videoUrl String?
videoGenerationMode String? // 视频生成方式normal | firstlastframe
videoMediaId String?
videoMedia MediaObject? @relation("NovelPromotionPanelVideoMedia", fields: [videoMediaId], references: [id], onDelete: SetNull)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
sceneType String?
candidateImages String?
linkedToNextPanel Boolean @default(false)
lipSyncTaskId String?
lipSyncVideoUrl String?
lipSyncVideoMediaId String?
lipSyncVideoMedia MediaObject? @relation("NovelPromotionPanelLipSyncVideoMedia", fields: [lipSyncVideoMediaId], references: [id], onDelete: SetNull)
sketchImageUrl String?
sketchImageMediaId String?
sketchImageMedia MediaObject? @relation("NovelPromotionPanelSketchMedia", fields: [sketchImageMediaId], references: [id], onDelete: SetNull)
photographyRules String?
actingNotes String? // 演技指导数据 JSON
previousImageUrl String?
previousImageMediaId String?
previousImageMedia MediaObject? @relation("NovelPromotionPanelPreviousImageMedia", fields: [previousImageMediaId], references: [id], onDelete: SetNull)
storyboard NovelPromotionStoryboard @relation(fields: [storyboardId], references: [id], onDelete: Cascade)
matchedVoiceLines NovelPromotionVoiceLine[]
@@unique([storyboardId, panelIndex])
@@index([storyboardId])
@@index([imageMediaId])
@@index([videoMediaId])
@@index([lipSyncVideoMediaId])
@@index([sketchImageMediaId])
@@index([previousImageMediaId])
@@map("novel_promotion_panels")
}
model NovelPromotionProject {
id String @id @default(uuid())
projectId String @unique
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
analysisModel String? // 用户配置的分析模型nullable必须配置后才能使用
imageModel String? // 用户配置的图片模型
videoModel String? // 用户配置的视频模型
videoRatio String @default("9:16")
ttsRate String @default("+50%")
globalAssetText String?
artStyle String @default("american-comic")
artStylePrompt String?
characterModel String? // 用户配置的角色图片模型
locationModel String? // 用户配置的场景图片模型
storyboardModel String? // 用户配置的分镜图片模型
editModel String? // 用户配置的修图/编辑模型
videoResolution String @default("720p")
capabilityOverrides String?
workflowMode String @default("srt")
lastEpisodeId String?
imageResolution String @default("2K")
importStatus String?
characters NovelPromotionCharacter[]
episodes NovelPromotionEpisode[]
locations NovelPromotionLocation[]
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
@@map("novel_promotion_projects")
}
model NovelPromotionShot {
id String @id @default(uuid())
episodeId String
clipId String?
shotId String
srtStart Int
srtEnd Int
srtDuration Float
sequence String?
locations String?
characters String?
plot String?
imagePrompt String?
scale String?
module String?
focus String?
zhSummarize String?
imageUrl String?
imageMediaId String?
imageMedia MediaObject? @relation("NovelPromotionShotImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
pov String?
clip NovelPromotionClip? @relation(fields: [clipId], references: [id], onDelete: Cascade)
episode NovelPromotionEpisode @relation(fields: [episodeId], references: [id], onDelete: Cascade)
@@index([clipId])
@@index([episodeId])
@@index([shotId])
@@index([imageMediaId])
@@map("novel_promotion_shots")
}
model NovelPromotionStoryboard {
id String @id @default(uuid())
episodeId String
clipId String @unique
storyboardImageUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
panelCount Int @default(9)
storyboardTextJson String?
imageHistory String?
candidateImages String?
lastError String?
photographyPlan String?
panels NovelPromotionPanel[]
clip NovelPromotionClip @relation(fields: [clipId], references: [id], onDelete: Cascade)
episode NovelPromotionEpisode @relation(fields: [episodeId], references: [id], onDelete: Cascade)
supplementaryPanels SupplementaryPanel[]
@@index([clipId])
@@index([episodeId])
@@map("novel_promotion_storyboards")
}
model SupplementaryPanel {
id String @id @default(uuid())
storyboardId String
sourceType String
sourcePanelId String?
description String?
imagePrompt String?
imageUrl String?
imageMediaId String?
imageMedia MediaObject? @relation("SupplementaryPanelImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
characters String?
location String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
storyboard NovelPromotionStoryboard @relation(fields: [storyboardId], references: [id], onDelete: Cascade)
@@index([storyboardId])
@@index([imageMediaId])
@@map("supplementary_panels")
}
model Project {
id String @id @default(uuid())
name String
description String?
mode String @default("novel-promotion")
userId String
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
lastAccessedAt DateTime?
novelPromotionData NovelPromotionProject?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
usageCosts UsageCost[]
@@index([userId])
@@map("projects")
}
model Session {
id String @id @default(uuid())
sessionToken String @unique(map: "Session_sessionToken_key")
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@map("session")
}
model UsageCost {
id String @id @default(uuid())
projectId String
userId String
apiType String
model String
action String
quantity Int
unit String
cost Decimal
metadata String?
createdAt DateTime @default(now())
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([apiType])
@@index([createdAt])
@@index([projectId])
@@index([userId])
@@map("usage_costs")
}
model User {
id String @id @default(uuid())
name String @unique(map: "User_name_key")
email String?
emailVerified DateTime?
image String?
password String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
accounts Account[]
projects Project[]
sessions Session[]
usageCosts UsageCost[]
balance UserBalance?
preferences UserPreference?
// 资产中心
globalAssetFolders GlobalAssetFolder[]
globalCharacters GlobalCharacter[]
globalLocations GlobalLocation[]
globalVoices GlobalVoice[]
tasks Task[]
taskEvents TaskEvent[]
@@map("user")
}
model UserPreference {
id String @id @default(uuid())
userId String @unique
analysisModel String? // 用户配置的分析模型nullable必须配置后才能使用
characterModel String? // 用户配置的角色图片模型
locationModel String? // 用户配置的场景图片模型
storyboardModel String? // 用户配置的分镜图片模型
editModel String? // 用户配置的修图模型
videoModel String? // 用户配置的视频模型
lipSyncModel String? // 用户配置的口型同步模型
videoRatio String @default("9:16")
videoResolution String @default("720p")
artStyle String @default("american-comic")
ttsRate String @default("+50%")
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
imageResolution String @default("2K")
capabilityDefaults String?
// API Key 配置(极简版)
llmBaseUrl String? @default("https://openrouter.ai/api/v1")
llmApiKey String? // 加密存储
falApiKey String? // FAL图片+视频+语音)
googleAiKey String? // Google AIGemini 图片)
arkApiKey String? // 火山引擎Seedream+Seedance
qwenApiKey String? // 阿里百炼(声音设计)
// 自定义模型列表 + 价格JSON
customModels String?
// 自定义 OpenAI 兼容提供商列表JSON包含加密的 API Key
customProviders String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("user_preferences")
}
model VerificationToken {
identifier String
token String @unique(map: "VerificationToken_token_key")
expires DateTime
@@unique([identifier, token])
@@map("verificationtoken")
}
model NovelPromotionVoiceLine {
id String @id @default(uuid())
episodeId String
lineIndex Int
speaker String
content String
voicePresetId String?
audioUrl String?
audioMediaId String?
audioMedia MediaObject? @relation("NovelPromotionVoiceLineAudioMedia", fields: [audioMediaId], references: [id], onDelete: SetNull)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
emotionPrompt String?
emotionStrength Float? @default(0.4)
matchedPanelIndex Int?
matchedStoryboardId String?
audioDuration Int?
matchedPanelId String?
episode NovelPromotionEpisode @relation(fields: [episodeId], references: [id], onDelete: Cascade)
matchedPanel NovelPromotionPanel? @relation(fields: [matchedPanelId], references: [id])
@@unique([episodeId, lineIndex])
@@index([episodeId])
@@index([matchedPanelId])
@@index([audioMediaId])
@@map("novel_promotion_voice_lines")
}
model VoicePreset {
id String @id @default(uuid())
name String
audioUrl String
audioMediaId String?
audioMedia MediaObject? @relation("VoicePresetAudioMedia", fields: [audioMediaId], references: [id], onDelete: SetNull)
description String?
gender String?
isSystem Boolean @default(true)
createdAt DateTime @default(now())
@@index([audioMediaId])
@@map("voice_presets")
}
model UserBalance {
id String @id @default(uuid())
userId String @unique
balance Decimal @default(0)
frozenAmount Decimal @default(0)
totalSpent Decimal @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("user_balances")
}
model BalanceFreeze {
id String @id @default(uuid())
userId String
amount Decimal
status String @default("pending")
source String?
taskId String?
requestId String?
idempotencyKey String? @unique
metadata String?
expiresAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@index([userId])
@@index([status])
@@index([taskId])
@@map("balance_freezes")
}
model BalanceTransaction {
id String @id @default(uuid())
userId String
type String
amount Decimal
balanceAfter Decimal
description String?
relatedId String?
freezeId String?
operatorId String?
externalOrderId String?
idempotencyKey String?
createdAt DateTime @default(now())
@@index([userId])
@@index([type])
@@index([createdAt])
@@index([freezeId])
@@index([externalOrderId])
@@unique([userId, type, idempotencyKey])
@@map("balance_transactions")
}
model Task {
id String @id @default(uuid())
userId String
projectId String
episodeId String?
type String
targetType String
targetId String
status String @default("queued")
progress Int @default(0)
attempt Int @default(0)
maxAttempts Int @default(5)
priority Int @default(0)
dedupeKey String? @unique
externalId String?
payload Json?
result Json?
errorCode String?
errorMessage String?
billingInfo Json?
billedAt DateTime?
queuedAt DateTime @default(now())
startedAt DateTime?
finishedAt DateTime?
heartbeatAt DateTime?
enqueuedAt DateTime?
enqueueAttempts Int @default(0)
lastEnqueueError String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
events TaskEvent[]
@@index([status])
@@index([type])
@@index([targetType, targetId])
@@index([projectId])
@@index([userId])
@@index([heartbeatAt])
@@map("tasks")
}
model TaskEvent {
id Int @id @default(autoincrement())
taskId String
projectId String
userId String
eventType String
payload Json?
createdAt DateTime @default(now())
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([projectId, id])
@@index([taskId])
@@index([userId])
@@map("task_events")
}
// ==================== 资产中心 ====================
// 资产文件夹(一层,不支持嵌套)
model GlobalAssetFolder {
id String @id @default(uuid())
userId String
name String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
characters GlobalCharacter[]
locations GlobalLocation[]
voices GlobalVoice[]
@@index([userId])
@@map("global_asset_folders")
}
// 全局角色(结构与 NovelPromotionCharacter 一致)
model GlobalCharacter {
id String @id @default(uuid())
userId String
folderId String?
name String
aliases String?
profileData String?
profileConfirmed Boolean @default(false)
voiceId String?
voiceType String?
customVoiceUrl String?
customVoiceMediaId String?
customVoiceMedia MediaObject? @relation("GlobalCharacterVoiceMedia", fields: [customVoiceMediaId], references: [id], onDelete: SetNull)
globalVoiceId String? // 绑定的全局音色 ID
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
folder GlobalAssetFolder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
appearances GlobalCharacterAppearance[]
@@index([userId])
@@index([folderId])
@@index([customVoiceMediaId])
@@map("global_characters")
}
// 全局角色形象(结构与 CharacterAppearance 一致)
model GlobalCharacterAppearance {
id String @id @default(uuid())
characterId String
appearanceIndex Int
changeReason String @default("default")
description String?
descriptions String?
imageUrl String?
imageMediaId String?
imageMedia MediaObject? @relation("GlobalCharacterAppearanceImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
imageUrls String?
selectedIndex Int?
previousImageUrl String?
previousImageMediaId String?
previousImageMedia MediaObject? @relation("GlobalCharacterAppearancePreviousImageMedia", fields: [previousImageMediaId], references: [id], onDelete: SetNull)
previousImageUrls String?
previousDescription String? // 上一次的描述词(用于撤回)
previousDescriptions String? // 上一次的描述词数组(用于撤回)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
character GlobalCharacter @relation(fields: [characterId], references: [id], onDelete: Cascade)
@@unique([characterId, appearanceIndex])
@@index([characterId])
@@index([imageMediaId])
@@index([previousImageMediaId])
@@map("global_character_appearances")
}
// 全局场景(结构与 NovelPromotionLocation 一致)
model GlobalLocation {
id String @id @default(uuid())
userId String
folderId String?
name String
summary String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
folder GlobalAssetFolder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
images GlobalLocationImage[]
@@index([userId])
@@index([folderId])
@@map("global_locations")
}
// 全局场景图片(结构与 LocationImage 一致)
model GlobalLocationImage {
id String @id @default(uuid())
locationId String
imageIndex Int
description String?
imageUrl String?
imageMediaId String?
imageMedia MediaObject? @relation("GlobalLocationImageMedia", fields: [imageMediaId], references: [id], onDelete: SetNull)
isSelected Boolean @default(false)
previousImageUrl String?
previousImageMediaId String?
previousImageMedia MediaObject? @relation("GlobalLocationImagePreviousImageMedia", fields: [previousImageMediaId], references: [id], onDelete: SetNull)
previousDescription String? // 上一次的描述词(用于撤回)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
location GlobalLocation @relation(fields: [locationId], references: [id], onDelete: Cascade)
@@unique([locationId, imageIndex])
@@index([locationId])
@@index([imageMediaId])
@@index([previousImageMediaId])
@@map("global_location_images")
}
// 全局音色库
model GlobalVoice {
id String @id @default(uuid())
userId String
folderId String?
name String // 音色名称
description String? // 详细描述
voiceId String? // qwen-tts-vd 的 voice ID
voiceType String @default("qwen-designed") // qwen-designed | custom
customVoiceUrl String? // 上传的音频 URL预览用
customVoiceMediaId String?
customVoiceMedia MediaObject? @relation("GlobalVoiceCustomVoiceMedia", fields: [customVoiceMediaId], references: [id], onDelete: SetNull)
voicePrompt String? // AI 设计时的提示词
gender String? // male | female | neutral
language String @default("zh")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
folder GlobalAssetFolder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
@@index([userId])
@@index([folderId])
@@index([customVoiceMediaId])
@@map("global_voices")
}
model MediaObject {
id String @id @default(uuid())
publicId String @unique
storageKey String @unique
sha256 String?
mimeType String?
sizeBytes BigInt?
width Int?
height Int?
durationMs Int?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
characterAppearanceImages CharacterAppearance[] @relation("CharacterAppearanceImageMedia")
locationImages LocationImage[] @relation("LocationImageMedia")
novelPromotionCharacterVoices NovelPromotionCharacter[] @relation("NovelPromotionCharacterVoiceMedia")
novelPromotionEpisodeAudios NovelPromotionEpisode[] @relation("NovelPromotionEpisodeAudioMedia")
novelPromotionPanelImages NovelPromotionPanel[] @relation("NovelPromotionPanelImageMedia")
novelPromotionPanelVideos NovelPromotionPanel[] @relation("NovelPromotionPanelVideoMedia")
novelPromotionPanelLipSyncVideos NovelPromotionPanel[] @relation("NovelPromotionPanelLipSyncVideoMedia")
novelPromotionPanelSketchImages NovelPromotionPanel[] @relation("NovelPromotionPanelSketchMedia")
novelPromotionPanelPreviousImages NovelPromotionPanel[] @relation("NovelPromotionPanelPreviousImageMedia")
novelPromotionShotImages NovelPromotionShot[] @relation("NovelPromotionShotImageMedia")
supplementaryPanelImages SupplementaryPanel[] @relation("SupplementaryPanelImageMedia")
novelPromotionVoiceLineAudios NovelPromotionVoiceLine[] @relation("NovelPromotionVoiceLineAudioMedia")
voicePresetAudios VoicePreset[] @relation("VoicePresetAudioMedia")
globalCharacterVoices GlobalCharacter[] @relation("GlobalCharacterVoiceMedia")
globalCharacterAppearanceImages GlobalCharacterAppearance[] @relation("GlobalCharacterAppearanceImageMedia")
globalCharacterAppearancePreviousImgs GlobalCharacterAppearance[] @relation("GlobalCharacterAppearancePreviousImageMedia")
globalLocationImageImages GlobalLocationImage[] @relation("GlobalLocationImageMedia")
globalLocationImagePreviousImages GlobalLocationImage[] @relation("GlobalLocationImagePreviousImageMedia")
globalVoiceCustomVoices GlobalVoice[] @relation("GlobalVoiceCustomVoiceMedia")
@@index([createdAt])
@@map("media_objects")
}
model LegacyMediaRefBackup {
id String @id @default(uuid())
runId String
tableName String
rowId String
fieldName String
legacyValue String
checksum String
createdAt DateTime @default(now())
@@index([runId])
@@index([tableName, fieldName])
@@map("legacy_media_refs_backup")
}