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") }