|
|
-- Profiles: public display info for users (creator names on community decks)
|
|
|
CREATE TABLE IF NOT EXISTS omotomo.profiles (
|
|
|
id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
display_name text,
|
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
|
);
|
|
|
|
|
|
ALTER TABLE omotomo.profiles ENABLE ROW LEVEL SECURITY;
|
|
|
|
|
|
-- Anyone can read profiles (to show creator names)
|
|
|
DROP POLICY IF EXISTS profiles_select ON omotomo.profiles;
|
|
|
DROP POLICY IF EXISTS profiles_insert ON omotomo.profiles;
|
|
|
DROP POLICY IF EXISTS profiles_update ON omotomo.profiles;
|
|
|
DROP POLICY IF EXISTS profiles_delete ON omotomo.profiles;
|
|
|
CREATE POLICY profiles_select ON omotomo.profiles
|
|
|
FOR SELECT USING (true);
|
|
|
|
|
|
-- Users can insert/update/delete only their own profile
|
|
|
CREATE POLICY profiles_insert ON omotomo.profiles
|
|
|
FOR INSERT WITH CHECK (auth.uid() = id);
|
|
|
|
|
|
CREATE POLICY profiles_update ON omotomo.profiles
|
|
|
FOR UPDATE USING (auth.uid() = id) WITH CHECK (auth.uid() = id);
|
|
|
|
|
|
CREATE POLICY profiles_delete ON omotomo.profiles
|
|
|
FOR DELETE USING (auth.uid() = id);
|
|
|
|
|
|
-- Create profile when a new user signs up (Supabase Auth)
|
|
|
CREATE OR REPLACE FUNCTION omotomo.handle_new_user()
|
|
|
RETURNS TRIGGER
|
|
|
LANGUAGE plpgsql
|
|
|
SECURITY DEFINER
|
|
|
SET search_path = omotomo, public
|
|
|
AS $$
|
|
|
BEGIN
|
|
|
INSERT INTO omotomo.profiles (id, display_name)
|
|
|
VALUES (
|
|
|
NEW.id,
|
|
|
COALESCE(
|
|
|
NEW.raw_user_meta_data->>'full_name',
|
|
|
NEW.raw_user_meta_data->>'name',
|
|
|
split_part(NEW.email, '@', 1),
|
|
|
'User'
|
|
|
)
|
|
|
)
|
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
RETURN NEW;
|
|
|
END;
|
|
|
$$;
|
|
|
|
|
|
DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;
|
|
|
CREATE TRIGGER on_auth_user_created
|
|
|
AFTER INSERT ON auth.users
|
|
|
FOR EACH ROW
|
|
|
EXECUTE FUNCTION omotomo.handle_new_user();
|
|
|
|
|
|
-- Backfill existing users: run in Supabase Dashboard SQL Editor (Service role) if you have users already:
|
|
|
-- INSERT INTO omotomo.profiles (id, display_name)
|
|
|
-- SELECT id, COALESCE(raw_user_meta_data->>'full_name', raw_user_meta_data->>'name', split_part(email, '@', 1), 'User')
|
|
|
-- FROM auth.users ON CONFLICT (id) DO NOTHING;
|
|
|
|
|
|
-- Deck ratings: one rating (1–5 stars) per user per deck
|
|
|
CREATE TABLE IF NOT EXISTS omotomo.deck_ratings (
|
|
|
deck_id uuid NOT NULL REFERENCES omotomo.decks(id) ON DELETE CASCADE,
|
|
|
user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
rating smallint NOT NULL CHECK (rating >= 1 AND rating <= 5),
|
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
|
PRIMARY KEY (deck_id, user_id)
|
|
|
);
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_deck_ratings_deck_id ON omotomo.deck_ratings(deck_id);
|
|
|
|
|
|
ALTER TABLE omotomo.deck_ratings ENABLE ROW LEVEL SECURITY;
|
|
|
|
|
|
-- Anyone can read ratings (for showing averages on community)
|
|
|
DROP POLICY IF EXISTS deck_ratings_select ON omotomo.deck_ratings;
|
|
|
DROP POLICY IF EXISTS deck_ratings_insert ON omotomo.deck_ratings;
|
|
|
DROP POLICY IF EXISTS deck_ratings_update ON omotomo.deck_ratings;
|
|
|
DROP POLICY IF EXISTS deck_ratings_delete ON omotomo.deck_ratings;
|
|
|
CREATE POLICY deck_ratings_select ON omotomo.deck_ratings
|
|
|
FOR SELECT USING (true);
|
|
|
|
|
|
-- Authenticated users can insert/update only their own rating, and not for decks they own
|
|
|
CREATE POLICY deck_ratings_insert ON omotomo.deck_ratings
|
|
|
FOR INSERT WITH CHECK (
|
|
|
auth.uid() = user_id
|
|
|
AND (SELECT d.owner_id FROM omotomo.decks d WHERE d.id = deck_id) IS DISTINCT FROM auth.uid()
|
|
|
);
|
|
|
|
|
|
CREATE POLICY deck_ratings_update ON omotomo.deck_ratings
|
|
|
FOR UPDATE USING (auth.uid() = user_id) WITH CHECK (
|
|
|
auth.uid() = user_id
|
|
|
AND (SELECT d.owner_id FROM omotomo.decks d WHERE d.id = deck_id) IS DISTINCT FROM auth.uid()
|
|
|
);
|
|
|
|
|
|
CREATE POLICY deck_ratings_delete ON omotomo.deck_ratings
|
|
|
FOR DELETE USING (auth.uid() = user_id);
|