-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchat-schema.sql
More file actions
198 lines (177 loc) · 6.77 KB
/
chat-schema.sql
File metadata and controls
198 lines (177 loc) · 6.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
-- Career Counseling Chat Application Database Schema
-- Run these queries in your Supabase SQL Editor
-- 1. Create chat_sessions table
CREATE TABLE public.chat_sessions (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES public.users(id) ON DELETE CASCADE NOT NULL,
title TEXT NOT NULL DEFAULT 'New Chat',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 2. Create chat_messages table
CREATE TABLE public.chat_messages (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
session_id UUID REFERENCES public.chat_sessions(id) ON DELETE CASCADE NOT NULL,
role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
content TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 3. Enable Row Level Security (RLS)
ALTER TABLE public.chat_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.chat_messages ENABLE ROW LEVEL SECURITY;
-- 4. Create RLS policies for chat_sessions
-- Users can view their own chat sessions
CREATE POLICY "Users can view own chat sessions" ON public.chat_sessions
FOR SELECT USING (auth.uid() = user_id);
-- Users can create their own chat sessions
CREATE POLICY "Users can create own chat sessions" ON public.chat_sessions
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- Users can update their own chat sessions
CREATE POLICY "Users can update own chat sessions" ON public.chat_sessions
FOR UPDATE USING (auth.uid() = user_id);
-- Users can delete their own chat sessions
CREATE POLICY "Users can delete own chat sessions" ON public.chat_sessions
FOR DELETE USING (auth.uid() = user_id);
-- 5. Create RLS policies for chat_messages
-- Users can view messages from their own chat sessions
CREATE POLICY "Users can view own chat messages" ON public.chat_messages
FOR SELECT USING (
EXISTS (
SELECT 1 FROM public.chat_sessions
WHERE chat_sessions.id = chat_messages.session_id
AND chat_sessions.user_id = auth.uid()
)
);
-- Users can create messages in their own chat sessions
CREATE POLICY "Users can create messages in own sessions" ON public.chat_messages
FOR INSERT WITH CHECK (
EXISTS (
SELECT 1 FROM public.chat_sessions
WHERE chat_sessions.id = chat_messages.session_id
AND chat_sessions.user_id = auth.uid()
)
);
-- Users can update messages in their own chat sessions
CREATE POLICY "Users can update own chat messages" ON public.chat_messages
FOR UPDATE USING (
EXISTS (
SELECT 1 FROM public.chat_sessions
WHERE chat_sessions.id = chat_messages.session_id
AND chat_sessions.user_id = auth.uid()
)
);
-- Users can delete messages from their own chat sessions
CREATE POLICY "Users can delete own chat messages" ON public.chat_messages
FOR DELETE USING (
EXISTS (
SELECT 1 FROM public.chat_sessions
WHERE chat_sessions.id = chat_messages.session_id
AND chat_sessions.user_id = auth.uid()
)
);
-- 6. Create triggers for updated_at timestamps
CREATE TRIGGER update_chat_sessions_updated_at
BEFORE UPDATE ON public.chat_sessions
FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();
-- 7. Create indexes for better performance
-- Index on chat_sessions for user queries
CREATE INDEX idx_chat_sessions_user_id ON public.chat_sessions(user_id);
CREATE INDEX idx_chat_sessions_created_at ON public.chat_sessions(created_at DESC);
CREATE INDEX idx_chat_sessions_updated_at ON public.chat_sessions(updated_at DESC);
-- Index on chat_messages for session queries
CREATE INDEX idx_chat_messages_session_id ON public.chat_messages(session_id);
CREATE INDEX idx_chat_messages_created_at ON public.chat_messages(created_at ASC);
CREATE INDEX idx_chat_messages_role ON public.chat_messages(role);
-- 8. Grant necessary permissions
GRANT USAGE ON SCHEMA public TO anon, authenticated;
GRANT ALL ON public.chat_sessions TO anon, authenticated;
GRANT ALL ON public.chat_messages TO anon, authenticated;
-- 9. Create function to get chat session with message count
CREATE OR REPLACE FUNCTION public.get_chat_sessions_with_message_count(user_uuid UUID)
RETURNS TABLE (
id UUID,
user_id UUID,
title TEXT,
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
message_count BIGINT,
last_message_at TIMESTAMP WITH TIME ZONE
) AS $$
BEGIN
RETURN QUERY
SELECT
cs.id,
cs.user_id,
cs.title,
cs.created_at,
cs.updated_at,
COUNT(cm.id) as message_count,
MAX(cm.created_at) as last_message_at
FROM public.chat_sessions cs
LEFT JOIN public.chat_messages cm ON cs.id = cm.session_id
WHERE cs.user_id = user_uuid
GROUP BY cs.id, cs.user_id, cs.title, cs.created_at, cs.updated_at
ORDER BY cs.updated_at DESC;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 10. Create function to get messages for a session with pagination
CREATE OR REPLACE FUNCTION public.get_chat_messages_paginated(
session_uuid UUID,
limit_count INTEGER DEFAULT 50,
offset_count INTEGER DEFAULT 0
)
RETURNS TABLE (
id UUID,
session_id UUID,
role TEXT,
content TEXT,
created_at TIMESTAMP WITH TIME ZONE
) AS $$
BEGIN
RETURN QUERY
SELECT
cm.id,
cm.session_id,
cm.role,
cm.content,
cm.created_at
FROM public.chat_messages cm
WHERE cm.session_id = session_uuid
ORDER BY cm.created_at ASC
LIMIT limit_count
OFFSET offset_count;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 11. Create function to update chat session title based on first user message
CREATE OR REPLACE FUNCTION public.update_chat_session_title()
RETURNS TRIGGER AS $$
BEGIN
-- Only update title if it's the first user message in the session
IF NEW.role = 'user' AND NOT EXISTS (
SELECT 1 FROM public.chat_messages
WHERE session_id = NEW.session_id
AND role = 'user'
AND id != NEW.id
) THEN
-- Extract first few words from the message as title
UPDATE public.chat_sessions
SET title = CASE
WHEN LENGTH(NEW.content) > 50 THEN
LEFT(NEW.content, 47) || '...'
ELSE
NEW.content
END,
updated_at = NOW()
WHERE id = NEW.session_id;
END IF;
-- Always update the session's updated_at timestamp
UPDATE public.chat_sessions
SET updated_at = NOW()
WHERE id = NEW.session_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 12. Create trigger to automatically update session title and timestamp
CREATE TRIGGER update_session_on_new_message
AFTER INSERT ON public.chat_messages
FOR EACH ROW EXECUTE FUNCTION public.update_chat_session_title();