From 29cd754e39783ed5d2da698577ef41ad4c2ce64f Mon Sep 17 00:00:00 2001 From: Christian Gick Date: Fri, 9 Jan 2026 17:21:40 +0200 Subject: [PATCH] fix: Add missing 001 base schema migration 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 --- migrations/001_base_schema.sql | 119 +++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 migrations/001_base_schema.sql diff --git a/migrations/001_base_schema.sql b/migrations/001_base_schema.sql new file mode 100644 index 0000000..dc16aee --- /dev/null +++ b/migrations/001_base_schema.sql @@ -0,0 +1,119 @@ +-- 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;