Creates core tables for task-mcp: - projects, task_sequences, epic_sequences - tasks with vector(1024) embedding for semantic search - epics, versions, task_checklist, task_links - HNSW index for fast vector similarity search Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
120 lines
4.6 KiB
SQL
120 lines
4.6 KiB
SQL
-- 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;
|