S10 (a1): public ledger profiles v1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
-- ---------------------------------------------------------------
|
||||
-- 022 — public_profiles (A1 Session 10, public ledger profiles v1).
|
||||
--
|
||||
-- Stage-3 seed: a user may claim a handle and publish their ENTIRE settled
|
||||
-- ledger record on a public page — wins and misses. Strava for betting.
|
||||
--
|
||||
-- PRIVACY: PRIVATE BY DEFAULT. `published` defaults false and only flips
|
||||
-- via one explicit toggle in Settings. The profile API returns the SAME
|
||||
-- 404 for an unknown handle and an unpublished one (no existence leak).
|
||||
--
|
||||
-- All writes go through the service role (the /api/profiles/me route).
|
||||
-- Clients only read: published rows (anyone) + their own row (owner).
|
||||
-- ---------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.public_profiles (
|
||||
user_id uuid PRIMARY KEY REFERENCES auth.users (id) ON DELETE CASCADE,
|
||||
handle text UNIQUE NOT NULL CHECK (handle ~ '^[a-z0-9_]{3,20}$'),
|
||||
published boolean NOT NULL DEFAULT false,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
ALTER TABLE public.public_profiles ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Anyone (anon + authenticated) reads PUBLISHED profiles only.
|
||||
CREATE POLICY public_profiles_select_published ON public.public_profiles
|
||||
FOR SELECT TO anon, authenticated
|
||||
USING (published = true);
|
||||
|
||||
-- The owner reads their own row (published or not).
|
||||
CREATE POLICY public_profiles_select_own ON public.public_profiles
|
||||
FOR SELECT TO authenticated
|
||||
USING (user_id = auth.uid());
|
||||
|
||||
-- No INSERT/UPDATE/DELETE policies: client-side writes are impossible.
|
||||
-- The API writes via the service role, which bypasses RLS.
|
||||
Reference in New Issue
Block a user