refactor(routes): Phase 3.3 - standardize notifications.js (explicit deps)
This commit is contained in:
@@ -3,12 +3,19 @@ const { validateURL, validateToken } = require('../input-validator');
|
|||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../pagination');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../errors');
|
||||||
|
|
||||||
module.exports = function(ctx) {
|
/**
|
||||||
|
* Notifications route factory
|
||||||
|
* @param {Object} deps - Explicit dependencies
|
||||||
|
* @param {Object} deps.notification - Notification manager
|
||||||
|
* @param {Function} deps.asyncHandler - Async route handler wrapper
|
||||||
|
* @returns {express.Router}
|
||||||
|
*/
|
||||||
|
module.exports = function({ notification, asyncHandler }) {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// GET /config — Get notification configuration (sensitive data redacted)
|
// GET /config — Get notification configuration (sensitive data redacted)
|
||||||
router.get('/config', ctx.asyncHandler(async (req, res) => {
|
router.get('/config', asyncHandler(async (req, res) => {
|
||||||
const notificationConfig = ctx.notification.getConfig();
|
const notificationConfig = notification.getConfig();
|
||||||
// Return config without sensitive data
|
// Return config without sensitive data
|
||||||
const safeConfig = {
|
const safeConfig = {
|
||||||
enabled: notificationConfig.enabled,
|
enabled: notificationConfig.enabled,
|
||||||
@@ -34,9 +41,9 @@ module.exports = function(ctx) {
|
|||||||
}, 'notifications-config-get'));
|
}, 'notifications-config-get'));
|
||||||
|
|
||||||
// POST /config — Update notification configuration
|
// POST /config — Update notification configuration
|
||||||
router.post('/config', ctx.asyncHandler(async (req, res) => {
|
router.post('/config', asyncHandler(async (req, res) => {
|
||||||
const { enabled, providers, events, healthCheck } = req.body;
|
const { enabled, providers, events, healthCheck } = req.body;
|
||||||
const notificationConfig = ctx.notification.getConfig();
|
const notificationConfig = notification.getConfig();
|
||||||
|
|
||||||
// Validate provider webhook URLs and tokens
|
// Validate provider webhook URLs and tokens
|
||||||
if (providers) {
|
if (providers) {
|
||||||
@@ -109,19 +116,19 @@ module.exports = function(ctx) {
|
|||||||
// Restart daemon if settings changed
|
// Restart daemon if settings changed
|
||||||
if (healthCheck.enabled !== wasEnabled || healthCheck.intervalMinutes) {
|
if (healthCheck.enabled !== wasEnabled || healthCheck.intervalMinutes) {
|
||||||
if (notificationConfig.healthCheck.enabled) {
|
if (notificationConfig.healthCheck.enabled) {
|
||||||
ctx.notification.startHealthDaemon();
|
notification.startHealthDaemon();
|
||||||
} else {
|
} else {
|
||||||
ctx.notification.stopHealthDaemon();
|
notification.stopHealthDaemon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.notification.saveConfig();
|
await notification.saveConfig();
|
||||||
res.json({ success: true, message: 'Notification config updated' });
|
res.json({ success: true, message: 'Notification config updated' });
|
||||||
}, 'notifications-config-update'));
|
}, 'notifications-config-update'));
|
||||||
|
|
||||||
// POST /test — Test notification delivery
|
// POST /test — Test notification delivery
|
||||||
router.post('/test', ctx.asyncHandler(async (req, res) => {
|
router.post('/test', asyncHandler(async (req, res) => {
|
||||||
const { provider } = req.body;
|
const { provider } = req.body;
|
||||||
|
|
||||||
if (provider) {
|
if (provider) {
|
||||||
@@ -129,13 +136,13 @@ module.exports = function(ctx) {
|
|||||||
let result;
|
let result;
|
||||||
switch (provider) {
|
switch (provider) {
|
||||||
case 'discord':
|
case 'discord':
|
||||||
result = await ctx.notification.sendDiscord('Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
result = await notification.sendDiscord('Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
||||||
break;
|
break;
|
||||||
case 'telegram':
|
case 'telegram':
|
||||||
result = await ctx.notification.sendTelegram('Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
result = await notification.sendTelegram('Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
||||||
break;
|
break;
|
||||||
case 'ntfy':
|
case 'ntfy':
|
||||||
result = await ctx.notification.sendNtfy('Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
result = await notification.sendNtfy('Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ValidationError('Unknown provider');
|
throw new ValidationError('Unknown provider');
|
||||||
@@ -143,14 +150,14 @@ module.exports = function(ctx) {
|
|||||||
res.json({ success: result.success, provider, error: result.error });
|
res.json({ success: result.success, provider, error: result.error });
|
||||||
} else {
|
} else {
|
||||||
// Test all enabled providers
|
// Test all enabled providers
|
||||||
const result = await ctx.notification.send('test', 'Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
const result = await notification.send('test', 'Test Notification', 'This is a test notification from DashCaddy.', 'info');
|
||||||
res.json({ success: true, ...result });
|
res.json({ success: true, ...result });
|
||||||
}
|
}
|
||||||
}, 'notifications-test'));
|
}, 'notifications-test'));
|
||||||
|
|
||||||
// GET /history — Get notification history
|
// GET /history — Get notification history
|
||||||
router.get('/history', ctx.asyncHandler(async (req, res) => {
|
router.get('/history', asyncHandler(async (req, res) => {
|
||||||
const notificationHistory = ctx.notification.getHistory();
|
const notificationHistory = notification.getHistory();
|
||||||
const paginationParams = parsePaginationParams(req.query);
|
const paginationParams = parsePaginationParams(req.query);
|
||||||
if (paginationParams) {
|
if (paginationParams) {
|
||||||
const result = paginate(notificationHistory, paginationParams);
|
const result = paginate(notificationHistory, paginationParams);
|
||||||
@@ -166,19 +173,19 @@ module.exports = function(ctx) {
|
|||||||
}, 'notifications-history'));
|
}, 'notifications-history'));
|
||||||
|
|
||||||
// DELETE /history — Clear notification history
|
// DELETE /history — Clear notification history
|
||||||
router.delete('/history', ctx.asyncHandler(async (req, res) => {
|
router.delete('/history', asyncHandler(async (req, res) => {
|
||||||
ctx.notification.clearHistory();
|
notification.clearHistory();
|
||||||
res.json({ success: true, message: 'Notification history cleared' });
|
res.json({ success: true, message: 'Notification history cleared' });
|
||||||
}, 'notifications-history-clear'));
|
}, 'notifications-history-clear'));
|
||||||
|
|
||||||
// POST /health-check — Manually trigger health check
|
// POST /health-check — Manually trigger health check
|
||||||
router.post('/health-check', ctx.asyncHandler(async (req, res) => {
|
router.post('/health-check', asyncHandler(async (req, res) => {
|
||||||
await ctx.notification.checkHealth();
|
await notification.checkHealth();
|
||||||
const notificationConfig = ctx.notification.getConfig();
|
const notificationConfig = notification.getConfig();
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
lastCheck: notificationConfig.healthCheck.lastCheck,
|
lastCheck: notificationConfig.healthCheck.lastCheck,
|
||||||
containersMonitored: Object.keys(ctx.notification.getHealthState()).length
|
containersMonitored: Object.keys(notification.getHealthState()).length
|
||||||
});
|
});
|
||||||
}, 'notifications-health-check'));
|
}, 'notifications-health-check'));
|
||||||
|
|
||||||
|
|||||||
@@ -303,7 +303,10 @@ async function createApp() {
|
|||||||
fetchT: ctx.fetchT,
|
fetchT: ctx.fetchT,
|
||||||
credentialManager: ctx.credentialManager
|
credentialManager: ctx.credentialManager
|
||||||
}));
|
}));
|
||||||
apiRouter.use('/notifications', notificationRoutes(ctx));
|
apiRouter.use('/notifications', notificationRoutes({
|
||||||
|
notification: ctx.notification,
|
||||||
|
asyncHandler: ctx.asyncHandler
|
||||||
|
}));
|
||||||
apiRouter.use('/containers', containerRoutes({
|
apiRouter.use('/containers', containerRoutes({
|
||||||
docker: ctx.docker,
|
docker: ctx.docker,
|
||||||
log: ctx.log,
|
log: ctx.log,
|
||||||
|
|||||||
Reference in New Issue
Block a user