iot-agent/routes/alerts.js
2025-08-03 23:07:33 +05:30

225 lines
5.6 KiB
JavaScript

const express = require('express');
const { body, validationResult } = require('express-validator');
const { protect, authorize } = require('../middleware/auth');
const database = require('../config/database');
const alertService = require('../services/alertService');
const logger = require('../utils/logger');
const router = express.Router();
// Get all alerts
router.get('/', protect, async (req, res) => {
try {
const { page = 1, limit = 50, status, severity, device_id } = req.query;
const offset = (page - 1) * limit;
let query = 'SELECT * FROM alerts WHERE 1=1';
const params = [];
if (status) {
query += ' AND status = ?';
params.push(status);
}
if (severity) {
query += ' AND severity = ?';
params.push(severity);
}
if (device_id) {
query += ' AND device_id = ?';
params.push(device_id);
}
query += ' ORDER BY created_at DESC LIMIT ? OFFSET ?';
params.push(parseInt(limit), offset);
const alerts = await database.query(query, params);
// Get total count
let countQuery = 'SELECT COUNT(*) as total FROM alerts WHERE 1=1';
const countParams = [];
if (status) {
countQuery += ' AND status = ?';
countParams.push(status);
}
if (severity) {
countQuery += ' AND severity = ?';
countParams.push(severity);
}
if (device_id) {
countQuery += ' AND device_id = ?';
countParams.push(device_id);
}
const [countResult] = await database.query(countQuery, countParams);
const total = countResult.total;
res.json({
success: true,
data: alerts,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit)
}
});
} catch (error) {
logger.error('Get alerts error:', error);
res.status(500).json({
success: false,
message: 'Failed to get alerts'
});
}
});
// Get alert by ID
router.get('/:alertId', protect, async (req, res) => {
try {
const { alertId } = req.params;
const alerts = await database.query(
'SELECT * FROM alerts WHERE id = ?',
[alertId]
);
if (alerts.length === 0) {
return res.status(404).json({
success: false,
message: 'Alert not found'
});
}
res.json({
success: true,
data: alerts[0]
});
} catch (error) {
logger.error('Get alert error:', error);
res.status(500).json({
success: false,
message: 'Failed to get alert'
});
}
});
// Acknowledge alert
router.post('/:alertId/acknowledge', protect, async (req, res) => {
try {
const { alertId } = req.params;
await alertService.acknowledgeAlert(alertId, req.user.id);
res.json({
success: true,
message: 'Alert acknowledged successfully'
});
} catch (error) {
logger.error('Acknowledge alert error:', error);
res.status(500).json({
success: false,
message: 'Failed to acknowledge alert'
});
}
});
// Resolve alert
router.post('/:alertId/resolve', protect, [
body('resolution').optional().isString().withMessage('Resolution must be a string')
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
errors: errors.array()
});
}
const { alertId } = req.params;
const { resolution } = req.body;
await alertService.resolveAlert(alertId, req.user.id, resolution);
res.json({
success: true,
message: 'Alert resolved successfully'
});
} catch (error) {
logger.error('Resolve alert error:', error);
res.status(500).json({
success: false,
message: 'Failed to resolve alert'
});
}
});
// Get alert statistics
router.get('/stats/overview', protect, async (req, res) => {
try {
const { period = '24h' } = req.query;
let timeFilter;
switch (period) {
case '1h':
timeFilter = 'DATE_SUB(NOW(), INTERVAL 1 HOUR)';
break;
case '24h':
timeFilter = 'DATE_SUB(NOW(), INTERVAL 24 HOUR)';
break;
case '7d':
timeFilter = 'DATE_SUB(NOW(), INTERVAL 7 DAY)';
break;
case '30d':
timeFilter = 'DATE_SUB(NOW(), INTERVAL 30 DAY)';
break;
default:
timeFilter = 'DATE_SUB(NOW(), INTERVAL 24 HOUR)';
}
// Get total alerts
const [totalAlerts] = await database.query(
`SELECT COUNT(*) as count FROM alerts WHERE created_at >= ${timeFilter}`
);
// Get alerts by severity
const severityStats = await database.query(
`SELECT severity, COUNT(*) as count FROM alerts WHERE created_at >= ${timeFilter} GROUP BY severity`
);
// Get alerts by status
const statusStats = await database.query(
`SELECT status, COUNT(*) as count FROM alerts WHERE created_at >= ${timeFilter} GROUP BY status`
);
// Get alerts by type
const typeStats = await database.query(
`SELECT type, COUNT(*) as count FROM alerts WHERE created_at >= ${timeFilter} GROUP BY type ORDER BY count DESC LIMIT 10`
);
const stats = {
period,
total_alerts: totalAlerts.count,
by_severity: severityStats,
by_status: statusStats,
by_type: typeStats
};
res.json({
success: true,
data: stats
});
} catch (error) {
logger.error('Get alert stats error:', error);
res.status(500).json({
success: false,
message: 'Failed to get alert statistics'
});
}
});
module.exports = router;