Files
microdao-daarion/services/memory-service/migrations/001_create_memory_tables.sql
2025-11-15 10:12:37 -08:00

133 lines
5.6 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- Міграція для Memory Service
-- Створює таблиці: user_facts, dialog_summaries, agent_memory_events, agent_memory_facts_vector
-- Розширення для UUID та vector
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "vector";
-- ========== User Facts ==========
CREATE TABLE IF NOT EXISTS user_facts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
team_id TEXT REFERENCES teams(id) ON DELETE CASCADE,
-- Ключ факту (наприклад: "language", "is_donor", "is_validator", "top_contributor")
fact_key TEXT NOT NULL,
-- Значення факту
fact_value TEXT,
fact_value_json JSONB,
-- Метадані
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
-- Токен-гейт
token_gated BOOLEAN NOT NULL DEFAULT false,
token_requirements JSONB,
-- Таймстемпи
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_user_facts_user_id ON user_facts(user_id);
CREATE INDEX IF NOT EXISTS idx_user_facts_team_id ON user_facts(team_id);
CREATE INDEX IF NOT EXISTS idx_user_facts_user_key ON user_facts(user_id, fact_key);
CREATE INDEX IF NOT EXISTS idx_user_facts_token_gated ON user_facts(token_gated);
CREATE INDEX IF NOT EXISTS idx_user_facts_expires_at ON user_facts(expires_at) WHERE expires_at IS NOT NULL;
-- ========== Dialog Summaries ==========
CREATE TABLE IF NOT EXISTS dialog_summaries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Контекст діалогу
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
channel_id TEXT REFERENCES channels(id) ON DELETE CASCADE,
agent_id TEXT REFERENCES agents(id) ON DELETE CASCADE,
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
-- Період
period_start TIMESTAMPTZ NOT NULL,
period_end TIMESTAMPTZ NOT NULL,
-- Підсумок
summary_text TEXT NOT NULL,
summary_json JSONB,
-- Статистика
message_count INTEGER NOT NULL DEFAULT 0,
participant_count INTEGER NOT NULL DEFAULT 0,
-- Ключові теми
topics JSONB,
-- Метадані
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_team_id ON dialog_summaries(team_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_channel_id ON dialog_summaries(channel_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_agent_id ON dialog_summaries(agent_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_user_id ON dialog_summaries(user_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_team_period ON dialog_summaries(team_id, period_start, period_end);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_created_at ON dialog_summaries(created_at);
-- ========== Agent Memory Events ==========
CREATE TABLE IF NOT EXISTS agent_memory_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
channel_id TEXT REFERENCES channels(id) ON DELETE CASCADE,
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
-- Scope: short_term, mid_term, long_term
scope TEXT NOT NULL CHECK (scope IN ('short_term', 'mid_term', 'long_term')),
-- Kind: message, fact, summary, note
kind TEXT NOT NULL CHECK (kind IN ('message', 'fact', 'summary', 'note')),
-- Тіло події
body_text TEXT,
body_json JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_agent_id ON agent_memory_events(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_team_id ON agent_memory_events(team_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_channel_id ON agent_memory_events(channel_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_user_id ON agent_memory_events(user_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_agent_team_scope ON agent_memory_events(agent_id, team_id, scope);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_channel ON agent_memory_events(agent_id, channel_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_created_at ON agent_memory_events(created_at);
-- ========== Agent Memory Facts Vector (для RAG) ==========
CREATE TABLE IF NOT EXISTS agent_memory_facts_vector (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
fact_text TEXT NOT NULL,
embedding vector(1536), -- OpenAI ada-002 embedding size
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_agent_id ON agent_memory_facts_vector(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_team_id ON agent_memory_facts_vector(team_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_agent_team ON agent_memory_facts_vector(agent_id, team_id);
-- Індекс для векторного пошуку (використовується pgvector)
-- Примітка: Створіть цей індекс після того, як у вас буде достатньо даних
-- CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_embedding
-- ON agent_memory_facts_vector USING ivfflat (embedding vector_cosine_ops)
-- WITH (lists = 100);