-- ClaudeDo SQLite schema (single source of truth, 3NF)
-- Applied by Worker on first startup. WAL mode is set via PRAGMA after open.

PRAGMA foreign_keys = ON;

CREATE TABLE IF NOT EXISTS lists (
    id                  TEXT PRIMARY KEY,
    name                TEXT NOT NULL,
    created_at          TIMESTAMP NOT NULL,
    working_dir         TEXT NULL,
    default_commit_type TEXT NOT NULL DEFAULT 'chore'
);

CREATE TABLE IF NOT EXISTS tasks (
    id            TEXT PRIMARY KEY,
    list_id       TEXT NOT NULL REFERENCES lists(id) ON DELETE CASCADE,
    title         TEXT NOT NULL,
    description   TEXT NULL,
    status        TEXT NOT NULL CHECK (status IN ('manual','queued','running','done','failed')),
    scheduled_for TIMESTAMP NULL,
    result        TEXT NULL,
    log_path      TEXT NULL,
    created_at    TIMESTAMP NOT NULL,
    started_at    TIMESTAMP NULL,
    finished_at   TIMESTAMP NULL,
    commit_type   TEXT NOT NULL DEFAULT 'chore'
);

CREATE INDEX IF NOT EXISTS idx_tasks_list_id ON tasks(list_id);
CREATE INDEX IF NOT EXISTS idx_tasks_status  ON tasks(status);

CREATE TABLE IF NOT EXISTS tags (
    id   INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL UNIQUE
);

CREATE TABLE IF NOT EXISTS list_tags (
    list_id TEXT    NOT NULL REFERENCES lists(id) ON DELETE CASCADE,
    tag_id  INTEGER NOT NULL REFERENCES tags(id)  ON DELETE CASCADE,
    PRIMARY KEY (list_id, tag_id)
);

CREATE TABLE IF NOT EXISTS task_tags (
    task_id TEXT    NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
    tag_id  INTEGER NOT NULL REFERENCES tags(id)  ON DELETE CASCADE,
    PRIMARY KEY (task_id, tag_id)
);

CREATE TABLE IF NOT EXISTS worktrees (
    task_id     TEXT PRIMARY KEY REFERENCES tasks(id) ON DELETE CASCADE,
    path        TEXT NOT NULL,
    branch_name TEXT NOT NULL,
    base_commit TEXT NOT NULL,
    head_commit TEXT NULL,
    diff_stat   TEXT NULL,
    state       TEXT NOT NULL DEFAULT 'active' CHECK (state IN ('active','merged','discarded','kept')),
    created_at  TIMESTAMP NOT NULL
);

-- Seed: minimal tag set (ignored if already present)
INSERT OR IGNORE INTO tags (name) VALUES ('agent');
INSERT OR IGNORE INTO tags (name) VALUES ('manual');
