Files
dashcaddy/dashcaddy-api/routes/config-drift.js
T
Hermes 11cfb8c26a
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Consolidate response helpers and error logger to single modules
Two cleanups in one pass for the v1.14.0 'works on any platform' theme:

1. Response helpers — merged src/utils/responses.js and the root-level
   response-helpers.js into a single module at src/utils/responses.js.
   The old module had a richer set (created, noContent, validationError,
   unauthorized, forbidden, notFound, conflict) and is now re-exported
   from the new location. Updated 15 routes to import from
   src/utils/responses and deleted the root response-helpers.js.

2. Error logger — error-handler.js now uses the unified
   src/utils/logging.js#logError (same one src/app.js uses), so all errors
   go to one log file with one rotation policy. Removed the dead
   asyncHandler export (the real one is in src/utils/async-handler.js
   and is used everywhere). Deleted the legacy error-logger.js.

Both are invisible to users — same HTTP response shapes, same log file
path, same error format. Internal-only refactor.
2026-06-10 21:37:55 -07:00

93 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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;
};