Overview
Integrate with Baseball Savant to fetch expected statistics (xBA, xSLG, xwOBA) and Statcast metrics (exit velocity, barrel%, hard hit%, sprint speed).
Parent Issue
Part of #94 (WAR and Advanced Stats)
Data Source
Baseball Savant Expected Statistics Leaderboard:
https://baseballsavant.mlb.com/leaderboard/expected_statistics?type=batter&year={year}&min=q&csv=true
Fields to Ingest
Expected Stats (Batting):
xba - Expected Batting Average
xslg - Expected Slugging
xwoba - Expected wOBA
xwobacon - Expected wOBA on Contact
Statcast Metrics (Batting):
avg_exit_velocity - Average Exit Velocity
avg_launch_angle - Average Launch Angle
barrel_pct - Barrel %
hard_hit_pct - Hard Hit %
sprint_speed - Sprint Speed
Statcast Metrics (Pitching):
avg_exit_velocity_against - Exit Velocity Against
hard_hit_pct_against - Hard Hit % Against
whiff_pct - Whiff %
chase_pct - Chase %
Current Entity Fields
These columns already exist in PlayerBattingStats (from V12 migration):
xba, xslg, xwoba
avg_exit_velocity, avg_launch_angle, barrel_pct, hard_hit_pct
sprint_speed
And in PlayerPitchingStats:
avg_exit_velocity_against, hard_hit_pct_against
whiff_pct, chase_pct
These fields exist but are NOT currently populated!
Files to Create/Modify
Modify: ingestion/client/BaseballSavantClient.java
Add methods:
public Map <Integer , ExpectedStats > getExpectedStatsByPlayerId (Integer season );
public Map <Integer , StatcastMetrics > getStatcastMetricsByPlayerId (Integer season );
Create: ingestion/client/dto/ExpectedStatsData.java
public record ExpectedStatsData (
Integer playerId ,
BigDecimal xba ,
BigDecimal xslg ,
BigDecimal xwoba ,
BigDecimal avgExitVelocity ,
BigDecimal avgLaunchAngle ,
BigDecimal barrelPct ,
BigDecimal hardHitPct ,
BigDecimal sprintSpeed
) {}
Create: ingestion/service/StatcastIngestionService.java
@ Service
public class StatcastIngestionService {
public int syncExpectedStats (Integer season );
public int syncStatcastMetrics (Integer season );
}
Modify: ingestion/mapper/StatsMapper.java
Add method:
public void applyStatcastMetrics (PlayerBattingStats stats , ExpectedStatsData data );
public void applyStatcastMetrics (PlayerPitchingStats stats , PitchingStatcastData data );
Sync Strategy
Weekly sync (with OAA in Baseball Savant OAA Integration #172 )
Statcast data updates after each game but aggregates change slowly
Expected stats are season-level, update less frequently
Test Cases
CSV parsing for all expected stats fields
Player mapping works correctly
Null/missing values handled gracefully
Updates existing stats without overwriting other fields
Acceptance Criteria
Dependencies
Notes
The ExpectedStatsResponse.java and SeasonAdvancedResponse.java DTOs already exist but aren't integrated. This issue completes that integration.
Overview
Integrate with Baseball Savant to fetch expected statistics (xBA, xSLG, xwOBA) and Statcast metrics (exit velocity, barrel%, hard hit%, sprint speed).
Parent Issue
Part of #94 (WAR and Advanced Stats)
Data Source
Baseball Savant Expected Statistics Leaderboard:
Fields to Ingest
Expected Stats (Batting):
xba- Expected Batting Averagexslg- Expected Sluggingxwoba- Expected wOBAxwobacon- Expected wOBA on ContactStatcast Metrics (Batting):
avg_exit_velocity- Average Exit Velocityavg_launch_angle- Average Launch Anglebarrel_pct- Barrel %hard_hit_pct- Hard Hit %sprint_speed- Sprint SpeedStatcast Metrics (Pitching):
avg_exit_velocity_against- Exit Velocity Againsthard_hit_pct_against- Hard Hit % Againstwhiff_pct- Whiff %chase_pct- Chase %Current Entity Fields
These columns already exist in
PlayerBattingStats(from V12 migration):xba,xslg,xwobaavg_exit_velocity,avg_launch_angle,barrel_pct,hard_hit_pctsprint_speedAnd in
PlayerPitchingStats:avg_exit_velocity_against,hard_hit_pct_againstwhiff_pct,chase_pctThese fields exist but are NOT currently populated!
Files to Create/Modify
Modify:
ingestion/client/BaseballSavantClient.javaAdd methods:
Create:
ingestion/client/dto/ExpectedStatsData.javaCreate:
ingestion/service/StatcastIngestionService.javaModify:
ingestion/mapper/StatsMapper.javaAdd method:
Sync Strategy
Test Cases
Acceptance Criteria
Dependencies
Notes
The
ExpectedStatsResponse.javaandSeasonAdvancedResponse.javaDTOs already exist but aren't integrated. This issue completes that integration.