botserver/migrations/6.1.8-01-research/up.sql

137 lines
5.4 KiB
SQL

-- Research / Knowledge Base / LLM Tables
-- Knowledge Base Documents
CREATE TABLE IF NOT EXISTS kb_documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
collection_name TEXT NOT NULL,
file_path TEXT NOT NULL,
file_size BIGINT NOT NULL DEFAULT 0,
file_hash TEXT NOT NULL,
first_published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
indexed_at TIMESTAMPTZ,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, collection_name, file_path)
);
CREATE INDEX IF NOT EXISTS idx_kb_documents_bot_id ON kb_documents(bot_id);
CREATE INDEX IF NOT EXISTS idx_kb_documents_collection ON kb_documents(collection_name);
CREATE INDEX IF NOT EXISTS idx_kb_documents_hash ON kb_documents(file_hash);
CREATE INDEX IF NOT EXISTS idx_kb_documents_indexed_at ON kb_documents(indexed_at);
-- Knowledge Base Collections
CREATE TABLE IF NOT EXISTS kb_collections (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
name TEXT NOT NULL,
folder_path TEXT NOT NULL,
qdrant_collection TEXT NOT NULL,
document_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, name)
);
CREATE INDEX IF NOT EXISTS idx_kb_collections_bot_id ON kb_collections(bot_id);
CREATE INDEX IF NOT EXISTS idx_kb_collections_name ON kb_collections(name);
-- User KB Associations
CREATE TABLE IF NOT EXISTS user_kb_associations (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
bot_id TEXT NOT NULL,
kb_name TEXT NOT NULL,
is_website INTEGER NOT NULL DEFAULT 0,
website_url TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
UNIQUE(user_id, bot_id, kb_name)
);
CREATE INDEX IF NOT EXISTS idx_user_kb_user_id ON user_kb_associations(user_id);
CREATE INDEX IF NOT EXISTS idx_user_kb_bot_id ON user_kb_associations(bot_id);
CREATE INDEX IF NOT EXISTS idx_user_kb_name ON user_kb_associations(kb_name);
CREATE INDEX IF NOT EXISTS idx_user_kb_website ON user_kb_associations(is_website);
-- Session KB Associations
CREATE TABLE IF NOT EXISTS session_kb_associations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES user_sessions(id) ON DELETE CASCADE,
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
kb_name TEXT NOT NULL,
kb_folder_path TEXT NOT NULL,
qdrant_collection TEXT NOT NULL,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
added_by_tool TEXT,
is_active BOOLEAN NOT NULL DEFAULT true,
UNIQUE(session_id, kb_name)
);
CREATE INDEX IF NOT EXISTS idx_session_kb_session_id ON session_kb_associations(session_id);
CREATE INDEX IF NOT EXISTS idx_session_kb_bot_id ON session_kb_associations(bot_id);
CREATE INDEX IF NOT EXISTS idx_session_kb_name ON session_kb_associations(kb_name);
CREATE INDEX IF NOT EXISTS idx_session_kb_active ON session_kb_associations(is_active) WHERE is_active = true;
-- Research Search History
CREATE TABLE IF NOT EXISTS research_search_history (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
query TEXT NOT NULL,
collection_id TEXT,
results_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_research_history_user ON research_search_history(user_id);
CREATE INDEX IF NOT EXISTS idx_research_history_created ON research_search_history(created_at DESC);
-- LLM Metrics & Budget (Moved from Core)
-- Note: Requires llm feature, but packed in research migration for simplicity or separated?
-- Plan says Research contains LLM tables.
-- Knowledge Graph Entities
CREATE TABLE IF NOT EXISTS kg_entities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
name TEXT NOT NULL,
entity_type VARCHAR(100) NOT NULL,
description TEXT,
properties JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(bot_id, name, entity_type)
);
CREATE INDEX IF NOT EXISTS idx_kg_entities_bot ON kg_entities(bot_id);
CREATE INDEX IF NOT EXISTS idx_kg_entities_type ON kg_entities(bot_id, entity_type);
CREATE TABLE IF NOT EXISTS kg_relationships (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
source_id UUID NOT NULL REFERENCES kg_entities(id) ON DELETE CASCADE,
target_id UUID NOT NULL REFERENCES kg_entities(id) ON DELETE CASCADE,
relation_type VARCHAR(100) NOT NULL,
properties JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(source_id, target_id, relation_type)
);
CREATE INDEX IF NOT EXISTS idx_kg_relationships_bot ON kg_relationships(bot_id);
-- Triggers
DROP TRIGGER IF EXISTS update_kb_documents_updated_at ON kb_documents;
CREATE TRIGGER update_kb_documents_updated_at
BEFORE UPDATE ON kb_documents
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_kb_collections_updated_at ON kb_collections;
CREATE TRIGGER update_kb_collections_updated_at
BEFORE UPDATE ON kb_collections
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_kg_entities_updated_at ON kg_entities;
CREATE TRIGGER update_kg_entities_updated_at
BEFORE UPDATE ON kg_entities
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();