Dashboard — Implementation¶
Routing¶
React Router v7 (react-router-dom) handles client-side routing. Routes defined in App.tsx.
9 routes: / (Overview), /stock, /predictions, /news, /trends, /tickers, /portfolio, /account, /chat
AuthGuard wraps all authenticated routes — unauthenticated requests redirect to /login.
Data Fetching¶
- TanStack Query v5 (
@tanstack/react-query) manages all API calls:staleTime: 60_000,retry: 1 frontend/src/api/client.ts— thinfetchwrapper withcredentials: "include"for cookie auth- Domain modules (
prices.ts,news.ts,predictions.ts, etc.) call FastAPI endpoints and type responses
Market Filter Implementation¶
- Overview / Stock Detail / Predictions / News Feed: filtering uses live ticker sets from
load_ticker_sets(db)(FastAPI backend call, cached 60s) — frontend receives all data and filters client-side by ticker membership - Sector Trends: filtering is API-side —
marketquery param passed toGET /trends/heatandGET /trends/alerts, which joinSentimentScoretoNewsArticleand filter onNewsArticle.marketat DB level - Sector Sentiment chart (
GET /trends/sectors): always cross-market —TrendingTopichas nomarketcolumn
Trending Alerts¶
get_trending_alerts(db, n=5, days=3)frommodels/trend_analyzer.py- Heat score =
mention_count × abs(avg_sentiment) - Each result includes up to 3 recent headlines with
title,url,published_at,label - Cached 300s on the API side
Price Chart¶
- Area/line chart —
close >= period_open→ green; otherwise red - Time range selector computes
chart_daysfrom a static map; re-fetches price history at selected depth pre_dfcaptures rows before the cutoff to deriveprev_closefor the reference line- Recharts; height 280px
Headline Translation¶
_get_display_title()selects the correct headline based on user's translation choicetitle_en/title_koareNoneuntilbatch_translate()is called — components must handlenull- One API call per page load for all missing translations (batch mode)
Gotchas¶
- CORS: allowed origins default to
localhost:5173,localhost:3000; override with theCORS_ORIGINSenv var (comma-separated) - Sector Trends market filter is API-side — unlike other pages; see Market Filter section above
- Vite proxy:
/apirequests proxied tolocalhost:8000in dev; no path rewrite — the backend serves all routes under/apiprefix - Production serving:
api/main.pyservesfrontend/distas a static SPA when the directory exists (built by Docker multi-stage ornpm run build); the/assetsmount must come before the catch-all/{full_path:path}route
Adding New UI Text¶
Add the string directly to the relevant React component in frontend/src/. For bilingual text, add both EN and KO variants inline in the component.