WP-08: Evaluate Endpoint #73

Closed
opened 2026-03-12 20:56:06 +00:00 by cal · 1 comment
Owner

Description

POST /v2/evolution/cards/{card_id}/evaluate — force-recalculates a card's evolution state from career totals (SUM across all player_season_stats rows for the player-team pair). Idempotent re-evaluation entry point for post-game callback and admin corrections.

Repo: database
Phase: 1b (API & Formula Engine)
Dependencies: WP-07, WP-05
Complexity: M

Evaluation Logic

  1. Load career totals: SUM all player_season_stats rows for (player_id, team_id) across all seasons
  2. Determine track from card_state.track_id
  3. Compute formula value (delegated to formula engine, WP-09)
  4. Compare value to track thresholds to determine new_tier
  5. Update card_state.current_value = computed value
  6. Update card_state.current_tier = max(current_tier, new_tier) — no regression
  7. Update card_state.fully_evolved = (new_tier >= 4)
  8. Update card_state.last_evaluated_at = NOW()

Files

  • Create: database/app/services/evolution_evaluator.py
  • Modify: database/app/routers_v2/evolution.py

Tests (write first in database/tests/test_evolution_evaluator.py)

  • Unit: tier assignment from value (e.g. value=50 → T1 for batter)
  • Unit: tier advancement (value=160 → T2)
  • Unit: partial progress (value=100, T2=149 → stays T1)
  • Unit: idempotency
  • Unit: fully evolved (value >= T4)
  • Unit: no regression (tier never decreases)
  • Integration: API endpoint returns updated state

Plan reference: docs/prd-evolution/PHASE1_PROJECT_PLAN.md WP-08

## Description `POST /v2/evolution/cards/{card_id}/evaluate` — force-recalculates a card's evolution state from career totals (SUM across all `player_season_stats` rows for the player-team pair). Idempotent re-evaluation entry point for post-game callback and admin corrections. **Repo:** `database` **Phase:** 1b (API & Formula Engine) **Dependencies:** WP-07, WP-05 **Complexity:** M ## Evaluation Logic 1. Load career totals: SUM all `player_season_stats` rows for (player_id, team_id) across all seasons 2. Determine track from `card_state.track_id` 3. Compute formula value (delegated to formula engine, WP-09) 4. Compare value to track thresholds to determine `new_tier` 5. Update `card_state.current_value = computed value` 6. Update `card_state.current_tier = max(current_tier, new_tier)` — no regression 7. Update `card_state.fully_evolved = (new_tier >= 4)` 8. Update `card_state.last_evaluated_at = NOW()` ## Files - **Create:** `database/app/services/evolution_evaluator.py` - **Modify:** `database/app/routers_v2/evolution.py` ## Tests (write first in `database/tests/test_evolution_evaluator.py`) - [ ] Unit: tier assignment from value (e.g. value=50 → T1 for batter) - [ ] Unit: tier advancement (value=160 → T2) - [ ] Unit: partial progress (value=100, T2=149 → stays T1) - [ ] Unit: idempotency - [ ] Unit: fully evolved (value >= T4) - [ ] Unit: no regression (tier never decreases) - [ ] Integration: API endpoint returns updated state **Plan reference:** `docs/prd-evolution/PHASE1_PROJECT_PLAN.md` WP-08
cal added this to the Card Evolution Phase 1 milestone 2026-03-12 20:59:12 +00:00
cal added the
evolution
phase-1b
labels 2026-03-12 20:59:23 +00:00
Claude added the
ai-working
label 2026-03-13 08:01:53 +00:00
Claude removed the
ai-working
label 2026-03-13 08:09:19 +00:00
Collaborator

PR #98 opened: #98

Implemented POST /api/v2/evolution/cards/{card_id}/evaluate with:

  • app/services/evolution_evaluator.py: evaluate_card(player_id, team_id) — sums career stats, computes tier via formula engine, updates card state with no-regression guarantee
  • app/routers_v2/evolution.py: endpoint resolves card_id → player/team via Card lookup, returns updated state dict
  • tests/test_evolution_evaluator.py: 15 unit tests (all pass) covering tier assignment, advancement, partial progress, idempotency, fully_evolved, no-regression, multi-season aggregation, missing state error

Models and formula engine are lazily imported so this is safely importable before WP-01/WP-05/WP-07/WP-09 merge.

PR #98 opened: https://git.manticorum.com/cal/paper-dynasty-database/pulls/98 Implemented `POST /api/v2/evolution/cards/{card_id}/evaluate` with: - `app/services/evolution_evaluator.py`: `evaluate_card(player_id, team_id)` — sums career stats, computes tier via formula engine, updates card state with no-regression guarantee - `app/routers_v2/evolution.py`: endpoint resolves card_id → player/team via Card lookup, returns updated state dict - `tests/test_evolution_evaluator.py`: 15 unit tests (all pass) covering tier assignment, advancement, partial progress, idempotency, fully_evolved, no-regression, multi-season aggregation, missing state error Models and formula engine are lazily imported so this is safely importable before WP-01/WP-05/WP-07/WP-09 merge.
Claude added the
ai-pr-opened
label 2026-03-13 08:09:30 +00:00
cal closed this issue 2026-03-18 20:31:55 +00:00
Sign in to join this conversation.
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/paper-dynasty-database#73
No description provided.