fix: calculate lob_2outs and rbipercent in SeasonPitchingStats (#28) #59
No reviewers
Labels
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/major-domo-database#59
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "ai/major-domo-database-28"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
lob_2outsandrbipercentinSeasonPitchingStatswere hardcoded to0.0in theupdate_season_pitching_stats()INSERT querypitching_statsCTE to compute both fromstratplaydata, using the same field semantics as the batting stats endpointWhat changed
app/dependencies.py—update_season_pitching_stats()CTE extended with two new computed columns:lob_2outs: sum of runners on 1st/2nd/3rd that were neither scored (on_*_final != 4) nor put out (on_*_final IS NOT NULL) when the pitcher's play resulted in the 3rd out (starting_outs + outs = 3). Mirrors the batting-sidecount_lo*_3outlogic.rbipercent:(SUM(rbi) - SUM(homerun)) / total_runners_on_base— RBI allowed (excluding HR, which don't require runners) per runner opportunity. Returns0.000if no runners were on base.The INSERT SELECT now references
ps.lob_2outs, ps.rbipercentinstead of0.0, 0.0.Other observations
app/routers_v3/stratplay/pitching.py:343still returns"lob_2outs": 0and"rbi%": 0with comments "Not available in current implementation" — that endpoint uses a different live aggregation path and is out of scope for this issue, but should be a follow-up.SeasonPitchingStatsmodel defines both fields asFloatField()(non-nullable); the new expressions produce numeric values, consistent with the schema.AI Code Review
Files Reviewed
app/dependencies.py(modified) —update_season_pitching_stats()CTE and INSERTFindings
Correctness
lob_2outsandrbipercentfaithfully replace the hardcoded0.0, 0.0placeholders.lob_2outslogic verified. The conditionon_*_final IS NOT NULL AND on_*_final != 4 AND starting_outs + outs = 3exactly mirrors the Peewee ORM equivalent inrouters_v3/stratplay/batting.py(count_lo*_3outaliases).IS NOT NULL= runner still on base;!= 4= didn't score;starting_outs + outs = 3= inning-ending play. Semantics are correct.rbipercentlogic verified.(SUM(rbi) - SUM(homerun)) / total_runners_on_basecorrectly uses start-of-play runner fields (on_first/on_second/on_third, not_final) for the denominator — runners on base represent opportunities. Division-by-zero is properly guarded withELSE 0.000.lob_2outs, rbipercent, re24) matches SELECT values (ps.lob_2outs, ps.rbipercent, COALESCE(ps.re24 * -1, 0.0)). ON CONFLICT UPDATE SET was already correct in the base branch.lob_2outsSQL produces an integer sum; model isFloatField(). PostgreSQL auto-casts on INSERT — no issue.rbipercentproducesDECIMALviaROUND(..., 3)— consistent withFloatField().on_first_finalfield existence confirmed —IntegerField(null=True)indb_engine.py:2156. All referenced fields (on_first,on_second,on_third,on_*_final,starting_outs,outs,rbi,homerun) are validstratplaycolumns.Security
send_webhook_message(line 484) — out of scope for this PR, tracked separately. The cosmetic reformatting of the surrounding block does not introduce or worsen this issue.Style & Conventions
Suggestions
lob_2outsmodel field isFloatField()but the computed SQL value is always a non-negative integer. This is harmless (PostgreSQL casts it), but if the column were redefined asIntegerFieldit would better represent the data type. Not blocking.app/routers_v3/stratplay/pitching.py:343still hardcodes"lob_2outs": 0and"rbi%": 0— acknowledged in the PR body as a follow-up. Worth creating a separate issue to track.Verdict: APPROVED
The implementation is correct and consistent with the existing batting-side field semantics. Both SQL expressions are logically sound, the INSERT/SELECT column alignment is verified, edge cases (empty runners, division by zero) are handled, and no new security issues are introduced.
Automated review by Claude PR Reviewer