-- Migration 001: Base Schema for Task MCP
-- Creates core tables for task management with pgvector semantic search

-- Ensure pgvector extension is available
CREATE EXTENSION IF NOT EXISTS vector;

-- Schema migrations tracking
CREATE TABLE IF NOT EXISTS schema_migrations (
    version TEXT PRIMARY KEY,
    applied_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Projects table
CREATE TABLE IF NOT EXISTS projects (
    key TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    path TEXT,
    active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Task ID sequences per project
CREATE TABLE IF NOT EXISTS task_sequences (
    project TEXT PRIMARY KEY REFERENCES projects(key) ON DELETE CASCADE,
    next_id INTEGER DEFAULT 1
);

-- Epic sequences per project
CREATE TABLE IF NOT EXISTS epic_sequences (
    project TEXT PRIMARY KEY REFERENCES projects(key) ON DELETE CASCADE,
    next_id INTEGER DEFAULT 1
);

-- Versions table (for release tracking)
CREATE TABLE IF NOT EXISTS versions (
    id TEXT PRIMARY KEY,
    project TEXT NOT NULL REFERENCES projects(key) ON DELETE CASCADE,
    version TEXT NOT NULL,
    build_number INTEGER,
    status TEXT DEFAULT 'planned' CHECK (status IN ('planned', 'in_progress', 'released', 'archived')),
    release_date DATE,
    release_notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_versions_project ON versions(project);
CREATE INDEX IF NOT EXISTS idx_versions_status ON versions(status);

-- Epics table (session-scoped work bundles)
CREATE TABLE IF NOT EXISTS epics (
    id TEXT PRIMARY KEY,
    project TEXT NOT NULL REFERENCES projects(key) ON DELETE CASCADE,
    title TEXT NOT NULL,
    description TEXT,
    status TEXT DEFAULT 'open' CHECK (status IN ('open', 'in_progress', 'completed')),
    target_version_id TEXT REFERENCES versions(id) ON DELETE SET NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_epics_project ON epics(project);
CREATE INDEX IF NOT EXISTS idx_epics_status ON epics(status);

-- Tasks table with embedding for semantic search
CREATE TABLE IF NOT EXISTS tasks (
    id TEXT PRIMARY KEY,
    project TEXT NOT NULL REFERENCES projects(key) ON DELETE CASCADE,
    title TEXT NOT NULL,
    description TEXT,
    type TEXT DEFAULT 'task' CHECK (type IN ('task', 'bug', 'feature', 'debt')),
    status TEXT DEFAULT 'open' CHECK (status IN ('open', 'in_progress', 'testing', 'blocked', 'completed')),
    priority TEXT DEFAULT 'P2' CHECK (priority IN ('P0', 'P1', 'P2', 'P3')),
    version_id TEXT REFERENCES versions(id) ON DELETE SET NULL,
    epic_id TEXT REFERENCES epics(id) ON DELETE SET NULL,
    embedding vector(1024),  -- LiteLLM proxy embedding dimension
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    completed_at TIMESTAMP WITH TIME ZONE
);

CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project);
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
CREATE INDEX IF NOT EXISTS idx_tasks_type ON tasks(type);
CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);
CREATE INDEX IF NOT EXISTS idx_tasks_epic ON tasks(epic_id);
CREATE INDEX IF NOT EXISTS idx_tasks_version ON tasks(version_id);
CREATE INDEX IF NOT EXISTS idx_tasks_created ON tasks(created_at);

-- HNSW index for fast vector similarity search
CREATE INDEX IF NOT EXISTS idx_tasks_embedding ON tasks USING hnsw (embedding vector_cosine_ops);

-- Task checklist items
CREATE TABLE IF NOT EXISTS task_checklist (
    id SERIAL PRIMARY KEY,
    task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
    item TEXT NOT NULL,
    checked BOOLEAN DEFAULT false,
    position INTEGER DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_checklist_task ON task_checklist(task_id);

-- Task links (dependencies, relations, duplicates)
CREATE TABLE IF NOT EXISTS task_links (
    id SERIAL PRIMARY KEY,
    from_task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
    to_task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
    link_type TEXT NOT NULL CHECK (link_type IN ('blocks', 'relates_to', 'duplicates')),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(from_task_id, to_task_id, link_type)
);

CREATE INDEX IF NOT EXISTS idx_links_from ON task_links(from_task_id);
CREATE INDEX IF NOT EXISTS idx_links_to ON task_links(to_task_id);
CREATE INDEX IF NOT EXISTS idx_links_type ON task_links(link_type);

-- Record migration
INSERT INTO schema_migrations (version, applied_at) VALUES ('001_base_schema', NOW())
ON CONFLICT DO NOTHING;
