# Session Chat Implementation Roadmap (Phases 7-11)

**Purpose:** Detailed roadmap for implementing session chat feature across Phases 7-11, with plan estimates, risk analysis, and testing strategy.

**Date:** 2026-01-26
**Phase:** 06-session-chat-research-design
**Plan:** 02

---

## Overview

This roadmap breaks down Phases 7-11 into executable plans, following the pattern from Phase 4 Plan 2 (which created Phase 5 roadmap for JamTrack).

**Total Scope:**
- **5 Phases** (7-11)
- **Estimated 11-13 Plans** (subject to refinement during phase planning)
- **Complexity:** Medium (simpler than JamTrack Phase 5, similar to Backing Track Phase 3)

**Reference Points:**
- Phase 3 (Backing Track): 3 plans, 7 tasks total
- Phase 5 (JamTrack): 9 plans, ~25 tasks total
- Phase 6 (Chat): Estimated 11-13 plans, ~28-32 tasks

**Complexity Comparison:**
- Chat is **1.5-2x more complex** than Backing Track (Phase 3)
- Chat is **0.6x less complex** than JamTrack (Phase 5)
- Rationale: No native client integration (simpler), but multi-channel + unread tracking (moderately complex)

---

## Phase-by-Phase Breakdown

### Phase 7: Chat Infrastructure & State Management

**Objective:** Build Redux foundation, API integration, and WebSocket handlers.

**Estimated Plans:** 3 plans

**Preliminary Plan Breakdown:**

#### Plan 7.1: Redux Slice & Core Reducers (TDD)

**Tasks (3-4):**
1. Create `sessionChatSlice.js` with initial state structure
2. Implement standard reducers: `addMessageFromWebSocket`, `setActiveChannel`, `openChatWindow`, `closeChatWindow`, `markAsRead`, `incrementUnreadCount`
3. Write unit tests for all reducers (TDD approach)
4. Test message deduplication logic (by `msg_id`)

**Dependencies:** None (foundational)

**TDD Candidates:**
- ✅ All reducers (state transitions)
- ✅ Message deduplication logic
- ✅ Unread count increment/reset logic

**Deliverables:**
- `jam-ui/src/store/features/sessionChatSlice.js`
- Unit tests: `sessionChatSlice.test.js`

**Complexity:** Simple
**Estimated Duration:** 1-2 sessions

---

#### Plan 7.2: Async Thunks & API Integration (TDD)

**Tasks (3-4):**
1. Add REST API client methods: `getChatMessages()`, `sendChatMessage()` in `rest.js`
2. Implement `fetchChatHistory` async thunk with extra reducers
3. Implement `sendMessage` async thunk with extra reducers
4. Write unit tests for async thunks (mock fetch, test success/error paths)
5. Test API error handling (404, 403, 422, 500)

**Dependencies:** Plan 7.1 (Redux slice must exist)

**TDD Candidates:**
- ✅ `getChatMessages` API client method
- ✅ `sendChatMessage` API client method
- ✅ `fetchChatHistory` async thunk
- ✅ `sendMessage` async thunk
- ✅ Error handling for all HTTP status codes

**Deliverables:**
- `jam-ui/src/helpers/rest.js` (extended)
- Async thunks in `sessionChatSlice.js`
- Unit tests: `rest.test.js`, `sessionChatSlice.test.js` (async thunks)

**Complexity:** Medium
**Estimated Duration:** 2-3 sessions

---

#### Plan 7.3: WebSocket Integration & Selectors (TDD)

**Tasks (3-4):**
1. Add `CHAT_MESSAGE` handler to `useSessionWebSocket.js`
2. Test WebSocket message routing to Redux (mock JamServer)
3. Implement memoized selectors: `selectChatMessages`, `selectUnreadCount`, etc.
4. Test selectors with various state scenarios
5. Add localStorage persistence for `lastReadAt` timestamps

**Dependencies:** Plan 7.1, 7.2

**TDD Candidates:**
- ✅ `CHAT_MESSAGE` WebSocket handler
- ✅ Selectors (unit tests)
- ✅ localStorage persistence logic

**Deliverables:**
- `jam-ui/src/hooks/useSessionWebSocket.js` (extended)
- Selectors in `sessionChatSlice.js`
- Unit tests: `useSessionWebSocket.test.js`, `sessionChatSlice.test.js` (selectors)

**Complexity:** Medium
**Estimated Duration:** 2 sessions

---

**Phase 7 Summary:**
- **3 Plans, ~10-12 Tasks**
- **All TDD** (data layer)
- **Foundation for Phases 8-11**

---

### Phase 8: Chat Window UI & Message Display

**Objective:** Build chat window components with WindowPortal integration.

**Estimated Plans:** 3 plans

**Preliminary Plan Breakdown:**

#### Plan 8.1: Chat Window Shell & WindowPortal Integration

**Tasks (3):**
1. Create `JKSessionChatWindow.js` component with WindowPortal wrapper
2. Create `JKChatHeader.js` component (title + close button)
3. Integrate chat window with JKSessionScreen (conditional rendering)
4. Test window open/close behavior (integration test)

**Dependencies:** Phase 7 complete (Redux slice available)

**TDD Candidates:**
- ✅ Window open/close behavior (integration test)
- ❌ Component rendering (visual, skip TDD)

**Deliverables:**
- `jam-ui/src/components/client/JKSessionChatWindow.js`
- `jam-ui/src/components/client/chat/JKChatHeader.js`
- Integration test: `chat-window.spec.ts`

**Complexity:** Simple
**Estimated Duration:** 1-2 sessions

---

#### Plan 8.2: Message List & Auto-Scroll

**Tasks (4-5):**
1. Create `JKChatMessageList.js` component with auto-scroll logic
2. Create `JKChatMessage.js` component (avatar, name, text, timestamp)
3. Create `JKChatLoadingSpinner.js` and `JKChatEmptyState.js` components
4. Implement auto-scroll behavior (scroll to bottom on new message)
5. Test auto-scroll logic (respect user manual scrolling)
6. Add timestamp formatting utility (dayjs relative time)

**Dependencies:** Plan 8.1

**TDD Candidates:**
- ✅ Auto-scroll logic (unit test: isUserScrolling state)
- ✅ Timestamp formatting utility
- ❌ Component rendering (visual, skip TDD)

**Deliverables:**
- `jam-ui/src/components/client/chat/JKChatMessageList.js`
- `jam-ui/src/components/client/chat/JKChatMessage.js`
- `jam-ui/src/components/client/chat/JKChatLoadingSpinner.js`
- `jam-ui/src/components/client/chat/JKChatEmptyState.js`
- `jam-ui/src/utils/formatTimestamp.js`
- Unit tests: `JKChatMessageList.test.js`, `formatTimestamp.test.js`

**Complexity:** Medium
**Estimated Duration:** 2-3 sessions

---

#### Plan 8.3: Chat Button & Unread Badge

**Tasks (3):**
1. Create `JKSessionChatButton.js` component with unread badge
2. Add chat button to JKSessionScreen top navigation
3. Test unread badge visibility and count updates
4. Style chat button (CSS/SCSS)

**Dependencies:** Phase 7 complete, Plan 8.1

**TDD Candidates:**
- ✅ Badge visibility logic (integration test)
- ✅ Unread count updates on message receive (integration test)
- ❌ CSS styling (skip TDD)

**Deliverables:**
- `jam-ui/src/components/client/JKSessionChatButton.js`
- Integration test: `chat-button.spec.ts`
- SCSS: `JKSessionChatButton.scss`

**Complexity:** Simple
**Estimated Duration:** 1-2 sessions

---

**Phase 8 Summary:**
- **3 Plans, ~10-12 Tasks**
- **Mixed TDD** (behavior tests, skip styling)
- **UI components complete**

---

### Phase 9: Message Composition & Sending

**Objective:** Implement message input, send functionality, and real-time delivery.

**Estimated Plans:** 2 plans

**Preliminary Plan Breakdown:**

#### Plan 9.1: Message Composer & Validation (TDD)

**Tasks (4-5):**
1. Create `JKChatComposer.js` component (textarea + send button)
2. Implement keyboard handling: Enter-to-send, Shift+Enter for newline
3. Add message validation: length (1-255 chars), non-empty
4. Add character count display (255 max)
5. Test keyboard handling and validation logic
6. Disable send button when disconnected (check `isConnected` from JamServerContext)

**Dependencies:** Phase 8 complete

**TDD Candidates:**
- ✅ Keyboard handling (Enter vs Shift+Enter)
- ✅ Message validation logic
- ✅ Character count calculation
- ✅ Disable send when disconnected

**Deliverables:**
- `jam-ui/src/components/client/chat/JKChatComposer.js`
- Unit tests: `JKChatComposer.test.js`
- Integration test: `message-composition.spec.ts`

**Complexity:** Medium
**Estimated Duration:** 2 sessions

---

#### Plan 9.2: Send Message & Real-Time Delivery (TDD)

**Tasks (4-5):**
1. Wire up `sendMessage` async thunk to send button
2. Test send message flow: API call → Redux update → UI update
3. Test real-time message delivery: WebSocket → Redux → UI update
4. Test message deduplication (sent message not duplicated on WebSocket receive)
5. Add error handling for send failures (display error message)
6. Test optimistic update behavior (message appears immediately)

**Dependencies:** Plan 9.1, Phase 7 complete

**TDD Candidates:**
- ✅ Send message flow (integration test)
- ✅ Real-time delivery (integration test with WebSocket mock)
- ✅ Message deduplication (unit test)
- ✅ Error handling (unit + integration test)

**Deliverables:**
- Integration tests: `send-message.spec.ts`, `receive-message.spec.ts`
- Error handling UI in `JKChatComposer.js`

**Complexity:** Medium
**Estimated Duration:** 2-3 sessions

---

**Phase 9 Summary:**
- **2 Plans, ~8-10 Tasks**
- **Full TDD** (behavior-focused)
- **Core functionality complete**

---

### Phase 10: Read/Unread Status Management

**Objective:** Implement read/unread tracking, badge updates, and localStorage persistence.

**Estimated Plans:** 2 plans

**Preliminary Plan Breakdown:**

#### Plan 10.1: Unread Tracking & Badge Updates (TDD)

**Tasks (4):**
1. Test unread count increment on message receive (window closed)
2. Test unread count reset on window open (mark as read)
3. Test badge visibility based on unread count
4. Test multi-channel unread tracking (global, session, lesson)
5. Add localStorage persistence for `lastReadAt` timestamps

**Dependencies:** Phase 8, 9 complete

**TDD Candidates:**
- ✅ Unread count increment logic (unit test)
- ✅ Badge visibility logic (integration test)
- ✅ localStorage persistence (unit test)
- ✅ Multi-channel tracking (unit test)

**Deliverables:**
- Integration tests: `unread-badge.spec.ts`
- Unit tests: `sessionChatSlice.test.js` (unread logic)

**Complexity:** Medium
**Estimated Duration:** 2 sessions

---

#### Plan 10.2: Channel Switching & Read State Sync

**Tasks (3-4):**
1. Implement channel switching logic (global ↔ session ↔ lesson)
2. Test read state sync on channel switch (mark as read)
3. Test unread counts persist across channel switches
4. Test localStorage persistence across browser sessions
5. Handle edge case: multiple tabs/windows (localStorage sync)

**Dependencies:** Plan 10.1

**TDD Candidates:**
- ✅ Channel switching (integration test)
- ✅ Read state sync (unit test)
- ✅ localStorage persistence (unit test)

**Deliverables:**
- Integration test: `channel-switching.spec.ts`
- localStorage sync logic in `sessionChatSlice.js`

**Complexity:** Medium
**Estimated Duration:** 2 sessions

---

**Phase 10 Summary:**
- **2 Plans, ~7-8 Tasks**
- **Full TDD** (state management focused)
- **Read/unread tracking complete**

---

### Phase 11: Chat Finalization & Polish

**Objective:** Error handling, edge cases, performance optimization, and UAT.

**Estimated Plans:** 3 plans

**Preliminary Plan Breakdown:**

#### Plan 11.1: Error Handling & Retry Logic

**Tasks (4-5):**
1. Handle API errors: 404, 403, 422, 500 (display user-friendly messages)
2. Handle WebSocket disconnection (disable send, show status)
3. Implement retry logic for failed message sends
4. Test error recovery flows (connection lost → reconnect → retry)
5. Add loading states (spinner during fetch/send)

**Dependencies:** Phase 9 complete

**TDD Candidates:**
- ✅ API error handling (unit test)
- ✅ WebSocket disconnection handling (integration test)
- ✅ Retry logic (unit test)

**Deliverables:**
- Error handling in `JKChatComposer.js`
- Retry logic in `sendMessage` async thunk
- Integration test: `error-handling.spec.ts`

**Complexity:** Medium
**Estimated Duration:** 2 sessions

---

#### Plan 11.2: Performance Optimization & Accessibility

**Tasks (4-5):**
1. Optimize message list rendering (React.memo for JKChatMessage)
2. Optimize selectors (Reselect memoization)
3. Add accessibility: ARIA labels, keyboard navigation
4. Test keyboard navigation (Tab, Enter, Esc)
5. Add focus management (auto-focus input on window open)
6. Consider virtualization for message list (if >100 messages) - **DEFER if not needed**

**Dependencies:** Phase 8-10 complete

**TDD Candidates:**
- ✅ Keyboard navigation (E2E test)
- ❌ React.memo optimization (performance test, not TDD)
- ❌ Accessibility (manual audit, skip TDD)

**Deliverables:**
- Optimized components (React.memo)
- Accessibility improvements (ARIA attributes)
- E2E test: `keyboard-navigation.spec.ts`

**Complexity:** Medium
**Estimated Duration:** 2 sessions

---

#### Plan 11.3: UAT & Final Integration Testing

**Tasks (4-5):**
1. Conduct comprehensive UAT (40+ test cases from CHAT_COMPONENT_DESIGN.md)
2. Fix critical UAT issues (P0/P1 severity)
3. Document deferred issues (P2/P3 severity)
4. Run full E2E test suite
5. Verify no regressions (Backing Track, JamTrack, Metronome still work)
6. Update documentation (CLAUDE.md, CONVENTIONS.md if needed)

**Dependencies:** Phase 7-10 complete, Plan 11.1-11.2 complete

**TDD Candidates:**
- ✅ E2E tests for complete workflows
- ❌ Manual UAT (user acceptance testing)

**Deliverables:**
- UAT test report
- E2E test suite: `complete-chat-flow.spec.ts`
- Deferred issues documented in GitHub issues (if any)

**Complexity:** Medium
**Estimated Duration:** 2-3 sessions

---

**Phase 11 Summary:**
- **3 Plans, ~12-15 Tasks**
- **Mixed TDD** (error handling + E2E tests, skip performance/accessibility)
- **Phase 6 complete!**

---

## Dependency Graph

```
Phase 7 (Infrastructure)
├── Plan 7.1: Redux Slice & Core Reducers
├── Plan 7.2: Async Thunks & API Integration (depends on 7.1)
└── Plan 7.3: WebSocket Integration & Selectors (depends on 7.1, 7.2)

Phase 8 (UI Components)
├── Plan 8.1: Chat Window Shell (depends on Phase 7)
├── Plan 8.2: Message List & Auto-Scroll (depends on 8.1)
└── Plan 8.3: Chat Button & Unread Badge (depends on Phase 7, 8.1)

Phase 9 (Message Composition)
├── Plan 9.1: Message Composer (depends on Phase 8)
└── Plan 9.2: Send Message & Real-Time Delivery (depends on 9.1, Phase 7)

Phase 10 (Read/Unread Tracking)
├── Plan 10.1: Unread Tracking & Badge Updates (depends on Phase 8, 9)
└── Plan 10.2: Channel Switching & Read State Sync (depends on 10.1)

Phase 11 (Finalization)
├── Plan 11.1: Error Handling & Retry Logic (depends on Phase 9)
├── Plan 11.2: Performance & Accessibility (depends on Phase 8-10)
└── Plan 11.3: UAT & Final Integration Testing (depends on 11.1, 11.2)
```

**Critical Path:**
- Phase 7 (all plans) → Phase 8.1 → Phase 8.2 → Phase 9.1 → Phase 9.2 → Phase 10.1 → Phase 10.2 → Phase 11.3

**Parallel Opportunities:**
- Plan 8.3 (chat button) can be built in parallel with Plan 8.2 (message list)
- Plan 11.1 (error handling) can start after Phase 9, doesn't need Phase 10

---

## Risk Analysis

### HIGH Risks

**Risk 1: WebSocket Message Deduplication**

**Description:** WebSocket messages may arrive multiple times (reconnect, race conditions). Deduplication by `msg_id` is critical to avoid duplicate UI rendering.

**Impact:** HIGH - Duplicate messages confuse users, degrade UX

**Mitigation:**
1. Implement deduplication in `addMessageFromWebSocket` reducer (check by `msg_id`)
2. Add unit tests for deduplication logic (receive same message twice)
3. Test with simulated reconnect scenarios

**Contingency:**
- If deduplication fails, add deduplication at WebSocket handler level (before Redux)
- Log duplicate messages for debugging

---

**Risk 2: localStorage Persistence Edge Cases**

**Description:** localStorage has quota limits, may be disabled in private browsing, or fail due to quota exceeded.

**Impact:** HIGH - Unread counts lost across sessions, poor UX

**Mitigation:**
1. Wrap localStorage access in try/catch blocks
2. Gracefully degrade: If localStorage fails, keep in-memory state only
3. Test in private browsing mode

**Contingency:**
- Fall back to Redux-only state (no persistence)
- Log localStorage errors for monitoring

---

### MEDIUM Risks

**Risk 3: Auto-Scroll Behavior Conflicts**

**Description:** Auto-scroll to bottom vs user manual scrolling. If not handled correctly, auto-scroll may interrupt user reading previous messages.

**Impact:** MEDIUM - Annoying UX, users can't read history

**Mitigation:**
1. Track `isUserScrolling` state (detect when user scrolls up)
2. Disable auto-scroll if user not at bottom
3. Re-enable auto-scroll when user scrolls to bottom
4. Test with rapid message influx (stress test)

**Contingency:**
- Add "Scroll to bottom" button if auto-scroll disabled
- Add "New messages" indicator

---

**Risk 4: Multi-Tab/Window State Sync**

**Description:** If user opens chat in multiple tabs, unread counts and `lastReadAt` may drift out of sync.

**Impact:** MEDIUM - Inconsistent badge counts across tabs

**Mitigation:**
1. Use localStorage events to sync state across tabs
2. Test with multiple tabs open
3. Consider marking as read in one tab clears badge in all tabs

**Contingency:**
- Document limitation: Unread counts may not sync perfectly across tabs (acceptable for MVP)
- Defer full sync to server-side tracking (next milestone)

---

**Risk 5: API Error Handling Complexity**

**Description:** Chat API has 4 error types (404, 403, 422, 500). Each requires different user feedback and recovery strategy.

**Impact:** MEDIUM - Users confused by errors, can't recover

**Mitigation:**
1. Map each error code to user-friendly message
2. Add retry button for transient errors (500)
3. Disable send for fatal errors (403)
4. Show inline validation for 422 errors

**Contingency:**
- Show generic error message if unknown error code
- Provide support contact link

---

**Risk 6: WindowPortal Styling Issues**

**Description:** WindowPortal copies stylesheets from parent, but may have timing issues or missing styles in popup window.

**Impact:** MEDIUM - Chat window looks broken/unstyled

**Mitigation:**
1. Test WindowPortal thoroughly (already proven for Metronome, JamTrack)
2. Add delay before rendering content (wait for stylesheets)
3. Reference existing WindowPortal usage patterns

**Contingency:**
- Fall back to inline styles if external stylesheets fail
- Add inline critical CSS

---

### LOW Risks

**Risk 7: Character Count Validation**

**Description:** Message length validation (max 255 chars). Edge cases: Unicode characters, emoji count.

**Impact:** LOW - Minor validation bugs

**Mitigation:**
1. Use `message.length` for character count (JS handles Unicode correctly)
2. Test with emoji, special characters
3. Server-side validation as backup (already exists)

**Contingency:**
- Server rejects invalid messages (422 error)
- Show validation error to user

---

**Risk 8: Timestamp Formatting Performance**

**Description:** `dayjs.fromNow()` called for every message on every render. Could be slow for large message lists.

**Impact:** LOW - Slight performance degradation

**Mitigation:**
1. Memoize `JKChatMessage` component with React.memo
2. Only update timestamp on message change (not on every render)
3. Consider caching formatted timestamps

**Contingency:**
- Use absolute timestamps (e.g., "12:30 PM") instead of relative (e.g., "5 minutes ago")
- Update timestamps on interval (every 60 seconds) instead of every render

---

## TDD Strategy

### When to Use TDD (per CLAUDE.md)

**ALWAYS use TDD for:**
- ✅ Redux reducers (state transitions)
- ✅ Async thunks (API calls, error handling)
- ✅ Selectors (computed values)
- ✅ WebSocket handlers (message routing)
- ✅ Validation logic (message length, character count)
- ✅ Business logic (deduplication, unread count, auto-scroll)

**TDD Optional for:**
- ❌ Styling-only changes (CSS/SCSS)
- ❌ Component rendering (visual appearance)
- ❌ Performance optimizations (React.memo, Reselect)

---

### TDD Workflow Summary

**Phase 7 (Infrastructure):**
- **100% TDD** - All data layer (Redux, API, WebSocket)
- Test-first approach for all reducers, thunks, selectors

**Phase 8 (UI Components):**
- **50% TDD** - Component behavior (open/close, auto-scroll), skip styling
- Integration tests for window open/close, badge visibility

**Phase 9 (Message Composition):**
- **100% TDD** - Keyboard handling, validation, send flow
- Integration tests for send message, receive message

**Phase 10 (Read/Unread Tracking):**
- **100% TDD** - Unread count logic, localStorage persistence
- Integration tests for badge updates, channel switching

**Phase 11 (Finalization):**
- **70% TDD** - Error handling, retry logic, keyboard navigation
- Skip TDD for performance optimizations, accessibility audits

---

### Test Coverage Goals

**Unit Tests (Jest):**
- Redux reducers: 100% coverage
- Async thunks: 100% coverage (success + error paths)
- Selectors: 100% coverage
- Utility functions: 100% coverage

**Integration Tests (Playwright):**
- Send message flow: ✅
- Receive message flow: ✅
- Unread badge updates: ✅
- Window open/close: ✅
- Auto-scroll behavior: ✅
- Channel switching: ✅
- Error handling: ✅

**E2E Tests (Playwright):**
- Complete chat workflow: Login → Create session → Send message → Receive message → Close chat → Unread badge → Open chat
- Multi-user scenario: Two users chatting in same session (requires test infrastructure)

---

## Testing Strategy

### Unit Tests (Jest)

**Location:** `jam-ui/src/**/__tests__/*.test.js`

**Coverage:**
- Redux slice: `sessionChatSlice.test.js`
- Async thunks: `sessionChatSlice.test.js` (async thunks section)
- API client: `rest.test.js`
- WebSocket handler: `useSessionWebSocket.test.js`
- Selectors: `sessionChatSlice.test.js` (selectors section)
- Utilities: `formatTimestamp.test.js`

**Example Test Structure:**
```javascript
describe('sessionChatSlice', () => {
  describe('reducers', () => {
    test('addMessageFromWebSocket', () => { ... });
    test('openChatWindow', () => { ... });
    test('markAsRead', () => { ... });
  });

  describe('async thunks', () => {
    test('fetchChatHistory success', async () => { ... });
    test('fetchChatHistory error', async () => { ... });
    test('sendMessage success', async () => { ... });
    test('sendMessage error', async () => { ... });
  });

  describe('selectors', () => {
    test('selectChatMessages', () => { ... });
    test('selectUnreadCount', () => { ... });
  });
});
```

---

### Integration Tests (Playwright)

**Location:** `jam-ui/test/session-chat/*.spec.ts`

**Test Files:**
- `chat-window.spec.ts` - Window open/close, basic rendering
- `send-message.spec.ts` - Send message flow (API call, UI update)
- `receive-message.spec.ts` - WebSocket message receive, UI update
- `unread-badge.spec.ts` - Badge visibility, count updates
- `auto-scroll.spec.ts` - Auto-scroll behavior, manual scroll detection
- `channel-switching.spec.ts` - Switch between global/session/lesson
- `error-handling.spec.ts` - API errors, WebSocket disconnection

**Example Test:**
```typescript
// send-message.spec.ts
test('sends message and updates UI', async ({ page }) => {
  await loginToJamUI(page);
  await createAndJoinSession(page);

  // Open chat
  await page.click('[data-testid="chat-button"]');

  // Send message
  await page.fill('[data-testid="chat-input"]', 'Test message');
  await page.keyboard.press('Enter');

  // Verify API call
  const chatCalls = interceptor.getCallsByPath('/api/chat');
  expect(chatCalls.length).toBe(1);

  // Verify UI update
  await expect(page.locator('[data-testid="chat-message"]').last())
    .toContainText('Test message');
});
```

---

### E2E Tests (Playwright)

**Location:** `jam-ui/test/e2e/complete-chat-flow.spec.ts`

**Test Scenarios:**
1. **Complete Chat Flow:**
   - Login → Create session → Join session
   - Open chat → Send message → Verify sent
   - Close chat → Simulate incoming message → Verify badge
   - Open chat → Verify badge cleared → Verify reply visible

2. **Multi-User Flow (Advanced, defer to Phase 11):**
   - User A creates session
   - User B joins session
   - User A sends message → User B receives message
   - User B sends reply → User A receives reply

---

## Deferred Features & Decisions

### Deferred to Next Milestone (Phase 12+)

**1. Server-Side Read/Unread Tracking**
- Create `chat_message_reads` table
- API endpoint: `PUT /api/chat/mark_read`
- Cross-device synchronization
- Per-message read receipts

**2. File Attachments**
- Support for music notation, audio files, recordings
- Upload UI and file validation
- Attachment rendering in messages

**3. Message Search/Filtering**
- Search messages by text, sender, date
- Filter by attachment type
- Pagination for large message lists

**4. Message Editing/Deletion**
- Edit sent messages (within time window)
- Delete messages (soft delete)
- Show "edited" indicator

**5. Typing Indicators**
- Show "User is typing..." when other users typing
- WebSocket message for typing state
- Throttle typing updates

**6. Emoji Picker**
- Inline emoji picker for message composition
- Emoji autocomplete (`:smile:` → 😊)

**7. Multi-Channel Tabs**
- Tab UI to switch between global, session, lesson
- Unread badge per tab
- Persist active tab preference

**8. Notification Sounds**
- Play sound when message received (window closed)
- User preference to enable/disable sounds

**9. Desktop Notifications**
- Browser notification API for new messages
- Request permission on first use
- Show message preview in notification

---

### Critical Decisions for Phase 7-11

**Decision 1: Message Virtualization**
- **Question:** Should message list use virtualization (react-window) for performance?
- **Options:**
  - A: Implement virtualization from start (prevents future refactor)
  - B: Defer until >100 messages becomes problem (simpler MVP)
- **Recommendation:** Option B - Defer until needed
- **Rationale:** Adds complexity, unlikely to have >100 messages in single session for MVP
- **Impact:** If deferred, may need refactor in Phase 11 or next milestone

**Decision 2: Optimistic UI Updates**
- **Question:** Should sent messages appear immediately (before API response)?
- **Options:**
  - A: Optimistic update (fast UX, handles API errors)
  - B: Wait for API response (simple, no error recovery needed)
- **Recommendation:** Option A - Optimistic update
- **Rationale:** Better UX (immediate feedback), API usually succeeds
- **Impact:** Requires error handling (rollback on failure)

**Decision 3: Unread Count Persistence**
- **Question:** Store unread counts in localStorage or Redux-only?
- **Options:**
  - A: localStorage (persists across sessions)
  - B: Redux-only (resets on page reload)
- **Recommendation:** Option A - localStorage
- **Rationale:** Better UX (remembers unread counts), simple to implement
- **Impact:** Requires localStorage error handling (quota, private browsing)

**Decision 4: Multi-Tab State Sync**
- **Question:** Should unread counts sync across browser tabs?
- **Options:**
  - A: Sync via localStorage events (complex, better UX)
  - B: No sync, each tab independent (simple, acceptable UX)
- **Recommendation:** Option B - No sync for MVP
- **Rationale:** Adds complexity, edge case scenario, can defer to next milestone
- **Impact:** Users may see inconsistent badge counts across tabs (document as limitation)

**Decision 5: Auto-Scroll Strategy**
- **Question:** How to handle auto-scroll when user manually scrolls up?
- **Options:**
  - A: Disable auto-scroll, show "New messages" button (user control)
  - B: Auto-scroll after N seconds of inactivity (automatic, may interrupt)
  - C: Track scroll position, re-enable when user scrolls to bottom (smart)
- **Recommendation:** Option C - Track scroll position
- **Rationale:** Best UX (doesn't interrupt, auto-resumes), matches legacy behavior
- **Impact:** Requires scroll event listener, slight complexity

---

## Success Metrics

### Functional Completeness

**Phase 7 Complete:**
- ✅ Redux slice with multi-channel state
- ✅ Async thunks for fetch history, send message
- ✅ WebSocket handler for real-time messages
- ✅ Selectors for data access

**Phase 8 Complete:**
- ✅ Chat window renders in WindowPortal
- ✅ Message list with auto-scroll
- ✅ Chat button with unread badge

**Phase 9 Complete:**
- ✅ Message composer with validation
- ✅ Send message functionality
- ✅ Real-time message delivery

**Phase 10 Complete:**
- ✅ Unread count tracking per channel
- ✅ Badge updates on message receive
- ✅ Mark as read on window open

**Phase 11 Complete:**
- ✅ Error handling for API and WebSocket
- ✅ Performance optimizations (React.memo, Reselect)
- ✅ Accessibility improvements
- ✅ UAT complete with all P0/P1 issues resolved

---

### Code Quality

**Test Coverage:**
- Unit tests: 80%+ coverage for Redux, API, WebSocket
- Integration tests: All critical user flows covered
- E2E tests: Complete workflow tested

**Code Standards:**
- All code follows jam-ui conventions (CONVENTIONS.md)
- TDD followed for all data layer (per CLAUDE.md)
- No ESLint errors or warnings
- Components use functional patterns (hooks, not classes)

**Documentation:**
- All components have JSDoc comments
- Redux actions/thunks documented
- README.md updated with chat feature description

---

### UX Quality

**Performance:**
- Message list renders smoothly (no lag for <100 messages)
- Auto-scroll doesn't jank
- Send message feels instant (optimistic update)

**Visual Design:**
- Chat window matches jam-ui styling
- Messages have clear sender identification
- Timestamps readable (relative time format)
- Unread badge visible and clear

**Accessibility:**
- Keyboard navigation works (Tab, Enter, Esc)
- Screen reader announces new messages
- ARIA labels on interactive elements
- Focus management (auto-focus input on window open)

---

## UAT Test Cases (40+ Cases)

### Category 1: Initialization (4 cases)

**UAT-001:** Join session → Chat button appears in top nav
**UAT-002:** Click chat button → Chat window opens in popup
**UAT-003:** Chat window closed by default on session join
**UAT-004:** Fetch message history on window open (show loading spinner)

---

### Category 2: Message Display (6 cases)

**UAT-005:** Messages render with avatar, name, text, timestamp
**UAT-006:** Current user messages right-aligned, others left-aligned
**UAT-007:** Timestamps show relative time ("5 minutes ago")
**UAT-008:** Empty state shown when no messages
**UAT-009:** Loading spinner shown while fetching history
**UAT-010:** Messages sorted by created_at (oldest first)

---

### Category 3: Message Composition (7 cases)

**UAT-011:** Type in textarea → Send button enabled
**UAT-012:** Press Enter → Message sent
**UAT-013:** Press Shift+Enter → Newline added (message not sent)
**UAT-014:** Empty message → Send button disabled
**UAT-015:** Message >255 chars → Validation error shown
**UAT-016:** Character count displayed (255 max)
**UAT-017:** Disconnected from server → Send button disabled

---

### Category 4: Message Sending (5 cases)

**UAT-018:** Click Send → API call made (POST /api/chat)
**UAT-019:** Message sent → Appears in UI immediately (optimistic update)
**UAT-020:** API error → Error message shown, input not cleared
**UAT-021:** Message sent → Input cleared, focus restored
**UAT-022:** Message sent → No duplicate on WebSocket receive (deduplication)

---

### Category 5: Real-Time Messages (5 cases)

**UAT-023:** Other user sends message → Message appears in UI
**UAT-024:** WebSocket message → Auto-scroll to bottom
**UAT-025:** User scrolled up → Auto-scroll disabled (doesn't interrupt)
**UAT-026:** User scrolls to bottom → Auto-scroll re-enabled
**UAT-027:** Duplicate WebSocket message → No duplicate in UI (deduplication)

---

### Category 6: Unread Badge (7 cases)

**UAT-028:** Chat window closed → Badge hidden (count = 0)
**UAT-029:** Message received (window closed) → Badge shows count = 1
**UAT-030:** Multiple messages received → Badge count increments
**UAT-031:** Open chat window → Badge count resets to 0
**UAT-032:** Badge hidden when count = 0
**UAT-033:** Unread count persists across page reload (localStorage)
**UAT-034:** Multiple tabs open → Badge updates independently per tab

---

### Category 7: Window Management (4 cases)

**UAT-035:** Click close button → Window closes
**UAT-036:** Close window → Unread count persists
**UAT-037:** Open window again → Same position (WindowPortal saves position)
**UAT-038:** WindowPortal stylesheets copied correctly (no broken styles)

---

### Category 8: Error Handling (5 cases)

**UAT-039:** API error 404 → "Session not found" message shown
**UAT-040:** API error 403 → "Not allowed to join session" message shown
**UAT-041:** API error 422 → Validation error shown inline
**UAT-042:** WebSocket disconnected → Send button disabled, status shown
**UAT-043:** WebSocket reconnected → Send button re-enabled

---

### Category 9: Edge Cases (7 cases)

**UAT-044:** Private browsing mode → localStorage gracefully degrades
**UAT-045:** localStorage quota exceeded → No crash, fallback to Redux-only
**UAT-046:** Very long username → Truncated with ellipsis
**UAT-047:** Message with emoji → Renders correctly
**UAT-048:** Message with newlines (Shift+Enter) → Preserves formatting
**UAT-049:** Rapid message influx (10 msgs/sec) → No performance degradation
**UAT-050:** Open chat, close session, reopen chat → No stale data

---

## Complexity Estimation

### Comparison to Previous Phases

**Phase 3 (Backing Track):**
- **Plans:** 3
- **Tasks:** ~7
- **Complexity:** Simple
- **Features:** Play/pause, volume, track selection
- **No network:** Pure jamClient integration

**Phase 5 (JamTrack):**
- **Plans:** 9
- **Tasks:** ~25
- **Complexity:** High
- **Features:** Download/sync, playback, mixdown selection, seek, JMEP
- **Network:** REST API + WebSocket + jamClient integration

**Phase 6 (Chat):**
- **Plans:** 11-13 (estimated)
- **Tasks:** ~28-32 (estimated)
- **Complexity:** Medium
- **Features:** Send/receive, unread tracking, multi-channel, WindowPortal
- **Network:** REST API + WebSocket (no jamClient)

**Multiplier:**
- Chat is **1.5-2x more complex** than Backing Track (more features, network layer)
- Chat is **0.6x less complex** than JamTrack (no native client, simpler state machine)

**Rationale:**
- Backing Track baseline: 3 plans × 1.5-2 = 4.5-6 plans (but Chat has more features)
- JamTrack reference: 9 plans × 0.6 = 5.4 plans (but Chat has unread tracking)
- Adjusted estimate: 11-13 plans (accounts for multi-channel, unread tracking, WindowPortal integration)

---

## Summary

**Phase 7-11 Roadmap Complete:**
- ✅ 5 phases broken down into 11-13 preliminary plans
- ✅ ~28-32 tasks estimated
- ✅ Dependency graph mapped (critical path identified)
- ✅ Risk analysis complete (2 HIGH, 4 MEDIUM, 2 LOW risks with mitigation)
- ✅ TDD strategy defined (100% for data layer, 50-70% for UI)
- ✅ Testing strategy comprehensive (unit, integration, E2E)
- ✅ 40+ UAT test cases defined
- ✅ Success metrics clear (functional, code quality, UX)
- ✅ Deferred features documented (server-side tracking, attachments, etc.)
- ✅ 5 critical decisions identified for Phase 7-11

**Ready for Phase 7 Execution:**
- Phase 6 design artifacts complete
- Phase 7-11 roadmap provides clear execution path
- Risk mitigation strategies defined
- TDD approach aligned with CLAUDE.md requirements

**Estimated Effort:**
- Phase 6 (research + design): 2 plans, ~6 tasks
- Phase 7-11 (implementation): 11-13 plans, ~28-32 tasks
- Total: 13-15 plans, ~34-38 tasks for complete session chat feature

**Next Steps:**
1. Review and approve roadmap
2. `/gsd:plan-phase 7` to create executable PLAN.md files
3. Execute Phase 7.1 (Redux Slice & Core Reducers) using TDD
4. Iterate through phases sequentially (7 → 8 → 9 → 10 → 11)

---

**Roadmap Complete!**
**Phase 6 Complete!**
**Ready for Phase 7: Chat Infrastructure & State Management**
