/** * Config Drift Detection Routes * * API endpoints for running drift detection, reading cached reports, * auto-fixing drift, and controlling periodic polling. * * @module routes/config-drift */ const express = require('express'); const { success } = require('../src/utils/responses'); const { ValidationError, NotFoundError } = require('../errors'); /** * Config-drift route factory * * @param {Object} deps - Explicit dependencies * @param {Object} deps.driftDetector - ConfigDriftDetector instance * @param {Function} deps.asyncHandler - Async route handler wrapper * @param {Function} deps.logError - Error logging function * @returns {express.Router} */ module.exports = function ({ driftDetector, asyncHandler, logError }) { const router = express.Router(); /** * GET /config-drift/report * Run a fresh drift detection and return the full report. */ router.get('/report', asyncHandler(async (_req, res) => { const report = await driftDetector.detect(); success(res, { report }); }, 'drift-report')); /** * GET /config-drift/last * Return the last cached drift report (no re-detection). */ router.get('/last', asyncHandler(async (_req, res) => { if (!driftDetector.lastReport) { throw new NotFoundError('No cached drift report — run detection first'); } success(res, { report: driftDetector.lastReport }); }, 'drift-last')); /** * POST /config-drift/fix * Auto-fix detected drift: remove stale records, flag unknown containers. */ router.post('/fix', asyncHandler(async (_req, res) => { const result = await driftDetector.autoFix(); success(res, { message: 'Auto-fix applied', staleRemoved: result.staleRemoved, unknownFlagged: result.unknownFlagged, }); }, 'drift-fix')); /** * POST /config-drift/polling * Enable or disable periodic drift detection polling. * * Body: { enabled: boolean, intervalMs?: number } */ router.post('/polling', asyncHandler(async (req, res) => { const { enabled, intervalMs } = req.body; if (typeof enabled !== 'boolean') { throw new ValidationError('enabled must be a boolean'); } if (intervalMs !== undefined) { if (!Number.isInteger(intervalMs) || intervalMs < 10000 || intervalMs > 86400000) { throw new ValidationError('intervalMs must be an integer between 10000 and 86400000 (10s – 24h)'); } } if (enabled) { driftDetector.startPolling(intervalMs || 300000); success(res, { message: 'Drift polling enabled', intervalMs: intervalMs || 300000, }); } else { driftDetector.stopPolling(); success(res, { message: 'Drift polling disabled' }); } }, 'drift-polling')); return router; };