105 lines
4.0 KiB
TypeScript
105 lines
4.0 KiB
TypeScript
import { z } from "zod";
|
|
import { registry } from "../registry.js";
|
|
import { bearer, okJson, okJsonNoData, standardErrors } from "../helpers.js";
|
|
import { getIncidentsByTeamQueryValidation, getIncidentSummaryQueryValidation } from "@/api/validation/incidentValidation.js";
|
|
|
|
const tags = ["incidents"];
|
|
|
|
const incidentIdParam = z.object({ incidentId: z.string() });
|
|
|
|
const incidentObject = z
|
|
.object({
|
|
id: z.string().openapi({ example: "65f1c2a4d8b9e0123456789c" }),
|
|
monitorId: z.string().openapi({ example: "65f1c2a4d8b9e0123456789a" }),
|
|
teamId: z.string().openapi({ example: "65f1c2a4d8b9e01234567890" }),
|
|
startTime: z.string().openapi({ example: "2026-04-15T03:21:00.000Z" }),
|
|
endTime: z.string().nullable().openapi({ example: "2026-04-15T03:34:00.000Z" }),
|
|
status: z.boolean().openapi({ example: true, description: "true = resolved, false = ongoing" }),
|
|
message: z.string().nullable().optional().openapi({ example: "HTTP 503 from origin" }),
|
|
statusCode: z.number().nullable().optional().openapi({ example: 503 }),
|
|
resolutionType: z.enum(["automatic", "manual"]).nullable().openapi({ example: "automatic" }),
|
|
resolvedBy: z.string().nullable().optional(),
|
|
resolvedByEmail: z.string().nullable().optional(),
|
|
comment: z.string().nullable().optional(),
|
|
createdAt: z.string().openapi({ example: "2026-04-15T03:21:00.000Z" }),
|
|
updatedAt: z.string().openapi({ example: "2026-04-15T03:34:00.000Z" }),
|
|
})
|
|
.passthrough()
|
|
.openapi("Incident");
|
|
|
|
const incidentSummaryItem = z
|
|
.object({
|
|
id: z.string().openapi({ example: "65f1c2a4d8b9e0123456789c" }),
|
|
monitorId: z.string().openapi({ example: "65f1c2a4d8b9e0123456789a" }),
|
|
monitorName: z.string().nullable().openapi({ example: "Marketing site" }),
|
|
status: z.boolean().openapi({ example: true }),
|
|
startTime: z.string().openapi({ example: "2026-04-15T03:21:00.000Z" }),
|
|
endTime: z.string().nullable().openapi({ example: "2026-04-15T03:34:00.000Z" }),
|
|
resolutionType: z.enum(["automatic", "manual"]).nullable().openapi({ example: "automatic" }),
|
|
message: z.string().nullable().openapi({ example: "HTTP 503 from origin" }),
|
|
statusCode: z.number().nullable().openapi({ example: 503 }),
|
|
createdAt: z.string().openapi({ example: "2026-04-15T03:21:00.000Z" }),
|
|
})
|
|
.openapi("IncidentSummaryItem");
|
|
|
|
const incidentSummary = z
|
|
.object({
|
|
total: z.number().openapi({ example: 12 }),
|
|
totalActive: z.number().openapi({ example: 1 }),
|
|
totalManualResolutions: z.number().openapi({ example: 2 }),
|
|
totalAutomaticResolutions: z.number().openapi({ example: 9 }),
|
|
avgResolutionTimeHours: z.number().openapi({ example: 0.5 }),
|
|
topMonitor: z
|
|
.object({
|
|
monitorId: z.string().openapi({ example: "65f1c2a4d8b9e0123456789a" }),
|
|
monitorName: z.string().nullable().openapi({ example: "Marketing site" }),
|
|
incidentCount: z.number().openapi({ example: 4 }),
|
|
})
|
|
.nullable(),
|
|
latestIncidents: z.array(incidentSummaryItem),
|
|
})
|
|
.openapi("IncidentSummary");
|
|
|
|
registry.registerPath({
|
|
method: "get",
|
|
path: "/incidents/team",
|
|
tags,
|
|
summary: "List incidents for the caller's team",
|
|
security: bearer,
|
|
request: { query: getIncidentsByTeamQueryValidation },
|
|
responses: { "200": okJson(z.array(incidentObject)), ...standardErrors },
|
|
});
|
|
|
|
registry.registerPath({
|
|
method: "get",
|
|
path: "/incidents/team/summary",
|
|
tags,
|
|
summary: "Incident summary for the caller's team",
|
|
security: bearer,
|
|
request: { query: getIncidentSummaryQueryValidation },
|
|
responses: { "200": okJson(incidentSummary), ...standardErrors },
|
|
});
|
|
|
|
registry.registerPath({
|
|
method: "get",
|
|
path: "/incidents/{incidentId}",
|
|
tags,
|
|
summary: "Get an incident by id",
|
|
security: bearer,
|
|
request: { params: incidentIdParam },
|
|
responses: {
|
|
"200": okJson(z.object({ incident: incidentObject, monitor: z.unknown(), user: z.unknown().nullable() })),
|
|
...standardErrors,
|
|
},
|
|
});
|
|
|
|
registry.registerPath({
|
|
method: "put",
|
|
path: "/incidents/{incidentId}/resolve",
|
|
tags,
|
|
summary: "Manually resolve an incident (admin/superadmin)",
|
|
security: bearer,
|
|
request: { params: incidentIdParam },
|
|
responses: { "200": okJsonNoData(), ...standardErrors },
|
|
});
|