-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase_setup.sql
More file actions
232 lines (208 loc) · 8.26 KB
/
database_setup.sql
File metadata and controls
232 lines (208 loc) · 8.26 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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
-- Enhanced Database Schema for Task Manager
-- Run these commands in your Supabase SQL Editor
-- 1. Enhance tasks table with new columns
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS description TEXT;
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS priority TEXT DEFAULT 'medium' CHECK (priority IN ('low', 'medium', 'high', 'urgent'));
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS category TEXT DEFAULT 'personal';
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS due_date TIMESTAMPTZ;
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS completed_at TIMESTAMPTZ;
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
-- 2. Create categories table
CREATE TABLE IF NOT EXISTS categories (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
color TEXT DEFAULT '#6b7280',
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(name, user_id)
);
-- 3. Create task_attachments table for future file uploads
CREATE TABLE IF NOT EXISTS task_attachments (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT REFERENCES tasks(id) ON DELETE CASCADE,
file_name TEXT NOT NULL,
file_url TEXT NOT NULL,
file_size INTEGER,
file_type TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 4. Add indexes for better performance
CREATE INDEX IF NOT EXISTS idx_tasks_user_id ON tasks(user_id);
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
CREATE INDEX IF NOT EXISTS idx_tasks_due_date ON tasks(due_date);
CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);
CREATE INDEX IF NOT EXISTS idx_tasks_category ON tasks(category);
CREATE INDEX IF NOT EXISTS idx_categories_user_id ON categories(user_id);
CREATE INDEX IF NOT EXISTS idx_task_attachments_task_id ON task_attachments(task_id);
-- 5. Enable Row Level Security (RLS) on all tables
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;
ALTER TABLE categories ENABLE ROW LEVEL SECURITY;
ALTER TABLE task_attachments ENABLE ROW LEVEL SECURITY;
-- 6. Create RLS policies for tasks table
DROP POLICY IF EXISTS "Users can view own tasks" ON tasks;
DROP POLICY IF EXISTS "Users can insert own tasks" ON tasks;
DROP POLICY IF EXISTS "Users can update own tasks" ON tasks;
DROP POLICY IF EXISTS "Users can delete own tasks" ON tasks;
CREATE POLICY "Users can view own tasks" ON tasks
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own tasks" ON tasks
FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own tasks" ON tasks
FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete own tasks" ON tasks
FOR DELETE USING (auth.uid() = user_id);
-- 7. Create RLS policies for categories table
DROP POLICY IF EXISTS "Users can manage own categories" ON categories;
CREATE POLICY "Users can manage own categories" ON categories
FOR ALL USING (auth.uid() = user_id);
-- 8. Create RLS policies for task_attachments table
DROP POLICY IF EXISTS "Users can manage attachments for own tasks" ON task_attachments;
CREATE POLICY "Users can manage attachments for own tasks" ON task_attachments
FOR ALL USING (
EXISTS (
SELECT 1 FROM tasks
WHERE tasks.id = task_attachments.task_id
AND tasks.user_id = auth.uid()
)
);
-- 9. Create function to get task statistics
CREATE OR REPLACE FUNCTION get_task_stats(user_uuid UUID)
RETURNS JSON AS $$
DECLARE
result JSON;
BEGIN
SELECT json_build_object(
'total_tasks', COUNT(*),
'completed_tasks', COUNT(*) FILTER (WHERE status = 'done'),
'ongoing_tasks', COUNT(*) FILTER (WHERE status = 'ongoing'),
'todo_tasks', COUNT(*) FILTER (WHERE status = 'todo'),
'overdue_tasks', COUNT(*) FILTER (WHERE due_date < NOW() AND status != 'done'),
'tasks_by_priority', json_build_object(
'urgent', COUNT(*) FILTER (WHERE priority = 'urgent'),
'high', COUNT(*) FILTER (WHERE priority = 'high'),
'medium', COUNT(*) FILTER (WHERE priority = 'medium'),
'low', COUNT(*) FILTER (WHERE priority = 'low')
),
'tasks_by_category', (
SELECT json_object_agg(category, task_count)
FROM (
SELECT category, COUNT(*) as task_count
FROM tasks
WHERE user_id = user_uuid
GROUP BY category
) cat_counts
),
'completion_rate',
CASE
WHEN COUNT(*) > 0 THEN
ROUND((COUNT(*) FILTER (WHERE status = 'done')::NUMERIC / COUNT(*)) * 100, 2)
ELSE 0
END,
'productivity_this_week', (
SELECT COUNT(*)
FROM tasks
WHERE user_id = user_uuid
AND completed_at >= DATE_TRUNC('week', NOW())
AND status = 'done'
),
'upcoming_due_tasks', (
SELECT COUNT(*)
FROM tasks
WHERE user_id = user_uuid
AND due_date BETWEEN NOW() AND NOW() + INTERVAL '7 days'
AND status != 'done'
)
) INTO result
FROM tasks
WHERE user_id = user_uuid;
RETURN result;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 10. Create function to update task updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 11. Create trigger to automatically update updated_at column
DROP TRIGGER IF EXISTS update_tasks_updated_at ON tasks;
CREATE TRIGGER update_tasks_updated_at
BEFORE UPDATE ON tasks
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- 12. Insert some default categories for new users (optional)
CREATE OR REPLACE FUNCTION create_default_categories()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO categories (name, color, user_id) VALUES
('Personal', '#22c55e', NEW.id),
('Work', '#3b82f6', NEW.id),
('Shopping', '#f59e0b', NEW.id),
('Health', '#ef4444', NEW.id)
ON CONFLICT (name, user_id) DO NOTHING;
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 13. Create trigger to add default categories for new users
DROP TRIGGER IF EXISTS create_user_default_categories ON auth.users;
CREATE TRIGGER create_user_default_categories
AFTER INSERT ON auth.users
FOR EACH ROW
EXECUTE FUNCTION create_default_categories();
-- 14. Create function to get user activity summary
CREATE OR REPLACE FUNCTION get_user_activity_summary(user_uuid UUID, days_back INTEGER DEFAULT 30)
RETURNS JSON AS $$
DECLARE
result JSON;
BEGIN
SELECT json_build_object(
'tasks_created_last_n_days', (
SELECT COUNT(*)
FROM tasks
WHERE user_id = user_uuid
AND created_at >= NOW() - INTERVAL '1 day' * days_back
),
'tasks_completed_last_n_days', (
SELECT COUNT(*)
FROM tasks
WHERE user_id = user_uuid
AND completed_at >= NOW() - INTERVAL '1 day' * days_back
AND status = 'done'
),
'average_completion_time_hours', (
SELECT ROUND(AVG(EXTRACT(EPOCH FROM (completed_at - created_at)) / 3600), 2)
FROM tasks
WHERE user_id = user_uuid
AND completed_at IS NOT NULL
AND created_at >= NOW() - INTERVAL '1 day' * days_back
),
'most_productive_day', (
SELECT TO_CHAR(DATE_TRUNC('day', completed_at), 'Day')
FROM tasks
WHERE user_id = user_uuid
AND completed_at >= NOW() - INTERVAL '1 day' * days_back
AND status = 'done'
GROUP BY DATE_TRUNC('day', completed_at)
ORDER BY COUNT(*) DESC
LIMIT 1
),
'busiest_category', (
SELECT category
FROM tasks
WHERE user_id = user_uuid
AND created_at >= NOW() - INTERVAL '1 day' * days_back
GROUP BY category
ORDER BY COUNT(*) DESC
LIMIT 1
)
) INTO result;
RETURN result;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 15. Grant necessary permissions
GRANT USAGE ON SCHEMA public TO anon, authenticated;
GRANT ALL ON ALL TABLES IN SCHEMA public TO anon, authenticated;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO anon, authenticated;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO anon, authenticated;