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>
This commit is contained in:
Cal Corum 2026-02-26 23:58:55 -06:00
parent db3822565c
commit 931416a7c7

View File

@ -0,0 +1,89 @@
# 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_singles``wh_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.