# Huntarr Development Guidelines Quick reference for development patterns, common issues, and critical requirements. ## 🚨 CRITICAL RULES ### 🚫 NO AUTO-COMMITTING **NEVER automatically commit changes without explicit user approval.** - Present fixes to user first - Get explicit approval before committing - Let user decide when to commit ### πŸ”„ MANDATORY TESTING WORKFLOW ```bash # ALWAYS rebuild and test changes cd /Users/home/Huntarr/Huntarr.io && docker-compose down && COMPOSE_BAKE=true docker-compose up -d --build # Check logs for errors docker logs huntarr ``` ### 🌐 CROSS-PLATFORM REQUIREMENTS - **NEVER use hard-coded absolute paths** (e.g., `/config/file.json`) - **ALWAYS use `os.path.join()`** for path construction - **ALWAYS use relative URLs** in frontend (e.g., `./api/` not `/api/`) - **ALWAYS test**: Docker, Windows, Mac, Linux, subpaths (`domain.com/huntarr/`) ### πŸŽ›οΈ SIDEBAR NAVIGATION ARCHITECTURE **Huntarr uses a multi-sidebar system for organized navigation:** #### **Sidebar Types:** 1. **Main Sidebar** (`#sidebar`) - Default navigation (Home, Apps, Swaparr, Requestarr, etc.) 2. **Apps Sidebar** (`#apps-sidebar`) - App-specific navigation (Sonarr, Radarr, Lidarr, etc.) 3. **Settings Sidebar** (`#settings-sidebar`) - Settings navigation (Main, Scheduling, Notifications, Backup/Restore, User) 4. **Requestarr Sidebar** (`#requestarr-sidebar`) - Requestarr navigation (Home, History) #### **Navigation Logic Pattern:** ```javascript // CRITICAL: All sidebar sections must be included in initialization logic if (this.currentSection === 'settings' || this.currentSection === 'scheduling' || this.currentSection === 'notifications' || this.currentSection === 'backup-restore' || this.currentSection === 'user') { this.showSettingsSidebar(); } else if (this.currentSection === 'requestarr' || this.currentSection === 'requestarr-history') { this.showRequestarrSidebar(); } else if (this.currentSection === 'apps' || this.currentSection === 'sonarr' || this.currentSection === 'radarr' || this.currentSection === 'lidarr' || this.currentSection === 'readarr' || this.currentSection === 'whisparr' || this.currentSection === 'eros' || this.currentSection === 'prowlarr') { this.showAppsSidebar(); } else { this.showMainSidebar(); } ``` #### **Apps Navigation Behavior:** - **Clicking "Apps"** β†’ Automatically redirects to Sonarr (most commonly used app) - **Apps nav item stays highlighted** when viewing any app (Sonarr, Radarr, etc.) - **Apps sidebar provides navigation** between individual apps - **Direct URLs still work** (`#sonarr`, `#radarr`, etc.) for bookmarking specific apps #### **Sidebar Switching Functions:** ```javascript showMainSidebar: function() { document.getElementById('sidebar').style.display = 'flex'; document.getElementById('apps-sidebar').style.display = 'none'; document.getElementById('settings-sidebar').style.display = 'none'; document.getElementById('requestarr-sidebar').style.display = 'none'; }, showAppsSidebar: function() { document.getElementById('sidebar').style.display = 'none'; document.getElementById('apps-sidebar').style.display = 'flex'; document.getElementById('settings-sidebar').style.display = 'none'; document.getElementById('requestarr-sidebar').style.display = 'none'; } // ... etc for other sidebars ``` #### **Required Elements for New Sidebars:** 1. **HTML Structure** - Must include logo, nav-menu, return button, and section groups 2. **Navigation Logic** - Must be added to both section switching AND initialization logic 3. **localStorage Management** - Set preferences like `localStorage.setItem('huntarr-apps-sidebar', 'true')` 4. **Mobile Responsiveness** - Ensure proper display on mobile devices 5. **Return Button** - Always include return navigation to main sidebar #### **Mobile Behavior:** - **Desktop**: Sidebars switch seamlessly with full navigation - **Mobile**: Sidebars collapse to icons only, maintain switching functionality - **Touch-friendly**: All navigation elements sized appropriately for mobile interaction ## πŸ› COMMON ISSUE PATTERNS ### 1. Frontend Log Regex Issues **Symptoms:** Logs generated but not displayed for specific apps **Root Cause:** Malformed regex with double backslashes **Fix:** ```javascript // ❌ BROKEN const logRegex = /^(?:\\[(\\w+)\\]\\s)?([\\d\\-]+\\s[\\d:]+)\\s-\\s([\\w\\.]+)\\s-\\s(\\w+)\\s-\\s(.*)$/; // βœ… FIXED const logRegex = /^(?:\[(\w+)\]\s)?([^\s]+\s[^\s]+)\s-\s([\w\.]+)\s-\s(\w+)\s-\s(.*)$/; ``` **File:** `/frontend/static/js/new-main.js` - `connectEventSource()` method ### 2. DEBUG Log Filtering Race Condition **Symptoms:** DEBUG logs appear in wrong filters (Info, Warning, Error) **Root Cause:** EventSource adds logs without checking current filter **Fix:** Apply filter to new entries as they arrive ```javascript // In EventSource onmessage handler, after appendChild: const currentLogLevel = this.elements.logLevelSelect ? this.elements.logLevelSelect.value : 'all'; if (currentLogLevel !== 'all') { this.applyFilterToSingleEntry(logEntry, currentLogLevel); } ``` **File:** `/frontend/static/js/new-main.js` - `connectEventSource()` method ### 3. Database Connection Issues **Symptoms:** "Database error", "No such table", settings not persisting **Root Cause:** Database path issues or missing tables **Fix:** Use DatabaseManager with environment detection ```python # ❌ BROKEN - Direct SQLite calls with hardcoded paths import sqlite3 conn = sqlite3.connect('/config/huntarr.db') # βœ… FIXED - Use DatabaseManager with auto-detection from src.primary.utils.database import DatabaseManager db = DatabaseManager() db.get_setting('sonarr', 'api_key') ``` **Debug Steps:** 1. Check database exists: `docker exec huntarr ls -la /config/huntarr.db` 2. Verify tables: `docker exec huntarr sqlite3 /config/huntarr.db ".tables"` 3. Check environment detection: Look for `/config` directory existence 4. Test local vs Docker paths: `./data/huntarr.db` vs `/config/huntarr.db` ### 4. Hard-Coded Path Issues (Legacy) **Symptoms:** "Error Loading" on bare metal, works in Docker **Root Cause:** Hard-coded Docker paths don't exist on bare metal **Fix:** Environment detection pattern (now handled by DatabaseManager) ```python # ❌ LEGACY - Old JSON file approach def _detect_environment(): return os.path.exists('/config') and os.path.exists('/app') def _get_paths(): if _detect_environment(): return {'data': '/config/tally/sleep.json'} else: base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) return {'data': os.path.join(base_dir, 'data', 'tally', 'sleep.json')} # βœ… NEW - Database approach from src.primary.utils.database import DatabaseManager db = DatabaseManager() # Automatically detects environment and uses correct database path ``` ### 4. JavaScript Variable Undefined Errors **Symptoms:** `ReferenceError: variableName is not defined` in settings **Root Cause:** Missing variable declarations in form generation **Fix:** Ensure all variables are declared before use ```javascript generateAppForm: function(container, settings = {}) { let instancesHtml = `...`; let searchSettingsHtml = `...`; // CRITICAL - must declare container.innerHTML = instancesHtml + searchSettingsHtml; } ``` **File:** `/frontend/static/js/settings_forms.js` ### 5. Subpath Compatibility Breaks **Symptoms:** Works at root domain but fails in subdirectories **Root Cause:** Absolute URLs in JavaScript/templates **Fix:** Use relative URLs everywhere ```javascript // ❌ BROKEN window.location.href = '/'; fetch('/api/endpoint'); // βœ… FIXED window.location.href = './'; fetch('./api/endpoint'); ``` ### 6. CSS Loading Order/Specificity Issues **Symptoms:** Inline component CSS styles not applying, especially mobile responsive changes **Root Cause:** External CSS files (`responsive-fix.css`, `new-style.css`) load after component templates and override inline styles **Fix:** Add critical responsive CSS to external files with higher specificity ```css /* ❌ BROKEN - Inline component CSS gets overridden */ /* βœ… FIXED - Add to external CSS file */ /* File: frontend/static/css/responsive-fix.css */ @media (max-width: 768px) { .app-stats-card.swaparr .stats-numbers { display: grid !important; grid-template-columns: 1fr !important; /* Debug border for testing */ border: 2px solid lime !important; } } ``` **Debugging Technique:** Use colored debug borders to confirm CSS is loading **Files:** `/frontend/static/css/responsive-fix.css`, `/frontend/static/css/new-style.css` ### 7. Info Icon Documentation Link Issues **Symptoms:** Info icons (i) linking to wrong domains, localhost, or broken forum links **Root Cause:** Hard-coded old links instead of GitHub documentation links **Fix:** Use proper GitHub documentation pattern with specific anchors ```javascript // ❌ BROKEN - Old forum or localhost links