7.1 KiB
MTG Card Interaction Pipeline - Code Review
Overview
The interaction pipeline consists of four main modules:
card_profile_extractor.py- Extracts structured profiles from MTGJSON datainteraction_determinator.py- Determines interactions between card pairsinteraction_recommender.py- Generates recommendations based on interactionsinteraction_pipeline.py- Orchestrates the full pipeline
Issues Found
1. Import Inconsistency (Critical)
File: interaction_pipeline.py
Issue: Complex import for sessionmaker
self.SessionLocal = __import__('sqlalchemy.orm', fromlist=['sessionmaker']).sessionmaker(bind=self.engine)
Fix: Use direct import at module level:
from sqlalchemy.orm import sessionmaker
# ...
self.SessionLocal = sessionmaker(bind=self.engine)
2. Type Hints Inconsistency (Medium)
File: interaction_pipeline.py
Issue: Inconsistent type hints
def extract_profiles(self, cards: List[Dict]) -> List: # Missing type parameter
def determine_interactions(self, profiles) -> dict: # Missing parameter type
Fix: Add proper type hints:
def extract_profiles(self, cards: List[Dict]) -> List[CardProfile]:
def determine_interactions(self, profiles: List[CardProfile]) -> dict:
3. Complex Conditional Logic (High)
File: interaction_pipeline.py
Issue: Nested ternary operators for synergy_type and counter_type determination
"synergy_type": "archetype" if interaction.metadata and interaction.metadata.get('common_archetypes') else
"mechanic" if interaction.metadata and interaction.metadata.get('mechanics') else
"mana" if interaction.metadata and interaction.metadata.get('colors') else
"combo" if interaction.metadata and interaction.metadata.get('card_a_targets') else
"support",
Fix: Extract to helper methods or use lookup dictionaries
4. Missing Validation (Medium)
File: interaction_pipeline.py
Issue: No validation for empty card lists or invalid data
Fix: Add validation at the start of methods
5. Evolution Type Mapping (High)
File: interaction_pipeline.py
Issue: Using interaction.interaction_type which is 'evolution' for all evolutions
Fix: Map to specific evolution types based on metadata
Recommended Fixes
Fix 1: Import Structure
# At top of file
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker
# In __init__
self.SessionLocal = sessionmaker(bind=self.engine)
Fix 2: Type Hints
def extract_profiles(self, cards: List[Dict]) -> List[CardProfile]:
return self.profile_extractor.extract_profiles_batch(cards)
def determine_interactions(self, profiles: List[CardProfile]) -> dict:
return self.determinator.determine_all_interactions(profiles)
Fix 3: Helper Methods for Type Determination
def _determine_synergy_type(self, interaction) -> str:
"""Determine synergy type from interaction metadata."""
metadata = interaction.metadata or {}
if 'common_archetypes' in metadata:
return 'archetype'
elif 'mechanics' in metadata:
return 'mechanic'
elif 'colors' in metadata:
return 'mana'
elif 'card_a_targets' in metadata:
return 'combo'
else:
return 'support'
def _determine_counter_type(self, interaction) -> str:
"""Determine counter type from interaction metadata."""
metadata = interaction.metadata or {}
if 'colors_a' in metadata:
return 'color'
elif 'power_a' in metadata:
return 'stats'
else:
return 'keyword'
def _determine_evolution_type(self, interaction) -> str:
"""Determine evolution type from interaction metadata."""
metadata = interaction.metadata or {}
if 'card_name' in metadata:
return 'reprint'
else:
return 'evolution'
Fix 4: Add Validation
def run_initial_load(self, set_code: Optional[str] = None):
"""Run initial load with validation."""
if not set_code:
logger.info("No set code provided, loading all cards")
all_cards = self.load_cards_from_db(set_code)
if not all_cards:
logger.warning("No cards found in database")
return
# Continue with processing...
Accuracy Review
Profile Extraction
✅ Correct: Color extraction from mana cost ✅ Correct: Mechanic extraction using regex patterns ✅ Correct: Archetype extraction from subtypes ✅ Correct: Target extraction from oracle text ✅ Correct: Trigger and effect extraction ✅ Correct: Theme extraction based on characteristics
Interaction Determination
✅ Correct: Archetype synergy detection ✅ Correct: Mana synergy detection ✅ Correct: Mechanic synergy detection (haste+trample, lifelink+combat) ✅ Correct: Combo synergy detection (targets + triggers) ✅ Correct: Support synergy detection ✅ Correct: Counter detection (color, stats, keywords) ✅ Correct: Evolution detection (reprints)
Database Schema
✅ Correct: Synergies table with proper constraints ✅ Correct: Counters table with proper constraints ✅ Correct: Evolutions table with proper constraints ✅ Correct: Statistics table with proper aggregations ✅ Correct: Foreign key relationships ✅ Correct: Unique constraints to prevent duplicates
Consistency Issues
1. File Organization
- All files in
/home/wall-o/projects/mtgonline/backend/scripts/ - No clear separation between core logic and pipeline
- Recommendation: Keep as is for simplicity
2. Naming Conventions
- Good: Consistent use of snake_case for methods
- Good: Consistent use of CamelCase for classes
- Issue: Mixed use of
set_codeparameter naming - Recommendation: Standardize on
set_code
3. Error Handling
- Good: Try/finally blocks for database connections
- Issue: No specific exception handling for database errors
- Recommendation: Add specific exception types
4. Logging
- Good: Consistent logging format
- Good: Appropriate log levels (INFO, WARNING, ERROR)
- Issue: Missing DEBUG logging for development
- Recommendation: Add DEBUG level logging
Summary
Critical Issues (Must Fix)
- ❌ Import structure for sessionmaker
- ❌ Complex conditional logic for type determination
High Priority Issues (Should Fix)
- ❌ Missing type hints
- ❌ Evolution type mapping
- ❌ Missing validation
Medium Priority Issues (Nice to Have)
- ⚠️ Add specific exception handling
- ⚠️ Add DEBUG logging
- ⚠️ Standardize parameter naming
Low Priority Issues (Can Defer)
- ✅ All core logic is accurate and correct
- ✅ Database schema is well-designed
- ✅ Interaction determination logic is sound
Next Steps
- Fix Critical Issues: Update import structure and simplify conditional logic
- Fix High Priority: Add proper type hints and validation
- Test: Run pipeline with sample data to verify functionality
- Document: Add docstrings and inline comments for complex logic