Frontend alignment with backend WebSocket protocol:
**Type System Fixes**:
- types/game.ts: Changed DecisionPhase to use 'awaiting_*' convention matching backend
- types/game.ts: Fixed PlayOutcome enum values to match backend string values (e.g., 'strikeout' not 'STRIKEOUT')
- types/game.ts: Added comprehensive play outcome types (groundball_a/b/c, flyout variants, x_check)
**Decision Detection**:
- store/game.ts: Updated decision detection to check both decision prompt AND gameState.decision_phase
- components: Updated all decision phase checks to use 'awaiting_defensive', 'awaiting_offensive', 'awaiting_stolen_base'
**WebSocket Enhancements**:
- useWebSocket.ts: Added game_joined event handler with success toast
- useWebSocket.ts: Fixed dice roll data - now receives d6_two_a and d6_two_b from server
- useWebSocket.ts: Request fresh game state after decision submissions to sync decision_phase
**New Constants**:
- constants/outcomes.ts: Created centralized PlayOutcome enum with display labels and descriptions
**Testing**:
- Updated test expectations for new decision phase naming
- All component tests passing
**Why**:
Eliminates confusion from dual naming conventions. Frontend now uses same vocabulary as backend.
Fixes runtime type errors from enum value mismatches.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Frontend refactor complete - updated TypeScript interfaces and OffensiveApproach
component to use new action-based system with smart filtering.
Changes:
- TypeScript interfaces: Replaced approach/hit_and_run/bunt_attempt with action field
- OffensiveApproach.vue: Complete refactor with 6 action choices and smart filtering
- Smart filtering: Automatically disables invalid actions based on game state
- Auto-reset: If current action becomes invalid, resets to swing_away
TypeScript updates (types/game.ts, types/websocket.ts):
- OffensiveDecision.action: 6 valid choices (swing_away, steal, check_jump,
hit_and_run, sac_bunt, squeeze_bunt)
- Removed deprecated fields: approach, hit_and_run, bunt_attempt
- OffensiveDecisionRequest updated to match
Component features:
- Smart filtering based on game state (runners, outs)
- Visual feedback for disabled actions with explanatory text
- Special handling notes for steal and squeeze_bunt
- Auto-reset to swing_away when actions become invalid
- Clean, modern UI with action icons and descriptions
Action requirements enforced in UI:
- check_jump: requires runner on base
- hit_and_run: requires runner on base
- sac_bunt: disabled with 2 outs
- squeeze_bunt: requires R3, disabled with 2 outs
- steal/swing_away: always available
Files modified:
- types/game.ts
- types/websocket.ts
- components/Decisions/OffensiveApproach.vue
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>