dashboard: redesign signal workspace and refresh flow

This commit is contained in:
Harwinder Sekhon
2026-08-18 14:54:47 -04:00
parent 2a2ccb13dd
commit aa270dc145
6 changed files with 492 additions and 300 deletions
+34 -6
View File
@@ -5670,7 +5670,21 @@ def _():
pub = dpub.DashboardPublisher(out_dir=tmp)
pub.install_static()
assert sorted(os.listdir(tmp)) == \
["dashboard.css", "dashboard.html", "dashboard.js", "gauge.js", "news_summary.php"] # all installed, no .tmp
["dashboard.css", "dashboard.html", "dashboard.js", "news_summary.php"] # all installed, no .tmp
@test("dashboard: static UI uses CSS gauges and a coordinated refresh loop")
def _():
static_dir = os.path.join(os.path.dirname(__file__), "static")
with open(os.path.join(static_dir, "dashboard.html"), encoding="utf-8") as fh:
html = fh.read()
with open(os.path.join(static_dir, "dashboard.js"), encoding="utf-8") as fh:
js = fh.read()
assert "chart.js" not in html.lower()
assert "gauge.js" not in html
assert "setInterval(poll" not in js
assert "FALLBACK_POLL_MS" in js and "pollInFlight" in js
assert "data-select-tf" in js and "localStorage" in js
@test("dashboard: publish is atomic and leaves no temp file")
@@ -5683,19 +5697,33 @@ def _():
assert os.listdir(tmp) == ["snapshot.json"] # no .tmp left
@test("dashboard: run_cycle publishes snapshot BEFORE news refresh")
@test("dashboard: run_cycle publishes technical snapshot before panels/news")
def _():
# News I/O (FF + RSS + DeepSeek) can take 20-30 s — fresh signals
# must reach the page first (2026-08-06 sync-latency fix).
# News and advisory panels can take 20-30 s cold — fresh technical
# signals must reach the page first.
pub = dpub.DashboardPublisher(out_dir="/nonexistent")
order = []
pub.scan_tf = lambda tf: order.append(f"scan:{tf.value}")
pub.publish_snapshot = lambda: order.append("snapshot")
pub.attach_panels = lambda tfs: (order.append("panels") or True)
pub.refresh_news = lambda: order.append("news_refresh")
pub.publish_news = lambda: order.append("news_publish")
pub.run_cycle([Timeframe.M5])
assert order == ["scan:5min", "snapshot", "news_refresh",
"news_publish"], order
assert order == ["scan:5min", "snapshot", "panels", "snapshot", "news_refresh",
"news_publish"], order
@test("dashboard: scan errors keep private exception detail out of snapshots")
def _():
pub = dpub.DashboardPublisher(out_dir="/nonexistent")
pub._provider = lambda: object()
with patch("dashboard_publisher.produce_signal",
side_effect=RuntimeError("provider token leaked")):
pub.scan_tf(Timeframe.M5)
entry = pub.snapshots["5min"]
assert entry["status"] == "error"
assert entry["error"] == "Scan unavailable"
assert "token" not in entry["error"]
@test("dashboard: seconds_until_boundary bounds and constants")