Initial commit: teaching institution management API.
Express/MongoDB backend with JWT auth, RBAC, S3 uploads, notifications, and scheduled jobs.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
// /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
|
||||
};
|
||||
Reference in New Issue
Block a user