Users & presence
The durable user key is the Rotur account ID. The server refreshes the stored username and last_login during authentication, but public objects expose usernames rather than internal IDs.
A user can have several WebSocket connections. user_connect is emitted when the first becomes active; user_disconnect only when the last closes. A first-ever authentication also emits user_join. Presence supports online, idle, dnd, offline, and invisible, plus up to 100 characters of status text.
Public users contain username, roles, calculated role color, optional nickname, and viewer-filtered status. Banned users are excluded from ordinary lists. Leaving can optionally remove authored messages; banning retains the account record with a banned role so future authentication is denied.
Presence changes are broadcast with cmd: "status_get"; there is no status_update event. Switching to or from invisible also produces the corresponding connect/disconnect visibility behavior for viewers.
See connection lifecycle and user commands.
