-- ============================================================================
-- Migration: 00001_enable_rls
-- Purpose: Enable PostgreSQL Row-Level Security (RLS) for multi-tenant
--          data isolation in the FitCRM platform.
--
-- Every table containing a `"clubId"` column receives two policies:
--   1. club_isolation_{table} (SELECT/UPDATE/DELETE) - restricts rows to
--      those matching the current tenant context.
--   2. club_insert_{table} (INSERT) - ensures new rows can only be created
--      for the current tenant.
--
-- The tenant context is set by the NestJS TenantMiddleware via:
--   SET app.club_id = '<uuid>';
--
-- current_setting('app.club_id', true) is used with the `true` flag so that
-- NULL is returned (instead of raising an error) when the setting has not
-- been set. This prevents failures during migrations, seed scripts, and
-- direct database access outside the application.
--
-- Tables excluded from RLS:
--   - clubs           : top-level entity, no self-referencing "clubId"
--   - refresh_tokens  : no "clubId" column, isolated via user_id FK
--   - _prisma_migrations : Prisma internal table
--
-- Special handling:
--   - audit_logs      : "clubId" is NULLABLE (platform-level events have
--                        NULL "clubId"), so the policy allows rows where
--                        "clubId" IS NULL or matches the current tenant.
-- ============================================================================

-- ---------------------------------------------------------------------------
-- 1. users
-- ---------------------------------------------------------------------------
ALTER TABLE users ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_users ON users
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_users ON users
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 2. api_keys
-- ---------------------------------------------------------------------------
ALTER TABLE api_keys ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_api_keys ON api_keys
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_api_keys ON api_keys
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 3. departments
-- ---------------------------------------------------------------------------
ALTER TABLE departments ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_departments ON departments
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_departments ON departments
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 4. rooms
-- ---------------------------------------------------------------------------
ALTER TABLE rooms ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_rooms ON rooms
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_rooms ON rooms
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 5. services
-- ---------------------------------------------------------------------------
ALTER TABLE services ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_services ON services
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_services ON services
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 6. service_categories
-- ---------------------------------------------------------------------------
ALTER TABLE service_categories ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_service_categories ON service_categories
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_service_categories ON service_categories
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 7. packages
-- ---------------------------------------------------------------------------
ALTER TABLE packages ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_packages ON packages
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_packages ON packages
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 8. clients
-- ---------------------------------------------------------------------------
ALTER TABLE clients ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_clients ON clients
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_clients ON clients
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 9. client_memberships
-- ---------------------------------------------------------------------------
ALTER TABLE client_memberships ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_client_memberships ON client_memberships
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_client_memberships ON client_memberships
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 10. client_goals
-- ---------------------------------------------------------------------------
ALTER TABLE client_goals ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_client_goals ON client_goals
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_client_goals ON client_goals
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 11. client_injuries
-- ---------------------------------------------------------------------------
ALTER TABLE client_injuries ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_client_injuries ON client_injuries
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_client_injuries ON client_injuries
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 12. client_services
-- ---------------------------------------------------------------------------
ALTER TABLE client_services ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_client_services ON client_services
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_client_services ON client_services
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 13. trainings
-- ---------------------------------------------------------------------------
ALTER TABLE trainings ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_trainings ON trainings
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_trainings ON trainings
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 14. funnel_entries
-- ---------------------------------------------------------------------------
ALTER TABLE funnel_entries ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_funnel_entries ON funnel_entries
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_funnel_entries ON funnel_entries
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 15. sales
-- ---------------------------------------------------------------------------
ALTER TABLE sales ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_sales ON sales
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_sales ON sales
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 16. work_schedules
-- ---------------------------------------------------------------------------
ALTER TABLE work_schedules ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_work_schedules ON work_schedules
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_work_schedules ON work_schedules
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 17. sip_calls
-- ---------------------------------------------------------------------------
ALTER TABLE sip_calls ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_sip_calls ON sip_calls
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_sip_calls ON sip_calls
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 18. sip_configs
-- ---------------------------------------------------------------------------
ALTER TABLE sip_configs ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_sip_configs ON sip_configs
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_sip_configs ON sip_configs
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 19. sip_accounts
-- ---------------------------------------------------------------------------
ALTER TABLE sip_accounts ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_sip_accounts ON sip_accounts
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_sip_accounts ON sip_accounts
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 20. notifications
-- ---------------------------------------------------------------------------
ALTER TABLE notifications ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_notifications ON notifications
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_notifications ON notifications
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 21. push_tokens
-- ---------------------------------------------------------------------------
ALTER TABLE push_tokens ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_push_tokens ON push_tokens
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_push_tokens ON push_tokens
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 22. webhook_subscriptions
-- ---------------------------------------------------------------------------
ALTER TABLE webhook_subscriptions ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_webhook_subscriptions ON webhook_subscriptions
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_webhook_subscriptions ON webhook_subscriptions
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 23. webhook_logs
-- ---------------------------------------------------------------------------
ALTER TABLE webhook_logs ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_webhook_logs ON webhook_logs
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_webhook_logs ON webhook_logs
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 24. club_modules
-- ---------------------------------------------------------------------------
ALTER TABLE club_modules ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_club_modules ON club_modules
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_club_modules ON club_modules
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 25. licenses
-- ---------------------------------------------------------------------------
ALTER TABLE licenses ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_licenses ON licenses
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_licenses ON licenses
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 26. usage_records
-- ---------------------------------------------------------------------------
ALTER TABLE usage_records ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_usage_records ON usage_records
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_usage_records ON usage_records
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 27. integration_configs
-- ---------------------------------------------------------------------------
ALTER TABLE integration_configs ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_integration_configs ON integration_configs
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_integration_configs ON integration_configs
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 28. sync_logs
-- ---------------------------------------------------------------------------
ALTER TABLE sync_logs ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_sync_logs ON sync_logs
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_sync_logs ON sync_logs
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 29. notification_settings
-- ---------------------------------------------------------------------------
ALTER TABLE notification_settings ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_notification_settings ON notification_settings
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_notification_settings ON notification_settings
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 30. reports
-- ---------------------------------------------------------------------------
ALTER TABLE reports ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_reports ON reports
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_reports ON reports
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 31. rating_periods
-- ---------------------------------------------------------------------------
ALTER TABLE rating_periods ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_rating_periods ON rating_periods
  USING ("clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_rating_periods ON rating_periods
  FOR INSERT
  WITH CHECK ("clubId" = current_setting('app.club_id', true));

-- ---------------------------------------------------------------------------
-- 32. audit_logs (SPECIAL: "clubId" is NULLABLE)
-- Platform-level events (super admin actions, system events) have NULL
-- "clubId". These must remain visible when no tenant context is set.
-- Club-scoped events are filtered normally.
-- ---------------------------------------------------------------------------
ALTER TABLE audit_logs ENABLE ROW LEVEL SECURITY;

CREATE POLICY club_isolation_audit_logs ON audit_logs
  USING ("clubId" IS NULL OR "clubId" = current_setting('app.club_id', true));

CREATE POLICY club_insert_audit_logs ON audit_logs
  FOR INSERT
  WITH CHECK (true);

-- ---------------------------------------------------------------------------
-- EXCLUDED TABLES (no RLS):
--   - clubs            : top-level tenant entity, no "clubId" self-reference
--   - refresh_tokens   : no "clubId" column, isolated through user_id FK
-- ---------------------------------------------------------------------------
