CREATE TABLE IF NOT EXISTS columns ( id TEXT PRIMARY KEY, name TEXT NOT NULL, position INTEGER NOT NULL DEFAULT 0, location TEXT NOT NULL DEFAULT 'board' CHECK(location IN ('board','sidebar')), width INTEGER NOT NULL DEFAULT 300, wip_limit INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS cards ( id TEXT PRIMARY KEY, requester TEXT NOT NULL DEFAULT '', title TEXT NOT NULL, description TEXT NOT NULL DEFAULT '', color TEXT NOT NULL DEFAULT '', column_id TEXT NOT NULL REFERENCES columns(id) ON DELETE CASCADE, position INTEGER NOT NULL DEFAULT 0, locked INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS card_column_history ( id TEXT PRIMARY KEY, card_id TEXT NOT NULL REFERENCES cards(id) ON DELETE CASCADE, column_id TEXT NOT NULL, entered_at TEXT NOT NULL, exited_at TEXT ); CREATE TABLE IF NOT EXISTS card_lock_history ( id TEXT PRIMARY KEY, card_id TEXT NOT NULL REFERENCES cards(id) ON DELETE CASCADE, locked_at TEXT NOT NULL, unlocked_at TEXT ); 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 DEFAULT '', created_at TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_cards_column ON cards(column_id); CREATE INDEX IF NOT EXISTS idx_cards_position ON cards(column_id, position); CREATE INDEX IF NOT EXISTS idx_history_card ON card_column_history(card_id); CREATE INDEX IF NOT EXISTS idx_columns_position ON columns(position); CREATE INDEX IF NOT EXISTS idx_lock_history_card ON card_lock_history(card_id);