const express = require('express'); const { ApiDebugLogger } = require('../utils/apiDebugLogger'); const { DroneDetection, Heartbeat, Device } = require('../models'); const { Op } = require('sequelize'); const { authenticateToken } = require('../middleware/auth'); const MultiTenantAuth = require('../middleware/multi-tenant-auth'); const router = express.Router(); const logger = new ApiDebugLogger(); // Test endpoint for API debugging router.get('/debug-test', (req, res) => { console.log('๐Ÿงช Debug test endpoint called'); const response = { message: 'Debug logging test successful', timestamp: new Date().toISOString(), debugEnabled: process.env.API_DEBUG === 'true', nodeEnv: process.env.NODE_ENV }; // Manual log entry for testing logger.log('GET', '/api/debug-test', 200, req.query, response); res.json(response); }); // Get recent detection payloads with raw data router.get('/detection-payloads', authenticateToken, MultiTenantAuth, async (req, res) => { try { const { limit = 50, offset = 0, device_id, detection_id } = req.query; const whereClause = { raw_payload: { [Op.ne]: null } }; if (device_id) { whereClause.device_id = device_id; } if (detection_id) { whereClause.id = detection_id; } // ๐Ÿ”’ SECURITY: Filter detections by user's tenant using device relationship const detections = await DroneDetection.findAll({ where: whereClause, include: [{ model: Device, as: 'device', where: { tenant_id: req.user.tenant_id }, attributes: ['id', 'name', 'tenant_id'] }], order: [['server_timestamp', 'DESC']], limit: parseInt(limit), offset: parseInt(offset), attributes: [ 'id', 'device_id', 'drone_id', 'drone_type', 'rssi', 'freq', 'server_timestamp', 'device_timestamp', 'raw_payload', 'confidence_level', 'signal_duration', 'geo_lat', 'geo_lon' ] }); console.log(`๏ฟฝ Retrieved ${detections.length} detection payloads for tenant ${req.user.tenant_id}`); res.json({ success: true, data: detections, total: detections.length, filters: { device_id, limit, offset }, tenant_id: req.user.tenant_id }); } catch (error) { console.error('Error fetching detection payloads:', error); res.status(500).json({ success: false, error: 'Failed to fetch detection payloads' }); } }); // Get recent heartbeat payloads with raw data router.get('/heartbeat-payloads', authenticateToken, MultiTenantAuth, async (req, res) => { try { const { limit = 50, offset = 0, device_id } = req.query; const whereClause = { raw_payload: { [Op.ne]: null }, tenant_id: req.user.tenant_id // ๐Ÿ”’ SECURITY: Filter by user's tenant }; if (device_id) { whereClause.device_id = device_id; } const heartbeats = await Heartbeat.findAll({ where: whereClause, order: [['received_at', 'DESC']], limit: parseInt(limit), offset: parseInt(offset), attributes: [ 'id', 'device_id', 'device_key', 'received_at', 'raw_payload', 'tenant_id' ] }); console.log(`๏ฟฝ Retrieved ${heartbeats.length} heartbeat payloads for tenant ${req.user.tenant_id}`); res.json({ success: true, data: heartbeats, total: heartbeats.length, filters: { device_id, limit, offset }, tenant_id: req.user.tenant_id }); } catch (error) { console.error('Error fetching heartbeat payloads:', error); res.status(500).json({ success: false, error: 'Failed to fetch heartbeat payloads' }); } }); // Get debug configuration status router.get('/config', authenticateToken, (req, res) => { const config = { STORE_HEARTBEATS: process.env.STORE_HEARTBEATS === 'true', STORE_DRONE_TYPE0: process.env.STORE_DRONE_TYPE0 === 'true', LOG_ALL_DETECTIONS: process.env.LOG_ALL_DETECTIONS === 'true', API_DEBUG: process.env.API_DEBUG === 'true', STORE_RAW_PAYLOAD: process.env.STORE_RAW_PAYLOAD === 'true', NODE_ENV: process.env.NODE_ENV }; console.log('๐Ÿ” Debug configuration requested'); res.json({ success: true, config, timestamp: new Date().toISOString() }); }); module.exports = router;