Standardize formatting with black and apply ruff auto-fixes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
119 lines
3.8 KiB
Python
119 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Comprehensive validation script to check for negative values in batting cards.
|
|
Checks all numeric fields that should never be negative.
|
|
"""
|
|
|
|
import asyncio
|
|
from db_calls import db_get
|
|
|
|
|
|
async def validate_batting_cards(cardset_id=27):
|
|
"""Check all batting cards for negative values in any field."""
|
|
|
|
print(f"Checking batting cards for cardset {cardset_id}...")
|
|
print("=" * 70)
|
|
|
|
# Get all batting cards for the cardset directly
|
|
batting_cards_response = await db_get(
|
|
"battingcards", params=[("cardset", cardset_id)]
|
|
)
|
|
|
|
if not batting_cards_response:
|
|
print(f"❌ No response from battingcards endpoint for cardset {cardset_id}")
|
|
return False
|
|
|
|
# Extract batting cards list - API returns 'cards' key
|
|
batting_cards = batting_cards_response.get("cards", [])
|
|
|
|
if not batting_cards:
|
|
print(f"❌ No batting cards found for cardset {cardset_id}")
|
|
return False
|
|
|
|
print(f"Found {len(batting_cards)} batting cards in cardset")
|
|
print()
|
|
|
|
# Check all cards
|
|
all_errors = []
|
|
cards_checked = 0
|
|
|
|
for card in batting_cards:
|
|
cards_checked += 1
|
|
card_id = card.get("id", "Unknown")
|
|
|
|
# Extract player info
|
|
player_info = card.get("player", {})
|
|
player_name = player_info.get("p_name", "Unknown")
|
|
player_id = player_info.get("player_id", "Unknown")
|
|
|
|
# Check all numeric fields
|
|
for field, value in card.items():
|
|
# Skip non-numeric or None values
|
|
if value is None or not isinstance(value, (int, float)):
|
|
continue
|
|
|
|
# Skip IDs and other fields that can be negative or are not relevant
|
|
if field in ["id", "player_id", "cardset", "variant"]:
|
|
continue
|
|
|
|
# Check for negative values in fields that should be non-negative
|
|
if value < 0:
|
|
# Most baseball stats should be >= 0
|
|
all_errors.append(
|
|
{
|
|
"card_id": card_id,
|
|
"player_name": player_name,
|
|
"player_id": player_id,
|
|
"field": field,
|
|
"value": value,
|
|
}
|
|
)
|
|
|
|
print(f"Checked {cards_checked} batting cards")
|
|
print()
|
|
|
|
if all_errors:
|
|
print(f"❌ VALIDATION ERRORS FOUND: {len(all_errors)} negative values")
|
|
print("=" * 70)
|
|
|
|
# Group by player
|
|
by_player = {}
|
|
for error in all_errors:
|
|
player_key = f"{error['player_id']} - {error['player_name']}"
|
|
if player_key not in by_player:
|
|
by_player[player_key] = []
|
|
by_player[player_key].append(error)
|
|
|
|
print(f"\nAffected players: {len(by_player)}")
|
|
print()
|
|
|
|
for player_key, player_errors in sorted(by_player.items()):
|
|
print(f"{player_key}:")
|
|
for error in player_errors:
|
|
print(
|
|
f" - Card {error['card_id']}: {error['field']} = {error['value']}"
|
|
)
|
|
|
|
print()
|
|
print("=" * 70)
|
|
print("🛑 DO NOT PROCEED WITH S3 UPLOAD")
|
|
print("These negative values will cause gameplay crashes!")
|
|
print()
|
|
print("Next steps:")
|
|
print("1. Identify root cause in card generation code")
|
|
print("2. Fix the calculation bug")
|
|
print("3. Re-run card generation (Step 2)")
|
|
print("4. Re-run this validation")
|
|
return False
|
|
else:
|
|
print("✅ No negative values found in any batting card fields")
|
|
print("✅ DATABASE VALIDATION PASSED")
|
|
print()
|
|
print("Safe to proceed with S3 upload (Step 6)")
|
|
return True
|
|
|
|
|
|
if __name__ == "__main__":
|
|
result = asyncio.run(validate_batting_cards(27))
|
|
exit(0 if result else 1)
|