Skip to content

Latest commit

 

History

History
64 lines (49 loc) · 2.44 KB

File metadata and controls

64 lines (49 loc) · 2.44 KB

ADR-0001: Project repositioned as post-close review tool

  • Status: Accepted
  • Date: 2026-05

Context

The project originally tried to be a real-time intra-day analyzer. This led to a sprawling implementation surface:

  • 7 free real-time quote fetchers, each with its own retry / cache logic
  • A BackgroundPoller thread polling every minute regardless of pipeline activity
  • dashboard_watchlist table tracking user "watch" state
  • market_hours lookups gating display
  • 1-second frontend polling
  • A market_open badge driving conditional UI

Real-time data is a different product than post-close analysis:

  • it requires sub-second freshness guarantees we cannot deliver on free APIs
  • it requires UI patterns (streaming, badges, hot-paths) that complicate the d3 heatmap
  • it doubles the testing surface (pre-market / open / close / extended hours)

In practice users only consumed the daily digest after close.

Decision

The project is positioned as a post-close review tool only. All real-time intra-day code was deleted. Quotes are read from the stock_quote_snapshot SQLite table written by the analysis pipeline at end of each batch run. The frontend does not poll on a timer; it refreshes on (a) initial load, (b) explicit user click, (c) tab visibility change after ≥ 5 min stale.

Consequences

Easier

  • Single source of truth for "current price": whatever the last batch wrote.
  • BatchContext data alignment is well-defined (one trading day per run).
  • Frontend has zero idle-tab CPU cost.
  • Test surface contracts to one phase.

Harder

  • Cannot serve true intra-day use cases (alerts, momentum scanners). Users needing this should adopt a different tool.
  • Cold start of /sectors/indices becomes user-visible (mitigated by kvcache pre-warm + 4s timeout cap).
  • Display must communicate "as-of date" prominently, otherwise users mistake Friday's close for "right now". Implemented via mandatory data_date field in tooltips and an [as_of] label on the freshness button.

Alternatives considered

  • Hybrid: keep poller off by default, allow opt-in. Rejected — the surface stays in code, latent bugs persist (e.g. silent staleness from Xueqiu — see CHANGELOG 2026-05 Fixed).
  • Real-time only: rebuild around a single paid feed. Rejected — out of scope for a single-maintainer project.

Cross-references

  • CHANGELOG 2026-05 / Removed / "Real-time intra-day code"
  • docs/context.md — Positioning statement