Problem
In frontend/src/hooks/usePortfolio.ts, both fetchPortfolio and executeRebalance call fetch() directly with relative paths like /api/portfolio/${portfolioId}. This bypasses:
- The centralized
API_CONFIG.BASE_URL from frontend/src/config/api.ts — needed for non-same-origin deployments (e.g., the production Render URL)
- The
apiRequest wrapper's retry logic (3 attempts with exponential backoff)
- The 15-second timeout via
AbortController
In production, if the API is on a different origin, the hook's calls silently fail or hit the wrong endpoint. This was partially addressed in issue #47 but the hook was not updated — only Dashboard.tsx and Landing.tsx use API_CONFIG.BASE_URL.
Proposed Fix
1. Use API_CONFIG.BASE_URL
Import API_CONFIG from ../config/api and prefix all fetch URLs:
const response = await fetch(`${API_CONFIG.BASE_URL}/api/portfolio/${portfolioId}`);
2. Replace with apiRequest
Use the existing apiRequest wrapper for automatic retry, timeout, and error parsing:
import { apiRequest, API_CONFIG } from '../config/api';
const data = await apiRequest(`${API_CONFIG.BASE_URL}/api/portfolio/${portfolioId}`);
3. Verify response parsing
apiRequest returns parsed JSON. The GET /portfolio/:id route returns { success: true, portfolio: {...} }, so make sure setPortfolio(data.portfolio) still works correctly.
Files to modify
frontend/src/hooks/usePortfolio.ts — update fetchPortfolio and executeRebalance
Acceptance Criteria
Affected Area
Frontend
Problem
In
frontend/src/hooks/usePortfolio.ts, bothfetchPortfolioandexecuteRebalancecallfetch()directly with relative paths like/api/portfolio/${portfolioId}. This bypasses:API_CONFIG.BASE_URLfromfrontend/src/config/api.ts— needed for non-same-origin deployments (e.g., the production Render URL)apiRequestwrapper's retry logic (3 attempts with exponential backoff)AbortControllerIn production, if the API is on a different origin, the hook's calls silently fail or hit the wrong endpoint. This was partially addressed in issue #47 but the hook was not updated — only
Dashboard.tsxandLanding.tsxuseAPI_CONFIG.BASE_URL.Proposed Fix
1. Use
API_CONFIG.BASE_URLImport
API_CONFIGfrom../config/apiand prefix all fetch URLs:2. Replace with
apiRequestUse the existing
apiRequestwrapper for automatic retry, timeout, and error parsing:3. Verify response parsing
apiRequestreturns parsed JSON. TheGET /portfolio/:idroute returns{ success: true, portfolio: {...} }, so make suresetPortfolio(data.portfolio)still works correctly.Files to modify
frontend/src/hooks/usePortfolio.ts— updatefetchPortfolioandexecuteRebalanceAcceptance Criteria
API_CONFIGfrom../config/apiAPI_CONFIG.BASE_URLfetch()withapiRequestwrappersetPortfolio(data.portfolio)still works correctly with parsed JSON responseVITE_API_URLis set to a remote URLapiRequestconfigAffected Area
Frontend