diff --git a/server/src/controllers/MonitorController.ts b/server/src/controllers/MonitorController.ts index 73f14a722..3728fc509 100644 --- a/server/src/controllers/MonitorController.ts +++ b/server/src/controllers/MonitorController.ts @@ -1,6 +1,5 @@ import { Request, Response, NextFunction } from "express"; import ApiError from "@/utils/ApiError.js"; -import { MonitorType } from "@/db/models/monitors/Monitor.js"; import { MonitorService, CheckService, @@ -11,7 +10,7 @@ export interface IMonitorController { create(req: Request, res: Response, next: NextFunction): Promise; getAll(req: Request, res: Response, next: NextFunction): Promise; getChecks(req: Request, res: Response, next: NextFunction): Promise; - toggleActive(req: Request, res: Response, next: NextFunction): Promise; + togglePause(req: Request, res: Response, next: NextFunction): Promise; get(req: Request, res: Response, next: NextFunction): Promise; update(req: Request, res: Response, next: NextFunction): Promise; delete(req: Request, res: Response, next: NextFunction): Promise; @@ -140,7 +139,7 @@ class MonitorController { } }; - toggleActive = async (req: Request, res: Response, next: NextFunction) => { + togglePause = async (req: Request, res: Response, next: NextFunction) => { try { const userContext = req.user; if (!userContext) { @@ -156,13 +155,13 @@ class MonitorController { throw new ApiError("Monitor ID is required", 400); } - const monitor = await this.monitorService.toggleActive( + const monitor = await this.monitorService.togglePause( userContext.sub, teamId, monitorId ); - const paused = monitor.isActive ? "resumed" : "paused"; + const paused = monitor.status === "paused" ? "paused" : "resumed"; res.status(200).json({ message: `Monitor ${paused} successfully`, diff --git a/server/src/db/models/monitors/Monitor.ts b/server/src/db/models/monitors/Monitor.ts index 35a3e4cff..119fcbfca 100644 --- a/server/src/db/models/monitors/Monitor.ts +++ b/server/src/db/models/monitors/Monitor.ts @@ -26,7 +26,6 @@ export interface IMonitor extends Document { secret?: string; type: MonitorType; interval: number; // in ms - isActive: boolean; status: MonitorStatus; n: number; // Number of consecutive successes required to change status lastCheckedAt?: Date; @@ -55,7 +54,6 @@ const MonitorSchema = new Schema( enum: MonitorTypes, }, interval: { type: Number, required: true, default: 60000 }, - isActive: { type: Boolean, required: true, default: true }, status: { type: String, required: true, @@ -123,11 +121,9 @@ MonitorSchema.pre( } ); -MonitorSchema.index({ isActive: 1 }); MonitorSchema.index({ status: 1 }); MonitorSchema.index({ type: 1 }); MonitorSchema.index({ lastCheckedAt: 1 }); -MonitorSchema.index({ isActive: 1, status: 1 }); MonitorSchema.index({ createdBy: 1 }); MonitorSchema.index({ updatedBy: 1 }); diff --git a/server/src/routes/monitors.ts b/server/src/routes/monitors.ts index aafe16bbb..ef94bee89 100644 --- a/server/src/routes/monitors.ts +++ b/server/src/routes/monitors.ts @@ -66,7 +66,7 @@ class MonitorRoutes { verifyToken, addUserContext, verifyTeamPermission([PERMISSIONS.monitors.write]), - this.controller.toggleActive + this.controller.togglePause ); this.router.get( diff --git a/server/src/services/business/MonitorService.ts b/server/src/services/business/MonitorService.ts index d93324ed4..0884a200c 100644 --- a/server/src/services/business/MonitorService.ts +++ b/server/src/services/business/MonitorService.ts @@ -36,7 +36,7 @@ export interface IMonitorService { range: string, status?: string ) => Promise; - toggleActive: ( + togglePause: ( userId: string, teamId: string, monitorId: string @@ -103,23 +103,7 @@ class MonitorService implements IMonitorService { } if (Array.isArray(status) && status.length > 0) { - const uniqueStatuses = Array.from(new Set(status)) as MonitorStatus[]; - const includesPaused = uniqueStatuses.includes("paused"); - const activeStatuses = uniqueStatuses.filter( - (currentStatus) => currentStatus !== "paused" - ); - - if (includesPaused && activeStatuses.length > 0) { - matchConditions.$or = [ - { status: { $in: activeStatuses }, isActive: true }, - { isActive: false }, - ]; - } else if (includesPaused) { - matchConditions.isActive = false; - } else { - matchConditions.status = { $in: uniqueStatuses }; - matchConditions.isActive = true; - } + matchConditions.status = { $in: status }; } const countResult = await Monitor.aggregate([ @@ -133,7 +117,7 @@ class MonitorService implements IMonitorService { upCount: { $sum: { $cond: [{ $eq: ["$status", "up"] }, 1, 0] } }, downCount: { $sum: { $cond: [{ $eq: ["$status", "down"] }, 1, 0] } }, pausedCount: { - $sum: { $cond: [{ $eq: ["$isActive", false] }, 1, 0] }, + $sum: { $cond: [{ $eq: ["$status", "paused"] }, 1, 0] }, }, }, }, @@ -150,6 +134,7 @@ class MonitorService implements IMonitorService { const monitors = await Monitor.find(matchConditions) .lean() + .sort({ name: 1 }) .skip(skip) .limit(rowsPerPage); @@ -172,7 +157,7 @@ class MonitorService implements IMonitorService { latestChecks: { $push: "$$ROOT" }, }, }, - { $project: { latestChecks: { $slice: ["$latestChecks", 25] } } }, + { $project: { latestChecks: { $slice: [{ $ifNull: ["$latestChecks", []] }, 25] } } }, ]); const checksMap = new Map( @@ -351,13 +336,13 @@ class MonitorService implements IMonitorService { temperature: { $map: { input: { - $range: [0, { $size: { $arrayElemAt: ["$tempsArrays", 0] } }], + $range: [0, { $size: { $ifNull: [{ $arrayElemAt: ["$tempsArrays", 0] }, []] } }], }, as: "idx", in: { $avg: { $map: { - input: "$tempsArrays", + input: { $ifNull: ["$tempsArrays", []] }, as: "arr", in: { $arrayElemAt: ["$$arr", "$$idx"] }, }, @@ -377,7 +362,7 @@ class MonitorService implements IMonitorService { disk: { $map: { input: { - $range: [0, { $size: { $arrayElemAt: ["$disksArray", 0] } }], + $range: [0, { $size: { $ifNull: [{ $arrayElemAt: ["$disksArray", 0] }, []] } }], }, as: "idx", in: { @@ -385,7 +370,7 @@ class MonitorService implements IMonitorService { vars: { diskGroup: { $map: { - input: "$disksArray", + input: { $ifNull: ["$disksArray", []] }, as: "diskArr", in: { $arrayElemAt: ["$$diskArr", "$$idx"] }, }, @@ -421,7 +406,7 @@ class MonitorService implements IMonitorService { net: { $map: { input: { - $range: [0, { $size: { $arrayElemAt: ["$netsArray", 0] } }], + $range: [0, { $size: { $ifNull: [{ $arrayElemAt: ["$netsArray", 0] }, []] } }], }, as: "idx", in: { @@ -429,7 +414,7 @@ class MonitorService implements IMonitorService { vars: { netGroup: { $map: { - input: "$netsArray", + input: { $ifNull: ["$netsArray", []] }, as: "netArr", in: { $arrayElemAt: ["$$netArr", "$$idx"] }, }, @@ -540,15 +525,19 @@ class MonitorService implements IMonitorService { }; }; - async toggleActive(userId: string, teamId: string, id: string) { - const pendingStatus: MonitorStatus = "initializing"; + async togglePause(userId: string, teamId: string, id: string) { const updatedMonitor = await Monitor.findOneAndUpdate( { _id: id, teamId }, [ { $set: { - isActive: { $not: "$isActive" }, - status: pendingStatus, + status: { + $cond: { + if: { $eq: ["$status", "paused"] }, + then: "initializing", + else: "paused", + }, + }, updatedBy: userId, updatedAt: new Date(), }, @@ -563,7 +552,7 @@ class MonitorService implements IMonitorService { await this.jobQueue.updateJob(updatedMonitor); - if (updatedMonitor?.isActive) { + if (updatedMonitor?.status !== "paused") { await this.jobQueue.resumeJob(updatedMonitor); } else { await this.jobQueue.pauseJob(updatedMonitor); @@ -581,7 +570,6 @@ class MonitorService implements IMonitorService { "name", "secret", "interval", - "isActive", "n", "notificationChannels", ]; diff --git a/server/src/services/infrastructure/JobQueue.ts b/server/src/services/infrastructure/JobQueue.ts index 038c46081..fd36b8b77 100644 --- a/server/src/services/infrastructure/JobQueue.ts +++ b/server/src/services/infrastructure/JobQueue.ts @@ -111,7 +111,7 @@ export default class JobQueue implements IJobQueue { id: monitor._id.toString(), template: "monitor-job", repeat: monitor.interval, - active: monitor.isActive, + active: monitor.status !== "paused", data: monitor, }); } catch (error) {