Commit Graph

8219 Commits

Author SHA1 Message Date
Nuwan 538cdd0239 docs(09-01): complete message composer UI & validation plan
Tasks completed: 3/3
- Create JKChatComposer component with textarea and send button
- Add keyboard handling for Enter and Shift+Enter
- Add character count validation feedback

SUMMARY: .planning/phases/09-message-composition/09-01-SUMMARY.md
2026-01-27 15:23:48 +05:30
Nuwan d4fc7005d8 feat(09-01): create JKChatComposer with validation and keyboard handling
- Controlled textarea for message input (1-255 chars after trim)
- Character count display (X/255) with color-coded feedback
- Enter to send, Shift+Enter for newline
- Disabled states: disconnected, sending, invalid input
- Validation messages for error states
- Error display for send failures
- React.memo and useCallback optimizations

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 15:21:21 +05:30
Nuwan 619e37f505 docs(09): create phase plan for message composition
Phase 9: Message Composition & Sending
- 2 plans created
- 6 total tasks defined
- Ready for execution

Plan 09-01: Message Composer UI & Validation (3 tasks)
- Create JKChatComposer component
- Add keyboard handling (Enter/Shift+Enter)
- Add character count validation

Plan 09-02: Send Message Integration & Real-Time Delivery (3 tasks)
- Integrate composer into chat window
- Write send message integration tests
- Write receive message integration tests
2026-01-27 15:14:32 +05:30
Nuwan c4acebcdeb docs(08-03): complete chat button & unread badge plan
Tasks completed: 3/4
- Create JKSessionChatButton component
- Integrate into JKSessionScreen navigation
- Write integration tests (7 tests)
- SCSS styling (skipped - optional)

SUMMARY: .planning/phases/08-chat-window-ui/08-03-SUMMARY.md

Phase 8 complete - Chat Window UI fully functional
2026-01-27 14:23:00 +05:30
Nuwan 9fd506695d test(08-03): add integration tests for chat button
- Test button visibility in session navigation
- Test badge hidden when unread count = 0
- Test badge shows correct count (1-99)
- Test badge shows "99+" for counts >= 100
- Test button opens chat window
- Test duplicate window prevention
- Test badge resets when window opens
- 7 comprehensive test cases
2026-01-27 14:20:52 +05:30
Nuwan b6e31b3bc2 feat(08-03): integrate chat button into session navigation
- Added JKSessionChatButton import
- Replaced placeholder Chat button with new component
- Passes sessionId prop from Redux state
- Button positioned after Open menu, before Attach button
2026-01-27 14:20:09 +05:30
Nuwan 1230448d96 feat(08-03): create JKSessionChatButton with unread badge
- Displays chat icon from assets
- Badge shows unread count (1-99) or "99+" for 100+
- Badge hidden when count = 0
- Reduced opacity when window already open
- Click handler opens chat window and sets active channel
- useCallback for handleClick optimization
2026-01-27 14:19:25 +05:30
Nuwan 6b687315ce docs(08-02): complete message list & auto-scroll plan
Update project documentation after completing Plan 08-02:

SUMMARY.md:
- Created 8 new files (utilities, components, tests)
- Modified 2 files (JKSessionChatWindow, package.json)
- 77 chat-related tests passing
- Auto-scroll logic validated with TDD
- Ready for Plan 08-03 (Chat Button & Unread Badge)

STATE.md:
- Update current position: Plan 08-02 complete, ready for 08-03
- Progress: 60% (Phase 8: 2/3 plans complete)
- Add accumulated context from Phase 8 Plan 2
- Document timestamp formatting patterns
- Document auto-scroll behavior and state machine
- Note testing library installation (@testing-library/react@12)

ROADMAP.md:
- Mark Plan 08-02 as complete (2026-01-27)
- Update Phase 8 progress: 2/3 plans complete

Total commits for Plan 08-02: 8 commits
- Task 1 (formatTimestamp TDD): 2 commits (RED + GREEN)
- Task 2 (JKChatMessage): 1 commit
- Task 3 (loading/empty states): 1 commit
- Task 4 (JKChatMessageList TDD): 2 commits (RED + GREEN)
- Task 5 (integration): 1 commit
- Metadata: 1 commit (this)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:09:37 +05:30
Nuwan 6df9356b61 feat(08-02): integrate message list into chat window
Replace placeholder content with JKChatMessageList component:
- Import JKChatMessageList
- Remove placeholder div with text
- JKChatMessageList handles its own styling (flex: 1, padding, scroll)
- Update component documentation

Chat window now displays:
- Header with channel name and close button (fixed top)
- Message list with auto-scroll (scrollable, flex: 1)
- Loading spinner when fetching history
- Empty state when no messages
- Individual messages with avatars and timestamps

Layout follows flexbox pattern with header fixed and message list
filling remaining space with independent scrolling.

Ready for Plan 8.3 (Chat Button & Unread Badge).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:07:42 +05:30
Nuwan 07779a9fa8 feat(08-02): implement JKChatMessageList with auto-scroll
GREEN phase: Create message list component with:
- Redux integration (activeChannel, messages, fetchStatus selectors)
- Auto-scroll logic with scroll state management
- Scroll to bottom on mount and new messages
- Disable auto-scroll when user scrolls up
- Re-enable auto-scroll when user scrolls to bottom (50px threshold)
- 300ms debounce for scroll detection
- Loading state (JKChatLoadingSpinner)
- Empty state (JKChatEmptyState)
- Message rendering (JKChatMessage components)

Auto-scroll behavior:
- isUserScrolling state tracks manual scrolling
- scrollToBottom helper with smooth scrolling
- isAtBottom detects bottom position (50px threshold)
- handleScroll debounces scroll events (300ms)
- Cleanup timeout on unmount prevents memory leaks

Mock Element.prototype.scrollTo in tests (not available in JSDOM).

All 3 tests passing:
- Empty state display
- Loading spinner display
- Message rendering

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:07:12 +05:30
Nuwan 41e6a82c5d test(08-02): add failing tests for JKChatMessageList
RED phase: Create test file with 3 test cases:
- Shows empty state when no messages
- Shows loading spinner when fetching
- Renders messages when available

Install @testing-library/react@12 and @testing-library/jest-dom@5
(compatible with React 16).

Create setupTests.js for jest-dom matchers.

Tests fail as expected (component not implemented yet).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:06:19 +05:30
Nuwan 2056629a04 feat(08-02): create loading and empty state components
Create two stateless components for chat UI states:

1. JKChatLoadingSpinner:
   - Displays spinner from reactstrap
   - Shows "Loading messages..." text
   - Used when fetchStatus is 'loading'

2. JKChatEmptyState:
   - Shows chat icon and encouraging message
   - Used when message list is empty
   - Centered layout with friendly copy

Both components are simple, stateless, and require no props.
Inline styles used for MVP (SCSS styling deferred to Plan 8.3).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:05:06 +05:30
Nuwan a78d2bc52f feat(08-02): create JKChatMessage component
Create individual message display component with:
- Avatar with initials (first + last name initial)
- Sender name in bold
- Relative timestamp using formatTimestamp utility
- Message text with word wrapping
- Inline styles for MVP (SCSS styling deferred to Plan 8.3)
- React.memo for performance optimization
- PropTypes validation

Component follows established React patterns with functional components,
hooks, and proper documentation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:04:45 +05:30
Nuwan 7264fcb8ee feat(08-02): implement formatTimestamp utility
GREEN phase: Implement timestamp formatting with dayjs:
- Returns "Just now" for messages < 1 minute old
- Returns "X minutes ago" for messages < 1 hour old
- Returns "X hours ago" for messages < 24 hours old
- Returns "Yesterday" for messages 1 day old
- Returns day name (e.g., "Monday") for messages < 7 days old
- Returns MM/DD/YYYY format for older messages
- Handles invalid input gracefully (returns empty string)

All 6 tests passing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:04:21 +05:30
Nuwan b4fe7aaaa0 test(08-02): add failing test for formatTimestamp utility
RED phase: Create test file with 6 test cases for timestamp formatting:
- "Just now" for messages within last minute
- "X minutes ago" for messages within last hour
- "X hours ago" for messages within last day
- "Yesterday" for previous day messages
- Date format (MM/DD/YYYY) for older messages
- Graceful handling of invalid dates

Install dayjs for timestamp formatting utility.

Tests fail as expected (utility not implemented yet).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:04:09 +05:30
Nuwan 03e85e6356 fix(08-01): move createSelector import to top of module
- Fixed ESLint import/first error on line 317
- Moved createSelector import to top with other @reduxjs/toolkit imports
- Blocking issue preventing dev server startup
2026-01-27 13:52:09 +05:30
Nuwan aafc5a26b9 docs(08-01): complete chat window shell plan
- Add 08-01-SUMMARY.md with accomplishments and metrics
- Update STATE.md: Phase 8 progress to 1/3 plans complete
- Update ROADMAP.md: Mark plan 08-01 complete
- Ready for Plan 08-02 (Message List & Auto-Scroll)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 13:39:03 +05:30
Nuwan 2c5d39d331 test(08-01): add integration tests for chat window open/close
- Expose Redux store for testing (dev/test environments only)
- Add 3 tests: window open, window close, placeholder message
- Tests verify WindowPortal integration and Redux state updates

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 13:37:31 +05:30
Nuwan 738b15da12 feat(08-01): integrate chat window with JKSessionScreen
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 13:36:32 +05:30
Nuwan c21aaef063 feat(08-01): create JKSessionChatWindow with WindowPortal integration
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 13:36:07 +05:30
Nuwan 33f9a357bd feat(08-01): create JKChatHeader component with close button
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 13:35:43 +05:30
Nuwan f8a3a7bb84 chore: create Phase 8 plans (Chat Window UI & Message Display)
- Plan 8.1: Chat Window Shell & WindowPortal Integration (4 tasks)
- Plan 8.2: Message List & Auto-Scroll (5 tasks, mixed TDD)
- Plan 8.3: Chat Button & Unread Badge (3-4 tasks)

Total: 3 plans, ~12 tasks for Phase 8
Updated ROADMAP.md and STATE.md with Phase 8 breakdown
2026-01-27 12:56:33 +05:30
Nuwan 9be85da11a docs(07-03): complete websocket integration and selectors plan
Summary:
- Added CHAT_MESSAGE WebSocket handler with message transformation
- Implemented 8 memoized selectors using Reselect
- Created localStorage utilities with error handling
- 90 total tests passing (14 WebSocket, 68 Redux/selectors, 8 localStorage)
- 9 commits following strict TDD RED-GREEN-REFACTOR methodology

Metadata Updates:
- Created 07-03-SUMMARY.md with decisions and test coverage details
- Updated STATE.md: Phase 7 complete (3/3 plans), progress 50%
- Updated ROADMAP.md: Phase 7 marked complete, ready for Phase 8

Phase 7 Status: Complete
Next: Phase 8 (Chat Window UI & Message Display)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:47:30 +05:30
Nuwan 8b312dafb7 refactor(07-03): enhance chatStorage documentation
- Add storage format example (JSON structure)
- Document error handling strategy (graceful degradation)
- Explain quota exceeded and parse error behaviors
- All 8 localStorage tests still passing after refactoring

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:45:54 +05:30
Nuwan 3cdeae691f feat(07-03): integrate localStorage with Redux slice
- Import saveLastReadAt and loadLastReadAt utilities
- Load lastReadAt from localStorage on Redux store initialization
- Save to localStorage when openChatWindow action is dispatched
- Save to localStorage when markAsRead action is dispatched
- All 68 Redux tests still passing after integration
- All 8 localStorage tests passing

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:45:33 +05:30
Nuwan 33deac659b feat(07-03): implement localStorage utilities for lastReadAt
- Add saveLastReadAt: saves timestamp with merge support
- Add loadLastReadAt: loads all timestamps with parse error handling
- Add clearLastReadAt: clears specific channel or all channels
- All functions handle localStorage errors gracefully (quota, parse errors)
- Storage key: 'jk_chat_lastReadAt'
- All 8 tests passing (GREEN phase)

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:44:52 +05:30
Nuwan f2bd7c6501 test(07-03): add failing tests for localStorage utilities
- Add 3 tests for saveLastReadAt (save, merge, error handling)
- Add 3 tests for loadLastReadAt (load, empty state, parse errors)
- Add 2 tests for clearLastReadAt (clear specific, clear all)
- All 8 tests failing (RED phase) - utilities not yet implemented

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:44:29 +05:30
Nuwan 4d166f7d39 refactor(07-03): enhance JSDoc comments for memoized selectors
- Add comprehensive JSDoc with usage descriptions for all 8 selectors
- Document memoization behavior (when selectors recompute)
- Add @private tags to input selectors
- Document return value types and defaults (empty arrays, 0, idle states)
- Clarify channel ID parameter (session ID, lesson ID, or 'global')
- All 68 tests still passing after refactoring

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:43:45 +05:30
Nuwan 306e2637ad feat(07-03): implement 8 memoized selectors with Reselect
- Add selectChatMessages: returns messages for channel with memoization
- Add selectUnreadCount: returns unread count for channel
- Add selectTotalUnreadCount: sums all unread counts across channels
- Add selectIsChatWindowOpen: returns window open state
- Add selectActiveChannel: returns active channel ID
- Add selectFetchStatus: returns fetch status for channel
- Add selectSendStatus: returns send status
- Add selectSendError: returns send error message
- All selectors use createSelector from Redux Toolkit for memoization
- All 68 tests passing (GREEN phase), including 15 selector tests

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:43:03 +05:30
Nuwan 555adcf100 test(07-03): add failing tests for 8 memoized selectors
- Add test structure for selectChatMessages, selectUnreadCount, selectTotalUnreadCount
- Add test structure for selectIsChatWindowOpen, selectActiveChannel
- Add test structure for selectFetchStatus, selectSendStatus, selectSendError
- All 8 tests failing (RED phase) - selectors not yet implemented
- Mock state with multi-channel messages and unread counts

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:42:09 +05:30
Nuwan 7a05f6e453 refactor(07-03): add JSDoc comments to CHAT_MESSAGE handler
- Add comprehensive JSDoc to getChannelKeyFromMessage helper
- Document channel key mapping logic (session, lesson, global)
- Add JSDoc to CHAT_MESSAGE handler with unread increment rules
- Extract shouldIncrementUnread for clarity
- All tests still passing after refactoring

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:41:27 +05:30
Nuwan 6c712bba57 feat(07-03): implement CHAT_MESSAGE WebSocket handler
- Add CHAT_MESSAGE handler to useSessionWebSocket callbacks
- Transform Protocol Buffer format (msg_id, user_id, etc.) to Redux format
- Construct channel keys: session uses sessionId, lesson uses lessonSessionId, global uses 'global'
- Implement unread increment logic: increment if window closed OR viewing different channel
- Use useSelector to access chat state for unread count logic
- Extract getChannelKeyFromMessage helper function for reusability
- All 14 tests passing (GREEN phase)

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:40:55 +05:30
Nuwan 4a5dd4b787 test(07-03): add failing tests for CHAT_MESSAGE WebSocket handler
- Add 15 tests for message transformation from Protocol Buffer to Redux format
- Test channel key construction for session, lesson, and global messages
- Test unread count increment logic based on window state
- Test WebSocket integration (register/unregister, dispatch actions)
- All tests failing (RED phase) - handler not yet implemented

Part of Phase 7 Plan 3 (WebSocket Integration & Selectors)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 12:38:36 +05:30
Nuwan 8fac2465a6 docs(07-02): complete async thunks and api integration plan
Phase 7 Plan 2 Summary:
- Implemented getChatMessages and sendChatMessage REST API methods
- Created fetchChatHistory async thunk with message deduplication
- Created sendMessage async thunk with optimistic UI updates
- Extracted createOptimisticMessage helper function
- 67 total tests passing (14 REST API, 53 Redux slice)
- 100% test coverage for all async operations
- Followed strict TDD methodology (RED-GREEN-REFACTOR)
- 7 commits: 3 RED phases, 3 GREEN phases, 1 REFACTOR phase

Updated metadata:
- STATE.md: Phase 7 progress 2/3 plans, 40% v1.1 milestone
- ROADMAP.md: Marked 07-02 complete
- Created 07-02-SUMMARY.md with complete accomplishments

Ready for Plan 07-03 (WebSocket Integration & Selectors).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:20:11 +05:30
Nuwan 2862e87bc6 refactor(07-02): extract optimistic message creation helper
Extract createOptimisticMessage helper function:
- Improves code clarity and maintainability
- Centralizes optimistic message structure
- Makes testing easier if needed in future
- All tests still passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:18:11 +05:30
Nuwan 7729f2767c feat(07-02): implement sendMessage async thunk with optimistic updates
Add sendMessage async thunk with complete optimistic UI flow:
- pending: Adds optimistic message immediately with temp ID
- fulfilled: Replaces optimistic message with real server response
- rejected: Removes optimistic message and sets error
- Optimistic messages marked with isOptimistic flag
- Channel initialization if not exists
- Preserves existing messages during replace/remove operations

All 53 unit tests passing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:17:45 +05:30
Nuwan 5d3b6d42e4 test(07-02): add failing tests for sendMessage async thunk with optimistic updates
Add unit tests for sendMessage optimistic UI flow:
- Test pending sets loading status
- Test pending adds optimistic message immediately
- Test pending initializes channel if needed
- Test fulfilled replaces optimistic message with real one
- Test rejected removes optimistic message
- Test other messages preserved during replace/remove

Tests fail as expected - async thunk not yet implemented.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:17:12 +05:30
Nuwan 4f5339d7eb feat(07-02): implement fetchChatHistory async thunk with extra reducers
Add fetchChatHistory async thunk with complete lifecycle handling:
- pending: Sets loading status and clears errors
- fulfilled: Adds messages with deduplication and sorting
- rejected: Sets error status with error message
- Message deduplication by ID to prevent duplicates
- Chronological sorting (createdAt ASC) after prepending
- Pagination cursor storage in nextCursors state
- Handles both session and global channels

All 46 unit tests passing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:16:26 +05:30
Nuwan b0b4ae1a53 test(07-02): add failing tests for fetchChatHistory async thunk
Add unit tests for fetchChatHistory extra reducers:
- Test pending state sets loading status
- Test fulfilled state adds messages and updates status
- Test message deduplication on fulfilled
- Test pagination: prepending older messages
- Test rejected state sets error
- Test null cursor handling

Tests fail as expected - async thunk not yet implemented.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:15:38 +05:30
Nuwan 95483da6fe feat(07-02): implement REST API chat methods getChatMessages and sendChatMessage
Implement chat API methods using native fetch:
- getChatMessages: Fetch messages with pagination support
- sendChatMessage: Send messages to session/global channels
- URL construction with URLSearchParams for clean query strings
- Error handling for all HTTP status codes
- Credentials and headers included for session auth
- JSDoc comments for API documentation

All 14 unit tests passing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:14:42 +05:30
Nuwan b6ce5010ac test(07-02): add failing tests for REST API chat methods
Add comprehensive unit tests for getChatMessages and sendChatMessage:
- Test session and global channel message fetching
- Test pagination cursor (before parameter)
- Test all HTTP error codes (403, 404, 422, 500)
- Test request headers and credentials
- Test error handling with invalid JSON responses

Tests fail as expected - functions not yet implemented.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:14:00 +05:30
Nuwan 08bf66cce3 docs: update roadmap - phase 7 plan 1 complete
- Mark 07-01 complete in phase breakdown
- Update progress table: 1/3 plans complete
2026-01-27 08:09:16 +05:30
Nuwan 966d44a8b5 docs(07-01): complete redux slice and core reducers plan
Phase 7 Plan 1 Summary:
- Created sessionChatSlice with 7 reducers using strict TDD methodology
- All 40 tests passing with 100% reducer coverage
- Message deduplication validated for WebSocket + REST scenario
- Multi-channel unread tracking working correctly
- 3 integration tests validate complete message flows

Commits:
- fd44d1255: Initial state tests (RED)
- e98504eba: Initial state implementation (GREEN)
- 60a559e58: Core reducer tests (RED)
- 15a658a5d: Core reducer implementation (GREEN)
- 96d7188a4: Unread tracking tests (RED)
- 7bafb3c69: Unread tracking implementation (GREEN)

Ready for Phase 7 Plan 2 (Async Thunks & API Integration).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:08:25 +05:30
Nuwan 7bafb3c697 feat(07-01): implement unread tracking reducers and complete slice
GREEN phase of TDD for Task 3:
- Implement markAsRead: resets unread count to 0, updates lastReadAt timestamp
- Implement incrementUnreadCount: safely handles missing channels
- Implement setWindowPosition: stores UI position for WindowPortal
- Export all 7 action creators from slice
- Complete sessionChatSlice with full reducer suite

All 40 tests pass including 3 integration tests:
- Complete flow validates message receiving, channel switching, window state
- Multi-channel flow validates independent unread counts per channel
- Deduplication test validates WebSocket + REST double-message scenario

Ready for async thunks in Phase 7 Plan 2.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:07:44 +05:30
Nuwan 96d7188a4c test(07-01): add failing tests for unread tracking and integration flows
RED phase of TDD for Task 3:
- Write tests for markAsRead (resets count, updates lastReadAt)
- Write tests for incrementUnreadCount (handles missing channel)
- Write tests for setWindowPosition (UI persistence)
- Write comprehensive integration tests:
  * Complete message flow: receive → set active → open → close
  * Multi-channel scenario with independent unread counts
  * Message deduplication preventing double unread increment
- Integration tests validate all 7 reducers working together

Tests fail as expected - action creators don't exist yet.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:07:35 +05:30
Nuwan 15a658a5dc feat(07-01): implement core reducers with message deduplication logic
GREEN phase of TDD for Task 2:
- Implement addMessageFromWebSocket with full logic:
  * getChannelKey helper for session vs global channel keys
  * Channel initialization on first message
  * Message deduplication by msg_id using Array.some()
  * Sort messages by createdAt after insertion
  * Unread increment: only if window closed OR viewing different channel
- Implement setActiveChannel: sets activeChannel + channelType
- Implement openChatWindow: sets isWindowOpen, resets unread count, updates lastReadAt
- Implement closeChatWindow: sets isWindowOpen false only
- Export all 4 action creators

All 28 tests pass. Message deduplication validated.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:06:21 +05:30
Nuwan 60a559e58f test(07-01): add failing tests for core reducers with message deduplication
RED phase of TDD for Task 2:
- Write tests for addMessageFromWebSocket with comprehensive scenarios:
  * Add message to new/existing channel
  * Message deduplication by msg_id (critical for WebSocket + REST)
  * Sort messages by createdAt ascending
  * Unread count increment logic (window closed OR different channel)
  * Global vs session channel handling
- Write tests for setActiveChannel (channel + channelType)
- Write tests for openChatWindow (resets unread, updates lastReadAt)
- Write tests for closeChatWindow (preserves unread counts)

Tests fail as expected - action creators don't exist yet.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:06:13 +05:30
Nuwan e98504ebad feat(07-01): implement sessionChatSlice with initial state structure
GREEN phase of TDD:
- Create sessionChatSlice.js with complete initial state
- All 12 state fields match CHAT_REDUX_DESIGN.md specification
- Multi-channel architecture: messagesByChannel keyed by channel ID
- Unread tracking: unreadCounts, lastReadAt per channel
- State machines: fetchStatus/error per channel, sendStatus/error global
- Pagination support: nextCursors per channel
- UI state: isWindowOpen, windowPosition
- Register slice in store.js as sessionChat reducer

All 13 tests pass. Ready for reducers in Task 2.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:04:51 +05:30
Nuwan fd44d1255f test(07-01): add failing tests for sessionChatSlice initial state
RED phase of TDD:
- Write tests for all 12 initial state fields
- Validates messagesByChannel, activeChannel, channelType
- Validates unread tracking: unreadCounts, lastReadAt
- Validates fetch state: fetchStatus, fetchError
- Validates send state: sendStatus, sendError
- Validates pagination: nextCursors
- Validates UI state: isWindowOpen, windowPosition

Tests fail as expected - slice doesn't exist yet.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 08:04:43 +05:30
Nuwan 9610a371da docs: update roadmap with phase 7 plan details
- Phase 6 marked complete (2/2 plans)
- Phase 7 breakdown: 3 TDD plans (Redux, API, WebSocket)
- Progress table updated
2026-01-27 08:00:43 +05:30