paper-dynasty-card-creation/docs/FULLCARD_MIGRATION_STATUS.md
Cal Corum 931416a7c7 Add FullCard migration status doc for session continuity
Documents current branch state, what's built, what's left,
known bugs, and decision points so the next session can pick
up without re-investigating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:58:55 -06:00

5.2 KiB
Raw Permalink Blame History

FullCard Migration Status

Branch: feature/fullcard-migration (5 commits ahead of main) Last Updated: 2026-02-26

What This Branch Does

Moves card-building logic (fitting continuous chances to discrete 2d6×d20 card mechanics) from the database to Python. Previously, Python sent raw continuous values and the database fitted them — meaning what you sent ≠ what got stored. Now Python builds the complete discrete card structure before POSTing.

New Files

File Purpose
card_layout.py Core card models: PlayResult, CardResult, CardColumn, FullCard, FullBattingCard, FullPitchingCard. Ported from database's card_creation.py. Uses col_* key names.
batters/card_builder.py build_batter_full_cards() — takes vL/vR ratings, returns two FullBattingCard objects
pitchers/card_builder.py build_pitcher_full_cards() — same for pitchers
batters/models.py Extracted BattingCardRatingsModel from calcs_batter.py
pitchers/models.py Extracted PitchingCardRatingsModel from calcs_pitcher.py
offense_col_resolver.py Maps player→offense_col for retrosheet pipeline (fixed 883 silent KeyErrors)
tests/test_rate_stats_formulas.py Tests for extracted rating model formulas

Integration Path

retrosheet_data.py → calcs_batter.py → build_batter_full_cards() → card_output() → vl_dict.update()
                   → calcs_pitcher.py → build_pitcher_full_cards() → card_output() → vr_dict.update()

Card builders are called inside a try/except in calcs_batter.py:339 and calcs_pitcher.py:134. On failure, logs a warning and the card still posts without col_* layout data (backwards compatible).

Commits on Branch

  1. a72abc0 — Add FullCard/CardColumn/CardResult models and card builder pipeline
  2. 39c652e — Extract BattingCardRatingsModel and PitchingCardRatingsModel into models.py files
  3. 2bf3a6c — Fix SLG formula drift in extracted rating models
  4. 32cadb1 — Fix two bugs in pitcher card builder dispatch logic
  5. db38225 — Add offense_col resolver for retrosheet pipeline to fix 883 silent KeyErrors

What's Left Before Merge

1. Database Migration (BLOCKING if you want col_* data persisted)

The database repo (paper-dynasty-database) has a parallel feature/fullcard-migration branch with:

  • 9 new nullable TextFields on BattingCardRatings and PitchingCardRatings tables
  • Pydantic model updates in routers_v2/battingcardratings.py and pitchingcardratings.py
  • Migration SQL documented but intentionally not run

Without this migration, the col_* fields in card_output() are computed but silently ignored by the API. The card-creation side works either way — it's a no-op until the DB accepts those fields.

2. live_series_update.py Not Integrated

This file has its own inline card generation — does NOT use calcs_batter/calcs_pitcher. Only the retrosheet pipeline benefits from the new card builders. Live series integration is a separate effort.

3. No Tests for Core New Code

card_layout.py (1015 lines), batters/card_builder.py (802 lines), pitchers/card_builder.py (776 lines) have zero test coverage. Priority targets:

  • get_chances() — maps continuous values to discrete EXACT_CHANCES
  • CardColumn.add_result() / FullCard.card_fill() — the filling algorithm
  • card_output() — serialization to col_* dict format
  • End-to-end: feed known ratings → assert expected card structure

4. Test Failures (Pre-existing, Not From This Branch)

  • test_wh_singleswh_singles(12, .45) returns 8.0 vs expected Decimal('7.95'). Fails on main too. The test file has a 1-line diff on this branch (import change).
  • 11 failures in test_automated_data_fetcher.py — mock setup issues, no diff on this branch.

Key Bugs Fixed During Development

  1. Float/Decimal mismatch — card_layout uses Decimal internally, models use float. Fix: wrap card_fill() outputs with float() in assign_bchances()/assign_pchances().
  2. PitchingCardRatingsModel xcheck defaults — Non-zero defaults (xcheck_ss=7.0, etc.) corrupted accumulation. Fix: explicitly zero all xcheck fields in new_ratings constructor.
  3. Pitcher dispatch logic — Two bugs in how pitcher card builder routed plays to columns.
  4. offense_col KeyError — Retrosheet pipeline had no offense_col resolver, causing 883 silent failures.

Architecture Reference

Full design doc: docs/architecture/CARD_BUILDER_REDESIGN.md

Migration phases:

  • Phase 1 (Extract & Validate) — Done
  • Phase 2 (Python Adoption) — In progress (retrosheet pipeline wired up)
  • Phase 3 (Database Simplification) — Pending DB migration + removing fitting logic from DB
  • Phase 4 (Enhancements) — Future (contracts/card personalities, preview endpoint)

Decision Points for Next Session

  1. Merge as-is? Branch is safe to merge — col_* fields are computed but harmlessly ignored until DB migrates. Card generation behavior is unchanged.
  2. Add tests first? Recommended but not strictly required since card builders are behind try/except.
  3. Run DB migration? Enables end-to-end persistence. Requires deploying database branch too.
  4. Wire up live series? Separate PR recommended — different pipeline, different concerns.