You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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

Powered by TurnKey Linux.