CREATE OR REPLACE FUNCTION public.get_thread(thread_uuid UUID, user_id UUID) RETURNS TABLE ( thread_id UUID, participants TEXT[], participant_suuids TEXT[], messages JSON[] ) AS $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM public.thread_participants tp WHERE tp.thread_id = thread_uuid AND tp.user_uuid = user_id ) THEN RETURN; END IF; RETURN QUERY WITH thread_info AS ( -- Get thread participants info first SELECT mt.id as tid, array_agg(DISTINCT u.username) as usernames, array_agg(DISTINCT u.suuid::TEXT) as suuids FROM public.message_threads mt JOIN public.thread_participants tp ON mt.id = tp.thread_id JOIN public.users u ON tp.user_uuid = u.uuid WHERE mt.id = thread_uuid GROUP BY mt.id ), messages_info AS ( -- Get messages separately SELECT m.thread_id, array_agg( json_build_object( 'id', m.id, 'content', CASE WHEN m.sender_uuid = user_id THEN m.sender_content ELSE m.recipient_content END, 'sender_uuid', m.sender_uuid, 'created_at', m.created_at ) ORDER BY m.created_at ASC -- Add ordering here ) FILTER (WHERE m.id IS NOT NULL) as msg_array FROM public.messages m WHERE m.thread_id = thread_uuid GROUP BY m.thread_id ) SELECT t.tid, t.usernames, t.suuids, COALESCE(m.msg_array, ARRAY[]::JSON[]) FROM thread_info t LEFT JOIN messages_info m ON t.tid = m.thread_id; END; $$ LANGUAGE plpgsql SECURITY DEFINER;