---
phase: 04-jamtrack-research-design
plan: 02
subsystem: documentation
tags: [jamtrack, component-design, redux-architecture, implementation-planning]

# Dependency graph
requires:
  - phase: 04-jamtrack-research-design
    plan: 01
    provides: Legacy patterns, jamClient API reference, React pattern analysis
provides:
  - COMPONENT_DESIGN.md - JKSessionJamTrackPlayer component architecture and sub-components
  - REDUX_DESIGN.md - Redux state extensions and async thunks for JamTrack
  - IMPLEMENTATION_ROADMAP.md - Phase 5 roadmap with 9 plans, risk analysis, testing strategy
affects: [05-jamtrack-implementation]

# Tech tracking
tech-stack:
  added: []
  patterns:
    - "Component architecture: JKSessionJamTrackPlayer with 10 sub-components"
    - "Redux extensions: 3 slices (media, activeSession, sessionUI) with 6 async thunks"
    - "6-state download/sync machine: idle → checking → downloading → keying → synchronized → error"
    - "WebSocket integration: 3 handlers (MIXER_CHANGES extended, JAM_TRACK_CHANGES, MIXDOWN_CHANGES)"
    - "Props vs Redux decision matrix for state ownership"

key-files:
  created:
    - .planning/phases/04-jamtrack-research-design/COMPONENT_DESIGN.md
    - .planning/phases/04-jamtrack-research-design/REDUX_DESIGN.md
    - .planning/phases/04-jamtrack-research-design/IMPLEMENTATION_ROADMAP.md
  modified: []

key-decisions:
  - "JKSessionJamTrackPlayer follows Backing Track patterns with extensions for download/sync and mixdown selection"
  - "Redux state split: jamTrackState (playback), downloadState (sync machine), availableMixdowns (mixdown cache)"
  - "6 async thunks needed: loadJamTrack (enhanced), downloadJamTrack, checkJamTrackSync, loadJMEP, seekJamTrack, closeJamTrack"
  - "Enhanced loadJamTrack fixes existing bug: uses fqId format instead of jamTrack.id"
  - "Phase 5 preliminary scope: 9 plans, 2.5-3x complexity of Phase 3 Backing Track"
  - "5 critical decisions deferred to Phase 5: popup mode support, stem control integration, error recovery strategy, download cancellation, UAT deferral threshold"

patterns-established:
  - "Design-before-implementation: comprehensive architecture docs before Phase 5 execution"
  - "Risk-driven planning: identify HIGH/MEDIUM/LOW risks with mitigation strategies"
  - "Complexity estimation: compare to baseline (Phase 3) for realistic scoping"
  - "Testing strategy as planning artifact: UAT checklist, unit tests, integration tests defined upfront"

issues-created: []

# Metrics
duration: 20min
completed: 2026-01-14
---

# Phase 4 Plan 2: Design React JamTrack Architecture Summary

**Comprehensive component and Redux architecture design with Phase 5 implementation roadmap**

## Performance

- **Duration:** 20 min
- **Started:** 2026-01-14T16:47:35Z
- **Completed:** 2026-01-14T17:07:56Z
- **Tasks:** 3
- **Files created:** 3

## Accomplishments

- **COMPONENT_DESIGN.md** (691 lines): Designed JKSessionJamTrackPlayer with 10 sub-components (PlaybackControls, SeekSlider, TimeDisplay, MixdownPicker, DownloadProgress, ErrorDisplay, SyncStatus, VolumeControl, LoadingSpinner, EmptyState), component lifecycle patterns, initialization/cleanup, Props vs Redux decision matrix, and comparison to Backing Track player
- **REDUX_DESIGN.md** (1014 lines): Designed Redux state extensions across 3 slices (mediaSlice, activeSessionSlice, sessionUISlice), 6 async thunks, 3 WebSocket handlers, 6-state download/sync machine, comprehensive selectors, and fixes existing loadJamTrack bug
- **IMPLEMENTATION_ROADMAP.md** (1030 lines): Created Phase 5 roadmap with 9 preliminary plans, dependency graph, risk analysis (2 HIGH, 4 MEDIUM, 2 LOW risks), 5 critical decisions, success metrics, testing strategy with 40+ UAT test cases, and comparison to Phase 3 effort (2.5-3x complexity)

## Task Commits

Each task was committed atomically:

1. **Task 1: Create COMPONENT_DESIGN.md** - `d25bd6262` (docs)
2. **Task 2: Create REDUX_DESIGN.md** - `2e5e30f8b` (docs)
3. **Task 3: Create IMPLEMENTATION_ROADMAP.md** - `7d7aa9760` (docs)

**Plan metadata:** (pending - this commit)

## Files Created/Modified

**Created:**
- `.planning/phases/04-jamtrack-research-design/COMPONENT_DESIGN.md` - JKSessionJamTrackPlayer architecture
- `.planning/phases/04-jamtrack-research-design/REDUX_DESIGN.md` - Redux state structure and thunks
- `.planning/phases/04-jamtrack-research-design/IMPLEMENTATION_ROADMAP.md` - Phase 5 roadmap and risk analysis

**Modified:** None

## Decisions Made

### Component Architecture

**JKSessionJamTrackPlayer Structure:**
- **Props interface**: 11 props including isOpen, jamTrack, jamClient, session, currentUser, initialMixdownId, autoPlay
- **Local state**: UI-specific (isPlaying, isPaused, selectedMixdownId, error, isLoadingSync, isOperating)
- **Redux state**: Shared data (jamTrackState, downloadState, availableMixdowns)
- **10 sub-components**: Modular design for maintainability and reusability

**Initialization pattern:**
1. Build fqId from jamTrack.id and sample rate
2. Check sync state via `checkJamTrackSync` thunk
3. If not synchronized → trigger download flow
4. If synchronized → load JMEP (if exists) → play

**Cleanup pattern:**
- Stop playback on unmount via `closeJamTrack` thunk
- Clear local state
- Remove event listeners
- Prevents stale state bugs

**Props vs Redux Decision Matrix:**
- jamClient → Prop (non-serializable)
- Session data → Prop (passed from parent)
- Playback state → Redux (shared across components)
- Download state → Redux (shared, updated via WebSocket)
- UI preferences → Redux (persisted across sessions)

---

### Redux State Structure

**mediaSlice Extensions:**

```javascript
jamTrackState: {
  isPlaying: boolean,
  isPaused: boolean,
  currentPositionMs: number,
  durationMs: number,
  selectedMixdownId: number | null,
  playbackMode: 'master' | 'custom-mix' | 'stem',
  lastUpdate: timestamp
}

downloadState: {
  jamTrackId: number | null,
  mixdownId: number | null,
  fqId: string | null,
  state: 'idle' | 'checking' | 'downloading' | 'keying' | 'synchronized' | 'error',
  progress: number,
  currentStep: number,
  totalSteps: number,
  error: {...} | null
}
```

**6-State Download/Sync Machine:**
- `idle` → No download in progress
- `checking` → Checking sync state via `JamTrackGetTrackDetail(fqId)`
- `downloading` → Download in progress (0-100% progress)
- `keying` → Requesting decryption keys via `JamTrackKeysRequest()`
- `synchronized` → Ready to play
- `error` → Download failed (with error details)

**activeSessionSlice Extensions:**
- `availableMixdowns`: Array of mixdown objects (master, custom mixes, stems)
- `activeMixdown`: Currently selected mixdown object
- `mixdownCache`: Map of mixdown packages by ID (metadata for download)

**sessionUISlice Extensions:**
- `openJamTrack`: Currently open JamTrack ID (or null)
- `jamTrackUI`: User preferences (lastUsedMixdown, volume)

---

### Async Thunks

**1. loadJamTrack (enhanced)** - FIXES EXISTING BUG
- **Bug fixed**: Current implementation uses `jamTrack.id` instead of fqId format
- **Fix**: Build fqId from `jamTrack.id` and sample rate (`{jamTrackId}-{sampleRate}`)
- **Flow**: Check sync → download if needed → load JMEP → play

**2. downloadJamTrack**
- Get package ID via `pickMyPackage()` logic (filters by ogg/jkz/sample_rate)
- Set up global download callbacks (string names: `'jamTrackDownloadProgress'`, `'jamTrackDownloadSuccess'`, `'jamTrackDownloadFail'`)
- Call `JamTrackDownload()` with callbacks
- Poll progress via WebSocket `MIXDOWN_CHANGES`
- Request keys via `JamTrackKeysRequest()` when complete

**3. checkJamTrackSync**
- Call `JamTrackGetTrackDetail(fqId)`
- Return sync state, key state, package info
- Used during initialization

**4. loadJMEP**
- Load JMEP (Jam Enhancement Package) for tempo/pitch modifications
- Call `JamTrackLoadJmep(fqId, jmepData)` before playback
- Only if `jamTrack.jmep` exists

**5. seekJamTrack**
- Call `JamTrackSeekMs(fqId, positionMs)`
- Apply UAT-003 fix pattern (pending seek while paused)

**6. closeJamTrack**
- Stop playback if playing
- Clear jamTrackState and downloadState
- Cleanup to prevent stale state

---

### WebSocket Handlers

**1. MIXER_CHANGES (extended)**
- Existing handler for Backing Track mixers
- Extend to handle JamTrack mixdown changes
- Update `availableMixdowns` when mixdown list changes

**2. JAM_TRACK_CHANGES (new)**
- Handle playback state updates from native client
- Update `isPlaying`, `isPaused`, `currentPositionMs` in Redux
- Reduces polling frequency (only need duration)

**3. MIXDOWN_CHANGES (new)**
- Handle download/packaging progress during server-side mixdown creation
- Update `downloadState.currentStep` and `totalSteps`
- Used during download flow to show "Packaging... (step 2 of 5)"

---

### Phase 5 Roadmap Structure

**9 Preliminary Plans (to be refined during Phase 5 planning):**

1. **Redux Infrastructure & Bug Fixes** - Foundation, fix loadJamTrack bug
2. **Async Thunks & WebSocket Handlers** - Core async operations
3. **Player Core Structure** - Component skeleton, initialization, cleanup
4. **Playback Controls** - Play/pause/stop, polling, seek slider
5. **Mixdown Selection** - Mixdown picker UI, selection logic
6. **Download/Sync UI** - Progress bar, sync state machine UI
7. **Modal Updates** - Update JKSessionJamTrackModal for new props
8. **Error Handling & Edge Cases** - Comprehensive error handling
9. **Performance Optimization & Final UAT** - Performance tuning, UAT

**Dependency Graph:**
- Plans 1-2 are foundational (Redux + thunks)
- Plans 3-6 are sequential component development
- Plan 7 can run in parallel after Plan 3
- Plans 8-9 must be last

**Estimated Effort:**
- JamTrack is 2.5-3x more complex than Backing Track (Phase 3)
- Phase 3 took 3 plans → Phase 5 should take ~7-9 plans
- Preliminary breakdown shows 9 plans → reasonable estimate
- May consolidate to 7-8 plans during actual planning based on config depth

---

### Risk Analysis

**HIGH Risks:**

**Risk 1: Download/Sync State Machine Complexity**
- 6-state machine vs Backing Track's simple load
- Legacy CoffeeScript has race conditions
- **Mitigation**: Reference legacy closely, add diagnostic logging, use Redux DevTools
- **Contingency**: Fall back to polling if WebSocket unreliable

**Risk 2: Native Client Race Conditions**
- Phase 3 encountered multiple race conditions (Issues 1-3)
- JamTrack has MORE async complexity → expect similar or worse
- **Mitigation**: Apply Phase 3 lessons (verification delays, pending state pattern, state machine guards)
- **Contingency**: Defer complex issues to future work (like Phase 3)

**MEDIUM Risks:**

**Risk 3: fqId Format Bugs Throughout Codebase**
- Identified bug in loadJamTrack thunk
- May exist in other places (modal, stems, other thunks)
- **Mitigation**: Audit all JamTrack code in Plan 1, create helper function `buildFqId()`
- **Contingency**: Add Plan 1.5 for comprehensive fqId audit

**Risk 4: Mixdown Selection Logic Complexity**
- `pickMyPackage()` has 50+ lines of filtering logic
- Must replicate accurately or downloads fail
- **Mitigation**: Study legacy implementation, unit tests, test with various JamTracks
- **Contingency**: Simplify initial implementation (master only), add advanced features later

**Risk 5: JMEP Support**
- Unclear if required or optional
- Error handling unclear
- **Mitigation**: Check if `jamTrack.jmep` exists before loading, test with/without JMEP
- **Contingency**: Make optional, log warning if fails

**Risk 6: WebSocket Handler Integration**
- Integration code not well-documented
- Must locate handler registration point
- **Mitigation**: Reference existing handlers, verify Protocol Buffer format
- **Contingency**: Fall back to polling

---

### Critical Decisions Deferred to Phase 5

**Decision 1: Popup Mode Support**
- Should JamTrack support popup window mode like Backing Track?
- **Recommendation**: Option A - Support both modes, document limitations
- **Impact**: Affects Plan 3 and Plan 9 UAT

**Decision 2: Stem Control Integration**
- Embed stem controls in player or keep separate?
- **Recommendation**: Option B - Keep separate, communicate via Redux
- **Impact**: Affects Plan 5 scope

**Decision 3: Error Recovery Strategy**
- Auto-retry with exponential backoff vs user-initiated retry?
- **Recommendation**: Option C - Hybrid (auto-retry transient, user retry fatal)
- **Impact**: Affects Plan 8 error handling tasks

**Decision 4: Download Cancellation**
- Should users be able to cancel in-progress downloads?
- **Recommendation**: Option A - Implement cancellation
- **Impact**: Affects Plan 6 download UI (+1 task)

**Decision 5: UAT Deferral Threshold**
- What severity threshold for deferring UAT issues?
- **Recommendation**: Option B - Defer minor only, fix medium+
- **Impact**: May need Plan 10 for critical UAT fixes

---

### Testing Strategy

**Unit Testing:**
- Redux reducers (all new state updates)
- Redux selectors (computed values)
- Async thunks (success + error paths)
- Helper functions (`buildFqId`, `pickMyPackage`, `formatTime`)

**Integration Testing:**
- Component + Redux (actions trigger updates)
- WebSocket + Redux (messages update state)
- jamClient + Redux (full user flows)

**Manual Testing (UAT):**
- 40+ test cases across 8 categories:
  - Initialization (4 cases)
  - Download/Sync (6 cases)
  - Playback Controls (7 cases)
  - Mixdown Selection (5 cases)
  - Display (5 cases)
  - Performance (4 cases)
  - Edge Cases (10 cases)
  - Cleanup (5 cases)

**Regression Testing:**
- Verify Backing Track still works (no regressions)
- Verify JamTrack modal/stems still work

---

## Deviations from Plan

None - plan executed exactly as written.

## Issues Encountered

None - all design tasks completed successfully based on Phase 4 Plan 1 documentation.

## Next Phase Readiness

**Phase 4 Complete** - Ready to proceed to Phase 5 (JamTrack Implementation)

**Design artifacts created:**
- ✓ Component architecture (JKSessionJamTrackPlayer with 10 sub-components)
- ✓ Redux state structure (3 slices extended, 6 thunks, 3 WebSocket handlers)
- ✓ Phase 5 roadmap (9 preliminary plans with dependency graph)
- ✓ Risk analysis (2 HIGH, 4 MEDIUM, 2 LOW risks with mitigation)
- ✓ Testing strategy (unit, integration, UAT with 40+ test cases)
- ✓ Success metrics (functional completeness, code quality, UX)

**Key insights for Phase 5:**
1. **Complexity multiplier**: JamTrack is 2.5-3x more complex than Backing Track
2. **High-risk areas**: Download/sync state machine, native client race conditions
3. **Critical bug fix**: loadJamTrack thunk uses wrong ID format (MUST fix in Plan 1)
4. **Reuse patterns**: Apply Phase 3 error handling, loading states, performance optimizations
5. **Expect deferrals**: Like Phase 3, expect 2-4 issues deferred to future work

**Phase 5 execution path:**
1. `/clear` to free context window
2. `/gsd:plan-phase 5` to create executable PLAN.md files
3. Refine 9 preliminary plans based on config depth
4. Finalize 5 critical decisions (popup mode, stem controls, etc.)
5. Execute plans with atomic commits per task

**Architectural foundation solid:**
- Component design follows established patterns from Phase 3
- Redux extensions logical and well-scoped
- Risk mitigation strategies clear
- Testing strategy comprehensive
- Dependencies mapped, critical path identified

**Ready for implementation.**

---
*Phase: 04-jamtrack-research-design*
*Completed: 2026-01-14*
