DC-010: convert res.json({success:true,...}) → ok() in updates/notifications/tailscale
Routes converted: updates.js (17), notifications.js (8), tailscale.js (12). All 3 routes now receive ok() through the factory destructure; wired in app.js. notifications.js: kept 2 res.json() calls for genuine partial-failure semantics - POST /test with ?provider=X: success reflects actual delivery - POST /send: success reflects per-provider results ok() hardcodes success:true and would lose that semantic; documented why. tailscale.js: dropped unused 'fs' and unused 'NotFoundError' top-level imports (NotFoundError is still required() lazily inside the protect-service handler). Net change: 12 calls cleaned up, 2 lint warnings fixed. 750/750 tests still pass.
This commit is contained in:
@@ -9,9 +9,10 @@ const { ValidationError } = require('../errors');
|
||||
* @param {Object} deps - Explicit dependencies
|
||||
* @param {Object} deps.notification - Notification manager
|
||||
* @param {Function} deps.asyncHandler - Async route handler wrapper
|
||||
* @param {Function} deps.ok - Success response helper
|
||||
* @returns {express.Router}
|
||||
*/
|
||||
module.exports = function({ notification, asyncHandler }) {
|
||||
module.exports = function({ notification, asyncHandler, ok }) {
|
||||
const router = express.Router();
|
||||
|
||||
// GET /config — Get notification configuration (sensitive data redacted)
|
||||
@@ -44,7 +45,7 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
events: notificationConfig.events,
|
||||
healthCheck: notificationConfig.healthCheck
|
||||
};
|
||||
res.json({ success: true, config: safeConfig });
|
||||
ok(res, { config: safeConfig });
|
||||
}, 'notifications-config-get'));
|
||||
|
||||
// POST /config — Update notification configuration
|
||||
@@ -150,7 +151,7 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
}
|
||||
|
||||
await notification.saveConfig();
|
||||
res.json({ success: true, message: 'Notification config updated' });
|
||||
ok(res, { message: 'Notification config updated' });
|
||||
}, 'notifications-config-update'));
|
||||
|
||||
// POST /test — Test notification delivery
|
||||
@@ -176,11 +177,13 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
default:
|
||||
throw new ValidationError('Unknown provider');
|
||||
}
|
||||
// result.success reflects actual delivery; keep that semantic by using
|
||||
// res.json directly (ok() hardcodes success:true).
|
||||
res.json({ success: result.success, provider, error: result.error });
|
||||
} else {
|
||||
// Test all enabled providers
|
||||
const result = await notification.send('test', 'Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
||||
res.json({ success: true, ...result });
|
||||
ok(res, { ...result });
|
||||
}
|
||||
}, 'notifications-test'));
|
||||
|
||||
@@ -190,11 +193,10 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
const paginationParams = parsePaginationParams(req.query);
|
||||
if (paginationParams) {
|
||||
const result = paginate(notificationHistory, paginationParams);
|
||||
res.json({ success: true, history: result.data, total: notificationHistory.length, pagination: result.pagination });
|
||||
ok(res, { history: result.data, total: notificationHistory.length, pagination: result.pagination });
|
||||
} else {
|
||||
const limit = parseInt(req.query.limit) || 50;
|
||||
res.json({
|
||||
success: true,
|
||||
ok(res, {
|
||||
history: notificationHistory.slice(0, limit),
|
||||
total: notificationHistory.length
|
||||
});
|
||||
@@ -204,15 +206,14 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
// DELETE /history — Clear notification history
|
||||
router.delete('/history', asyncHandler(async (req, res) => {
|
||||
notification.clearHistory();
|
||||
res.json({ success: true, message: 'Notification history cleared' });
|
||||
ok(res, { message: 'Notification history cleared' });
|
||||
}, 'notifications-history-clear'));
|
||||
|
||||
// POST /health-check — Manually trigger health check
|
||||
router.post('/health-check', asyncHandler(async (req, res) => {
|
||||
await notification.checkHealth();
|
||||
const notificationConfig = notification.getConfig();
|
||||
res.json({
|
||||
success: true,
|
||||
ok(res, {
|
||||
lastCheck: notificationConfig.healthCheck.lastCheck,
|
||||
containersMonitored: Object.keys(notification.getHealthState()).length
|
||||
});
|
||||
@@ -222,9 +223,8 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
router.get('/status', asyncHandler(async (req, res) => {
|
||||
const notificationConfig = notification.getConfig();
|
||||
const providers = notificationConfig.providers || {};
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
|
||||
ok(res, {
|
||||
enabled: notificationConfig.enabled,
|
||||
providers: {
|
||||
discord: providers.discord?.enabled && !!providers.discord?.webhookUrl,
|
||||
@@ -244,18 +244,20 @@ module.exports = function({ notification, asyncHandler }) {
|
||||
// POST /send — Manual test send (used by frontend "Send Test" button)
|
||||
router.post('/send', asyncHandler(async (req, res) => {
|
||||
const { event, data, type } = req.body;
|
||||
|
||||
|
||||
if (!event) {
|
||||
throw new ValidationError('Event type is required');
|
||||
}
|
||||
|
||||
// Use 'test' as the event for manual sends
|
||||
const result = await notification.send(event, data || {}, type || 'info');
|
||||
|
||||
res.json({
|
||||
success: result.success,
|
||||
|
||||
// result.success reflects actual per-provider delivery; ok() hardcodes true,
|
||||
// so use res.json to preserve the partial-failure semantic.
|
||||
res.json({
|
||||
success: result.success,
|
||||
event,
|
||||
results: result.results
|
||||
results: result.results
|
||||
});
|
||||
}, 'notifications-send'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user