-- Update the can_view_profile_field function to handle all the new privacy settings CREATE OR REPLACE FUNCTION public.can_view_profile_field(_viewer_id uuid, _profile_user_id uuid, _field_name text) RETURNS boolean LANGUAGE plpgsql STABLE SECURITY DEFINER SET search_path = 'public' AS $$ DECLARE profile_privacy_level text; user_privacy_settings jsonb; BEGIN -- Allow users to view their own profile fields IF _viewer_id = _profile_user_id THEN RETURN true; END IF; -- Allow moderators/admins to view all profile fields IF is_moderator(_viewer_id) THEN RETURN true; END IF; -- Get profile privacy level SELECT privacy_level INTO profile_privacy_level FROM public.profiles WHERE user_id = _profile_user_id; -- If profile is private, deny access to all fields except basic info IF profile_privacy_level = 'private' THEN -- Only allow basic public info for private profiles RETURN _field_name IN ('username', 'display_name'); END IF; -- For public profiles, check granular privacy settings SELECT privacy_settings INTO user_privacy_settings FROM public.user_preferences WHERE user_id = _profile_user_id; -- If no privacy settings found, apply conservative defaults IF user_privacy_settings IS NULL THEN -- Only allow basic safe fields RETURN _field_name IN ('username', 'display_name', 'bio', 'avatar_url', 'show_pronouns', 'preferred_pronouns'); END IF; -- Check specific field permissions based on privacy settings CASE _field_name -- Age/birth date fields WHEN 'date_of_birth' THEN RETURN COALESCE((user_privacy_settings->>'show_age')::boolean, false); -- Location fields WHEN 'personal_location' THEN RETURN COALESCE((user_privacy_settings->>'show_location')::boolean, false); WHEN 'location_id' THEN RETURN COALESCE((user_privacy_settings->>'show_location')::boolean, false); -- Avatar fields WHEN 'avatar_url', 'avatar_image_id' THEN RETURN COALESCE((user_privacy_settings->>'show_avatar')::boolean, true); -- Bio field WHEN 'bio' THEN RETURN COALESCE((user_privacy_settings->>'show_bio')::boolean, true); -- Home park field WHEN 'home_park_id' THEN RETURN COALESCE((user_privacy_settings->>'show_home_park')::boolean, false); -- Activity statistics fields WHEN 'ride_count', 'coaster_count', 'park_count', 'review_count', 'reputation_score' THEN RETURN COALESCE((user_privacy_settings->>'show_activity_stats')::boolean, true); -- Always allow these basic fields for public profiles WHEN 'username', 'display_name' THEN RETURN true; -- Respect show_pronouns setting on the profile WHEN 'preferred_pronouns' THEN RETURN COALESCE((SELECT show_pronouns FROM public.profiles WHERE user_id = _profile_user_id), false); -- Allow these safe metadata fields by default WHEN 'timezone', 'preferred_language', 'theme_preference', 'privacy_level', 'show_pronouns', 'created_at', 'updated_at' THEN RETURN true; -- Deny access to other sensitive fields by default ELSE RETURN false; END CASE; END; $$;