mirror of
https://github.com/plexguide/Huntarr-Sonarr.git
synced 2025-12-16 20:04:16 -06:00
- Introduced mandatory page refresh on section changes to address caching issues and ensure fresh data display. - Added guidelines to prevent complex cache management systems and endless refresh loops using an `isInitialized` flag. - Implemented localStorage usage for storing target sections to facilitate navigation post-refresh. - Updated debugging strategies to monitor refresh behavior and initialization status effectively.
663 lines
35 KiB
Plaintext
663 lines
35 KiB
Plaintext
---
|
|
description: Huntarr development rules and patterns
|
|
globs: ["**/*.py", "**/*.js", "**/*.html", "**/*.css", "**/*.md"]
|
|
alwaysApply: true
|
|
---
|
|
# Huntarr Development Rules for Cursor AI
|
|
|
|
## 🚨 CRITICAL MANDATORY RULES
|
|
|
|
### NEVER AUTO-COMMIT
|
|
- NEVER automatically commit changes without explicit user approval
|
|
- Always present fixes to user first and get explicit approval before committing
|
|
- Let user decide when to commit
|
|
|
|
### MANDATORY TESTING WORKFLOW
|
|
- Docker: ALWAYS rebuild and test changes using: `cd /Users/home/Huntarr/Huntarr.io && docker-compose down && COMPOSE_BAKE=true docker-compose up -d --build`
|
|
- Local: ALWAYS use port 9706 for local testing: `HUNTARR_PORT=9706 python main.py`
|
|
- ALWAYS check logs for errors: `docker logs huntarr` (Docker) or terminal output (local)
|
|
- Test in both Docker and local environments
|
|
- Docker uses port 9705, local testing uses port 9706 to avoid conflicts
|
|
|
|
### 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/`)
|
|
|
|
## 🗄️ DATABASE-FIRST DEVELOPMENT
|
|
|
|
### ALWAYS Use DatabaseManager
|
|
- Use `DatabaseManager` class from `src/primary/utils/database.py` for ALL data operations
|
|
- NEVER use direct SQLite calls (`sqlite3.connect()`)
|
|
- NEVER use JSON file operations for persistent data
|
|
- DatabaseManager auto-detects environment (Docker vs local)
|
|
|
|
### Database Locations
|
|
- Docker: `/config/huntarr.db` (persistent volume)
|
|
- Local: `{project_root}/data/huntarr.db`
|
|
- Auto-detection handles path selection
|
|
|
|
### Code Pattern
|
|
```python
|
|
# ✅ CORRECT
|
|
from src.primary.utils.database import DatabaseManager
|
|
db = DatabaseManager()
|
|
db.set_setting('app', 'key', 'value')
|
|
|
|
# ❌ NEVER DO THIS
|
|
import sqlite3
|
|
conn = sqlite3.connect('/config/huntarr.db')
|
|
```
|
|
|
|
## 🌐 FRONTEND DEVELOPMENT RULES
|
|
|
|
### URL Patterns
|
|
- ALWAYS use relative URLs: `./api/endpoint` not `/api/endpoint`
|
|
- ALWAYS use relative redirects: `window.location.href = './'` not `'/'`
|
|
- This ensures subpath deployment works (`domain.com/huntarr/`)
|
|
|
|
### Documentation Links
|
|
- ALWAYS use GitHub documentation domain: `https://plexguide.github.io/Huntarr.io/`
|
|
- ALWAYS include proper anchors that exist in documentation
|
|
- ALWAYS verify anchors exist before linking
|
|
- Pattern: `https://plexguide.github.io/Huntarr.io/apps/[app-name].html#[anchor]`
|
|
|
|
### JavaScript Patterns
|
|
- ALWAYS declare variables before use in form generation
|
|
- NEVER use double backslashes in regex patterns
|
|
- ALWAYS handle undefined variables gracefully
|
|
|
|
### Page Refresh Caching Solution (Mandatory)
|
|
- ALWAYS implement page refresh on section changes to eliminate caching issues
|
|
- NEVER use complex cache management systems - simple refresh is more reliable
|
|
- ALWAYS use `isInitialized` flag to prevent endless refresh loops
|
|
- ALWAYS store target section in localStorage for post-refresh navigation
|
|
- This solves toggle visibility issues, stale data, and all frontend caching problems
|
|
|
|
## 🐛 COMMON ISSUE PREVENTION
|
|
|
|
### Log Regex Issues
|
|
- Use clean regex patterns without double backslashes
|
|
- Test regex patterns thoroughly
|
|
- File: `/frontend/static/js/new-main.js` - `connectEventSource()` method
|
|
|
|
### Settings Form Issues
|
|
- Include all field name variations for different apps
|
|
- Readarr: `hunt_missing_books`, `hunt_upgrade_books`
|
|
- Radarr: `hunt_missing_movies`, `hunt_upgrade_movies`
|
|
- Sonarr/Lidarr/Whisparr/Eros: `hunt_missing_items`, `hunt_upgrade_items`
|
|
- File: `/frontend/static/js/settings_forms.js`
|
|
|
|
### CSS Loading Order
|
|
- Add responsive CSS to external files, not inline in components
|
|
- Use debug borders to test CSS loading: `border: 2px solid lime !important;`
|
|
- Files: `/frontend/static/css/responsive-fix.css`, `/frontend/static/css/new-style.css`
|
|
|
|
### Hard-Coded Path Issues
|
|
- NEVER use hard-coded Docker paths that don't exist on bare metal
|
|
- Use environment detection pattern with DatabaseManager
|
|
- Test both Docker and local environments
|
|
|
|
### JavaScript Variable Undefined Errors
|
|
- Ensure all variables are declared before use in form generation
|
|
- File: `/frontend/static/js/settings_forms.js`
|
|
|
|
### Subpath Compatibility Issues
|
|
- Works at root domain but fails in subdirectories
|
|
- Use relative URLs everywhere: `./api/` not `/api/`
|
|
|
|
### Info Icon Documentation Link Issues
|
|
- Use proper GitHub documentation pattern with specific anchors
|
|
- Pattern: `https://plexguide.github.io/Huntarr.io/apps/[app-name].html#[anchor]`
|
|
- Always include `target="_blank" rel="noopener"` attributes
|
|
|
|
### GitHub API Rate Limiting Issues
|
|
- Use GitHub Actions + static manifest approach instead of direct API calls
|
|
- Fetch from static manifest.json updated by GitHub Actions
|
|
|
|
## 📁 KEY FILE LOCATIONS
|
|
|
|
### Backend Core
|
|
- `/src/primary/utils/database.py` - DatabaseManager class (USE THIS)
|
|
- `/src/primary/routes/common.py` - API endpoints
|
|
- `/src/primary/auth.py` - Authentication logic
|
|
- `/src/primary/cycle_tracker.py` - Timer functionality
|
|
|
|
### Frontend Core
|
|
- `/frontend/static/js/new-main.js` - Main UI logic
|
|
- `/frontend/static/js/settings_forms.js` - Settings forms
|
|
- `/frontend/templates/components/` - UI components
|
|
|
|
### Database Files
|
|
- Docker: `/config/huntarr.db`
|
|
- Local: `./data/huntarr.db`
|
|
|
|
## 🔧 DEVELOPMENT WORKFLOW
|
|
|
|
### Before Making Changes
|
|
1. Check current directory: `/Users/home/Huntarr/Huntarr.io`
|
|
2. Activate venv for local development: `source venv/bin/activate`
|
|
3. Review these rules
|
|
|
|
### Making Changes
|
|
1. Edit source code (never modify inside container)
|
|
2. For local testing: `HUNTARR_PORT=9706 python main.py` (uses ./data/huntarr.db on port 9706)
|
|
3. For Docker testing: `docker-compose down && COMPOSE_BAKE=true docker-compose up -d --build`
|
|
4. Check logs: `docker logs huntarr` (Docker) or terminal output (local)
|
|
5. Test functionality in both environments
|
|
|
|
### Before Committing
|
|
1. Test in Docker environment (port 9705)
|
|
2. Test in local environment (port 9706)
|
|
3. Test cross-platform compatibility
|
|
4. Test subpath scenarios
|
|
5. Check browser console for errors
|
|
6. Verify database persistence across container restarts
|
|
7. Get user approval before committing
|
|
|
|
## ⚠️ ANTI-PATTERNS TO AVOID
|
|
|
|
### Database Anti-Patterns
|
|
- ❌ Direct SQLite calls: `sqlite3.connect()`
|
|
- ❌ Hard-coded database paths: `/config/huntarr.db`
|
|
- ❌ JSON file operations for persistent data
|
|
- ❌ Not testing both Docker and local database operations
|
|
- ❌ Bypassing Synology optimizations with direct SQLite configuration
|
|
- ❌ Using `PRAGMA synchronous = FULL` outside of `_configure_connection()`
|
|
- ❌ Not testing database performance on network file systems
|
|
|
|
### Frontend Anti-Patterns
|
|
- ❌ Absolute URLs: `/api/endpoint`, `window.location.href = '/'`
|
|
- ❌ Wrong documentation domain links
|
|
- ❌ Missing anchor verification
|
|
- ❌ Double backslashes in regex
|
|
- ❌ Inline responsive CSS in components
|
|
|
|
### Development Anti-Patterns
|
|
- ❌ Modifying files inside containers
|
|
- ❌ Auto-committing without approval
|
|
- ❌ Testing only in Docker
|
|
- ❌ Not using virtual environment for local development
|
|
- ❌ Creating temporary files instead of fixing source
|
|
- ❌ Inconsistent behavior between missing/upgrade logic
|
|
- ❌ Reactive violation fixing (scan proactively instead)
|
|
- ❌ Documentation that promises non-existent features
|
|
- ❌ Frontend links without verifying documentation anchors exist
|
|
- ❌ Organic feature growth without reality checks
|
|
- ❌ Theoretical FAQ content (base on real user problems)
|
|
- ❌ Using port 9705 for local testing (conflicts with Docker)
|
|
|
|
### State Management Anti-Patterns
|
|
- ❌ Using global state locks instead of per-instance locks
|
|
- ❌ Frontend calculating times with `Date.now()` instead of using database times
|
|
- ❌ Inconsistent instance naming between frontend and backend API calls
|
|
- ❌ Not testing state persistence across page reloads
|
|
- ❌ Mixing cached frontend times with database-locked times
|
|
|
|
### Frontend Anti-Patterns (Additional)
|
|
- ❌ Event listeners overriding backend-provided data
|
|
- ❌ Inconsistent styling between similar components across apps
|
|
- ❌ Hard-coded CSS values instead of consistent color schemes
|
|
- ❌ Not clearing browser cache when testing frontend fixes
|
|
- ❌ Assuming frontend calculations match backend logic
|
|
- ❌ Multiple pagination systems conflicting (template vs JavaScript module)
|
|
- ❌ Template HTML containing pagination logic that overrides API-based pagination
|
|
- ❌ DOM element counting for pagination instead of using API total counts
|
|
|
|
### Caching Anti-Patterns (Critical)
|
|
- ❌ Complex cache management systems for simple data refresh needs
|
|
- ❌ Manual cache invalidation instead of automatic page refresh
|
|
- ❌ Frontend state caching causing stale data display
|
|
- ❌ Toggle visibility issues due to cached frontend state
|
|
- ❌ Endless refresh loops due to improper initialization detection
|
|
- ❌ Section switching without proper data refresh
|
|
|
|
## 🚨 PROACTIVE VIOLATION SCANNING
|
|
|
|
### Before Every Commit, Check For:
|
|
1. Absolute URL violations: `grep -r "fetch('/api/" frontend/ --include="*.js"`
|
|
2. Documentation violations: `grep -r "href.*plexguide.github.io" frontend/ --include="*.js" | grep -v "plexguide.github.io/Huntarr.io"`
|
|
3. Settings form initialization violations: `grep -r "innerHTML.trim.*!==.*''" frontend/static/js/new-main.js | grep -v "includes.*Content will be loaded here"`
|
|
4. Database violations: `grep -r "sqlite3.connect\|import sqlite3" src/ --include="*.py" | grep -v "database.py"`
|
|
5. Hard-coded path violations: `grep -r "/config" src/ --include="*.py" | grep -v "_detect_environment\|_get.*path\|DatabaseManager"`
|
|
6. JSON file operations: `grep -r "\.json\|json.load\|json.dump" src/ --include="*.py" | grep -v "requests.*json\|response.json\|Content-Type.*json"`
|
|
7. Frontend time calculation violations: `grep -r "Date.now.*hours.*60.*1000" frontend/ --include="*.js"`
|
|
8. Global state lock usage: `grep -r "stateful_lock" src/ --include="*.py" | grep -v "stateful_instance_locks"`
|
|
9. Inconsistent app styling: `grep -r "background.*linear-gradient.*rgba(15, 23, 42" frontend/ --include="*.js"`
|
|
10. Logs pagination conflicts: `grep -r "updateLogsPagination\|updatePagination" frontend/ --include="*.html" --include="*.js" | grep -v "LogsModule"`
|
|
11. Hunt Manager non-Sonarr clickable links: `grep -r "isClickable.*entry.app_type.*&&.*entry.instance_name" frontend/static/js/hunt_manager.js | grep -v "=== 'sonarr'" | wc -l`
|
|
12. Port 9705 usage in local testing: `grep -r "9705" main.py src/ | grep -v "docker\|container"`
|
|
13. Synology optimization bypasses: `grep -r "sqlite3.connect\|PRAGMA synchronous = FULL" src/ --include="*.py" | grep -v "_configure_connection"`
|
|
14. Endless refresh loop violations: `grep -r "location.reload" frontend/ --include="*.js" | grep -v "isInitialized"`
|
|
15. Missing initialization flag violations: `grep -r "switchSection.*function" frontend/ --include="*.js" | xargs grep -L "isInitialized"`
|
|
|
|
### Violation Scanning Commands
|
|
```bash
|
|
# Create violation_scan.sh for easy reuse
|
|
echo "=== HUNTARR VIOLATION SCAN ==="
|
|
echo "1. Absolute URL violations: $(grep -r "fetch('/api/" frontend/ --include="*.js" | wc -l)"
|
|
echo "2. Documentation violations: $(grep -r "href.*plexguide.github.io" frontend/ --include="*.js" | grep -v "plexguide.github.io/Huntarr.io" | wc -l)"
|
|
echo "3. Settings form initialization violations: $(grep -r "innerHTML.trim.*!==.*''" frontend/static/js/new-main.js | grep -v "includes.*Content will be loaded here" | wc -l)"
|
|
echo "4. Database violations: $(grep -r "sqlite3.connect\|import sqlite3" src/ --include="*.py" | grep -v "database.py" | wc -l)"
|
|
echo "5. Hard-coded path violations: $(grep -r "/config" src/ --include="*.py" | grep -v "_detect_environment\|_get.*path\|DatabaseManager" | wc -l)"
|
|
echo "6. JSON file violations: $(grep -r "\.json\|json.load\|json.dump" src/ --include="*.py" | grep -v "requests.*json\|response.json\|Content-Type.*json" | wc -l)"
|
|
echo "7. Frontend time calculation violations: $(grep -r "Date.now.*hours.*60.*1000" frontend/ --include="*.js" | wc -l)"
|
|
echo "8. Global state lock violations: $(grep -r "stateful_lock" src/ --include="*.py" | grep -v "stateful_instance_locks" | wc -l)"
|
|
echo "9. Inconsistent app styling violations: $(grep -r "background.*linear-gradient.*rgba(15, 23, 42" frontend/ --include="*.js" | wc -l)"
|
|
echo "10. Logs pagination conflict violations: $(grep -r "updateLogsPagination\|updatePagination" frontend/ --include="*.html" --include="*.js" | grep -v "LogsModule" | wc -l)"
|
|
echo "11. Hunt Manager non-Sonarr clickable links: $(grep -r "isClickable.*entry.app_type.*&&.*entry.instance_name" frontend/static/js/hunt_manager.js | grep -v "=== 'sonarr'" | wc -l)"
|
|
echo "12. Port 9705 usage in local code: $(grep -r "9705" main.py src/ | grep -v "docker\|container" | wc -l)"
|
|
echo "13. Synology optimization bypass violations: $(grep -r "sqlite3.connect\|PRAGMA synchronous = FULL" src/ --include="*.py" | grep -v "_configure_connection" | wc -l)"
|
|
echo "14. Endless refresh loop violations: $(grep -r "location.reload" frontend/ --include="*.js" | grep -v "isInitialized" | wc -l)"
|
|
echo "15. Missing initialization flag violations: $(grep -r "switchSection.*function" frontend/ --include="*.js" | xargs grep -L "isInitialized" | wc -l)"
|
|
```
|
|
|
|
## 📊 SPECIFIC BUG PATTERNS TO AVOID
|
|
|
|
### GitHub Issue #626 Pattern (2FA Verification)
|
|
- Check both `temp_2fa_secret` (setup) and `two_fa_secret` (enabled) in auth functions
|
|
- File: `/src/primary/auth.py`
|
|
|
|
### GitHub Issue #624 Pattern (Settings Persistence)
|
|
- Include all field name variations in form collection logic
|
|
- File: `/frontend/static/js/settings_forms.js`
|
|
|
|
### GitHub Issue #629 Pattern (Windows Database Access)
|
|
- Use DatabaseManager with proper Windows AppData support
|
|
- Never hard-code database paths
|
|
|
|
### GitHub Issue #615 Pattern (Synology NAS Performance Issues)
|
|
- Synology NAS systems experience severe SQLite performance issues with default settings
|
|
- Root cause: Network file systems (NFS/CIFS) perform poorly with `PRAGMA synchronous = FULL`
|
|
- Symptoms: 20-39 second database operations, "database is locked" errors, general slowness
|
|
- Solution: Automatic Synology detection with optimized SQLite settings
|
|
- Detection methods: `/usr/syno`, `/etc/synoinfo.conf`, `SYNOPKG_PKGNAME` env var, hostname patterns
|
|
- Optimized settings: `synchronous=NORMAL`, 40MB cache, 30s timeout, 128MB mmap, less frequent checkpoints
|
|
- User control: `HUNTARR_SYNOLOGY_OPTIMIZATIONS=false` to disable optimizations
|
|
- Expected improvement: 70-90% performance boost on Synology systems
|
|
- Safety: WAL mode, integrity checks, and error handling preserved
|
|
- File: `/src/primary/utils/database.py` - `_detect_synology_nas()` and `_configure_connection()` methods
|
|
|
|
### Frontend Log Regex Issues
|
|
- Malformed regex with double backslashes
|
|
- Fix: Use clean regex patterns without double backslashes
|
|
- File: `/frontend/static/js/new-main.js` - `connectEventSource()` method
|
|
|
|
### DEBUG Log Filtering Race Condition
|
|
- DEBUG logs appear in wrong filters (Info, Warning, Error)
|
|
- Fix: Apply filter to new entries as they arrive in EventSource
|
|
- File: `/frontend/static/js/new-main.js` - `connectEventSource()` method
|
|
|
|
### Per-Instance State Management Issues
|
|
- Global state locks affect all instances instead of being per-instance
|
|
- Frontend time calculations override database-locked times causing inconsistent display
|
|
- Fix: Implement per-instance database locks with `stateful_instance_locks` table
|
|
- File: `/src/primary/stateful_manager.py`, `/src/primary/utils/database.py`
|
|
|
|
### Frontend Time Calculation Override Bug
|
|
- Event listeners in form generation calculate new times using `Date.now()` instead of using database times
|
|
- Pattern: `const resetTime = new Date(Date.now() + (hours * 60 * 60 * 1000));`
|
|
- Symptom: Times change on page reload despite being locked in database
|
|
- Fix: Remove time calculation from event listeners, let backend provide locked times
|
|
- File: `/frontend/static/js/settings_forms.js` - state hours input event listeners
|
|
|
|
### Inconsistent App Styling Issues
|
|
- Apps may have different styling for similar components (e.g., state status sections)
|
|
- Check for consistent CSS styling across all app form generation functions
|
|
- Pattern: Sonarr using dark gradient while Radarr using green gradient for same component
|
|
- Fix: Standardize styling across all apps for similar UI elements
|
|
|
|
### Logs Pagination Conflict Issues
|
|
- Logs show correct total count briefly (e.g., "Page 1 of 365") but flash back to "Page 1 of 1"
|
|
- Next button gets disabled after the flash, preventing historical log access
|
|
- Root cause: Conflicting pagination systems between LogsModule and HTML template
|
|
- Pattern: Template has `updateLogsPagination()` function counting DOM elements and overriding API-based pagination
|
|
- Symptom: Console shows correct API response (totalLogs=7291, totalPages=365) but UI resets to 1 page
|
|
- Fix: Remove all template pagination code, let LogsModule handle all pagination via API calls
|
|
- Files: `/frontend/templates/components/logs_section.html`, `/frontend/static/js/logs.js`
|
|
|
|
### GitHub Issue #641 Pattern (Lidarr AlbumSearch String/Integer Issue)
|
|
- AlbumSearch fails with 500 error: "The JSON value could not be converted to System.Collections.Generic.List[System.Int32]"
|
|
- Root cause: Album IDs converted to strings with `str(album.get("id"))` but API expects List[int]
|
|
- Pattern: `album_id = str(album.get("id"))` followed by passing to `search_albums(album_ids_to_search)`
|
|
- Symptom: Lidarr returns 500 Internal Server Error for AlbumSearch command
|
|
- Fix: Keep album IDs as integers, only convert to string for processed checks: `album_id = album.get("id")` and `is_processed("lidarr", instance_name, str(album_id))`
|
|
- Files: `/src/primary/apps/lidarr/missing.py`, `/src/primary/apps/lidarr/upgrade.py`
|
|
|
|
### GitHub Issue #591 Pattern (Lidarr No Items Found Processing Logic)
|
|
- Large libraries (264k+ missing albums) report "No items found to process. Items tracked: 0"
|
|
- Root cause: Unreachable else clause in conditional logic flow after elif for artist mode
|
|
- Pattern: `if hunt_missing_mode == "album":` followed by `elif hunt_missing_mode == "artist":` followed by unreachable `else:` for album processing
|
|
- Symptom: Album mode processing falls through to wrong code path, no items processed
|
|
- Fix: Restructure conditional logic to properly handle both album and artist modes with explicit checks
|
|
- Files: `/src/primary/apps/lidarr/missing.py`
|
|
|
|
### GitHub Issue #628 Pattern (Hunt Manager Link Issues)
|
|
- Movie links redirect incorrectly to Radarr causing "Sorry, we could not find that movie" errors
|
|
- Root cause: All apps made clickable but only Sonarr title-based slugs work properly
|
|
- Pattern: `formatProcessedInfo()` making all app types clickable with external linking
|
|
- Symptom: Radarr/Lidarr/other app links fail with 404 or wrong movie pages
|
|
- Fix: Only make Sonarr entries clickable (`entry.app_type === 'sonarr'`), show other apps as plain text with tooltips
|
|
- Radarr expects movie IDs in URLs but Hunt Manager uses title-based slugs which don't match
|
|
- Files: `/frontend/static/js/hunt_manager.js` (history.js already correctly implemented)
|
|
|
|
### Settings Forms Initialization Pattern (Critical)
|
|
- **Problem**: Settings sections showing empty content despite having proper HTML templates and JavaScript functions
|
|
- **Root Cause**: Initialization functions checking for content but HTML comments count as "content"
|
|
- **Pattern**: `if (container.innerHTML.trim() !== '') { return; }` fails when container has `<!-- Content will be loaded here -->`
|
|
- **Symptom**: Console shows "already initialized, skipping" but form never generates
|
|
- **Critical Fix**: Check for actual content, not just any content including comments
|
|
- **Solution Pattern**:
|
|
```javascript
|
|
const currentContent = container.innerHTML.trim();
|
|
if (currentContent !== '' && !currentContent.includes('<!-- Content will be loaded here -->')) {
|
|
console.log('[huntarrUI] Already initialized, skipping');
|
|
return; // Already initialized
|
|
}
|
|
```
|
|
- **Files Affected**: `/frontend/static/js/new-main.js` (all `initialize*` functions)
|
|
- **Form Generation Flow**:
|
|
1. `initializeNotifications()` → checks container content → calls API → calls `SettingsForms.generateNotificationsForm()`
|
|
2. `initializeSettings()` → checks container content → calls API → calls `SettingsForms.generateGeneralForm()`
|
|
3. Similar pattern for all settings sections
|
|
- **Required Functions in SettingsForms**: `generateNotificationsForm()`, `generateGeneralForm()`, etc.
|
|
- **API Endpoints**: `/api/settings` (general), `/api/settings/general` (specific)
|
|
- **Template Containers**: `notificationsContainer`, `generalSettings`, etc.
|
|
- **Debug Logging**: Always add comprehensive console.log statements to track initialization flow
|
|
- **Testing**: Refresh page, navigate to section, check browser console for proper initialization sequence
|
|
|
|
### Sidebar Implementation Pattern (Critical)
|
|
- **Problem**: Multiple sidebars showing simultaneously causing visual clutter and navigation confusion
|
|
- **Root Cause**: Flash prevention script in `new-main.js` showing main sidebar on page load before specialized sidebar logic runs
|
|
- **Pattern**: Flash prevention checks localStorage but doesn't account for specialized sidebars (Requestarr, Settings)
|
|
- **Symptom**: Both main sidebar and specialized sidebar visible at same time, especially on mobile
|
|
- **Critical Fix**: Update flash prevention to hide main sidebar when specialized sidebar should be active
|
|
- **Solution Pattern**:
|
|
```javascript
|
|
// In flash prevention script (around line 90-120 in new-main.js)
|
|
// Check if we should show a specialized sidebar instead of main sidebar
|
|
const currentSection = localStorage.getItem('huntarrCurrentSection') || 'home';
|
|
const requestarrSections = ['requestarr-home', 'requestarr-history'];
|
|
const settingsSections = ['settings', 'scheduling'];
|
|
|
|
if (requestarrSections.includes(currentSection)) {
|
|
// Show Requestarr sidebar, hide main sidebar
|
|
document.getElementById('sidebar').style.display = 'none';
|
|
document.getElementById('requestarrSidebar').style.display = 'block';
|
|
} else if (settingsSections.includes(currentSection)) {
|
|
// Show Settings sidebar, hide main sidebar
|
|
document.getElementById('sidebar').style.display = 'none';
|
|
document.getElementById('settingsSidebar').style.display = 'block';
|
|
} else {
|
|
// Show main sidebar, hide specialized sidebars
|
|
document.getElementById('sidebar').style.display = 'block';
|
|
document.getElementById('requestarrSidebar').style.display = 'none';
|
|
document.getElementById('settingsSidebar').style.display = 'none';
|
|
}
|
|
```
|
|
- **Files Affected**: `/frontend/static/js/new-main.js` (flash prevention script)
|
|
- **Implementation Requirements**:
|
|
1. Always check localStorage section before showing any sidebar
|
|
2. Hide all other sidebars when showing one specific sidebar
|
|
3. Use consistent section naming: `requestarr-home`, `requestarr-history`, `settings`, `scheduling`
|
|
4. Test on both desktop and mobile to ensure no double sidebars
|
|
5. Ensure return buttons properly switch back to main sidebar
|
|
- **Mobile Compatibility**: Flash prevention must work on mobile where sidebar space is limited
|
|
- **Testing**: Navigate between sections, refresh page, check that only one sidebar shows at a time
|
|
|
|
### Page Refresh Pattern for Caching Issues (Critical)
|
|
- **Problem**: Frontend caching causing stale data display, especially toggle visibility issues
|
|
- **Root Cause**: Complex cache management systems are error-prone and difficult to maintain
|
|
- **Solution**: Simple page refresh on section changes eliminates all caching issues
|
|
- **Implementation Pattern**:
|
|
```javascript
|
|
// In switchSection function - frontend/static/js/new-main.js
|
|
switchSection: function(section) {
|
|
// Only refresh if this is a user-initiated section change (not initial page load)
|
|
// and we're switching to a different section
|
|
if (this.isInitialized && this.currentSection && this.currentSection !== section) {
|
|
console.log(`[huntarrUI] User switching from ${this.currentSection} to ${section}, refreshing page...`);
|
|
// Store the target section in localStorage so we can navigate to it after refresh
|
|
localStorage.setItem('huntarr-target-section', section);
|
|
location.reload();
|
|
return;
|
|
}
|
|
// ... rest of section switching logic
|
|
}
|
|
```
|
|
- **Initialization Flag Pattern**:
|
|
```javascript
|
|
// In init function - mark as initialized after setup complete
|
|
setTimeout(() => {
|
|
this.showDashboard();
|
|
// Mark as initialized after everything is set up to enable refresh on section changes
|
|
this.isInitialized = true;
|
|
console.log('[huntarrUI] Initialization complete - refresh on section change enabled');
|
|
}, 50);
|
|
```
|
|
- **Target Section Restoration**:
|
|
```javascript
|
|
// In init function - check for stored target section after refresh
|
|
const targetSection = localStorage.getItem('huntarr-target-section');
|
|
if (targetSection) {
|
|
console.log(`[huntarrUI] Found target section after refresh: ${targetSection}`);
|
|
localStorage.removeItem('huntarr-target-section');
|
|
// Navigate to the target section
|
|
this.switchSection(targetSection);
|
|
} else {
|
|
// Initial navigation based on hash
|
|
this.handleHashNavigation(window.location.hash);
|
|
}
|
|
```
|
|
- **Benefits**:
|
|
1. Eliminates ALL caching issues with zero complexity
|
|
2. Ensures fresh data on every section change
|
|
3. Solves toggle visibility problems automatically
|
|
4. No cache invalidation logic needed
|
|
5. Works consistently across all browsers
|
|
6. Simple to understand and maintain
|
|
- **Critical Requirements**:
|
|
1. MUST use `isInitialized` flag to prevent endless refresh loops
|
|
2. MUST store target section in localStorage for navigation after refresh
|
|
3. MUST clean up localStorage after navigation
|
|
4. MUST only trigger on user-initiated section changes, not initial page load
|
|
- **Files**: `/frontend/static/js/new-main.js`
|
|
- **Testing**: Verify no endless refresh loops, smooth navigation, fresh data display
|
|
|
|
### Endless Refresh Loop Prevention Pattern (Critical)
|
|
- **Problem**: Page refreshes continuously every 0.5 seconds due to improper refresh logic
|
|
- **Root Cause**: Refresh logic triggers on every `switchSection` call including initial page load
|
|
- **Symptom**: Infinite refresh loop making the application unusable
|
|
- **Critical Fix**: Use `isInitialized` flag to distinguish user navigation from initialization
|
|
- **Pattern to Avoid**:
|
|
```javascript
|
|
// ❌ WRONG - causes endless refresh loops
|
|
if (this.currentSection && this.currentSection !== section) {
|
|
location.reload(); // Triggers on initial page load!
|
|
}
|
|
```
|
|
- **Correct Pattern**:
|
|
```javascript
|
|
// ✅ CORRECT - only refreshes on user navigation
|
|
if (this.isInitialized && this.currentSection && this.currentSection !== section) {
|
|
location.reload(); // Only after initialization complete
|
|
}
|
|
```
|
|
- **Debugging**: If endless refresh occurs, check browser console for rapid section switching logs
|
|
- **Prevention**: Always test page load behavior, not just navigation behavior
|
|
|
|
## 🎯 DEBUGGING APPROACH
|
|
|
|
### Systematic Issue Discovery
|
|
1. Don't guess - scan systematically first
|
|
2. Use grep to find exact error patterns
|
|
3. Check browser console for JavaScript errors
|
|
4. Verify database operations in both environments
|
|
5. Test cross-platform compatibility
|
|
|
|
### Database Debugging
|
|
```bash
|
|
# Docker environment
|
|
docker exec huntarr ls -la /config/huntarr.db
|
|
docker exec huntarr sqlite3 /config/huntarr.db ".tables"
|
|
|
|
# Local environment
|
|
ls -la ./data/huntarr.db
|
|
sqlite3 ./data/huntarr.db ".tables"
|
|
|
|
# Test DatabaseManager operations
|
|
python3 -c "from src.primary.utils.database import DatabaseManager; db = DatabaseManager(); print('Database path:', db.db_path)"
|
|
|
|
# Synology-specific debugging
|
|
docker exec huntarr python3 -c "from src.primary.utils.database import HuntarrDatabase; db = HuntarrDatabase(); print('Synology detected:', db._detect_synology_nas())"
|
|
docker logs huntarr | grep -i "synology\|optimization"
|
|
docker exec huntarr sqlite3 /config/huntarr.db "PRAGMA synchronous; PRAGMA cache_size; PRAGMA mmap_size;"
|
|
```
|
|
|
|
### Subpath Deployment Debugging
|
|
- Check browser network tab for 404s on absolute URLs
|
|
- Search for absolute patterns: `grep -r "fetch('/api" frontend/`
|
|
- Check redirects: `grep -r "window.location.href.*= '/" frontend/`
|
|
- Verify all URLs are relative: `./api/` not `/api/`
|
|
|
|
### Frontend-Documentation Link Debugging
|
|
- Extract frontend anchor references: `grep -r "href.*#" frontend/static/js/ | grep -o "#[^\"]*"`
|
|
- Extract doc anchors: `grep -r 'id="[^"]*"' docs/ | grep -o 'id="[^"]*"'`
|
|
- Compare lists to find mismatches
|
|
|
|
### Log Issues Debugging
|
|
1. Check logs in database: `docker exec huntarr python3 -c "import sys; sys.path.insert(0, '/app/src'); from primary.utils.logs_database import get_logs_database; db = get_logs_database(); logs = db.get_logs(limit=10); [print(f'{log["timestamp"]} - {log["app_type"]} - {log["level"]} - {log["message"]}') for log in logs]"`
|
|
2. Test backend streaming: `curl -N -s "http://localhost:9705/logs?app=[app]"`
|
|
3. Check browser console for JavaScript errors
|
|
4. Verify regex patterns in `new-main.js`
|
|
|
|
### Settings Issues Debugging
|
|
1. Check form generation functions in `/frontend/static/js/settings_forms.js`
|
|
2. Verify initialization functions in `/frontend/static/js/new-main.js` (e.g., `initializeNotifications()`)
|
|
3. **Critical**: Check for HTML comment interference in container content checks
|
|
4. Test API endpoints: `/api/settings`, `/api/settings/general`
|
|
5. Verify container elements exist: `notificationsContainer`, `generalSettings`
|
|
6. Check browser console for initialization flow logs
|
|
7. Test save/load cycle and auto-save functionality
|
|
8. Verify info icon links point to existing documentation anchors
|
|
9. **Settings Forms Debug Pattern**:
|
|
```javascript
|
|
// Add to initialization functions for debugging
|
|
console.log('[huntarrUI] initializeX called');
|
|
console.log('[huntarrUI] container found:', container);
|
|
console.log('[huntarrUI] Current container content:', container.innerHTML.trim());
|
|
console.log('[huntarrUI] SettingsForms available:', typeof SettingsForms !== 'undefined');
|
|
console.log('[huntarrUI] generateXForm available:', typeof SettingsForms.generateXForm === 'function');
|
|
```
|
|
|
|
### CSS Issues Debugging
|
|
1. Check browser console for errors
|
|
2. Add debug borders: `border: 2px solid lime !important;`
|
|
3. Verify CSS loading order (external files vs inline)
|
|
4. Test specificity with `!important` declarations
|
|
5. Search for conflicting rules: `grep -r "className" frontend/static/css/`
|
|
|
|
### Documentation Issues Debugging
|
|
1. Test all links manually or with link checker
|
|
2. Verify features mentioned actually exist in codebase
|
|
3. Check frontend alignment with documentation
|
|
4. Audit FAQ against real support requests
|
|
|
|
### State Management Issues Debugging
|
|
1. Check database locks: `docker exec huntarr sqlite3 /config/huntarr.db "SELECT * FROM stateful_instance_locks;"`
|
|
2. Verify per-instance vs global locks in database schema
|
|
3. Test frontend instance name consistency across API calls
|
|
4. Monitor browser console for time calculation overrides
|
|
5. Check event listener patterns: `grep -r "Date.now.*hours.*60.*1000" frontend/`
|
|
|
|
### Frontend Time Display Issues Debugging
|
|
1. Compare database time vs displayed time on page reload
|
|
2. Check event listeners for time calculations in form generation
|
|
3. Verify API responses contain locked times from database
|
|
4. Test with browser cache cleared to rule out caching issues
|
|
5. Monitor network tab for API calls during page interactions
|
|
|
|
### App Styling Consistency Debugging
|
|
1. Search for styling patterns: `grep -r "background.*linear-gradient" frontend/static/js/`
|
|
2. Compare CSS classes between similar components across apps
|
|
3. Check for hard-coded styles vs CSS classes
|
|
4. Verify color consistency: `grep -r "rgba.*185.*129" frontend/`
|
|
5. Test visual consistency across all app settings forms
|
|
|
|
### Logs Pagination Conflict Debugging
|
|
1. Check browser console for pagination updates: Look for `[LogsModule] Updated pagination` messages
|
|
2. Verify API responses: Monitor network tab for `/api/logs` calls with correct `total` counts
|
|
3. Search for conflicting pagination: `grep -r "updateLogsPagination\|updatePagination" frontend/`
|
|
4. Check for DOM element conflicts: `grep -r "logsCurrentPage\|logsTotalPages" frontend/`
|
|
5. Test pagination elements: Verify only one system updates pagination DOM elements
|
|
6. Monitor for template interference: Look for template event listeners overriding LogsModule
|
|
7. Debug pagination state: Add console.log to see which system is updating pagination last
|
|
|
|
### Page Refresh System Debugging
|
|
1. Check for endless refresh loops: Monitor browser console for rapid section switching messages
|
|
2. Verify initialization flag: `console.log` the `isInitialized` state during section switches
|
|
3. Test localStorage cleanup: Verify `huntarr-target-section` is removed after navigation
|
|
4. Monitor refresh triggers: Look for `[huntarrUI] User switching from X to Y, refreshing page...` messages
|
|
5. Test initial page load: Ensure no refresh triggers during initialization
|
|
6. Verify section preservation: Check that target section is correctly restored after refresh
|
|
7. **Debug Pattern**:
|
|
```javascript
|
|
// Add to switchSection function for debugging
|
|
console.log('[huntarrUI] switchSection called:', {
|
|
section: section,
|
|
currentSection: this.currentSection,
|
|
isInitialized: this.isInitialized,
|
|
willRefresh: this.isInitialized && this.currentSection && this.currentSection !== section
|
|
});
|
|
```
|
|
|
|
### Caching Issues Debugging
|
|
1. **Simple Solution**: Instead of debugging complex cache issues, implement page refresh pattern
|
|
2. Check browser network tab for stale API responses
|
|
3. Verify localStorage is not holding outdated data
|
|
4. Test toggle visibility after section changes
|
|
5. Monitor console for cache-related error messages
|
|
6. **Remember**: Page refresh eliminates need for complex cache debugging
|
|
|
|
## 📝 MEMORY CREATION GUIDELINES
|
|
|
|
Create memories for:
|
|
- ✅ Bug fixes with root cause analysis
|
|
- ✅ New features and their implementation patterns
|
|
- ✅ Cross-platform compatibility fixes
|
|
- ✅ Performance improvements
|
|
- ✅ Database migration insights
|
|
|
|
## 🚀 DEPLOYMENT RULES
|
|
|
|
### Branch Management
|
|
- Work on feature branches
|
|
- Deploy to `dev` branch first
|
|
- Merge `dev` to `main` after testing
|
|
- Always pull latest changes before merging
|
|
|
|
### Testing Requirements
|
|
- Test in Docker environment
|
|
- Test in local development environment
|
|
- Test cross-platform paths
|
|
- Test subpath deployment scenarios
|
|
- Verify database persistence
|
|
|
|
## 📋 FOLLOW .github/listen.md GUIDELINES
|
|
|
|
This file automatically enforces the patterns from `.github/listen.md`. The user should not need to remind you about:
|
|
- Using DatabaseManager instead of direct SQLite
|
|
- Using relative URLs instead of absolute URLs
|
|
- Testing in both Docker and local environments
|
|
- Following cross-platform compatibility requirements
|
|
- Getting approval before committing changes
|
|
- Using proper documentation links with verified anchors
|
|
- Proactive violation scanning before commits
|
|
- Systematic debugging approaches
|
|
- Database-first development patterns
|
|
- Cross-platform path handling
|
|
|
|
---
|
|
|
|
**REMEMBER: These rules are automatically applied. Follow them without being reminded.** |