feat: Complete admin panel implementation
- Add user management system with all CRUD operations - Add promotion statistics dashboard with export - Simplify Trading & Market settings UI - Fix promotion schema (dates now optional) - Add missing API endpoints and PATCH support - Add comprehensive documentation - Fix critical bugs (deletePromotion, duplicate endpoints) All features tested and production-ready.
This commit is contained in:
252
PROXY_FIX_EXPLAINED.md
Normal file
252
PROXY_FIX_EXPLAINED.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# Admin Routes 404 Issue - Proxy Configuration Fix
|
||||
|
||||
## 🎯 Problem Identified
|
||||
|
||||
The admin routes were returning **404 Not Found** errors even though:
|
||||
- ✅ Backend was running
|
||||
- ✅ User was authenticated as admin
|
||||
- ✅ Routes were registered in the backend
|
||||
|
||||
## 🔍 Root Cause
|
||||
|
||||
The issue was in the **AdminDebugPanel.vue** component. It was making API calls with:
|
||||
|
||||
```javascript
|
||||
// WRONG - Bypasses Vite proxy
|
||||
const response = await axios.get('/health', {
|
||||
baseURL: 'http://localhost:3000', // ❌ Direct backend URL
|
||||
timeout: 5000,
|
||||
});
|
||||
```
|
||||
|
||||
### Why This Caused 404 Errors
|
||||
|
||||
1. **Vite Proxy Configuration** (`vite.config.js`):
|
||||
```javascript
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: "http://localhost:3000",
|
||||
changeOrigin: true,
|
||||
}
|
||||
}
|
||||
```
|
||||
- This tells Vite: "When you see `/api/*`, proxy it to `http://localhost:3000/api/*`"
|
||||
|
||||
2. **Axios Configuration** (`frontend/src/utils/axios.js`):
|
||||
```javascript
|
||||
baseURL: import.meta.env.VITE_API_URL || '/api'
|
||||
```
|
||||
- Default baseURL is `/api`
|
||||
- This works with the Vite proxy
|
||||
|
||||
3. **AdminDebugPanel Issue**:
|
||||
- It was overriding the baseURL to `http://localhost:3000`
|
||||
- This bypassed the Vite proxy completely
|
||||
- Requests went directly to backend, missing the `/api` prefix
|
||||
- Backend routes are at `/api/admin/*`, not `/admin/*`
|
||||
- Result: 404 Not Found
|
||||
|
||||
## 📊 Request Flow Comparison
|
||||
|
||||
### ❌ Before (Broken)
|
||||
|
||||
```
|
||||
Frontend Request: GET /admin/config
|
||||
↓
|
||||
AdminDebugPanel override: baseURL = 'http://localhost:3000'
|
||||
↓
|
||||
Actual request: http://localhost:3000/admin/config
|
||||
↓
|
||||
Backend looks for: /admin/config (doesn't exist)
|
||||
↓
|
||||
Result: 404 Not Found
|
||||
```
|
||||
|
||||
### ✅ After (Fixed)
|
||||
|
||||
```
|
||||
Frontend Request: GET /admin/config
|
||||
↓
|
||||
Axios baseURL: /api
|
||||
↓
|
||||
Full path: /api/admin/config
|
||||
↓
|
||||
Vite Proxy intercepts: /api/*
|
||||
↓
|
||||
Proxies to: http://localhost:3000/api/admin/config
|
||||
↓
|
||||
Backend route exists: /api/admin/config ✅
|
||||
↓
|
||||
Result: 200 OK
|
||||
```
|
||||
|
||||
## 🔧 The Fix
|
||||
|
||||
Changed AdminDebugPanel to use the same axios configuration as the rest of the app:
|
||||
|
||||
```javascript
|
||||
// ✅ CORRECT - Uses Vite proxy
|
||||
const response = await axios.get('/health', {
|
||||
timeout: 5000,
|
||||
// No baseURL override - uses default from axios.js
|
||||
});
|
||||
```
|
||||
|
||||
Now the requests flow through the Vite proxy correctly:
|
||||
- `/admin/config` → axios adds `/api` → `/api/admin/config` → proxy → backend ✅
|
||||
|
||||
## 🎓 Key Lessons
|
||||
|
||||
### 1. Never Override baseURL in Components
|
||||
|
||||
**❌ Bad:**
|
||||
```javascript
|
||||
await axios.get('/endpoint', { baseURL: 'http://localhost:3000' })
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
```javascript
|
||||
await axios.get('/endpoint') // Uses configured baseURL
|
||||
```
|
||||
|
||||
### 2. Understand the Request Path
|
||||
|
||||
In development with Vite:
|
||||
```
|
||||
Component: /admin/config
|
||||
↓ (axios adds baseURL)
|
||||
Axios: /api/admin/config
|
||||
↓ (Vite proxy intercepts /api/*)
|
||||
Proxy: http://localhost:3000/api/admin/config
|
||||
↓
|
||||
Backend: Receives /api/admin/config ✅
|
||||
```
|
||||
|
||||
### 3. Production vs Development
|
||||
|
||||
**Development (with Vite proxy):**
|
||||
- Frontend: `http://localhost:5173`
|
||||
- Backend: `http://localhost:3000`
|
||||
- Requests: `/api/*` → proxied to backend
|
||||
- CORS: No issues (same origin due to proxy)
|
||||
|
||||
**Production (no proxy):**
|
||||
- Frontend: `https://yourdomain.com`
|
||||
- Backend: `https://yourdomain.com/api` or separate domain
|
||||
- Requests: Direct to backend
|
||||
- CORS: Must be configured on backend
|
||||
|
||||
## 📋 Checklist for Similar Issues
|
||||
|
||||
If you encounter 404 errors with API routes:
|
||||
|
||||
- [ ] Check if routes are registered in backend
|
||||
- [ ] Check if server was restarted after adding routes
|
||||
- [ ] Check the actual URL being requested (Network tab)
|
||||
- [ ] Verify Vite proxy configuration
|
||||
- [ ] Verify axios baseURL configuration
|
||||
- [ ] Check for baseURL overrides in components
|
||||
- [ ] Ensure `/api` prefix is consistent
|
||||
- [ ] Test with curl to verify backend routes exist
|
||||
|
||||
## 🧪 Testing the Fix
|
||||
|
||||
### 1. Check Network Tab
|
||||
Open DevTools (F12) → Network tab:
|
||||
- URL should be: `http://localhost:5173/api/admin/config`
|
||||
- Status should be: 200 OK (not 404)
|
||||
|
||||
### 2. Use Debug Panel
|
||||
Navigate to `/admin` → Debug tab → Run Tests:
|
||||
- All 4 tests should pass ✅
|
||||
- No 404 errors
|
||||
|
||||
### 3. Manual Test
|
||||
```bash
|
||||
# This should work (proxied through Vite)
|
||||
curl http://localhost:5173/api/admin/config
|
||||
|
||||
# This won't work in development (no /api prefix)
|
||||
curl http://localhost:3000/admin/config # 404
|
||||
|
||||
# This will work (correct backend path)
|
||||
curl http://localhost:3000/api/admin/config
|
||||
```
|
||||
|
||||
## 📝 Configuration Summary
|
||||
|
||||
### Vite Proxy (vite.config.js)
|
||||
```javascript
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: "http://localhost:3000",
|
||||
changeOrigin: true,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Axios Base URL (frontend/src/utils/axios.js)
|
||||
```javascript
|
||||
baseURL: import.meta.env.VITE_API_URL || '/api'
|
||||
```
|
||||
|
||||
### Backend Routes (index.js)
|
||||
```javascript
|
||||
await fastify.register(adminManagementRoutes, { prefix: "/api/admin" });
|
||||
```
|
||||
|
||||
### Component Usage
|
||||
```javascript
|
||||
// ✅ Correct - No baseURL override
|
||||
await axios.get('/admin/config')
|
||||
// Becomes: /api/admin/config via proxy
|
||||
|
||||
// ❌ Wrong - Overrides baseURL
|
||||
await axios.get('/admin/config', { baseURL: 'http://localhost:3000' })
|
||||
// Becomes: http://localhost:3000/admin/config (bypasses proxy, 404)
|
||||
```
|
||||
|
||||
## 🎉 Result
|
||||
|
||||
After the fix:
|
||||
- ✅ All admin routes accessible
|
||||
- ✅ Debug panel tests pass
|
||||
- ✅ Config tab loads settings
|
||||
- ✅ Users tab works
|
||||
- ✅ No 404 errors
|
||||
- ✅ Proxy working correctly
|
||||
|
||||
## 🔜 Prevention
|
||||
|
||||
To prevent this issue in the future:
|
||||
|
||||
1. **Establish a pattern:**
|
||||
- Always use the shared axios instance from `@/utils/axios`
|
||||
- Never override baseURL in components
|
||||
- Let the configuration handle URL construction
|
||||
|
||||
2. **Code review checklist:**
|
||||
- Check for baseURL overrides
|
||||
- Verify proxy paths are correct
|
||||
- Test API routes after adding new ones
|
||||
|
||||
3. **Documentation:**
|
||||
- Document the request flow
|
||||
- Explain proxy configuration
|
||||
- Provide examples of correct usage
|
||||
|
||||
## 📚 Related Files
|
||||
|
||||
- `frontend/vite.config.js` - Proxy configuration
|
||||
- `frontend/src/utils/axios.js` - Axios setup
|
||||
- `frontend/src/components/AdminDebugPanel.vue` - Fixed component
|
||||
- `index.js` - Backend route registration
|
||||
- `routes/admin-management.js` - Admin routes
|
||||
|
||||
---
|
||||
|
||||
**Issue:** Admin routes returning 404
|
||||
**Cause:** baseURL override bypassing Vite proxy
|
||||
**Solution:** Remove baseURL override, use default configuration
|
||||
**Status:** ✅ Fixed and tested
|
||||
**Build:** ✅ Successful
|
||||
Reference in New Issue
Block a user