14 KiB
Implementation Plan: Signal Dashboard
Overview
Incremental build of the Signal Dashboard SPA in frontend/. Each phase wires up end-to-end before moving on, so there's always a runnable app. Backend API is already live — we consume it as-is.
Tasks
-
1. Scaffold Vite + React + TypeScript project
-
1.1 Initialize
frontend/with Vite React-TS template, install dependencies (react, react-dom, react-router-dom, @tanstack/react-query, zustand, axios, recharts, tailwindcss, postcss, autoprefixer)- Create
package.json,tsconfig.json,vite.config.ts,tailwind.config.ts,postcss.config.js - Configure Vite proxy for
/api/v1/to backend during dev - Configure Tailwind with dark mode class strategy
- Create
src/main.tsx,src/App.tsx,src/styles/globals.csswith Tailwind directives - Requirements: 14.1, 14.4, 13.2
- Create
-
1.2 Create shared TypeScript interfaces and formatting utilities
- Create
src/lib/types.tswith all data model interfaces (APIEnvelope, TokenResponse, WatchlistEntry, OHLCVBar, ScoreResponse, TradeSetup, SRLevel, SentimentResponse, FundamentalResponse, IndicatorResult, EMACrossResult, Ticker, AdminUser, SystemSetting, etc.) - Create
src/lib/format.tswithformatPrice,formatPercent,formatLargeNumber,formatDate,formatDateTime - Requirements: 13.4
- Create
-
* 1.3 Write property tests for formatting utilities
- Property 16: Number formatting
- Validates: Requirements 13.4
- Install vitest, @testing-library/react, fast-check as dev dependencies
- Create
frontend/vitest.config.tswith jsdom environment - Create
frontend/tests/property/format.test.ts - Test
formatPricealways produces 2 decimal places,formatPercentends with%,formatLargeNumberuses correct suffix
-
-
2. API client and auth store
-
2.1 Create Axios API client with interceptors
- Create
src/api/client.tswith base URL/api/v1/, 30s timeout, JSON content type - Add request interceptor to attach Bearer token from auth store
- Add response interceptor to unwrap
{ status, data, error }envelope - Add 401 handler that clears auth store and redirects to login
- Create
ApiErrorclass for typed error handling - Requirements: 12.1, 12.2, 12.3, 12.4, 12.5
- Create
-
2.2 Create Zustand auth store
- Create
src/stores/authStore.tswith token, username, role state login(token)decodes JWT payload, extractssubandrole, persists to localStoragelogout()clears state and localStorage- Initialize from localStorage on store creation for session persistence
- Requirements: 1.1, 1.6
- Create
-
2.3 Create API module files for each domain
- Create
src/api/auth.ts(login, register) - Create
src/api/watchlist.ts(list, add, remove) - Create
src/api/tickers.ts(list, create, delete) - Create
src/api/scores.ts(getScores, getRankings, updateWeights) - Create
src/api/trades.ts(list) - Create
src/api/ohlcv.ts(getOHLCV) - Create
src/api/indicators.ts(getIndicator, getEMACross) - Create
src/api/sr-levels.ts(getLevels) - Create
src/api/sentiment.ts(getSentiment) - Create
src/api/fundamentals.ts(getFundamentals) - Create
src/api/ingestion.ts(fetchData) - Create
src/api/admin.ts(users CRUD, settings, jobs, cleanup) - Create
src/api/health.ts(check) - Requirements: 12.1, 12.2
- Create
-
* 2.4 Write property tests for API client and auth store
- Property 1: Token storage round-trip
- Property 2: Bearer token attachment
- Property 5: API envelope unwrapping
- Validates: Requirements 1.1, 1.3, 1.6, 12.2, 12.3
-
-
3. Checkpoint — Verify foundation
- Ensure all tests pass, ask the user if questions arise.
-
4. Routing, layout, and auth pages
-
4.1 Create ProtectedRoute component and router setup
- Create
src/components/auth/ProtectedRoute.tsx— redirects to/loginif no token, redirects non-admin away from admin routes - Set up React Router in
src/App.tsxwith route structure from design (login, register, protected shell with watchlist, ticker detail, scanner, rankings, admin) - Requirements: 2.1, 2.2, 2.3, 2.4
- Create
-
4.2 Create AppShell layout with sidebar navigation
- Create
src/components/layout/AppShell.tsx— sidebar + main content area with<Outlet /> - Create
src/components/layout/Sidebar.tsx— nav links to watchlist, scanner, rankings, admin (admin link only if role is admin) - Create
src/components/layout/MobileNav.tsx— hamburger menu for screens < 1024px - Apply dark color scheme with Tailwind dark mode classes
- Add smooth transitions (150-300ms) for navigation and interactive elements
- Requirements: 2.5, 13.1, 13.2, 13.3
- Create
-
4.3 Create Login and Register pages
- Create
src/pages/LoginPage.tsxwith username/password form, callsuseAuth().loginmutation - Create
src/pages/RegisterPage.tsxwith username (min 1 char) / password (min 6 chars) validation, callsuseAuth().registermutation - Create
src/hooks/useAuth.tswith login/register/logout mutations using TanStack Query - Display API errors via toast on failure, redirect to watchlist on login success
- Requirements: 1.1, 1.2, 1.4, 1.5
- Create
-
4.4 Create shared UI components
- Create
src/components/ui/Toast.tsx— toast context + portal, auto-dismiss 4s, max 3 visible, color-coded (red/green/blue) - Create
src/components/ui/Skeleton.tsx— Tailwindanimate-pulseplaceholder blocks - Create
src/components/ui/Badge.tsx— small label component for entry types - Create
src/components/ui/ConfirmDialog.tsx— modal confirmation dialog - Create
src/components/ui/ScoreCard.tsx— composite score display with colored ring (green > 70, yellow 40-70, red < 40) and dimension breakdown - Requirements: 13.3, 13.5, 1.5
- Create
-
* 4.5 Write property tests for routing and registration validation
- Property 3: Registration form validation
- Property 4: Route protection based on auth state
- Validates: Requirements 1.2, 2.1, 2.2
-
-
5. Checkpoint — Verify auth flow and navigation
- Ensure all tests pass, ask the user if questions arise.
-
6. Watchlist view
-
6.1 Create TanStack Query hooks for watchlist
- Create
src/hooks/useWatchlist.tswithuseWatchlist()query,useAddToWatchlist()mutation,useRemoveFromWatchlist()mutation - Invalidate watchlist query on add/remove success
- Surface errors to toast system
- Requirements: 3.1, 3.3, 3.4, 3.5
- Create
-
6.2 Create WatchlistPage and sub-components
- Create
src/pages/WatchlistPage.tsx— fetches watchlist, renders table/cards, loading skeletons, error state - Create
src/components/watchlist/WatchlistTable.tsx— displays symbol (clickable →/ticker/{symbol}), entry type badge (auto/manual), composite score, dimension scores, R:R ratio, R:R direction, nearest S/R levels, remove button - Create
src/components/watchlist/AddTickerForm.tsx— input + submit to add symbol to watchlist - Requirements: 3.1, 3.2, 3.3, 3.4, 3.6, 3.7
- Create
-
* 6.3 Write property tests for watchlist rendering
- Property 6: Watchlist entry rendering completeness
- Property 7: Symbol click navigation (watchlist portion)
- Validates: Requirements 3.2, 3.6, 3.7
-
-
7. Ticker detail view
-
7.1 Create TanStack Query hooks for ticker detail
- Create
src/hooks/useTickerDetail.tswith parallel queries for OHLCV, scores, S/R levels, sentiment, fundamentals - Each query is independent — partial failure renders available sections
- Requirements: 4.1, 4.9
- Create
-
7.2 Create TickerDetailPage with chart and data panels
- Create
src/pages/TickerDetailPage.tsx— orchestrates parallel data fetching, renders sections with independent loading/error states - Create
src/components/charts/CandlestickChart.tsx— Recharts ComposedChart with custom Bar shapes for OHLCV candles, date x-axis, price y-axis - Create
src/components/ticker/SROverlay.tsx— renders S/R levels as ReferenceLine components on chart (green = support, red = resistance) - Render ScoreCard for composite + dimension scores
- Requirements: 4.1, 4.2, 4.3, 4.4, 4.9
- Create
-
7.3 Create sentiment, fundamentals, and indicator panels
- Create
src/components/ticker/SentimentPanel.tsx— displays classification, confidence, dimension score - Create
src/components/ticker/FundamentalsPanel.tsx— displays P/E, revenue growth, earnings surprise, market cap (placeholder for nulls) - Create
src/components/ticker/IndicatorSelector.tsx— dropdown to select indicator type (ADX, EMA, RSI, ATR, volume_profile, pivot_points), fetches from/api/v1/indicators/{symbol}/{type}, displays result with normalized score. Includes EMA cross signal display. - Requirements: 4.5, 4.6, 4.7, 4.8
- Create
-
7.4 Add data ingestion trigger to ticker detail
- Add fetch-data button to TickerDetailPage
- POST to
/api/v1/ingestion/fetch/{symbol}, show loading indicator on button, toast on success/failure, refresh OHLCV data on success - Requirements: 10.1, 10.2, 10.3, 10.4
-
* 7.5 Write property tests for ticker detail components
- Property 8: Score card rendering
- Property 9: Sentiment panel rendering
- Property 10: Fundamentals panel rendering
- Validates: Requirements 4.4, 4.5, 4.6
-
-
8. Checkpoint — Verify watchlist and ticker detail
- Ensure all tests pass, ask the user if questions arise.
-
9. Scanner view
-
9.1 Create TanStack Query hooks and scanner page
- Create
src/hooks/useTrades.tswithuseTrades()query - Create
src/pages/ScannerPage.tsx— fetches trade setups, renders filter controls and table, loading skeletons - Create
src/components/scanner/TradeTable.tsx— sortable table displaying symbol (clickable →/ticker/{symbol}), direction, entry price, stop loss, target, R:R ratio, composite score, detection timestamp - Add filter controls: minimum R:R numeric input, direction dropdown (long/short/both)
- Add column sorting (R:R ratio, composite score, symbol, detection time) with ascending/descending toggle
- Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6
- Create
-
* 9.2 Write property tests for scanner filtering and sorting
- Property 11: Trade setup rendering
- Property 12: Scanner filtering
- Property 13: Scanner sorting
- Validates: Requirements 5.2, 5.3, 5.4, 5.5
-
-
10. Rankings view
-
10.1 Create TanStack Query hooks and rankings page
- Create
src/hooks/useScores.tswithuseRankings()query,useUpdateWeights()mutation - Create
src/pages/RankingsPage.tsx— fetches rankings, renders table sorted by composite score descending, displays current weights - Create
src/components/rankings/RankingsTable.tsx— displays rank position, symbol (clickable →/ticker/{symbol}), composite score, all dimension scores - Create
src/components/rankings/WeightsForm.tsx— editable numeric inputs per dimension, submit updates weights via PUT, refreshes rankings on success - Requirements: 6.1, 6.2, 6.3, 6.4, 11.1, 11.2, 11.3, 11.4
- Create
-
* 10.2 Write property tests for rankings and weights
- Property 14: Rankings display order
- Property 17: Weights form rendering
- Validates: Requirements 6.1, 6.2, 11.1
-
-
11. Checkpoint — Verify scanner and rankings
- Ensure all tests pass, ask the user if questions arise.
-
12. Ticker management
- 12.1 Create TanStack Query hooks and ticker management UI
- Create
src/hooks/useTickers.tswithuseTickers()query,useAddTicker()mutation,useDeleteTicker()mutation - Add ticker list display to an appropriate location (e.g., admin page or dedicated section)
- Add ticker form for adding new symbols
- Delete button triggers ConfirmDialog before sending DELETE request
- Remove ticker from display on successful delete without full page reload
- Requirements: 9.1, 9.2, 9.3, 9.4, 9.5
- Create
- 12.1 Create TanStack Query hooks and ticker management UI
-
13. Admin panel
-
13.1 Create admin hooks and user management section
- Create
src/hooks/useAdmin.tswith queries and mutations for users, settings, jobs, cleanup - Create
src/pages/AdminPage.tsx— tabbed layout with user management, settings, jobs, data cleanup sections - Create
src/components/admin/UserTable.tsx— displays username, role, access status; toggle access, reset password controls - Add create-user form (username, password, role, access flag)
- Requirements: 7.1, 7.2, 7.3, 7.4, 7.5, 7.6
- Create
-
13.2 Create settings, jobs, and data cleanup sections
- Create
src/components/admin/SettingsForm.tsx— editable fields for each setting, registration toggle - Create
src/components/admin/JobControls.tsx— toggle on/off per job, manual trigger button, toast confirmation - Create
src/components/admin/DataCleanup.tsx— older-than-days input, submit cleanup, display result via toast - Requirements: 8.1, 8.2, 8.3, 8.4, 8.5, 8.6
- Create
-
* 13.3 Write property test for admin user table rendering
- Property 15: Admin user table rendering
- Validates: Requirements 7.2
-
-
14. Final wiring and polish
-
14.1 Add health check and loading states
- Create health check query using
GET /api/v1/health— display backend status indicator in sidebar - Ensure all pages show Skeleton placeholders during loading
- Ensure all mutation errors surface through Toast system consistently
- Requirements: 14.5, 13.5, 12.4
- Create health check query using
-
14.2 Configure production build
- Verify
vite buildoutputs tofrontend/dist/with hashed filenames - Add Nginx config snippet in comments or README for
try_files $uri $uri/ /index.htmland/api/v1/proxy - Requirements: 14.1, 14.2, 14.3, 14.4
- Verify
-
-
15. Final checkpoint — Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
Notes
- Tasks marked with
*are optional property test tasks and can be skipped for faster MVP - Each task references specific requirements for traceability
- Backend API is already running — no backend changes needed
- All 17 correctness properties are covered across optional test tasks
- Checkpoints are placed after each major phase for incremental validation