Skip to content

feat: wire TUI dashboard panels to live data (closes #134)#152

Merged
luceinaltis merged 2 commits into
mainfrom
feat/134-functional-tui-dashboard
Apr 8, 2026
Merged

feat: wire TUI dashboard panels to live data (closes #134)#152
luceinaltis merged 2 commits into
mainfrom
feat/134-functional-tui-dashboard

Conversation

@luceinaltis
Copy link
Copy Markdown
Owner

Summary

Closes #134. Makes the Textual TUI dashboard functional by wiring panels to the live data layer instead of showing only static config snapshots.

  • OverviewPanel: fetches live prices for portfolio holdings and the watchlist via DataRegistry.async_get_with_fallback(PriceProvider, "get_price", …); per-holding P&L computed when prices are available. Replaces the static "S&P 500 / NASDAQ / VIX" placeholder with a live Watchlist mini-table.
  • PortfolioPanel: uses RiskCalculator.build_snapshot() to render market values, weights, and unrealized P&L once all holdings have prices; falls back to a cost-basis view for partial data. A total-value label shows either live portfolio value or cost basis.
  • WatchlistPanel: fetches live prices for each ticker on refresh.
  • AlertsPanel: replaces the static placeholder with a DataTable backed by AlertStore, with hot-reload via mtime checks (picks up alerts created by qracer repl without restarting the dashboard).
  • TasksPanel (new): reads TaskStore.get_active() and renders schedule + human-readable next run time (in 5m / in 2h / due). Added to the DASH sidebar group with hotkey 5.
  • QracerDashboard accepts optional data_registry, alert_store, task_store kwargs and injects them into panels both on compose and on sidebar navigation.
  • qracer dashboard CLI now calls _build_registries() and passes ~/.qracer/alerts.json + ~/.qracer/tasks.json stores to the app.

Panels keep their placeholder behaviour when no registry/store is provided (useful for tests and users without live data) — every cell that depends on live data falls back to .

Test plan

  • uv run pytest tests/dashboard/49 passed (14 new tests: refresh_data behaviour for Overview/Portfolio/Watchlist with a _FakeRegistry, partial-price fallback, AlertsPanel hot-reload, TasksPanel empty/populated/hot-reload, _format_next_run edge cases)
  • uv run pytest tests/cli/ tests/test_cli.py tests/test_alerts.py tests/test_tasks.py tests/test_watchlist.py tests/storage/ tests/risk/238 passed total
  • uv run ruff check qracer/dashboard/ qracer/cli.py tests/dashboard/ → clean
  • uv run pyright qracer/dashboard/ qracer/cli.py → 0 errors
  • Manual smoke test: qracer dashboard with a populated portfolio and watchlist — verify prices appear within one refresh interval and switching panels keeps live data.

Notes

  • Refresh cadence is unchanged (REFRESH_INTERVAL_SECONDS = 5.0).
  • Async price fetches go through DataRegistry.async_get_with_fallback, matching the pattern used by AlertMonitor, so provider priority and fallback are consistent across the app.
  • Individual ticker fetch failures are logged at DEBUG level and skipped rather than blanking the whole table.

claude added 2 commits April 8, 2026 13:23
Make the Textual dashboard functional by wiring its panels to the
live data layer instead of showing only static config snapshots.

- OverviewPanel: fetches live prices for portfolio holdings and the
  watchlist via DataRegistry.async_get_with_fallback; P&L computed
  per holding when prices are available.
- PortfolioPanel: uses RiskCalculator.build_snapshot to render market
  values, weights, and unrealized P&L once all holdings have prices,
  with a cost-basis fallback for partial data.
- WatchlistPanel: fetches live prices for each ticker on refresh.
- AlertsPanel: reads active alerts from AlertStore with hot-reload
  via mtime checks (replacing the static placeholder).
- TasksPanel (new): displays scheduled tasks from TaskStore with
  human-readable next run times (in 5m / in 2h / due).
- QracerDashboard accepts optional data_registry, alert_store, and
  task_store kwargs and injects them into panels during construction
  and sidebar navigation.
- `qracer dashboard` CLI builds the registries via _build_registries()
  and wires the default ~/.qracer/ stores into the app.

Panels keep their existing behaviour when no registry is provided so
unit tests (and users without live data) see a "—" placeholder view.
Formatting-only changes to satisfy the code-quality CI step
(ruff format --check), no behavioural changes.
@luceinaltis luceinaltis merged commit 2d7b450 into main Apr 8, 2026
3 checks passed
@luceinaltis luceinaltis deleted the feat/134-functional-tui-dashboard branch April 8, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: functional TUI dashboard with live data

2 participants