|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS public.chat_conversations ( |
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), |
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, |
|
|
title TEXT NOT NULL DEFAULT 'New Conversation', |
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), |
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() |
|
|
); |
|
|
|
|
|
|
|
|
COMMENT ON TABLE public.chat_conversations IS 'Stores chat conversation metadata for users'; |
|
|
COMMENT ON COLUMN public.chat_conversations.id IS 'Unique conversation identifier'; |
|
|
COMMENT ON COLUMN public.chat_conversations.user_id IS 'References the user who owns this conversation (from auth.users)'; |
|
|
COMMENT ON COLUMN public.chat_conversations.title IS 'Conversation title, typically derived from first message'; |
|
|
COMMENT ON COLUMN public.chat_conversations.created_at IS 'Timestamp when conversation was created'; |
|
|
COMMENT ON COLUMN public.chat_conversations.updated_at IS 'Timestamp when conversation was last updated'; |
|
|
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_chat_conversations_user_id |
|
|
ON public.chat_conversations(user_id); |
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_chat_conversations_created_at |
|
|
ON public.chat_conversations(created_at DESC); |
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_chat_conversations_updated_at |
|
|
ON public.chat_conversations(updated_at DESC); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS public.chat_messages ( |
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), |
|
|
conversation_id UUID NOT NULL REFERENCES public.chat_conversations(id) ON DELETE CASCADE, |
|
|
role TEXT NOT NULL CHECK (role IN ('user', 'assistant')), |
|
|
content TEXT NOT NULL, |
|
|
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(), |
|
|
metadata JSONB DEFAULT NULL |
|
|
); |
|
|
|
|
|
|
|
|
COMMENT ON TABLE public.chat_messages IS 'Stores individual messages within chat conversations'; |
|
|
COMMENT ON COLUMN public.chat_messages.id IS 'Unique message identifier'; |
|
|
COMMENT ON COLUMN public.chat_messages.conversation_id IS 'References the conversation this message belongs to'; |
|
|
COMMENT ON COLUMN public.chat_messages.role IS 'Message sender: "user" or "assistant"'; |
|
|
COMMENT ON COLUMN public.chat_messages.content IS 'Message content (text)'; |
|
|
COMMENT ON COLUMN public.chat_messages.timestamp IS 'Timestamp when message was created'; |
|
|
COMMENT ON COLUMN public.chat_messages.metadata IS 'Optional JSON metadata (e.g., sources, tokens, model info)'; |
|
|
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_chat_messages_conversation_id |
|
|
ON public.chat_messages(conversation_id); |
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_chat_messages_timestamp |
|
|
ON public.chat_messages(timestamp ASC); |
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_chat_messages_role |
|
|
ON public.chat_messages(role); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION public.update_conversation_updated_at() |
|
|
RETURNS TRIGGER AS $$ |
|
|
BEGIN |
|
|
UPDATE public.chat_conversations |
|
|
SET updated_at = NOW() |
|
|
WHERE id = NEW.conversation_id; |
|
|
RETURN NEW; |
|
|
END; |
|
|
$$ LANGUAGE plpgsql; |
|
|
|
|
|
|
|
|
DROP TRIGGER IF EXISTS trigger_update_conversation_timestamp ON public.chat_messages; |
|
|
CREATE TRIGGER trigger_update_conversation_timestamp |
|
|
AFTER INSERT ON public.chat_messages |
|
|
FOR EACH ROW |
|
|
EXECUTE FUNCTION public.update_conversation_updated_at(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ALTER TABLE public.chat_conversations ENABLE ROW LEVEL SECURITY; |
|
|
ALTER TABLE public.chat_messages ENABLE ROW LEVEL SECURITY; |
|
|
|
|
|
|
|
|
DROP POLICY IF EXISTS "Users can view their own conversations" ON public.chat_conversations; |
|
|
DROP POLICY IF EXISTS "Users can insert their own conversations" ON public.chat_conversations; |
|
|
DROP POLICY IF EXISTS "Users can update their own conversations" ON public.chat_conversations; |
|
|
DROP POLICY IF EXISTS "Users can delete their own conversations" ON public.chat_conversations; |
|
|
|
|
|
DROP POLICY IF EXISTS "Users can view messages in their conversations" ON public.chat_messages; |
|
|
DROP POLICY IF EXISTS "Users can insert messages in their conversations" ON public.chat_messages; |
|
|
DROP POLICY IF EXISTS "Users can delete messages in their conversations" ON public.chat_messages; |
|
|
|
|
|
|
|
|
CREATE POLICY "Users can view their own conversations" |
|
|
ON public.chat_conversations |
|
|
FOR SELECT |
|
|
USING (auth.uid() = user_id); |
|
|
|
|
|
CREATE POLICY "Users can insert their own conversations" |
|
|
ON public.chat_conversations |
|
|
FOR INSERT |
|
|
WITH CHECK (auth.uid() = user_id); |
|
|
|
|
|
CREATE POLICY "Users can update their own conversations" |
|
|
ON public.chat_conversations |
|
|
FOR UPDATE |
|
|
USING (auth.uid() = user_id); |
|
|
|
|
|
CREATE POLICY "Users can delete their own conversations" |
|
|
ON public.chat_conversations |
|
|
FOR DELETE |
|
|
USING (auth.uid() = user_id); |
|
|
|
|
|
|
|
|
CREATE POLICY "Users can view messages in their conversations" |
|
|
ON public.chat_messages |
|
|
FOR SELECT |
|
|
USING ( |
|
|
EXISTS ( |
|
|
SELECT 1 FROM public.chat_conversations |
|
|
WHERE chat_conversations.id = chat_messages.conversation_id |
|
|
AND chat_conversations.user_id = auth.uid() |
|
|
) |
|
|
); |
|
|
|
|
|
CREATE POLICY "Users can insert messages in their conversations" |
|
|
ON public.chat_messages |
|
|
FOR INSERT |
|
|
WITH CHECK ( |
|
|
EXISTS ( |
|
|
SELECT 1 FROM public.chat_conversations |
|
|
WHERE chat_conversations.id = chat_messages.conversation_id |
|
|
AND chat_conversations.user_id = auth.uid() |
|
|
) |
|
|
); |
|
|
|
|
|
CREATE POLICY "Users can delete messages in their conversations" |
|
|
ON public.chat_messages |
|
|
FOR DELETE |
|
|
USING ( |
|
|
EXISTS ( |
|
|
SELECT 1 FROM public.chat_conversations |
|
|
WHERE chat_conversations.id = chat_messages.conversation_id |
|
|
AND chat_conversations.user_id = auth.uid() |
|
|
) |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRANT USAGE ON SCHEMA public TO authenticated; |
|
|
GRANT ALL ON public.chat_conversations TO authenticated; |
|
|
GRANT ALL ON public.chat_messages TO authenticated; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|