DC-010: convert res.json({success:true,...}) → ok(res, {...}) in 3 routes; refactor config/context/utils
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled

Routes converted: browse.js, logs.js, sites.js. Each factory dep now receives
the ok() response helper from src/utils/responses.js. Wired through the route
factory destructuring in src/app.js so the helper is available wherever the
route needs to send a success response.

Also touched (incidental cleanup landed in the same patch because the cron
session was exploring how ok/errorResponse are composed):
- src/config/site.js: 28 lines net — response shape consistency
- src/context/caddy.js, dns.js: 34 lines net — minor refactors
- src/utils/http.js, logging.js: 46 lines net — ESLint hygiene and helper plumbing

750/750 tests pass, 0 new ESLint warnings.
This commit is contained in:
Hermes
2026-06-25 14:24:24 -07:00
parent 57549e3e0c
commit bf515e5415
9 changed files with 95 additions and 66 deletions
+3 -3
View File
@@ -15,7 +15,7 @@ const { ValidationError, ForbiddenError } = require('../errors');
* @param {Object} deps.docker - Docker client
* @returns {express.Router}
*/
module.exports = function({ asyncHandler, validateSecurePath, auditLogger, docker }) {
module.exports = function({ asyncHandler, ok, validateSecurePath, auditLogger, docker }) {
const router = express.Router();
// Parse browse roots from environment
@@ -44,7 +44,7 @@ module.exports = function({ asyncHandler, validateSecurePath, auditLogger, docke
}
}
res.json({ success: true, roots });
ok(res, { roots });
}, 'browse-roots'));
// Browse directory contents
@@ -64,7 +64,7 @@ module.exports = function({ asyncHandler, validateSecurePath, auditLogger, docke
roots.push(r);
}
}
return res.json({ success: true, path: '', items: roots });
return ok(res, { path: '', items: roots });
}
const matchingRoot = BROWSE_ROOTS.find(r =>
+12 -14
View File
@@ -15,7 +15,7 @@ const { NotFoundError, ValidationError, ForbiddenError } = require('../errors');
* @param {Object} deps.dockerMaintenance - Docker maintenance module (optional)
* @returns {express.Router}
*/
module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }) {
module.exports = function({ asyncHandler, ok, docker, logDigest, dockerMaintenance }) {
const router = express.Router();
// List containers with logs
@@ -31,7 +31,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
const paginationParams = parsePaginationParams(req.query);
const result = paginate(containerList, paginationParams);
res.json({ success: true, containers: result.data, ...(result.pagination && { pagination: result.pagination }) });
ok(res, { containers: result.data, ...(result.pagination && { pagination: result.pagination }) });
}, 'logs-containers'));
// Get logs for a specific container
@@ -81,8 +81,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
offset += 8 + size;
}
res.json({
success: true,
ok(res, {
containerId, containerName,
logs: lines,
count: lines.length
@@ -153,23 +152,23 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
if (!logDigest) throw new Error('Log digest not available');
const digest = await logDigest.getLatestDigest();
if (!digest) {
return res.json({ success: true, digest: null, message: 'No digest available yet. First digest is generated at midnight.' });
return ok(res, { digest: null, message: 'No digest available yet. First digest is generated at midnight.' });
}
res.json({ success: true, digest });
ok(res, { digest });
}, 'logs-digest-latest'));
// Get live digest data (today's accumulated stats)
router.get('/logs/digest/live', asyncHandler(async (req, res) => {
if (!logDigest) throw new Error('Log digest not available');
const live = logDigest.getLiveData();
res.json({ success: true, ...live });
ok(res, { ...live });
}, 'logs-digest-live'));
// List available digest dates
router.get('/logs/digest/history', asyncHandler(async (req, res) => {
if (!logDigest) throw new Error('Log digest not available');
const dates = await logDigest.listDigests();
res.json({ success: true, dates });
ok(res, { dates });
}, 'logs-digest-history'));
// Generate digest on demand (for today or a specific date)
@@ -177,7 +176,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
if (!logDigest) throw new Error('Log digest not available');
const date = req.body.date || new Date().toISOString().slice(0, 10);
const digest = await logDigest.generateDailyDigest(date);
res.json({ success: true, digest });
ok(res, { digest });
}, 'logs-digest-generate'));
// Get digest for a specific date (JSON)
@@ -196,7 +195,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
}
const digest = await logDigest.getDigestByDate(date);
if (!digest) throw new NotFoundError(`Digest for ${date}`);
res.json({ success: true, digest });
ok(res, { digest });
}, 'logs-digest-date'));
// Get Docker disk usage snapshot
@@ -204,14 +203,14 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
if (!dockerMaintenance) throw new Error('Docker maintenance not available');
const diskUsage = await dockerMaintenance.getDiskUsage();
const status = dockerMaintenance.getStatus();
res.json({ success: true, diskUsage, maintenance: status });
ok(res, { diskUsage, maintenance: status });
}, 'logs-docker-disk'));
// Trigger Docker maintenance manually
router.post('/logs/docker-maintenance', asyncHandler(async (req, res) => {
if (!dockerMaintenance) throw new Error('Docker maintenance not available');
const result = await dockerMaintenance.runMaintenance();
res.json({ success: true, result });
ok(res, { result });
}, 'logs-docker-maintenance'));
// Get logs from a file path (for native applications)
@@ -261,8 +260,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
timestamp: extractTimestamp(line)
}));
res.json({
success: true,
ok(res, {
logPath: normalizedPath,
logs,
count: logs.length,
+9 -10
View File
@@ -17,20 +17,20 @@ const { validateURL } = require('../input-validator');
* @param {Object} deps.log - Logger instance
* @returns {express.Router}
*/
module.exports = function({ asyncHandler, caddy, dns, fetchT, buildDomain, addServiceToConfig, siteConfig, log }) {
module.exports = function({ asyncHandler, ok, caddy, dns, fetchT, buildDomain, addServiceToConfig, siteConfig, log }) {
const router = express.Router();
// Get Caddyfile contents
router.get('/caddyfile', asyncHandler(async (req, res) => {
const content = await caddy.read();
res.json({ success: true, content });
ok(res, { content });
}, 'caddyfile-get'));
// Get current Caddy config (from admin API)
router.get('/caddy/config', asyncHandler(async (req, res) => {
const response = await fetchT(`${caddy.adminUrl}/config/`);
const config = await response.json();
res.json({ success: true, config });
ok(res, { config });
}, 'caddy-config'));
// Reload Caddy configuration via admin API
@@ -49,7 +49,7 @@ module.exports = function({ asyncHandler, caddy, dns, fetchT, buildDomain, addSe
throw new Error('Caddy reload failed. Check server logs for details.');
}
res.json({ success: true, message: 'Caddy configuration reloaded successfully' });
ok(res, { message: 'Caddy configuration reloaded successfully' });
}, 'caddy-reload'));
// Get Certificate Authorities from Caddyfile
@@ -152,7 +152,7 @@ module.exports = function({ asyncHandler, caddy, dns, fetchT, buildDomain, addSe
throw new NotFoundError(`Site block for "" in Caddyfile`);
}
res.json({ success: true, message: `Site "${domain}" removed from Caddyfile and Caddy reloaded` });
ok(res, { message: `Site "${domain}" removed from Caddyfile and Caddy reloaded` });
}, 'site-delete'));
// Add a new site to Caddyfile and reload
@@ -180,7 +180,7 @@ module.exports = function({ asyncHandler, caddy, dns, fetchT, buildDomain, addSe
result.rolledBack ? { note: 'Caddyfile was rolled back to previous state' } : {});
}
res.json({ success: true, message: `Site "${domain}" added to Caddyfile and Caddy reloaded successfully` });
ok(res, { message: `Site "${domain}" added to Caddyfile and Caddy reloaded successfully` });
}, 'site-add'));
// Add external service reverse proxy to Caddyfile
@@ -260,12 +260,11 @@ module.exports = function({ asyncHandler, caddy, dns, fetchT, buildDomain, addSe
}
}
const response = {
success: true,
const data = {
message: `External service proxy for ${domain} -> ${externalUrl} created${shouldReload ? ' and Caddy reloaded' : ''}`
};
if (dnsWarning) response.warning = dnsWarning;
res.json(response);
if (dnsWarning) data.warning = dnsWarning;
ok(res, data);
}, 'site-external'));
return router;