807 lines
20 KiB
Markdown
807 lines
20 KiB
Markdown
# EU-Utility Improvement Plan
|
|
|
|
**Comprehensive Code Review & Analysis**
|
|
**Date:** February 14, 2026
|
|
**Analyst:** AI Code Review System
|
|
**Scope:** Full codebase analysis of EU-Utility v2.0
|
|
|
|
---
|
|
|
|
## 1. Executive Summary
|
|
|
|
### Top 10 Critical Issues
|
|
|
|
| # | Issue | Severity | Impact | File(s) |
|
|
|---|-------|----------|--------|---------|
|
|
| 1 | **No Input Validation on File Operations** | Critical | Data corruption, security | `plugin_manager.py`, `settings.py`, multiple plugins |
|
|
| 2 | **Race Conditions in Event Bus** | Critical | Data loss, crashes | `event_bus.py` |
|
|
| 3 | **Missing Exception Handling in OCR Thread** | Critical | App crash | `game_reader/plugin.py` |
|
|
| 4 | **Hardcoded Paths Without Validation** | High | Cross-platform failures | `log_reader.py`, `settings.py` |
|
|
| 5 | **No Rate Limiting on Nexus API** | High | API bans, poor UX | `nexus_api.py` |
|
|
| 6 | **Memory Leaks in Plugin UI** | High | Performance degradation | `overlay_window.py`, plugins |
|
|
| 7 | **Unvalidated JSON Parsing** | High | Crashes on corrupt data | All plugins with data files |
|
|
| 8 | **No Cleanup of QThreads** | Medium | Resource leaks | `skill_scanner/plugin.py`, `game_reader/plugin.py` |
|
|
| 9 | **Missing Type Hints** | Medium | Maintenance burden | Entire codebase |
|
|
| 10 | **No Logging Framework** | Medium | Debugging difficulties | Entire codebase |
|
|
|
|
### Quick Stats
|
|
- **Total Files Analyzed:** 50+
|
|
- **Core Modules:** 15
|
|
- **Plugins:** 26
|
|
- **Lines of Code:** ~15,000+
|
|
- **Critical Issues:** 4
|
|
- **High Priority Issues:** 12
|
|
- **Medium Priority Issues:** 28
|
|
|
|
---
|
|
|
|
## 2. Architecture Review
|
|
|
|
### 2.1 Strengths
|
|
|
|
1. **Well-Structured Plugin System**
|
|
- Clean `BasePlugin` abstract class
|
|
- Proper lifecycle management (initialize, get_ui, shutdown)
|
|
- Good separation of concerns between core and plugins
|
|
|
|
2. **Comprehensive Service Layer**
|
|
- OCR Service with multiple backend support
|
|
- HTTP Client with caching and retry logic
|
|
- Event Bus with typed events
|
|
- Task Manager for background operations
|
|
|
|
3. **Cross-Platform Considerations**
|
|
- Windows-specific features gracefully degrade on Linux
|
|
- Platform detection in `window_manager.py`
|
|
- Fallback mechanisms for OCR backends
|
|
|
|
4. **Modern Python Patterns**
|
|
- Dataclasses for data structures
|
|
- Type hints (partial)
|
|
- Singleton pattern for services
|
|
- Context managers where appropriate
|
|
|
|
### 2.2 Weaknesses
|
|
|
|
1. **Tight Coupling to PyQt6**
|
|
- No abstraction layer for UI framework
|
|
- Difficult to test without GUI
|
|
- Blocks headless operation
|
|
|
|
2. **Global State Management**
|
|
- Heavy reliance on singletons
|
|
- Difficult to mock for testing
|
|
- Potential for circular imports
|
|
|
|
3. **No Dependency Injection**
|
|
- Services directly instantiate dependencies
|
|
- Hard to swap implementations
|
|
- Testing requires monkey-patching
|
|
|
|
4. **Inconsistent Error Handling**
|
|
- Mix of try/except, error returns, and exceptions
|
|
- No unified error response format
|
|
- Silent failures in many places
|
|
|
|
5. **Missing Abstraction Layers**
|
|
- Direct file system access everywhere
|
|
- No repository pattern for data access
|
|
- No configuration abstraction
|
|
|
|
---
|
|
|
|
## 3. Performance Analysis
|
|
|
|
### 3.1 Identified Bottlenecks
|
|
|
|
| Component | Issue | Impact | Recommendation |
|
|
|-----------|-------|--------|----------------|
|
|
| OCR Service | Synchronous initialization blocks UI | High startup delay | Move to background thread |
|
|
| Event Bus | Lock contention on high-frequency events | Reduced throughput | Use lock-free queues |
|
|
| HTTP Client | Blocking I/O in main thread | UI freezing | Use async/await |
|
|
| Plugin Manager | Synchronous plugin discovery | Slow startup | Lazy loading |
|
|
| Log Reader | 500ms polling interval | CPU waste | Use file system events |
|
|
| Screenshot | Full-screen capture on every OCR | Memory pressure | Region-based capture |
|
|
|
|
### 3.2 Memory Usage Issues
|
|
|
|
1. **Unbounded Caches**
|
|
- `EventBus` history limited to 1000 events (good)
|
|
- `HTTPClient` cache has no size limit (bad)
|
|
- Plugin data files loaded entirely into memory (bad)
|
|
|
|
2. **UI Widget Leaks**
|
|
```python
|
|
# In overlay_window.py - widgets not properly deleted
|
|
while self.plugin_stack.count() > 0:
|
|
widget = self.plugin_stack.widget(0)
|
|
self.plugin_stack.removeWidget(widget) # Not deleted!
|
|
```
|
|
|
|
3. **Image Retention**
|
|
- Screenshots kept in memory indefinitely
|
|
- No LRU cache for OCR images
|
|
|
|
### 3.3 Optimization Recommendations
|
|
|
|
1. **Implement Async Operations**
|
|
```python
|
|
# Current (blocking)
|
|
result = api.nexus_search(query)
|
|
|
|
# Recommended (async)
|
|
result = await api.nexus_search_async(query)
|
|
```
|
|
|
|
2. **Add Connection Pooling**
|
|
- HTTP client should reuse connections
|
|
- Current implementation creates new session per request
|
|
|
|
3. **Lazy Loading for Plugins**
|
|
- Only load plugin UI when first viewed
|
|
- Current: All UIs created at startup
|
|
|
|
4. **Image Compression**
|
|
- Compress screenshots before OCR
|
|
- Use lower resolution for text detection
|
|
|
|
---
|
|
|
|
## 4. Code Quality Issues
|
|
|
|
### 4.1 Error Handling Deficiencies
|
|
|
|
#### Issue: Bare Except Clauses
|
|
**Files:** Multiple plugins
|
|
|
|
```python
|
|
# BAD - Catches everything including KeyboardInterrupt
|
|
try:
|
|
data = json.load(f)
|
|
except:
|
|
pass
|
|
|
|
# GOOD - Specific exception handling
|
|
try:
|
|
data = json.load(f)
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"Invalid JSON in {file_path}: {e}")
|
|
data = {}
|
|
except IOError as e:
|
|
logger.error(f"Failed to read {file_path}: {e}")
|
|
raise DataLoadError from e
|
|
```
|
|
|
|
#### Issue: Silent Failures
|
|
**File:** `core/plugin_manager.py:52-55`
|
|
|
|
```python
|
|
# Current
|
|
try:
|
|
return json.loads(config_path.read_text())
|
|
except json.JSONDecodeError:
|
|
pass # Silent failure!
|
|
|
|
# Recommended
|
|
try:
|
|
return json.loads(config_path.read_text())
|
|
except json.JSONDecodeError as e:
|
|
logger.warning(f"Corrupted config file, using defaults: {e}")
|
|
self._backup_corrupted_config(config_path)
|
|
return self._get_default_config()
|
|
```
|
|
|
|
### 4.2 Type Safety Issues
|
|
|
|
#### Missing Type Hints
|
|
**Coverage:** ~40% of functions lack proper type hints
|
|
|
|
**Priority files to annotate:**
|
|
1. `core/plugin_api.py` - Public API surface
|
|
2. `core/event_bus.py` - Critical for event handling
|
|
3. `plugins/base_plugin.py` - Base class for all plugins
|
|
|
|
#### Optional/None Confusion
|
|
**File:** `core/ocr_service.py:45-50`
|
|
|
|
```python
|
|
# Current - unclear return type
|
|
def capture_screen(self, region=None):
|
|
# Returns Image.Image or raises
|
|
pass
|
|
|
|
# Recommended
|
|
def capture_screen(self, region: Optional[Tuple[int, int, int, int]] = None) -> Image.Image:
|
|
"""Capture screen or region.
|
|
|
|
Args:
|
|
region: (x, y, width, height) or None for full screen
|
|
|
|
Returns:
|
|
PIL Image
|
|
|
|
Raises:
|
|
RuntimeError: If screenshot service unavailable
|
|
"""
|
|
```
|
|
|
|
### 4.3 Code Duplication
|
|
|
|
#### Pattern: File Loading
|
|
**Found in:** 12+ plugins
|
|
|
|
```python
|
|
# Duplicated pattern
|
|
data_file = Path("data/something.json")
|
|
data_file.parent.mkdir(parents=True, exist_ok=True)
|
|
if data_file.exists():
|
|
try:
|
|
with open(data_file, 'r') as f:
|
|
data = json.load(f)
|
|
except:
|
|
data = {}
|
|
```
|
|
|
|
**Solution:** Create `DataStore` utility class
|
|
|
|
#### Pattern: UI Styling
|
|
**Found in:** All plugins
|
|
|
|
Each plugin defines its own styles instead of using shared styles from `eu_styles.py`.
|
|
|
|
### 4.4 Specific File Issues
|
|
|
|
#### `core/main.py`
|
|
- **Line 45-50:** No graceful degradation if keyboard library fails
|
|
- **Line 120-150:** Service initialization not parallelized
|
|
- **Line 200-220:** Missing cleanup on startup failure
|
|
|
|
#### `core/plugin_manager.py`
|
|
- **Line 85-95:** Plugin discovery can hang on malformed plugins
|
|
- **Line 120-140:** No timeout on plugin initialization
|
|
- **Line 180-200:** Hotkey triggering not thread-safe
|
|
|
|
#### `plugins/game_reader/plugin.py`
|
|
- **Line 45-80:** OCR thread has no cancellation mechanism
|
|
- **Line 100-120:** Screenshot temp file not cleaned up on crash
|
|
- **Line 150-180:** No validation of OCR result before processing
|
|
|
|
---
|
|
|
|
## 5. Security Audit
|
|
|
|
### 5.1 Critical Vulnerabilities
|
|
|
|
#### 1. Path Traversal in Plugin Loading
|
|
**File:** `core/plugin_manager.py:85-95`
|
|
|
|
```python
|
|
# VULNERABLE - No path validation
|
|
spec = importlib.util.spec_from_file_location(module_name, plugin_file)
|
|
```
|
|
|
|
**Risk:** Malicious plugin could access files outside plugin directory
|
|
|
|
**Fix:**
|
|
```python
|
|
from pathlib import Path
|
|
|
|
def _validate_plugin_path(self, plugin_file: Path) -> bool:
|
|
"""Ensure plugin file is within allowed directories."""
|
|
resolved = plugin_file.resolve()
|
|
allowed_paths = [Path(d).resolve() for d in self.PLUGIN_DIRS]
|
|
return any(str(resolved).startswith(str(allowed)) for allowed in allowed_paths)
|
|
```
|
|
|
|
#### 2. Code Injection via Log Parsing
|
|
**File:** `core/log_reader.py:85-95`
|
|
|
|
```python
|
|
# VULNERABLE - Regex patterns could be exploited
|
|
PATTERNS = {
|
|
'skill_gain': re.compile(r'(.+?)\s+has\s+improved...'),
|
|
}
|
|
```
|
|
|
|
**Risk:** Crafted log lines could cause ReDoS (Regular Expression Denial of Service)
|
|
|
|
**Fix:** Add regex timeout and complexity limits
|
|
|
|
#### 3. Unsafe Deserialization
|
|
**File:** Multiple plugins
|
|
|
|
```python
|
|
# VULNERABLE - Loading untrusted JSON
|
|
data = json.load(f) # Could contain malicious data
|
|
```
|
|
|
|
**Risk:** While json.load is safer than pickle, nested structures could cause memory exhaustion
|
|
|
|
**Fix:** Implement depth and size limits
|
|
|
|
### 5.2 Medium Risk Issues
|
|
|
|
#### 1. No HTTPS Certificate Validation
|
|
**File:** `core/nexus_api.py:180-200`
|
|
|
|
The requests library validates by default, but no pinning is implemented.
|
|
|
|
#### 2. Sensitive Data in Logs
|
|
**File:** `core/plugin_api.py`
|
|
|
|
API keys or tokens could be logged in error messages.
|
|
|
|
#### 3. Temp File Race Condition
|
|
**File:** `plugins/game_reader/plugin.py:60-70`
|
|
|
|
```python
|
|
# VULNERABLE
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp:
|
|
screenshot_path = tmp.name # Predictable path
|
|
```
|
|
|
|
### 5.3 Security Recommendations
|
|
|
|
1. **Implement Plugin Signing**
|
|
- Verify plugin integrity before loading
|
|
- Whitelist approved plugins
|
|
|
|
2. **Add Sandboxing**
|
|
- Restrict plugin file system access
|
|
- Network access controls
|
|
|
|
3. **Input Sanitization**
|
|
- Validate all external inputs
|
|
- Escape log message content
|
|
|
|
4. **Secure Defaults**
|
|
- Disable plugins by default
|
|
- Require explicit user approval
|
|
|
|
---
|
|
|
|
## 6. UI/UX Improvements
|
|
|
|
### 6.1 Current Pain Points
|
|
|
|
1. **No Loading States**
|
|
- OCR operations block UI without feedback
|
|
- Network requests show no progress
|
|
|
|
2. **Poor Error Messages**
|
|
- Generic "Error" messages
|
|
- No actionable guidance
|
|
|
|
3. **Inconsistent Styling**
|
|
- Each plugin has different button styles
|
|
- No unified color scheme enforcement
|
|
|
|
4. **No Keyboard Navigation**
|
|
- Tab order not defined
|
|
- No shortcuts for common actions
|
|
|
|
### 6.2 Design Recommendations
|
|
|
|
#### Implement Toast Notifications
|
|
```python
|
|
# Add to core/notifications.py
|
|
class NotificationManager:
|
|
def show_toast(self, message: str, type: str = "info", duration: int = 3000):
|
|
"""Show non-intrusive notification."""
|
|
```
|
|
|
|
#### Add Loading Indicators
|
|
```python
|
|
# Add to base_plugin.py
|
|
class BasePlugin:
|
|
def show_loading(self, message: str = "Loading..."):
|
|
"""Show loading overlay."""
|
|
|
|
def hide_loading(self):
|
|
"""Hide loading overlay."""
|
|
```
|
|
|
|
#### Standardize Form Validation
|
|
```python
|
|
# Add validation utilities
|
|
class FormValidator:
|
|
@staticmethod
|
|
def validate_number(value: str, min: float, max: float) -> ValidationResult:
|
|
"""Validate numeric input."""
|
|
```
|
|
|
|
### 6.3 Accessibility Improvements
|
|
|
|
1. **Add Screen Reader Support**
|
|
- Set proper `accessibleName` on all widgets
|
|
- Provide text alternatives for icons
|
|
|
|
2. **High Contrast Mode**
|
|
- Add theme option for visibility
|
|
- Respect system accessibility settings
|
|
|
|
3. **Font Scaling**
|
|
- Support system font size changes
|
|
- Allow user-defined scaling
|
|
|
|
---
|
|
|
|
## 7. Feature Gaps
|
|
|
|
### 7.1 Missing vs Competitors
|
|
|
|
| Feature | EU-Utility | Competitor A | Competitor B | Priority |
|
|
|---------|------------|--------------|--------------|----------|
|
|
| Auto-loot tracking | Manual only | ✓ Auto | ✓ Auto | P0 |
|
|
| Market price alerts | ✗ | ✓ | ✓ | P1 |
|
|
| Team/Shared tracking | ✗ | ✓ | ✗ | P2 |
|
|
| Mobile companion | ✗ | ✓ | ✓ | P2 |
|
|
| Cloud sync | ✗ | ✓ | ✗ | P1 |
|
|
| Plugin marketplace | Basic | ✓ | ✗ | P2 |
|
|
| Analytics dashboard | Basic | ✓ | ✓ | P1 |
|
|
| Discord integration | ✗ | ✓ | ✓ | P3 |
|
|
|
|
### 7.2 Technical Debt Features
|
|
|
|
1. **Configuration Management**
|
|
- Current: JSON files scattered across codebase
|
|
- Needed: Unified config with validation schema
|
|
|
|
2. **Data Migration**
|
|
- No versioning for data files
|
|
- Breaking changes lose user data
|
|
|
|
3. **Plugin API Versioning**
|
|
- No version compatibility checking
|
|
- Plugins can break on core updates
|
|
|
|
4. **Update System**
|
|
- No auto-update mechanism
|
|
- Manual download required
|
|
|
|
### 7.3 Recommended New Features
|
|
|
|
#### P0 (Critical)
|
|
1. **Automatic Loot Detection**
|
|
- Parse chat log for loot messages
|
|
- Auto-populate loot tracker
|
|
|
|
2. **Session Persistence**
|
|
- Save/restore hunting sessions
|
|
- Crash recovery
|
|
|
|
#### P1 (High)
|
|
3. **Market Price Monitoring**
|
|
- Track item prices over time
|
|
- Alert on price changes
|
|
|
|
4. **Cloud Backup**
|
|
- Optional encrypted backup
|
|
- Cross-device sync
|
|
|
|
#### P2 (Medium)
|
|
5. **Plugin SDK**
|
|
- Better documentation
|
|
- Example plugins
|
|
- Debug tools
|
|
|
|
6. **Mobile App**
|
|
- View stats remotely
|
|
- Push notifications
|
|
|
|
---
|
|
|
|
## 8. Prioritized Action Plan
|
|
|
|
### P0 - Fix Immediately (Critical)
|
|
|
|
#### 8.1.1 Fix Race Conditions in Event Bus
|
|
**File:** `core/event_bus.py`
|
|
**Effort:** 4 hours
|
|
**Impact:** Prevents data loss and crashes
|
|
|
|
```python
|
|
# Add proper locking
|
|
from threading import RLock
|
|
|
|
class EventBus:
|
|
def __init__(self):
|
|
self._lock = RLock()
|
|
self._history_lock = RLock()
|
|
```
|
|
|
|
#### 8.1.2 Add Input Validation to File Operations
|
|
**Files:** All plugins with file I/O
|
|
**Effort:** 8 hours
|
|
**Impact:** Prevents data corruption
|
|
|
|
```python
|
|
def safe_json_load(filepath: Path, default: Any = None) -> Any:
|
|
"""Safely load JSON with validation."""
|
|
if not filepath.exists():
|
|
return default
|
|
|
|
# Check file size (prevent memory exhaustion)
|
|
max_size = 10 * 1024 * 1024 # 10MB
|
|
if filepath.stat().st_size > max_size:
|
|
raise FileTooLargeError(f"{filepath} exceeds max size")
|
|
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
# Validate JSON structure
|
|
return json.loads(content)
|
|
```
|
|
|
|
#### 8.1.3 Fix OCR Thread Exception Handling
|
|
**File:** `plugins/game_reader/plugin.py`
|
|
**Effort:** 2 hours
|
|
**Impact:** Prevents app crashes
|
|
|
|
```python
|
|
def run(self):
|
|
"""Capture screen and perform OCR."""
|
|
try:
|
|
# ... existing code ...
|
|
except Exception as e:
|
|
logger.exception("OCR failed")
|
|
self.error_occurred.emit(f"OCR failed: {str(e)}")
|
|
finally:
|
|
# Always cleanup
|
|
self._cleanup_temp_files()
|
|
```
|
|
|
|
#### 8.1.4 Implement Proper Resource Cleanup
|
|
**File:** `core/main.py`, `core/overlay_window.py`
|
|
**Effort:** 4 hours
|
|
**Impact:** Prevents memory leaks
|
|
|
|
### P1 - High Priority (Next Sprint)
|
|
|
|
#### 8.2.1 Add Comprehensive Logging
|
|
**Files:** All core modules
|
|
**Effort:** 12 hours
|
|
**Impact:** Debugging, monitoring
|
|
|
|
```python
|
|
# Replace print statements
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
logger.info("Plugin loaded: %s", plugin_name)
|
|
logger.warning("Config file corrupted, using defaults")
|
|
logger.error("Failed to initialize OCR service", exc_info=True)
|
|
```
|
|
|
|
#### 8.2.2 Implement Type Hints
|
|
**Files:** Core API surface
|
|
**Effort:** 16 hours
|
|
**Impact:** Maintainability, IDE support
|
|
|
|
#### 8.2.3 Add Unit Tests
|
|
**Files:** Core services
|
|
**Effort:** 24 hours
|
|
**Impact:** Code reliability
|
|
|
|
Target coverage:
|
|
- Event Bus: 90%
|
|
- Plugin API: 80%
|
|
- OCR Service: 70%
|
|
- HTTP Client: 80%
|
|
|
|
#### 8.2.4 Create Data Access Layer
|
|
**Files:** New `core/data/` module
|
|
**Effort:** 16 hours
|
|
**Impact:** Consistency, testability
|
|
|
|
### P2 - Medium Priority (Backlog)
|
|
|
|
#### 8.3.1 UI/UX Polish
|
|
- Loading indicators
|
|
- Better error messages
|
|
- Consistent styling
|
|
|
|
#### 8.3.2 Performance Optimizations
|
|
- Async HTTP requests
|
|
- Lazy plugin loading
|
|
- Image caching
|
|
|
|
#### 8.3.3 Security Hardening
|
|
- Plugin sandboxing
|
|
- Input sanitization
|
|
- Path validation
|
|
|
|
#### 8.3.4 Documentation
|
|
- API documentation
|
|
- Plugin development guide
|
|
- Architecture decision records
|
|
|
|
---
|
|
|
|
## 9. Quick Wins (Easy Improvements)
|
|
|
|
### 9.1 Low Effort, High Impact
|
|
|
|
1. **Replace print() with logging** (2 hours)
|
|
- Global search/replace with proper log levels
|
|
|
|
2. **Add docstrings to public APIs** (4 hours)
|
|
- Focus on `BasePlugin` and `PluginAPI`
|
|
|
|
3. **Fix bare except clauses** (2 hours)
|
|
- Replace `except:` with `except Exception:`
|
|
|
|
4. **Add __all__ to modules** (1 hour)
|
|
- Clean up public API surface
|
|
|
|
5. **Sort imports** (1 hour)
|
|
- Use isort for consistency
|
|
|
|
### 9.2 Code Quality Quick Fixes
|
|
|
|
```python
|
|
# Before
|
|
except:
|
|
pass
|
|
|
|
# After
|
|
except Exception as e:
|
|
logger.debug("Operation failed: %s", e)
|
|
```
|
|
|
|
```python
|
|
# Before
|
|
def load_data():
|
|
if file.exists():
|
|
with open(file) as f:
|
|
return json.load(f)
|
|
|
|
# After
|
|
def load_data() -> dict:
|
|
"""Load data from file."""
|
|
if not file.exists():
|
|
return {}
|
|
try:
|
|
with open(file, 'r', encoding='utf-8') as f:
|
|
return json.load(f)
|
|
except json.JSONDecodeError as e:
|
|
logger.error("Corrupted data file: %s", e)
|
|
return {}
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Long-term Architectural Recommendations
|
|
|
|
### 10.1 Migration to Async Architecture
|
|
|
|
**Current:** Blocking I/O throughout
|
|
**Target:** Async/await with Qt event loop integration
|
|
|
|
```python
|
|
# Future architecture
|
|
class PluginAPI:
|
|
async def nexus_search(self, query: str) -> List[SearchResult]:
|
|
"""Async search that doesn't block UI."""
|
|
```
|
|
|
|
### 10.2 Plugin Isolation
|
|
|
|
**Current:** Plugins run in same process
|
|
**Target:** Plugin sandboxing with IPC
|
|
|
|
Benefits:
|
|
- Crash isolation
|
|
- Security boundaries
|
|
- Hot reloading
|
|
|
|
### 10.3 Data Persistence Layer
|
|
|
|
**Current:** JSON files
|
|
**Target:** SQLite with migrations
|
|
|
|
```python
|
|
# Future data layer
|
|
class DataStore:
|
|
def __init__(self):
|
|
self._db = sqlite3.connect('data/eu_utility.db')
|
|
self._migrations = MigrationManager()
|
|
```
|
|
|
|
### 10.4 Testing Infrastructure
|
|
|
|
**Current:** No tests
|
|
**Target:** Comprehensive test suite
|
|
|
|
```
|
|
tests/
|
|
├── unit/
|
|
│ ├── core/
|
|
│ │ ├── test_event_bus.py
|
|
│ │ ├── test_plugin_api.py
|
|
│ │ └── test_ocr_service.py
|
|
│ └── plugins/
|
|
├── integration/
|
|
│ └── test_plugin_loading.py
|
|
└── e2e/
|
|
└── test_hunting_session.py
|
|
```
|
|
|
|
### 10.5 CI/CD Pipeline
|
|
|
|
```yaml
|
|
# .github/workflows/ci.yml
|
|
name: CI
|
|
on: [push, pull_request]
|
|
jobs:
|
|
test:
|
|
runs-on: [ubuntu, windows, macos]
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- name: Run tests
|
|
run: pytest --cov=core tests/
|
|
- name: Type check
|
|
run: mypy core/
|
|
- name: Lint
|
|
run: ruff check .
|
|
```
|
|
|
|
---
|
|
|
|
## Appendix A: Critical Bugs to Fix Immediately
|
|
|
|
1. **Event Bus Race Condition** - Can cause crash under load
|
|
2. **OCR Thread Exception** - App crashes on OCR failure
|
|
3. **File Path Traversal** - Security vulnerability
|
|
4. **Memory Leak in Plugin Reload** - UI widgets not deleted
|
|
5. **Unbounded HTTP Cache** - Can fill disk
|
|
6. **No Log Rotation** - chat.log parsing can hang
|
|
7. **Plugin Init Timeout** - Malformed plugins block startup
|
|
8. **Settings Corruption** - No backup on parse failure
|
|
|
|
## Appendix B: Migration Guide for Plugin Developers
|
|
|
|
### Version 2.0 to 2.1 Changes
|
|
|
|
1. **New Error Handling Pattern**
|
|
```python
|
|
# Old
|
|
try:
|
|
data = self.api.ocr_capture()
|
|
except:
|
|
pass
|
|
|
|
# New
|
|
try:
|
|
data = self.api.ocr_capture()
|
|
except OCRServiceError as e:
|
|
logger.error("OCR failed: %s", e)
|
|
self.show_error("OCR unavailable")
|
|
```
|
|
|
|
2. **Typed Events**
|
|
```python
|
|
# Old
|
|
self.api.publish_event('loot', {'item': 'Hide'})
|
|
|
|
# New
|
|
from core.event_bus import LootEvent
|
|
self.api.publish_typed(LootEvent(
|
|
mob_name="Daikiba",
|
|
items=[{"name": "Animal Hide", "value": 0.03}]
|
|
))
|
|
```
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
EU-Utility is a well-architected application with a solid plugin system and comprehensive service layer. However, it has accumulated technical debt in error handling, type safety, and testing. The critical issues (race conditions, exception handling, security) should be addressed immediately to ensure stability. The high-priority items (logging, type hints, tests) will significantly improve maintainability.
|
|
|
|
**Estimated effort for full remediation:** 120-160 hours
|
|
**Recommended team:** 2 developers for 4-6 weeks
|
|
|
|
---
|
|
|
|
*Document generated: February 14, 2026*
|
|
*Review scheduled: March 14, 2026*
|