Pure functions for computing boosted card ratings when a player reaches a new Refractor tier. Batter boost applies fixed +0.5 to four offensive columns per tier; pitcher boost uses a 1.5 TB-budget priority algorithm. Both preserve the 108-sum invariant. - Create refractor_boost.py with apply_batter_boost, apply_pitcher_boost, and compute_variant_hash (Decimal arithmetic, zero-floor truncation) - Add RefractorBoostAudit model, Card.variant, BattingCard/PitchingCard image_url, RefractorCardState.variant fields to db_engine.py - Add migration SQL for refractor_card_state.variant column and refractor_boost_audit table (JSONB, UNIQUE constraint, transactional) - 26 unit tests covering 108-sum invariant, deltas, truncation, TB accounting, determinism, x-check protection, and variant hash behavior Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.9 KiB
PL/PgSQL
48 lines
1.9 KiB
PL/PgSQL
-- Migration: Refractor Phase 2 — rating boost support
|
|
-- Date: 2026-03-28
|
|
-- Purpose: Extends the Refractor system to track and audit rating boosts
|
|
-- applied at each tier-up. Adds a variant column to
|
|
-- refractor_card_state (mirrors card.variant for promoted copies)
|
|
-- and creates the refractor_boost_audit table to record the
|
|
-- boost delta, source card, and variant assigned at each tier.
|
|
--
|
|
-- Tables affected:
|
|
-- refractor_card_state — new column: variant INTEGER
|
|
-- refractor_boost_audit — new table
|
|
--
|
|
-- Run on dev first, verify with:
|
|
-- SELECT column_name FROM information_schema.columns
|
|
-- WHERE table_name = 'refractor_card_state'
|
|
-- AND column_name = 'variant';
|
|
-- SELECT count(*) FROM refractor_boost_audit;
|
|
--
|
|
-- Rollback: See DROP/ALTER statements at bottom of file
|
|
|
|
BEGIN;
|
|
|
|
-- Verify card.variant column exists (should be from Phase 1 migration).
|
|
-- If not present, uncomment:
|
|
-- ALTER TABLE card ADD COLUMN IF NOT EXISTS variant INTEGER DEFAULT NULL;
|
|
|
|
-- New columns on refractor_card_state (additive, no data migration needed)
|
|
ALTER TABLE refractor_card_state ADD COLUMN IF NOT EXISTS variant INTEGER;
|
|
|
|
-- Boost audit table: records what was applied at each tier-up
|
|
CREATE TABLE IF NOT EXISTS refractor_boost_audit (
|
|
id SERIAL PRIMARY KEY,
|
|
card_state_id INTEGER NOT NULL REFERENCES refractor_card_state(id) ON DELETE CASCADE,
|
|
tier SMALLINT NOT NULL,
|
|
battingcard_id INTEGER REFERENCES battingcard(id),
|
|
pitchingcard_id INTEGER REFERENCES pitchingcard(id),
|
|
variant_created INTEGER NOT NULL,
|
|
boost_delta_json JSONB NOT NULL,
|
|
applied_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
UNIQUE(card_state_id, tier) -- Prevent duplicate audit records on retry
|
|
);
|
|
|
|
COMMIT;
|
|
|
|
-- Rollback:
|
|
-- DROP TABLE IF EXISTS refractor_boost_audit;
|
|
-- ALTER TABLE refractor_card_state DROP COLUMN IF EXISTS variant;
|