import { drizzle } from 'drizzle-orm/better-sqlite3'; import Database from 'better-sqlite3'; let testDb: ReturnType | null = null; let sqlite: Database.Database | null = null; const schemaSQL = ` CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, clerk_id TEXT NOT NULL UNIQUE, email TEXT NOT NULL UNIQUE, name TEXT, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, owner_id INTEGER NOT NULL REFERENCES users(id), is_public INTEGER NOT NULL DEFAULT 0, theme TEXT, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS characters ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL REFERENCES projects(id), name TEXT NOT NULL, slug TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'supporting', bio TEXT, description TEXT, arc TEXT, arc_type TEXT, age INTEGER, gender TEXT, voice TEXT, traits TEXT, motivation TEXT, conflict TEXT, secret TEXT, image_url TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS character_relationships ( id INTEGER PRIMARY KEY AUTOINCREMENT, character_a_id INTEGER NOT NULL REFERENCES characters(id), character_b_id INTEGER NOT NULL REFERENCES characters(id), relationship_type TEXT NOT NULL, description TEXT, strength INTEGER NOT NULL DEFAULT 50, is_antagonistic INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS scenes ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL REFERENCES projects(id), title TEXT NOT NULL, content TEXT NOT NULL DEFAULT '', "order" INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS scene_characters ( id INTEGER PRIMARY KEY AUTOINCREMENT, scene_id INTEGER NOT NULL REFERENCES scenes(id), character_id INTEGER NOT NULL REFERENCES characters(id), screen_time INTEGER, dialogue_lines INTEGER DEFAULT 0 ); CREATE TABLE IF NOT EXISTS project_members ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL REFERENCES projects(id), user_id INTEGER NOT NULL REFERENCES users(id), role TEXT NOT NULL DEFAULT 'editor', added_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS scripts ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL REFERENCES projects(id), title TEXT NOT NULL, version TEXT NOT NULL DEFAULT '1.0', content TEXT, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS revisions ( id INTEGER PRIMARY KEY AUTOINCREMENT, script_id INTEGER NOT NULL REFERENCES scripts(id), version_number INTEGER NOT NULL, branch_name TEXT NOT NULL DEFAULT 'main', parent_revision_id INTEGER, title TEXT NOT NULL, summary TEXT, content TEXT NOT NULL, author_id INTEGER NOT NULL REFERENCES users(id), status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft', 'pending_review', 'accepted', 'rejected')), reviewed_by_id INTEGER REFERENCES users(id), reviewed_at TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS revision_changes ( id INTEGER PRIMARY KEY AUTOINCREMENT, revision_id INTEGER NOT NULL REFERENCES revisions(id), change_type TEXT NOT NULL CHECK(change_type IN ('addition', 'deletion', 'modification')), element_type TEXT, old_content TEXT, new_content TEXT, scene_number INTEGER, line_number INTEGER, page_number INTEGER, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS teams ( id TEXT PRIMARY KEY, name TEXT NOT NULL, owner_id INTEGER NOT NULL REFERENCES users(id), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS team_members ( id INTEGER PRIMARY KEY AUTOINCREMENT, team_id TEXT NOT NULL REFERENCES teams(id), user_id INTEGER NOT NULL REFERENCES users(id), role TEXT NOT NULL DEFAULT 'editor', joined_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); `; export let globalSqlite: Database.Database | null = null; export async function getTestDb(): Promise> { if (testDb && sqlite) return testDb; sqlite = new Database(':memory:'); globalSqlite = sqlite; sqlite.exec('PRAGMA foreign_keys = OFF;'); sqlite.exec(schemaSQL); sqlite.exec('PRAGMA foreign_keys = ON;'); // Insert a test user sqlite.exec("INSERT INTO users (id, clerk_id, email, name) VALUES (1, 'user_test', 'test@test.com', 'Test User');"); // Insert a test project sqlite.exec("INSERT INTO projects (id, name, description, owner_id) VALUES (1, 'Test Project', 'A test project', 1);"); // Insert a test script sqlite.exec("INSERT INTO scripts (id, project_id, title, version) VALUES (1, 1, 'Test Script', '1.0');"); testDb = drizzle(sqlite); return testDb; } export async function resetTestDb(): Promise> { testDb = null; sqlite = null; globalSqlite = null; return getTestDb(); }