begin; -- Tüm tablolar için RLS aç alter table public.profiles enable row level security; alter table public.user_roles enable row level security; alter table public.tournaments enable row level security; alter table public.tournament_participants enable row level security; alter table public.tournament_draws enable row level security; alter table public.matches enable row level security; alter table public.match_evidences enable row level security; alter table public.match_disputes enable row level security; alter table public.tournament_messages enable row level security; alter table public.match_messages enable row level security; alter table public.user_blocks enable row level security; alter table public.notifications enable row level security; -- Yardımcı fonksiyonlar: rol kontrol create or replace function public.is_super_admin() returns boolean language sql stable as $$ select exists ( select 1 from public.user_roles r where r.user_id = auth.uid() and r.role = 'super_admin' ); $$; create or replace function public.is_admin() returns boolean language sql stable as $$ select exists ( select 1 from public.user_roles r where r.user_id = auth.uid() and r.role in ('admin','super_admin') ); $$; -- profiles: kullanıcı kendi profilini okuyabilir/düzenleyebilir; diğerleri okur create policy "Profiles public read" on public.profiles for select using (true); create policy "Profiles self update" on public.profiles for update using (id = auth.uid()) with check (id = auth.uid()); -- user_roles: kimse doğrudan değiştiremesin; edge function/admin kurar create policy "User roles no direct read" on public.user_roles for select using (false); create policy "User roles no direct write" on public.user_roles for insert with check (false); create policy "User roles no direct update" on public.user_roles for update using (false); create policy "User roles no direct delete" on public.user_roles for delete using (false); -- tournaments: herkes turnuva okuyabilir; admin oluşturabilir create policy "Tournaments read all" on public.tournaments for select using (true); create policy "Tournaments create admin" on public.tournaments for insert with check (public.is_admin()); create policy "Tournaments update admin" on public.tournaments for update using (public.is_admin()) with check (public.is_admin()); -- participants: kullanıcı kendi kaydını yapar; aynı turnuvaya tekrar yok (pk ile engelli) create policy "Participants self read" on public.tournament_participants for select using (user_id = auth.uid() OR public.is_admin()); create policy "Participants self insert" on public.tournament_participants for insert with check (user_id = auth.uid() AND not public.is_admin() = false); -- Admin participant ekleme/kapatma için update/delete create policy "Participants admin manage" on public.tournament_participants for update using (public.is_admin()) with check (public.is_admin()); create policy "Participants admin delete" on public.tournament_participants for delete using (public.is_admin()); -- matches: herkes maçları okuyabilir; skor/kanıt/itiraz sadece ilgili kullanıcı ve admin akışı ile create policy "Matches read all" on public.matches for select using (true); -- skor gönderme: home/away takım içinden create policy "Match submit result - team can update pending fields" on public.matches for update using ( auth.uid() = any(home_team_user_ids) OR auth.uid() = any(away_team_user_ids) ) with check ( -- sadece skor teslim/son durum değişimi edge tarafından yapılacaksa burada limit koyarız true ); -- Admin skor onay create policy "Match confirm result - admin" on public.matches for update using (public.is_admin()) with check (public.is_admin()); -- Kanıt yükleme: sadece maçı oynayan taraf create policy "Evidence upload by match participant" on public.match_evidences for insert with check ( uploaded_by = auth.uid() AND ( auth.uid() = any((select m.home_team_user_ids from public.matches m where m.id = match_id)) OR auth.uid() = any((select m.away_team_user_ids from public.matches m where m.id = match_id)) ) ); create policy "Evidence read by match participants and admins" on public.match_evidences for select using ( public.is_admin() OR uploaded_by = auth.uid() OR auth.uid() = any((select m.home_team_user_ids from public.matches m where m.id = match_id)) OR auth.uid() = any((select m.away_team_user_ids from public.matches m where m.id = match_id)) ); -- Itiraz: maç tarafı itiraz edebilir; admin çözebilir create policy "Dispute submit by match participant" on public.match_disputes for insert with check ( submitted_by = auth.uid() AND ( auth.uid() = any((select m.home_team_user_ids from public.matches m where m.id = match_id)) OR auth.uid() = any((select m.away_team_user_ids from public.matches m where m.id = match_id)) ) ); create policy "Dispute read match participants/admin" on public.match_disputes for select using ( public.is_admin() OR submitted_by = auth.uid() ); -- Mesajlar: blok kontrolü ile create policy "Tournament messages read all" on public.tournament_messages for select using (true); create policy "Tournament message insert by signed-in" on public.tournament_messages for insert with check ( sender_id = auth.uid() ); -- Blok yapanlar engellenen kişiden gelen mesajları görmesin (select filtre) create policy "Tournament message select respecting blocks" on public.tournament_messages for select using ( not exists ( select 1 from public.user_blocks b where b.blocker_id = auth.uid() and b.blocked_id = sender_id ) ); -- Match messages create policy "Match messages read all" on public.match_messages for select using (true); create policy "Match message select respecting blocks" on public.match_messages for select using ( not exists ( select 1 from public.user_blocks b where b.blocker_id = auth.uid() and b.blocked_id = sender_id ) ); create policy "Match message insert signed-in" on public.match_messages for insert with check (sender_id = auth.uid()); -- Block yönetimi create policy "User blocks manage self" on public.user_blocks for insert with check (blocker_id = auth.uid()); create policy "User blocks read self" on public.user_blocks for select using (blocker_id = auth.uid() OR blocked_id = auth.uid()); -- notifications: kullanıcı sadece kendi bildirimlerini görür create policy "Notifications read own" on public.notifications for select using (user_id = auth.uid()); create policy "Notifications insert by system/admin" on public.notifications for insert with check (public.is_admin() OR public.is_super_admin()); commit;