Files
Sauci/apps/supabase/migrations/20231227000001_initial_schema.sql
T
2025-12-27 19:10:11 +00:00

109 lines
3.7 KiB
PL/PgSQL
Executable File

-- 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();