major-domo-database/app/routers_v3/stratplay/models.py
Cal Corum 86f8495284
All checks were successful
Build Docker Image / build (pull_request) Successful in 2m32s
feat: Add group_by=sbaplayer to batting, pitching, and fielding endpoints
Enables career-total aggregation by real-world player identity (SbaPlayer)
across all seasons. JOINs StratPlay → Player to access Player.sbaplayer FK,
groups by that FK, and excludes players with null sbaplayer. Also refactors
stratplay router from single file into package and adds integration tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:42:14 -06:00

107 lines
2.4 KiB
Python

from typing import List, Literal
from pydantic import BaseModel, validator
POS_LIST = Literal[
"C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "P", "DH", "PH", "PR", "GHOST"
]
class PlayModel(BaseModel):
game_id: int
play_num: int
batter_id: int = None
batter_team_id: int = None
pitcher_id: int
pitcher_team_id: int = None
on_base_code: str
inning_half: Literal["top", "bot", "Top", "Bot"]
inning_num: int
batting_order: int
starting_outs: int
away_score: int
home_score: int
batter_pos: POS_LIST = None
on_first_id: int = None
on_first_final: int = None
on_second_id: int = None
on_second_final: int = None
on_third_id: int = None
on_third_final: int = None
batter_final: int = None
pa: int = 0
ab: int = 0
e_run: int = 0
run: int = 0
hit: int = 0
rbi: int = 0
double: int = 0
triple: int = 0
homerun: int = 0
bb: int = 0
so: int = 0
hbp: int = 0
sac: int = 0
ibb: int = 0
gidp: int = 0
bphr: int = 0
bpfo: int = 0
bp1b: int = 0
bplo: int = 0
sb: int = 0
cs: int = 0
outs: int = 0
wpa: float = 0
catcher_id: int = None
catcher_team_id: int = None
defender_id: int = None
defender_team_id: int = None
runner_id: int = None
runner_team_id: int = None
check_pos: POS_LIST = None
error: int = 0
wild_pitch: int = 0
passed_ball: int = 0
pick_off: int = 0
balk: int = 0
is_go_ahead: bool = False
is_tied: bool = False
is_new_inning: bool = False
hand_batting: str = None
hand_pitching: str = None
re24_primary: float = None
re24_running: float = None
@validator("on_first_final")
def no_final_if_no_runner_one(cls, v, values):
if values["on_first_id"] is None:
return None
return v
@validator("on_second_final")
def no_final_if_no_runner_two(cls, v, values):
if values["on_second_id"] is None:
return None
return v
@validator("on_third_final")
def no_final_if_no_runner_three(cls, v, values):
if values["on_third_id"] is None:
return None
return v
@validator("batter_final")
def no_final_if_no_batter(cls, v, values):
if values["batter_id"] is None:
return None
return v
class PlayList(BaseModel):
plays: List[PlayModel]