- Add position coverage, IL players, missing card warnings, and detailed
sync status sections to the dashboard
- Fix team sync to include IL/MiL teams (active_only=false), matching
Python behavior so get_my_roster() finds WVIL/WVMiL teams
- Re-fetch all dashboard data after successful sync so changes reflect
immediately without navigating away
- Add sWAR budget bar (90-100% range) with color thresholds from
Team.salary_cap
- Add team-scoped missing card queries and bulk sync status query
- Mark Phase 2 and Phase 3 project plans as complete
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
API returns move_id as string ("Season-013-Week-11-1772073335"), not
i64. Also disable foreign_keys at pool level via SqliteConnectOptions
since transactions reference players/teams that may not exist locally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The API returns gmid/gmid2 as quoted strings ("258104532423147520")
to avoid JavaScript precision loss. Changed types to Option<String>.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Errors were only visible in the truncated status bar notification.
Add tracing-appender to write to data/sba-scout.log with env-filter
support (RUST_LOG), and add tracing::error! calls alongside all
notification-only error paths for full diagnostic visibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace blocking event loop with tokio::select! over EventStream, mpsc
channel, and tick interval. Add message bus architecture with AppMessage
enum for background task results. Implement Dashboard with roster summary
cards and API sync, and Gameday with cascading team/pitcher selectors,
matchup table, and 9-slot lineup management with save/load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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