-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.sql
More file actions
465 lines (379 loc) · 13.3 KB
/
database.sql
File metadata and controls
465 lines (379 loc) · 13.3 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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
-- Claude Code Online Platform Database Schema
-- Purpose: Enable users to access fullstack-deploy skill via web interface
-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================================================
-- User Credentials Table
-- Stores encrypted third-party service credentials for each user
-- ============================================================================
CREATE TABLE user_credentials (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- GitHub credentials
github_token TEXT,
github_username TEXT,
-- Vercel credentials
vercel_token TEXT,
vercel_team_id TEXT,
-- Supabase credentials
supabase_url TEXT,
supabase_anon_key TEXT,
supabase_project_ref TEXT,
-- Timestamps
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
-- Ensure one credential set per user
UNIQUE(user_id)
);
-- Row Level Security
ALTER TABLE user_credentials ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own credentials"
ON user_credentials FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own credentials"
ON user_credentials FOR INSERT
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own credentials"
ON user_credentials FOR UPDATE
USING (auth.uid() = user_id);
-- Auto-update timestamp trigger
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_user_credentials_updated_at
BEFORE UPDATE ON user_credentials
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- ============================================================================
-- Projects Table
-- Stores information about deployed projects
-- ============================================================================
CREATE TABLE projects (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- Project details
name TEXT NOT NULL,
description TEXT,
framework TEXT NOT NULL, -- 'nextjs', 'flask', 'fastapi', 'vue', etc.
-- URLs
github_url TEXT,
vercel_url TEXT,
-- Status
status TEXT NOT NULL DEFAULT 'pending',
-- Status options: 'pending', 'in_queue', 'processing', 'deploying', 'success', 'failed'
error_message TEXT,
-- Metadata
features JSONB DEFAULT '[]'::jsonb,
tech_stack JSONB DEFAULT '[]'::jsonb,
-- Timestamps
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
completed_at TIMESTAMPTZ
);
-- Indexes
CREATE INDEX idx_projects_user_id ON projects(user_id);
CREATE INDEX idx_projects_status ON projects(status);
CREATE INDEX idx_projects_created_at ON projects(created_at DESC);
-- Row Level Security
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own projects"
ON projects FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own projects"
ON projects FOR INSERT
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own projects"
ON projects FOR UPDATE
USING (auth.uid() = user_id);
CREATE TRIGGER update_projects_updated_at
BEFORE UPDATE ON projects
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- ============================================================================
-- Deployment Logs Table
-- Stores detailed execution logs for each deployment phase
-- ============================================================================
CREATE TABLE deployment_logs (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
-- Log details
phase TEXT NOT NULL, -- 'requirements', 'database', 'development', 'git', 'deployment', 'completion'
phase_number INTEGER NOT NULL,
message TEXT NOT NULL,
log_type TEXT DEFAULT 'info', -- 'info', 'success', 'error', 'warning'
-- Metadata
metadata JSONB DEFAULT '{}'::jsonb,
-- Timestamp
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_deployment_logs_project_id ON deployment_logs(project_id);
CREATE INDEX idx_deployment_logs_created_at ON deployment_logs(created_at);
-- Row Level Security
ALTER TABLE deployment_logs ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own deployment logs"
ON deployment_logs FOR SELECT
USING (
EXISTS (
SELECT 1 FROM projects
WHERE projects.id = deployment_logs.project_id
AND projects.user_id = auth.uid()
)
);
CREATE POLICY "Service can insert deployment logs"
ON deployment_logs FOR INSERT
WITH CHECK (
EXISTS (
SELECT 1 FROM projects
WHERE projects.id = deployment_logs.project_id
AND projects.user_id = auth.uid()
)
);
-- ============================================================================
-- Task Queue Table
-- Manages deployment task queue with concurrent processing limits
-- ============================================================================
CREATE TABLE task_queue (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- Queue details
status TEXT NOT NULL DEFAULT 'pending',
-- Status options: 'pending', 'processing', 'completed', 'failed'
priority INTEGER DEFAULT 0,
queue_position INTEGER,
-- Processing details
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
retry_count INTEGER DEFAULT 0,
max_retries INTEGER DEFAULT 0,
-- Timestamps
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_task_queue_status ON task_queue(status);
CREATE INDEX idx_task_queue_created_at ON task_queue(created_at);
CREATE INDEX idx_task_queue_user_id ON task_queue(user_id);
-- Row Level Security
ALTER TABLE task_queue ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own tasks"
ON task_queue FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own tasks"
ON task_queue FOR INSERT
WITH CHECK (auth.uid() = user_id);
CREATE TRIGGER update_task_queue_updated_at
BEFORE UPDATE ON task_queue
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- ============================================================================
-- Conversations Table
-- Stores chat conversations between users and the AI
-- ============================================================================
CREATE TABLE conversations (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
-- Conversation details
title TEXT,
-- Timestamps
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_conversations_user_id ON conversations(user_id);
CREATE INDEX idx_conversations_created_at ON conversations(created_at DESC);
-- Row Level Security
ALTER TABLE conversations ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own conversations"
ON conversations FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own conversations"
ON conversations FOR INSERT
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own conversations"
ON conversations FOR UPDATE
USING (auth.uid() = user_id);
CREATE TRIGGER update_conversations_updated_at
BEFORE UPDATE ON conversations
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- ============================================================================
-- Messages Table
-- Stores individual messages within conversations
-- ============================================================================
CREATE TABLE messages (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
conversation_id UUID NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
-- Message details
role TEXT NOT NULL, -- 'user', 'assistant', 'system'
content TEXT NOT NULL,
-- Metadata
metadata JSONB DEFAULT '{}'::jsonb,
-- Timestamp
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_messages_conversation_id ON messages(conversation_id);
CREATE INDEX idx_messages_created_at ON messages(created_at);
-- Row Level Security
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view messages in own conversations"
ON messages FOR SELECT
USING (
EXISTS (
SELECT 1 FROM conversations
WHERE conversations.id = messages.conversation_id
AND conversations.user_id = auth.uid()
)
);
CREATE POLICY "Users can insert messages in own conversations"
ON messages FOR INSERT
WITH CHECK (
EXISTS (
SELECT 1 FROM conversations
WHERE conversations.id = messages.conversation_id
AND conversations.user_id = auth.uid()
)
);
-- ============================================================================
-- User Profiles Table (Extended user information)
-- ============================================================================
CREATE TABLE user_profiles (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- Profile details
display_name TEXT,
avatar_url TEXT,
-- Usage limits
daily_request_limit INTEGER DEFAULT 5,
daily_request_count INTEGER DEFAULT 0,
last_request_date DATE DEFAULT CURRENT_DATE,
-- Timestamps
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id)
);
-- Row Level Security
ALTER TABLE user_profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own profile"
ON user_profiles FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own profile"
ON user_profiles FOR INSERT
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own profile"
ON user_profiles FOR UPDATE
USING (auth.uid() = user_id);
CREATE TRIGGER update_user_profiles_updated_at
BEFORE UPDATE ON user_profiles
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- ============================================================================
-- Functions
-- ============================================================================
-- Function to reset daily request count
CREATE OR REPLACE FUNCTION reset_daily_request_count()
RETURNS void AS $$
BEGIN
UPDATE user_profiles
SET daily_request_count = 0
WHERE last_request_date < CURRENT_DATE;
UPDATE user_profiles
SET last_request_date = CURRENT_DATE
WHERE last_request_date < CURRENT_DATE;
END;
$$ LANGUAGE plpgsql;
-- Function to check if user can create new project
CREATE OR REPLACE FUNCTION can_create_project(p_user_id UUID)
RETURNS BOOLEAN AS $$
DECLARE
v_daily_limit INTEGER;
v_daily_count INTEGER;
v_last_date DATE;
BEGIN
-- Get user's current usage
SELECT daily_request_limit, daily_request_count, last_request_date
INTO v_daily_limit, v_daily_count, v_last_date
FROM user_profiles
WHERE user_id = p_user_id;
-- If no profile exists, return false
IF NOT FOUND THEN
RETURN FALSE;
END IF;
-- Reset count if it's a new day
IF v_last_date < CURRENT_DATE THEN
UPDATE user_profiles
SET daily_request_count = 0, last_request_date = CURRENT_DATE
WHERE user_id = p_user_id;
v_daily_count := 0;
END IF;
-- Check if under limit
RETURN v_daily_count < v_daily_limit;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Function to increment request count
CREATE OR REPLACE FUNCTION increment_request_count(p_user_id UUID)
RETURNS void AS $$
BEGIN
-- Reset count if it's a new day
UPDATE user_profiles
SET daily_request_count = 0, last_request_date = CURRENT_DATE
WHERE user_id = p_user_id AND last_request_date < CURRENT_DATE;
-- Increment count
UPDATE user_profiles
SET daily_request_count = daily_request_count + 1
WHERE user_id = p_user_id;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Function to update queue positions
CREATE OR REPLACE FUNCTION update_queue_positions()
RETURNS void AS $$
BEGIN
WITH ranked_tasks AS (
SELECT
id,
ROW_NUMBER() OVER (ORDER BY priority DESC, created_at ASC) as new_position
FROM task_queue
WHERE status = 'pending'
)
UPDATE task_queue
SET queue_position = ranked_tasks.new_position
FROM ranked_tasks
WHERE task_queue.id = ranked_tasks.id;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Trigger to auto-create user profile on signup
CREATE OR REPLACE FUNCTION create_user_profile()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO user_profiles (user_id)
VALUES (NEW.id);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW
EXECUTE FUNCTION create_user_profile();
-- ============================================================================
-- Sample Data (for testing)
-- ============================================================================
-- Note: Sample data should only be inserted in development environment
-- Uncomment the following lines if you want to test with sample data
/*
-- Insert sample user (requires auth.users to exist first)
INSERT INTO user_credentials (user_id, github_token, vercel_token, supabase_url, supabase_anon_key)
VALUES (
'your-test-user-uuid-here',
'ghp_test_token',
'vercel_test_token',
'https://test.supabase.co',
'test_anon_key'
);
*/