Spaces:
Sleeping
Sleeping
| -- Drop existing tables if they exist to prevent schema mismatch | |
| DROP TABLE IF EXISTS user_reviews CASCADE; | |
| DROP TABLE IF EXISTS user_streaks CASCADE; | |
| DROP TABLE IF EXISTS problems CASCADE; | |
| -- Enable UUID extension | |
| CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; | |
| -- Table: problems | |
| CREATE TABLE problems ( | |
| id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), | |
| user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, | |
| name VARCHAR(255) NOT NULL, | |
| problem_number INTEGER, -- Tracked for Journey Path | |
| pattern VARCHAR(100) NOT NULL, | |
| difficulty VARCHAR(20) NOT NULL DEFAULT 'Medium' CHECK (difficulty IN ('Easy', 'Medium', 'Hard')), | |
| google_doc_url TEXT, | |
| google_doc_id VARCHAR(100), -- Tracks file | |
| optimal_time VARCHAR(50) NOT NULL DEFAULT 'O(N)', | |
| optimal_space VARCHAR(50) NOT NULL DEFAULT 'O(N)', | |
| description TEXT, | |
| reference_code TEXT, -- Stores reference code synced from Doc | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, | |
| CONSTRAINT unique_user_problem UNIQUE (user_id, name) | |
| ); | |
| -- Table: user_reviews | |
| CREATE TABLE user_reviews ( | |
| id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), | |
| user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, | |
| problem_id UUID NOT NULL REFERENCES problems(id) ON DELETE CASCADE, | |
| box_level INTEGER NOT NULL DEFAULT 1 CHECK (box_level BETWEEN 1 AND 5), | |
| last_reviewed TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, | |
| next_review TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| times_correct INTEGER NOT NULL DEFAULT 0, | |
| total_attempts INTEGER NOT NULL DEFAULT 0, | |
| CONSTRAINT unique_user_problem_review UNIQUE (user_id, problem_id) | |
| ); | |
| -- Table: user_streaks | |
| CREATE TABLE user_streaks ( | |
| user_id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, | |
| current_streak INTEGER NOT NULL DEFAULT 0 CHECK (current_streak >= 0), | |
| longest_streak INTEGER NOT NULL DEFAULT 0 CHECK (longest_streak >= 0), | |
| last_active_date DATE, | |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| -- Enable RLS on all tables | |
| ALTER TABLE problems ENABLE ROW LEVEL SECURITY; | |
| ALTER TABLE user_reviews ENABLE ROW LEVEL SECURITY; | |
| ALTER TABLE user_streaks ENABLE ROW LEVEL SECURITY; | |
| -- RLS Policies for problems | |
| CREATE POLICY select_problems ON problems FOR SELECT USING (true); | |
| CREATE POLICY insert_problems ON problems FOR INSERT TO authenticated WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY update_problems ON problems FOR UPDATE TO authenticated USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY delete_problems ON problems FOR DELETE TO authenticated USING (auth.uid() = user_id); | |
| -- RLS Policies for user_reviews | |
| CREATE POLICY select_reviews ON user_reviews FOR SELECT TO authenticated USING (auth.uid() = user_id); | |
| CREATE POLICY insert_reviews ON user_reviews FOR INSERT TO authenticated WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY update_reviews ON user_reviews FOR UPDATE TO authenticated USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY delete_reviews ON user_reviews FOR DELETE TO authenticated USING (auth.uid() = user_id); | |
| -- RLS Policies for user_streaks | |
| CREATE POLICY select_streaks ON user_streaks FOR SELECT TO authenticated USING (auth.uid() = user_id); | |
| CREATE POLICY insert_streaks ON user_streaks FOR INSERT TO authenticated WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY update_streaks ON user_streaks FOR UPDATE TO authenticated USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY delete_streaks ON user_streaks FOR DELETE TO authenticated USING (auth.uid() = user_id); | |
| -- Table: user_journey_progress | |
| CREATE TABLE user_journey_progress ( | |
| id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), | |
| user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, | |
| problem_number INTEGER NOT NULL, | |
| viewed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, | |
| CONSTRAINT unique_user_journey_problem UNIQUE (user_id, problem_number) | |
| ); | |
| -- Enable RLS on new table | |
| ALTER TABLE user_journey_progress ENABLE ROW LEVEL SECURITY; | |
| -- RLS Policies for user_journey_progress | |
| CREATE POLICY select_journey ON user_journey_progress FOR SELECT TO authenticated USING (auth.uid() = user_id); | |
| CREATE POLICY insert_journey ON user_journey_progress FOR INSERT TO authenticated WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY update_journey ON user_journey_progress FOR UPDATE TO authenticated USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY delete_journey ON user_journey_progress FOR DELETE TO authenticated USING (auth.uid() = user_id); | |
| -- Table: user_scores | |
| CREATE TABLE IF NOT EXISTS user_scores ( | |
| user_id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, | |
| total_score INTEGER DEFAULT 0 CHECK (total_score >= 0), | |
| python_challenges_completed INTEGER DEFAULT 0, | |
| sql_challenges_completed INTEGER DEFAULT 0, | |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| -- Table: challenge_history | |
| CREATE TABLE IF NOT EXISTS challenge_history ( | |
| id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), | |
| user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, | |
| challenge_type VARCHAR(20) NOT NULL CHECK (challenge_type IN ('python', 'mysql')), | |
| challenge_title VARCHAR(255) NOT NULL, | |
| points_awarded INTEGER NOT NULL DEFAULT 0, | |
| completed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| -- Enable RLS on new tables | |
| ALTER TABLE user_scores ENABLE ROW LEVEL SECURITY; | |
| ALTER TABLE challenge_history ENABLE ROW LEVEL SECURITY; | |
| -- RLS Policies for user_scores | |
| CREATE POLICY select_scores ON user_scores FOR SELECT TO authenticated USING (auth.uid() = user_id); | |
| CREATE POLICY insert_scores ON user_scores FOR INSERT TO authenticated WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY update_scores ON user_scores FOR UPDATE TO authenticated USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY delete_scores ON user_scores FOR DELETE TO authenticated USING (auth.uid() = user_id); | |
| -- RLS Policies for challenge_history | |
| CREATE POLICY select_history ON challenge_history FOR SELECT TO authenticated USING (auth.uid() = user_id); | |
| CREATE POLICY insert_history ON challenge_history FOR INSERT TO authenticated WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY update_history ON challenge_history FOR UPDATE TO authenticated USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); | |
| CREATE POLICY delete_history ON challenge_history FOR DELETE TO authenticated USING (auth.uid() = user_id); | |