← 回主控台

🔐 ArenaMate 權限稽核 — RLS 上鎖清單

稽核日期 2026-07-16。起因:「每個功能真的都有做權限過濾嗎?」
一句話:除了金流表(上次已鎖),全站 79 張表的「寫入」權限本來都是敞開的——任何登入者(部分含未登入)繞過 App 直接打資料庫,就能改任何人的資料。已完成:6 批乾淨表(約 55 張)全部上鎖並實測(模擬登入驗證「別人改被擋、本人/幹部放行」)。剩約 10 張「比賽結算表」(評分/戰績/信任分/比分)因為結算在手機端跑、會改所有參賽者的列,要先把結算搬進 server RPC 才能鎖 → 見文末。
圖例:public = 連未登入都能寫(最急) authed = 任何登入者能寫 已鎖 = 本次/上次已修

✅ 已鎖好(不用再處理)

項目原本的洞已改成狀態
10 張金流表寫入全開(曾全 using(true)綁擁有者/幹部;費率不吃 client 值已鎖(上次)
arena_team_join零檢查 + 開放 anon → 任何人把任何人加進任何隊幹部或本人 + 擋 anon已鎖
coach_release_slot可繞銷課閘門提前套現只留 server(死碼 caller 移除)已鎖
arena_notify_direct冒名對任何人發任何通知(釣魚/洗版)限該館幹部 + kind 白名單 + 擋 anon已鎖
arena_complete_bracket_session可關掉別人賽事的場次限該賽事幹部 + 擋 anon已鎖
arena_bump_player_sport_season可把任何人 SLP/XP/排名灌爆登入 + server 上限夾住 + 擋 anon已鎖
65 支測試/demo/teleport RPC全 anon 可打、會改正式資料revoke anon(你登入還能用)已鎖

✅ 6 批乾淨表 — 已全部上鎖並實測

以下 6 批(約 55 張)都已寫上「誰能寫」的條件、線上實測通過(模擬登入:別人改被擋、本人/幹部放行)。下表是每張的規則,供對照。各批內 public 的也一併鎖了。

批 1 · 帳號 / 身分最高優先:可改任何人身分

是什麼現況提議誰能寫
user_profiles名字/性別/生日/頭像/LINEauthed只能改自己
gym_athletes每館的球員身分authed本人名下 或 該館幹部
athlete_follows追蹤 / 好友關係publicfollower=自己(保留掃碼加好友雙向寫)
athlete_trust · athlete_pass_progress · athlete_season_stats · gym_athlete_sport_stats信任額度 / 通行證 / 戰績統計authed只走 server RPC
gym_password_history場館密碼箱歷史authed該館幹部

批 2 · 場館治理可改/刪任何場館

是什麼現況提議
gyms場館本體authed該館 owner/admin
gym_settings · gym_venues · gym_sports · gym_day_hours · gym_schedules · gym_special_dates · gym_special_sessions · gym_fixed_sessions場館設定 / 場地 / 時段authed該館幹部
gym_coaches場館教練名冊public該館幹部
gym_access_checklists · gym_access_logs進場檢查 / 紀錄authed該館幹部 / 相關人

批 3 · 戰隊可改/刪任何戰隊、加踢任何人

是什麼現況提議
gym_teams戰隊本體authed該隊幹部
gym_team_members隊員名冊(加人已走 RPC,直接寫還開)authed該隊幹部(本人可退隊)
gym_team_invites戰隊邀請public該隊幹部
gym_rep_teams代表隊public該館幹部
team_honors · arena_team_challenges榮譽 / 約戰authed系統 / 隊幹部

批 4 · 賽事可改別人賽事/比分/裁判

現況提議
gym_tournaments · gym_tournament_entries · gym_tournament_matches · gym_tournament_match_liveauthed主辦館幹部 / 報名隊 / 裁判
gym_matches · gym_match_players · gym_match_eventsauthed賽事幹部 / 裁判 / 參賽者
gym_tournament_officials · gym_tournament_invites · gym_tournament_venue_votespublic賽事幹部 / 相關隊
arena_tournament_match_officials · arena_tournament_staff · arena_match_forfeits · arena_match_results_log · gym_tournament_arrivals · gym_rep_historyauthed賽事幹部 / 裁判

批 5 · 課程 / 教練金流相鄰,金流部分已鎖

現況提議
coach_courses · coach_enrollmentsauthed教練 / 該館幹部 / 報名學員本人
arena_coach_programs · arena_program_* · arena_course_templates · arena_course_reviews · arena_coach_resumesauthed教練本人 / 幹部
coach_bookingspublic相關人
coach_student_reviews · arena_course_wishes · arena_course_wish_votesauthed本人

批 6 · 社交 / 系統 / 雜項

現況提議
gym_kudos · gym_match_mvp_votes · gym_chat_messages · gym_session_invitespublic發話者 / 相關人本人
street_courtspublic建立者 / 幹部
official_badges · arena_player_sport · arena_player_pass · gym_rating_eventspublic/authedserver-only(SLP/XP/評級只走 RPC)
arena_message_templates · arena_lineups · arena_lineup_templatespublicoperator / 建立者
seasons · season_pass_rewards · rule_templates · partner_offers · arena_tutorials · arena_gym_rivalry_events · arena_gym_closures · gym_reports · gym_venue_requests · arena_tournament_feedback · gym_sessionsauthedoperator/系統 / 該館幹部 / 相關人
pitch_feedbackanon+authed保留 anon(意見回饋合理)

🟠 剩下:約 10 張「比賽結算表」(要先搬 RPC 才能鎖)

這組表的寫入不是「改自己的資料」,而是比賽結算時在手機端一次改「所有參賽者/兩隊/兩館」的列(評分、戰績、信任分、比分)。所以綁「只能改自己」會把結算打斷 → 必須先把結算邏輯搬進 server 的 SECURITY DEFINER RPC,再把這些表鎖成「只有 server 能寫」。

結算時寫什麼
gym_athletes(評分欄)每位參賽者的 rating/勝敗(concludeMatch loop)
athlete_season_stats · athlete_trust · athlete_pass_progress每位參賽者的賽季戰績/信任分/通行證 XP
gym_match_players一場比賽兩隊所有上場球員
gym_teams(戰績欄)勝隊+敗隊的 rating/勝敗
gyms(Elo 欄)· gym_rating_events · arena_gym_rivalry_events館間賽兩館的 Elo/強度/對戰事件
official_badges該場裁判/線審的執法場次徽章

⚠️ 這是動到正在使用的計分引擎,最高風險,建議獨立一次做(含完整結算流程測試),不跟其他批混。全域排名(arena_player_sport/pass + SLP/XP bump RPC)已在前面鎖好,這組是舊的「單場館」戰績。

後續(比 RLS 更後面)

65 支測試 RPC 目前只擋了 anon,更強的「只限 operator/本人」要逐支加內部檢查。