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

90 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.