From 6b5fd8d17ffb928cdc4c32f3b0c5151aa1863dd0 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 15 Jan 2026 18:21:36 +0000 Subject: [PATCH] update, pause --- .../v1/MonitorDetailsControlHeader/index.jsx | 10 +++---- client/src/Hooks/monitorHooks.js | 2 +- client/src/Pages/Uptime/Create/index.jsx | 4 +-- client/src/Validation/validation.js | 2 +- .../checks/MongoChecksRepistory.ts | 7 +---- .../monitors/IMonitorsRepository.ts | 5 +++- .../monitors/MongoMonitorsRepository.ts | 29 ++++++++++++++++++- server/src/service/business/monitorService.ts | 17 ++++++----- .../service/infrastructure/statusService.js | 4 +-- 9 files changed, 53 insertions(+), 27 deletions(-) diff --git a/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx b/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx index bb4399b85..a86565f49 100644 --- a/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx +++ b/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx @@ -66,7 +66,7 @@ const MonitorDetailsControlHeader = ({ gap={theme.spacing(2)} > @@ -78,7 +78,7 @@ const MonitorDetailsControlHeader = ({ startIcon={} disabled={isTestNotificationsDisabled} onClick={() => { - testAllNotifications({ monitorId: monitor?._id }); + testAllNotifications({ monitorId: monitor?.id }); }} sx={{ whiteSpace: "nowrap", @@ -92,7 +92,7 @@ const MonitorDetailsControlHeader = ({ variant="contained" color="secondary" onClick={(e) => { - navigate(`/incidents/${monitor?._id}`); + navigate(`/incidents/${monitor?.id}`); }} > {t("menu.incidents")} @@ -107,7 +107,7 @@ const MonitorDetailsControlHeader = ({ } onClick={() => { pauseMonitor({ - monitorId: monitor?._id, + monitorId: monitor?.id, triggerUpdate, }); }} @@ -120,7 +120,7 @@ const MonitorDetailsControlHeader = ({ variant="contained" color="secondary" startIcon={} - onClick={() => navigate(`/${path}/configure/${monitor._id}`)} + onClick={() => navigate(`/${path}/configure/${monitor.id}`)} > Configure diff --git a/client/src/Hooks/monitorHooks.js b/client/src/Hooks/monitorHooks.js index 92844ad16..d865ffab8 100644 --- a/client/src/Hooks/monitorHooks.js +++ b/client/src/Hooks/monitorHooks.js @@ -387,7 +387,7 @@ export const useUpdateMonitor = () => { }), }; await networkService.updateMonitor({ - monitorId: monitor._id, + monitorId: monitor.id, updatedFields, }); diff --git a/client/src/Pages/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx index c3421e875..c54af3d07 100644 --- a/client/src/Pages/Uptime/Create/index.jsx +++ b/client/src/Pages/Uptime/Create/index.jsx @@ -194,7 +194,7 @@ const UptimeCreate = ({ isClone = false }) => { }; } else { form = { - _id: monitor._id, + id: monitor.id, url: monitor.url, name: monitor.name || monitor.url.substring(0, 50), statusWindowSize: monitor.statusWindowSize, @@ -287,7 +287,7 @@ const UptimeCreate = ({ isClone = false }) => { const handleRemove = async (event) => { event.preventDefault(); - const TEMP_MONITOR = { id: monitor._id }; + const TEMP_MONITOR = { id: monitor.id }; await deleteMonitor({ monitor: TEMP_MONITOR, redirect: "/uptime" }); }; diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 112bbb349..9a84e2e39 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -112,7 +112,7 @@ const loginCredentials = joi.object({ }); const monitorValidation = joi.object({ - _id: joi.string(), + id: joi.string(), userId: joi.string(), teamId: joi.string(), statusWindowSize: joi.number().min(1).max(20).default(5).messages({ diff --git a/server/src/repositories/checks/MongoChecksRepistory.ts b/server/src/repositories/checks/MongoChecksRepistory.ts index a6a049840..b5489309d 100644 --- a/server/src/repositories/checks/MongoChecksRepistory.ts +++ b/server/src/repositories/checks/MongoChecksRepistory.ts @@ -184,18 +184,13 @@ class MongoChecksRepository implements IChecksRepository { } const mongoIds = monitorIds.map((id) => new mongoose.Types.ObjectId(id)); const limitPerMonitor = options?.limitPerMonitor ?? 25; - const maxIntervalMs = Number(10 * 60 * 1000); - const bufferMs = Number(maxIntervalMs); - const lookbackMs = limitPerMonitor * maxIntervalMs + bufferMs; - - const cutoffDate = new Date(Date.now() - lookbackMs); const checkGroups = await CheckModel.aggregate([ { $match: { "metadata.monitorId": { $in: mongoIds }, - createdAt: { $gte: cutoffDate }, }, }, + { $sort: { "metadata.monitorId": 1, createdAt: -1 } }, { $group: { _id: "$metadata.monitorId", diff --git a/server/src/repositories/monitors/IMonitorsRepository.ts b/server/src/repositories/monitors/IMonitorsRepository.ts index 50fc79b2b..1007842e7 100644 --- a/server/src/repositories/monitors/IMonitorsRepository.ts +++ b/server/src/repositories/monitors/IMonitorsRepository.ts @@ -24,8 +24,10 @@ export interface IMonitorsRepository { // collection fetch findAll(): Promise; findByTeamId(teamId: string, config: TeamQueryConfig): Promise; + // update - update(monitorId: string, updates: Partial): Promise; + updateById(monitorId: string, updates: Partial): Promise; + togglePauseById(monitorId: string, teamId: string): Promise; // delete deleteByTeamId(teamId: string): Promise<{ monitors: Monitor[]; deletedCount: number }>; @@ -34,4 +36,5 @@ export interface IMonitorsRepository { // other findMonitorsSummaryByTeamId(teamId: string, config?: SummaryConfig): Promise; + findGroupsByTeamId(teamId: string): Promise; } diff --git a/server/src/repositories/monitors/MongoMonitorsRepository.ts b/server/src/repositories/monitors/MongoMonitorsRepository.ts index a7b933851..5e579c703 100644 --- a/server/src/repositories/monitors/MongoMonitorsRepository.ts +++ b/server/src/repositories/monitors/MongoMonitorsRepository.ts @@ -96,7 +96,7 @@ class MongoMonitorsRepository implements IMonitorsRepository { return count; }; - update = async (monitorId: string, patch: Partial) => { + updateById = async (monitorId: string, patch: Partial) => { const updatedMonitor = await MonitorModel.findOneAndUpdate( { _id: monitorId }, { @@ -112,6 +112,25 @@ class MongoMonitorsRepository implements IMonitorsRepository { return this.toEntity(updatedMonitor); }; + togglePauseById = async (monitorId: string, teamId: string) => { + const monitor = await MonitorModel.findOneAndUpdate( + { _id: monitorId, teamId }, + [ + { + $set: { + isActive: { $not: "$isActive" }, + status: "$$REMOVE", + }, + }, + ], + { new: true } + ); + if (!monitor) { + throw new AppError({ message: `Monitor with ID ${monitorId} not found for the given team.`, status: 404 }); + } + return this.toEntity(monitor); + }; + deleteByTeamId = async (teamId: string) => { const monitors = await MonitorModel.find({ teamId }); const { deletedCount } = await MonitorModel.deleteMany({ teamId }); @@ -157,6 +176,14 @@ class MongoMonitorsRepository implements IMonitorsRepository { return summary ?? { totalMonitors: 0, upMonitors: 0, downMonitors: 0, pausedMonitors: 0 }; }; + findGroupsByTeamId = async (teamId: string): Promise => { + const groups = await MonitorModel.distinct("group", { + teamId: new mongoose.Types.ObjectId(teamId), + group: { $nin: [null, ""] }, + }); + return groups.sort(); + }; + private mapDocuments = (documents: MonitorDocument[]): Monitor[] => { if (!documents?.length) { return []; diff --git a/server/src/service/business/monitorService.ts b/server/src/service/business/monitorService.ts index 0a767779e..cb439f1cc 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/service/business/monitorService.ts @@ -48,10 +48,10 @@ export interface IMonitorService { explain?: boolean; }): Promise<{ summary: any; count: number; monitors: any[] }>; getAllGames(): any; - getGroupsByTeamId(args: { teamId: string }): Promise; + getGroupsByTeamId(args: { teamId: string }): Promise; // update - editMonitor(args: { teamId: string; monitorId: string; body: any }): Promise; + editMonitor(args: { teamId: string; monitorId: string; body: Monitor }): Promise; pauseMonitor(args: { teamId: string; monitorId: string }): Promise; // delete @@ -423,21 +423,22 @@ export class MonitorService implements IMonitorService { return this.games; }; - getGroupsByTeamId = async ({ teamId }: { teamId: string }): Promise => { - const groups = await this.db.monitorModule.getGroupsByTeamId({ teamId }); + getGroupsByTeamId = async ({ teamId }: { teamId: string }): Promise => { + const groups = await this.monitorsRepository.findGroupsByTeamId(teamId); return groups; }; - editMonitor = async ({ teamId, monitorId, body }: { teamId: string; monitorId: string; body: any }): Promise => { + editMonitor = async ({ teamId, monitorId, body }: { teamId: string; monitorId: string; body: Monitor }) => { await this.verifyTeamAccess({ teamId, monitorId }); - const editedMonitor = await this.db.monitorModule.editMonitor({ monitorId, body }); + const editedMonitor = await this.monitorsRepository.updateById(monitorId, body); await this.jobQueue.updateJob(editedMonitor); + return editedMonitor; }; pauseMonitor = async ({ teamId, monitorId }: { teamId: string; monitorId: string }): Promise => { await this.verifyTeamAccess({ teamId, monitorId }); - const monitor = await this.db.monitorModule.pauseMonitor({ monitorId }); - monitor.isActive === true ? await this.jobQueue.resumeJob(monitor._id, monitor) : await this.jobQueue.pauseJob(monitor); + const monitor = await this.monitorsRepository.togglePauseById(monitorId, teamId); + monitor.isActive === true ? await this.jobQueue.resumeJob(monitor) : await this.jobQueue.pauseJob(monitor); return monitor; }; diff --git a/server/src/service/infrastructure/statusService.js b/server/src/service/infrastructure/statusService.js index 105f89c44..cfbf1b339 100755 --- a/server/src/service/infrastructure/statusService.js +++ b/server/src/service/infrastructure/statusService.js @@ -195,7 +195,7 @@ class StatusService { // Return early if not enough data points if (monitor.statusWindow.length < monitor.statusWindowSize) { - const updated = await this.monitorsRepository.update(monitor.id, monitor); + const updated = await this.monitorsRepository.updateById(monitor.id, monitor); return { monitor: updated, statusChanged: false, @@ -285,7 +285,7 @@ class StatusService { } monitor.status = newStatus; - const updated = await this.monitorsRepository.update(monitor.id, monitor); + const updated = await this.monitorsRepository.updateById(monitor.id, monitor); return { monitor: updated,