-- ExposedGays privacy: trait hide rules + block list (cloud sync) ALTER TABLE profiles ADD COLUMN IF NOT EXISTS height_in integer, ADD COLUMN IF NOT EXISTS weight_lb integer, ADD COLUMN IF NOT EXISTS body_type text, ADD COLUMN IF NOT EXISTS hide_from_anonymous boolean NOT NULL DEFAULT false, ADD COLUMN IF NOT EXISTS block_messages_from_anonymous boolean NOT NULL DEFAULT false, ADD COLUMN IF NOT EXISTS hide_from_no_photo boolean NOT NULL DEFAULT false, ADD COLUMN IF NOT EXISTS block_messages_from_no_photo boolean NOT NULL DEFAULT false; CREATE TABLE IF NOT EXISTS hide_from_rules ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), user_id uuid NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, label text NOT NULL DEFAULT '', height_in integer, height_tolerance_in integer DEFAULT 1, weight_lb integer, weight_tolerance_lb integer DEFAULT 10, age_min integer, age_max integer, positions text[] DEFAULT '{}', body_types text[] DEFAULT '{}', kinks text[] DEFAULT '{}', communities text[] DEFAULT '{}', created_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_hide_from_rules_user ON hide_from_rules(user_id); CREATE TABLE IF NOT EXISTS user_blocks ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), blocker_id uuid NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, blocked_id uuid NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, blocked_username text, blocked_display_name text, blocked_avatar_url text, created_at timestamptz NOT NULL DEFAULT now(), UNIQUE (blocker_id, blocked_id) ); CREATE INDEX IF NOT EXISTS idx_user_blocks_blocker ON user_blocks(blocker_id); CREATE INDEX IF NOT EXISTS idx_user_blocks_blocked ON user_blocks(blocked_id); ALTER TABLE hide_from_rules ENABLE ROW LEVEL SECURITY; ALTER TABLE user_blocks ENABLE ROW LEVEL SECURITY; CREATE POLICY hide_from_rules_own ON hide_from_rules FOR ALL USING (auth.uid() = user_id); CREATE POLICY user_blocks_own ON user_blocks FOR ALL USING (auth.uid() = blocker_id);