refactor: add Joi validation, rename to updateNotifications, add default case

This commit is contained in:
ashu130698 committed 2026-03-05 23:06:41 +05:30
1 parent 8eca81c8be
commit 9c17fbe79c
4 files changed
+27 -23

No files matched your search

@@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { Notification } from "@/types/index.js";
import { createNotificationBodyValidation } from "@/validation/joi.js";
import { createNotificationBodyValidation, bulkEditNotificationBodyValidation } from "@/validation/joi.js";
import { AppError } from "@/utils/AppError.js";
import { IMonitorsRepository } from "@/repositories/index.js";
import { INotificationsService } from "@/service/index.js";
@@ -154,31 +154,18 @@ class NotificationController {
}
};
// Handler for bulk editing monitor notification associations
bulkEditMonitorNotifications = async (req: Request, res: Response, next: NextFunction) => {
try {
const teamId = requireTeamId(req.user?.teamId);
// Joi validates monitorIds, notificationIds, and action automatically
await bulkEditNotificationBodyValidation.validateAsync(req.body, {
abortEarly: false,
});
const teamId = requireTeamId(req.user?.teamId);
const { monitorIds, notificationIds, action } = req.body;
if (!monitorIds || !Array.isArray(monitorIds) || monitorIds.length === 0) {
throw new AppError({ message: "Monitor IDs are required", status: 400 });
}
if (!notificationIds || !Array.isArray(notificationIds)) {
throw new AppError({ message: "Notification IDs must be an array", status: 400 });
}
if (!action || !["add", "remove", "set"].includes(action)) {
throw new AppError({ message: "Action must be 'add', 'remove', or 'set'", status: 400 });
}
// "add" and "remove" need at least one notification ID
// "set" can be empty (to clear all notifications from monitors)
if (notificationIds.length === 0 && action !== "set") {
throw new AppError({ message: "Notification IDs are required for add/remove actions", status: 400 });
}
const modifiedCount = await this.monitorsRepository.bulkUpdateNotifications(monitorIds, notificationIds, action, teamId);
const modifiedCount = await this.monitorsRepository.updateNotifications(monitorIds, notificationIds, action, teamId);
return res.status(200).json({
success: true,
@@ -41,7 +41,7 @@ export interface IMonitorsRepository {
findMonitorsSummaryByTeamId(teamId: string, config?: SummaryConfig): Promise<MonitorsSummary>;
findGroupsByTeamId(teamId: string): Promise<string[]>;
removeNotificationFromMonitors(notificationId: string): Promise<void>;
bulkUpdateNotifications(monitorIds: string[], notificationIds: string[], action: "add" | "remove" | "set", teamId: string): Promise<number>;
updateNotifications(monitorIds: string[], notificationIds: string[], action: "add" | "remove" | "set", teamId: string): Promise<number>;
deleteByTeamIdsNotIn(teamIds: string[]): Promise<number>;
findAllMonitorIds(): Promise<string[]>;
}
@@ -298,7 +298,7 @@ class MongoMonitorsRepository implements IMonitorsRepository {
await MonitorModel.updateMany({ notifications: notificationId }, { $pull: { notifications: notificationId } });
};
bulkUpdateNotifications = async (
updateNotifications = async (
monitorIds: string[],
notificationIds: string[],
action: "add" | "remove" | "set",
@@ -323,6 +323,8 @@ class MongoMonitorsRepository implements IMonitorsRepository {
case "set":
update = { $set: { notifications: notificationIds } };
break;
default:
throw new AppError({ message: `Invalid action: ${action}`, status: 400 });
}
const result = await MonitorModel.updateMany(filter, update);
+15
View File
@@ -573,6 +573,20 @@ const triggerNotificationBodyValidation = joi.object({
}),
});
const bulkEditNotificationBodyValidation = joi.object({
monitorIds: joi.array().items(joi.string()).min(1).required().messages({
"array.min": "At least one monitor ID is required",
"any.required": "Monitor IDs are required",
}),
notificationIds: joi.array().items(joi.string()).required().messages({
"any.required": "Notification IDs are required",
}),
action: joi.string().valid("add", "remove", "set").required().messages({
"any.only": "Action must be 'add', 'remove', or 'set'",
"any.required": "Action is required",
}),
});
const createNotificationBodyValidation = joi.object({
notificationName: joi.string().required().messages({
"string.empty": "Notification name is required",
@@ -793,6 +807,7 @@ export {
imageValidation,
triggerNotificationBodyValidation,
createNotificationBodyValidation,
bulkEditNotificationBodyValidation,
webhookConfigValidation,
createAnnouncementValidation,
sendTestEmailBodyValidation,