Remove the legacy TEXT role column ('owner'/'admin'/'member') from
server_members and make the bitwise RBAC member_roles junction table
the sole authority for role assignments. Owner detection now uses
servers.ownerId exclusively.
- Remove MemberRole type and role field from shared types
- Remove role from Drizzle schema, raw SQL CREATE TABLE, and seed data
- Rewrite PATCH /members/:uid to accept { roleIds: string[] }
- Fix GET /members to populate roles array (was TODO)
- Replace member.role === 'owner' guard with isServerOwner()
- Remove getMemberRole() helper and legacy bridge code
- MemberSidebar groups by highest-positioned role instead of legacy string
- ServerSettings replaces admin/member dropdown with role checkboxes
- Message.tsx derives color from roles[] with owner fallback via ownerId
- Existing DBs keep vestigial column (Drizzle ignores it); new DBs omit it
Replace string-based role checks (role === 'admin') with a bitwise BigInt
permission system. Adds computePermissions() resolution engine following
Discord's model: @everyone base → role union → admin shortcut → channel
overrides (role deny/allow → member deny/allow). Ready payload now filters
channels by VIEW_CHANNEL and attaches per-user myPermissions to each
server and channel. Includes channel_overrides table, @everyone role
auto-creation, migration for existing servers, and override CRUD API.
- Fix stale message cache: add force param to loadMessages, clearAllMessages action
- Fix reload race condition: URL-based isDmChannel fallback before WS ready
- Add read_states DB table for persistent unread tracking
- Add channel_ack WS event (client→server→echo) with BigInt comparison
- Wire up unread state in chatStore (readStates, unreadChannels, ackChannel)
- Auto-ack channels on MessageList view (200ms debounced)
- Unread pill indicators on server icons in ServerSidebar
- Bold text + white dot on unread channels/DMs in ChannelSidebar
- Replace all showDms reads with data-driven isDmChannel() across 8 files
- Design system, UI polish, and component fixes from previous sessions