Wires the new dashboard to real market data and adds the strategy
builder & screener UIs that were stubbed in the previous commit.
Frontend (web/src/):
- lib/marketApi.ts: authenticated fetch helpers for chart bars,
market indices, news, and FMP research endpoints
- views/HomeView.tsx: StockChart now fetches live OHLCV via
fetchChartBars on symbol/period change with loading/error states;
ResearchCards replaces the static placeholder with live FMP
profile/metrics/earnings (next-earnings + last 3 historical)
- components/layout/Header.tsx: live SPY/DIA/QQQ price + change%
via fetchMarketIndices, refreshing every 60s; removed unused
static sparkline placeholder
- components/strategy/VisualRuleBuilder.tsx: drag-and-drop IF/THEN
rule composer using @dnd-kit (RSI/MACD/EMA/Price/Volume,
above/below/crosses, BUY/SELL with shares or % of capital);
saves via POST /api/profiles
- components/strategy/CodeStrategyEditor.tsx: Monaco editor with
JS strategy template; "Run Backtest" posts to /api/backtest and
renders return/win-rate/Sharpe/drawdown plus trade log
- views/ResearchView.tsx: adds "Visual Builder" and "Code Editor"
sub-tabs alongside Strategies / Signals / Backtesting
- views/ScreenerView.tsx: live FMP screener with market-cap and
sector filters, sortable columns, click-to-load-symbol routing
- index.css: light theme background; @keyframes spin for loaders
- App.dom.test.tsx: rewritten for router-based AppShell (was
asserting on the removed tab UI; fixes 5 prior failures)
Backend (backend/src/services/apiServer.ts):
- /api/chart/bars: detects crypto symbols (contains "/") and
routes to Alpaca v1beta3/crypto/us/bars; equities use
v2/stocks/{symbol}/bars with iex feed
- (existing) /api/news, /api/market/indices, /api/research/{
profile,metrics,earnings}, /api/screener proxy endpoints
Build/config:
- web/vite.config.ts: dedupe react / react/jsx-runtime /
react-router-dom so the vendored react-auth dist resolves the
same React instance (fixes "Cannot resolve react/jsx-runtime"
Rollup error)
- web/tsconfig.app.json: exclude shared/platform-clients.ts and
shared/platform-mobile.ts (mobile-only, missing RN SDK)
- web/package.json: add react-router-dom, @monaco-editor/react,
@dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities
Verification: `npm run build` in web/ → clean (✓ built in 3s);
backend tsc --noEmit → clean. Test suite: 151/155 pass; the 4
remaining failures are pre-existing (3 useTabFeatureFlags module
cache leaks, 1 EntryForm), not introduced here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
1.8 KiB
TypeScript
45 lines
1.8 KiB
TypeScript
import { defineConfig } from 'vitest/config'
|
|
import react from '@vitejs/plugin-react'
|
|
import tailwindcss from '@tailwindcss/vite'
|
|
import path from 'node:path'
|
|
import fs from 'node:fs'
|
|
|
|
// Resolve a @bytelyst/* package: prefer web/node_modules, fall back to vendor/
|
|
function bytelystAlias(pkg: string): string {
|
|
const nmPath = path.resolve(__dirname, 'node_modules/@bytelyst', pkg);
|
|
const vendorPath = path.resolve(__dirname, '../vendor/bytelyst', pkg);
|
|
if (fs.existsSync(nmPath)) return nmPath;
|
|
if (fs.existsSync(vendorPath)) return vendorPath;
|
|
return nmPath; // let Vite surface the missing-module error
|
|
}
|
|
|
|
// https://vite.dev/config/
|
|
export default defineConfig({
|
|
plugins: [
|
|
react(),
|
|
tailwindcss(),
|
|
],
|
|
// Shared files (../shared/*.ts) live outside web/ so Vite resolves their imports
|
|
// from the repo root where @bytelyst/* are not installed. Redirect all @bytelyst/*
|
|
// imports first to web/node_modules, then fall back to the monorepo vendor/ dir.
|
|
resolve: {
|
|
// Deduplicate React so the vendored react-auth dist resolves the same react instance
|
|
dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react-router-dom'],
|
|
alias: [
|
|
// Vendor packages that live only in vendor/ (not in web/node_modules/)
|
|
{ find: '@bytelyst/api-client', replacement: bytelystAlias('api-client') },
|
|
{ find: '@bytelyst/errors', replacement: bytelystAlias('errors') },
|
|
// General catch-all: every other @bytelyst/* → web/node_modules
|
|
{
|
|
find: /^@bytelyst\/(.+)/,
|
|
replacement: path.resolve(__dirname, 'node_modules/@bytelyst/$1'),
|
|
},
|
|
],
|
|
},
|
|
test: {
|
|
environment: 'jsdom',
|
|
setupFiles: ['./src/test/setup.ts'],
|
|
include: ['src/**/*.test.ts', 'src/**/*.test.tsx', 'src/**/*.dom.test.tsx'],
|
|
},
|
|
})
|