- Split Server/admin/api.go (788→281 lines) into handlers_users.go,
handlers_channels.go, handlers_settings.go, handlers_backup.go
- Split Client SettingsOverlay.ts (~685→173 lines) into 7 per-tab
modules under components/settings/
- Add queueMicrotask-based notification batching to createStore with
flush() for synchronous test assertions
- Update 8 test files with flush() calls for batched store updates
Addresses TODOS.md #9 (split oversized files) for 2 of 3 targets.
Server fixes:
- Move ATTACH_FILES permission check before CreateMessage to prevent
orphaned messages on permission denial
- Fix hardcoded /api/files/ URL to /api/v1/files/ per spec
- Add error logging for GetAttachmentsByMessageIDs failure
- Set 1MB WebSocket read limit to match client-side limit
- Extract requireChannelPerm helper, replacing 8 repeated patterns
Client fixes:
- Wire onUnauthorized callback to clear auth on 401 responses
- Store auth token in authStore before WS connect
- Reset WS state to disconnected when Tauri APIs unavailable
- Add connectivity guard and 200ms send debounce on message send
- Add toast container to MainPage with error feedback on 5 API failures
- Clear voice currentChannelId on server-driven voice_leave for current user
- Apply stored theme/font/compact preferences at app startup
- Fix infinite scroll throttle to use store subscription instead of fixed timer
Tests:
- Add TestChatSend_AttachmentsDeniedNoMessageCreated
- Add attachments table to handler test schema
- Fix CSS classes across 8 components to match ui-mockup.html
(ReactionBar, VoiceChannel, EmojiPicker, DmSidebar, Toast,
ServerBanner, MessageActionsBar, MessageList)
- Rewrite MainPage to compose standalone components instead of
inline builders, with reactive channel switching
- Wire all outbound WS handlers: chat send/edit/delete, typing,
reactions, voice mute/deafen/disconnect
- Wire REST message loading with infinite scroll and abort on
channel switch
- Wire reconnect banner to WS state and server_restart events
- Add reaction_update, chat_send_ok, member_ban, voice_config,
voice_speakers dispatcher handlers
- Add updateReaction action in messages store
- Fix MessageList double-render bug when no code blocks present
- Fix membersStore subscription to skip re-render on typing events
- Add scroll-top debounce to prevent duplicate API calls
- Replace dead More button with functional Delete button
- Clear unread count on channel switch in channels store
- Add midnight theme, connectionStatus, error fields to UI store
- Add voiceConfigs state and setSpeakers action to voice store
- Update tests: 369 passing across 21 test files
Root cause: server's db.Role and db.VoiceState structs had no JSON tags,
causing Go to serialize field names as PascalCase while the C# client
expected snake_case. Every role deserialized with Id=0, crashing
ToDictionary with "duplicate key: 0".
- Add json tags to Role and VoiceState in Server/db/models.go
- Change Disconnected event to carry reason string for diagnostics
- Wire ErrorReceived in MainViewModel to show server-side WS errors
- Fix MainWindow to surface WebSocket errors on MainPage (not ConnectPage)
- Use _reconnectCts.Token for receive loop instead of caller's token
- Make ToDictionary calls safe with TryAdd to prevent future crashes
- Replace 5x ToList().FindIndex() with direct for-loops in MainViewModel
- UpdateUnreadCount now updates ChannelGroup in-place instead of full rebuild
- Remove redundant RebuildChannelGroups() call in OnReady
- Freeze all SolidColorBrush instances in converters for thread safety
- EmojiPicker search shows empty state instead of fallback to all categories
- MainViewModel implements IDisposable for _typingTimer cleanup
- ApiMessage.Username changed to string? to match server reality
- Redesign ConnectPage with modern dark theme, profile cards with delete buttons, login/register toggle
- Add DPAPI-encrypted password saving with "Remember my password" checkbox
- Fix permission bit constants to match SCHEMA.md (Member role 0x663)
- Add migration 004 to fix existing Member role permissions
- Add comprehensive audit logging across all server packages (auth, admin, ws, setup)
- Add member_join WebSocket broadcast so new users appear in members list in real-time
- Add host URL normalization (strip scheme prefix) for reverse proxy compatibility
- Add REST API client, ChatService orchestrator, WebSocket service with reconnection
- Add model types (WsEnvelope payloads, API responses), converters, tests