sba-scouting/CLAUDE.md
Cal Corum 3adc064a42 Fix Gameday lineup row selection and deselect behavior
- 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>
2026-01-28 13:47:03 -06:00

3.0 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

SBA Scout is a TUI (Terminal User Interface) application for SBA fantasy baseball scouting and team management. Built with Textual for the interface, SQLAlchemy for async database operations, and pydantic-settings for configuration.

Commands

# Install dependencies (use uv, not pip)
uv pip install -e .

# Run the application
sba-scout          # via console script
python main.py     # direct execution

# Lint code
ruff check src/
ruff check --fix src/   # auto-fix

# Format code
ruff format src/

There is no test suite currently (tests/ directory exists but is empty).

Architecture

Layer Structure

src/sba_scout/
├── api/           # External API integration
├── calc/          # Scoring and statistics calculations
├── db/            # SQLAlchemy models and queries
├── screens/       # Textual UI screens
├── app.py         # Main application and DashboardScreen
└── config.py      # Pydantic settings management

Data Flow

  1. API Layer (api/) syncs data from League API → SQLite database
  2. CSV Import (api/importer.py) loads batter/pitcher card data from spreadsheets
  3. Database Layer (db/) stores teams, players, cards, lineups
  4. Calc Layer (calc/) computes standardized matchup scores using league stats
  5. UI Layer (screens/, app.py) displays data via Textual TUI

Key Patterns

  • Async throughout: SQLAlchemy async with aiosqlite, httpx async client
  • Lazy singletons: get_settings() returns global Settings, database engine initialized on first use
  • Context managers: API client and database sessions use async with
  • Layered config: Pydantic defaults → .env file → data/settings.yaml (user editable)

Database Models (db/models.py)

Core models: Team, Player, BatterCard, PitcherCard, Lineup, MatchupCache, StandardizedScoreCache, SyncStatus, Transaction

Screens (screens/)

  • roster.py - Tabbed roster view (majors/minors/IL)
  • matchup.py - Batter vs pitcher analysis
  • lineup.py - Lineup builder with drag/drop
  • gameday.py - Combined matchup + lineup view
  • settings.py - Configuration UI with YAML persistence

Matchup Scoring System (calc/)

  • Standardizes stats to -3 to +3 range based on league averages/stdev
  • Handedness-aware (vLHP/vRHP for batters, vLHB/vRHB for pitchers)
  • Weighted composite scores with tier assignment (A/B/C/D/F)
  • Cached for performance in StandardizedScoreCache

Configuration

Environment variables use SBA_SCOUT_ prefix with __ for nesting:

  • SBA_SCOUT_API__BASE_URL
  • SBA_SCOUT_API__API_KEY
  • SBA_SCOUT_TEAM__TEAM_ABBREV

User settings saved to data/settings.yaml (editable via Settings screen or directly).

Code Style

  • Line length: 100 characters
  • Python 3.12+
  • Ruff rules: E, F, I, N, W, UP (standard + imports + naming + upgrades)