feat: score-history chart on the regime tab
Deploy / lint (push) Successful in 6s
Deploy / test (push) Successful in 41s
Deploy / deploy (push) Successful in 25s

Plots the index, early-warning, and combined scores over time beneath the live
gauges, with a 1M/3M/6M/All range toggle and band reference lines — so the trend
and any divergence between the scores is visible, not just today's snapshot.

- Backend: GET /regime/history + get_regime_history (the three scores per
  snapshot date from regime_snapshots).
- Frontend: recharts line chart, lazy-loaded so recharts ships in its own
  regime-tab chunk instead of nearly doubling the main bundle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 15:48:42 +02:00
parent 60def1155b
commit 66444af65c
6 changed files with 192 additions and 2 deletions
+24
View File
@@ -681,6 +681,30 @@ async def get_regime_monitor(db: AsyncSession) -> dict:
return result
async def get_regime_history(db: AsyncSession, days: int = 400) -> list[dict]:
"""Daily history of the index, early-warning, and combined scores for the
score-over-time chart. One point per snapshot date, ascending."""
cutoff = date.today() - timedelta(days=days)
res = await db.execute(
select(RegimeSnapshot)
.where(RegimeSnapshot.date >= cutoff)
.order_by(RegimeSnapshot.date.asc())
)
out: list[dict] = []
for row in res.scalars().all():
try:
data = json.loads(row.breakdown_json)
except (TypeError, ValueError):
data = {}
out.append({
"date": row.date.isoformat(),
"index": row.total_score,
"early_warning": (data.get("early_warning") or {}).get("score"),
"combined": (data.get("combined") or {}).get("score"),
})
return out
# ---------------------------------------------------------------------------
# F1/F3 via grounded LLM (reuses the configured sentiment provider)
# ---------------------------------------------------------------------------