Files
Checkmate/server/src/controllers/IncidentsController.ts
T
2025-12-08 23:18:46 +00:00

163 lines
4.4 KiB
TypeScript

import { Request, Response, NextFunction } from "express";
import ApiError from "@/utils/ApiError.js";
import {
IncidentService,
NotificationService,
MonitorService,
} from "@/services/index.js";
import { getChildLogger } from "@/logger/Logger.js";
const logger = getChildLogger("IncidentController");
export interface IIncidentsController {
getIncidents: (req: Request, res: Response, next: NextFunction) => void;
getIncidentById: (req: Request, res: Response, next: NextFunction) => void;
resolveIncident: (req: Request, res: Response, next: NextFunction) => void;
exportIncidents: (req: Request, res: Response, next: NextFunction) => void;
}
class IncidentsController implements IIncidentsController {
private incidentService: IncidentService;
private notificationService: NotificationService;
private monitorService: MonitorService;
constructor(
incidentService: IncidentService,
notificationService: NotificationService,
monitorService: MonitorService
) {
this.incidentService = incidentService;
this.notificationService = notificationService;
this.monitorService = monitorService;
}
getIncidents = async (req: Request, res: Response, next: NextFunction) => {
try {
const userContext = req.user;
if (!userContext) {
return res.status(401).json({ message: "Unauthorized" });
}
const teamId = userContext.currentTeamId;
if (!teamId) {
throw new ApiError("No team ID", 400);
}
const { resolved, resolutionType, page, rowsPerPage, range, monitorId } =
req.validatedQuery;
const incidents = await this.incidentService.getAll(
teamId,
monitorId,
page,
rowsPerPage,
range,
resolved,
resolutionType
);
res.status(200).json({ message: "OK", data: incidents });
} catch (error) {
next(error);
}
};
getIncidentById = async (req: Request, res: Response, next: NextFunction) => {
try {
const userContext = req.user;
if (!userContext) {
return res.status(401).json({ message: "Unauthorized" });
}
const teamId = userContext.currentTeamId;
if (!teamId) {
throw new ApiError("No team ID", 400);
}
const { id } = req.params;
if (!id) {
throw new ApiError("No incident ID", 400);
}
const incident = await this.incidentService.get(teamId, id);
if (!incident) {
throw new ApiError("Incident not found", 404);
}
res.status(200).json({ message: "OK", data: incident });
} catch (error) {
next(error);
}
};
resolveIncident = async (req: Request, res: Response, next: NextFunction) => {
try {
const userContext = req.user;
if (!userContext) {
return res.status(401).json({ message: "Unauthorized" });
}
const teamId = userContext.currentTeamId;
if (!teamId) {
throw new ApiError("No team ID", 400);
}
const { id } = req.params;
if (!id) {
throw new ApiError("No incident ID", 400);
}
const { resolutionNote } = req.body;
const resolved = await this.incidentService.resolve(
teamId,
id,
"manual",
undefined,
userContext.sub,
resolutionNote
);
if (!resolved) {
throw new ApiError("Incident not found or could not be resolved", 500);
}
// This should be best effort only, don't wait and don't fail
this.monitorService
.get(teamId, resolved.monitorId.toString())
.then((monitor) => {
this.notificationService.handleNotifications(monitor, resolved);
})
.catch((error) => {
logger.warn(error);
});
return res
.status(200)
.json({ message: "Incident resolved", data: resolved });
} catch (error) {
next(error);
}
};
exportIncidents = async (req: Request, res: Response, next: NextFunction) => {
try {
const userContext = req.user;
if (!userContext) {
return res.status(401).json({ message: "Unauthorized" });
}
const teamId = userContext.currentTeamId;
if (!teamId) {
throw new ApiError("No team ID", 400);
}
const incidents = await this.incidentService.export(teamId);
return res.status(200).json({ message: "OK", data: incidents });
} catch (error) {
next(error);
}
};
}
export default IncidentsController;