From f095ef24aa6c12c331531ca8233ddaa0600242b9 Mon Sep 17 00:00:00 2001 From: Krystie Date: Sat, 28 Mar 2026 19:30:03 -0700 Subject: [PATCH] refactor(routes): Phase 3.5 - standardize monitoring.js (only 3 deps!) --- dashcaddy-api/routes/monitoring.js | 68 +++++++++++++++++------------- dashcaddy-api/server.js | 6 ++- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/dashcaddy-api/routes/monitoring.js b/dashcaddy-api/routes/monitoring.js index 699624b..d1c60c0 100644 --- a/dashcaddy-api/routes/monitoring.js +++ b/dashcaddy-api/routes/monitoring.js @@ -1,72 +1,81 @@ const express = require('express'); +const { success } = require('../response-helpers'); -module.exports = function(ctx) { +/** + * Monitoring routes factory + * @param {Object} deps - Explicit dependencies + * @param {Object} deps.resourceMonitor - Resource monitoring manager + * @param {Object} deps.docker - Docker client wrapper + * @param {Function} deps.asyncHandler - Async route handler wrapper + * @returns {express.Router} + */ +module.exports = function({ resourceMonitor, docker, asyncHandler }) { const router = express.Router(); // ===== RESOURCE MONITORING ENDPOINTS ===== // Get all container stats (from resource monitor module) - router.get('/monitoring/stats', ctx.asyncHandler(async (req, res) => { - const stats = ctx.resourceMonitor.getAllStats(); - res.json({ success: true, stats }); + router.get('/monitoring/stats', asyncHandler(async (req, res) => { + const stats = resourceMonitor.getAllStats(); + success(res, { stats }); }, 'monitoring-stats')); // Get stats for specific container - router.get('/monitoring/stats/:containerId', ctx.asyncHandler(async (req, res) => { - const stats = ctx.resourceMonitor.getCurrentStats(req.params.containerId); + router.get('/monitoring/stats/:containerId', asyncHandler(async (req, res) => { + const stats = resourceMonitor.getCurrentStats(req.params.containerId); if (!stats) { const { NotFoundError } = require('../errors'); throw new NotFoundError('Container'); } - res.json({ success: true, stats }); + success(res, { stats }); }, 'monitoring-stats-container')); // Get historical stats - router.get('/monitoring/history/:containerId', ctx.asyncHandler(async (req, res) => { + router.get('/monitoring/history/:containerId', asyncHandler(async (req, res) => { const hours = parseInt(req.query.hours) || 24; - const history = ctx.resourceMonitor.getHistoricalStats(req.params.containerId, hours); - res.json({ success: true, history, hours }); + const history = resourceMonitor.getHistoricalStats(req.params.containerId, hours); + success(res, { history, hours }); }, 'monitoring-history')); // Get aggregated stats - router.get('/monitoring/aggregated/:containerId', ctx.asyncHandler(async (req, res) => { + router.get('/monitoring/aggregated/:containerId', asyncHandler(async (req, res) => { const hours = parseInt(req.query.hours) || 24; - const aggregated = ctx.resourceMonitor.getAggregatedStats(req.params.containerId, hours); + const aggregated = resourceMonitor.getAggregatedStats(req.params.containerId, hours); if (!aggregated) { const { NotFoundError } = require('../errors'); throw new NotFoundError('Monitoring data'); } - res.json({ success: true, aggregated, hours }); + success(res, { aggregated, hours }); }, 'monitoring-aggregated')); // Configure alerts - router.post('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => { - ctx.resourceMonitor.setAlertConfig(req.params.containerId, req.body); - res.json({ success: true, message: 'Alert configuration saved' }); + router.post('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => { + resourceMonitor.setAlertConfig(req.params.containerId, req.body); + success(res, { message: 'Alert configuration saved' }); }, 'monitoring-alerts-set')); // Get alert configuration - router.get('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => { - const config = ctx.resourceMonitor.getAlertConfig(req.params.containerId); - res.json({ success: true, config: config || {} }); + router.get('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => { + const config = resourceMonitor.getAlertConfig(req.params.containerId); + success(res, { config: config || {} }); }, 'monitoring-alerts-get')); // Delete alert configuration - router.delete('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => { - ctx.resourceMonitor.removeAlertConfig(req.params.containerId); - res.json({ success: true, message: 'Alert configuration removed' }); + router.delete('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => { + resourceMonitor.removeAlertConfig(req.params.containerId); + success(res, { message: 'Alert configuration removed' }); }, 'monitoring-alerts-delete')); // ===== CONTAINER STATS ENDPOINTS (legacy /stats/) ===== // Get all container stats (live Docker stats) - router.get('/stats/containers', ctx.asyncHandler(async (req, res) => { - const containers = await ctx.docker.client.listContainers({ all: false }); + router.get('/stats/containers', asyncHandler(async (req, res) => { + const containers = await docker.client.listContainers({ all: false }); const stats = []; for (const containerInfo of containers) { try { - const container = ctx.docker.client.getContainer(containerInfo.Id); + const container = docker.client.getContainer(containerInfo.Id); const containerStats = await container.stats({ stream: false }); // Calculate CPU percentage @@ -114,12 +123,12 @@ module.exports = function(ctx) { } } - res.json({ success: true, stats, timestamp: new Date().toISOString() }); + success(res, { stats, timestamp: new Date().toISOString() }); }, 'stats-containers')); // Get single container stats - router.get('/stats/container/:id', ctx.asyncHandler(async (req, res) => { - const container = ctx.docker.client.getContainer(req.params.id); + router.get('/stats/container/:id', asyncHandler(async (req, res) => { + const container = docker.client.getContainer(req.params.id); const containerStats = await container.stats({ stream: false }); const info = await container.inspect(); @@ -143,8 +152,7 @@ module.exports = function(ctx) { } } - res.json({ - success: true, + success(res, { stats: { name: info.Name.replace(/^\//, ''), image: info.Config.Image, diff --git a/dashcaddy-api/server.js b/dashcaddy-api/server.js index 5608379..1f802d0 100644 --- a/dashcaddy-api/server.js +++ b/dashcaddy-api/server.js @@ -1225,7 +1225,11 @@ apiRouter.use(healthRoutes({ logError: ctx.logError, healthChecker: ctx.healthChecker })); -apiRouter.use(monitoringRoutes(ctx)); +apiRouter.use(monitoringRoutes({ + resourceMonitor: ctx.resourceMonitor, + docker: ctx.docker, + asyncHandler: ctx.asyncHandler +})); apiRouter.use(updatesRoutes(ctx)); apiRouter.use('/tailscale', tailscaleRoutes(ctx)); apiRouter.use(sitesRoutes(ctx));