This document provides the complete setup for connecting the React frontend with the FastAPI backend for the QuantResearch platform.
- URL:
http://localhost:8000 - Authentication: JWT tokens
- API Prefix:
/api
- URL:
http://localhost:3003 - Framework: React 18 + TypeScript
- Build Tool: Vite
cd c:\Users\PRAJWAL\OneDrive\Desktop\quantresearch\QuantResearch
pip install -r requirements-dev.txtCreate/update .env in the root directory:
# Database
DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/qrs
REDIS_URL=redis://localhost:6379/0
# Security
JWT_SECRET=your-secret-key-change-this-in-production
ALGORITHM=HS256
JWT_EXPIRE_MINUTES=60
# CORS - Allow frontend origins
CORS_ORIGINS=http://localhost:3003,http://localhost:3000
# Server
HOST=0.0.0.0
PORT=8000# Make sure PostgreSQL and Redis are running
# Then start the backend
uvicorn src.quant_research_starter.api.main:app --reload --host 0.0.0.0 --port 8000cd src\quant_research_starter\frontend\cauwebnpm installThe .env file is already configured:
# Backend API URL (must match where backend is running)
VITE_API_URL=http://localhost:8000
# WebSocket URL (for real-time updates)
VITE_WS_URL=ws://localhost:8000npm run devThe frontend will be available at http://localhost:3003
Location: src/quant_research_starter/frontend/cauweb/src/utils/api.ts
Key Changes:
- ✅ Uses environment variable
VITE_API_URLinstead of hardcoded URL - ✅ Centralized error handling with
handleApiError() - ✅ Automatic token management from localStorage
- ✅ Auto-redirect to login on 401 Unauthorized
Usage Example:
// Login
const data = await api.login(email, password);
localStorage.setItem('token', data.access_token);
// Fetch protected data
const positions = await api.getPositions();Location: src/quant_research_starter/frontend/cauweb/src/context/AuthContext.tsx
Key Changes:
- ✅ Removed Supabase dependency
- ✅ Pure JWT token-based authentication
- ✅ Persistent auth state via localStorage
- ✅ Simple API:
setAuthData()andclearAuth()
Usage Example:
import { useAuth } from '../context/AuthContext';
function MyComponent() {
const { user, isAuthenticated, setAuthData, clearAuth } = useAuth();
// After login
setAuthData(token, { id: 1, username: 'user@example.com', email: 'user@example.com' });
// Logout
clearAuth();
}Location: src/quant_research_starter/frontend/cauweb/src/main.tsx
Key Changes:
- ✅ Wrapped app with
<AuthProvider>for global auth state
- ✅
.env- Active environment configuration - ✅
.env.example- Template for new setups
POST /api/auth/register- Register new userPOST /api/auth/token- Login (returns JWT token)GET /api/auth/me- Get current user info
GET /api/dashboard/overview- Dashboard statisticsGET /api/dashboard/positions- User positionsGET /api/dashboard/trades- Recent trades
POST /api/positions/buy- Buy stockPOST /api/positions/sell- Sell stockGET /api/positions- Get all positionsGET /api/trades- Get trade history
GET /api/portfolio/balance- Get portfolio balancePOST /api/portfolio/deposit- Deposit cashPOST /api/portfolio/withdraw- Withdraw cash
POST /api/backtest- Run backtestGET /api/backtest/{jobId}/results- Get backtest results
GET /api/watchlists- Get all watchlistsPOST /api/watchlists- Create watchlistPOST /api/watchlists/{id}/symbols- Add symbol to watchlist
GET /api/alerts- Get all alertsPOST /api/alerts- Create alertDELETE /api/alerts/{id}- Delete alert
GET /api/strategies- Get all strategiesPOST /api/strategies- Create strategyPOST /api/strategies/{id}/activate- Activate strategyPOST /api/strategies/{id}/deactivate- Deactivate strategy
const response = await api.register('user@example.com', 'password123');
// User created, now loginconst data = await api.login('user@example.com', 'password123');
localStorage.setItem('token', data.access_token);
localStorage.setItem('user', JSON.stringify({ email: 'user@example.com' }));
window.location.href = '/';All API requests automatically include the JWT token from localStorage:
// Automatically includes: Authorization: Bearer <token>
const positions = await api.getPositions();When a token expires (401 Unauthorized), the app automatically:
- Clears localStorage (token + user)
- Redirects to
/login - Shows "Session expired" message
The backend is configured to accept requests from:
http://localhost:3003(default frontend port)http://localhost:3000(alternative)http://localhost:3004-3006(for testing)
To add more origins, update CORS_ORIGINS in backend .env:
CORS_ORIGINS=http://localhost:3003,http://localhost:3000,http://yourdomain.com# Terminal 1 - Backend
cd c:\Users\PRAJWAL\OneDrive\Desktop\quantresearch\QuantResearch
uvicorn src.quant_research_starter.api.main:app --reload --port 8000
# Terminal 2 - Frontend
cd src\quant_research_starter\frontend\cauweb
npm run dev- Open
http://localhost:3003 - Click "Register" and create account
- Login with credentials
- You should be redirected to dashboard
Open browser DevTools Console and test:
// Should show 401 without token
fetch('http://localhost:8000/api/dashboard/overview')
// Login first, then try again
// Should work with token in localStorageSolution:
- Verify backend is running on port 8000
- Check
VITE_API_URLin frontend.env - Ensure no firewall blocking localhost:8000
Solution:
- Check if token exists:
localStorage.getItem('token') - Verify token is valid (not expired)
- Re-login to get fresh token
Solution:
- Add frontend URL to
CORS_ORIGINSin backend.env - Restart backend after changing .env
- Clear browser cache
Solution:
- Clear localStorage:
localStorage.clear() - Register new account or login again
- Check JWT_EXPIRE_MINUTES in backend .env
- Set strong
JWT_SECRETin production - Use production database URL
- Set
CORS_ORIGINSto actual frontend domain - Enable HTTPS
- Build production bundle:
npm run build - Update
VITE_API_URLto production backend URL - Deploy
dist/folder to static hosting (Vercel, Netlify, etc.)
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/dbname
REDIS_URL=redis://localhost:6379/0
JWT_SECRET=change-this-to-random-secret
JWT_EXPIRE_MINUTES=60
CORS_ORIGINS=http://localhost:3003
HOST=0.0.0.0
PORT=8000VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000- ✅ Never commit .env files - Use .env.example as template
- ✅ Use strong JWT secrets - Generate random 32+ character strings
- ✅ Set appropriate token expiry - Balance security vs UX
- ✅ Validate all inputs - Backend validates all requests
- ✅ Use HTTPS in production - Never send tokens over HTTP
- ✅ Implement rate limiting - Prevent brute force attacks
- ✅ Log security events - Monitor authentication attempts
User Registration/Login
↓
Frontend sends credentials to /api/auth/token
↓
Backend validates & returns JWT token
↓
Frontend stores token in localStorage
↓
Frontend includes token in all API requests
↓
Backend validates token & processes request
↓
Frontend displays data to user
- ✅ Frontend and backend are connected
- ✅ Authentication works with JWT tokens
- ✅ All API endpoints are integrated
- 🔜 Add real-time features with WebSockets
- 🔜 Implement refresh tokens for better UX
- 🔜 Add user profile management
- 🔜 Deploy to production
Status: ✅ Frontend-Backend Integration Complete and Working!
Last Updated: January 2026