CREATE OR REPLACE FUNCTION public.get_user_threads(user_id UUID) RETURNS TABLE ( thread_id UUID, participants TEXT[], messages JSON[] ) AS $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM public.thread_participants WHERE user_uuid = user_id ) THEN -- Return empty result if user has no threads RETURN; END IF; RETURN QUERY SELECT mt.id, array_agg(DISTINCT u.username), COALESCE(array_agg( CASE WHEN m.id IS NOT NULL THEN 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 ) ELSE NULL END ) FILTER (WHERE m.id IS NOT NULL), ARRAY[]::JSON[]) 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 LEFT JOIN public.messages m ON mt.id = m.thread_id WHERE mt.id IN ( SELECT tp2.thread_id FROM public.thread_participants tp2 WHERE tp2.user_uuid = user_id ) GROUP BY mt.id; END; $$ LANGUAGE plpgsql SECURITY DEFINER;