Starting Postgres 18…
Query
select u.id, u.name,
  -- every post, as an array
  (
    select coalesce(jsonb_agg(jsonb_build_object(
      'id', p.id,
      'title', p.title
    ) order by p.id), '[]')
    from posts p
    where p.user_id = u.id
  ) as posts,
  -- the latest post, or null
  (
    select jsonb_build_object('id', p.id, 'title', p.title)
    from posts p
    where p.user_id = u.id
    order by p.published_at desc nulls last
    limit 1
  ) as latest_post
from users u