// Request debugging utility // Add this to your browser console to track API requests window.requestTracker = { requests: [], isTracking: false, start() { if (this.isTracking) return; this.isTracking = true; this.requests = []; // Override fetch to track requests const originalFetch = window.fetch; window.fetch = async (...args) => { const start = performance.now(); const url = args[0]; const method = args[1]?.method || 'GET'; try { const response = await originalFetch(...args); const end = performance.now(); const duration = Math.round(end - start); this.requests.push({ url, method, status: response.status, duration, timestamp: new Date().toISOString(), type: url.includes('/api/') ? 'API' : 'Other' }); // Keep only last 100 requests if (this.requests.length > 100) { this.requests = this.requests.slice(-100); } return response; } catch (error) { const end = performance.now(); const duration = Math.round(end - start); this.requests.push({ url, method, error: error.message, duration, timestamp: new Date().toISOString(), type: url.includes('/api/') ? 'API' : 'Other' }); throw error; } }; console.log('🔍 Request tracking started'); }, stop() { this.isTracking = false; // Restore original fetch (simplified - in production you'd store the reference) console.log('🔍 Request tracking stopped'); }, stats() { const apiRequests = this.requests.filter(r => r.type === 'API'); const lastMinute = apiRequests.filter(r => { const requestTime = new Date(r.timestamp); const oneMinuteAgo = new Date(Date.now() - 60000); return requestTime > oneMinuteAgo; }); const lastFiveMinutes = apiRequests.filter(r => { const requestTime = new Date(r.timestamp); const fiveMinutesAgo = new Date(Date.now() - 300000); return requestTime > fiveMinutesAgo; }); // Group by endpoint const endpointCounts = {}; apiRequests.forEach(r => { const endpoint = r.url.split('/').pop() || 'unknown'; endpointCounts[endpoint] = (endpointCounts[endpoint] || 0) + 1; }); console.log('📊 Request Statistics:'); console.log(`Total API requests: ${apiRequests.length}`); console.log(`Last 1 minute: ${lastMinute.length}`); console.log(`Last 5 minutes: ${lastFiveMinutes.length}`); console.log('Endpoints:', endpointCounts); // Show suspicious patterns if (lastMinute.length > 30) { console.warn('⚠️ High request frequency detected!'); } return { total: apiRequests.length, lastMinute: lastMinute.length, lastFiveMinutes: lastFiveMinutes.length, endpoints: endpointCounts }; }, recent(limit = 20) { console.log('📝 Recent requests:'); this.requests.slice(-limit).forEach((r, i) => { const status = r.status || 'ERR'; const icon = status === 200 ? '✅' : status >= 400 ? '❌' : '⚠️'; console.log(`${icon} ${r.method} ${r.url} (${status}) - ${r.duration}ms`); }); } }; // Auto-start tracking window.requestTracker.start(); // Show stats every 30 seconds setInterval(() => { if (window.requestTracker.isTracking) { window.requestTracker.stats(); } }, 30000);