Implemented complete WebSocket integration for real-time player substitutions.
System is now 80% complete - only tests remain.
## WebSocket Events Implemented (600 lines)
### Event Handlers (backend/app/websocket/handlers.py):
1. request_pinch_hitter - Pinch hitter substitution
- Validates: game_id, player_out_lineup_id, player_in_card_id, team_id
- Executes: SubstitutionManager.pinch_hit()
- Broadcasts: player_substituted (all clients), substitution_confirmed (requester)
- Error codes: MISSING_FIELD, INVALID_FORMAT, NOT_CURRENT_BATTER, etc.
2. request_defensive_replacement - Defensive replacement
- Additional field: new_position (P, C, 1B, 2B, 3B, SS, LF, CF, RF)
- Executes: SubstitutionManager.defensive_replace()
- Same broadcast pattern as pinch hitter
3. request_pitching_change - Pitching change
- Validates minimum batters faced (handled in SubstitutionManager)
- Executes: SubstitutionManager.change_pitcher()
- Broadcasts new pitcher to all clients
4. get_lineup - Get active lineup for team
- Returns: lineup_data with all active players
- Uses: StateManager cache (O(1)) or database fallback
- Purpose: UI refresh after substitutions
### Event Pattern (follows existing handlers):
- Validate inputs (UUID format, required fields, game exists)
- Create SubstitutionManager instance with DatabaseOperations
- Execute substitution (validate → DB → state)
- Broadcast player_substituted to game room
- Send substitution_confirmed to requester
- Error handling with specific error codes
### Events Emitted:
- player_substituted (broadcast) - Includes: type, lineup IDs, position, batting_order
- substitution_confirmed (requester) - Success confirmation with new_lineup_id
- substitution_error (requester) - Validation error with error code
- lineup_data (requester) - Active lineup response
- error (requester) - Generic error
## Documentation Updates (350 lines)
### backend/app/websocket/CLAUDE.md:
- Complete handler documentation with examples
- Event data structures and response formats
- Error code reference (MISSING_FIELD, INVALID_FORMAT, NOT_CURRENT_BATTER, etc.)
- Client integration examples (JavaScript)
- Complete workflow diagrams
- Updated event summary table (+8 events)
- Updated Common Imports section
### .claude/implementation/ updates:
- NEXT_SESSION.md: Marked Task 1 complete, updated to 80% done
- SUBSTITUTION_SYSTEM_SUMMARY.md: Added WebSocket section, updated status
- GAMESTATE_REFACTOR_PLAN.md: Marked complete
- PHASE_3_OVERVIEW.md: Updated all phases to reflect completion
- phase-3e-COMPLETED.md: Created comprehensive completion doc
## Architecture
### DB-First Pattern (maintained):
```
Client Request → WebSocket Handler
↓
SubstitutionManager
├─ SubstitutionRules.validate_*()
├─ DatabaseOperations.create_substitution() (DB first!)
├─ StateManager.update_lineup_cache()
└─ Update GameState if applicable
↓
Success Responses
├─ player_substituted (broadcast to room)
└─ substitution_confirmed (to requester)
```
### Error Handling:
- Three-tier: ValidationError, GameValidationError, Exception
- Specific error codes for each failure type
- User-friendly error messages
- Comprehensive logging at each step
## Status Update
**Phase 3F Substitution System**: 80% Complete
- ✅ Core logic (SubstitutionRules, SubstitutionManager) - 1,027 lines
- ✅ Database operations (create_substitution, get_eligible_substitutes)
- ✅ WebSocket events (4 handlers) - 600 lines
- ✅ Documentation (350 lines)
- ⏳ Unit tests (20% remaining) - ~300 lines needed
- ⏳ Integration tests - ~400 lines needed
**Phase 3 Overall**: ~97% Complete
- Phase 3A-D (X-Check Core): 100%
- Phase 3E (GameState, Ratings, Redis, Testing): 100%
- Phase 3F (Substitutions): 80%
## Files Modified
backend/app/websocket/handlers.py (+600 lines)
backend/app/websocket/CLAUDE.md (+350 lines)
.claude/implementation/NEXT_SESSION.md (updated progress)
.claude/implementation/SUBSTITUTION_SYSTEM_SUMMARY.md (added WebSocket section)
.claude/implementation/GAMESTATE_REFACTOR_PLAN.md (marked complete)
.claude/implementation/PHASE_3_OVERVIEW.md (updated all phases)
.claude/implementation/phase-3e-COMPLETED.md (new file, 400+ lines)
## Next Steps
Remaining work (2-3 hours):
1. Unit tests for SubstitutionRules (~300 lines)
- 15+ pinch hitter tests
- 12+ defensive replacement tests
- 10+ pitching change tests
2. Integration tests for SubstitutionManager (~400 lines)
- Full DB + state sync flow
- State recovery verification
- Error handling and rollback
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
||
|---|---|---|
| .claude | ||
| backend | ||
| frontend-pd | ||
| frontend-sba | ||
| .dockerignore | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| prd-web-scorecard-1.1.md | ||
| QUICKSTART.md | ||
| README.md | ||
Paper Dynasty Real-Time Game Engine
Web-based real-time multiplayer baseball simulation platform replacing the legacy Google Sheets system.
Project Structure
strat-gameplay-webapp/
├── backend/ # FastAPI game engine
├── frontend-sba/ # SBA League Nuxt frontend
├── frontend-pd/ # PD League Nuxt frontend
├── .claude/ # Claude AI implementation guides
├── docker-compose.yml # Full stack orchestration
└── README.md # This file
Two Development Workflows
Option 1: Local Development (Recommended for Daily Work)
Best for: Fast hot-reload, quick iteration, debugging
Services:
- ✅ Backend runs locally (Python hot-reload)
- ✅ Frontends run locally (Nuxt hot-reload)
- ✅ Redis in Docker (lightweight)
- ✅ PostgreSQL on your existing server
Setup:
-
Environment Setup
# Copy environment template cp .env.example .env # Edit .env with your database credentials and API keys -
Start Redis (in one terminal)
cd backend docker-compose up -
Start Backend (in another terminal)
cd backend uv run python -m app.main # Or manually activate: source .venv/bin/activate && python -m app.mainBackend will be available at http://localhost:8000
-
Start SBA Frontend (in another terminal)
cd frontend-sba npm run devSBA frontend will be available at http://localhost:3000
-
Start PD Frontend (in another terminal)
cd frontend-pd npm run devPD frontend will be available at http://localhost:3001
Advantages:
- ⚡ Instant hot-reload on code changes
- 🐛 Easy debugging (native debuggers work)
- 💨 Fast startup times
- 🔧 Simple to restart individual services
Option 2: Full Docker Orchestration
Best for: Integration testing, demos, production-like environment
Services:
- ✅ Everything runs in containers
- ✅ Consistent environment
- ✅ One command to start everything
Setup:
-
Environment Setup
# Copy environment template cp .env.example .env # Edit .env with your database credentials and API keys -
Start Everything
# From project root docker-compose upOr run in background:
docker-compose up -d -
View Logs
# All services docker-compose logs -f # Specific service docker-compose logs -f backend docker-compose logs -f frontend-sba -
Stop Everything
docker-compose down
Advantages:
- 🎯 Production-like environment
- 🚀 One-command startup
- 🔄 Easy to share with team
- ✅ CI/CD ready
Development Commands
Backend
cd backend
# Install UV (one-time setup)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Run server
uv run python -m app.main
# Run tests
uv run pytest tests/ -v
# Code formatting
uv run black app/ tests/
# Linting
uv run flake8 app/ tests/
# Type checking
uv run mypy app/
Frontend
cd frontend-sba # or frontend-pd
# Install dependencies
npm install
# Run dev server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Lint
npm run lint
# Type check
npm run type-check
Database Setup
This project uses an existing PostgreSQL server. You need to manually create the database:
-- On your PostgreSQL server
CREATE DATABASE paperdynasty_dev;
CREATE USER paperdynasty WITH PASSWORD 'your-secure-password';
GRANT ALL PRIVILEGES ON DATABASE paperdynasty_dev TO paperdynasty;
Then update DATABASE_URL in .env:
DATABASE_URL=postgresql+asyncpg://paperdynasty:your-password@your-db-server:5432/paperdynasty_dev
Environment Variables
Copy .env.example to .env and configure:
Required
DATABASE_URL- PostgreSQL connection stringSECRET_KEY- Application secret key (at least 32 characters)DISCORD_CLIENT_ID- Discord OAuth client IDDISCORD_CLIENT_SECRET- Discord OAuth secretSBA_API_URL/SBA_API_KEY- SBA League API credentialsPD_API_URL/PD_API_KEY- PD League API credentials
Optional
REDIS_URL- Redis connection (auto-configured in Docker)CORS_ORIGINS- Allowed origins (defaults to localhost:3000,3001)
Available Services
When running, the following services are available:
| Service | URL | Description |
|---|---|---|
| Backend API | http://localhost:8000 | FastAPI REST API |
| Backend Docs | http://localhost:8000/docs | Interactive API documentation |
| SBA Frontend | http://localhost:3000 | SBA League web app |
| PD Frontend | http://localhost:3001 | PD League web app |
| Redis | localhost:6379 | Cache (not exposed via HTTP) |
Health Checks
# Backend health
curl http://localhost:8000/api/health
# Or visit in browser
open http://localhost:8000/api/health
Troubleshooting
Backend won't start
- Check
DATABASE_URLis correct in.env - Verify PostgreSQL database exists
- Ensure Redis is running (
docker-compose upin backend/) - Check logs for specific errors
Frontend won't connect to backend
- Verify backend is running at http://localhost:8000
- Check CORS settings in backend
.env - Clear browser cache and cookies
- Check browser console for errors
Docker containers won't start
- Ensure
.envfile exists with all required variables - Run
docker-compose downthendocker-compose upagain - Check
docker-compose logsfor specific errors - Verify no port conflicts (8000, 3000, 3001, 6379)
Database connection fails
- Verify PostgreSQL server is accessible
- Check firewall rules allow connection
- Confirm database and user exist
- Test connection with
psqldirectly
Documentation
- Full PRD: See
/prd-web-scorecard-1.1.md - Implementation Guide: See
.claude/implementation/00-index.md - Architecture Docs: See
.claude/implementation/directory
Tech Stack
Backend
- Framework: FastAPI (Python 3.13+)
- Package Manager: UV (modern Python package management)
- WebSocket: Socket.io
- Database: PostgreSQL 14+ with SQLAlchemy
- Cache: Redis 7
- Auth: Discord OAuth with JWT
Frontend
- Framework: Vue 3 + Nuxt 3
- Language: TypeScript
- Styling: Tailwind CSS
- State: Pinia
- WebSocket: Socket.io-client
Contributing
See .claude/implementation/ for detailed implementation guides and architecture documentation.
License
Proprietary - Paper Dynasty League System