--- title: Paper Dynasty Database Release — 2026.3.17 description: Database migration and schema changes for Paper Dynasty on 2026-03-17. type: reference domain: paper-dynasty tags: [paper-dynasty, deployment, release-notes, database] --- # Paper Dynasty Database Release — 2026.3.17 **Date:** 2026-03-17 **Branch:** next-release → main (PR #100, 27 commits) **Repo:** cal/paper-dynasty-database **Server:** pddev.manticorum.com:816 ## Release Summary Major release adding the evolution system foundation, render pipeline improvements, query performance fixes, and infrastructure hardening. This is the first release cut from the next-release branch for this repo. ## Evolution System (Card Evolution Phase 1) The core backend for the card evolution feature. Cards can now progress through tiers based on accumulated player stats across seasons. - **Season stats model** (`app/models/season_stats.py`): `BattingSeasonStats` and `PitchingSeasonStats` Peewee models for per-player, per-team, per-season stat accumulators. Originally a single `PlayerSeasonStats` model, refactored mid-cycle to split batting/pitching and rename `so`→`so_batter`, `k`→`so_pitcher` for clarity. - **Season stats CRUD** (`app/routers_v2/season_stats.py`): Full REST endpoints for reading/writing season stats. - **Track catalog API** (`app/routers_v2/evolution.py`, WP-06): `GET /api/v2/evolution/tracks` and `GET /api/v2/evolution/tracks/{id}` endpoints serving the three universal tracks (Batter, SP, RP) with tier thresholds. - **Formula engine** (`app/services/formula_engine.py`, WP-09): Computes evolution value from career stats. Handles batter OPS-based formula and pitcher ERA/WHIP/K-based formula with split weighting. - **Evolution seed data** (`app/seed/evolution_tracks.py`, WP-03): Seed script and JSON for the three base tracks with t1-t4 thresholds. ### Tests Added - `tests/test_formula_engine.py` — 188 lines covering batter/pitcher value computation - `tests/test_evolution_seed.py` — 119 lines validating seed data structure and idempotency - `tests/test_evolution_track_api.py` — 132 lines for track catalog endpoints - `tests/test_season_stats_model.py` — 451 lines for the stats model CRUD ## Render Pipeline - **Persistent browser instance** (WP-02, `#89`): Playwright Chromium browser is now launched once at startup via FastAPI lifespan hooks and reused across all card render requests. Eliminates ~1-1.5s per-request launch/teardown overhead. Uses `asyncio.Lock` to prevent concurrent launch races and error-tolerant shutdown. - **Dockerfile optimization**: Multi-stage build, switched to `python:3.11-slim-bookworm` for Playwright compatibility, pinned base image. ## Query Performance - **Batch Paperdex lookups** (`#17`): Replaced N+1 per-player Paperdex queries with a single batch `WHERE player_id IN (...)` query in both `get_players` and `get_random_player` endpoints. - **Materialize queryset** (`get_random_player`): Added `list()` call before double-iteration to prevent queryset exhaustion. ## Bug Fixes - **Pitcher OPS split weighting** (`#6`): Use `max()` instead of incorrect weighting for pitcher OPS formula - **Remove stub endpoint** (`#11`): Deleted unimplemented `live_update_pitching` endpoint that returned 501 - **Docker build fixes**: Removed Docker Hub registry cache (blob limits), pinned base image for Playwright compatibility ## Infrastructure - `pyproject.toml` added for ruff configuration - `requirements.txt` pinned all dependency versions (`#64`) ## Merge Conflict Resolution **Files:** `app/main.py`, `app/routers_v2/players.py` **Cause:** Main had the Phase 0 render pipeline optimization (PR #94 — asyncio.Lock, `--no-sandbox` args, error-tolerant shutdown). Next-release had an earlier version of the same persistent browser feature (`#89` — simpler, no lock, no error handling). **Resolution:** Kept main's version (the more robust implementation) for all browser-related code. Added the evolution router import/inclusion from next-release. ## Open PRs Still Targeting next-release After this release, 5 PRs remain open against next-release: | PR | Title | Status | |----|-------|--------| | #84 | SQL migration for evolution tables (WP-00) | Conflict | | #95 | Phase 0 benchmark script | Mergeable | | #96 | Self-hosted WOFF2 fonts | Mergeable | | #98 | WP-08 evaluate endpoint | Conflict | | #99 | Lifespan hooks for browser pre-warm | Conflict | PRs #98 and #99 conflict because they contain earlier versions of code already in main (evaluate endpoint and browser lifespan). PR #84 conflicts on shared test infrastructure files. These should be rebased or have conflicts resolved before merging into next-release.