4.3 KiB
Quick Implementation Guide
Integrating Full-Stack Enhancements
🚀 Phase 1: Quick Wins (30 minutes)
Step 1: Add Request Deduplication (Backend)
File: backend/src/server.js
import { requestDeduplication } from './middleware/requestDeduplication.js';
// Add before routes
app.use('/api/options', requestDeduplication, optionsFlowRouter);
app.use('/api/scanner', requestDeduplication, scannerRouter);
Expected Impact: 40-60% reduction in duplicate database queries
Step 2: Add Error Boundary (Frontend)
File: frontend/src/App.jsx or frontend/src/main.jsx
import { ErrorBoundary } from '@/components/ErrorBoundary';
function App() {
return (
<ErrorBoundary>
{/* Your existing app content */}
</ErrorBoundary>
);
}
Expected Impact: Better error handling, no more full app crashes
Step 3: Update API Configuration (Frontend)
File: frontend/src/hooks/useOptionsFlow.js
Replace:
const response = await fetch(`http://localhost:3010/api/options/flow?${params}`);
With:
import { getApiUrl, fetchWithRetry } from '@/config/api';
const response = await fetchWithRetry(
getApiUrl('/api/options/flow') + '?' + params
);
File: frontend/.env (create if doesn't exist)
VITE_API_URL=http://localhost:3010
VITE_WS_URL=ws://localhost:5010
Expected Impact: Environment-based config, automatic retry on failures
Step 4: Add Request Cancellation (Frontend)
File: frontend/src/hooks/useOptionsFlow.js
Update the hook to use AbortController:
const abortControllerRef = useRef(null);
const fetchData = useCallback(async () => {
// Cancel previous request
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
const abortController = new AbortController();
abortControllerRef.current = abortController;
try {
const response = await fetchWithRetry(
getApiUrl('/api/options/flow') + '?' + params,
{ signal: abortController.signal }
);
// ... rest of logic
} catch (err) {
if (err.name !== 'AbortError') {
setError(err.message);
}
}
}, [/* dependencies */]);
Expected Impact: No stale requests, better performance
Step 5: Add Retry Logic (Backend)
File: backend/src/routes/optionsFlow.js
import { RetryHandler } from '../utils/retryHandler.js';
// Wrap database queries
const rawData = await RetryHandler.withRetry(
() => rawQuery(optionsFlowQuery, [startDate, endDate]),
{
maxRetries: 3,
retryDelay: 500,
onRetry: (attempt, max, error, delay) => {
console.warn(`Retry ${attempt}/${max} after ${delay}ms`);
}
}
);
Expected Impact: Automatic recovery from transient failures
📊 Testing Your Changes
1. Test Request Deduplication
# Make multiple simultaneous requests
curl http://localhost:3010/api/options/flow?startDate=2024-01-15 &
curl http://localhost:3010/api/options/flow?startDate=2024-01-15 &
curl http://localhost:3010/api/options/flow?startDate=2024-01-15 &
# Check response headers - should see X-Cache: DEDUP for duplicate requests
2. Test Error Boundary
// Temporarily break something to test
throw new Error('Test error');
3. Test Retry Logic
# Simulate network failure (temporarily stop database)
# Should see retry attempts in logs
🎯 Next Steps
After Phase 1 is working:
- Measure improvements - Use
/api/performance/metrics - Move to Phase 2 - Batch processing, virtual scrolling
- Monitor - Watch for cache hit rates, error rates
⚠️ Common Issues
Issue: Request deduplication not working
Fix: Make sure middleware is added BEFORE routes in server.js
Issue: Environment variables not loading
Fix: Restart dev server after adding .env file
Issue: AbortController errors
Fix: Check that you're handling AbortError in catch blocks
📈 Expected Results
After Phase 1:
- ✅ 40-60% fewer duplicate database queries
- ✅ Better error handling (no app crashes)
- ✅ Automatic retry on transient failures
- ✅ Request cancellation prevents stale data
- ✅ Environment-based configuration
Ready to implement? Start with Step 1 and test each change!