Express/MongoDB backend with JWT auth, RBAC, S3 uploads, notifications, and scheduled jobs.
52 lines
1.4 KiB
JavaScript
52 lines
1.4 KiB
JavaScript
// /utils/senders/notificationRecorder.js
|
|
'use strict';
|
|
|
|
const Notification = require('../../components/notifications/notificationModel');
|
|
const logger = require('../logger');
|
|
|
|
/**
|
|
* Persist a notification row, attempt delivery, then mark sent/failed.
|
|
* Use this for every outbound sms / email / baleBot message.
|
|
*/
|
|
const recordAndSend = async ({
|
|
userId = null,
|
|
channel,
|
|
subject = '',
|
|
body,
|
|
relatedEvent = null,
|
|
sendFn
|
|
}) => {
|
|
const notification = await Notification.create({
|
|
user: userId || undefined,
|
|
channel,
|
|
subject: subject || undefined,
|
|
body: body || subject || 'Notification',
|
|
status: 'pending',
|
|
relatedEvent: relatedEvent || undefined
|
|
});
|
|
|
|
try {
|
|
const result = await sendFn();
|
|
const skipped = result && result.skipped === true;
|
|
notification.status = skipped ? 'failed' : 'sent';
|
|
if (skipped) {
|
|
notification.lastError = result.reason || 'Delivery skipped';
|
|
} else {
|
|
notification.sentAt = new Date();
|
|
}
|
|
await notification.save();
|
|
return { notification, result };
|
|
} catch (err) {
|
|
notification.status = 'failed';
|
|
notification.lastError = err.message;
|
|
notification.retryCount = (notification.retryCount || 0) + 1;
|
|
await notification.save();
|
|
logger.error(`[NotificationRecorder] ${channel} failed: ${err.message}`);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
recordAndSend
|
|
};
|