-- ============================================================ -- MulliganMates — Row Level Security Policies -- ============================================================ alter table public.profiles enable row level security; alter table public.courses enable row level security; alter table public.tees enable row level security; alter table public.holes enable row level security; alter table public.rounds enable row level security; alter table public.round_players enable row level security; alter table public.round_invites enable row level security; alter table public.scores enable row level security; -- ============================================================ -- Helper: is the current user a member of the given round? -- ============================================================ create or replace function public.is_round_member(p_round_id uuid) returns boolean language sql security definer stable as $$ select exists ( select 1 from public.round_players where round_id = p_round_id and user_id = auth.uid() ) $$; -- ============================================================ -- Profiles -- ============================================================ create policy "Anyone can read profiles" on public.profiles for select using (true); create policy "Users can update their own profile" on public.profiles for update using (id = auth.uid()); -- ============================================================ -- Courses -- ============================================================ create policy "Authenticated users can read courses" on public.courses for select using (auth.role() = 'authenticated'); create policy "Authenticated users can create courses" on public.courses for insert with check (auth.role() = 'authenticated'); create policy "Course creator can update" on public.courses for update using (created_by = auth.uid()); -- ============================================================ -- Tees -- ============================================================ create policy "Authenticated users can read tees" on public.tees for select using (auth.role() = 'authenticated'); create policy "Authenticated users can manage tees on their courses" on public.tees for all using ( exists ( select 1 from public.courses where id = tees.course_id and created_by = auth.uid() ) ); -- ============================================================ -- Holes -- ============================================================ create policy "Authenticated users can read holes" on public.holes for select using (auth.role() = 'authenticated'); create policy "Course creator can manage holes" on public.holes for all using ( exists ( select 1 from public.courses where id = holes.course_id and created_by = auth.uid() ) ); -- ============================================================ -- Rounds -- ============================================================ create policy "Round members can read round" on public.rounds for select using (public.is_round_member(id)); create policy "Authenticated users can create rounds" on public.rounds for insert with check ( auth.role() = 'authenticated' and created_by = auth.uid() ); create policy "Round creator can update round" on public.rounds for update using (created_by = auth.uid()); -- ============================================================ -- Round Players -- ============================================================ create policy "Round members can read player list" on public.round_players for select using (public.is_round_member(round_id)); create policy "Round creator can add players" on public.round_players for insert with check ( exists ( select 1 from public.rounds where id = round_players.round_id and created_by = auth.uid() and status = 'lobby' ) ); create policy "Users can join a round via insert of own record" on public.round_players for insert with check (user_id = auth.uid()); -- ============================================================ -- Round Invites -- ============================================================ create policy "Round members can read invites" on public.round_invites for select using (public.is_round_member(round_id)); create policy "Round creator can send invites" on public.round_invites for insert with check ( exists ( select 1 from public.rounds where id = round_invites.round_id and created_by = auth.uid() and status = 'lobby' ) ); create policy "Invited user can mark invite accepted" on public.round_invites for update using ( email = (select email from auth.users where id = auth.uid()) ); -- ============================================================ -- Scores -- ============================================================ create policy "Round members can read scores" on public.scores for select using (public.is_round_member(round_id)); create policy "Round members can enter and edit scores" on public.scores for insert with check ( public.is_round_member(round_id) and exists ( select 1 from public.rounds where id = scores.round_id and status = 'active' ) ); create policy "Round members can update scores" on public.scores for update using ( public.is_round_member(round_id) and exists ( select 1 from public.rounds where id = scores.round_id and status = 'active' ) );