Add controller, db, and validation for notifications

This commit is contained in:
Alex Holliday
2025-06-09 10:30:21 +08:00
parent 0f10a39f91
commit 5a50e9b301
3 changed files with 128 additions and 1 deletions
+48 -1
View File
@@ -1,4 +1,7 @@
import { triggerNotificationBodyValidation } from "../validation/joi.js";
import {
triggerNotificationBodyValidation,
createNotificationBodyValidation,
} from "../validation/joi.js";
import { handleError, handleValidationError } from "./controllerUtils.js";
const SERVICE_NAME = "NotificationController";
@@ -169,6 +172,50 @@ class NotificationController {
next(handleError(error, SERVICE_NAME, "testWebhook"));
}
}
createNotification = async (req, res, next) => {
try {
await createNotificationBodyValidation.validateAsync(req.body, {
abortEarly: false,
});
} catch (error) {
next(handleValidationError(error, SERVICE_NAME));
return;
}
try {
const notification = await this.db.createNotification(req.body);
return res.success({
msg: "Notification created successfully",
data: notification,
});
} catch (error) {
next(handleError(error, SERVICE_NAME, "createNotification"));
}
};
getNotificationsByTeamId = async (req, res, next) => {
try {
const notifications = await this.db.getNotificationsByTeamId(req.params.teamId);
return res.success({
msg: "Notifications fetched successfully",
data: notifications,
});
} catch (error) {
next(handleError(error, SERVICE_NAME, "getNotificationsByTeamId"));
}
};
deleteNotification = async (req, res, next) => {
try {
await this.db.deleteNotificationById(req.params.id);
return res.success({
msg: "Notification deleted successfully",
});
} catch (error) {
next(handleError(error, SERVICE_NAME, "deleteNotification"));
}
};
}
export default NotificationController;
@@ -1,4 +1,5 @@
import Notification from "../../models/Notification.js";
import Monitor from "../../models/Monitor.js";
const SERVICE_NAME = "notificationModule";
/**
* Creates a new notification.
@@ -21,6 +22,28 @@ const createNotification = async (notificationData) => {
}
};
const getNotificationsByTeamId = async (teamId) => {
try {
const notifications = await Notification.find({ teamId });
return notifications;
} catch (error) {
error.service = SERVICE_NAME;
error.method = "getNotificationsByTeamId";
throw error;
}
};
const getNotificationsByIds = async (notificationIds) => {
try {
const notifications = await Notification.find({ _id: { $in: notificationIds } });
return notifications;
} catch (error) {
error.service = SERVICE_NAME;
error.method = "getNotificationsByIds";
throw error;
}
};
/**
* Retrieves notifications by monitor ID.
* @param {mongoose.Types.ObjectId} monitorId - The ID of the monitor.
@@ -49,8 +72,23 @@ const deleteNotificationsByMonitorId = async (monitorId) => {
}
};
const deleteNotificationById = async (id) => {
try {
const result = await Notification.findByIdAndDelete(id);
await Monitor.updateMany({ notifications: id }, { $pull: { notifications: id } });
return result;
} catch (error) {
error.service = SERVICE_NAME;
error.method = "deleteNotificationById";
throw error;
}
};
export {
createNotification,
getNotificationsByTeamId,
getNotificationsByIds,
getNotificationsByMonitorId,
deleteNotificationsByMonitorId,
deleteNotificationById,
};
+42
View File
@@ -566,6 +566,47 @@ const triggerNotificationBodyValidation = joi.object({
}),
});
const createNotificationBodyValidation = joi.object({
userId: joi.number().required().messages({
"number.empty": "User ID is required",
"any.required": "User ID is required",
}),
teamId: joi.number().required().messages({
"string.empty": "Team ID is required",
"any.required": "Team ID is required",
}),
notificationName: joi.string().required().messages({
"string.empty": "Notification name is required",
"any.required": "Notification name is required",
}),
address: joi.when("type", {
is: "email",
then: joi.string().email().required().messages({
"string.empty": "E-mail address cannot be empty",
"any.required": "E-mail address is required",
"string.email": "Please enter a valid e-mail address",
}),
}),
type: joi.string().valid("email", "webhook", "pager_duty").required().messages({
"string.empty": "Notification type is required",
"any.required": "Notification type is required",
"any.only": "Notification type must be email, webhook, or pager_duty",
}),
config: joi.when("type", {
is: "webhook",
then: joi.object({
webhookUrl: joi.string().uri().required().messages({
"string.uri": "Webhook URL must be a valid URI",
"any.required": "Webhook URL is required",
}),
platform: joi.string().required().messages({
"string.empty": "Platform is required",
"any.required": "Platform is required",
}),
}),
}),
});
//****************************************
// Announcetment Page Validation
//****************************************
@@ -653,6 +694,7 @@ export {
getStatusPageQueryValidation,
imageValidation,
triggerNotificationBodyValidation,
createNotificationBodyValidation,
webhookConfigValidation,
createAnnouncementValidation,
sendTestEmailBodyValidation,