# 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