Files
Deep-Package-Inspection/backend/routes/dashboard/agents.js
T

103 lines
3.6 KiB
JavaScript

// backend/routes/dashboard/agents.js
// ─────────────────────────────────────────────────────────────────────────────
// Agent Management and Telemetry API Router
// ─────────────────────────────────────────────────────────────────────────────
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const { Summary } = require('../../models/Schemas');
const { getTimeFilter } = require('./helpers');
// GET /api/dashboard/agents/uptime
router.get('/agents/uptime', async (req, res) => {
try {
const range = req.query.timeRange || '1d';
const cyclesMap = {
'5m': 1,
'30m': 6,
'1h': 12,
'1d': 288,
'7d': 2016,
};
const ideal = cyclesMap[range] ?? 12;
let timeFilter = getTimeFilter(req);
if (!timeFilter) {
const now = new Date();
timeFilter = { $gte: new Date(now.getTime() - 7 * 24 * 3600000) };
}
const query = { timestamp: timeFilter };
if (req.user?.site_uuid) query.site_uuid = req.user.site_uuid;
const stats = await Summary.aggregate([
{ $match: query },
{ $group: { _id: "$agent_uuid", count: { $sum: 1 } } }
]);
const uptimeMap = {};
stats.forEach(s => {
if (s._id) {
const pct = Math.min(100, Math.round((s.count / ideal) * 1000) / 10);
uptimeMap[s._id] = pct;
}
});
res.json({ ok: true, uptime: uptimeMap });
} catch (err) {
res.status(500).json({ ok: false, error: err.message });
}
});
// GET /api/dashboard/agents
router.get('/agents', async (req, res) => {
try {
const isAuthorized = req.user?.role === 'SUPER_ADMIN' ||
req.user?.role === 'TENANT_ADMIN' ||
req.user?._originalRole === 'SUPER_ADMIN' ||
req.user?._originalRole === 'TENANT_ADMIN';
if (!isAuthorized) {
return res.status(403).json({ ok: false, error: 'Forbidden: Admin access only' });
}
const query = {};
const effectiveRole = req.user?._originalRole || req.user?.role;
if (effectiveRole === 'TENANT_ADMIN') {
query.site_uuid = req.user.site_uuid;
}
const agents = await Summary.distinct('agent_uuid', query);
res.json({ ok: true, count: agents.length, agents });
} catch (err) {
res.status(500).json({ ok: false, error: err.message });
}
});
// GET /api/dashboard/agents/storage
// Returns per-agent total data size from in-memory cache (capacityTracker).
// Cache is computed once at startup and refreshed every 5-minute collection cycle.
// Values represent total MongoDB storage footprint per agent (across 7-day retention window).
router.get('/agents/storage', async (req, res) => {
try {
const isAuthorized = req.user?.role === 'SUPER_ADMIN' ||
req.user?.role === 'TENANT_ADMIN' ||
req.user?._originalRole === 'SUPER_ADMIN' ||
req.user?._originalRole === 'TENANT_ADMIN';
if (!isAuthorized) {
return res.status(403).json({ ok: false, error: 'Forbidden: Admin access only' });
}
const { agentSizesCache, lastCacheUpdate } = require('../../db/capacityTracker');
const storage = agentSizesCache();
const cachedAt = lastCacheUpdate();
res.json({ ok: true, storage, cached_at: cachedAt });
} catch (err) {
res.status(500).json({ ok: false, error: err.message });
}
});
module.exports = router;