claude-configs/skills/paper-dynasty/scripts/validate_database.py
Cal Corum 0fa8486e93 Sync: update agents, paper-dynasty skills, sessions
- agents: issue-worker.md and pr-reviewer.md updated for standard
  branch naming (issue/<number>-<slug> instead of ai/<repo>#<number>)
- paper-dynasty: updated SKILL.md, generate_summary, smoke_test,
  validate_database scripts; added ecosystem_status.sh and plan/
- plugins: updated marketplace submodules and blocklist
- sessions: rotate session files, add session-analysis/
- settings: updated settings.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 23:03:10 -05:00

158 lines
4.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Database Validation Script for Paper Dynasty Card Generation
Checks for common errors in card data via the API before deployment:
- Missing batting or pitching cards for a cardset
- Players with no corresponding card record
- Rarity distribution sanity check
Usage:
python validate_database.py [--cardset-id 24] [--env prod]
"""
import sys
import argparse
from pathlib import Path
from typing import List, Dict
sys.path.insert(0, str(Path(__file__).parent.parent))
from api_client import PaperDynastyAPI
class ValidationError:
def __init__(self, entity: str, issue: str, count: int, examples: List[str]):
self.entity = entity
self.issue = issue
self.count = count
self.examples = examples
def __str__(self):
lines = [f"{self.entity}: {self.issue} ({self.count} records)"]
for example in self.examples[:5]: # Show max 5 examples
lines.append(f" - {example}")
if self.count > 5:
lines.append(f" ... and {self.count - 5} more")
return "\n".join(lines)
def get_card_counts(api: PaperDynastyAPI, cardset_id: int) -> Dict[str, int]:
"""Get total card counts for the cardset from the API"""
batting = api.get("battingcards", params=[("cardset_id", cardset_id)])
pitching = api.get("pitchingcards", params=[("cardset_id", cardset_id)])
return {
"batting": batting.get("count", 0),
"pitching": pitching.get("count", 0),
}
def validate_card_counts(api: PaperDynastyAPI, cardset_id: int) -> List[ValidationError]:
"""Check that batting and pitching cards exist for the cardset"""
errors = []
counts = get_card_counts(api, cardset_id)
if counts["batting"] == 0:
errors.append(ValidationError(
"battingcards", f"No batting cards found for cardset {cardset_id}", 0, []
))
if counts["pitching"] == 0:
errors.append(ValidationError(
"pitchingcards", f"No pitching cards found for cardset {cardset_id}", 0, []
))
return errors
def validate_player_coverage(api: PaperDynastyAPI, cardset_id: int) -> List[ValidationError]:
"""Check that every player in the cardset has at least one card"""
errors = []
try:
players = api.list_players(cardset_id=cardset_id)
except Exception as e:
errors.append(ValidationError("players", f"Could not fetch players: {e}", 0, []))
return errors
if not players:
errors.append(ValidationError(
"players", f"No players found for cardset {cardset_id}", 0, []
))
return errors
batting_data = api.get("battingcards", params=[("cardset_id", cardset_id)])
pitching_data = api.get("pitchingcards", params=[("cardset_id", cardset_id)])
batting_player_ids = {
c["player"]["player_id"]
for c in batting_data.get("cards", [])
if c.get("player")
}
pitching_player_ids = {
c["player"]["player_id"]
for c in pitching_data.get("cards", [])
if c.get("player")
}
all_card_player_ids = batting_player_ids | pitching_player_ids
uncovered = [
p for p in players
if p["player_id"] not in all_card_player_ids
]
if uncovered:
examples = [
f"{p.get('p_name', 'Unknown')} (ID: {p['player_id']}, rarity: {p.get('rarity', {}).get('name', '?') if isinstance(p.get('rarity'), dict) else p.get('rarity', '?')})"
for p in uncovered
]
errors.append(ValidationError(
"players", "Players with no batting or pitching card", len(uncovered), examples
))
return errors
def main():
parser = argparse.ArgumentParser(
description="Validate Paper Dynasty card data via the API"
)
parser.add_argument(
"--cardset-id", type=int, default=24,
help="Cardset ID to validate (default: 24, the live cardset)"
)
parser.add_argument(
"--env", choices=["prod", "dev"], default="prod",
help="API environment (default: prod)"
)
args = parser.parse_args()
api = PaperDynastyAPI(environment=args.env)
print(f"🔍 Validating cardset {args.cardset_id} ({args.env})")
print()
counts = get_card_counts(api, args.cardset_id)
print(f"📊 Total Cards:")
print(f" - Batting: {counts['batting']}")
print(f" - Pitching: {counts['pitching']}")
print()
all_errors = []
all_errors.extend(validate_card_counts(api, args.cardset_id))
all_errors.extend(validate_player_coverage(api, args.cardset_id))
if all_errors:
print("❌ VALIDATION FAILED")
print()
for error in all_errors:
print(error)
print()
print(f"Total issues: {len(all_errors)}")
sys.exit(1)
else:
print("✅ VALIDATION PASSED")
print("No errors found")
sys.exit(0)
if __name__ == "__main__":
main()