feat(06-02): design Redux state and WebSocket integration for chat

Create comprehensive Redux architecture for session chat:

Redux State Structure:
- sessionChatSlice with multi-channel message storage
- messagesByChannel keyed by channel ID (efficient lookup)
- unreadCounts per channel (NEW functionality)
- lastReadAt timestamps for read tracking
- fetchStatus/sendStatus per channel

Async Thunks (3):
- fetchChatHistory: Load message history via REST API
- sendMessage: Send new message with optimistic update
- markMessagesAsRead: Mark as read (future server-side tracking)

Reducers (7):
- addMessageFromWebSocket: Handle real-time messages, deduplicate by msg_id
- setActiveChannel: Switch between global/session/lesson
- openChatWindow: Reset unread count, mark as read
- closeChatWindow: Close window state
- markAsRead: Client-side read tracking with localStorage persistence
- incrementUnreadCount: Increment on message receive
- setWindowPosition: Save window position

Selectors (8 memoized):
- selectChatMessages, selectUnreadCount, selectTotalUnreadCount
- selectIsChatWindowOpen, selectActiveChannel
- selectFetchStatus, selectSendStatus, selectSendError

WebSocket Integration:
- CHAT_MESSAGE handler in useSessionWebSocket
- Protocol Buffer to Redux format conversion
- Unread count increment logic (if window closed)
- Message deduplication by msg_id

Read/Unread Tracking System (NEW):
- Client-side tracking with localStorage persistence
- lastReadAt timestamp per channel
- Unread count calculation on message receive
- Reset on window open / channel switch
- Server-side tracking deferred to future milestone

Error Handling:
- API errors: 404, 403, 422, 500
- WebSocket errors: Connection lost, duplicate messages
- Retry logic and user feedback

Testing Strategy:
- Unit tests: Reducers, async thunks, deduplication logic
- Integration tests: Send/receive flow, unread badge behavior

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-01-26 15:48:44 +05:30
parent 192703f592
commit 3206c12685
1 changed files with 1132 additions and 0 deletions

File diff suppressed because it is too large Load Diff