Commit Graph

6 Commits

Author SHA1 Message Date
Cal Corum
569dc53c00 test: add Tier 1 and Tier 2 refractor system test cases
Implements all gap tests identified in the PO review for the refractor
card progression system (Phase 1 foundation).

TIER 1 (critical):
- T1-1: Negative singles guard in compute_batter_value — documents that
  hits=1, doubles=1, triples=1 produces singles=-1 and flows through
  unclamped (value=8.0, not 10.0)
- T1-2: SP tier boundary precision with floats — outs=29 (IP=9.666) stays
  T0, outs=30 (IP=10.0) promotes to T1; also covers T2 float boundary
- T1-3: evaluate-game with non-existent game_id returns 200 with empty results
- T1-4: Seed threshold ordering + positivity invariant (t1<t2<t3<t4, all >0)

TIER 2 (high):
- T2-1: fully_evolved=True persists when stats are zeroed or drop below
  previous tier — no-regression applies to both tier and fully_evolved flag
- T2-2: Parametrized edge cases for _determine_card_type: DH, C, 2B, empty
  string, None, and compound "SP/RP" (resolves to "sp", SP checked first)
- T2-3: evaluate-game with zero StratPlay rows returns empty batch result
- T2-4: GET /teams/{id}/refractors with valid team and zero states is empty
- T2-5: GET /teams/99999/refractors documents 200+empty (no team existence check)
- T2-6: POST /cards/{id}/evaluate with zero season stats stays at T0 value=0.0
- T2-9: Per-player error isolation — patches source module so router's local
  from-import picks up the patched version; one failure, one success = evaluated=1
- T2-10: Each card_type has exactly one RefractorTrack after seeding

All 101 tests pass (15 PostgreSQL-only tests skip without POSTGRES_HOST).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 09:02:30 -05:00
Cal Corum
b7dec3f231 refactor: rename evolution system to refractor
Complete rename of the card progression system from "Evolution" to
"Refractor" across all code, routes, models, services, seeds, and tests.

- Route prefix: /api/v2/evolution → /api/v2/refractor
- Model classes: EvolutionTrack → RefractorTrack, etc.
- 12 files renamed, 8 files content-edited
- New migration to rename DB tables
- 117 tests pass, no logic changes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:31:55 -05:00
Cal Corum
eba23369ca fix: align tier_from_value with DB model field names (t1_threshold)
formula_engine.tier_from_value read track.t1/t2/t3/t4 but the
EvolutionTrack model defines t1_threshold/t2_threshold/etc. Updated
both the function and test fixtures to use the _threshold suffix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 15:07:07 -05:00
Cal Corum
bd8e4578cc refactor: split PlayerSeasonStats into BattingSeasonStats and PitchingSeasonStats
Some checks failed
Build Docker Image / build (push) Has been cancelled
Separate batting and pitching into distinct tables with descriptive column
names. Eliminates naming collisions (so/k ambiguity) and column mismatches
between the ORM model and raw SQL. Each table now covers all aggregatable
fields from its source (BattingStat/PitchingStat) including sac, ibb, gidp,
earned_runs, runs_allowed, wild_pitches, balks, and games_started.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 09:43:22 -05:00
Cal Corum
4ed62dea2c refactor: rename PlayerSeasonStats so to so_batter and k to so_pitcher
All checks were successful
Build Docker Image / build (push) Successful in 8m41s
The single-letter `k` field was ambiguous and too short for comfortable use.
Rename to `so_pitcher` for clarity, and `so` to `so_batter` to distinguish
batting strikeouts from pitching strikeouts in the same model.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 09:31:52 -05:00
Cal Corum
40e988ac9d feat: formula engine for evolution value computation (WP-09)
Closes #74

Adds app/services/formula_engine.py with three pure formula functions
(compute_batter_value, compute_sp_value, compute_rp_value), a dispatch
helper (compute_value_for_track), and a tier classifier (tier_from_value).
Tier boundaries and thresholds match the locked seed data from WP-03.

Note: pitcher formulas use stats.k (not stats.so) to match the
PlayerSeasonStats model field name introduced in WP-02.

19 unit tests in tests/test_formula_engine.py — all pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 19:34:40 -05:00