CREATE OR REPLACE FUNCTION public.create_private_thread( participant_suuid TEXT ) RETURNS UUID AS $$ DECLARE current_user_uuid UUID; current_user_suuid TEXT; target_user_uuid UUID; new_thread_id UUID; existing_thread_id UUID; BEGIN -- Get current user's UUID and SUUID SELECT uuid, suuid INTO STRICT current_user_uuid, current_user_suuid FROM public.users WHERE uuid = auth.uid(); -- Get target user's UUID SELECT uuid INTO STRICT target_user_uuid FROM public.users WHERE suuid = participant_suuid; -- Check if thread already exists between these users SELECT tp1.thread_id INTO existing_thread_id FROM thread_participants tp1 JOIN thread_participants tp2 ON tp1.thread_id = tp2.thread_id WHERE tp1.user_uuid = current_user_uuid AND tp2.user_uuid = target_user_uuid AND ( SELECT COUNT(*) FROM thread_participants tp3 WHERE tp3.thread_id = tp1.thread_id ) = 2; -- If thread exists, return it IF existing_thread_id IS NOT NULL THEN RETURN existing_thread_id; END IF; -- Create new thread INSERT INTO message_threads DEFAULT VALUES RETURNING id INTO new_thread_id; -- Add participants INSERT INTO thread_participants (thread_id, user_uuid) VALUES (new_thread_id, current_user_uuid), (new_thread_id, target_user_uuid); -- Update users with both requests array and a timestamp update to force change detection UPDATE users SET requests = array_remove(COALESCE(requests, ARRAY[]::text[]), participant_suuid), created_at = created_at -- This forces a row update WHERE uuid = current_user_uuid; UPDATE users SET requests = array_remove(COALESCE(requests, ARRAY[]::text[]), current_user_suuid), created_at = created_at -- This forces a row update WHERE uuid = target_user_uuid; RETURN new_thread_id; END; $$ LANGUAGE plpgsql SECURITY DEFINER;