Bug: Dashboard permanently shows stale hardcoded demo data (never fetches live data or connects SSE)
Summary
On a fresh clone + docker compose up -d --build, the dashboard loads once and never updates. It shows the hardcoded demo data baked into dashboard/public/jarvis.html, dated 2026-04-03, instead of live sweep data — even though the server-side sweeps complete successfully every 15 minutes.
Root cause
dashboard/public/jarvis.html ships with a hardcoded sample data block:
let D = {"meta":{"version":"2.0.0","timestamp":"2026-04-03T16:18:10.188Z", ...The page's boot logic (near the end of the file) decides whether to fetch live data based on whether D already looks populated:
document.addEventListener('DOMContentLoaded', () => {
const hasInlineData = !!(D && D.meta);
const canProbeApi = location.protocol !== 'file:';
if (canProbeApi && !hasInlineData) {
fetch('/api/data')
.then(r => r.json())
.then(data => { D = data; init(); connectSSE(); })
.catch(() => { ... });
} else if (hasInlineData) {
init();
}
});Because the hardcoded demo block already has a .meta field, hasInlineData is always true. This means:
fetch('/api/data')never runs in server modeconnectSSE()never runs, since it's only called inside that fetch's.then()- The dashboard renders the shipped demo snapshot and never asks the server for anything again
This affects every fresh install, not a specific environment — it will reproduce on any platform since the demo block is checked into the repo.
Steps to reproduce
Fresh clone, following the README's Docker instructions exactly:
git clone https://github.com/calesthio/Crucix.git
cd Crucix
cp .env.example .env # add your API keys
docker compose up -dThen:
- Confirm sweeps complete:
docker logs <container> | grep "Sweep complete" - Confirm
/api/healthreports a recentlastSweep - Open the dashboard at
http://localhost:3117— topbar date and news feed are stuck on 2026-04-03, regardless of hard refresh or private browsing - Network tab confirms no request to
/api/dataand no/events(SSE) connection is ever made
Suggested fix
The check should key off canProbeApi (i.e., whether we're in server mode vs standalone file:// mode) rather than whether D happens to already contain data. In server mode, live data should always be preferred over any inline/demo content:
if (canProbeApi) {
fetch('/api/data')
.then(r => r.json())
.then(data => { D = data; init(); connectSSE(); })
.catch(() => {
if (D && D.meta) { init(); connectSSE(); }
});
} else if (hasInlineData) {
init();
}Environment
- Docker Compose (official
docker-compose.yml), image built from the providedDockerfile(node:22-alpine) - Host: Docker running inside a Proxmox LXC container (confirmed not a factor — server-side data, container clock, and
/api/healthwere all correct; the bug is purely client-side JS logic) - Reproduced with hard refresh and in a private/incognito window, on a direct IP:port connection with no reverse proxy involved
Source: calesthio/Crucix