-- Enable necessary extensions CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- Create custom types CREATE TYPE public.answer_type AS ENUM ('yes', 'no', 'maybe'); CREATE TYPE public.match_type AS ENUM ('yes_yes', 'yes_maybe', 'maybe_maybe'); -- Couples table (must be created first due to FK references) CREATE TABLE public.couples ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), invite_code TEXT UNIQUE DEFAULT substr(md5(random()::text), 1, 8), created_at TIMESTAMPTZ DEFAULT NOW() ); -- User profiles (extends auth.users) CREATE TABLE public.profiles ( id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, name TEXT, avatar_url TEXT, push_token TEXT, is_premium BOOLEAN DEFAULT FALSE, couple_id UUID REFERENCES public.couples(id) ON DELETE SET NULL, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Question packs CREATE TABLE public.question_packs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, description TEXT, icon TEXT, is_premium BOOLEAN DEFAULT FALSE, is_public BOOLEAN DEFAULT TRUE, sort_order INT DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW() ); -- Questions within packs CREATE TABLE public.questions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), pack_id UUID NOT NULL REFERENCES public.question_packs(id) ON DELETE CASCADE, text TEXT NOT NULL, intensity INT DEFAULT 1 CHECK (intensity BETWEEN 1 AND 5), created_at TIMESTAMPTZ DEFAULT NOW() ); -- User responses to questions CREATE TABLE public.responses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE, question_id UUID NOT NULL REFERENCES public.questions(id) ON DELETE CASCADE, couple_id UUID NOT NULL REFERENCES public.couples(id) ON DELETE CASCADE, answer public.answer_type NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(user_id, question_id) ); -- Matches between partners CREATE TABLE public.matches ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), couple_id UUID NOT NULL REFERENCES public.couples(id) ON DELETE CASCADE, question_id UUID NOT NULL REFERENCES public.questions(id) ON DELETE CASCADE, match_type public.match_type NOT NULL, is_new BOOLEAN DEFAULT TRUE, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(couple_id, question_id) ); -- Create indexes for common queries CREATE INDEX idx_profiles_couple_id ON public.profiles(couple_id); CREATE INDEX idx_questions_pack_id ON public.questions(pack_id); CREATE INDEX idx_responses_couple_question ON public.responses(couple_id, question_id); CREATE INDEX idx_matches_couple_id ON public.matches(couple_id); CREATE INDEX idx_matches_is_new ON public.matches(is_new) WHERE is_new = TRUE; -- Function to auto-create profile on signup CREATE OR REPLACE FUNCTION public.handle_new_user() RETURNS TRIGGER AS $$ BEGIN INSERT INTO public.profiles (id, name, avatar_url) VALUES ( NEW.id, COALESCE(NEW.raw_user_meta_data->>'name', NEW.raw_user_meta_data->>'full_name'), NEW.raw_user_meta_data->>'avatar_url' ); RETURN NEW; END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Trigger to create profile on signup CREATE TRIGGER on_auth_user_created AFTER INSERT ON auth.users FOR EACH ROW EXECUTE FUNCTION public.handle_new_user(); -- Function to update updated_at timestamp CREATE OR REPLACE FUNCTION public.update_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Trigger to auto-update updated_at on profiles CREATE TRIGGER update_profiles_updated_at BEFORE UPDATE ON public.profiles FOR EACH ROW EXECUTE FUNCTION public.update_updated_at();