Changeset 0.6.0 (#36)
This commit is contained in:
114
server/database/migrations/006_channels_unify.sql
Normal file
114
server/database/migrations/006_channels_unify.sql
Normal file
@@ -0,0 +1,114 @@
|
||||
-- ==========================================
|
||||
-- Migration 006: Unify Chats → Channels
|
||||
-- ==========================================
|
||||
-- "Everything is a channel." Merges the separate chats/channels
|
||||
-- schema into a single unified channel model.
|
||||
--
|
||||
-- The old channels/channel_members/channel_messages tables (from 001)
|
||||
-- were never populated — safe to drop and rebuild on top of chats.
|
||||
-- ==========================================
|
||||
|
||||
-- ── 1. Drop unused legacy channel tables ────
|
||||
-- These were placeholders from 001; no data, no handlers.
|
||||
-- Order matters: drop dependents first.
|
||||
|
||||
-- Remove FK references in tool_usage_log before dropping
|
||||
ALTER TABLE tool_usage_log DROP CONSTRAINT IF EXISTS tool_usage_log_channel_id_fkey;
|
||||
ALTER TABLE tool_usage_log DROP COLUMN IF EXISTS channel_id;
|
||||
|
||||
DROP TABLE IF EXISTS channel_messages CASCADE;
|
||||
DROP TABLE IF EXISTS channel_members CASCADE;
|
||||
DROP TABLE IF EXISTS channels CASCADE;
|
||||
|
||||
-- Drop the old trigger (will re-create after rename)
|
||||
DROP TRIGGER IF EXISTS channels_updated_at ON channels;
|
||||
|
||||
-- ── 2. Rename chats → channels ──────────────
|
||||
|
||||
ALTER TABLE chats RENAME TO channels;
|
||||
ALTER TABLE chat_messages RENAME TO messages;
|
||||
|
||||
-- Rename columns to match new schema
|
||||
ALTER TABLE messages RENAME COLUMN chat_id TO channel_id;
|
||||
|
||||
-- Rename indexes
|
||||
ALTER INDEX IF EXISTS idx_chats_user RENAME TO idx_channels_user;
|
||||
ALTER INDEX IF EXISTS idx_chats_updated RENAME TO idx_channels_updated;
|
||||
ALTER INDEX IF EXISTS idx_chats_tags RENAME TO idx_channels_tags;
|
||||
ALTER INDEX IF EXISTS idx_chat_messages_chat RENAME TO idx_messages_channel;
|
||||
|
||||
-- Rename constraints (PK and FK auto-renamed with table on some PG versions,
|
||||
-- but let's be explicit for the FK)
|
||||
-- Note: PG auto-renames PKs but not FKs or check constraints
|
||||
|
||||
-- Rename the updated_at trigger
|
||||
DROP TRIGGER IF EXISTS chats_updated_at ON channels;
|
||||
CREATE TRIGGER channels_updated_at BEFORE UPDATE ON channels
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
||||
|
||||
-- ── 3. Add channel type + description ───────
|
||||
|
||||
ALTER TABLE channels ADD COLUMN IF NOT EXISTS type VARCHAR(20) DEFAULT 'direct';
|
||||
ALTER TABLE channels ADD COLUMN IF NOT EXISTS description TEXT;
|
||||
|
||||
COMMENT ON COLUMN channels.type IS 'direct=1:1 AI chat, group=multi-model, channel=named persistent';
|
||||
|
||||
-- Backfill: all existing rows are 1:1 AI chats
|
||||
UPDATE channels SET type = 'direct' WHERE type IS NULL;
|
||||
|
||||
-- Index on type for filtered queries
|
||||
CREATE INDEX IF NOT EXISTS idx_channels_type ON channels(type);
|
||||
|
||||
-- ── 4. Add message tree (parent_id) ─────────
|
||||
|
||||
ALTER TABLE messages ADD COLUMN IF NOT EXISTS parent_id UUID REFERENCES messages(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_parent ON messages(parent_id);
|
||||
|
||||
-- Backfill linear parent chains on existing messages.
|
||||
-- Each message's parent is the previous message in the same channel (by created_at).
|
||||
WITH ordered AS (
|
||||
SELECT id, channel_id, created_at,
|
||||
LAG(id) OVER (PARTITION BY channel_id ORDER BY created_at) AS prev_id
|
||||
FROM messages
|
||||
)
|
||||
UPDATE messages m
|
||||
SET parent_id = o.prev_id
|
||||
FROM ordered o
|
||||
WHERE m.id = o.id AND o.prev_id IS NOT NULL AND m.parent_id IS NULL;
|
||||
|
||||
-- ── 5. Add participant columns on messages ──
|
||||
-- Decouples messages from user-only: AI models are participants too.
|
||||
|
||||
ALTER TABLE messages ADD COLUMN IF NOT EXISTS participant_type VARCHAR(10) DEFAULT 'user';
|
||||
ALTER TABLE messages ADD COLUMN IF NOT EXISTS participant_id VARCHAR(255);
|
||||
|
||||
COMMENT ON COLUMN messages.participant_type IS 'user or model';
|
||||
COMMENT ON COLUMN messages.participant_id IS 'user UUID or model identifier string';
|
||||
|
||||
-- Backfill: user messages get the channel owner's user_id;
|
||||
-- assistant messages get the model name as participant_id.
|
||||
UPDATE messages m
|
||||
SET participant_type = CASE WHEN m.role = 'assistant' THEN 'model' ELSE 'user' END,
|
||||
participant_id = CASE
|
||||
WHEN m.role = 'assistant' THEN COALESCE(m.model, 'unknown')
|
||||
ELSE (SELECT c.user_id::text FROM channels c WHERE c.id = m.channel_id)
|
||||
END
|
||||
WHERE m.participant_id IS NULL;
|
||||
|
||||
-- ── 6. Update model_routing_log FK ──────────
|
||||
|
||||
-- The FK column was named chat_id — rename it
|
||||
ALTER TABLE model_routing_log RENAME COLUMN chat_id TO channel_id;
|
||||
ALTER INDEX IF EXISTS idx_routing_log_chat RENAME TO idx_routing_log_channel;
|
||||
|
||||
-- message_id FK still valid (messages table was renamed, FK follows)
|
||||
|
||||
-- ── 7. Update tool_usage_log ────────────────
|
||||
-- We already dropped the old channel_id column above.
|
||||
-- Re-add it pointing to the unified channels table.
|
||||
-- Also rename the old chat_id column.
|
||||
|
||||
ALTER TABLE tool_usage_log RENAME COLUMN chat_id TO channel_id;
|
||||
-- The FK auto-follows the table rename, but let's be safe:
|
||||
-- (chat_id FK pointed to chats(id), which is now channels(id) — PG handles this)
|
||||
Reference in New Issue
Block a user