From a9ce980d032cc918a2033728dfb5df49ddba1250 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 9 Jan 2026 14:49:44 -0800 Subject: [PATCH] monitor controller -> ts --- server/src/config/controllers.js | 7 +- .../src/controllers/v1/monitorController.js | 493 ----------------- .../src/controllers/v1/monitorController.ts | 505 ++++++++++++++++++ server/src/service/infrastructure/notes | 83 --- .../v1/infrastructure/bufferService.js | 5 +- server/src/types/express.d.ts | 1 + server/src/utils/AppError.ts | 24 + 7 files changed, 535 insertions(+), 583 deletions(-) delete mode 100644 server/src/controllers/v1/monitorController.js create mode 100644 server/src/controllers/v1/monitorController.ts delete mode 100644 server/src/service/infrastructure/notes create mode 100644 server/src/utils/AppError.ts diff --git a/server/src/config/controllers.js b/server/src/config/controllers.js index 5493a141b..4589ddd85 100644 --- a/server/src/config/controllers.js +++ b/server/src/config/controllers.js @@ -28,12 +28,7 @@ export const initializeControllers = (services) => { userService: services.userService, }); - controllers.monitorController = new MonitorController(commonDependencies, { - settingsService: services.settingsService, - jobQueue: services.jobQueue, - emailService: services.emailService, - monitorService: services.monitorService, - }); + controllers.monitorController = new MonitorController(services.monitorService); controllers.settingsController = new SettingsController(commonDependencies, { settingsService: services.settingsService, diff --git a/server/src/controllers/v1/monitorController.js b/server/src/controllers/v1/monitorController.js deleted file mode 100644 index 85cfea3d1..000000000 --- a/server/src/controllers/v1/monitorController.js +++ /dev/null @@ -1,493 +0,0 @@ -import { - getMonitorByIdParamValidation, - getMonitorByIdQueryValidation, - getMonitorsByTeamIdParamValidation, - getMonitorsByTeamIdQueryValidation, - createMonitorBodyValidation, - editMonitorBodyValidation, - pauseMonitorParamValidation, - getMonitorStatsByIdParamValidation, - getMonitorStatsByIdQueryValidation, - getCertificateParamValidation, - getHardwareDetailsByIdParamValidation, - getHardwareDetailsByIdQueryValidation, -} from "../../validation/joi.js"; -import sslChecker from "ssl-checker"; -import { fetchMonitorCertificate } from "./controllerUtils.js"; -import BaseController from "./baseController.js"; - -const SERVICE_NAME = "monitorController"; -class MonitorController extends BaseController { - static SERVICE_NAME = SERVICE_NAME; - constructor(commonDependencies, { settingsService, jobQueue, emailService, monitorService }) { - super(commonDependencies); - this.settingsService = settingsService; - this.jobQueue = jobQueue; - this.emailService = emailService; - this.monitorService = monitorService; - } - - get serviceName() { - return MonitorController.SERVICE_NAME; - } - - async verifyTeamAccess(teamId, monitorId) { - const monitor = await this.db.monitorModule.getMonitorById(monitorId); - if (!monitor.teamId.equals(teamId)) { - throw this.errorService.createAuthorizationError(); - } - } - - getAllMonitors = this.asyncHandler( - async (req, res) => { - const monitors = await this.monitorService.getAllMonitors(); - return res.success({ - msg: this.stringService.monitorGetAll, - data: monitors, - }); - }, - SERVICE_NAME, - "getAllMonitors" - ); - - getUptimeDetailsById = this.asyncHandler( - async (req, res) => { - const monitorId = req?.params?.monitorId; - const dateRange = req?.query?.dateRange; - const normalize = req?.query?.normalize; - - const teamId = req?.user?.teamId; - - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const data = await this.monitorService.getUptimeDetailsById({ - teamId, - monitorId, - dateRange, - normalize, - }); - return res.success({ - msg: this.stringService.monitorGetByIdSuccess, - data: data, - }); - }, - SERVICE_NAME, - "getUptimeDetailsById" - ); - - getMonitorStatsById = this.asyncHandler( - async (req, res) => { - await getMonitorStatsByIdParamValidation.validateAsync(req.params); - await getMonitorStatsByIdQueryValidation.validateAsync(req.query); - - let { limit, sortOrder, dateRange, numToDisplay, normalize } = req.query; - const monitorId = req?.params?.monitorId; - - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const monitorStats = await this.monitorService.getMonitorStatsById({ - teamId, - monitorId, - limit, - sortOrder, - dateRange, - numToDisplay, - normalize, - }); - - return res.success({ - msg: this.stringService.monitorStatsById, - data: monitorStats, - }); - }, - SERVICE_NAME, - "getMonitorStatsById" - ); - - /** - * Get hardware details for a specific monitor by ID - * @async - * @param {Express.Request} req - Express request object containing monitorId in params - * @param {Express.Response} res - Express response object - * @param {Express.NextFunction} next - Express next middleware function - * @returns {Promise} - * @throws {Error} - Throws error if monitor not found or other database errors - */ - getHardwareDetailsById = this.asyncHandler( - async (req, res) => { - await getHardwareDetailsByIdParamValidation.validateAsync(req.params); - await getHardwareDetailsByIdQueryValidation.validateAsync(req.query); - - const monitorId = req?.params?.monitorId; - const dateRange = req?.query?.dateRange; - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const monitor = await this.monitorService.getHardwareDetailsById({ - teamId, - monitorId, - dateRange, - }); - - return res.success({ - msg: this.stringService.monitorGetByIdSuccess, - data: monitor, - }); - }, - SERVICE_NAME, - "getHardwareDetailsById" - ); - - getMonitorCertificate = this.asyncHandler( - async (req, res) => { - await getCertificateParamValidation.validateAsync(req.params); - - const { monitorId } = req.params; - const monitor = await this.db.monitorModule.getMonitorById(monitorId); - const certificate = await fetchMonitorCertificate(sslChecker, monitor); - - return res.success({ - msg: this.stringService.monitorCertificate, - data: { - certificateDate: new Date(certificate.validTo), - }, - }); - }, - SERVICE_NAME, - "getMonitorCertificate" - ); - - getMonitorById = this.asyncHandler( - async (req, res) => { - await getMonitorByIdParamValidation.validateAsync(req.params); - await getMonitorByIdQueryValidation.validateAsync(req.query); - - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const monitor = await this.monitorService.getMonitorById({ teamId, monitorId: req?.params?.monitorId }); - - return res.success({ - msg: this.stringService.monitorGetByIdSuccess, - data: monitor, - }); - }, - SERVICE_NAME, - "getMonitorById" - ); - - createMonitor = this.asyncHandler( - async (req, res) => { - await createMonitorBodyValidation.validateAsync(req.body); - - const userId = req?.user?._id; - const teamId = req?.user?.teamId; - - const monitor = await this.monitorService.createMonitor({ teamId, userId, body: req.body }); - - return res.success({ - msg: this.stringService.monitorCreate, - data: monitor, - }); - }, - SERVICE_NAME, - "createMonitor" - ); - - createBulkMonitors = this.asyncHandler( - async (req, res) => { - if (!req.file) { - throw this.errorService.createBadRequestError("No file uploaded"); - } - - if (!req.file.mimetype.includes("csv")) { - throw this.errorService.createBadRequestError("File is not a CSV"); - } - - if (req.file.size === 0) { - throw this.errorService.createBadRequestError("File is empty"); - } - - const userId = req?.user?._id; - const teamId = req?.user?.teamId; - - if (!userId || !teamId) { - throw this.errorService.createBadRequestError("Missing userId or teamId"); - } - - const fileData = req?.file?.buffer?.toString("utf-8"); - if (!fileData) { - throw this.errorService.createBadRequestError("Cannot get file from buffer"); - } - - const monitors = await this.monitorService.createBulkMonitors({ fileData, userId, teamId }); - - return res.success({ - msg: this.stringService.bulkMonitorsCreate, - data: monitors, - }); - }, - SERVICE_NAME, - "createBulkMonitors" - ); - - deleteMonitor = this.asyncHandler( - async (req, res) => { - await getMonitorByIdParamValidation.validateAsync(req.params); - const monitorId = req.params.monitorId; - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const deletedMonitor = await this.monitorService.deleteMonitor({ teamId, monitorId }); - - return res.success({ msg: this.stringService.monitorDelete, data: deletedMonitor }); - }, - SERVICE_NAME, - "deleteMonitor" - ); - - deleteAllMonitors = this.asyncHandler( - async (req, res) => { - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const deletedCount = await this.monitorService.deleteAllMonitors({ teamId }); - - return res.success({ msg: `Deleted ${deletedCount} monitors` }); - }, - SERVICE_NAME, - "deleteAllMonitors" - ); - - editMonitor = this.asyncHandler( - async (req, res) => { - await getMonitorByIdParamValidation.validateAsync(req.params); - await editMonitorBodyValidation.validateAsync(req.body); - const monitorId = req?.params?.monitorId; - - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const editedMonitor = await this.monitorService.editMonitor({ teamId, monitorId, body: req.body }); - - return res.success({ - msg: this.stringService.monitorEdit, - data: editedMonitor, - }); - }, - SERVICE_NAME, - "editMonitor" - ); - - pauseMonitor = this.asyncHandler( - async (req, res) => { - await pauseMonitorParamValidation.validateAsync(req.params); - - const monitorId = req.params.monitorId; - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const monitor = await this.monitorService.pauseMonitor({ teamId, monitorId }); - - return res.success({ - msg: monitor.isActive ? this.stringService.monitorResume : this.stringService.monitorPause, - data: monitor, - }); - }, - SERVICE_NAME, - "pauseMonitor" - ); - - addDemoMonitors = this.asyncHandler( - async (req, res) => { - const { _id, teamId } = req.user; - const demoMonitors = await this.monitorService.addDemoMonitors({ userId: _id, teamId }); - - return res.success({ - msg: this.stringService.monitorDemoAdded, - data: demoMonitors?.length ?? 0, - }); - }, - SERVICE_NAME, - "addDemoMonitors" - ); - - sendTestEmail = this.asyncHandler( - async (req, res) => { - const { to } = req.body; - if (!to || typeof to !== "string") { - throw this.errorService.createBadRequestError(this.stringService.errorForValidEmailAddress); - } - - const messageId = await this.monitorService.sendTestEmail({ to }); - return res.success({ - msg: this.stringService.sendTestEmail, - data: { messageId }, - }); - }, - SERVICE_NAME, - "sendTestEmail" - ); - - getMonitorsByTeamId = this.asyncHandler( - async (req, res) => { - await getMonitorsByTeamIdParamValidation.validateAsync(req.params); - await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); - - let { limit, type, page, rowsPerPage, filter, field, order } = req.query; - const teamId = req?.user?.teamId; - - const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, limit, type, page, rowsPerPage, filter, field, order }); - - return res.success({ - msg: this.stringService.monitorGetByTeamId, - data: monitors, - }); - }, - SERVICE_NAME, - "getMonitorsByTeamId" - ); - - getMonitorsAndSummaryByTeamId = this.asyncHandler( - async (req, res) => { - await getMonitorsByTeamIdParamValidation.validateAsync(req.params); - await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); - - const explain = req?.query?.explain; - const type = req?.query?.type; - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const result = await this.monitorService.getMonitorsAndSummaryByTeamId({ teamId, type, explain }); - - return res.success({ - msg: this.stringService.monitorSummaryByTeamId, - data: result, - }); - }, - SERVICE_NAME, - "getMonitorsAndSummaryByTeamId" - ); - - getMonitorsWithChecksByTeamId = this.asyncHandler( - async (req, res) => { - await getMonitorsByTeamIdParamValidation.validateAsync(req.params); - await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); - - const explain = req?.query?.explain; - let { limit, type, page, rowsPerPage, filter, field, order } = req.query; - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const monitors = await this.monitorService.getMonitorsWithChecksByTeamId({ - teamId, - limit, - type, - page, - rowsPerPage, - filter, - field, - order, - explain, - }); - - return res.success({ - msg: this.stringService.monitorGetByTeamId, - data: monitors, - }); - }, - SERVICE_NAME, - "getMonitorsWithChecksByTeamId" - ); - - exportMonitorsToCSV = this.asyncHandler( - async (req, res) => { - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const csv = await this.monitorService.exportMonitorsToCSV({ teamId }); - - return res.file({ - data: csv, - headers: { - "Content-Type": "text/csv", - "Content-Disposition": "attachment; filename=monitors.csv", - }, - }); - }, - SERVICE_NAME, - "exportMonitorsToCSV" - ); - - exportMonitorsToJSON = this.asyncHandler( - async (req, res) => { - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const json = await this.monitorService.exportMonitorsToJSON({ teamId }); - - return res.success({ - msg: this.stringService.monitorExportSuccess, - data: json, - }); - }, - SERVICE_NAME, - "exportMonitorsToJSON" - ); - - getAllGames = this.asyncHandler( - async (req, res) => { - return res.success({ - msg: this.stringService.gameListSuccess, - data: this.monitorService.getAllGames(), - }); - }, - SERVICE_NAME, - "getAllGames" - ); - - getGroupsByTeamId = this.asyncHandler( - async (req, res) => { - const teamId = req?.user?.teamId; - if (!teamId) { - throw this.errorService.createBadRequestError("Team ID is required"); - } - - const groups = await this.monitorService.getGroupsByTeamId({ teamId }); - - return res.success({ - msg: this.stringService.groupsByTeamId, - data: groups, - }); - }, - SERVICE_NAME, - "getGroupsByTeamId" - ); -} - -export default MonitorController; diff --git a/server/src/controllers/v1/monitorController.ts b/server/src/controllers/v1/monitorController.ts new file mode 100644 index 000000000..aac59cd27 --- /dev/null +++ b/server/src/controllers/v1/monitorController.ts @@ -0,0 +1,505 @@ +import { Request, Response, NextFunction } from "express"; + +import { + getMonitorByIdParamValidation, + getMonitorByIdQueryValidation, + getMonitorsByTeamIdParamValidation, + getMonitorsByTeamIdQueryValidation, + createMonitorBodyValidation, + editMonitorBodyValidation, + pauseMonitorParamValidation, + getMonitorStatsByIdParamValidation, + getMonitorStatsByIdQueryValidation, + getCertificateParamValidation, + getHardwareDetailsByIdParamValidation, + getHardwareDetailsByIdQueryValidation, +} from "../../validation/joi.js"; +import sslChecker from "ssl-checker"; +import { fetchMonitorCertificate } from "./controllerUtils.js"; +import { AppError } from "@/utils/AppError.js"; + +const SERVICE_NAME = "monitorController"; +class MonitorController { + static SERVICE_NAME = SERVICE_NAME; + + private monitorService: any; + + constructor(monitorService: any) { + this.monitorService = monitorService; + } + + get serviceName() { + return MonitorController.SERVICE_NAME; + } + + async verifyTeamAccess(teamId: string, monitorId: string) { + const monitor = await this.monitorService.getMonitorById(monitorId); + if (!monitor.teamId.equals(teamId)) { + throw new AppError({ message: "Access denied", status: 403 }); + } + } + + getAllMonitors = async (req: Request, res: Response, next: NextFunction) => { + try { + const monitors = await this.monitorService.getAllMonitors(); + return res.status(200).json({ + success: true, + msg: "Retrieved all monitors successfully", + data: monitors, + }); + } catch (error) { + next(error); + } + }; + + getMonitorCertificate = async (req: Request, res: Response, next: NextFunction) => { + try { + await getCertificateParamValidation.validateAsync(req.params); + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + const { monitorId } = req.params; + const monitor = await this.monitorService.getMonitorById({ teamId, monitorId }); + const certificate = await fetchMonitorCertificate(sslChecker, monitor); + + return res.status(200).json({ + success: true, + msg: "SSL certificate retrieved successfully", + data: { + certificateDate: new Date(certificate.validTo), + }, + }); + } catch (error) { + next(error); + } + }; + + getUptimeDetailsById = async (req: Request, res: Response, next: NextFunction) => { + try { + const monitorId = req?.params?.monitorId; + const dateRange = req?.query?.dateRange; + const normalize = req?.query?.normalize; + + const teamId = req?.user?.teamId; + + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const data = await this.monitorService.getUptimeDetailsById({ + teamId, + monitorId, + dateRange, + normalize, + }); + return res.status(200).json({ + success: true, + msg: "Uptime details retrieved successfully", + data: data, + }); + } catch (error) { + next(error); + } + }; + + getMonitorStatsById = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorStatsByIdParamValidation.validateAsync(req.params); + await getMonitorStatsByIdQueryValidation.validateAsync(req.query); + + let { limit, sortOrder, dateRange, numToDisplay, normalize } = req.query; + const monitorId = req?.params?.monitorId; + + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const monitorStats = await this.monitorService.getMonitorStatsById({ + teamId, + monitorId, + limit, + sortOrder, + dateRange, + numToDisplay, + normalize, + }); + + return res.status(200).json({ + success: true, + msg: "Monitor stats retrieved successfully", + data: monitorStats, + }); + } catch (error) { + next(error); + } + }; + + getHardwareDetailsById = async (req: Request, res: Response, next: NextFunction) => { + try { + await getHardwareDetailsByIdParamValidation.validateAsync(req.params); + await getHardwareDetailsByIdQueryValidation.validateAsync(req.query); + + const monitorId = req?.params?.monitorId; + const dateRange = req?.query?.dateRange; + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const monitor = await this.monitorService.getHardwareDetailsById({ + teamId, + monitorId, + dateRange, + }); + + return res.status(200).json({ + success: true, + msg: "Hardware details retrieved successfully", + data: monitor, + }); + } catch (error) { + next(error); + } + }; + + getMonitorById = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorByIdParamValidation.validateAsync(req.params); + await getMonitorByIdQueryValidation.validateAsync(req.query); + + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const monitor = await this.monitorService.getMonitorById({ teamId, monitorId: req?.params?.monitorId }); + + return res.status(200).json({ + success: true, + msg: "Monitor retrieved successfully", + data: monitor, + }); + } catch (error) { + next(error); + } + }; + + createMonitor = async (req: Request, res: Response, next: NextFunction) => { + try { + await createMonitorBodyValidation.validateAsync(req.body); + + const userId = req?.user?._id; + const teamId = req?.user?.teamId; + + const monitor = await this.monitorService.createMonitor({ teamId, userId, body: req.body }); + + return res.status(200).json({ + success: true, + msg: "Monitor created successfully", + data: monitor, + }); + } catch (error) { + next(error); + } + }; + + createBulkMonitors = async (req: Request, res: Response, next: NextFunction) => { + try { + if (!req.file) { + throw new AppError({ message: "No file uploaded", status: 400 }); + } + + if (!req.file.mimetype.includes("csv")) { + throw new AppError({ message: "File is not a CSV", status: 400 }); + } + + if (req.file.size === 0) { + throw new AppError({ message: "File is empty", status: 400 }); + } + + const userId = req?.user?._id; + const teamId = req?.user?.teamId; + + if (!userId || !teamId) { + throw new AppError({ message: "Missing userId or teamId", status: 400 }); + } + + const fileData = req?.file?.buffer?.toString("utf-8"); + if (!fileData) { + throw new AppError({ message: "Cannot get file from buffer", status: 400 }); + } + + const monitors = await this.monitorService.createBulkMonitors({ fileData, userId, teamId }); + + return res.status(200).json({ + success: true, + msg: "Bulk monitors created successfully", + data: monitors, + }); + } catch (error) { + next(error); + } + }; + + deleteMonitor = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorByIdParamValidation.validateAsync(req.params); + const monitorId = req.params.monitorId; + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const deletedMonitor = await this.monitorService.deleteMonitor({ teamId, monitorId }); + + return res.status(200).json({ + success: true, + msg: "Monitor deleted successfully", + data: deletedMonitor, + }); + } catch (error) { + next(error); + } + }; + + deleteAllMonitors = async (req: Request, res: Response, next: NextFunction) => { + try { + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const deletedCount = await this.monitorService.deleteAllMonitors({ teamId }); + + return res.status(200).json({ + success: true, + msg: `Deleted ${deletedCount} monitors`, + }); + } catch (error) { + next(error); + } + }; + + editMonitor = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorByIdParamValidation.validateAsync(req.params); + await editMonitorBodyValidation.validateAsync(req.body); + const monitorId = req?.params?.monitorId; + + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const editedMonitor = await this.monitorService.editMonitor({ teamId, monitorId, body: req.body }); + + return res.status(200).json({ + success: true, + msg: "Monitor edited successfully", + data: editedMonitor, + }); + } catch (error) { + next(error); + } + }; + + pauseMonitor = async (req: Request, res: Response, next: NextFunction) => { + try { + await pauseMonitorParamValidation.validateAsync(req.params); + + const monitorId = req.params.monitorId; + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const monitor = await this.monitorService.pauseMonitor({ teamId, monitorId }); + + return res.status(200).json({ + success: true, + msg: monitor.isActive ? "Monitor resumed successfully" : "Monitor paused successfully", + data: monitor, + }); + } catch (error) { + next(error); + } + }; + + addDemoMonitors = async (req: Request, res: Response, next: NextFunction) => { + try { + const { _id, teamId } = req.user; + const demoMonitors = await this.monitorService.addDemoMonitors({ userId: _id, teamId }); + + return res.status(200).json({ + success: true, + msg: "Demo monitors added successfully", + data: demoMonitors?.length ?? 0, + }); + } catch (error) { + next(error); + } + }; + + sendTestEmail = async (req: Request, res: Response, next: NextFunction) => { + try { + const { to } = req.body; + if (!to || typeof to !== "string") { + throw new AppError({ message: "Invalid 'to' email address", status: 400 }); + } + + const messageId = await this.monitorService.sendTestEmail({ to }); + return res.status(200).json({ + success: true, + msg: "Test email sent successfully", + data: { messageId }, + }); + } catch (error) { + next(error); + } + }; + + getMonitorsByTeamId = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorsByTeamIdParamValidation.validateAsync(req.params); + await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); + + let { limit, type, page, rowsPerPage, filter, field, order } = req.query; + const teamId = req?.user?.teamId; + + const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, limit, type, page, rowsPerPage, filter, field, order }); + + return res.status(200).json({ + success: true, + msg: "Monitors retrieved successfully", + data: monitors, + }); + } catch (error) { + next(error); + } + }; + + getMonitorsAndSummaryByTeamId = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorsByTeamIdParamValidation.validateAsync(req.params); + await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); + + const explain = req?.query?.explain; + const type = req?.query?.type; + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const result = await this.monitorService.getMonitorsAndSummaryByTeamId({ teamId, type, explain }); + + return res.status(200).json({ + msg: "Monitors and summary retrieved successfully", + data: result, + }); + } catch (error) { + next(error); + } + }; + + getMonitorsWithChecksByTeamId = async (req: Request, res: Response, next: NextFunction) => { + try { + await getMonitorsByTeamIdParamValidation.validateAsync(req.params); + await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); + + const explain = req?.query?.explain; + let { limit, type, page, rowsPerPage, filter, field, order } = req.query; + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const monitors = await this.monitorService.getMonitorsWithChecksByTeamId({ + teamId, + limit, + type, + page, + rowsPerPage, + filter, + field, + order, + explain, + }); + + return res.status(200).json({ + msg: "Monitors retrieved successfully", + data: monitors, + }); + } catch (error) { + next(error); + } + }; + exportMonitorsToCSV = async (req: Request, res: Response, next: NextFunction) => { + try { + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const csv = await this.monitorService.exportMonitorsToCSV({ teamId }); + res.setHeader("Content-Type", "text/csv"); + res.setHeader("Content-Disposition", "attachment; filename=monitors.csv"); + return res.send(csv); + } catch (error) { + next(error); + } + }; + + exportMonitorsToJSON = async (req: Request, res: Response, next: NextFunction) => { + try { + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const json = await this.monitorService.exportMonitorsToJSON({ teamId }); + + return res.status(200).json({ + success: true, + msg: "Monitors exported successfully", + data: json, + }); + } catch (error) { + next(error); + } + }; + + getAllGames = async (req: Request, res: Response, next: NextFunction) => { + try { + const games = this.monitorService.getAllGames(); + return res.status(200).json({ + success: true, + msg: "Supported games retrieved successfully", + data: games, + }); + } catch (error) { + next(error); + } + }; + + getGroupsByTeamId = async (req: Request, res: Response, next: NextFunction) => { + try { + const teamId = req?.user?.teamId; + if (!teamId) { + throw new AppError({ message: "Team ID is required", status: 400 }); + } + + const groups = await this.monitorService.getGroupsByTeamId({ teamId }); + + return res.status(200).json({ + msg: "Groups retrieved successfully", + data: groups, + }); + } catch (error) { + next(error); + } + }; +} + +export default MonitorController; diff --git a/server/src/service/infrastructure/notes b/server/src/service/infrastructure/notes deleted file mode 100644 index ce5a77ddb..000000000 --- a/server/src/service/infrastructure/notes +++ /dev/null @@ -1,83 +0,0 @@ -import { Typography, Select } from "@mui/material"; -import MenuItem from "@mui/material/MenuItem"; -import type { SelectProps } from "@mui/material/Select"; -import { useTheme } from "@mui/material/styles"; -import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; - -export const SelectInput: React.FC = ({ ...props }) => { - const theme = useTheme(); - return ( -