鉴影 ICE-GL-CA001 969ca660c0 EED-129 · LIB v2.0 · 管线全面升级
铁律合规:
- P0: 移除三处硬编码API密钥 → lib/secrets.py 三层查找
- P0: 统一LIB/engines调用关系(tts复用音色表,composer桥接editor)
- P0: batch支持参数+batch-resume断点续传
- P0: Seed一致性(seed_value/lock_seed字段+gen --lock-seed)
- P0: 跨集资产继承(inherit命令)+A/B对比(compare命令)
- P1: concat逻辑修复/滤镜崩溃修复/FFmpeg路径统一/成本追踪
- P2: 状态判断修复/CLI --help+--version+模糊匹配
- 新增: 65条命令(原17条)覆盖全链路
- 新增: deps/info/note/history/report/flow/director等
- 语法OK 零重复函数 零密钥泄露
2026-07-10 14:49:17 +08:00

114 lines
3.3 KiB
Python

# LIB · 蛋蛋短剧生产管线 · 数据库模型
# D180 · 2026-07-10
import sqlite3
import json
import os
from datetime import datetime, timezone
DB_PATH = os.path.join(os.path.dirname(__file__), "lib.db")
SCHEMA = """
CREATE TABLE IF NOT EXISTS projects (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS episodes (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL REFERENCES projects(id),
number INTEGER NOT NULL,
script_path TEXT,
status TEXT DEFAULT 'pending',
created_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS shots (
id TEXT PRIMARY KEY,
episode_id TEXT NOT NULL REFERENCES episodes(id),
shot_number TEXT NOT NULL,
description TEXT,
script_ref TEXT,
camera TEXT,
duration_sec REAL,
status TEXT DEFAULT 'pending',
prompt TEXT,
model TEXT DEFAULT 'doubao-seedance-2-0-260128',
resolution TEXT DEFAULT '720p',
output_path TEXT,
seedance_task_id TEXT,
seed_value INTEGER DEFAULT 0,
lock_seed INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
error_log TEXT
);
CREATE TABLE IF NOT EXISTS assets (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL REFERENCES projects(id),
type TEXT NOT NULL CHECK(type IN ('CHAR','ENV','PROP','MASTER')),
name TEXT NOT NULL,
file_path TEXT NOT NULL,
status TEXT DEFAULT 'pending',
approved_at TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS shot_assets (
shot_id TEXT NOT NULL REFERENCES shots(id),
asset_id TEXT NOT NULL REFERENCES assets(id),
role TEXT NOT NULL CHECK(role IN ('reference','character','scene','prop','master')),
PRIMARY KEY (shot_id, asset_id, role)
);
CREATE TABLE IF NOT EXISTS generation_tasks (
id TEXT PRIMARY KEY,
shot_id TEXT NOT NULL REFERENCES shots(id),
task_type TEXT NOT NULL CHECK(task_type IN ('image','video','master_frame')),
seedance_task_id TEXT,
status TEXT DEFAULT 'submitted',
prompt_used TEXT,
references_used TEXT,
error_message TEXT,
cost_estimated REAL DEFAULT 0,
cost_actual REAL DEFAULT 0,
started_at TEXT,
completed_at TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS experience_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category TEXT NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL,
tags TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
"""
def get_db():
db = sqlite3.connect(DB_PATH)
db.row_factory = sqlite3.Row
db.executescript(SCHEMA)
db.commit()
return db
def init():
db = get_db()
# Create default project and episode if not exist
db.execute("INSERT OR IGNORE INTO projects (id, name) VALUES (?, ?)",
("deep-sea-voyage", "深海迷航"))
db.execute("""INSERT OR IGNORE INTO episodes (id, project_id, number, script_path, status)
VALUES (?, ?, ?, ?, ?)""",
("DSV-EP01", "deep-sea-voyage", 1,
"projects/deep-sea-voyage/script/EP01-SCRIPT-LOCK.hdlp", "ready"))
db.commit()
print(f"LIB initialized: {DB_PATH}")
return db
if __name__ == "__main__":
init()