-- Migration: Create messages table -- Description: Chat messages in rooms CREATE TABLE IF NOT EXISTS messages ( id BIGSERIAL PRIMARY KEY, room_id BIGINT NOT NULL, user_id BIGINT NOT NULL, content TEXT NOT NULL, message_type VARCHAR(50) NOT NULL DEFAULT 'text', -- 'text', 'image', 'audio', 'file', 'system' parent_id BIGINT, -- For threaded replies is_edited BOOLEAN DEFAULT false, is_deleted BOOLEAN DEFAULT false, metadata JSONB, -- For additional data (file info, mentions, etc.) created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP WITH TIME ZONE, CONSTRAINT fk_messages_room_id FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE, CONSTRAINT fk_messages_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, CONSTRAINT fk_messages_parent_id FOREIGN KEY (parent_id) REFERENCES messages(id) ON DELETE SET NULL ); -- Indexes CREATE INDEX IF NOT EXISTS idx_messages_room_id_created_at ON messages(room_id, created_at DESC); CREATE INDEX IF NOT EXISTS idx_messages_user_id ON messages(user_id); CREATE INDEX IF NOT EXISTS idx_messages_parent_id ON messages(parent_id) WHERE parent_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_messages_message_type ON messages(message_type); CREATE INDEX IF NOT EXISTS idx_messages_deleted_at ON messages(deleted_at); CREATE INDEX IF NOT EXISTS idx_messages_is_deleted ON messages(is_deleted) WHERE is_deleted = false; -- Full-text search index for message content CREATE INDEX IF NOT EXISTS idx_messages_content_search ON messages USING gin(to_tsvector('english', content)); -- Comments COMMENT ON TABLE messages IS 'Chat messages in rooms with support for threading and different types'; COMMENT ON COLUMN messages.message_type IS 'Type of message: text, image, audio, file, or system'; COMMENT ON COLUMN messages.parent_id IS 'Parent message ID for threaded replies'; COMMENT ON COLUMN messages.metadata IS 'JSON metadata for file info, mentions, reactions, etc.';