# Ops Portal Jul 12 Cleanup Audit 42 bugs found across 11 pages by Claude Sonnet 4-6 subagent. ## Root Causes (5 issues causing 80% of bugs) ### 1. `/js/utils.js` 404 `utils.js` existed at `/var/www/ops/js/utils.js` but NOT at `/opt/ops-portal/static/js/` (the backend's JS directory). Every page referenced `/js/utils.js` which returned 404 via Caddy's `/js/*` file_server handler. Fix: `cp /var/www/ops/js/utils.js /opt/ops-portal/static/js/utils.js` ### 2. `window.initNav` undefined `initNav()` is exported as `window.Ops.initNav` (via `app.js`), not `window.initNav`. Every page calling `window.initNav()` calls undefined. Fix: Pages must call `Ops.initNav()`, or export `window.initNav = initNav` in app.js. ### 3. `logoutBtn` DOM lookup before nav fetch Pages services.html, servers.html, backups.html call `document.getElementById('logoutBtn')` synchronously before the `fetch('/nav.html')` callback completes. The nav (and `logoutBtn`) doesn't exist yet → TypeError. Fix: Move all `getElementById('logoutBtn')` calls inside the fetch callback. ### 4. Pages missing required script files Some pages loaded only `app.js` (missing `utils.js`), others loaded only `utils.js` (missing `app.js`). Fix: EVERY page must load BOTH: ```html ``` ### 5. No auth guard on 6 pages network.html, cron.html, config.html, logs.html, cost.html, fleettracker360.html have no login overlay or auth check. Fix: Add login overlay + `Ops.isAuthenticated()` guard. ## Critical Bugs by Page | Page | Critical Bugs | File Path | |------|------|-----------| | index.html | 1 | /opt/ops-portal/static/index.html | | services.html | 3 | /opt/ops-portal/static/services.html | | servers.html | 2 | /opt/ops-portal/static/servers.html | | backups.html | 2 | /opt/ops-portal/static/backups.html | | network.html | 2 | /opt/ops-portal/static/network.html | | cron.html | 2 | /opt/ops-portal/static/cron.html | | config.html | 4 | /opt/ops-portal/static/config.html | | logs.html | 2 | /opt/ops-portal/static/logs.html | | audit.html | 2 | /opt/ops-portal/static/audit.html | | cost.html | 3 | /opt/ops-portal/static/cost.html | | fleettracker360.html | 0 | /opt/ops-portal/static/fleettracker360.html | ## Quick Fixes Applied Jul 12 - Copied utils.js to backend static dir → 404 fixed - Added cache busting `?v=2` to all JS/CSS - Fixed Grafana link from 127.0.0.1 to Tailscale IP - Added z-index: 1000 to nav-links - Added inline onclick fallback to nav-toggle - Hid "Invalid credentials" error text by default - Both JS files added to all 10 pages ## Remaining Work - Export `window.initNav` properly - Fix `logoutBtn` timing on services/servers/backups - Add auth guards to 6 unprotected pages - Fix `window.fetchStatus` on cost.html - Fix `window.escapeHtml` on config.html - Fix audit.html `sessionStorage` → `localStorage`