Port the Python calc layer to Rust: league stat distributions (avg excludes zeros,
stdev N-1 includes zeros), weighted standardized matchup scoring with switch-hitter
resolution and pitcher inversion, and SHA-256-validated score cache with automatic
rebuild after card imports. 105 tests passing (76 unit + 5 integration + 24 DB).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port the full data ingestion layer from Python to Rust:
- Typed API client with 10 endpoints, serde response types, and error handling
- Team/player/transaction sync with proper upsert semantics (preserves hand field)
- Batter and pitcher CSV importers with 40+ column mappings each
- Parse helpers for float/int/endurance with 21 unit tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set up lib.rs for integration test access, add 50 tests covering
calc engine (weights, standardization), model helpers (Player positions,
Lineup JSON roundtrips), and full query layer (in-memory SQLite).
Update PHASE1_PROJECT_PLAN.json to reflect all 12 tasks completed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire up the full data pipeline for the Rust TUI rewrite:
- SQL schema creation for all 9 tables with correct types, FKs, and constraints
- 20 async query functions (teams, players, cards, lineups, sync status, cache)
- Config loading via figment integrated into main.rs startup flow
- App struct now holds SqlitePool and Settings for screen access
- Roster aggregate query and Lineup JSON helper methods
- Added csv, sha2, regex crates for upcoming phases
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Initialize rust/ subdirectory with ratatui + tokio + sqlx stack,
mirroring the Python module structure. Includes all DB models,
config loader, matchup scoring logic, and screen stubs that
compile cleanly with cargo check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Redirect all logging to data/logs/sba_scout.log instead of stderr
- Prevents log output from corrupting the Textual TUI display
- Add loading spinner for sync operations to show progress
- Improve error messages for Cloudflare/API errors
- Add TROUBLESHOOTING.md guide for common sync issues
- Exclude data/ directory from git
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix bug where clicking to select a player in the middle of the lineup
would operate on the last added player instead of the clicked row
- Deselect now requires clicking the same row twice (for screenshots)
- Clicking the table after deselect re-enables selection mode
- Fix main.py to actually launch the TUI app
- Add CLAUDE.md with codebase documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New Settings screen (press 'x') for configuring app settings
- Settings stored in data/settings.yaml (user-editable)
- Editable fields: team abbrev, season, API URL, API key (masked), theme
- Team validation against database before saving
- Read-only team info display from database (name, sWAR cap, ID)
- Load order: defaults -> .env -> settings.yaml
- Added pyyaml dependency
Features:
- Lineup Builder screen: set batting order, assign positions, save/load lineups
- Gameday screen: integrated matchup scout + lineup builder side-by-side
- Matchup Scout: analyze batters vs opposing pitchers with standardized scoring
- Standardized scoring system with league AVG/STDEV calculations
- Score caching for fast matchup lookups
Lineup Builder (press 'l'):
- Dual-panel UI with available batters and 9-slot lineup
- Keyboard controls: a=add, r=remove, k/j=reorder, p=change position
- Save/load named lineups, delete saved lineups with 'd'
Gameday screen (press 'g'):
- Left panel: team/pitcher selection with matchup ratings
- Right panel: lineup builder with live matchup ratings per batter
- Players in lineup marked with * in matchup list
- Click highlighted row to toggle selection for screenshots
Other changes:
- Dynamic season configuration (removed hardcoded season=13)
- Added delete_lineup query function
- StandardizedScoreCache model for pre-computed scores
- Auto-rebuild score cache after card imports