# MTG Card Interaction Pipeline - Code Review

## Overview

The interaction pipeline consists of four main modules:
1. `card_profile_extractor.py` - Extracts structured profiles from MTGJSON data
2. `interaction_determinator.py` - Determines interactions between card pairs
3. `interaction_recommender.py` - Generates recommendations based on interactions
4. `interaction_pipeline.py` - Orchestrates the full pipeline

## Issues Found

### 1. Import Inconsistency (Critical)
**File**: `interaction_pipeline.py`
**Issue**: Complex import for `sessionmaker`
```python
self.SessionLocal = __import__('sqlalchemy.orm', fromlist=['sessionmaker']).sessionmaker(bind=self.engine)
```
**Fix**: Use direct import at module level:
```python
from sqlalchemy.orm import sessionmaker
# ...
self.SessionLocal = sessionmaker(bind=self.engine)
```

### 2. Type Hints Inconsistency (Medium)
**File**: `interaction_pipeline.py`
**Issue**: Inconsistent type hints
```python
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:
```python
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
```python
"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
```python
# 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
```python
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
```python
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
```python
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_code` parameter 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)
1. ❌ Import structure for sessionmaker
2. ❌ Complex conditional logic for type determination

### High Priority Issues (Should Fix)
3. ❌ Missing type hints
4. ❌ Evolution type mapping
5. ❌ Missing validation

### Medium Priority Issues (Nice to Have)
6. ⚠️ Add specific exception handling
7. ⚠️ Add DEBUG logging
8. ⚠️ Standardize parameter naming

### Low Priority Issues (Can Defer)
9. ✅ All core logic is accurate and correct
10. ✅ Database schema is well-designed
11. ✅ Interaction determination logic is sound

## Next Steps

1. **Fix Critical Issues**: Update import structure and simplify conditional logic
2. **Fix High Priority**: Add proper type hints and validation
3. **Test**: Run pipeline with sample data to verify functionality
4. **Document**: Add docstrings and inline comments for complex logic
