CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, display_name TEXT NOT NULL, role TEXT NOT NULL, status TEXT NOT NULL, permissions TEXT NOT NULL, create_time TEXT NOT NULL, last_login TEXT, protected INTEGER NOT NULL DEFAULT 0 ); CREATE TABLE IF NOT EXISTS models ( id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, type TEXT NOT NULL, purpose TEXT NOT NULL, model_source TEXT NOT NULL, description TEXT, path TEXT, api_url TEXT, api_key TEXT, online_model_name TEXT, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS trained_models ( id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, train_methods TEXT NOT NULL, base_model_path TEXT, create_time TEXT NOT NULL, merged INTEGER NOT NULL DEFAULT 0, merging INTEGER NOT NULL DEFAULT 0, merged_path TEXT, artifact_dir TEXT, compute_node_id TEXT, compute_node_name TEXT ); CREATE TABLE IF NOT EXISTS model_lineage ( id TEXT PRIMARY KEY, child_resource_type TEXT NOT NULL, child_resource_id TEXT NOT NULL, parent_resource_type TEXT NOT NULL, parent_resource_id TEXT NOT NULL, relation_type TEXT NOT NULL, compute_job_id TEXT, payload TEXT NOT NULL, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS model_artifacts ( id TEXT PRIMARY KEY, model_id TEXT NOT NULL, model_kind TEXT NOT NULL, artifact_type TEXT NOT NULL, path TEXT NOT NULL, size_bytes BIGINT NOT NULL DEFAULT 0, checksum_sha256 TEXT, metadata TEXT NOT NULL, compute_job_id TEXT, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS model_export_jobs ( id TEXT PRIMARY KEY, trained_model_id TEXT, compute_job_id TEXT NOT NULL, node_id TEXT, export_type TEXT NOT NULL, quantization_bit INTEGER NOT NULL DEFAULT 0, status TEXT NOT NULL, output_dir TEXT, payload TEXT NOT NULL, create_time TEXT NOT NULL, completed_at TEXT ); CREATE TABLE IF NOT EXISTS datasets ( id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, type TEXT NOT NULL, storage_type TEXT NOT NULL, source TEXT NOT NULL, task_id TEXT, size TEXT, count INTEGER NOT NULL DEFAULT 0, description TEXT, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS dataset_files ( id TEXT PRIMARY KEY, dataset_id TEXT NOT NULL REFERENCES datasets(id) ON DELETE CASCADE, name TEXT NOT NULL, size TEXT, content TEXT NOT NULL, active_version_id TEXT NOT NULL, versions TEXT NOT NULL, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS compute_nodes ( id TEXT PRIMARY KEY, code TEXT NOT NULL UNIQUE, name TEXT NOT NULL, api_base_url TEXT NOT NULL, file_gateway_url TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1, scheduler_status TEXT NOT NULL, scheduler_weight INTEGER NOT NULL DEFAULT 100, tags TEXT NOT NULL, gpu_count INTEGER NOT NULL DEFAULT 0, current_running_jobs INTEGER NOT NULL DEFAULT 0, max_parallel_jobs INTEGER NOT NULL DEFAULT 2, data_root TEXT NOT NULL, model_root TEXT NOT NULL, log_root TEXT NOT NULL, api_version TEXT NOT NULL DEFAULT 'v1', capabilities TEXT NOT NULL DEFAULT '[]', description TEXT, last_health_check_at TEXT, health_detail TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS gpus ( id TEXT PRIMARY KEY, node_id TEXT NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE, gpu_index INTEGER NOT NULL, uuid TEXT NOT NULL, name TEXT NOT NULL, memory_total_gb DOUBLE PRECISION NOT NULL, power_limit_w DOUBLE PRECISION NOT NULL, base_temperature INTEGER NOT NULL, last_seen_at TEXT ); CREATE TABLE IF NOT EXISTS fine_tune_tasks ( id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, payload TEXT NOT NULL, status TEXT NOT NULL, progress INTEGER NOT NULL DEFAULT 0, process_id INTEGER, create_time TEXT NOT NULL, start_time TEXT, completed_at TEXT, compute_node_id TEXT REFERENCES compute_nodes(id) ON DELETE SET NULL, gpus TEXT NOT NULL, sync_job_id TEXT, compute_job_id TEXT ); CREATE TABLE IF NOT EXISTS fine_tune_metrics ( id TEXT PRIMARY KEY, task_id TEXT NOT NULL REFERENCES fine_tune_tasks(id) ON DELETE CASCADE, step INTEGER NOT NULL, epoch DOUBLE PRECISION, loss DOUBLE PRECISION, grad_norm DOUBLE PRECISION, learning_rate DOUBLE PRECISION, raw TEXT NOT NULL, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS fine_tune_checkpoints ( id TEXT PRIMARY KEY, task_id TEXT NOT NULL REFERENCES fine_tune_tasks(id) ON DELETE CASCADE, step INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL, size_bytes BIGINT NOT NULL DEFAULT 0, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS compute_jobs ( id TEXT PRIMARY KEY, task_id TEXT REFERENCES fine_tune_tasks(id) ON DELETE SET NULL, node_id TEXT REFERENCES compute_nodes(id) ON DELETE SET NULL, engine TEXT NOT NULL, status TEXT NOT NULL, command TEXT NOT NULL, output_dir TEXT, log_file TEXT, payload TEXT NOT NULL, create_time TEXT NOT NULL, update_time TEXT NOT NULL, completed_at TEXT ); CREATE TABLE IF NOT EXISTS gpu_allocations ( id TEXT PRIMARY KEY, task_id TEXT REFERENCES fine_tune_tasks(id) ON DELETE CASCADE, compute_job_id TEXT, node_id TEXT REFERENCES compute_nodes(id) ON DELETE CASCADE, gpu_index INTEGER NOT NULL, status TEXT NOT NULL, create_time TEXT NOT NULL, released_at TEXT ); CREATE TABLE IF NOT EXISTS scheduler_locks ( lock_key TEXT PRIMARY KEY, owner TEXT NOT NULL, expires_at TEXT NOT NULL, create_time TEXT NOT NULL, update_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS resource_replicas ( id TEXT PRIMARY KEY, node_id TEXT NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE, resource_type TEXT NOT NULL, resource_id TEXT NOT NULL, local_path TEXT NOT NULL, status TEXT NOT NULL, sync_status TEXT NOT NULL, checksum_sha256 TEXT, byte_size BIGINT NOT NULL DEFAULT 0, last_checked_at TEXT, last_error TEXT, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS resource_sync_jobs ( id TEXT PRIMARY KEY, target_node_id TEXT NOT NULL, resources TEXT NOT NULL, status TEXT NOT NULL, progress INTEGER NOT NULL DEFAULT 0, create_time TEXT NOT NULL, completed_at TEXT ); CREATE TABLE IF NOT EXISTS eval_tasks ( id TEXT PRIMARY KEY, name TEXT NOT NULL, payload TEXT NOT NULL, status TEXT NOT NULL, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS eval_dimensions ( id TEXT PRIMARY KEY, name TEXT NOT NULL, payload TEXT NOT NULL, is_active INTEGER NOT NULL DEFAULT 1, is_default INTEGER NOT NULL DEFAULT 0, create_time TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS compare_tasks ( id TEXT PRIMARY KEY, name TEXT NOT NULL, payload TEXT NOT NULL, status TEXT NOT NULL, create_time TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_fine_tune_status ON fine_tune_tasks(status); CREATE INDEX IF NOT EXISTS idx_fine_tune_compute_job ON fine_tune_tasks(compute_job_id); CREATE INDEX IF NOT EXISTS idx_fine_tune_compute_node_status ON fine_tune_tasks(compute_node_id, status); CREATE INDEX IF NOT EXISTS idx_model_lineage_child ON model_lineage(child_resource_type, child_resource_id); CREATE INDEX IF NOT EXISTS idx_model_lineage_parent ON model_lineage(parent_resource_type, parent_resource_id); CREATE INDEX IF NOT EXISTS idx_model_artifacts_model ON model_artifacts(model_kind, model_id, artifact_type); CREATE INDEX IF NOT EXISTS idx_model_export_jobs_model ON model_export_jobs(trained_model_id, create_time DESC); CREATE INDEX IF NOT EXISTS idx_model_export_jobs_compute ON model_export_jobs(compute_job_id); CREATE INDEX IF NOT EXISTS idx_fine_tune_metrics_task_step ON fine_tune_metrics(task_id, step); CREATE UNIQUE INDEX IF NOT EXISTS uq_fine_tune_metrics_task_step_epoch ON fine_tune_metrics(task_id, step, epoch); CREATE INDEX IF NOT EXISTS idx_fine_tune_checkpoints_task_step ON fine_tune_checkpoints(task_id, step); CREATE UNIQUE INDEX IF NOT EXISTS uq_fine_tune_checkpoints_task_path ON fine_tune_checkpoints(task_id, path); CREATE INDEX IF NOT EXISTS idx_compute_jobs_task ON compute_jobs(task_id); CREATE INDEX IF NOT EXISTS idx_compute_jobs_node_status ON compute_jobs(node_id, status); CREATE INDEX IF NOT EXISTS idx_gpu_allocations_node_status ON gpu_allocations(node_id, status); CREATE UNIQUE INDEX IF NOT EXISTS uq_gpu_allocations_active ON gpu_allocations(node_id, gpu_index) WHERE status IN ('allocated','running'); CREATE INDEX IF NOT EXISTS idx_scheduler_locks_expires ON scheduler_locks(expires_at); CREATE INDEX IF NOT EXISTS idx_dataset_files_dataset ON dataset_files(dataset_id); CREATE INDEX IF NOT EXISTS idx_gpus_node ON gpus(node_id); CREATE UNIQUE INDEX IF NOT EXISTS uq_gpus_node_index ON gpus(node_id, gpu_index); CREATE INDEX IF NOT EXISTS idx_replicas_resource ON resource_replicas(resource_type, resource_id); CREATE UNIQUE INDEX IF NOT EXISTS uq_replicas_node_resource ON resource_replicas(node_id, resource_type, resource_id); CREATE INDEX IF NOT EXISTS idx_sync_jobs_node_status ON resource_sync_jobs(target_node_id, status); CREATE INDEX IF NOT EXISTS idx_eval_tasks_status ON eval_tasks(status); CREATE INDEX IF NOT EXISTS idx_eval_dimensions_active ON eval_dimensions(is_active); CREATE INDEX IF NOT EXISTS idx_compare_tasks_status ON compare_tasks(status); -- ===================== Project / Tenant ===================== CREATE TABLE IF NOT EXISTS projects ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL DEFAULT 'default', name TEXT NOT NULL, code TEXT NOT NULL, description TEXT, quota TEXT, status TEXT NOT NULL DEFAULT 'active', create_time TEXT NOT NULL, create_by TEXT, updated_at TEXT ); CREATE TABLE IF NOT EXISTS project_members ( project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE, user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, role TEXT NOT NULL DEFAULT 'member', create_time TEXT NOT NULL, PRIMARY KEY (project_id, user_id) ); CREATE TABLE IF NOT EXISTS roles ( id TEXT PRIMARY KEY, name TEXT NOT NULL, permissions TEXT NOT NULL DEFAULT '[]', create_time TEXT ); CREATE TABLE IF NOT EXISTS sessions ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, issued_at TEXT NOT NULL, expires_at TEXT NOT NULL, ip TEXT ); CREATE TABLE IF NOT EXISTS acls ( id TEXT PRIMARY KEY, resource_type TEXT NOT NULL, resource_id TEXT NOT NULL, principal_type TEXT NOT NULL, principal_id TEXT NOT NULL, permission TEXT NOT NULL, create_time TEXT );