DM uploads silently failed because the 5-point chain (types, frontend, POST, GET, WS broadcast) was never wired for attachments. Added buildDmMessageWithUser/getDmMessageWithUser helpers mirroring the server channel pattern, and plumbed attachmentIds + replyToId through all DM code paths.