From 6b1966ce903a6137b29570d38ba18634c506338d Mon Sep 17 00:00:00 2001 From: saas-backend-agent Date: Tue, 8 Sep 2026 02:09:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20#1775=20=E9=BB=98=E8=AE=A4=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE/=E9=BB=98=E8=AE=A4=E7=B4=A0=E6=9D=90=E5=BA=93?= =?UTF-8?q?=E5=B9=82=E7=AD=89=E5=8C=96=EF=BC=88DB=20=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E7=BA=A6=E6=9D=9F=E5=85=9C=E5=BA=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:小程序端 getOrCreateDefaultProject 在重试/并发/重复调用下, 仅靠应用层"先查后插"不保证幂等,会给同一用户重复创建默认项目。 素材库虽有唯一约束 uq_asset_libraries_project_kind(迁移058), 但 ensure-default 接口未捕获冲突,并发下直接 500。 改动: 1. projects 表新增 is_default 列 + 部分唯一索引 uq_projects_owner_default(owner_user_id WHERE is_default=true), 保证每用户至多一个默认项目(迁移069,存量"默认项目"最早一条回填) 2. Project 实体/Model/Repository 增加 is_default 字段 3. 新增 get_or_create_default_project / find_default_by_owner: INSERT 冲突时捕获 IntegrityError 回滚重查,返回已有记录不报500 4. 素材库仓储新增 get_or_create_default_library(同上幂等语义) 5. 新增 POST /projects/ensure-default 组合接口: 一次请求幂等返回默认项目 + 三类默认素材库ID 6. ensure-default 素材库接口改用幂等仓储方法(修复并发500) 7. in-memory 仓储同步幂等方法 测试:15 个新测试(并发10次只建1个、跨用户独立、IntegrityError恢复、 字段语义),99 个相关旧测试全过。 --- .../069_project_is_default_idempotent.py | 72 + apps/api/app/api/routes/asset_libraries.py | 29 +- apps/api/app/api/routes/projects.py | 42 +- docs/schema-metadata-snapshot.json | 7212 +++++++++-------- .../in_memory/asset_library_repository.py | 18 + .../adapters/in_memory/project_repository.py | 27 + .../asset_library_repository.py | 72 + packages/adapters/sqlalchemy_impl/models.py | 8 +- .../sqlalchemy_impl/project_repository.py | 60 + packages/domain/entities.py | 4 +- .../test_default_project_idempotent_1775.py | 197 + 11 files changed, 4144 insertions(+), 3597 deletions(-) create mode 100644 alembic/versions/069_project_is_default_idempotent.py create mode 100644 tests/unit/test_default_project_idempotent_1775.py diff --git a/alembic/versions/069_project_is_default_idempotent.py b/alembic/versions/069_project_is_default_idempotent.py new file mode 100644 index 000000000..17d3817f1 --- /dev/null +++ b/alembic/versions/069_project_is_default_idempotent.py @@ -0,0 +1,72 @@ +"""Projects is_default + partial unique index for idempotent default project (Issue #1775) + +Revision ID: 069_project_is_default +Revises: 068_user_profile_completed +Create Date: 2026-09-08 + +背景: +小程序端 getOrCreateDefaultProject 在重试/并发/前端重复调用下, +仅靠应用层"先查再插"不保证幂等,会给同一用户重复创建默认项目。 + +改动: +1. projects 表新增 is_default 布尔列(默认 false) +2. 部分唯一索引 uq_projects_owner_default:(owner_user_id) WHERE is_default = true + —— 保证每个用户至多一个默认项目 +3. 存量数据回填:把名为"默认项目"的存量项目按创建时间最早者标记为 is_default=true + (只标记不删除;存量重复项目的清理另行确认后单独执行) + +注意:部分唯一索引依赖 PostgreSQL,不支持 downgrade 到其他方言。 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "069_project_is_default" +down_revision = "068_user_profile_completed" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # 1. 新增 is_default 列 + op.add_column( + "projects", + sa.Column( + "is_default", + sa.Boolean(), + nullable=False, + server_default=sa.text("false"), + ), + ) + + # 2. 存量回填:每个拥有"默认项目"的用户,只把最早创建的那一个标记为默认。 + # 用 ROW_NUMBER() 取每组第一条;非"默认项目"命名的项目不标记(保守,不动用户自建项目)。 + op.execute(""" + UPDATE projects p + SET is_default = true + WHERE p.id IN ( + SELECT id FROM ( + SELECT id, + ROW_NUMBER() OVER ( + PARTITION BY owner_user_id + ORDER BY created_at ASC, id ASC + ) AS rn + FROM projects + WHERE name = '默认项目' + ) t + WHERE t.rn = 1 + ) + """) + + # 3. 部分唯一索引:每用户至多一个默认项目(只约束 is_default = true 的行) + op.execute(""" + CREATE UNIQUE INDEX uq_projects_owner_default + ON projects (owner_user_id) + WHERE is_default = true + """) + + +def downgrade() -> None: + op.execute("DROP INDEX IF EXISTS uq_projects_owner_default") + op.drop_column("projects", "is_default") diff --git a/apps/api/app/api/routes/asset_libraries.py b/apps/api/app/api/routes/asset_libraries.py index 7b75e54c2..ba1340450 100755 --- a/apps/api/app/api/routes/asset_libraries.py +++ b/apps/api/app/api/routes/asset_libraries.py @@ -20,7 +20,7 @@ from packages.application import ( GetProjectUseCase, ListAssetLibrariesUseCase, ) -from packages.domain import AssetLibrary, AssetLibraryKind +from packages.domain import AssetLibraryKind from ._helpers import check_project_access @@ -120,30 +120,11 @@ def ensure_default_library( kind = AssetLibraryKind(request.kind) - # 查找该项目下同 kind 的素材库,返回第一个 - existing = asset_library_repository.find_by_project(request.project_id) - for lib in existing: - if lib.kind == kind: - return _to_asset_library_response(lib) - - # 不存在 → 自动创建 - import uuid - from datetime import datetime, timezone - - now = datetime.now(timezone.utc) + # Issue #1775: 幂等获取/创建——依赖唯一约束 uq_asset_libraries_project_kind, + # 并发创建冲突时回滚重查返回已有记录,不再依赖应用层"先查后插",也不会 500。 default_name = _DEFAULT_LIBRARY_NAMES.get(request.kind, f"{request.kind}素材库") - library = AssetLibrary( - id=str(uuid.uuid4()), - project_id=request.project_id, - name=default_name, - kind=kind, - asset_count=0, - total_size=0, - created_at=now, - updated_at=now, - ) - created = asset_library_repository.create(library) - return _to_asset_library_response(created) + library = asset_library_repository.get_or_create_default_library(request.project_id, kind, name=default_name) + return _to_asset_library_response(library) @router.delete("/{library_id}", status_code=status.HTTP_204_NO_CONTENT, response_class=Response) diff --git a/apps/api/app/api/routes/projects.py b/apps/api/app/api/routes/projects.py index b17219ed0..e65a6724d 100644 --- a/apps/api/app/api/routes/projects.py +++ b/apps/api/app/api/routes/projects.py @@ -1,13 +1,14 @@ from typing import Any from app.auth import AuthenticatedUser, get_current_user -from app.dependencies import get_project_repository +from app.dependencies import get_asset_library_repository, get_project_repository from app.schemas.project import ( CreateProjectRequest, ListProjectsResponse, ProjectResponse, ) from fastapi import APIRouter, Depends, HTTPException, Response, status +from pydantic import BaseModel from packages.application import ( CreateProjectCommand, @@ -16,10 +17,20 @@ from packages.application import ( GetProjectUseCase, ListProjectsUseCase, ) +from packages.domain import AssetLibraryKind router = APIRouter() +class DefaultContextResponse(BaseModel): + """幂等默认上下文响应(Issue #1775):默认项目 + 各类型默认素材库 ID。""" + + project_id: str + image_library_id: str + video_library_id: str + voice_library_id: str + + def _to_project_response(item) -> ProjectResponse: return ProjectResponse( id=item.id, @@ -72,6 +83,35 @@ def create_project( return _to_project_response(project) +@router.post("/ensure-default", response_model=DefaultContextResponse) +def ensure_default_project_and_libraries( + authenticated_user: AuthenticatedUser = Depends(get_current_user), + project_repository: Any = Depends(get_project_repository), + asset_library_repository: Any = Depends(get_asset_library_repository), +) -> DefaultContextResponse: + """幂等获取/创建当前用户的默认项目和三类默认素材库(Issue #1775)。 + + - 同一用户永远只有一个默认项目(部分唯一索引 uq_projects_owner_default) + - 同一项目同 kind 永远只有一个默认素材库(唯一约束 uq_asset_libraries_project_kind) + - 并发调用/失败重试:唯一约束冲突时返回已存在记录,不报 500 + - 项目和素材库的创建各自在仓储事务内幂等,冲突回滚后重查返回同一条 + """ + user_id = authenticated_user.user.id + project = project_repository.get_or_create_default_project(user_id) + + libraries = {} + for kind in (AssetLibraryKind.VIDEO, AssetLibraryKind.VOICE, AssetLibraryKind.IMAGE): + library = asset_library_repository.get_or_create_default_library(project.id, kind) + libraries[kind] = library.id + + return DefaultContextResponse( + project_id=project.id, + image_library_id=libraries[AssetLibraryKind.IMAGE], + video_library_id=libraries[AssetLibraryKind.VIDEO], + voice_library_id=libraries[AssetLibraryKind.VOICE], + ) + + @router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None, response_class=Response) def delete_project( project_id: str, diff --git a/docs/schema-metadata-snapshot.json b/docs/schema-metadata-snapshot.json index 1cff40b65..7a90d0cb6 100644 --- a/docs/schema-metadata-snapshot.json +++ b/docs/schema-metadata-snapshot.json @@ -1,3573 +1,3645 @@ { - "tables": { - "asset_libraries": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false + "tables": { + "asset_libraries": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": true, + "name": "kind", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "asset_count", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "total_size", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["kind"], "name": "ix_asset_libraries_kind", "unique": false}, + {"columns": ["project_id"], "name": "ix_asset_libraries_project_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "asset_tags": { + "columns": [ + { + "index": false, + "name": "asset_id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "tag_id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [], + "primary_key": ["asset_id", "tag_id"], + }, + "assets": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "asset_library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": true, + "name": "file_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "file_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": false, + "name": "storage_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "thumbnail_url", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": false, + "name": "duration", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "width", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "height", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "fps", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "codec", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": true, + "name": "classification_status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "classification_result", + "nullable": true, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "quality_score", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "uploaded_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "file_hash", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false, + }, + { + "index": true, + "name": "client_upload_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": true, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["asset_library_id"], "name": "ix_assets_asset_library_id", "unique": false}, + {"columns": ["classification_status"], "name": "ix_assets_classification_status", "unique": false}, + {"columns": ["client_upload_id"], "name": "ix_assets_client_upload_id", "unique": false}, + {"columns": ["created_at"], "name": "ix_assets_created_at", "unique": false}, + {"columns": ["file_hash"], "name": "ix_assets_file_hash", "unique": false}, + {"columns": ["file_type"], "name": "ix_assets_file_type", "unique": false}, + {"columns": ["project_id"], "name": "ix_assets_project_id", "unique": false}, + {"columns": ["status"], "name": "ix_assets_status", "unique": false}, + ], + "primary_key": ["id"], + }, + "billing_records": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "plan_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "amount", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "billing_cycle", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "payment_method", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "payment_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "invoice_url", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "paid_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [{"columns": ["user_id"], "name": "ix_billing_records_user_id", "unique": false}], + "primary_key": ["id"], + }, + "classification_jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "classification", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "confidence", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["asset_id"], "name": "ix_classification_jobs_asset_id", "unique": false}, + {"columns": ["project_id"], "name": "ix_classification_jobs_project_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "cover_templates": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false, + }, + { + "index": false, + "name": "thumbnail_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": true, + "name": "is_system", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["is_system"], "name": "ix_cover_templates_is_system", "unique": false}, + {"columns": ["user_id"], "name": "ix_cover_templates_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "duplication_records": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "filename", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "storage_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "duration_seconds", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "duplicate_rate", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "duplicate_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "visual_similarity", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "match_count", + "nullable": true, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "video_fingerprint", + "nullable": true, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["status"], "name": "ix_duplication_records_status", "unique": false}, + {"columns": ["user_id"], "name": "ix_duplication_records_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "duplication_segments": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "record_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "source_start", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "source_end", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "matched_video_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "matched_video_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "matched_start", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "matched_end", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "similarity", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + ], + "indexes": [{"columns": ["record_id"], "name": "ix_duplication_segments_record_id", "unique": false}], + "primary_key": ["id"], + }, + "edit_plan_clips": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "plan_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "clip_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": true, + "name": "template_clip_config_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "text_content", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "start_time", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "transition_effect", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "transition_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "playback_speed", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["asset_id"], "name": "ix_edit_plan_clips_asset_id", "unique": false}, + {"columns": ["clip_type"], "name": "ix_edit_plan_clips_clip_type", "unique": false}, + {"columns": ["plan_id"], "name": "ix_edit_plan_clips_plan_id", "unique": false}, + {"columns": ["status"], "name": "ix_edit_plan_clips_status", "unique": false}, + { + "columns": ["template_clip_config_id"], + "name": "ix_edit_plan_clips_template_clip_config_id", + "unique": false, + }, + ], + "primary_key": ["id"], + }, + "edit_plans": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "total_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": true, + "name": "source_edit_plan_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "created_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["created_by_user_id"], "name": "ix_edit_plans_created_by_user_id", "unique": false}, + {"columns": ["project_id"], "name": "ix_edit_plans_project_id", "unique": false}, + {"columns": ["source_edit_plan_id"], "name": "ix_edit_plans_source_edit_plan_id", "unique": false}, + {"columns": ["status"], "name": "ix_edit_plans_status", "unique": false}, + {"columns": ["template_id"], "name": "ix_edit_plans_template_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "edit_template_versions": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": false, + }, + { + "index": false, + "name": "version", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false, + }, + { + "index": false, + "name": "editing_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(30)", + "unique": false, + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "clip_configs", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "change_note", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "published_by", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [{"columns": ["template_id"], "name": "ix_edit_template_versions_template_id", "unique": false}], + "primary_key": ["id"], + }, + "edit_templates": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(120)", + "unique": false, + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": true, + "name": "template_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "editing_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "preview_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": true, + "name": "sort_weight", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "version", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["sort_weight"], "name": "ix_edit_templates_sort_weight", "unique": false}, + {"columns": ["status"], "name": "ix_edit_templates_status", "unique": false}, + {"columns": ["template_type"], "name": "ix_edit_templates_template_type", "unique": false}, + ], + "primary_key": ["id"], + }, + "generated_videos": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "generation_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "file_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "thumbnail_url", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": false, + "name": "width", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "height", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "fps", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": true, + "name": "review_status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "generation_params", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "generated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "video_fingerprint", + "nullable": true, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "is_duplicate", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "duplicate_of", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "duplicate_rate", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "match_count", + "nullable": true, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "visual_similarity", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["generation_task_id"], "name": "ix_generated_videos_generation_task_id", "unique": false}, + {"columns": ["project_id"], "name": "ix_generated_videos_project_id", "unique": false}, + {"columns": ["review_status"], "name": "ix_generated_videos_review_status", "unique": false}, + {"columns": ["status"], "name": "ix_generated_videos_status", "unique": false}, + {"columns": ["user_id"], "name": "ix_generated_videos_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "generation_tasks": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "strategy_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "asset_library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "voice_library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "asset_ids", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "title_ids", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "voice_ids", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": true, + "name": "editing_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "progress", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "result_count", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "error_info", + "nullable": true, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "auto_retry_enabled", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "auto_retry_max", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "started_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": true, + "name": "created_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "source_edit_plan_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "edit_plan_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "asset_select_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": true, + "name": "batch_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "video_title", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "resolution", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": true, + "name": "is_preview", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": true, + "name": "source_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": false, + }, + { + "index": false, + "name": "celery_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false, + }, + { + "index": false, + "name": "output_width", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "output_height", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "cover_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": false, + "name": "custom_title", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "title_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "bgm_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "logs", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["asset_library_id"], "name": "ix_generation_tasks_asset_library_id", "unique": false}, + {"columns": ["batch_id"], "name": "ix_generation_tasks_batch_id", "unique": false}, + {"columns": ["created_by_user_id"], "name": "ix_generation_tasks_created_by_user_id", "unique": false}, + {"columns": ["edit_plan_id"], "name": "ix_generation_tasks_edit_plan_id", "unique": false}, + {"columns": ["editing_mode"], "name": "ix_generation_tasks_editing_mode", "unique": false}, + {"columns": ["is_preview"], "name": "ix_generation_tasks_is_preview", "unique": false}, + {"columns": ["project_id"], "name": "ix_generation_tasks_project_id", "unique": false}, + { + "columns": ["source_edit_plan_id"], + "name": "ix_generation_tasks_source_edit_plan_id", + "unique": false, + }, + {"columns": ["source_task_id"], "name": "ix_generation_tasks_source_task_id", "unique": false}, + {"columns": ["status"], "name": "ix_generation_tasks_status", "unique": false}, + {"columns": ["template_id"], "name": "ix_generation_tasks_template_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "ingest_jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "storage_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "result_asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "file_hash", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false, + }, + { + "index": true, + "name": "asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "celery_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["asset_id"], "name": "ix_ingest_jobs_asset_id", "unique": false}, + {"columns": ["file_hash"], "name": "ix_ingest_jobs_file_hash", "unique": false}, + {"columns": ["library_id"], "name": "ix_ingest_jobs_library_id", "unique": false}, + {"columns": ["project_id"], "name": "ix_ingest_jobs_project_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "job_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(30)", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "progress", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "current_stage", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false, + }, + { + "index": false, + "name": "payload", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "result", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "max_retries", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "celery_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": true, + "name": "source_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "created_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "started_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["created_by_user_id"], "name": "ix_jobs_created_by_user_id", "unique": false}, + {"columns": ["job_type"], "name": "ix_jobs_job_type", "unique": false}, + {"columns": ["project_id"], "name": "ix_jobs_project_id", "unique": false}, + {"columns": ["source_id"], "name": "ix_jobs_source_id", "unique": false}, + {"columns": ["status"], "name": "ix_jobs_status", "unique": false}, + ], + "primary_key": ["id"], + }, + "projects": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "owner_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "shared_users", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "is_default", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["owner_user_id"], "name": "ix_projects_owner_user_id", "unique": false}, + {"columns": ["owner_user_id"], "name": "uq_projects_owner_default", "unique": true}, + ], + "primary_key": ["id"], + }, + "recipe_items": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "recipe_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "item_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "item_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "position", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + ], + "indexes": [{"columns": ["recipe_id"], "name": "ix_recipe_items_recipe_id", "unique": false}], + "primary_key": ["id"], + }, + "recipes": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false, + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "generation_params", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [{"columns": ["user_id"], "name": "ix_recipes_user_id", "unique": false}], + "primary_key": ["id"], + }, + "tags": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [{"columns": ["user_id"], "name": "ix_tags_user_id", "unique": false}], + "primary_key": ["id"], + }, + "template_categories": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "sort_order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [{"columns": ["user_id"], "name": "ix_template_categories_user_id", "unique": false}], + "primary_key": ["id"], + }, + "template_clip_configs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "clip_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "min_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "max_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "text_template", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "material_requirements", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "transition_effect", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["clip_type"], "name": "ix_template_clip_configs_clip_type", "unique": false}, + {"columns": ["template_id"], "name": "ix_template_clip_configs_template_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "template_segments": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "segment_order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "duration_min", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "duration_max", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "material_type", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [{"columns": ["template_id"], "name": "ix_template_segments_template_id", "unique": false}], + "primary_key": ["id"], + }, + "templates": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false, + }, + { + "index": true, + "name": "mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(30)", + "unique": false, + }, + { + "index": false, + "name": "category", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "tags", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "title_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "subtitle_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "bgm_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "estimated_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["mode"], "name": "ix_templates_mode", "unique": false}, + {"columns": ["user_id"], "name": "ix_templates_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "title_libraries": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": true, + "name": "category", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "text", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "tags", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "usage_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": true, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["category"], "name": "ix_title_libraries_category", "unique": false}, + {"columns": ["is_active"], "name": "ix_title_libraries_is_active", "unique": false}, + {"columns": ["user_id"], "name": "ix_title_libraries_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "tts_jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "input_text", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "voice_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "voice_model", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "voice_clone_profile_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "output_audio_url", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "output_audio_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false, + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "sample_rate", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "format", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "max_retries", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "started_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["status"], "name": "ix_tts_jobs_status", "unique": false}, + {"columns": ["user_id"], "name": "ix_tts_jobs_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "users": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "email", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": true, + }, + { + "index": true, + "name": "username", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": true, + }, + { + "index": false, + "name": "display_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "password_hash", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "email_verified", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "email_verification_token", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "password_reset_token", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "password_reset_expires_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "last_login_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "last_login_ip", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "subscription_plan", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "subscription_status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "subscription_expires_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "max_projects", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "max_storage_gb", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "used_storage_gb", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "is_admin", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": true, + "name": "wechat_openid", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(128)", + "unique": true, + }, + { + "index": true, + "name": "wechat_unionid", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(128)", + "unique": true, + }, + { + "index": true, + "name": "phone", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": true, + }, + { + "index": false, + "name": "phone_verified", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "binding_completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "profile_completed", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["email"], "name": "ix_users_email", "unique": true}, + {"columns": ["phone"], "name": "ix_users_phone", "unique": true}, + {"columns": ["username"], "name": "ix_users_username", "unique": true}, + {"columns": ["wechat_openid"], "name": "ix_users_wechat_openid", "unique": true}, + {"columns": ["wechat_unionid"], "name": "ix_users_wechat_unionid", "unique": true}, + ], + "primary_key": ["id"], + }, + "verification_codes": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "recipient", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "code", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(10)", + "unique": false, + }, + { + "index": true, + "name": "code_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": false, + }, + { + "index": false, + "name": "expires_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "used_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "attempts", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["code_type"], "name": "ix_verification_codes_code_type", "unique": false}, + {"columns": ["recipient"], "name": "ix_verification_codes_recipient", "unique": false}, + ], + "primary_key": ["id"], + }, + "video_fingerprint_chunks": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "video_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "start_time_ms", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "end_time_ms", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "phash_binary", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(16)", + "unique": false, + }, + { + "index": false, + "name": "color_histogram", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "frame_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["project_id"], "name": "ix_video_fingerprint_chunks_project_id", "unique": false}, + {"columns": ["user_id"], "name": "ix_video_fingerprint_chunks_user_id", "unique": false}, + {"columns": ["video_id"], "name": "ix_video_fingerprint_chunks_video_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "video_shares": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(32)", + "unique": false, + }, + { + "index": true, + "name": "video_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": false, + }, + { + "index": false, + "name": "share_token", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(16)", + "unique": true, + }, + { + "index": false, + "name": "password_hash", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "expires_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "view_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "download_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["user_id"], "name": "ix_video_shares_user_id", "unique": false}, + {"columns": ["video_id"], "name": "ix_video_shares_video_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "voice_clone_profiles": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "source_audio_url", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "voice_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "voice_model", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "language", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "gender", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "max_retries", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["status"], "name": "ix_voice_clone_profiles_status", "unique": false}, + {"columns": ["user_id"], "name": "ix_voice_clone_profiles_user_id", "unique": false}, + ], + "primary_key": ["id"], + }, + "voice_libraries": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": true, + "name": "project_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false, + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false, + }, + { + "index": false, + "name": "text", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false, + }, + { + "index": false, + "name": "voice_provider", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false, + }, + { + "index": false, + "name": "voice_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "voice_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false, + }, + { + "index": false, + "name": "audio_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false, + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false, + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false, + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false, + }, + { + "index": false, + "name": "tags", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false, + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false, + }, + ], + "indexes": [ + {"columns": ["project_id"], "name": "ix_voice_libraries_project_id", "unique": false}, + {"columns": ["status"], "name": "ix_voice_libraries_status", "unique": false}, + {"columns": ["user_id"], "name": "ix_voice_libraries_user_id", "unique": false}, + ], + "primary_key": ["id"], }, - { - "index": true, - "name": "project_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": true, - "name": "kind", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "asset_count", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "total_size", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "kind" - ], - "name": "ix_asset_libraries_kind", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_asset_libraries_project_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "asset_tags": { - "columns": [ - { - "index": false, - "name": "asset_id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "tag_id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [], - "primary_key": [ - "asset_id", - "tag_id" - ] - }, - "assets": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "asset_library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": true, - "name": "file_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "file_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": false, - "name": "storage_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "thumbnail_url", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": false, - "name": "duration", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "width", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "height", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "fps", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "codec", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": true, - "name": "classification_status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "classification_result", - "nullable": true, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "quality_score", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "uploaded_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "file_hash", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": true, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "asset_library_id" - ], - "name": "ix_assets_asset_library_id", - "unique": false - }, - { - "columns": [ - "classification_status" - ], - "name": "ix_assets_classification_status", - "unique": false - }, - { - "columns": [ - "created_at" - ], - "name": "ix_assets_created_at", - "unique": false - }, - { - "columns": [ - "file_hash" - ], - "name": "ix_assets_file_hash", - "unique": false - }, - { - "columns": [ - "file_type" - ], - "name": "ix_assets_file_type", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_assets_project_id", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_assets_status", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "billing_records": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "plan_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "amount", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "billing_cycle", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "payment_method", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "payment_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "invoice_url", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "paid_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "user_id" - ], - "name": "ix_billing_records_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "classification_jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "classification", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "confidence", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "asset_id" - ], - "name": "ix_classification_jobs_asset_id", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_classification_jobs_project_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "duplication_records": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "filename", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "storage_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "duration_seconds", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "duplicate_rate", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "duplicate_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "video_fingerprint", - "nullable": true, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "status" - ], - "name": "ix_duplication_records_status", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_duplication_records_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "duplication_segments": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "record_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "source_start", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "source_end", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "matched_video_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "matched_video_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "matched_start", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "matched_end", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "similarity", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "record_id" - ], - "name": "ix_duplication_segments_record_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "edit_plan_clips": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "plan_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "clip_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": true, - "name": "template_clip_config_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "text_content", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "start_time", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "transition_effect", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "transition_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "playback_speed", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "asset_id" - ], - "name": "ix_edit_plan_clips_asset_id", - "unique": false - }, - { - "columns": [ - "clip_type" - ], - "name": "ix_edit_plan_clips_clip_type", - "unique": false - }, - { - "columns": [ - "plan_id" - ], - "name": "ix_edit_plan_clips_plan_id", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_edit_plan_clips_status", - "unique": false - }, - { - "columns": [ - "template_clip_config_id" - ], - "name": "ix_edit_plan_clips_template_clip_config_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "edit_plans": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "total_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "result_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": true, - "name": "source_edit_plan_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "created_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "created_by_user_id" - ], - "name": "ix_edit_plans_created_by_user_id", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_edit_plans_project_id", - "unique": false - }, - { - "columns": [ - "source_edit_plan_id" - ], - "name": "ix_edit_plans_source_edit_plan_id", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_edit_plans_status", - "unique": false - }, - { - "columns": [ - "template_id" - ], - "name": "ix_edit_plans_template_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "edit_templates": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(120)", - "unique": false - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": true, - "name": "template_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "editing_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "preview_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": true, - "name": "sort_weight", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "sort_weight" - ], - "name": "ix_edit_templates_sort_weight", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_edit_templates_status", - "unique": false - }, - { - "columns": [ - "template_type" - ], - "name": "ix_edit_templates_template_type", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "generated_videos": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "generation_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "file_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "thumbnail_url", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": false, - "name": "width", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "height", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "fps", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": true, - "name": "review_status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "generation_params", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "generated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "video_fingerprint", - "nullable": true, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "is_duplicate", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": false, - "name": "duplicate_of", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "generation_task_id" - ], - "name": "ix_generated_videos_generation_task_id", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_generated_videos_project_id", - "unique": false - }, - { - "columns": [ - "review_status" - ], - "name": "ix_generated_videos_review_status", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_generated_videos_status", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_generated_videos_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "generation_tasks": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "strategy_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "asset_library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "voice_library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "asset_ids", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "title_ids", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "voice_ids", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": true, - "name": "editing_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "progress", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "result_count", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "error_info", - "nullable": true, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "auto_retry_enabled", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": false, - "name": "auto_retry_max", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "started_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": true, - "name": "created_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "source_edit_plan_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "asset_select_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": true, - "name": "batch_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "video_title", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "logs", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "is_preview", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": true, - "name": "source_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": false - }, - { - "index": false, - "name": "output_width", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "output_height", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "cover_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": false, - "name": "custom_title", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "asset_library_id" - ], - "name": "ix_generation_tasks_asset_library_id", - "unique": false - }, - { - "columns": [ - "batch_id" - ], - "name": "ix_generation_tasks_batch_id", - "unique": false - }, - { - "columns": [ - "created_by_user_id" - ], - "name": "ix_generation_tasks_created_by_user_id", - "unique": false - }, - { - "columns": [ - "editing_mode" - ], - "name": "ix_generation_tasks_editing_mode", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_generation_tasks_project_id", - "unique": false - }, - { - "columns": [ - "source_edit_plan_id" - ], - "name": "ix_generation_tasks_source_edit_plan_id", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_generation_tasks_status", - "unique": false - }, - { - "columns": [ - "template_id" - ], - "name": "ix_generation_tasks_template_id", - "unique": false - }, - { - "columns": [ - "source_task_id" - ], - "name": "ix_generation_tasks_source_task_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "ingest_jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "storage_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "result_asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "file_hash", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "file_hash" - ], - "name": "ix_ingest_jobs_file_hash", - "unique": false - }, - { - "columns": [ - "library_id" - ], - "name": "ix_ingest_jobs_library_id", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_ingest_jobs_project_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "job_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(30)", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "progress", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "current_stage", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false - }, - { - "index": false, - "name": "payload", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "result", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "max_retries", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "celery_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": true, - "name": "source_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "created_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "started_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "created_by_user_id" - ], - "name": "ix_jobs_created_by_user_id", - "unique": false - }, - { - "columns": [ - "job_type" - ], - "name": "ix_jobs_job_type", - "unique": false - }, - { - "columns": [ - "project_id" - ], - "name": "ix_jobs_project_id", - "unique": false - }, - { - "columns": [ - "source_id" - ], - "name": "ix_jobs_source_id", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_jobs_status", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "projects": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "owner_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "shared_users", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "owner_user_id" - ], - "name": "ix_projects_owner_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "recipe_items": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "recipe_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "item_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "item_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "position", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "recipe_id" - ], - "name": "ix_recipe_items_recipe_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "recipes": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "generation_params", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "user_id" - ], - "name": "ix_recipes_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "tags": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "user_id" - ], - "name": "ix_tags_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "template_categories": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "user_id" - ], - "name": "ix_template_categories_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "template_clip_configs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "clip_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "min_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "max_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "text_template", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "material_requirements", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "transition_effect", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "clip_type" - ], - "name": "ix_template_clip_configs_clip_type", - "unique": false - }, - { - "columns": [ - "template_id" - ], - "name": "ix_template_clip_configs_template_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "template_segments": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "segment_order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "duration_min", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "duration_max", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "material_type", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "template_id" - ], - "name": "ix_template_segments_template_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "templates": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false - }, - { - "index": true, - "name": "mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(30)", - "unique": false - }, - { - "index": false, - "name": "category", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "tags", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "title_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "subtitle_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "bgm_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "estimated_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "mode" - ], - "name": "ix_templates_mode", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_templates_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "title_libraries": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": true, - "name": "category", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "text", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "tags", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "usage_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": true, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "category" - ], - "name": "ix_title_libraries_category", - "unique": false - }, - { - "columns": [ - "is_active" - ], - "name": "ix_title_libraries_is_active", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_title_libraries_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "tts_jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "input_text", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "voice_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "voice_model", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "voice_clone_profile_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "output_audio_url", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "output_audio_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "sample_rate", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "format", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "max_retries", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "started_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "status" - ], - "name": "ix_tts_jobs_status", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_tts_jobs_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "users": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "email", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": true - }, - { - "index": true, - "name": "username", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": true - }, - { - "index": false, - "name": "display_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "password_hash", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "email_verified", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": false, - "name": "email_verification_token", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "password_reset_token", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "password_reset_expires_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "last_login_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "last_login_ip", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "subscription_plan", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "subscription_status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "subscription_expires_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "max_projects", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "max_storage_gb", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "used_storage_gb", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "is_admin", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false - }, - { - "index": true, - "name": "wechat_openid", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(128)", - "unique": true - }, - { - "index": true, - "name": "wechat_unionid", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(128)", - "unique": true - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "email" - ], - "name": "ix_users_email", - "unique": true - }, - { - "columns": [ - "username" - ], - "name": "ix_users_username", - "unique": true - }, - { - "columns": [ - "wechat_openid" - ], - "name": "ix_users_wechat_openid", - "unique": true - }, - { - "columns": [ - "wechat_unionid" - ], - "name": "ix_users_wechat_unionid", - "unique": true - } - ], - "primary_key": [ - "id" - ] - }, - "voice_clone_profiles": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "source_audio_url", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "voice_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "voice_model", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "language", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "gender", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "max_retries", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "status" - ], - "name": "ix_voice_clone_profiles_status", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_voice_clone_profiles_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] - }, - "voice_libraries": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": true, - "name": "project_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false - }, - { - "index": false, - "name": "text", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false - }, - { - "index": false, - "name": "voice_provider", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false - }, - { - "index": false, - "name": "voice_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "voice_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false - }, - { - "index": false, - "name": "audio_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false - }, - { - "index": false, - "name": "tags", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false - } - ], - "indexes": [ - { - "columns": [ - "project_id" - ], - "name": "ix_voice_libraries_project_id", - "unique": false - }, - { - "columns": [ - "status" - ], - "name": "ix_voice_libraries_status", - "unique": false - }, - { - "columns": [ - "user_id" - ], - "name": "ix_voice_libraries_user_id", - "unique": false - } - ], - "primary_key": [ - "id" - ] } - } -} \ No newline at end of file +} diff --git a/packages/adapters/in_memory/asset_library_repository.py b/packages/adapters/in_memory/asset_library_repository.py index 97b7012af..a758546a5 100644 --- a/packages/adapters/in_memory/asset_library_repository.py +++ b/packages/adapters/in_memory/asset_library_repository.py @@ -46,3 +46,21 @@ class InMemoryAssetLibraryRepository: if library: library.asset_count = max(0, library.asset_count - 1) library.total_size = max(0, library.total_size - size_delta) + + def get_or_create_default_library( + self, + project_id: str, + kind: AssetLibraryKind, + *, + name: str | None = None, + ) -> AssetLibrary: + """幂等获取/创建默认素材库(Issue #1775,内存实现,模拟唯一约束语义)。""" + for lib in self._libraries.values(): + if lib.project_id == project_id and lib.kind == kind: + return lib + # 回退到 find_by_project + for lib in self.find_by_project(project_id, kind): + return lib + library_name = name or f"{kind.value}素材库" + library = AssetLibrary.create(project_id=project_id, name=library_name, kind=kind) + return self.create(library) diff --git a/packages/adapters/in_memory/project_repository.py b/packages/adapters/in_memory/project_repository.py index 8df5e8359..aa3c66cb7 100644 --- a/packages/adapters/in_memory/project_repository.py +++ b/packages/adapters/in_memory/project_repository.py @@ -29,3 +29,30 @@ class InMemoryProjectRepository: del self._items[project_id] return True return False + + def find_default_by_owner(self, owner_user_id: str) -> Project | None: + """查找用户的默认项目(Issue #1775 幂等接口,内存实现)。""" + for p in self._items.values(): + if p.owner_user_id == owner_user_id and getattr(p, "is_default", False): + return p + return None + + def get_or_create_default_project( + self, + owner_user_id: str, + *, + name: str = "默认项目", + description: str = "小程序自动创建的默认项目", + ) -> Project: + """幂等获取/创建默认项目(内存实现,模拟 DB 部分唯一索引语义)。""" + existing = self.find_default_by_owner(owner_user_id) + if existing is not None: + return existing + project = Project.create( + owner_user_id=owner_user_id, + name=name, + description=description, + is_default=True, + ) + self._items[project.id] = project + return project diff --git a/packages/adapters/sqlalchemy_impl/asset_library_repository.py b/packages/adapters/sqlalchemy_impl/asset_library_repository.py index 52025d794..fe0998a51 100644 --- a/packages/adapters/sqlalchemy_impl/asset_library_repository.py +++ b/packages/adapters/sqlalchemy_impl/asset_library_repository.py @@ -90,3 +90,75 @@ class SQLAlchemyAssetLibraryRepository: model.asset_count = max(0, (model.asset_count or 0) - 1) model.total_size = max(0, (model.total_size or 0) - size_delta) self.session.commit() + + def get_or_create_default_library( + self, + project_id: str, + kind: AssetLibraryKind, + *, + name: str | None = None, + ) -> AssetLibrary: + """幂等获取/创建项目下指定 kind 的默认素材库(Issue #1775)。 + + 依赖唯一约束 uq_asset_libraries_project_kind(project_id, kind): + 并发创建只有一个成功,其余 IntegrityError 后回滚重查, + 保证同一项目同 kind 永远只有一个素材库。 + """ + from sqlalchemy.exc import IntegrityError + + default_names = { + AssetLibraryKind.VIDEO: "视频素材库", + AssetLibraryKind.VOICE: "配音素材库", + AssetLibraryKind.IMAGE: "图片素材库", + } + library_name = name or default_names.get(kind, f"{kind.value}素材库") + + # 快速路径 + existing = ( + self.session.query(AssetLibraryModel) + .filter(AssetLibraryModel.project_id == project_id, AssetLibraryModel.kind == kind.value) + .first() + ) + if existing: + return self._to_entity(existing) + + library = AssetLibrary.create(project_id=project_id, name=library_name, kind=kind) + model = AssetLibraryModel( + id=library.id, + project_id=library.project_id, + name=library.name, + kind=library.kind.value, + asset_count=0, + total_size=0, + created_at=library.created_at, + updated_at=library.updated_at, + ) + try: + self.session.add(model) + self.session.commit() + return library + except IntegrityError: + self.session.rollback() + existing = ( + self.session.query(AssetLibraryModel) + .filter( + AssetLibraryModel.project_id == project_id, + AssetLibraryModel.kind == kind.value, + ) + .first() + ) + if existing: + return self._to_entity(existing) + raise + + def _to_entity(self, model: AssetLibraryModel) -> AssetLibrary: + return AssetLibrary( + id=model.id, + project_id=model.project_id, + name=model.name, + kind=AssetLibraryKind(model.kind), + asset_count=int(model.asset_count or 0), + total_size=int(model.total_size or 0), + created_at=model.created_at, + updated_at=model.updated_at, + ) diff --git a/packages/adapters/sqlalchemy_impl/models.py b/packages/adapters/sqlalchemy_impl/models.py index 04ff2381d..9d9a88097 100755 --- a/packages/adapters/sqlalchemy_impl/models.py +++ b/packages/adapters/sqlalchemy_impl/models.py @@ -1,7 +1,7 @@ from datetime import datetime, timezone from typing import Any -from sqlalchemy import JSON, Boolean, Column, DateTime, Float, Integer, String, Text, UniqueConstraint +from sqlalchemy import JSON, Boolean, Column, DateTime, Float, Index, Integer, String, Text, UniqueConstraint, text from sqlalchemy.orm import declarative_base Base: Any = declarative_base() @@ -44,12 +44,18 @@ class UserModel(Base): class ProjectModel(Base): __tablename__ = "projects" + __table_args__ = ( + # Issue #1775: 每个用户至多一个默认项目(部分唯一索引,只约束 is_default=true 的行)。 + # 注意:不加 UniqueConstraint(那会要求全表唯一),用部分索引表达"每用户一个默认项目"。 + Index("uq_projects_owner_default", "owner_user_id", unique=True, postgresql_where=text("is_default = true")), + ) id = Column(String(36), primary_key=True) owner_user_id = Column(String(36), nullable=False, index=True) name = Column(String(100), nullable=False) description = Column(Text, nullable=False, default="") shared_users = Column(JSON, nullable=False, default=list) # 被共享的用户 ID 列表 + is_default = Column(Boolean, nullable=False, default=False, server_default="false") extra_meta = Column("metadata", JSON, nullable=False, default=dict) created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc)) diff --git a/packages/adapters/sqlalchemy_impl/project_repository.py b/packages/adapters/sqlalchemy_impl/project_repository.py index 5444861b7..27b9db972 100644 --- a/packages/adapters/sqlalchemy_impl/project_repository.py +++ b/packages/adapters/sqlalchemy_impl/project_repository.py @@ -15,6 +15,7 @@ class SQLAlchemyProjectRepository: name=model.name, description=model.description, shared_users=model.shared_users or [], + is_default=bool(getattr(model, "is_default", False)), created_at=model.created_at, ) @@ -33,9 +34,12 @@ class SQLAlchemyProjectRepository: name=project.name, description=project.description, shared_users=project.shared_users, + is_default=project.is_default, created_at=project.created_at, ) self.session.add(model) + if existing: + existing.is_default = project.is_default self.session.commit() return project @@ -76,3 +80,59 @@ class SQLAlchemyProjectRepository: self.session.delete(model) self.session.commit() return True + + def find_default_by_owner(self, owner_user_id: str) -> Project | None: + """查找用户的默认项目(is_default=true)。""" + model = ( + self.session.query(ProjectModel) + .filter(ProjectModel.owner_user_id == owner_user_id, ProjectModel.is_default.is_(True)) + .first() + ) + return self._to_entity(model) if model else None + + def get_or_create_default_project( + self, + owner_user_id: str, + *, + name: str = "默认项目", + description: str = "小程序自动创建的默认项目", + ) -> Project: + """幂等获取/创建用户的默认项目(Issue #1775)。 + + 依赖部分唯一索引 uq_projects_owner_default(每用户至多一条 is_default=true): + 并发创建时只有一个 INSERT 成功,其余触发 IntegrityError 后回滚重查, + 保证同一用户永远只有一个默认项目。 + """ + from sqlalchemy.exc import IntegrityError + + # 快速路径:已有默认项目 + existing = self.find_default_by_owner(owner_user_id) + if existing is not None: + return existing + + project = Project.create( + owner_user_id=owner_user_id, + name=name, + description=description, + is_default=True, + ) + model = ProjectModel( + id=project.id, + owner_user_id=project.owner_user_id, + name=project.name, + description=project.description, + shared_users=project.shared_users, + is_default=True, + created_at=project.created_at, + ) + try: + self.session.add(model) + self.session.commit() + return project + except IntegrityError: + # 并发:另一个请求已插入默认项目,回滚后重查 + self.session.rollback() + existing = self.find_default_by_owner(owner_user_id) + if existing is not None: + return existing + raise diff --git a/packages/domain/entities.py b/packages/domain/entities.py index b03997a16..cb5329457 100755 --- a/packages/domain/entities.py +++ b/packages/domain/entities.py @@ -70,10 +70,11 @@ class Project: name: str description: str = "" shared_users: list[str] = field(default_factory=list) # 被共享的用户 ID 列表 + is_default: bool = False # 是否为用户的默认项目(小程序自动创建),DB 部分唯一索引保证每人至多一个 created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) @classmethod - def create(cls, owner_user_id: str, name: str, description: str = "") -> "Project": + def create(cls, owner_user_id: str, name: str, description: str = "", is_default: bool = False) -> "Project": clean_name = name.strip() if not clean_name: raise ValueError("项目名称不能为空") @@ -83,6 +84,7 @@ class Project: name=clean_name, description=description.strip(), shared_users=[], + is_default=is_default, ) def is_owner(self, user_id: str) -> bool: diff --git a/tests/unit/test_default_project_idempotent_1775.py b/tests/unit/test_default_project_idempotent_1775.py new file mode 100644 index 000000000..488ceb612 --- /dev/null +++ b/tests/unit/test_default_project_idempotent_1775.py @@ -0,0 +1,197 @@ +"""默认项目/默认素材库幂等化测试(Issue #1775)。 + +覆盖: +- get_or_create_default_project:同用户幂等、不同用户独立、并发只建一个 +- get_or_create_default_library:同项目同 kind 幂等、IntegrityError 后重查 +- Project.is_default 字段传递 +- ensure-default-context 组合逻辑(用内存仓储) +""" + +from __future__ import annotations + +import threading +from unittest.mock import MagicMock + +import pytest + +from packages.adapters.in_memory.asset_library_repository import InMemoryAssetLibraryRepository +from packages.adapters.in_memory.project_repository import InMemoryProjectRepository +from packages.adapters.sqlalchemy_impl.asset_library_repository import ( + SQLAlchemyAssetLibraryRepository, +) +from packages.adapters.sqlalchemy_impl.project_repository import SQLAlchemyProjectRepository +from packages.domain import AssetLibrary, AssetLibraryKind, Project + + +class TestDefaultProjectIdempotent: + """默认项目幂等。""" + + def test_first_call_creates_default(self): + repo = InMemoryProjectRepository() + project = repo.get_or_create_default_project("user-1") + assert project.owner_user_id == "user-1" + assert project.is_default is True + assert project.name == "默认项目" + + def test_second_call_returns_same_project(self): + repo = InMemoryProjectRepository() + p1 = repo.get_or_create_default_project("user-1") + p2 = repo.get_or_create_default_project("user-1") + assert p1.id == p2.id + + def test_different_users_independent(self): + repo = InMemoryProjectRepository() + p1 = repo.get_or_create_default_project("user-1") + p2 = repo.get_or_create_default_project("user-2") + assert p1.id != p2.id + assert p1.owner_user_id == "user-1" + assert p2.owner_user_id == "user-2" + + def test_find_default_by_owner(self): + repo = InMemoryProjectRepository() + created = repo.get_or_create_default_project("user-1") + found = repo.find_default_by_owner("user-1") + assert found is not None + assert found.id == created.id + + def test_find_default_returns_none_when_no_default(self): + repo = InMemoryProjectRepository() + # 手动建一个非默认项目 + normal = Project.create(owner_user_id="user-1", name="普通项目") + normal.is_default = False + repo.save(normal) + assert repo.find_default_by_owner("user-1") is None + + def test_concurrent_10_calls_only_one_project(self): + """并发 10 次调用,只产生 1 个默认项目。""" + repo = InMemoryProjectRepository() + results = [] + lock = threading.Lock() + + def call(): + p = repo.get_or_create_default_project("user-concurrent") + with lock: + results.append(p.id) + + threads = [threading.Thread(target=call) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + + assert len(results) == 10 + assert len(set(results)) == 1, f"应只有 1 个项目,实际: {set(results)}" + # 数据库中也只有 1 个默认项目 + defaults = [p for p in repo.find_by_owner_user_id("user-concurrent") if p.is_default] + assert len(defaults) == 1 + + +class TestDefaultLibraryIdempotent: + """默认素材库幂等。""" + + def test_first_call_creates(self): + repo = InMemoryAssetLibraryRepository() + lib = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VIDEO) + assert lib.project_id == "proj-1" + assert lib.kind == AssetLibraryKind.VIDEO + + def test_second_call_returns_same(self): + repo = InMemoryAssetLibraryRepository() + l1 = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VIDEO) + l2 = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VIDEO) + assert l1.id == l2.id + + def test_different_kinds_independent(self): + repo = InMemoryAssetLibraryRepository() + v = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VIDEO) + a = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VOICE) + i = repo.get_or_create_default_library("proj-1", AssetLibraryKind.IMAGE) + assert len({v.id, a.id, i.id}) == 3 + + def test_different_projects_independent(self): + repo = InMemoryAssetLibraryRepository() + l1 = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VIDEO) + l2 = repo.get_or_create_default_library("proj-2", AssetLibraryKind.VIDEO) + assert l1.id != l2.id + + def test_concurrent_calls_only_one_library(self): + repo = InMemoryAssetLibraryRepository() + results = [] + lock = threading.Lock() + + def call(): + lib = repo.get_or_create_default_library("proj-cc", AssetLibraryKind.VOICE) + with lock: + results.append(lib.id) + + threads = [threading.Thread(target=call) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + + assert len(set(results)) == 1 + + +class TestProjectIsDefaultField: + """Project.is_default 字段语义。""" + + def test_create_non_default_by_default(self): + p = Project.create(owner_user_id="u", name="普通项目") + assert p.is_default is False + + def test_create_default(self): + p = Project.create(owner_user_id="u", name="默认项目", is_default=True) + assert p.is_default is True + + +class TestSqlRepoIntegrityErrorRecovery: + """SQLAlchemy 仓储:唯一约束冲突时回滚重查,返回已有记录(不报 500)。""" + + def test_project_integrity_error_returns_existing(self): + from sqlalchemy.exc import IntegrityError + + session = MagicMock() + # commit 第一次抛 IntegrityError(并发冲突),回滚后查询返回已有项目 + existing_model = MagicMock() + existing_model.id = "existing-id" + existing_model.owner_user_id = "user-1" + existing_model.name = "默认项目" + existing_model.description = "" + existing_model.shared_users = [] + existing_model.is_default = True + existing_model.created_at = None + + session.commit.side_effect = [IntegrityError("stmt", {}, Exception("dup")), None] + # 第一次 query(快速路径 find_default)返回 None;rollback 后第二次返回 existing + session.query.return_value.filter.return_value.first.side_effect = [None, existing_model] + + repo = SQLAlchemyProjectRepository(session) + result = repo.get_or_create_default_project("user-1") + + assert result.id == "existing-id" + session.rollback.assert_called_once() + + def test_library_integrity_error_returns_existing(self): + from sqlalchemy.exc import IntegrityError + + session = MagicMock() + existing_model = MagicMock() + existing_model.id = "lib-existing" + existing_model.project_id = "proj-1" + existing_model.name = "视频素材库" + existing_model.kind = "video" + existing_model.asset_count = 0 + existing_model.total_size = 0 + existing_model.created_at = None + existing_model.updated_at = None + + session.commit.side_effect = [IntegrityError("stmt", {}, Exception("dup")), None] + session.query.return_value.filter.return_value.first.side_effect = [None, existing_model] + + repo = SQLAlchemyAssetLibraryRepository(session) + result = repo.get_or_create_default_library("proj-1", AssetLibraryKind.VIDEO) + + assert result.id == "lib-existing" + assert result.kind == AssetLibraryKind.VIDEO + session.rollback.assert_called_once() -- 2.54.0 From f6c18b3aa95c57885279e8c76e85ca4163490af3 Mon Sep 17 00:00:00 2001 From: saas-backend-agent Date: Tue, 8 Sep 2026 02:10:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20schema=20=E5=BF=AB=E7=85=A7?= =?UTF-8?q?=E4=BB=85=E5=A2=9E=E9=87=8F=20is=5Fdefault=20=E5=88=97+?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=94=AF=E4=B8=80=E7=B4=A2=E5=BC=95=EF=BC=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BC=A9=E8=BF=9B=E6=A0=BC=E5=BC=8F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/schema-metadata-snapshot.json | 7163 ++++++++++++++-------------- 1 file changed, 3553 insertions(+), 3610 deletions(-) diff --git a/docs/schema-metadata-snapshot.json b/docs/schema-metadata-snapshot.json index 7a90d0cb6..ad75ae9a7 100644 --- a/docs/schema-metadata-snapshot.json +++ b/docs/schema-metadata-snapshot.json @@ -1,3645 +1,3588 @@ { - "tables": { - "asset_libraries": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": true, - "name": "kind", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "asset_count", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "total_size", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["kind"], "name": "ix_asset_libraries_kind", "unique": false}, - {"columns": ["project_id"], "name": "ix_asset_libraries_project_id", "unique": false}, - ], - "primary_key": ["id"], + "tables": { + "asset_libraries": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false }, - "asset_tags": { - "columns": [ - { - "index": false, - "name": "asset_id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "tag_id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [], - "primary_key": ["asset_id", "tag_id"], + { + "index": true, + "name": "project_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false }, - "assets": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "asset_library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": true, - "name": "file_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "file_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": false, - "name": "storage_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "thumbnail_url", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": false, - "name": "duration", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "width", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "height", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "fps", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "codec", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": true, - "name": "classification_status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "classification_result", - "nullable": true, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "quality_score", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "uploaded_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "file_hash", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false, - }, - { - "index": true, - "name": "client_upload_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": true, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["asset_library_id"], "name": "ix_assets_asset_library_id", "unique": false}, - {"columns": ["classification_status"], "name": "ix_assets_classification_status", "unique": false}, - {"columns": ["client_upload_id"], "name": "ix_assets_client_upload_id", "unique": false}, - {"columns": ["created_at"], "name": "ix_assets_created_at", "unique": false}, - {"columns": ["file_hash"], "name": "ix_assets_file_hash", "unique": false}, - {"columns": ["file_type"], "name": "ix_assets_file_type", "unique": false}, - {"columns": ["project_id"], "name": "ix_assets_project_id", "unique": false}, - {"columns": ["status"], "name": "ix_assets_status", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false }, - "billing_records": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "plan_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "amount", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "billing_cycle", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "payment_method", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "payment_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "invoice_url", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "paid_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [{"columns": ["user_id"], "name": "ix_billing_records_user_id", "unique": false}], - "primary_key": ["id"], + { + "index": true, + "name": "kind", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false }, - "classification_jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "classification", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "confidence", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["asset_id"], "name": "ix_classification_jobs_asset_id", "unique": false}, - {"columns": ["project_id"], "name": "ix_classification_jobs_project_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "asset_count", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "cover_templates": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false, - }, - { - "index": false, - "name": "thumbnail_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": true, - "name": "is_system", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["is_system"], "name": "ix_cover_templates_is_system", "unique": false}, - {"columns": ["user_id"], "name": "ix_cover_templates_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "total_size", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "duplication_records": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "filename", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "storage_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "duration_seconds", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "duplicate_rate", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "duplicate_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "visual_similarity", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "match_count", - "nullable": true, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "video_fingerprint", - "nullable": true, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["status"], "name": "ix_duplication_records_status", "unique": false}, - {"columns": ["user_id"], "name": "ix_duplication_records_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false }, - "duplication_segments": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "record_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "source_start", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "source_end", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "matched_video_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "matched_video_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "matched_start", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "matched_end", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "similarity", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - ], - "indexes": [{"columns": ["record_id"], "name": "ix_duplication_segments_record_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false }, - "edit_plan_clips": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "plan_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "clip_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": true, - "name": "template_clip_config_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "text_content", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "start_time", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "transition_effect", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "transition_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "playback_speed", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["asset_id"], "name": "ix_edit_plan_clips_asset_id", "unique": false}, - {"columns": ["clip_type"], "name": "ix_edit_plan_clips_clip_type", "unique": false}, - {"columns": ["plan_id"], "name": "ix_edit_plan_clips_plan_id", "unique": false}, - {"columns": ["status"], "name": "ix_edit_plan_clips_status", "unique": false}, - { - "columns": ["template_clip_config_id"], - "name": "ix_edit_plan_clips_template_clip_config_id", - "unique": false, - }, - ], - "primary_key": ["id"], + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "kind" + ], + "name": "ix_asset_libraries_kind", + "unique": false }, - "edit_plans": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "total_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": true, - "name": "source_edit_plan_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "created_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["created_by_user_id"], "name": "ix_edit_plans_created_by_user_id", "unique": false}, - {"columns": ["project_id"], "name": "ix_edit_plans_project_id", "unique": false}, - {"columns": ["source_edit_plan_id"], "name": "ix_edit_plans_source_edit_plan_id", "unique": false}, - {"columns": ["status"], "name": "ix_edit_plans_status", "unique": false}, - {"columns": ["template_id"], "name": "ix_edit_plans_template_id", "unique": false}, - ], - "primary_key": ["id"], + { + "columns": [ + "project_id" + ], + "name": "ix_asset_libraries_project_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "asset_tags": { + "columns": [ + { + "index": false, + "name": "asset_id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false }, - "edit_template_versions": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": false, - }, - { - "index": false, - "name": "version", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false, - }, - { - "index": false, - "name": "editing_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(30)", - "unique": false, - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "clip_configs", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "change_note", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "published_by", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [{"columns": ["template_id"], "name": "ix_edit_template_versions_template_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "tag_id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false }, - "edit_templates": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(120)", - "unique": false, - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": true, - "name": "template_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "editing_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "preview_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": true, - "name": "sort_weight", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "version", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["sort_weight"], "name": "ix_edit_templates_sort_weight", "unique": false}, - {"columns": ["status"], "name": "ix_edit_templates_status", "unique": false}, - {"columns": ["template_type"], "name": "ix_edit_templates_template_type", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [], + "primary_key": [ + "asset_id", + "tag_id" + ] + }, + "assets": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false }, - "generated_videos": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "generation_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "file_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "thumbnail_url", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": false, - "name": "width", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "height", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "fps", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": true, - "name": "review_status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "generation_params", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "generated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "video_fingerprint", - "nullable": true, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "is_duplicate", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "duplicate_of", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "duplicate_rate", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "match_count", - "nullable": true, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "visual_similarity", - "nullable": true, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["generation_task_id"], "name": "ix_generated_videos_generation_task_id", "unique": false}, - {"columns": ["project_id"], "name": "ix_generated_videos_project_id", "unique": false}, - {"columns": ["review_status"], "name": "ix_generated_videos_review_status", "unique": false}, - {"columns": ["status"], "name": "ix_generated_videos_status", "unique": false}, - {"columns": ["user_id"], "name": "ix_generated_videos_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false }, - "generation_tasks": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "strategy_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "asset_library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "voice_library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "asset_ids", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "title_ids", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "voice_ids", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": true, - "name": "editing_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "progress", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "result_count", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "error_info", - "nullable": true, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "auto_retry_enabled", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "auto_retry_max", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "started_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": true, - "name": "created_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "source_edit_plan_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "edit_plan_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "asset_select_mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": true, - "name": "batch_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "video_title", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "resolution", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": true, - "name": "is_preview", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": true, - "name": "source_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": false, - }, - { - "index": false, - "name": "celery_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false, - }, - { - "index": false, - "name": "output_width", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "output_height", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "cover_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": false, - "name": "custom_title", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "title_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "bgm_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "logs", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["asset_library_id"], "name": "ix_generation_tasks_asset_library_id", "unique": false}, - {"columns": ["batch_id"], "name": "ix_generation_tasks_batch_id", "unique": false}, - {"columns": ["created_by_user_id"], "name": "ix_generation_tasks_created_by_user_id", "unique": false}, - {"columns": ["edit_plan_id"], "name": "ix_generation_tasks_edit_plan_id", "unique": false}, - {"columns": ["editing_mode"], "name": "ix_generation_tasks_editing_mode", "unique": false}, - {"columns": ["is_preview"], "name": "ix_generation_tasks_is_preview", "unique": false}, - {"columns": ["project_id"], "name": "ix_generation_tasks_project_id", "unique": false}, - { - "columns": ["source_edit_plan_id"], - "name": "ix_generation_tasks_source_edit_plan_id", - "unique": false, - }, - {"columns": ["source_task_id"], "name": "ix_generation_tasks_source_task_id", "unique": false}, - {"columns": ["status"], "name": "ix_generation_tasks_status", "unique": false}, - {"columns": ["template_id"], "name": "ix_generation_tasks_template_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": true, + "name": "asset_library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false }, - "ingest_jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "library_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "storage_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "result_asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "file_hash", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false, - }, - { - "index": true, - "name": "asset_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "celery_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(64)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["asset_id"], "name": "ix_ingest_jobs_asset_id", "unique": false}, - {"columns": ["file_hash"], "name": "ix_ingest_jobs_file_hash", "unique": false}, - {"columns": ["library_id"], "name": "ix_ingest_jobs_library_id", "unique": false}, - {"columns": ["project_id"], "name": "ix_ingest_jobs_project_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false }, - "jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "job_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(30)", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "progress", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "current_stage", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false, - }, - { - "index": false, - "name": "payload", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "result", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "max_retries", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "celery_task_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": true, - "name": "source_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "created_by_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "started_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["created_by_user_id"], "name": "ix_jobs_created_by_user_id", "unique": false}, - {"columns": ["job_type"], "name": "ix_jobs_job_type", "unique": false}, - {"columns": ["project_id"], "name": "ix_jobs_project_id", "unique": false}, - {"columns": ["source_id"], "name": "ix_jobs_source_id", "unique": false}, - {"columns": ["status"], "name": "ix_jobs_status", "unique": false}, - ], - "primary_key": ["id"], + { + "index": true, + "name": "file_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false }, - "projects": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "owner_user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "shared_users", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "is_default", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["owner_user_id"], "name": "ix_projects_owner_user_id", "unique": false}, - {"columns": ["owner_user_id"], "name": "uq_projects_owner_default", "unique": true}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false }, - "recipe_items": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "recipe_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "item_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "item_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "position", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - ], - "indexes": [{"columns": ["recipe_id"], "name": "ix_recipe_items_recipe_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "file_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false }, - "recipes": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false, - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "generation_params", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [{"columns": ["user_id"], "name": "ix_recipes_user_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "storage_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false }, - "tags": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [{"columns": ["user_id"], "name": "ix_tags_user_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "thumbnail_url", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false }, - "template_categories": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "sort_order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [{"columns": ["user_id"], "name": "ix_template_categories_user_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "duration", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "template_clip_configs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "clip_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "min_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "max_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "text_template", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "material_requirements", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "transition_effect", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["clip_type"], "name": "ix_template_clip_configs_clip_type", "unique": false}, - {"columns": ["template_id"], "name": "ix_template_clip_configs_template_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "width", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "template_segments": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "template_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "segment_order", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "duration_min", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "duration_max", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "material_type", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [{"columns": ["template_id"], "name": "ix_template_segments_template_id", "unique": false}], - "primary_key": ["id"], + { + "index": false, + "name": "height", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "templates": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(200)", - "unique": false, - }, - { - "index": true, - "name": "mode", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(30)", - "unique": false, - }, - { - "index": false, - "name": "category", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "tags", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "title_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "subtitle_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "bgm_config", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "estimated_duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["mode"], "name": "ix_templates_mode", "unique": false}, - {"columns": ["user_id"], "name": "ix_templates_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "fps", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "title_libraries": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": true, - "name": "category", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "text", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "tags", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "usage_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": true, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["category"], "name": "ix_title_libraries_category", "unique": false}, - {"columns": ["is_active"], "name": "ix_title_libraries_is_active", "unique": false}, - {"columns": ["user_id"], "name": "ix_title_libraries_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "codec", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false }, - "tts_jobs": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "input_text", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "voice_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "voice_model", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "voice_clone_profile_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "output_audio_url", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "output_audio_key", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(500)", - "unique": false, - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "sample_rate", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "format", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "max_retries", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "started_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["status"], "name": "ix_tts_jobs_status", "unique": false}, - {"columns": ["user_id"], "name": "ix_tts_jobs_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false }, - "users": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "email", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": true, - }, - { - "index": true, - "name": "username", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": true, - }, - { - "index": false, - "name": "display_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "password_hash", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "email_verified", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "email_verification_token", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "password_reset_token", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "password_reset_expires_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "last_login_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "last_login_ip", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "subscription_plan", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "subscription_status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "subscription_expires_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "max_projects", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "max_storage_gb", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "used_storage_gb", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "is_admin", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": true, - "name": "wechat_openid", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(128)", - "unique": true, - }, - { - "index": true, - "name": "wechat_unionid", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(128)", - "unique": true, - }, - { - "index": true, - "name": "phone", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": true, - }, - { - "index": false, - "name": "phone_verified", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "binding_completed_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "profile_completed", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["email"], "name": "ix_users_email", "unique": true}, - {"columns": ["phone"], "name": "ix_users_phone", "unique": true}, - {"columns": ["username"], "name": "ix_users_username", "unique": true}, - {"columns": ["wechat_openid"], "name": "ix_users_wechat_openid", "unique": true}, - {"columns": ["wechat_unionid"], "name": "ix_users_wechat_unionid", "unique": true}, - ], - "primary_key": ["id"], + { + "index": true, + "name": "classification_status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false }, - "verification_codes": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "recipient", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "code", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(10)", - "unique": false, - }, - { - "index": true, - "name": "code_type", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": false, - }, - { - "index": false, - "name": "expires_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "used_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "attempts", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["code_type"], "name": "ix_verification_codes_code_type", "unique": false}, - {"columns": ["recipient"], "name": "ix_verification_codes_recipient", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "classification_result", + "nullable": true, + "primary_key": false, + "type": "TEXT", + "unique": false }, - "video_fingerprint_chunks": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "video_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "start_time_ms", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "end_time_ms", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "phash_binary", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(16)", - "unique": false, - }, - { - "index": false, - "name": "color_histogram", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "frame_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["project_id"], "name": "ix_video_fingerprint_chunks_project_id", "unique": false}, - {"columns": ["user_id"], "name": "ix_video_fingerprint_chunks_user_id", "unique": false}, - {"columns": ["video_id"], "name": "ix_video_fingerprint_chunks_video_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "quality_score", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false }, - "video_shares": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(32)", - "unique": false, - }, - { - "index": true, - "name": "video_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(32)", - "unique": false, - }, - { - "index": false, - "name": "share_token", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(16)", - "unique": true, - }, - { - "index": false, - "name": "password_hash", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "expires_at", - "nullable": true, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "view_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "download_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "is_active", - "nullable": false, - "primary_key": false, - "type": "BOOLEAN", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["user_id"], "name": "ix_video_shares_user_id", "unique": false}, - {"columns": ["video_id"], "name": "ix_video_shares_video_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "uploaded_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false }, - "voice_clone_profiles": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "description", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "source_audio_url", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "voice_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "voice_model", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "language", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "gender", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "error_message", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "retry_count", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "max_retries", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["status"], "name": "ix_voice_clone_profiles_status", "unique": false}, - {"columns": ["user_id"], "name": "ix_voice_clone_profiles_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": true, + "name": "file_hash", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false }, - "voice_libraries": { - "columns": [ - { - "index": false, - "name": "id", - "nullable": false, - "primary_key": true, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "user_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": true, - "name": "project_id", - "nullable": true, - "primary_key": false, - "type": "VARCHAR(36)", - "unique": false, - }, - { - "index": false, - "name": "name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(255)", - "unique": false, - }, - { - "index": false, - "name": "text", - "nullable": false, - "primary_key": false, - "type": "TEXT", - "unique": false, - }, - { - "index": false, - "name": "voice_provider", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(50)", - "unique": false, - }, - { - "index": false, - "name": "voice_id", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "voice_name", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(100)", - "unique": false, - }, - { - "index": false, - "name": "audio_url", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(1000)", - "unique": false, - }, - { - "index": false, - "name": "duration", - "nullable": false, - "primary_key": false, - "type": "FLOAT", - "unique": false, - }, - { - "index": false, - "name": "file_size", - "nullable": false, - "primary_key": false, - "type": "INTEGER", - "unique": false, - }, - { - "index": true, - "name": "status", - "nullable": false, - "primary_key": false, - "type": "VARCHAR(20)", - "unique": false, - }, - { - "index": false, - "name": "tags", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "metadata", - "nullable": false, - "primary_key": false, - "type": "JSON", - "unique": false, - }, - { - "index": false, - "name": "created_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - { - "index": false, - "name": "updated_at", - "nullable": false, - "primary_key": false, - "type": "DATETIME", - "unique": false, - }, - ], - "indexes": [ - {"columns": ["project_id"], "name": "ix_voice_libraries_project_id", "unique": false}, - {"columns": ["status"], "name": "ix_voice_libraries_status", "unique": false}, - {"columns": ["user_id"], "name": "ix_voice_libraries_user_id", "unique": false}, - ], - "primary_key": ["id"], + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false }, + { + "index": true, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "asset_library_id" + ], + "name": "ix_assets_asset_library_id", + "unique": false + }, + { + "columns": [ + "classification_status" + ], + "name": "ix_assets_classification_status", + "unique": false + }, + { + "columns": [ + "created_at" + ], + "name": "ix_assets_created_at", + "unique": false + }, + { + "columns": [ + "file_hash" + ], + "name": "ix_assets_file_hash", + "unique": false + }, + { + "columns": [ + "file_type" + ], + "name": "ix_assets_file_type", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_assets_project_id", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_assets_status", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "billing_records": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "plan_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "amount", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "billing_cycle", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "payment_method", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "payment_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "invoice_url", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "paid_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "user_id" + ], + "name": "ix_billing_records_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "classification_jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "classification", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "confidence", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "asset_id" + ], + "name": "ix_classification_jobs_asset_id", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_classification_jobs_project_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "duplication_records": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "filename", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "storage_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + }, + { + "index": false, + "name": "duration_seconds", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "duplicate_rate", + "nullable": true, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "duplicate_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "video_fingerprint", + "nullable": true, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "status" + ], + "name": "ix_duplication_records_status", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_duplication_records_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "duplication_segments": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "record_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "source_start", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "source_end", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "matched_video_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "matched_video_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + }, + { + "index": false, + "name": "matched_start", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "matched_end", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "similarity", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "record_id" + ], + "name": "ix_duplication_segments_record_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "edit_plan_clips": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "plan_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "clip_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": true, + "name": "template_clip_config_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "text_content", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "start_time", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "transition_effect", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "transition_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "playback_speed", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "asset_id" + ], + "name": "ix_edit_plan_clips_asset_id", + "unique": false + }, + { + "columns": [ + "clip_type" + ], + "name": "ix_edit_plan_clips_clip_type", + "unique": false + }, + { + "columns": [ + "plan_id" + ], + "name": "ix_edit_plan_clips_plan_id", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_edit_plan_clips_status", + "unique": false + }, + { + "columns": [ + "template_clip_config_id" + ], + "name": "ix_edit_plan_clips_template_clip_config_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "edit_plans": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "total_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "result_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": true, + "name": "source_edit_plan_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "created_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "created_by_user_id" + ], + "name": "ix_edit_plans_created_by_user_id", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_edit_plans_project_id", + "unique": false + }, + { + "columns": [ + "source_edit_plan_id" + ], + "name": "ix_edit_plans_source_edit_plan_id", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_edit_plans_status", + "unique": false + }, + { + "columns": [ + "template_id" + ], + "name": "ix_edit_plans_template_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "edit_templates": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(120)", + "unique": false + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": true, + "name": "template_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "editing_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "preview_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false + }, + { + "index": true, + "name": "sort_weight", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "sort_weight" + ], + "name": "ix_edit_templates_sort_weight", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_edit_templates_status", + "unique": false + }, + { + "columns": [ + "template_type" + ], + "name": "ix_edit_templates_template_type", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "generated_videos": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "generation_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "file_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "thumbnail_url", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false + }, + { + "index": false, + "name": "width", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "height", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "fps", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": true, + "name": "review_status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "generation_params", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "generated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "video_fingerprint", + "nullable": true, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "is_duplicate", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "duplicate_of", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "generation_task_id" + ], + "name": "ix_generated_videos_generation_task_id", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_generated_videos_project_id", + "unique": false + }, + { + "columns": [ + "review_status" + ], + "name": "ix_generated_videos_review_status", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_generated_videos_status", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_generated_videos_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "generation_tasks": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "strategy_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "asset_library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "voice_library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "asset_ids", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "title_ids", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "voice_ids", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": true, + "name": "editing_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "progress", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "result_count", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "error_info", + "nullable": true, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "auto_retry_enabled", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "auto_retry_max", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "started_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": true, + "name": "created_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "source_edit_plan_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "asset_select_mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": true, + "name": "batch_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "video_title", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "logs", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "is_preview", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": true, + "name": "source_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(32)", + "unique": false + }, + { + "index": false, + "name": "output_width", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "output_height", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "cover_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false + }, + { + "index": false, + "name": "custom_title", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "asset_library_id" + ], + "name": "ix_generation_tasks_asset_library_id", + "unique": false + }, + { + "columns": [ + "batch_id" + ], + "name": "ix_generation_tasks_batch_id", + "unique": false + }, + { + "columns": [ + "created_by_user_id" + ], + "name": "ix_generation_tasks_created_by_user_id", + "unique": false + }, + { + "columns": [ + "editing_mode" + ], + "name": "ix_generation_tasks_editing_mode", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_generation_tasks_project_id", + "unique": false + }, + { + "columns": [ + "source_edit_plan_id" + ], + "name": "ix_generation_tasks_source_edit_plan_id", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_generation_tasks_status", + "unique": false + }, + { + "columns": [ + "template_id" + ], + "name": "ix_generation_tasks_template_id", + "unique": false + }, + { + "columns": [ + "source_task_id" + ], + "name": "ix_generation_tasks_source_task_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "ingest_jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "library_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "storage_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "result_asset_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "file_hash", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(64)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "file_hash" + ], + "name": "ix_ingest_jobs_file_hash", + "unique": false + }, + { + "columns": [ + "library_id" + ], + "name": "ix_ingest_jobs_library_id", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_ingest_jobs_project_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "job_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(30)", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "progress", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "current_stage", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false + }, + { + "index": false, + "name": "payload", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "result", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "max_retries", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "celery_task_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": true, + "name": "source_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "created_by_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "started_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "created_by_user_id" + ], + "name": "ix_jobs_created_by_user_id", + "unique": false + }, + { + "columns": [ + "job_type" + ], + "name": "ix_jobs_job_type", + "unique": false + }, + { + "columns": [ + "project_id" + ], + "name": "ix_jobs_project_id", + "unique": false + }, + { + "columns": [ + "source_id" + ], + "name": "ix_jobs_source_id", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_jobs_status", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "projects": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "owner_user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "shared_users", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "is_default", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "owner_user_id" + ], + "name": "ix_projects_owner_user_id", + "unique": false + }, + { + "columns": [ + "owner_user_id" + ], + "name": "uq_projects_owner_default", + "unique": true + } + ], + "primary_key": [ + "id" + ] + }, + "recipe_items": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "recipe_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "item_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "item_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "position", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "recipe_id" + ], + "name": "ix_recipe_items_recipe_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "recipes": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "generation_params", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "user_id" + ], + "name": "ix_recipes_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "tags": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "user_id" + ], + "name": "ix_tags_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "template_categories": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "user_id" + ], + "name": "ix_template_categories_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "template_clip_configs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "clip_type", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "min_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "max_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "text_template", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "material_requirements", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "transition_effect", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "clip_type" + ], + "name": "ix_template_clip_configs_clip_type", + "unique": false + }, + { + "columns": [ + "template_id" + ], + "name": "ix_template_clip_configs_template_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "template_segments": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "template_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "segment_order", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "duration_min", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "duration_max", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "material_type", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "template_id" + ], + "name": "ix_template_segments_template_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "templates": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(200)", + "unique": false + }, + { + "index": true, + "name": "mode", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(30)", + "unique": false + }, + { + "index": false, + "name": "category", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "tags", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "title_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "subtitle_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "bgm_config", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "estimated_duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "mode" + ], + "name": "ix_templates_mode", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_templates_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "title_libraries": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": true, + "name": "category", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "text", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + }, + { + "index": false, + "name": "tags", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "usage_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": true, + "name": "is_active", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "category" + ], + "name": "ix_title_libraries_category", + "unique": false + }, + { + "columns": [ + "is_active" + ], + "name": "ix_title_libraries_is_active", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_title_libraries_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "tts_jobs": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "input_text", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "voice_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "voice_model", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "project_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "voice_clone_profile_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "output_audio_url", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "output_audio_key", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(500)", + "unique": false + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "sample_rate", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "format", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "max_retries", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "started_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "completed_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "status" + ], + "name": "ix_tts_jobs_status", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_tts_jobs_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "users": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "email", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": true + }, + { + "index": true, + "name": "username", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": true + }, + { + "index": false, + "name": "display_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "password_hash", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "email_verified", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": false, + "name": "email_verification_token", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "password_reset_token", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "password_reset_expires_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "last_login_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "last_login_ip", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "subscription_plan", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "subscription_status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "subscription_expires_at", + "nullable": true, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "max_projects", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "max_storage_gb", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "used_storage_gb", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "is_admin", + "nullable": false, + "primary_key": false, + "type": "BOOLEAN", + "unique": false + }, + { + "index": true, + "name": "wechat_openid", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(128)", + "unique": true + }, + { + "index": true, + "name": "wechat_unionid", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(128)", + "unique": true + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "email" + ], + "name": "ix_users_email", + "unique": true + }, + { + "columns": [ + "username" + ], + "name": "ix_users_username", + "unique": true + }, + { + "columns": [ + "wechat_openid" + ], + "name": "ix_users_wechat_openid", + "unique": true + }, + { + "columns": [ + "wechat_unionid" + ], + "name": "ix_users_wechat_unionid", + "unique": true + } + ], + "primary_key": [ + "id" + ] + }, + "voice_clone_profiles": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "description", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "source_audio_url", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "voice_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "voice_model", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "language", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "gender", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "error_message", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "retry_count", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "max_retries", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "status" + ], + "name": "ix_voice_clone_profiles_status", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_voice_clone_profiles_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] + }, + "voice_libraries": { + "columns": [ + { + "index": false, + "name": "id", + "nullable": false, + "primary_key": true, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "user_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": true, + "name": "project_id", + "nullable": true, + "primary_key": false, + "type": "VARCHAR(36)", + "unique": false + }, + { + "index": false, + "name": "name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(255)", + "unique": false + }, + { + "index": false, + "name": "text", + "nullable": false, + "primary_key": false, + "type": "TEXT", + "unique": false + }, + { + "index": false, + "name": "voice_provider", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(50)", + "unique": false + }, + { + "index": false, + "name": "voice_id", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "voice_name", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(100)", + "unique": false + }, + { + "index": false, + "name": "audio_url", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(1000)", + "unique": false + }, + { + "index": false, + "name": "duration", + "nullable": false, + "primary_key": false, + "type": "FLOAT", + "unique": false + }, + { + "index": false, + "name": "file_size", + "nullable": false, + "primary_key": false, + "type": "INTEGER", + "unique": false + }, + { + "index": true, + "name": "status", + "nullable": false, + "primary_key": false, + "type": "VARCHAR(20)", + "unique": false + }, + { + "index": false, + "name": "tags", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "metadata", + "nullable": false, + "primary_key": false, + "type": "JSON", + "unique": false + }, + { + "index": false, + "name": "created_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + }, + { + "index": false, + "name": "updated_at", + "nullable": false, + "primary_key": false, + "type": "DATETIME", + "unique": false + } + ], + "indexes": [ + { + "columns": [ + "project_id" + ], + "name": "ix_voice_libraries_project_id", + "unique": false + }, + { + "columns": [ + "status" + ], + "name": "ix_voice_libraries_status", + "unique": false + }, + { + "columns": [ + "user_id" + ], + "name": "ix_voice_libraries_user_id", + "unique": false + } + ], + "primary_key": [ + "id" + ] } + } } -- 2.54.0