diff --git a/server/src/config/controllers.js b/server/src/config/controllers.js index 825d478aa..357c33a4b 100644 --- a/server/src/config/controllers.js +++ b/server/src/config/controllers.js @@ -46,9 +46,7 @@ export const initializeControllers = (services) => { diagnosticService: services.diagnosticService, }); - controllers.incidentController = new IncidentController(commonDependencies, { - incidentService: services.incidentService, - }); + controllers.incidentController = new IncidentController(services.incidentService); return controllers; }; diff --git a/server/src/controllers/v1/incidentController.js b/server/src/controllers/v1/incidentController.js deleted file mode 100644 index d20e3cdb8..000000000 --- a/server/src/controllers/v1/incidentController.js +++ /dev/null @@ -1,191 +0,0 @@ -import BaseController from "./baseController.js"; - -const SERVICE_NAME = "incidentController"; - -/** - * Incident Controller - * - * Handles all incident-related HTTP requests including retrieving incidents, - * resolving incidents manually, and getting incident summaries. - * - * @class IncidentController - * @description Manages incident operations and tracking - */ -class IncidentController extends BaseController { - static SERVICE_NAME = SERVICE_NAME; - - /** - * Creates an instance of IncidentController. - * - * @param {Object} commonDependencies - Common dependencies injected into the controller - * @param {Object} dependencies - The dependencies required by the controller - * @param {Object} dependencies.incidentService - Incident business logic service - */ - constructor(commonDependencies, { incidentService }) { - super(commonDependencies); - this.incidentService = incidentService; - } - - get serviceName() { - return IncidentController.SERVICE_NAME; - } - - /** - * Retrieves all incidents for the current user's team with filtering and pagination. - * - * @async - * @function getIncidentsByTeam - * @param {Object} req - Express request object - * @param {Object} req.query - Query parameters for filtering and pagination - * @param {string} [req.query.sortOrder] - Sort order (asc/desc) - * @param {string} [req.query.dateRange] - Date range filter - * @param {string} [req.query.filter] - General filter string - * @param {number} [req.query.page] - Page number for pagination - * @param {number} [req.query.rowsPerPage] - Number of rows per page - * @param {boolean} [req.query.status] - Filter by incident status (true=active, false=resolved) - * @param {string} [req.query.monitorId] - Filter by monitor ID - * @param {string} [req.query.resolutionType] - Filter by resolution type (automatic/manual) - * @param {Object} req.user - Current authenticated user (from JWT) - * @param {string} req.user.teamId - User's team ID - * @param {Object} res - Express response object - * @returns {Promise} Success response with incidents data - * @throws {Error} 422 - Validation error if query parameters are invalid - * @example - * GET /incidents/team?page=1&rowsPerPage=20&status=true&filter=active - * // Requires JWT authentication - */ - getIncidentsByTeam = this.asyncHandler( - async (req, res) => { - const result = await this.incidentService.getIncidentsByTeam({ - teamId: req?.user?.teamId, - query: req?.query, - }); - - return res.success({ - msg: "Incidents retrieved successfully", - data: result, - }); - }, - SERVICE_NAME, - "getIncidentsByTeam" - ); - - /** - * Retrieves a summary of incidents for the current user's team. - * - * @async - * @function getIncidentSummary - * @param {Object} req - Express request object - * @param {Object} req.query - Query parameters - * @param {number} [req.query.limit=10] - Number of latest incidents to return - * @param {Object} req.user - Current authenticated user (from JWT) - * @param {string} req.user.teamId - User's team ID - * @param {Object} res - Express response object - * @returns {Promise} Success response with incidents summary containing: - * - totalActive: Number of active incidents - * - avgResolutionTimeHours: Average time to resolve incidents in hours - * - topMonitor: Monitor with most incidents (monitorId, monitorName, incidentCount) - * - total: Total number of incidents - * - totalManualResolutions: Total incidents resolved manually - * - totalAutomaticResolutions: Total incidents resolved automatically - * - latestIncidents: Array of latest incidents created - * @example - * GET /incidents/team/summary?limit=5 - * // Requires JWT authentication - */ - getIncidentSummary = this.asyncHandler( - async (req, res) => { - const summary = await this.incidentService.getIncidentSummary({ - teamId: req?.user?.teamId, - query: req?.query, - }); - - return res.success({ - msg: "Incident summary retrieved successfully", - data: summary, - }); - }, - SERVICE_NAME, - "getIncidentSummary" - ); - - /** - * Retrieves a specific incident by ID. - * - * @async - * @function getIncidentById - * @param {Object} req - Express request object - * @param {Object} req.params - URL parameters - * @param {string} req.params.incidentId - ID of the incident to retrieve - * @param {Object} req.user - Current authenticated user (from JWT) - * @param {string} req.user.teamId - User's team ID - * @param {Object} res - Express response object - * @returns {Promise} Success response with incident data - * @throws {Error} 404 - Not found if incident doesn't exist - * @throws {Error} 403 - Forbidden if user doesn't have access to incident - * @example - * GET /incidents/507f1f77bcf86cd799439011 - * // Requires JWT authentication - */ - getIncidentById = this.asyncHandler( - async (req, res) => { - const incident = await this.incidentService.getIncidentById({ - incidentId: req?.params?.incidentId, - teamId: req?.user?.teamId, - }); - - return res.success({ - msg: "Incident retrieved successfully", - data: incident, - }); - }, - SERVICE_NAME, - "getIncidentById" - ); - - /** - * Manually resolves a specific incident by ID. - * - * @async - * @function resolveIncidentManually - * @param {Object} req - Express request object - * @param {Object} req.params - URL parameters - * @param {string} req.params.incidentId - ID of the incident to resolve - * @param {Object} req.body - Request body containing resolution data - * @param {string} [req.body.comment] - Optional comment about the resolution - * @param {Object} req.user - Current authenticated user (from JWT) - * @param {string} req.user.teamId - User's team ID - * @param {string} req.user._id - User's ID - * @param {Object} res - Express response object - * @returns {Promise} Success response with updated incident data - * @throws {Error} 422 - Validation error if request body is invalid - * @throws {Error} 404 - Not found if incident doesn't exist - * @throws {Error} 403 - Forbidden if user doesn't have access to incident - * @throws {Error} 400 - Bad request if incident is already resolved - * @example - * PUT /incidents/507f1f77bcf86cd799439011/resolve - * { - * "comment": "Issue resolved by restarting the service" - * } - * // Requires JWT authentication - */ - resolveIncidentManually = this.asyncHandler( - async (req, res) => { - const resolvedIncident = await this.incidentService.resolveIncidentManually({ - incidentId: req?.params?.incidentId, - userId: req?.user?._id, - teamId: req?.user?.teamId, - comment: req?.body?.comment, - }); - - return res.success({ - msg: "Incident resolved successfully", - data: resolvedIncident, - }); - }, - SERVICE_NAME, - "resolveIncidentManually" - ); -} - -export default IncidentController; diff --git a/server/src/controllers/v1/incidentController.ts b/server/src/controllers/v1/incidentController.ts new file mode 100644 index 000000000..8a56b5ef8 --- /dev/null +++ b/server/src/controllers/v1/incidentController.ts @@ -0,0 +1,88 @@ +import { Request, Response, NextFunction } from "express"; + +const SERVICE_NAME = "incidentController"; + +class IncidentController { + static SERVICE_NAME = SERVICE_NAME; + + private incidentService: any; + constructor(incidentService: any) { + this.incidentService = incidentService; + } + + get serviceName() { + return IncidentController.SERVICE_NAME; + } + + getIncidentsByTeam = async (req: Request, res: Response, next: NextFunction) => { + try { + const result = await this.incidentService.getIncidentsByTeam({ + teamId: req?.user?.teamId, + query: req?.query, + }); + + return res.status(200).json({ + success: true, + msg: "Incidents retrieved successfully", + data: result, + }); + } catch (error) { + next(error); + } + }; + + getIncidentSummary = async (req: Request, res: Response, next: NextFunction) => { + try { + const summary = await this.incidentService.getIncidentSummary({ + teamId: req?.user?.teamId, + query: req?.query, + }); + + return res.status(200).json({ + success: true, + msg: "Incident summary retrieved successfully", + data: summary, + }); + } catch (error) { + next(error); + } + }; + + getIncidentById = async (req: Request, res: Response, next: NextFunction) => { + try { + const incident = await this.incidentService.getIncidentById({ + incidentId: req?.params?.incidentId, + teamId: req?.user?.teamId, + }); + + return res.status(200).json({ + success: true, + msg: "Incident retrieved successfully", + data: incident, + }); + } catch (error) { + next(error); + } + }; + + resolveIncidentManually = async (req: Request, res: Response, next: NextFunction) => { + try { + const resolvedIncident = await this.incidentService.resolveIncidentManually({ + incidentId: req?.params?.incidentId, + userId: req?.user?._id, + teamId: req?.user?.teamId, + comment: req?.body?.comment, + }); + + return res.status(200).json({ + success: true, + msg: "Incident resolved successfully", + data: resolvedIncident, + }); + } catch (error) { + next(error); + } + }; +} + +export default IncidentController;