Initial AI manga platform

This commit is contained in:
www
2026-06-15 17:45:28 +08:00
commit 7a8191650f
267 changed files with 105987 additions and 0 deletions
+826
View File
@@ -0,0 +1,826 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id BigInt @id @default(autoincrement())
email String? @unique @db.VarChar(191)
phone String? @unique @db.VarChar(50)
password_hash String @db.VarChar(255)
nickname String? @db.VarChar(100)
avatar_url String? @db.VarChar(500)
role String @default("user") @db.VarChar(50)
status String @default("active") @db.VarChar(50)
wechat_openid String? @unique @db.VarChar(191)
last_login_at DateTime?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([role, status])
@@index([created_at])
@@map("users")
}
model Project {
id BigInt @id @default(autoincrement())
user_id BigInt
title String? @db.VarChar(255)
input_mode String @db.VarChar(50)
genre String? @db.VarChar(100)
style_code String? @db.VarChar(100)
output_type String? @db.VarChar(50)
output_mode String @default("image_manga") @db.VarChar(50)
visual_mode String? @db.VarChar(100)
video_generation_level String? @db.VarChar(50)
target_episode_count Int?
episode_duration Int?
status String @default("draft") @db.VarChar(80)
copyright_status String @default("pending") @db.VarChar(80)
payment_status String @default("unpaid") @db.VarChar(80)
quality_level String? @db.VarChar(50)
is_long_series Boolean @default(false)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
completed_at DateTime?
@@index([user_id, status])
@@index([genre, status])
@@index([created_at])
@@map("projects")
}
model NovelSource {
id BigInt @id @default(autoincrement())
project_id BigInt
source_type String @db.VarChar(50)
title String? @db.VarChar(255)
author_name String? @db.VarChar(100)
raw_asset_id BigInt?
raw_text String? @db.LongText
clean_text String? @db.LongText
word_count Int?
chapter_count Int?
parse_status String @default("pending") @db.VarChar(50)
parse_report Json?
created_at DateTime @default(now())
@@index([project_id])
@@index([parse_status])
@@map("novel_sources")
}
model NovelChapter {
id BigInt @id @default(autoincrement())
project_id BigInt
novel_source_id BigInt?
chapter_no Int
title String? @db.VarChar(255)
content String @db.LongText
summary String? @db.Text
visual_summary String? @db.Text
word_count Int?
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
@@unique([novel_source_id, chapter_no])
@@index([project_id, chapter_no])
@@index([project_id, status])
@@map("novel_chapters")
}
model CopyrightRecord {
id BigInt @id @default(autoincrement())
project_id BigInt
user_id BigInt
authorization_type String @db.VarChar(50)
statement_text String @db.Text
ip String? @db.VarChar(80)
user_agent String? @db.Text
confirmed_at DateTime @default(now())
@@index([project_id])
@@index([user_id])
@@index([authorization_type])
@@map("copyright_records")
}
model StoryBible {
id BigInt @id @default(autoincrement())
project_id BigInt
title String? @db.VarChar(255)
logline String? @db.Text
main_plot String? @db.Text
core_conflict String? @db.Text
selling_points String? @db.Text
tone String? @db.VarChar(100)
world_summary String? @db.Text
ending_direction String? @db.Text
taboo_rules String? @db.Text
version Int @default(1)
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id, status])
@@map("story_bibles")
}
model WorldBible {
id BigInt @id @default(autoincrement())
project_id BigInt
world_type String? @db.VarChar(100)
setting_text String? @db.Text
rules_text String? @db.Text
power_system String? @db.Text
social_structure String? @db.Text
time_period String? @db.Text
visual_rules String? @db.Text
forbidden_rules String? @db.Text
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
@@index([project_id, status])
@@map("world_bibles")
}
model Character {
id BigInt @id @default(autoincrement())
project_id BigInt
global_character_id BigInt?
name String @db.VarChar(100)
alias_names Json?
role_type String @db.VarChar(50)
gender_label String? @db.VarChar(50)
age_group String? @db.VarChar(50)
identity_desc String? @db.Text
appearance_desc String? @db.Text
face_desc String? @db.Text
hair_desc String? @db.Text
eye_desc String? @db.Text
body_desc String? @db.Text
costume_rules String? @db.Text
special_props String? @db.Text
personality_desc String? @db.Text
speech_style String? @db.Text
relationship_desc String? @db.Text
character_arc String? @db.Text
negative_rules String? @db.Text
anchor_asset_id BigInt?
wardrobe_variant String? @db.VarChar(100)
voice_provider_code String? @db.VarChar(100)
voice_model String? @db.VarChar(100)
voice_id String? @db.VarChar(100)
voice_style String? @db.Text
performance_style String? @db.Text
importance_level Int @default(0)
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id, role_type])
@@index([project_id, status])
@@index([global_character_id])
@@map("characters")
}
model GlobalCharacter {
id BigInt @id @default(autoincrement())
name String @db.VarChar(100)
display_name String? @db.VarChar(100)
role_archetype String @default("lead") @db.VarChar(50)
gender_label String? @db.VarChar(50)
age_group String? @db.VarChar(50)
identity_desc String? @db.Text
appearance_desc String? @db.Text
face_desc String? @db.Text
hair_desc String? @db.Text
eye_desc String? @db.Text
body_desc String? @db.Text
default_costume_rules String? @db.Text
wardrobe_json Json?
special_props String? @db.Text
personality_desc String? @db.Text
speech_style String? @db.Text
voice_provider_code String? @db.VarChar(100)
voice_model String? @db.VarChar(100)
voice_id String? @db.VarChar(100)
voice_style String? @db.Text
performance_style String? @db.Text
negative_rules String? @db.Text
anchor_asset_id BigInt?
voice_sample_asset_id BigInt?
commercial_status String @default("internal_test") @db.VarChar(50)
usage_scope String @default("internal") @db.VarChar(50)
status String @default("active") @db.VarChar(50)
created_by_user_id BigInt?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([status, role_archetype])
@@index([commercial_status])
@@index([created_by_user_id])
@@map("global_characters")
}
model GlobalCharacterAsset {
id BigInt @id @default(autoincrement())
global_character_id BigInt
asset_id BigInt?
asset_type String @db.VarChar(50)
label String? @db.VarChar(100)
prompt_text String? @db.Text
is_primary Boolean @default(false)
status String @default("active") @db.VarChar(50)
created_at DateTime @default(now())
@@index([global_character_id, asset_type])
@@index([asset_id])
@@map("global_character_assets")
}
model CharacterImage {
id BigInt @id @default(autoincrement())
project_id BigInt
character_id BigInt
asset_id BigInt?
image_type String @db.VarChar(50)
prompt_text String? @db.Text
negative_prompt String? @db.Text
is_anchor Boolean @default(false)
quality_score Decimal? @db.Decimal(5, 2)
status String @default("pending") @db.VarChar(50)
created_at DateTime @default(now())
@@index([project_id])
@@index([character_id, image_type])
@@index([character_id, is_anchor])
@@map("character_images")
}
model CharacterMemory {
id BigInt @id @default(autoincrement())
project_id BigInt
character_id BigInt
episode_id BigInt?
memory_type String @db.VarChar(50)
content String @db.Text
created_at DateTime @default(now())
@@index([project_id, character_id])
@@index([project_id, episode_id])
@@index([memory_type])
@@map("character_memories")
}
model Episode {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_no Int
source_chapter_ids Json?
title String? @db.VarChar(255)
summary String? @db.Text
opening_hook String? @db.Text
middle_conflict String? @db.Text
ending_hook String? @db.Text
target_duration Int?
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@unique([project_id, episode_no])
@@index([project_id, status])
@@map("episodes")
}
model EpisodeScript {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt
script_text String? @db.LongText
narration_text String? @db.LongText
dialogue_json Json?
version Int @default(1)
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id])
@@index([episode_id, version])
@@map("episode_scripts")
}
model StoryboardShot {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt
shot_no Int
scene_name String? @db.VarChar(255)
location_desc String? @db.Text
characters_json Json?
visual_desc String? @db.Text
action_desc String? @db.Text
dialogue_text String? @db.Text
narration_text String? @db.Text
camera_motion String? @db.VarChar(100)
effect_type String? @db.VarChar(100)
duration Decimal? @db.Decimal(6, 2)
scene_type String? @db.VarChar(50)
importance_score Int?
emotion_score Int?
action_score Int?
route_tier String? @db.VarChar(50)
prompt_text String? @db.Text
negative_prompt String? @db.Text
live_action_desc String? @db.Text
actor_action String? @db.Text
camera_instruction String? @db.Text
performance_instruction String? @db.Text
video_prompt String? @db.Text
keyframe_asset_id BigInt?
video_clip_asset_id BigInt?
video_status String? @db.VarChar(50)
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@unique([episode_id, shot_no])
@@index([project_id, episode_id, shot_no])
@@index([project_id, status])
@@index([scene_type])
@@index([route_tier])
@@map("storyboard_shots")
}
model ShotImage {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt?
shot_id BigInt
asset_id BigInt?
image_type String @default("preview") @db.VarChar(50)
prompt_text String? @db.Text
negative_prompt String? @db.Text
quality_score Decimal? @db.Decimal(5, 2)
status String @default("pending") @db.VarChar(50)
created_at DateTime @default(now())
@@index([project_id, episode_id])
@@index([shot_id, image_type])
@@map("shot_images")
}
model ActorProfile {
id BigInt @id @default(autoincrement())
project_id BigInt
character_id BigInt
actor_desc String? @db.Text
appearance_rules String? @db.Text
wardrobe_rules String? @db.Text
performance_style String? @db.Text
voice_style String? @db.Text
reference_asset_ids Json?
anchor_asset_id BigInt?
status String @default("draft") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@unique([project_id, character_id])
@@index([project_id, status])
@@index([character_id])
@@map("actor_profiles")
}
model VideoClip {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt
shot_id BigInt
provider_id BigInt?
input_asset_id BigInt?
output_asset_id BigInt?
duration Decimal? @db.Decimal(6, 2)
prompt_text String? @db.Text
status String @default("pending") @db.VarChar(50)
cost_actual Decimal? @db.Decimal(12, 4)
retry_count Int @default(0)
quality_status String? @db.VarChar(50)
quality_score Decimal? @db.Decimal(5, 2)
quality_issues Json?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id, episode_id])
@@index([shot_id, status])
@@index([provider_id])
@@map("video_clips")
}
model PlotMemory {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt?
chapter_id BigInt?
memory_type String @db.VarChar(50)
content String @db.Text
importance_level Int @default(0)
status String @default("active") @db.VarChar(50)
created_at DateTime @default(now())
@@index([project_id, episode_id])
@@index([project_id, memory_type])
@@map("plot_memories")
}
model PlotThread {
id BigInt @id @default(autoincrement())
project_id BigInt
thread_name String @db.VarChar(255)
thread_type String @db.VarChar(80)
description String? @db.Text
start_episode_no Int?
expected_resolve_episode_no Int?
resolved_episode_no Int?
status String @default("open") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id, status])
@@index([project_id, thread_type])
@@map("plot_threads")
}
model ContinuityCheck {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt?
check_type String @db.VarChar(80)
result_status String @db.VarChar(50)
issue_text String? @db.Text
suggestion_text String? @db.Text
created_at DateTime @default(now())
@@index([project_id, episode_id])
@@index([result_status])
@@map("continuity_checks")
}
model Asset {
id BigInt @id @default(autoincrement())
user_id BigInt?
project_id BigInt?
asset_type String @db.VarChar(50)
file_path String @db.VarChar(500)
file_url String? @db.VarChar(500)
mime_type String? @db.VarChar(100)
width Int?
height Int?
duration Decimal? @db.Decimal(10, 2)
size BigInt?
hash String? @db.VarChar(128)
visibility String @default("private") @db.VarChar(30)
status String @default("active") @db.VarChar(50)
created_at DateTime @default(now())
@@index([project_id, asset_type])
@@index([user_id, asset_type])
@@index([hash])
@@map("assets")
}
model RenderTask {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt?
shot_id BigInt?
task_type String @db.VarChar(80)
provider_id BigInt?
status String @default("pending") @db.VarChar(50)
input_json Json?
input_hash String? @db.VarChar(128)
idempotency_key String? @unique @db.VarChar(191)
output_asset_id BigInt?
provider_request_id String? @db.VarChar(255)
retry_count Int @default(0)
max_retry Int @default(0)
cost_estimate Decimal? @db.Decimal(12, 4)
cost_actual Decimal? @db.Decimal(12, 4)
error_code String? @db.VarChar(100)
error_message String? @db.Text
created_at DateTime @default(now())
started_at DateTime?
finished_at DateTime?
@@index([project_id, status])
@@index([task_type, status])
@@index([project_id, episode_id])
@@index([input_hash])
@@map("render_tasks")
}
model ProviderConfig {
id BigInt @id @default(autoincrement())
provider_type String @db.VarChar(80)
provider_code String @db.VarChar(100)
display_name String? @db.VarChar(100)
mode String @default("mock") @db.VarChar(50)
model_name String? @db.VarChar(100)
config_json Json?
fallback_provider_id BigInt?
is_enabled Boolean @default(true)
priority Int @default(0)
rate_limit_json Json?
cost_rule_json Json?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@unique([provider_type, provider_code])
@@index([provider_type, is_enabled])
@@map("provider_configs")
}
model ProviderLog {
id BigInt @id @default(autoincrement())
provider_id BigInt?
task_id BigInt?
project_id BigInt?
provider_type String @db.VarChar(80)
provider_code String? @db.VarChar(100)
model_name String? @db.VarChar(100)
request_json Json?
response_json Json?
input_size Int?
output_size Int?
cost_estimate Decimal? @db.Decimal(12, 4)
cost_actual Decimal? @db.Decimal(12, 4)
status String @default("success") @db.VarChar(50)
error_code String? @db.VarChar(100)
error_message String? @db.Text
started_at DateTime?
finished_at DateTime?
created_at DateTime @default(now())
@@index([provider_type, status])
@@index([project_id])
@@index([task_id])
@@index([created_at])
@@map("provider_logs")
}
model Order {
id BigInt @id @default(autoincrement())
user_id BigInt
project_id BigInt?
order_no String @unique @db.VarChar(100)
package_code String? @db.VarChar(100)
amount Decimal @default(0) @db.Decimal(12, 2)
currency String @default("CNY") @db.VarChar(20)
payment_method String? @db.VarChar(50)
payment_status String @default("pending") @db.VarChar(50)
paid_at DateTime?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([user_id, payment_status])
@@index([project_id])
@@map("orders")
}
model QuotaAccount {
id BigInt @id @default(autoincrement())
user_id BigInt @unique
total_quota Decimal @default(0) @db.Decimal(12, 2)
available_quota Decimal @default(0) @db.Decimal(12, 2)
frozen_quota Decimal @default(0) @db.Decimal(12, 2)
used_quota Decimal @default(0) @db.Decimal(12, 2)
status String @default("active") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([status])
@@map("quota_accounts")
}
model QuotaLog {
id BigInt @id @default(autoincrement())
user_id BigInt
project_id BigInt?
task_id BigInt?
change_type String @db.VarChar(50)
amount Decimal @db.Decimal(12, 2)
balance_after Decimal? @db.Decimal(12, 2)
reason String? @db.VarChar(255)
metadata_json Json?
created_at DateTime @default(now())
@@index([user_id, created_at])
@@index([project_id])
@@index([task_id])
@@map("quota_logs")
}
model RevisionRequest {
id BigInt @id @default(autoincrement())
project_id BigInt
user_id BigInt
revision_type String @db.VarChar(50)
target_type String? @db.VarChar(80)
target_id BigInt?
description String @db.Text
status String @default("pending") @db.VarChar(50)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id, status])
@@index([user_id, status])
@@map("revision_requests")
}
model ContentReview {
id BigInt @id @default(autoincrement())
project_id BigInt?
user_id BigInt?
target_type String @db.VarChar(80)
target_id BigInt?
review_type String @db.VarChar(80)
result_status String @default("pending") @db.VarChar(50)
risk_level String? @db.VarChar(50)
issue_text String? @db.Text
suggestion_text String? @db.Text
reviewer_id BigInt?
reviewed_at DateTime?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([project_id, result_status])
@@index([target_type, target_id])
@@index([review_type, result_status])
@@map("content_reviews")
}
model CaseShowcase {
id BigInt @id @default(autoincrement())
project_id BigInt
user_id BigInt?
title String @db.VarChar(255)
cover_asset_id BigInt?
video_asset_id BigInt?
authorization_status String @default("pending") @db.VarChar(50)
visibility String @default("private") @db.VarChar(30)
sort_order Int @default(0)
published_at DateTime?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([visibility, sort_order])
@@index([project_id])
@@map("case_showcases")
}
model HitAnalysisCase {
id BigInt @id @default(autoincrement())
title String @db.VarChar(255)
source_platform String? @db.VarChar(100)
source_url String? @db.VarChar(500)
content_type String @default("short_drama") @db.VarChar(80)
genre String? @db.VarChar(100)
language String @default("zh-CN") @db.VarChar(30)
target_audience String? @db.VarChar(255)
duration_seconds Int?
episode_count Int?
tags_json Json?
metrics_json Json?
transcript_text String? @db.LongText
summary_text String? @db.Text
analysis_json Json?
diagnosis_score Decimal? @db.Decimal(5, 2)
status String @default("draft") @db.VarChar(50)
created_by_user_id BigInt?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([source_platform])
@@index([genre, status])
@@index([status, diagnosis_score])
@@index([created_at])
@@map("hit_analysis_cases")
}
model HitAnalysisSegment {
id BigInt @id @default(autoincrement())
case_id BigInt
segment_no Int
start_second Int?
end_second Int?
scene_type String? @db.VarChar(80)
hook_type String? @db.VarChar(100)
emotion String? @db.VarChar(80)
conflict_type String? @db.VarChar(100)
plot_function String? @db.VarChar(120)
visual_strategy String? @db.VarChar(120)
dialogue_pattern String? @db.VarChar(120)
camera_notes String? @db.Text
importance_score Int?
emotion_score Int?
action_score Int?
tags_json Json?
summary_text String? @db.Text
prompt_seed String? @db.Text
created_at DateTime @default(now())
@@unique([case_id, segment_no])
@@index([case_id])
@@index([scene_type])
@@index([hook_type])
@@map("hit_analysis_segments")
}
model CreativePattern {
id BigInt @id @default(autoincrement())
source_case_id BigInt?
pattern_type String @db.VarChar(80)
title String @db.VarChar(255)
genre String? @db.VarChar(100)
language String @default("zh-CN") @db.VarChar(30)
description String? @db.Text
structure_json Json?
prompt_template String? @db.Text
negative_prompt String? @db.Text
tags_json Json?
usage_count Int @default(0)
effectiveness_score Decimal? @db.Decimal(5, 2)
status String @default("active") @db.VarChar(50)
created_by_user_id BigInt?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([pattern_type, status])
@@index([genre, status])
@@index([source_case_id])
@@map("creative_patterns")
}
model ProjectCreativePattern {
id BigInt @id @default(autoincrement())
project_id BigInt
creative_pattern_id BigInt
source String @default("user_selected") @db.VarChar(50)
snapshot_json Json?
sort_order Int @default(0)
created_at DateTime @default(now())
@@unique([project_id, creative_pattern_id])
@@index([project_id, sort_order])
@@index([creative_pattern_id])
@@map("project_creative_patterns")
}
model AnalyticsEvent {
id BigInt @id @default(autoincrement())
project_id BigInt
episode_id BigInt?
event_type String @db.VarChar(80)
platform String? @db.VarChar(80)
metric_json Json?
created_at DateTime @default(now())
@@index([project_id])
@@index([episode_id])
@@index([event_type, created_at])
@@map("analytics_events")
}
model SystemConfig {
id BigInt @id @default(autoincrement())
config_key String @unique @db.VarChar(191)
config_value Json?
description String? @db.Text
is_public Boolean @default(false)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([is_public])
@@map("system_configs")
}
model OperationLog {
id BigInt @id @default(autoincrement())
user_id BigInt?
operator_role String? @db.VarChar(50)
action String @db.VarChar(100)
target_type String? @db.VarChar(80)
target_id BigInt?
ip String? @db.VarChar(80)
user_agent String? @db.Text
metadata_json Json?
created_at DateTime @default(now())
@@index([user_id, created_at])
@@index([target_type, target_id])
@@index([action, created_at])
@@map("operation_logs")
}