From 30e8cfc9ec0e53607b0ac3cb4997f828d90d5a0d Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Sun, 7 Jun 2026 22:37:24 -0400 Subject: [PATCH 1/9] Add custom domain support for published status pages. Fixes #3647 --- client/src/Hooks/useStatusPageForm.ts | 1 + client/src/Pages/StatusPage/Create/index.tsx | 26 + .../Components/HeaderStatusPageControls.tsx | 5 +- client/src/Pages/StatusPage/Status/index.tsx | 16 +- .../Components/StatusPagesTable.tsx | 11 +- client/src/Routes/index.tsx | 16 + client/src/Types/StatusPage.ts | 1 + client/src/Utils/statusPageUrl.ts | 72 + client/src/Validation/statusPage.ts | 23 + client/src/locales/en.json | 5 + server/openapi.json | 24437 +++++++++------- server/openapi/routes/statusPage.ts | 16 +- server/src/app.ts | 3 +- .../src/controllers/statusPageController.ts | 100 +- server/src/db/models/StatusPage.ts | 8 + server/src/middleware/statusPageCorsOrigin.ts | 39 + .../status-pages/IStatusPagesRepository.ts | 1 + .../MongoStatusPagesRepository.ts | 25 +- server/src/routes/statusPageRoute.ts | 1 + .../src/service/business/statusPageService.ts | 38 +- server/src/types/statusPage.ts | 1 + server/src/utils/statusPageDomain.ts | 29 + server/src/validation/statusPageValidation.ts | 18 +- .../unit/services/statusPageService.test.ts | 43 +- .../test/unit/utils/statusPageDomain.test.ts | 28 + 25 files changed, 13919 insertions(+), 11044 deletions(-) create mode 100644 client/src/Utils/statusPageUrl.ts create mode 100644 server/src/middleware/statusPageCorsOrigin.ts create mode 100644 server/src/utils/statusPageDomain.ts create mode 100644 server/test/unit/utils/statusPageDomain.test.ts diff --git a/client/src/Hooks/useStatusPageForm.ts b/client/src/Hooks/useStatusPageForm.ts index 681a3da6c..609db4792 100644 --- a/client/src/Hooks/useStatusPageForm.ts +++ b/client/src/Hooks/useStatusPageForm.ts @@ -31,6 +31,7 @@ export const useStatusPageForm = ({ const defaults: StatusPageFormData = { companyName: data?.companyName || "", url: data?.url || generateDefaultUrl(), + customDomain: data?.customDomain ?? null, timezone: resolveTimezone(data?.timezone), type: data?.type || ["uptime"], color: data?.color || "#13715B", diff --git a/client/src/Pages/StatusPage/Create/index.tsx b/client/src/Pages/StatusPage/Create/index.tsx index c9bc04838..8a7b48010 100644 --- a/client/src/Pages/StatusPage/Create/index.tsx +++ b/client/src/Pages/StatusPage/Create/index.tsx @@ -151,6 +151,11 @@ const CreateStatusPage = () => { fd.append("isPublished", String(data.isPublished)); if (data.companyName) fd.append("companyName", data.companyName); if (data.url) fd.append("url", data.url); + if (data.customDomain !== undefined && data.customDomain !== null) { + fd.append("customDomain", data.customDomain); + } else { + fd.append("customDomain", ""); + } if (data.timezone) fd.append("timezone", data.timezone); if (data.color) fd.append("color", data.color); fd.append("showCharts", String(data.showCharts)); @@ -284,6 +289,27 @@ const CreateStatusPage = () => { /> )} /> + ( + + )} + /> } /> diff --git a/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx b/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx index ba3a5940d..93c29d188 100644 --- a/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx +++ b/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx @@ -8,7 +8,8 @@ import { Settings, ExternalLink } from "lucide-react"; import { useTheme } from "@mui/material"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; -import { PUBLIC_STATUS_PAGE_PREFIX, type StatusPage } from "@/Types/StatusPage"; +import { type StatusPage } from "@/Types/StatusPage"; +import { getStatusPagePublicUrl } from "@/Utils/statusPageUrl"; interface HeaderStatusPageControlsProps { isAdmin: boolean; @@ -50,7 +51,7 @@ export const HeaderStatusPageControls = ({ { window.open( - `${PUBLIC_STATUS_PAGE_PREFIX}/${statusPage.url}`, + getStatusPagePublicUrl(statusPage), "_blank", "noopener,noreferrer" ); diff --git a/client/src/Pages/StatusPage/Status/index.tsx b/client/src/Pages/StatusPage/Status/index.tsx index 9c4001fae..5ccc5f44c 100644 --- a/client/src/Pages/StatusPage/Status/index.tsx +++ b/client/src/Pages/StatusPage/Status/index.tsx @@ -14,6 +14,11 @@ import { type StatusPageResponse, type StatusPageTheme, } from "@/Types/StatusPage"; +import { + buildStatusPageApiPath, + getStatusPagePublicUrl, + isCustomDomainHost, +} from "@/Utils/statusPageUrl"; import { HeaderStatusPageControls } from "@/Pages/StatusPage/Status/Components/HeaderStatusPageControls"; import { StatusPageThemeProvider } from "@/Pages/StatusPage/Status/themes/StatusPageThemeProvider"; import { @@ -67,9 +72,14 @@ const StatusPageView = () => { const isAdmin = useIsAdmin(); const location = useLocation(); - const isPublic = location.pathname.startsWith(PUBLIC_STATUS_PAGE_PREFIX); + const onCustomDomainHost = isCustomDomainHost(); + const isPublic = + onCustomDomainHost || location.pathname.startsWith(PUBLIC_STATUS_PAGE_PREFIX); - const apiUrl = url ? `/status-page/${url}?type=uptime&type=infrastructure` : null; + const apiUrl = buildStatusPageApiPath({ + url, + useCustomDomain: onCustomDomainHost, + }); const { data, isLoading, error } = useGet( apiUrl, @@ -134,7 +144,7 @@ const StatusPageView = () => { ); } - const publicUrl = `${window.location.origin}${PUBLIC_STATUS_PAGE_PREFIX}/${statusPage.url}`; + const publicUrl = getStatusPagePublicUrl(statusPage); return ( { if (row.isPublished) { e.stopPropagation(); - const url = `${PUBLIC_STATUS_PAGE_PREFIX}/${row.url}`; - window.open(url, "_blank", "noopener,noreferrer"); + window.open(getStatusPagePublicUrl(row), "_blank", "noopener,noreferrer"); } }; @@ -70,7 +71,9 @@ export const StatusPagesTable = ({ content: t("pages.statusPages.table.headers.url"), render: (row) => { const content = row.isPublished - ? `/${row.url}` + ? row.customDomain + ? getStatusPagePublicPath(row) + : `/${row.url}` : t("pages.statusPages.table.unpublished"); return ( { + if (isCustomDomainHost()) { + return ( + + } + /> + } + /> + + ); + } + return ( { + const source = + CLIENT_HOST || (typeof window !== "undefined" ? window.location.origin : undefined); + if (!source) { + return null; + } + + try { + return new URL(source).hostname.toLowerCase(); + } catch { + return null; + } +}; + +export const isCustomDomainHost = (): boolean => { + if (typeof window === "undefined") { + return false; + } + + const appHostname = getAppHostname(); + if (!appHostname) { + return false; + } + + return window.location.hostname.toLowerCase() !== appHostname; +}; + +export const getStatusPagePublicPath = ( + statusPage: Pick +): string => { + if (statusPage.customDomain) { + return `https://${statusPage.customDomain}`; + } + + return `${PUBLIC_STATUS_PAGE_PREFIX}/${statusPage.url}`; +}; + +export const getStatusPagePublicUrl = ( + statusPage: Pick +): string => { + if (statusPage.customDomain) { + return `https://${statusPage.customDomain}`; + } + + if (typeof window !== "undefined") { + return `${window.location.origin}${PUBLIC_STATUS_PAGE_PREFIX}/${statusPage.url}`; + } + + return `${PUBLIC_STATUS_PAGE_PREFIX}/${statusPage.url}`; +}; + +export const buildStatusPageApiPath = (options: { + url?: string; + useCustomDomain?: boolean; +}): string | null => { + const query = "type=uptime&type=infrastructure"; + + if (options.useCustomDomain && typeof window !== "undefined") { + const domain = encodeURIComponent(window.location.hostname); + return `/status-page/resolve?domain=${domain}&${query}`; + } + + if (options.url) { + return `/status-page/${options.url}?${query}`; + } + + return null; +}; diff --git a/client/src/Validation/statusPage.ts b/client/src/Validation/statusPage.ts index 542f6b2ae..271699765 100644 --- a/client/src/Validation/statusPage.ts +++ b/client/src/Validation/statusPage.ts @@ -9,6 +9,23 @@ import { STATUS_PAGE_THEMES, STATUS_PAGE_THEME_MODES } from "@/Types/StatusPage" // field definitions. export const statusPageStepRegistry = z.registry<{ step: number }>(); +const statusPageHostnameRegex = + /^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/; + +const normalizeCustomDomainInput = (raw: string | null): string | null => { + if (raw === null) { + return null; + } + + const trimmed = raw.trim().toLowerCase(); + if (!trimmed) { + return null; + } + + const withoutScheme = trimmed.replace(/^https?:\/\//, ""); + return withoutScheme.split("/")[0]?.split(":")[0] ?? null; +}; + export const statusPageSchema = z.object({ companyName: z .string() @@ -22,6 +39,12 @@ export const statusPageSchema = z.object({ /^[a-z0-9-]+$/, "URL can only contain lowercase letters, numbers, and hyphens" ), + customDomain: z + .union([z.string(), z.null()]) + .transform(normalizeCustomDomainInput) + .refine((domain) => domain === null || statusPageHostnameRegex.test(domain), { + message: "Enter a valid domain name (e.g. status.example.com)", + }), timezone: z.string().optional(), type: z .array(z.enum(["uptime", "infrastructure"])) diff --git a/client/src/locales/en.json b/client/src/locales/en.json index e5f7073b6..b209bf414 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -1509,6 +1509,11 @@ "url": { "label": "Your status page address", "placeholder": "my-status-page" + }, + "customDomain": { + "label": "Custom domain", + "placeholder": "status.example.com", + "helper": "Optional. Point a DNS record to this Checkmate instance to serve the status page at your own domain." } } }, diff --git a/server/openapi.json b/server/openapi.json index 2a5abd6e0..d1900f322 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -1,10995 +1,13446 @@ { - "openapi": "3.0.0", - "info": { - "title": "Checkmate API", - "version": "1.0.0", - "description": "Generated from Zod validation schemas. Source of truth: server/src/validation/*.ts" - }, - "servers": [ - { - "url": "/api/v1", - "description": "Current server" - } - ], - "tags": [ - { - "name": "auth", - "description": "Sign up, log in, password reset, and the authenticated user's profile." - }, - { - "name": "monitors", - "description": "Configure and inspect monitors (HTTP, port, ping, hardware, docker, game, gRPC) for the caller's team." - }, - { - "name": "checks", - "description": "Individual monitoring check results, including history, summaries, and bulk deletes." - }, - { - "name": "geo-checks", - "description": "Geographic check results for monitors with multi-region probing enabled." - }, - { - "name": "incidents", - "description": "Downtime incidents derived from monitor state changes, including filtering and CSV export." - }, - { - "name": "notifications", - "description": "Notification channels (email, webhook, Slack, Discord, PagerDuty, Matrix, Teams, Telegram, Pushover, Twilio) and test alerts." - }, - { - "name": "maintenance-window", - "description": "Scheduled maintenance windows during which monitors do not generate incidents or alerts." - }, - { - "name": "status-page", - "description": "Public status pages, their configuration, and the monitors they expose." - }, - { - "name": "settings", - "description": "Global application settings (admin/superadmin)." - }, - { - "name": "invite", - "description": "Team invitations and accepting them." - }, - { - "name": "queue", - "description": "Background job queue introspection and admin actions (admin/superadmin)." - }, - { - "name": "diagnostic", - "description": "System diagnostics for the running server (admin/superadmin)." - }, - { - "name": "logs", - "description": "Application logs for the running server (admin/superadmin)." - } - ], - "components": { - "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT" - } - }, - "schemas": { - "AuthPayload": { - "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - }, - "token": { - "type": "string" - } - }, - "required": ["user"], - "example": { - "user": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": ["admin"], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - }, - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "User": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "email": { - "type": "string" - }, - "role": { - "type": "array", - "items": { - "type": "string" - } - }, - "teamId": { - "type": "string" - }, - "profileImage": { - "type": "string", - "nullable": true - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": ["_id", "firstName", "lastName", "email", "role", "createdAt", "updatedAt"], - "additionalProperties": { - "nullable": true - }, - "example": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": ["admin"], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - } - }, - "Incident": { - "type": "object", - "properties": { - "id": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789c" - }, - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "teamId": { - "type": "string", - "example": "65f1c2a4d8b9e01234567890" - }, - "startTime": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "endTime": { - "type": "string", - "nullable": true, - "example": "2026-04-15T03:34:00.000Z" - }, - "status": { - "type": "boolean", - "example": true, - "description": "true = resolved, false = ongoing" - }, - "message": { - "type": "string", - "nullable": true, - "example": "HTTP 503 from origin" - }, - "statusCode": { - "type": "number", - "nullable": true, - "example": 503 - }, - "resolutionType": { - "type": "string", - "nullable": true, - "enum": ["automatic", "manual", null], - "example": "automatic" - }, - "resolvedBy": { - "type": "string", - "nullable": true - }, - "resolvedByEmail": { - "type": "string", - "nullable": true - }, - "comment": { - "type": "string", - "nullable": true - }, - "createdAt": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "updatedAt": { - "type": "string", - "example": "2026-04-15T03:34:00.000Z" - } - }, - "required": ["id", "monitorId", "teamId", "startTime", "endTime", "status", "resolutionType", "createdAt", "updatedAt"], - "additionalProperties": { - "nullable": true - } - }, - "IncidentSummary": { - "type": "object", - "properties": { - "total": { - "type": "number", - "example": 12 - }, - "totalActive": { - "type": "number", - "example": 1 - }, - "totalManualResolutions": { - "type": "number", - "example": 2 - }, - "totalAutomaticResolutions": { - "type": "number", - "example": 9 - }, - "avgResolutionTimeHours": { - "type": "number", - "example": 0.5 - }, - "topMonitor": { - "type": "object", - "nullable": true, - "properties": { - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "monitorName": { - "type": "string", - "nullable": true, - "example": "Marketing site" - }, - "incidentCount": { - "type": "number", - "example": 4 - } - }, - "required": ["monitorId", "monitorName", "incidentCount"] - }, - "latestIncidents": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncidentSummaryItem" - } - } - }, - "required": [ - "total", - "totalActive", - "totalManualResolutions", - "totalAutomaticResolutions", - "avgResolutionTimeHours", - "topMonitor", - "latestIncidents" - ] - }, - "IncidentSummaryItem": { - "type": "object", - "properties": { - "id": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789c" - }, - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "monitorName": { - "type": "string", - "nullable": true, - "example": "Marketing site" - }, - "status": { - "type": "boolean", - "example": true - }, - "startTime": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "endTime": { - "type": "string", - "nullable": true, - "example": "2026-04-15T03:34:00.000Z" - }, - "resolutionType": { - "type": "string", - "nullable": true, - "enum": ["automatic", "manual", null], - "example": "automatic" - }, - "message": { - "type": "string", - "nullable": true, - "example": "HTTP 503 from origin" - }, - "statusCode": { - "type": "number", - "nullable": true, - "example": 503 - }, - "createdAt": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - } - }, - "required": ["id", "monitorId", "monitorName", "status", "startTime", "endTime", "resolutionType", "message", "statusCode", "createdAt"] - }, - "Monitor": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - "url": { - "type": "string" - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean" - }, - "interval": { - "type": "number" - }, - "status": { - "type": "string", - "enum": ["up", "down", "paused", "initializing", "maintenance", "breached"] - }, - "statusWindowSize": { - "type": "number" - }, - "statusWindowThreshold": { - "type": "number" - }, - "ignoreTlsErrors": { - "type": "boolean" - }, - "useAdvancedMatching": { - "type": "boolean" - }, - "jsonPath": { - "type": "string" - }, - "expectedValue": { - "type": "string" - }, - "matchMethod": { - "type": "string", - "enum": ["equal", "include", "regex"] - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "secret": { - "type": "string" - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "gameId": { - "type": "string" - }, - "grpcServiceName": { - "type": "string" - }, - "group": { - "type": "string", - "nullable": true - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - } - }, - "geoCheckInterval": { - "type": "number" - }, - "dnsServer": { - "type": "string" - }, - "dnsRecordType": { - "type": "string", - "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] - }, - "teamId": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "_id", - "name", - "type", - "url", - "isActive", - "interval", - "status", - "statusWindowSize", - "statusWindowThreshold", - "ignoreTlsErrors", - "useAdvancedMatching", - "notifications", - "tags", - "cpuAlertThreshold", - "memoryAlertThreshold", - "diskAlertThreshold", - "tempAlertThreshold", - "selectedDisks", - "geoCheckEnabled", - "geoCheckLocations", - "geoCheckInterval", - "teamId", - "userId", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - }, - "example": { - "_id": "65f1c2a4d8b9e0123456789a", - "name": "Marketing site", - "description": "Production marketing site monitored from the EU region", - "type": "http", - "url": "https://www.example.com", - "port": 443, - "isActive": true, - "interval": 60000, - "status": "up", - "statusWindowSize": 5, - "statusWindowThreshold": 3, - "ignoreTlsErrors": false, - "useAdvancedMatching": false, - "notifications": ["65f1c2a4d8b9e0123456789b"], - "cpuAlertThreshold": 90, - "memoryAlertThreshold": 90, - "diskAlertThreshold": 90, - "tempAlertThreshold": 80, - "selectedDisks": [], - "geoCheckEnabled": false, - "geoCheckLocations": [], - "geoCheckInterval": 300000, - "teamId": "65f1c2a4d8b9e01234567890", - "userId": "65f1c2a4d8b9e01234567891", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - } - }, - "NotificationChannelBody": { - "oneOf": [ - { - "$ref": "#/components/schemas/EmailNotification" - }, - { - "$ref": "#/components/schemas/WebhookNotification" - }, - { - "$ref": "#/components/schemas/SlackNotification" - }, - { - "$ref": "#/components/schemas/DiscordNotification" - }, - { - "$ref": "#/components/schemas/PagerDutyNotification" - }, - { - "$ref": "#/components/schemas/MatrixNotification" - }, - { - "$ref": "#/components/schemas/TeamsNotification" - }, - { - "$ref": "#/components/schemas/TelegramNotification" - }, - { - "$ref": "#/components/schemas/PushoverNotification" - }, - { - "$ref": "#/components/schemas/TwilioNotification" - }, - { - "$ref": "#/components/schemas/NtfyNotification" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "email": "#/components/schemas/EmailNotification", - "webhook": "#/components/schemas/WebhookNotification", - "slack": "#/components/schemas/SlackNotification", - "discord": "#/components/schemas/DiscordNotification", - "pager_duty": "#/components/schemas/PagerDutyNotification", - "matrix": "#/components/schemas/MatrixNotification", - "teams": "#/components/schemas/TeamsNotification", - "telegram": "#/components/schemas/TelegramNotification", - "pushover": "#/components/schemas/PushoverNotification", - "twilio": "#/components/schemas/TwilioNotification", - "ntfy": "#/components/schemas/NtfyNotification" - } - } - }, - "EmailNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["email"] - }, - "address": { - "type": "string", - "format": "email" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - } - }, - "required": ["notificationName", "type", "address"], - "example": { - "notificationName": "Ops on-call email", - "type": "email", - "address": "alerts@example.com" - } - }, - "WebhookNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["webhook"] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - } - }, - "required": ["notificationName", "type", "address"], - "example": { - "notificationName": "Custom webhook", - "type": "webhook", - "address": "https://example.com/hooks/checkmate" - } - }, - "SlackNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["slack"] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - } - }, - "required": ["notificationName", "type", "address"], - "example": { - "notificationName": "#alerts", - "type": "slack", - "address": "https://hooks.slack.com/services/T000/B000/XXXX" - } - }, - "DiscordNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["discord"] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - } - }, - "required": ["notificationName", "type", "address"], - "example": { - "notificationName": "#status", - "type": "discord", - "address": "https://discord.com/api/webhooks/123/abc" - } - }, - "PagerDutyNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["pager_duty"] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - } - }, - "required": ["notificationName", "type", "address"], - "example": { - "notificationName": "PagerDuty primary", - "type": "pager_duty", - "address": "R01XXXXXXXXXXXXXXXXXXXXXXX" - } - }, - "MatrixNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["matrix"] - }, - "address": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "homeserverUrl": { - "type": "string", - "format": "uri" - }, - "roomId": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": ["notificationName", "type", "homeserverUrl", "roomId", "accessToken"], - "example": { - "notificationName": "Matrix room", - "type": "matrix", - "homeserverUrl": "https://matrix.example.com", - "roomId": "!abc123:example.com", - "accessToken": "syt_xxx" - } - }, - "TeamsNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["teams"] - }, - "address": { - "type": "string", - "format": "uri" - } - }, - "required": ["notificationName", "type", "address"], - "example": { - "notificationName": "Teams ops channel", - "type": "teams", - "address": "https://outlook.office.com/webhook/..." - } - }, - "TelegramNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["telegram"] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": ["notificationName", "type", "address", "accessToken"], - "example": { - "notificationName": "Telegram bot", - "type": "telegram", - "address": "-1001234567890", - "accessToken": "123456:ABC-DEF" - } - }, - "PushoverNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["pushover"] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": ["notificationName", "type", "address", "accessToken"], - "example": { - "notificationName": "Pushover personal", - "type": "pushover", - "address": "u1234567890abcdef", - "accessToken": "a1234567890abcdef" - } - }, - "TwilioNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["twilio"] - }, - "accountSid": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - }, - "phone": { - "type": "string", - "minLength": 1 - }, - "twilioPhoneNumber": { - "type": "string", - "minLength": 1 - } - }, - "required": ["notificationName", "type", "accountSid", "accessToken", "phone", "twilioPhoneNumber"], - "example": { - "notificationName": "Twilio SMS", - "type": "twilio", - "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "accessToken": "your-auth-token", - "phone": "+15551234567", - "twilioPhoneNumber": "+15557654321" - } - }, - "NtfyNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": ["ntfy"] - }, - "address": { - "type": "string", - "format": "uri" - }, - "topic": { - "type": "string", - "minLength": 1 - } - }, - "required": ["notificationName", "type", "address", "topic"], - "example": { - "notificationName": "ntfy topic", - "type": "ntfy", - "address": "https://ntfy.sh", - "topic": "checkmate-alerts" - } - } - }, - "parameters": {} - }, - "paths": { - "/auth/register": { - "post": { - "tags": ["auth"], - "summary": "Register a new user (first user becomes superadmin)", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "profileImage": { - "type": "string", - "format": "binary" - }, - "inviteToken": { - "type": "string", - "default": "" - } - }, - "required": ["firstName", "lastName", "email", "password", "profileImage"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/AuthPayload" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/login": { - "post": { - "tags": ["auth"], - "summary": "Log in", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 1 - } - }, - "required": ["email", "password"] - }, - "example": { - "email": "ada@example.com", - "password": "S3cure!Passw0rd" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/AuthPayload" - } - }, - "required": ["success", "msg", "data"] - }, - "example": { - "success": true, - "msg": "OK", - "data": { - "user": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": ["admin"], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - }, - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - } - } - } - }, - "401": { - "description": "Invalid credentials", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/recovery/request": { - "post": { - "tags": ["auth"], - "summary": "Request a password recovery email", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - } - }, - "required": ["email"] - }, - "example": { - "email": "ada@example.com" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/recovery/validate": { - "post": { - "tags": ["auth"], - "summary": "Validate a password recovery token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "recoveryToken": { - "type": "string", - "minLength": 1 - } - }, - "required": ["recoveryToken"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/recovery/reset": { - "post": { - "tags": ["auth"], - "summary": "Reset password using a recovery token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "recoveryToken": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "confirm": { - "type": "string" - } - }, - "required": ["recoveryToken", "password"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/users/superadmin": { - "get": { - "tags": ["auth"], - "summary": "Check whether a superadmin user exists", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "superAdminExists": { - "type": "boolean" - } - }, - "required": ["superAdminExists"] - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/users": { - "get": { - "tags": ["auth"], - "summary": "List all users (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "post": { - "tags": ["auth"], - "summary": "Create a new user (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": ["user", "admin", "superadmin", "demo"] - }, - "minItems": 1 - }, - "profileImage": { - "type": "string", - "format": "binary" - } - }, - "required": ["firstName", "lastName", "email", "password", "role", "profileImage"] - } - } - } - }, - "responses": { - "201": { - "description": "User created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/users/{userId}": { - "get": { - "tags": ["auth"], - "summary": "Get a user by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "404": { - "description": "User not found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "patch": { - "tags": ["auth"], - "summary": "Edit a user (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": ["user", "admin", "superadmin", "demo"] - }, - "minItems": 1 - } - }, - "required": ["firstName", "lastName", "role"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["auth"], - "summary": "Delete a user (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/users/{userId}/password": { - "patch": { - "tags": ["auth"], - "summary": "Change a user's password (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - } - }, - "required": ["password"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/auth/user": { - "patch": { - "tags": ["auth"], - "summary": "Edit the currently authenticated user", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "profilePicture": { - "type": "string" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "newPassword": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "profileImage": { - "type": "string", - "format": "binary" - } - }, - "required": ["profileImage"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["auth"], - "summary": "Delete the currently authenticated user", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/checks/team/summary": { - "get": { - "tags": ["checks"], - "summary": "Aggregate check summary for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/checks/team": { - "get": { - "tags": ["checks"], - "summary": "List checks across the team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["all", "up", "down", "resolve"] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["checks"], - "summary": "Delete all checks for the team (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "deletedCount": { - "type": "number" - } - }, - "required": ["deletedCount"] - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/checks/{monitorId}": { - "get": { - "tags": ["checks"], - "summary": "List checks for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["all", "up", "down", "resolve"] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["checks"], - "summary": "Delete checks for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/diagnostic/system": { - "get": { - "tags": ["diagnostic"], - "summary": "Get system diagnostics (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/geo-checks/{monitorId}": { - "get": { - "tags": ["geo-checks"], - "summary": "Get geo check results for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["all", "up", "down", "resolve"] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/incidents/team": { - "get": { - "tags": ["incidents"], - "summary": "List incidents for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"], - "default": "all" - }, - "required": false, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "integer", - "nullable": true, - "minimum": 0 - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "monitorId", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["manual", "automatic"] - }, - "required": false, - "name": "resolutionType", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Incident" - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/incidents/team/summary": { - "get": { - "tags": ["incidents"], - "summary": "Incident summary for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": false, - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/IncidentSummary" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/incidents/{incidentId}": { - "get": { - "tags": ["incidents"], - "summary": "Get an incident by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string" - }, - "required": true, - "name": "incidentId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "incident": { - "$ref": "#/components/schemas/Incident" - }, - "monitor": { - "nullable": true - }, - "user": { - "nullable": true - } - }, - "required": ["incident"] - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/incidents/{incidentId}/resolve": { - "put": { - "tags": ["incidents"], - "summary": "Manually resolve an incident (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string" - }, - "required": true, - "name": "incidentId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/invite/send": { - "post": { - "tags": ["invite"], - "summary": "Send an invite email (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": ["user", "admin", "superadmin", "demo"] - }, - "minItems": 1 - }, - "teamId": { - "type": "string", - "minLength": 1 - } - }, - "required": ["email", "role", "teamId"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/invite/verify": { - "post": { - "tags": ["invite"], - "summary": "Verify an invite token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "token": { - "type": "string", - "minLength": 1 - } - }, - "required": ["token"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "role": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["email"], - "additionalProperties": { - "nullable": true - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/invite": { - "post": { - "tags": ["invite"], - "summary": "Create an invite token (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": ["user", "admin", "superadmin", "demo"] - }, - "minItems": 1 - }, - "teamId": { - "type": "string", - "minLength": 1 - } - }, - "required": ["email", "role", "teamId"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "token": { - "type": "string" - } - }, - "required": ["token"], - "additionalProperties": { - "nullable": true - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/logs": { - "get": { - "tags": ["logs"], - "summary": "Get application logs (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/maintenance-window": { - "post": { - "tags": ["maintenance-window"], - "summary": "Create one or more maintenance windows", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitors": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "name": { - "type": "string", - "minLength": 1 - }, - "active": { - "type": "boolean" - }, - "duration": { - "type": "number", - "minimum": 1 - }, - "durationUnit": { - "type": "string", - "enum": ["seconds", "minutes", "hours", "days"] - }, - "start": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "end": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "repeat": { - "type": "number", - "minimum": 0 - }, - "expiry": { - "type": "string", - "nullable": true, - "format": "date-time" - } - }, - "required": ["monitors", "name", "duration", "durationUnit", "start", "end", "repeat"], - "additionalProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/maintenance-window/team": { - "get": { - "tags": ["maintenance-window"], - "summary": "List maintenance windows for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "active", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "field", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": false, - "name": "order", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/maintenance-window/monitor/{monitorId}": { - "get": { - "tags": ["maintenance-window"], - "summary": "List maintenance windows for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/maintenance-window/{id}": { - "get": { - "tags": ["maintenance-window"], - "summary": "Get a maintenance window by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "patch": { - "tags": ["maintenance-window"], - "summary": "Edit a maintenance window", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "active": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "repeat": { - "type": "number" - }, - "start": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "end": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "expiry": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "monitors": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "duration": { - "type": "number" - }, - "durationUnit": { - "type": "string", - "enum": ["seconds", "minutes", "hours", "days"] - } - }, - "additionalProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["maintenance-window"], - "summary": "Delete a maintenance window", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/team": { - "get": { - "tags": ["monitors"], - "summary": "List monitors for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - } - } - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "required": false, - "name": "tags", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Monitor" - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/team/with-checks": { - "get": { - "tags": ["monitors"], - "summary": "List team monitors with their most recent checks (paginated)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "integer", - "nullable": true, - "minimum": 0 - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "field", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": false, - "name": "order", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - } - } - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "required": false, - "name": "tags", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "explain", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/team/groups": { - "get": { - "tags": ["monitors"], - "summary": "List monitor groups for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/uptime/details/{monitorId}": { - "get": { - "tags": ["monitors"], - "summary": "Get uptime details for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "normalize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/hardware/details/{monitorId}": { - "get": { - "tags": ["monitors"], - "summary": "Get hardware metrics detail for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/pagespeed/details/{monitorId}": { - "get": { - "tags": ["monitors"], - "summary": "Get PageSpeed detail for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/{monitorId}/geo-checks": { - "get": { - "tags": ["monitors"], - "summary": "Get geo check results for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["asc", "desc"] - }, - "required": false, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": ["recent", "hour", "day", "week", "month", "all"] - }, - "required": false, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "numToDisplay", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "normalize", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/pause/{monitorId}": { - "post": { - "tags": ["monitors"], - "summary": "Toggle pause state for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/certificate/{monitorId}": { - "get": { - "tags": ["monitors"], - "summary": "Get SSL certificate info for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "certificateDate": { - "type": "string" - } - }, - "required": ["certificateDate"] - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/notifications": { - "patch": { - "tags": ["monitors"], - "summary": "Bulk update notifications across monitors", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitorIds": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1, - "maxItems": 100 - }, - "notificationIds": { - "type": "array", - "items": { - "type": "string" - }, - "maxItems": 100 - }, - "action": { - "type": "string", - "enum": ["add", "remove", "set"] - } - }, - "required": ["monitorIds", "notificationIds", "action"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "modifiedCount": { - "type": "number" - } - }, - "required": ["modifiedCount"] - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors": { - "post": { - "tags": ["monitors"], - "summary": "Create a new monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "name": { - "type": "string", - "minLength": 1 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "type": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "url": { - "type": "string", - "minLength": 1 - }, - "ignoreTlsErrors": { - "type": "boolean", - "default": false - }, - "useAdvancedMatching": { - "type": "boolean", - "default": false - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean" - }, - "interval": { - "type": "number" - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "secret": { - "type": "string" - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": ["equal", "include", "regex"] - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ], - "default": "" - }, - "strategy": { - "type": "string", - "enum": ["desktop", "mobile"] - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - } - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] - } - }, - "required": ["name", "type", "url"] - } - } - } - }, - "responses": { - "200": { - "description": "Monitor created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["monitors"], - "summary": "Delete every monitor (superadmin only)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/demo": { - "post": { - "tags": ["monitors"], - "summary": "Insert preconfigured demo monitors", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "number" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/export/json": { - "get": { - "tags": ["monitors"], - "summary": "Export all team monitors as JSON", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/import/json": { - "post": { - "tags": ["monitors"], - "summary": "Import monitors from JSON", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "teamId": { - "type": "string" - }, - "name": { - "type": "string", - "minLength": 1 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "status": { - "type": "string", - "enum": ["up", "down", "paused", "initializing", "maintenance", "breached"], - "default": "initializing" - }, - "statusWindow": { - "type": "array", - "items": { - "type": "boolean" - }, - "default": [] - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "type": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - "ignoreTlsErrors": { - "type": "boolean", - "default": false - }, - "useAdvancedMatching": { - "type": "boolean", - "default": false - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": ["equal", "include", "regex"] - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "url": { - "type": "string", - "minLength": 1 - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean", - "default": true - }, - "interval": { - "type": "number", - "default": 60000 - }, - "uptimePercentage": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "secret": { - "type": "string" - }, - "cpuAlertThreshold": { - "type": "number", - "default": 100 - }, - "cpuAlertCounter": { - "type": "number", - "default": 5 - }, - "memoryAlertThreshold": { - "type": "number", - "default": 100 - }, - "memoryAlertCounter": { - "type": "number", - "default": 5 - }, - "diskAlertThreshold": { - "type": "number", - "default": 100 - }, - "diskAlertCounter": { - "type": "number", - "default": 5 - }, - "tempAlertThreshold": { - "type": "number", - "default": 100 - }, - "tempAlertCounter": { - "type": "number", - "default": 5 - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ], - "default": "" - }, - "strategy": { - "type": "string", - "enum": ["desktop", "mobile"] - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - } - ], - "default": null - }, - "geoCheckEnabled": { - "type": "boolean", - "default": false - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - }, - "default": [] - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000, - "default": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": ["name", "type", "url"] - }, - "minItems": 1 - } - }, - "required": ["monitors"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "imported": { - "type": "number" - } - }, - "required": ["imported"], - "additionalProperties": { - "nullable": true - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/games": { - "get": { - "tags": ["monitors"], - "summary": "List supported game-server types", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/monitors/{monitorId}": { - "get": { - "tags": ["monitors"], - "summary": "Get a monitor by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "patch": { - "tags": ["monitors"], - "summary": "Edit a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] - }, - "url": { - "type": "string" - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "interval": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "secret": { - "type": "string" - }, - "ignoreTlsErrors": { - "type": "boolean" - }, - "useAdvancedMatching": { - "type": "boolean" - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": ["equal", "include", "regex"] - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "port": { - "type": "number", - "minimum": 1, - "maximum": 65535 - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "strategy": { - "type": "string", - "enum": ["desktop", "mobile"] - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] - } - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["monitors"], - "summary": "Delete a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/notifications": { - "post": { - "tags": ["notifications"], - "summary": "Create a notification channel", - "description": "Create a notification channel of any supported type. The `type` field discriminates the body shape.", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/notifications/test/all": { - "post": { - "tags": ["notifications"], - "summary": "Send a test alert through every notification channel for the team", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitorId": { - "type": "string", - "minLength": 1 - } - }, - "required": ["monitorId"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/notifications/test": { - "post": { - "tags": ["notifications"], - "summary": "Send a test alert through a single notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - }, - "required": ["success"], - "additionalProperties": { - "nullable": true - } - } - }, - "required": ["success", "msg", "data"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/notifications/team": { - "get": { - "tags": ["notifications"], - "summary": "List notification channels for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/notifications/{id}": { - "get": { - "tags": ["notifications"], - "summary": "Get a notification channel by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["notifications"], - "summary": "Delete a notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "patch": { - "tags": ["notifications"], - "summary": "Edit a notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/queue/jobs": { - "get": { - "tags": ["queue"], - "summary": "List queued monitor jobs (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/queue/metrics": { - "get": { - "tags": ["queue"], - "summary": "Get queue runtime metrics (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/queue/all-metrics": { - "get": { - "tags": ["queue"], - "summary": "Get queue metrics across all monitors (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/queue/flush": { - "post": { - "tags": ["queue"], - "summary": "Flush the monitor job queue (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/settings": { - "get": { - "tags": ["settings"], - "summary": "Get application settings", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "patch": { - "tags": ["settings"], - "summary": "Update application settings (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "checkTTL": { - "type": "integer", - "minimum": 1, - "maximum": 366 - }, - "systemEmailPort": { - "type": "number", - "nullable": true - }, - "pagespeedApiKey": { - "type": "string", - "nullable": true - }, - "language": { - "type": "string" - }, - "timezone": { - "type": "string" - }, - "systemEmailHost": { - "type": "string", - "nullable": true - }, - "systemEmailAddress": { - "type": "string", - "nullable": true - }, - "systemEmailDisplayName": { - "type": "string", - "nullable": true, - "maxLength": 100 - }, - "systemEmailPassword": { - "type": "string", - "nullable": true - }, - "systemEmailUser": { - "type": "string", - "nullable": true - }, - "systemEmailConnectionHost": { - "type": "string", - "nullable": true - }, - "systemEmailTLSServername": { - "type": "string", - "nullable": true - }, - "showURL": { - "type": "boolean" - }, - "systemEmailSecure": { - "type": "boolean" - }, - "systemEmailPool": { - "type": "boolean" - }, - "systemEmailIgnoreTLS": { - "type": "boolean" - }, - "systemEmailRequireTLS": { - "type": "boolean" - }, - "systemEmailRejectUnauthorized": { - "type": "boolean" - }, - "globalThresholds": { - "type": "object", - "properties": { - "cpu": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "memory": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "disk": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "temperature": { - "type": "number", - "minimum": 1, - "maximum": 150 - } - } - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/settings/test-email": { - "post": { - "tags": ["settings"], - "summary": "Send a test email using current SMTP settings (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "to": { - "type": "string", - "minLength": 1 - }, - "systemEmailHost": { - "type": "string" - }, - "systemEmailPort": { - "type": "number" - }, - "systemEmailSecure": { - "type": "boolean" - }, - "systemEmailPool": { - "type": "boolean" - }, - "systemEmailAddress": { - "type": "string" - }, - "systemEmailDisplayName": { - "type": "string" - }, - "systemEmailPassword": { - "type": "string" - }, - "systemEmailUser": { - "type": "string" - }, - "systemEmailConnectionHost": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - }, - "systemEmailIgnoreTLS": { - "type": "boolean" - }, - "systemEmailRequireTLS": { - "type": "boolean" - }, - "systemEmailRejectUnauthorized": { - "type": "boolean" - }, - "systemEmailTLSServername": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [""] - } - ] - } - }, - "required": ["to"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/status-page/team": { - "get": { - "tags": ["status-page"], - "summary": "List status pages for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/status-page": { - "post": { - "tags": ["status-page"], - "summary": "Create a status page (logo upload optional)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "type": { - "anyOf": [ - { - "type": "string", - "enum": ["uptime", "infrastructure"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["uptime", "infrastructure"] - } - } - ] - }, - "companyName": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "pattern": "^[a-zA-Z0-9_-]+$" - }, - "timezone": { - "type": "string" - }, - "color": { - "type": "string" - }, - "monitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - }, - "minItems": 1 - }, - "subMonitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - } - }, - "deleteSubmonitors": { - "type": "boolean" - }, - "isPublished": { - "type": "boolean" - }, - "showCharts": { - "type": "boolean" - }, - "showUptimePercentage": { - "type": "boolean" - }, - "showAdminLoginLink": { - "type": "boolean" - }, - "showInfrastructure": { - "type": "boolean" - }, - "removeLogo": { - "anyOf": [ - { - "type": "string", - "enum": ["true"] - }, - { - "type": "string", - "enum": ["false"] - } - ] - }, - "theme": { - "type": "string", - "enum": ["refined", "modern", "bold", "editorial"] - }, - "themeMode": { - "type": "string", - "enum": ["auto", "light", "dark"] - }, - "logo": { - "type": "string", - "format": "binary" - } - }, - "required": ["type", "companyName", "url", "monitors", "isPublished", "showUptimePercentage", "logo"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/status-page/{id}": { - "put": { - "tags": ["status-page"], - "summary": "Update a status page (logo upload optional)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "type": { - "anyOf": [ - { - "type": "string", - "enum": ["uptime", "infrastructure"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["uptime", "infrastructure"] - } - } - ] - }, - "companyName": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "pattern": "^[a-zA-Z0-9_-]+$" - }, - "timezone": { - "type": "string" - }, - "color": { - "type": "string" - }, - "monitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - }, - "minItems": 1 - }, - "subMonitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - } - }, - "deleteSubmonitors": { - "type": "boolean" - }, - "isPublished": { - "type": "boolean" - }, - "showCharts": { - "type": "boolean" - }, - "showUptimePercentage": { - "type": "boolean" - }, - "showAdminLoginLink": { - "type": "boolean" - }, - "showInfrastructure": { - "type": "boolean" - }, - "removeLogo": { - "anyOf": [ - { - "type": "string", - "enum": ["true"] - }, - { - "type": "string", - "enum": ["false"] - } - ] - }, - "theme": { - "type": "string", - "enum": ["refined", "modern", "bold", "editorial"] - }, - "themeMode": { - "type": "string", - "enum": ["auto", "light", "dark"] - }, - "logo": { - "type": "string", - "format": "binary" - } - }, - "required": ["type", "companyName", "url", "monitors", "isPublished", "showUptimePercentage", "logo"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - }, - "delete": { - "tags": ["status-page"], - "summary": "Delete a status page", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - } - }, - "required": ["success", "msg"] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - }, - "/status-page/{url}": { - "get": { - "tags": ["status-page"], - "summary": "Get a public status page by its URL slug", - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "url", - "in": "path" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": ["uptime", "infrastructure"] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": ["uptime", "infrastructure"] - } - } - ] - }, - "required": true, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "timeFrame", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [true] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - }, - "404": { - "description": "Status page not found" - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [false] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": ["success", "msg"] - } - } - } - } - } - } - } - } + "openapi": "3.0.0", + "info": { + "title": "Checkmate API", + "version": "1.0.0", + "description": "Generated from Zod validation schemas. Source of truth: server/src/validation/*.ts" + }, + "servers": [ + { + "url": "/api/v1", + "description": "Current server" + } + ], + "tags": [ + { + "name": "auth", + "description": "Sign up, log in, password reset, and the authenticated user's profile." + }, + { + "name": "monitors", + "description": "Configure and inspect monitors (HTTP, port, ping, hardware, docker, game, gRPC) for the caller's team." + }, + { + "name": "checks", + "description": "Individual monitoring check results, including history, summaries, and bulk deletes." + }, + { + "name": "geo-checks", + "description": "Geographic check results for monitors with multi-region probing enabled." + }, + { + "name": "incidents", + "description": "Downtime incidents derived from monitor state changes, including filtering and CSV export." + }, + { + "name": "notifications", + "description": "Notification channels (email, webhook, Slack, Discord, PagerDuty, Matrix, Teams, Telegram, Pushover, Twilio) and test alerts." + }, + { + "name": "maintenance-window", + "description": "Scheduled maintenance windows during which monitors do not generate incidents or alerts." + }, + { + "name": "status-page", + "description": "Public status pages, their configuration, and the monitors they expose." + }, + { + "name": "settings", + "description": "Global application settings (admin/superadmin)." + }, + { + "name": "invite", + "description": "Team invitations and accepting them." + }, + { + "name": "queue", + "description": "Background job queue introspection and admin actions (admin/superadmin)." + }, + { + "name": "diagnostic", + "description": "System diagnostics for the running server (admin/superadmin)." + }, + { + "name": "logs", + "description": "Application logs for the running server (admin/superadmin)." + } + ], + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT" + } + }, + "schemas": { + "AuthPayload": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + }, + "token": { + "type": "string" + } + }, + "required": [ + "user" + ], + "example": { + "user": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": [ + "admin" + ], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + }, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + }, + "User": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "array", + "items": { + "type": "string" + } + }, + "teamId": { + "type": "string" + }, + "profileImage": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "_id", + "firstName", + "lastName", + "email", + "role", + "createdAt", + "updatedAt" + ], + "additionalProperties": { + "nullable": true + }, + "example": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": [ + "admin" + ], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + } + }, + "Incident": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789c" + }, + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "teamId": { + "type": "string", + "example": "65f1c2a4d8b9e01234567890" + }, + "startTime": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "endTime": { + "type": "string", + "nullable": true, + "example": "2026-04-15T03:34:00.000Z" + }, + "status": { + "type": "boolean", + "example": true, + "description": "true = resolved, false = ongoing" + }, + "message": { + "type": "string", + "nullable": true, + "example": "HTTP 503 from origin" + }, + "statusCode": { + "type": "number", + "nullable": true, + "example": 503 + }, + "resolutionType": { + "type": "string", + "nullable": true, + "enum": [ + "automatic", + "manual", + null + ], + "example": "automatic" + }, + "resolvedBy": { + "type": "string", + "nullable": true + }, + "resolvedByEmail": { + "type": "string", + "nullable": true + }, + "comment": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "updatedAt": { + "type": "string", + "example": "2026-04-15T03:34:00.000Z" + } + }, + "required": [ + "id", + "monitorId", + "teamId", + "startTime", + "endTime", + "status", + "resolutionType", + "createdAt", + "updatedAt" + ], + "additionalProperties": { + "nullable": true + } + }, + "IncidentSummary": { + "type": "object", + "properties": { + "total": { + "type": "number", + "example": 12 + }, + "totalActive": { + "type": "number", + "example": 1 + }, + "totalManualResolutions": { + "type": "number", + "example": 2 + }, + "totalAutomaticResolutions": { + "type": "number", + "example": 9 + }, + "avgResolutionTimeHours": { + "type": "number", + "example": 0.5 + }, + "topMonitor": { + "type": "object", + "nullable": true, + "properties": { + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "monitorName": { + "type": "string", + "nullable": true, + "example": "Marketing site" + }, + "incidentCount": { + "type": "number", + "example": 4 + } + }, + "required": [ + "monitorId", + "monitorName", + "incidentCount" + ] + }, + "latestIncidents": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IncidentSummaryItem" + } + } + }, + "required": [ + "total", + "totalActive", + "totalManualResolutions", + "totalAutomaticResolutions", + "avgResolutionTimeHours", + "topMonitor", + "latestIncidents" + ] + }, + "IncidentSummaryItem": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789c" + }, + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "monitorName": { + "type": "string", + "nullable": true, + "example": "Marketing site" + }, + "status": { + "type": "boolean", + "example": true + }, + "startTime": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "endTime": { + "type": "string", + "nullable": true, + "example": "2026-04-15T03:34:00.000Z" + }, + "resolutionType": { + "type": "string", + "nullable": true, + "enum": [ + "automatic", + "manual", + null + ], + "example": "automatic" + }, + "message": { + "type": "string", + "nullable": true, + "example": "HTTP 503 from origin" + }, + "statusCode": { + "type": "number", + "nullable": true, + "example": 503 + }, + "createdAt": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + } + }, + "required": [ + "id", + "monitorId", + "monitorName", + "status", + "startTime", + "endTime", + "resolutionType", + "message", + "statusCode", + "createdAt" + ] + }, + "Monitor": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + "url": { + "type": "string" + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "status": { + "type": "string", + "enum": [ + "up", + "down", + "paused", + "initializing", + "maintenance", + "breached" + ] + }, + "statusWindowSize": { + "type": "number" + }, + "statusWindowThreshold": { + "type": "number" + }, + "ignoreTlsErrors": { + "type": "boolean" + }, + "useAdvancedMatching": { + "type": "boolean" + }, + "jsonPath": { + "type": "string" + }, + "expectedValue": { + "type": "string" + }, + "matchMethod": { + "type": "string", + "enum": [ + "equal", + "include", + "regex" + ] + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "gameId": { + "type": "string" + }, + "grpcServiceName": { + "type": "string" + }, + "group": { + "type": "string", + "nullable": true + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + } + }, + "geoCheckInterval": { + "type": "number" + }, + "dnsServer": { + "type": "string" + }, + "dnsRecordType": { + "type": "string", + "enum": [ + "A", + "AAAA", + "CNAME", + "MX", + "TXT", + "NS" + ] + }, + "teamId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "_id", + "name", + "type", + "url", + "isActive", + "interval", + "status", + "statusWindowSize", + "statusWindowThreshold", + "ignoreTlsErrors", + "useAdvancedMatching", + "notifications", + "tags", + "cpuAlertThreshold", + "memoryAlertThreshold", + "diskAlertThreshold", + "tempAlertThreshold", + "selectedDisks", + "geoCheckEnabled", + "geoCheckLocations", + "geoCheckInterval", + "teamId", + "userId", + "createdAt", + "updatedAt" + ], + "additionalProperties": { + "nullable": true + }, + "example": { + "_id": "65f1c2a4d8b9e0123456789a", + "name": "Marketing site", + "description": "Production marketing site monitored from the EU region", + "type": "http", + "url": "https://www.example.com", + "port": 443, + "isActive": true, + "interval": 60000, + "status": "up", + "statusWindowSize": 5, + "statusWindowThreshold": 3, + "ignoreTlsErrors": false, + "useAdvancedMatching": false, + "notifications": [ + "65f1c2a4d8b9e0123456789b" + ], + "cpuAlertThreshold": 90, + "memoryAlertThreshold": 90, + "diskAlertThreshold": 90, + "tempAlertThreshold": 80, + "selectedDisks": [], + "geoCheckEnabled": false, + "geoCheckLocations": [], + "geoCheckInterval": 300000, + "teamId": "65f1c2a4d8b9e01234567890", + "userId": "65f1c2a4d8b9e01234567891", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + } + }, + "NotificationChannelBody": { + "oneOf": [ + { + "$ref": "#/components/schemas/EmailNotification" + }, + { + "$ref": "#/components/schemas/WebhookNotification" + }, + { + "$ref": "#/components/schemas/SlackNotification" + }, + { + "$ref": "#/components/schemas/DiscordNotification" + }, + { + "$ref": "#/components/schemas/PagerDutyNotification" + }, + { + "$ref": "#/components/schemas/MatrixNotification" + }, + { + "$ref": "#/components/schemas/TeamsNotification" + }, + { + "$ref": "#/components/schemas/TelegramNotification" + }, + { + "$ref": "#/components/schemas/PushoverNotification" + }, + { + "$ref": "#/components/schemas/TwilioNotification" + }, + { + "$ref": "#/components/schemas/NtfyNotification" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "email": "#/components/schemas/EmailNotification", + "webhook": "#/components/schemas/WebhookNotification", + "slack": "#/components/schemas/SlackNotification", + "discord": "#/components/schemas/DiscordNotification", + "pager_duty": "#/components/schemas/PagerDutyNotification", + "matrix": "#/components/schemas/MatrixNotification", + "teams": "#/components/schemas/TeamsNotification", + "telegram": "#/components/schemas/TelegramNotification", + "pushover": "#/components/schemas/PushoverNotification", + "twilio": "#/components/schemas/TwilioNotification", + "ntfy": "#/components/schemas/NtfyNotification" + } + } + }, + "EmailNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "email" + ] + }, + "address": { + "type": "string", + "format": "email" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + } + }, + "required": [ + "notificationName", + "type", + "address" + ], + "example": { + "notificationName": "Ops on-call email", + "type": "email", + "address": "alerts@example.com" + } + }, + "WebhookNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "webhook" + ] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + } + }, + "required": [ + "notificationName", + "type", + "address" + ], + "example": { + "notificationName": "Custom webhook", + "type": "webhook", + "address": "https://example.com/hooks/checkmate" + } + }, + "SlackNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "slack" + ] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + } + }, + "required": [ + "notificationName", + "type", + "address" + ], + "example": { + "notificationName": "#alerts", + "type": "slack", + "address": "https://hooks.slack.com/services/T000/B000/XXXX" + } + }, + "DiscordNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "discord" + ] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + } + }, + "required": [ + "notificationName", + "type", + "address" + ], + "example": { + "notificationName": "#status", + "type": "discord", + "address": "https://discord.com/api/webhooks/123/abc" + } + }, + "PagerDutyNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "pager_duty" + ] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + } + }, + "required": [ + "notificationName", + "type", + "address" + ], + "example": { + "notificationName": "PagerDuty primary", + "type": "pager_duty", + "address": "R01XXXXXXXXXXXXXXXXXXXXXXX" + } + }, + "MatrixNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "matrix" + ] + }, + "address": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "homeserverUrl": { + "type": "string", + "format": "uri" + }, + "roomId": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "notificationName", + "type", + "homeserverUrl", + "roomId", + "accessToken" + ], + "example": { + "notificationName": "Matrix room", + "type": "matrix", + "homeserverUrl": "https://matrix.example.com", + "roomId": "!abc123:example.com", + "accessToken": "syt_xxx" + } + }, + "TeamsNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "teams" + ] + }, + "address": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "notificationName", + "type", + "address" + ], + "example": { + "notificationName": "Teams ops channel", + "type": "teams", + "address": "https://outlook.office.com/webhook/..." + } + }, + "TelegramNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "telegram" + ] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "notificationName", + "type", + "address", + "accessToken" + ], + "example": { + "notificationName": "Telegram bot", + "type": "telegram", + "address": "-1001234567890", + "accessToken": "123456:ABC-DEF" + } + }, + "PushoverNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "pushover" + ] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "notificationName", + "type", + "address", + "accessToken" + ], + "example": { + "notificationName": "Pushover personal", + "type": "pushover", + "address": "u1234567890abcdef", + "accessToken": "a1234567890abcdef" + } + }, + "TwilioNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "twilio" + ] + }, + "accountSid": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + }, + "phone": { + "type": "string", + "minLength": 1 + }, + "twilioPhoneNumber": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "notificationName", + "type", + "accountSid", + "accessToken", + "phone", + "twilioPhoneNumber" + ], + "example": { + "notificationName": "Twilio SMS", + "type": "twilio", + "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "accessToken": "your-auth-token", + "phone": "+15551234567", + "twilioPhoneNumber": "+15557654321" + } + }, + "NtfyNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": [ + "ntfy" + ] + }, + "address": { + "type": "string", + "format": "uri" + }, + "topic": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "notificationName", + "type", + "address", + "topic" + ], + "example": { + "notificationName": "ntfy topic", + "type": "ntfy", + "address": "https://ntfy.sh", + "topic": "checkmate-alerts" + } + } + }, + "parameters": {} + }, + "paths": { + "/auth/register": { + "post": { + "tags": [ + "auth" + ], + "summary": "Register a new user (first user becomes superadmin)", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "profileImage": { + "type": "string", + "format": "binary" + }, + "inviteToken": { + "type": "string", + "default": "" + } + }, + "required": [ + "firstName", + "lastName", + "email", + "password", + "profileImage" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/AuthPayload" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/login": { + "post": { + "tags": [ + "auth" + ], + "summary": "Log in", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "email", + "password" + ] + }, + "example": { + "email": "ada@example.com", + "password": "S3cure!Passw0rd" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/AuthPayload" + } + }, + "required": [ + "success", + "msg", + "data" + ] + }, + "example": { + "success": true, + "msg": "OK", + "data": { + "user": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": [ + "admin" + ], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + }, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + } + } + } + }, + "401": { + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/recovery/request": { + "post": { + "tags": [ + "auth" + ], + "summary": "Request a password recovery email", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "example": { + "email": "ada@example.com" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/recovery/validate": { + "post": { + "tags": [ + "auth" + ], + "summary": "Validate a password recovery token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "recoveryToken": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "recoveryToken" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/recovery/reset": { + "post": { + "tags": [ + "auth" + ], + "summary": "Reset password using a recovery token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "recoveryToken": { + "type": "string", + "minLength": 1 + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "confirm": { + "type": "string" + } + }, + "required": [ + "recoveryToken", + "password" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/users/superadmin": { + "get": { + "tags": [ + "auth" + ], + "summary": "Check whether a superadmin user exists", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "superAdminExists": { + "type": "boolean" + } + }, + "required": [ + "superAdminExists" + ] + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/users": { + "get": { + "tags": [ + "auth" + ], + "summary": "List all users (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "post": { + "tags": [ + "auth" + ], + "summary": "Create a new user (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "user", + "admin", + "superadmin", + "demo" + ] + }, + "minItems": 1 + }, + "profileImage": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "firstName", + "lastName", + "email", + "password", + "role", + "profileImage" + ] + } + } + } + }, + "responses": { + "201": { + "description": "User created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/users/{userId}": { + "get": { + "tags": [ + "auth" + ], + "summary": "Get a user by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "404": { + "description": "User not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "patch": { + "tags": [ + "auth" + ], + "summary": "Edit a user (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "user", + "admin", + "superadmin", + "demo" + ] + }, + "minItems": 1 + } + }, + "required": [ + "firstName", + "lastName", + "role" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "auth" + ], + "summary": "Delete a user (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/users/{userId}/password": { + "patch": { + "tags": [ + "auth" + ], + "summary": "Change a user's password (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + } + }, + "required": [ + "password" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/auth/user": { + "patch": { + "tags": [ + "auth" + ], + "summary": "Edit the currently authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "profilePicture": { + "type": "string" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "newPassword": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "profileImage": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "profileImage" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "auth" + ], + "summary": "Delete the currently authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/checks/team/summary": { + "get": { + "tags": [ + "checks" + ], + "summary": "Aggregate check summary for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/checks/team": { + "get": { + "tags": [ + "checks" + ], + "summary": "List checks across the team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "all", + "up", + "down", + "resolve" + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "checks" + ], + "summary": "Delete all checks for the team (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "deletedCount": { + "type": "number" + } + }, + "required": [ + "deletedCount" + ] + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/checks/{monitorId}": { + "get": { + "tags": [ + "checks" + ], + "summary": "List checks for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "all", + "up", + "down", + "resolve" + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "checks" + ], + "summary": "Delete checks for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/diagnostic/system": { + "get": { + "tags": [ + "diagnostic" + ], + "summary": "Get system diagnostics (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/geo-checks/{monitorId}": { + "get": { + "tags": [ + "geo-checks" + ], + "summary": "Get geo check results for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "all", + "up", + "down", + "resolve" + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/incidents/team": { + "get": { + "tags": [ + "incidents" + ], + "summary": "List incidents for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ], + "default": "all" + }, + "required": false, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "integer", + "nullable": true, + "minimum": 0 + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "monitorId", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "manual", + "automatic" + ] + }, + "required": false, + "name": "resolutionType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Incident" + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/incidents/team/summary": { + "get": { + "tags": [ + "incidents" + ], + "summary": "Incident summary for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": false, + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/IncidentSummary" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/incidents/{incidentId}": { + "get": { + "tags": [ + "incidents" + ], + "summary": "Get an incident by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string" + }, + "required": true, + "name": "incidentId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "incident": { + "$ref": "#/components/schemas/Incident" + }, + "monitor": { + "nullable": true + }, + "user": { + "nullable": true + } + }, + "required": [ + "incident" + ] + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/incidents/{incidentId}/resolve": { + "put": { + "tags": [ + "incidents" + ], + "summary": "Manually resolve an incident (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string" + }, + "required": true, + "name": "incidentId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/invite/send": { + "post": { + "tags": [ + "invite" + ], + "summary": "Send an invite email (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "user", + "admin", + "superadmin", + "demo" + ] + }, + "minItems": 1 + }, + "teamId": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "email", + "role", + "teamId" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/invite/verify": { + "post": { + "tags": [ + "invite" + ], + "summary": "Verify an invite token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "token": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "token" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "role": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "email" + ], + "additionalProperties": { + "nullable": true + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/invite": { + "post": { + "tags": [ + "invite" + ], + "summary": "Create an invite token (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "user", + "admin", + "superadmin", + "demo" + ] + }, + "minItems": 1 + }, + "teamId": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "email", + "role", + "teamId" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + }, + "required": [ + "token" + ], + "additionalProperties": { + "nullable": true + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/logs": { + "get": { + "tags": [ + "logs" + ], + "summary": "Get application logs (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/maintenance-window": { + "post": { + "tags": [ + "maintenance-window" + ], + "summary": "Create one or more maintenance windows", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitors": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "name": { + "type": "string", + "minLength": 1 + }, + "active": { + "type": "boolean" + }, + "duration": { + "type": "number", + "minimum": 1 + }, + "durationUnit": { + "type": "string", + "enum": [ + "seconds", + "minutes", + "hours", + "days" + ] + }, + "start": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "end": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "repeat": { + "type": "number", + "minimum": 0 + }, + "expiry": { + "type": "string", + "nullable": true, + "format": "date-time" + } + }, + "required": [ + "monitors", + "name", + "duration", + "durationUnit", + "start", + "end", + "repeat" + ], + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/maintenance-window/team": { + "get": { + "tags": [ + "maintenance-window" + ], + "summary": "List maintenance windows for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "active", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "field", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": false, + "name": "order", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/maintenance-window/monitor/{monitorId}": { + "get": { + "tags": [ + "maintenance-window" + ], + "summary": "List maintenance windows for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/maintenance-window/{id}": { + "get": { + "tags": [ + "maintenance-window" + ], + "summary": "Get a maintenance window by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "patch": { + "tags": [ + "maintenance-window" + ], + "summary": "Edit a maintenance window", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "active": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "repeat": { + "type": "number" + }, + "start": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "end": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "expiry": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "monitors": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "duration": { + "type": "number" + }, + "durationUnit": { + "type": "string", + "enum": [ + "seconds", + "minutes", + "hours", + "days" + ] + } + }, + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "maintenance-window" + ], + "summary": "Delete a maintenance window", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/team": { + "get": { + "tags": [ + "monitors" + ], + "summary": "List monitors for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + } + } + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "required": false, + "name": "tags", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Monitor" + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/team/with-checks": { + "get": { + "tags": [ + "monitors" + ], + "summary": "List team monitors with their most recent checks (paginated)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "integer", + "nullable": true, + "minimum": 0 + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "field", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": false, + "name": "order", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + } + } + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "required": false, + "name": "tags", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "explain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/team/groups": { + "get": { + "tags": [ + "monitors" + ], + "summary": "List monitor groups for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/uptime/details/{monitorId}": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Get uptime details for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "normalize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/hardware/details/{monitorId}": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Get hardware metrics detail for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/pagespeed/details/{monitorId}": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Get PageSpeed detail for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/{monitorId}/geo-checks": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Get geo check results for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "required": false, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "recent", + "hour", + "day", + "week", + "month", + "all" + ] + }, + "required": false, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "numToDisplay", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "normalize", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/pause/{monitorId}": { + "post": { + "tags": [ + "monitors" + ], + "summary": "Toggle pause state for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/certificate/{monitorId}": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Get SSL certificate info for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "certificateDate": { + "type": "string" + } + }, + "required": [ + "certificateDate" + ] + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/notifications": { + "patch": { + "tags": [ + "monitors" + ], + "summary": "Bulk update notifications across monitors", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitorIds": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 100 + }, + "notificationIds": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 100 + }, + "action": { + "type": "string", + "enum": [ + "add", + "remove", + "set" + ] + } + }, + "required": [ + "monitorIds", + "notificationIds", + "action" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "modifiedCount": { + "type": "number" + } + }, + "required": [ + "modifiedCount" + ] + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors": { + "post": { + "tags": [ + "monitors" + ], + "summary": "Create a new monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "type": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "url": { + "type": "string", + "minLength": 1 + }, + "ignoreTlsErrors": { + "type": "boolean", + "default": false + }, + "useAdvancedMatching": { + "type": "boolean", + "default": false + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": [ + "equal", + "include", + "regex" + ] + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ], + "default": "" + }, + "strategy": { + "type": "string", + "enum": [ + "desktop", + "mobile" + ] + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + } + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": [ + "A", + "AAAA", + "CNAME", + "MX", + "TXT", + "NS" + ] + } + }, + "required": [ + "name", + "type", + "url" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Monitor created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "monitors" + ], + "summary": "Delete every monitor (superadmin only)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/demo": { + "post": { + "tags": [ + "monitors" + ], + "summary": "Insert preconfigured demo monitors", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "number" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/export/json": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Export all team monitors as JSON", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/import/json": { + "post": { + "tags": [ + "monitors" + ], + "summary": "Import monitors from JSON", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "status": { + "type": "string", + "enum": [ + "up", + "down", + "paused", + "initializing", + "maintenance", + "breached" + ], + "default": "initializing" + }, + "statusWindow": { + "type": "array", + "items": { + "type": "boolean" + }, + "default": [] + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "type": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + "ignoreTlsErrors": { + "type": "boolean", + "default": false + }, + "useAdvancedMatching": { + "type": "boolean", + "default": false + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": [ + "equal", + "include", + "regex" + ] + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "url": { + "type": "string", + "minLength": 1 + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean", + "default": true + }, + "interval": { + "type": "number", + "default": 60000 + }, + "uptimePercentage": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "secret": { + "type": "string" + }, + "cpuAlertThreshold": { + "type": "number", + "default": 100 + }, + "cpuAlertCounter": { + "type": "number", + "default": 5 + }, + "memoryAlertThreshold": { + "type": "number", + "default": 100 + }, + "memoryAlertCounter": { + "type": "number", + "default": 5 + }, + "diskAlertThreshold": { + "type": "number", + "default": 100 + }, + "diskAlertCounter": { + "type": "number", + "default": 5 + }, + "tempAlertThreshold": { + "type": "number", + "default": 100 + }, + "tempAlertCounter": { + "type": "number", + "default": 5 + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ], + "default": "" + }, + "strategy": { + "type": "string", + "enum": [ + "desktop", + "mobile" + ] + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + } + ], + "default": null + }, + "geoCheckEnabled": { + "type": "boolean", + "default": false + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + }, + "default": [] + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000, + "default": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": [ + "A", + "AAAA", + "CNAME", + "MX", + "TXT", + "NS" + ] + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "name", + "type", + "url" + ] + }, + "minItems": 1 + } + }, + "required": [ + "monitors" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "imported": { + "type": "number" + } + }, + "required": [ + "imported" + ], + "additionalProperties": { + "nullable": true + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/games": { + "get": { + "tags": [ + "monitors" + ], + "summary": "List supported game-server types", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/monitors/{monitorId}": { + "get": { + "tags": [ + "monitors" + ], + "summary": "Get a monitor by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "patch": { + "tags": [ + "monitors" + ], + "summary": "Edit a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "http", + "ping", + "pagespeed", + "hardware", + "docker", + "port", + "game", + "grpc", + "websocket", + "dns", + "unknown" + ] + }, + "url": { + "type": "string" + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "interval": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + }, + "ignoreTlsErrors": { + "type": "boolean" + }, + "useAdvancedMatching": { + "type": "boolean" + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": [ + "equal", + "include", + "regex" + ] + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "port": { + "type": "number", + "minimum": 1, + "maximum": 65535 + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "strategy": { + "type": "string", + "enum": [ + "desktop", + "mobile" + ] + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "EU", + "NA", + "AS", + "SA", + "AF", + "OC" + ] + } + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": [ + "A", + "AAAA", + "CNAME", + "MX", + "TXT", + "NS" + ] + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "monitors" + ], + "summary": "Delete a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/notifications": { + "post": { + "tags": [ + "notifications" + ], + "summary": "Create a notification channel", + "description": "Create a notification channel of any supported type. The `type` field discriminates the body shape.", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/notifications/test/all": { + "post": { + "tags": [ + "notifications" + ], + "summary": "Send a test alert through every notification channel for the team", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitorId": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "monitorId" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/notifications/test": { + "post": { + "tags": [ + "notifications" + ], + "summary": "Send a test alert through a single notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "additionalProperties": { + "nullable": true + } + } + }, + "required": [ + "success", + "msg", + "data" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/notifications/team": { + "get": { + "tags": [ + "notifications" + ], + "summary": "List notification channels for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/notifications/{id}": { + "get": { + "tags": [ + "notifications" + ], + "summary": "Get a notification channel by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "notifications" + ], + "summary": "Delete a notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "patch": { + "tags": [ + "notifications" + ], + "summary": "Edit a notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/queue/jobs": { + "get": { + "tags": [ + "queue" + ], + "summary": "List queued monitor jobs (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/queue/metrics": { + "get": { + "tags": [ + "queue" + ], + "summary": "Get queue runtime metrics (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/queue/all-metrics": { + "get": { + "tags": [ + "queue" + ], + "summary": "Get queue metrics across all monitors (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/queue/flush": { + "post": { + "tags": [ + "queue" + ], + "summary": "Flush the monitor job queue (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/settings": { + "get": { + "tags": [ + "settings" + ], + "summary": "Get application settings", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Update application settings (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "checkTTL": { + "type": "integer", + "minimum": 1, + "maximum": 366 + }, + "systemEmailPort": { + "type": "number", + "nullable": true + }, + "pagespeedApiKey": { + "type": "string", + "nullable": true + }, + "language": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "systemEmailHost": { + "type": "string", + "nullable": true + }, + "systemEmailAddress": { + "type": "string", + "nullable": true + }, + "systemEmailDisplayName": { + "type": "string", + "nullable": true, + "maxLength": 100 + }, + "systemEmailPassword": { + "type": "string", + "nullable": true + }, + "systemEmailUser": { + "type": "string", + "nullable": true + }, + "systemEmailConnectionHost": { + "type": "string", + "nullable": true + }, + "systemEmailTLSServername": { + "type": "string", + "nullable": true + }, + "showURL": { + "type": "boolean" + }, + "systemEmailSecure": { + "type": "boolean" + }, + "systemEmailPool": { + "type": "boolean" + }, + "systemEmailIgnoreTLS": { + "type": "boolean" + }, + "systemEmailRequireTLS": { + "type": "boolean" + }, + "systemEmailRejectUnauthorized": { + "type": "boolean" + }, + "globalThresholds": { + "type": "object", + "properties": { + "cpu": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "memory": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "disk": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "temperature": { + "type": "number", + "minimum": 1, + "maximum": 150 + } + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/settings/test-email": { + "post": { + "tags": [ + "settings" + ], + "summary": "Send a test email using current SMTP settings (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "to": { + "type": "string", + "minLength": 1 + }, + "systemEmailHost": { + "type": "string" + }, + "systemEmailPort": { + "type": "number" + }, + "systemEmailSecure": { + "type": "boolean" + }, + "systemEmailPool": { + "type": "boolean" + }, + "systemEmailAddress": { + "type": "string" + }, + "systemEmailDisplayName": { + "type": "string" + }, + "systemEmailPassword": { + "type": "string" + }, + "systemEmailUser": { + "type": "string" + }, + "systemEmailConnectionHost": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + }, + "systemEmailIgnoreTLS": { + "type": "boolean" + }, + "systemEmailRequireTLS": { + "type": "boolean" + }, + "systemEmailRejectUnauthorized": { + "type": "boolean" + }, + "systemEmailTLSServername": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [ + "" + ] + } + ] + } + }, + "required": [ + "to" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/status-page/team": { + "get": { + "tags": [ + "status-page" + ], + "summary": "List status pages for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/status-page": { + "post": { + "tags": [ + "status-page" + ], + "summary": "Create a status page (logo upload optional)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "type": { + "anyOf": [ + { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + } + } + ] + }, + "companyName": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "customDomain": { + "anyOf": [ + { + "type": "string", + "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" + }, + { + "nullable": true + } + ] + }, + "timezone": { + "type": "string" + }, + "color": { + "type": "string" + }, + "monitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1 + }, + "subMonitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + } + }, + "deleteSubmonitors": { + "type": "boolean" + }, + "isPublished": { + "type": "boolean" + }, + "showCharts": { + "type": "boolean" + }, + "showUptimePercentage": { + "type": "boolean" + }, + "showAdminLoginLink": { + "type": "boolean" + }, + "showInfrastructure": { + "type": "boolean" + }, + "removeLogo": { + "anyOf": [ + { + "type": "string", + "enum": [ + "true" + ] + }, + { + "type": "string", + "enum": [ + "false" + ] + } + ] + }, + "theme": { + "type": "string", + "enum": [ + "refined", + "modern", + "bold", + "editorial" + ] + }, + "themeMode": { + "type": "string", + "enum": [ + "auto", + "light", + "dark" + ] + }, + "logo": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "type", + "companyName", + "url", + "monitors", + "isPublished", + "showUptimePercentage", + "logo" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/status-page/{id}": { + "put": { + "tags": [ + "status-page" + ], + "summary": "Update a status page (logo upload optional)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "type": { + "anyOf": [ + { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + } + } + ] + }, + "companyName": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "customDomain": { + "anyOf": [ + { + "type": "string", + "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" + }, + { + "nullable": true + } + ] + }, + "timezone": { + "type": "string" + }, + "color": { + "type": "string" + }, + "monitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1 + }, + "subMonitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + } + }, + "deleteSubmonitors": { + "type": "boolean" + }, + "isPublished": { + "type": "boolean" + }, + "showCharts": { + "type": "boolean" + }, + "showUptimePercentage": { + "type": "boolean" + }, + "showAdminLoginLink": { + "type": "boolean" + }, + "showInfrastructure": { + "type": "boolean" + }, + "removeLogo": { + "anyOf": [ + { + "type": "string", + "enum": [ + "true" + ] + }, + { + "type": "string", + "enum": [ + "false" + ] + } + ] + }, + "theme": { + "type": "string", + "enum": [ + "refined", + "modern", + "bold", + "editorial" + ] + }, + "themeMode": { + "type": "string", + "enum": [ + "auto", + "light", + "dark" + ] + }, + "logo": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "type", + "companyName", + "url", + "monitors", + "isPublished", + "showUptimePercentage", + "logo" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "status-page" + ], + "summary": "Delete a status page", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + } + }, + "required": [ + "success", + "msg" + ] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/status-page/resolve": { + "get": { + "tags": [ + "status-page" + ], + "summary": "Resolve a published status page by custom domain", + "parameters": [ + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + } + } + ] + }, + "required": true, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "timeFrame", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "domain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "404": { + "description": "Status page not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + }, + "/status-page/{url}": { + "get": { + "tags": [ + "status-page" + ], + "summary": "Get a public status page by its URL slug", + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "url", + "in": "path" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "uptime", + "infrastructure" + ] + } + } + ] + }, + "required": true, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "timeFrame", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + true + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + }, + "404": { + "description": "Status page not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": [ + "success", + "msg" + ] + } + } + } + } + } + } + } + } } diff --git a/server/openapi/routes/statusPage.ts b/server/openapi/routes/statusPage.ts index ac315b31c..d17ab88f5 100644 --- a/server/openapi/routes/statusPage.ts +++ b/server/openapi/routes/statusPage.ts @@ -1,6 +1,11 @@ import { registry } from "../registry.js"; import { bearer, multipart, okJsonNoData, okUnknown, standardErrors } from "../helpers.js"; -import { createStatusPageBodyValidation, getStatusPageParamValidation, getStatusPageQueryValidation } from "@/validation/statusPageValidation.js"; +import { + createStatusPageBodyValidation, + getStatusPageParamValidation, + getStatusPageQueryValidation, + resolveStatusPageQueryValidation, +} from "@/validation/statusPageValidation.js"; const tags = ["status-page"]; @@ -33,6 +38,15 @@ registry.registerPath({ responses: { "200": okUnknown, ...standardErrors }, }); +registry.registerPath({ + method: "get", + path: "/status-page/resolve", + tags, + summary: "Resolve a published status page by custom domain", + request: { query: resolveStatusPageQueryValidation }, + responses: { "200": okUnknown, "404": { description: "Status page not found" }, "500": standardErrors["500"] }, +}); + registry.registerPath({ method: "get", path: "/status-page/{url}", diff --git a/server/src/app.ts b/server/src/app.ts index da1cd8ad9..02802fc83 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -12,6 +12,7 @@ import { setupRoutes } from "@/config/routes.js"; import { InitializedServices } from "@/config/services.js"; import { InitializedControllers } from "@/config/controllers.js"; import { EnvConfig } from "@/service/system/settingsService.js"; +import { createStatusPageCorsOrigin } from "@/middleware/statusPageCorsOrigin.js"; export const createApp = ({ services, @@ -33,7 +34,7 @@ export const createApp = ({ app.use( cors({ - origin: allowedOrigin, + origin: createStatusPageCorsOrigin(allowedOrigin, services.statusPagesRepository), methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS", allowedHeaders: ["Content-Type", "Authorization", "Accept-Language"], credentials: true, diff --git a/server/src/controllers/statusPageController.ts b/server/src/controllers/statusPageController.ts index 190c3a9fd..1a7ed2347 100644 --- a/server/src/controllers/statusPageController.ts +++ b/server/src/controllers/statusPageController.ts @@ -5,6 +5,7 @@ import { getStatusPageParamValidation, getStatusPageQueryValidation, imageValidation, + resolveStatusPageQueryValidation, } from "@/validation/statusPageValidation.js"; import { AppError } from "@/utils/AppError.js"; import { requireTeamId, requireUserId } from "@/controllers/controllerUtils.js"; @@ -12,6 +13,8 @@ import { IStatusPageService } from "@/service/business/statusPageService.js"; import { IMonitorsRepository } from "@/repositories/index.js"; import { ISettingsService } from "@/service/system/settingsService.js"; import { NormalizeData } from "@/utils/dataUtils.js"; +import { resolveStatusPageDomainFromRequest } from "@/utils/statusPageDomain.js"; +import type { StatusPage } from "@/types/statusPage.js"; const SERVICE_NAME = "statusPageController"; @@ -20,6 +23,7 @@ export interface IStatusPageController { createStatusPage(req: Request, res: Response, next: NextFunction): Promise; updateStatusPage(req: Request, res: Response, next: NextFunction): Promise; getStatusPageByUrl(req: Request, res: Response, next: NextFunction): Promise; + resolveStatusPageByDomain(req: Request, res: Response, next: NextFunction): Promise; getStatusPagesByTeamId(req: Request, res: Response, next: NextFunction): Promise; deleteStatusPage(req: Request, res: Response, next: NextFunction): Promise; } @@ -39,6 +43,41 @@ class StatusPageController implements IStatusPageController { return StatusPageController.SERVICE_NAME; } + private buildStatusPagePayload = async (statusPage: StatusPage, req: Request) => { + if (!statusPage.isPublished) { + const teamId = requireTeamId(req?.user?.teamId); + if (statusPage.teamId !== teamId) { + throw new AppError({ message: "Forbidden", status: 403 }); + } + } + + const settings = await this.settingsService.getDBSettings(); + const showURL = settings.showURL; + + const monitors = await this.monitorsRepository.findByIds(statusPage.monitors); + const monitorOrder = new Map(statusPage.monitors.map((id, index) => [id, index])); + const sortedMonitors = [...monitors].sort((a, b) => { + const orderA = monitorOrder.get(a.id) ?? Number.MAX_SAFE_INTEGER; + const orderB = monitorOrder.get(b.id) ?? Number.MAX_SAFE_INTEGER; + return orderA - orderB; + }); + + const normalizedMonitors = sortedMonitors.map((monitor) => { + const normalizedChecks = NormalizeData(monitor.recentChecks, 10, 100); + if (!showURL) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { url, port, secret, notifications, ...rest } = monitor; + return { ...rest, checks: normalizedChecks }; + } + return { ...monitor, checks: normalizedChecks }; + }); + + return { + statusPage, + monitors: normalizedMonitors, + }; + }; + createStatusPage = async (req: Request, res: Response, next: NextFunction) => { try { createStatusPageBodyValidation.parse(req.body); @@ -96,47 +135,44 @@ class StatusPageController implements IStatusPageController { } const statusPage = await this.statusPageService.getStatusPageByUrl(req.params.url as string); + const data = await this.buildStatusPagePayload(statusPage, req); - if (!statusPage.isPublished) { - const teamId = requireTeamId(req?.user?.teamId); - if (statusPage.teamId !== teamId) { - throw new AppError({ message: "Forbidden", status: 403 }); - } - } - - const settings = await this.settingsService.getDBSettings(); - const showURL = settings.showURL; - - const monitors = await this.monitorsRepository.findByIds(statusPage.monitors); - // Sort monitors according to the order in statusPage.monitors - const monitorOrder = new Map(statusPage.monitors.map((id, index) => [id, index])); - const sortedMonitors = [...monitors].sort((a, b) => { - const orderA = monitorOrder.get(a.id) ?? Number.MAX_SAFE_INTEGER; - const orderB = monitorOrder.get(b.id) ?? Number.MAX_SAFE_INTEGER; - return orderA - orderB; - }); - - const normalizedMonitors = sortedMonitors.map((monitor) => { - const normalizedChecks = NormalizeData(monitor.recentChecks, 10, 100); - if (!showURL) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { url, port, secret, notifications, ...rest } = monitor; - return { ...rest, checks: normalizedChecks }; - } - return { ...monitor, checks: normalizedChecks }; - }); return res.status(200).json({ success: true, msg: "Status page retrieved successfully", - data: { - statusPage, - monitors: normalizedMonitors, - }, + data, }); } catch (error) { next(error); } }; + + resolveStatusPageByDomain = async (req: Request, res: Response, next: NextFunction) => { + try { + resolveStatusPageQueryValidation.parse(req.query); + + const domain = resolveStatusPageDomainFromRequest(req.hostname, req.query.domain as string | undefined); + if (!domain) { + throw new AppError({ message: "Domain is required", status: 400 }); + } + + const statusPage = await this.statusPageService.getStatusPageByCustomDomain(domain); + if (!statusPage.isPublished) { + throw new AppError({ message: "Status page not found", status: 404 }); + } + + const data = await this.buildStatusPagePayload(statusPage, req); + + return res.status(200).json({ + success: true, + msg: "Status page retrieved successfully", + data, + }); + } catch (error) { + next(error); + } + }; + getStatusPagesByTeamId = async (req: Request, res: Response, next: NextFunction) => { try { const teamId = requireTeamId(req.user?.teamId); diff --git a/server/src/db/models/StatusPage.ts b/server/src/db/models/StatusPage.ts index 0b6451492..358b0dde5 100644 --- a/server/src/db/models/StatusPage.ts +++ b/server/src/db/models/StatusPage.ts @@ -65,6 +65,14 @@ const StatusPageSchema = new Schema( required: true, default: "", }, + customDomain: { + type: String, + default: null, + lowercase: true, + trim: true, + sparse: true, + unique: true, + }, timezone: { type: String, }, diff --git a/server/src/middleware/statusPageCorsOrigin.ts b/server/src/middleware/statusPageCorsOrigin.ts new file mode 100644 index 000000000..0ec25c1c0 --- /dev/null +++ b/server/src/middleware/statusPageCorsOrigin.ts @@ -0,0 +1,39 @@ +import type { CorsOptions } from "cors"; +import type { IStatusPagesRepository } from "@/repositories/index.js"; +import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; + +export const createStatusPageCorsOrigin = (clientHost: string, statusPagesRepository: IStatusPagesRepository): CorsOptions["origin"] => { + return (origin, callback) => { + if (!origin) { + callback(null, true); + return; + } + + if (origin === clientHost) { + callback(null, true); + return; + } + + let customDomain: string | null = null; + try { + customDomain = normalizeStatusPageDomain(new URL(origin).hostname); + } catch { + callback(null, false); + return; + } + + if (!customDomain) { + callback(null, false); + return; + } + + statusPagesRepository + .findByCustomDomain(customDomain) + .then((statusPage) => { + callback(null, statusPage.isPublished ? origin : false); + }) + .catch(() => { + callback(null, false); + }); + }; +}; diff --git a/server/src/repositories/status-pages/IStatusPagesRepository.ts b/server/src/repositories/status-pages/IStatusPagesRepository.ts index c901b3c6d..d4ca85f78 100644 --- a/server/src/repositories/status-pages/IStatusPagesRepository.ts +++ b/server/src/repositories/status-pages/IStatusPagesRepository.ts @@ -5,6 +5,7 @@ export interface IStatusPagesRepository { create(userId: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise; // single fetch findByUrl(url: string): Promise; + findByCustomDomain(customDomain: string): Promise; findByTeamId(teamId: string): Promise; // collection fetch // update diff --git a/server/src/repositories/status-pages/MongoStatusPagesRepository.ts b/server/src/repositories/status-pages/MongoStatusPagesRepository.ts index 3f4630eb1..785cfd139 100644 --- a/server/src/repositories/status-pages/MongoStatusPagesRepository.ts +++ b/server/src/repositories/status-pages/MongoStatusPagesRepository.ts @@ -3,6 +3,7 @@ import { type StatusPageDocument, StatusPageModel } from "@/db/models/StatusPage import type { StatusPage, StatusPageLogo, StatusPageLogoDocument } from "@/types/statusPage.js"; import mongoose from "mongoose"; import { AppError } from "@/utils/AppError.js"; +import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; // Type for update data that can include document-level fields (Buffer for logo) type StatusPageUpdateData = Partial> & { @@ -47,6 +48,7 @@ class MongoStatusPagesRepository implements IStatusPagesRepository { type: doc.type, companyName: doc.companyName, url: doc.url, + customDomain: doc.customDomain ?? null, timezone: doc.timezone ?? undefined, color: doc.color, monitors: this.mapIdArray(doc.monitors), @@ -74,10 +76,11 @@ class MongoStatusPagesRepository implements IStatusPagesRepository { }; create = async (userId: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise => { - const { logo, ...restData } = data; + const { logo, customDomain, ...restData } = data; void logo; const statusPage = new StatusPageModel({ ...restData, + customDomain: normalizeStatusPageDomain(customDomain), userId, teamId, }); @@ -102,6 +105,21 @@ class MongoStatusPagesRepository implements IStatusPagesRepository { // Get status page }; + findByCustomDomain = async (customDomain: string): Promise => { + const normalizedDomain = normalizeStatusPageDomain(customDomain); + if (!normalizedDomain) { + throw new AppError({ message: "Status page not found", status: 404 }); + } + + const statusPage = await StatusPageModel.findOne({ + customDomain: normalizedDomain, + }); + if (!statusPage) { + throw new AppError({ message: "Status page not found", status: 404 }); + } + return this.toEntity(statusPage); + }; + findByTeamId = async (teamId: string): Promise => { const statusPages = await StatusPageModel.find({ teamId }); return this.mapDocuments(statusPages); @@ -113,9 +131,12 @@ class MongoStatusPagesRepository implements IStatusPagesRepository { image: Express.Multer.File | undefined, patch: Partial & { removeLogo?: string } ): Promise => { - const { logo, removeLogo, ...restPatch } = patch; + const { logo, removeLogo, customDomain, ...restPatch } = patch; void logo; const updateData: StatusPageUpdateData = { ...restPatch }; + if (customDomain !== undefined) { + updateData.customDomain = normalizeStatusPageDomain(customDomain); + } if (image) { updateData.logo = { data: image.buffer as Buffer, diff --git a/server/src/routes/statusPageRoute.ts b/server/src/routes/statusPageRoute.ts index 871a67300..29cdab609 100755 --- a/server/src/routes/statusPageRoute.ts +++ b/server/src/routes/statusPageRoute.ts @@ -19,6 +19,7 @@ class StatusPageRoutes { this.router.post("/", upload.single("logo"), verifyJWT, this.statusPageController.createStatusPage); this.router.put("/:id", upload.single("logo"), verifyJWT, this.statusPageController.updateStatusPage); + this.router.get("/resolve", this.statusPageController.resolveStatusPageByDomain); this.router.get("/:url", verifyStatusPageAccess, this.statusPageController.getStatusPageByUrl); this.router.delete("/:id", verifyJWT, this.statusPageController.deleteStatusPage); } diff --git a/server/src/service/business/statusPageService.ts b/server/src/service/business/statusPageService.ts index 179461f25..1b77991f3 100644 --- a/server/src/service/business/statusPageService.ts +++ b/server/src/service/business/statusPageService.ts @@ -1,10 +1,13 @@ import { type IStatusPagesRepository } from "@/repositories/index.js"; import { ISettingsService } from "@/service/system/settingsService.js"; import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE, StatusPage } from "@/types/index.js"; +import { AppError } from "@/utils/AppError.js"; +import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; export interface IStatusPageService { createStatusPage(userId: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise; getStatusPageByUrl(url: string): Promise; + getStatusPageByCustomDomain(customDomain: string): Promise; getStatusPagesByTeamId(teamId: string): Promise; updateStatusPage(id: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise; @@ -19,6 +22,30 @@ export class StatusPageService implements IStatusPageService { this.settingsService = settingsService; } + private assertCustomDomainAllowed = (customDomain: string | null | undefined) => { + if (!customDomain) { + return; + } + + const clientHost = normalizeStatusPageDomain(this.settingsService.getSettings().clientHost); + if (clientHost && customDomain === clientHost) { + throw new AppError({ + message: "Custom domain cannot match the Checkmate instance host", + status: 400, + }); + } + }; + + private normalizeCustomDomainInput = (data: Partial): Partial => { + if (!("customDomain" in data)) { + return data; + } + + const customDomain = normalizeStatusPageDomain(data.customDomain); + this.assertCustomDomainAllowed(customDomain); + return { ...data, customDomain }; + }; + private withoutThemeFields = (data: Partial): Partial => { const { theme: _theme, themeMode: _themeMode, ...rest } = data; return rest; @@ -42,7 +69,8 @@ export class StatusPageService implements IStatusPageService { image: Express.Multer.File | undefined, data: Partial ): Promise => { - const created = await this.statusPagesRepository.create(userId, teamId, image, this.normalizeInput(data)); + const normalizedData = this.normalizeCustomDomainInput(this.normalizeInput(data)); + const created = await this.statusPagesRepository.create(userId, teamId, image, normalizedData); return this.normalizeTheme(created); }; @@ -51,13 +79,19 @@ export class StatusPageService implements IStatusPageService { return this.normalizeTheme(statusPage); }; + getStatusPageByCustomDomain = async (customDomain: string): Promise => { + const statusPage = await this.statusPagesRepository.findByCustomDomain(customDomain); + return this.normalizeTheme(statusPage); + }; + getStatusPagesByTeamId = async (teamId: string): Promise => { const statusPages = await this.statusPagesRepository.findByTeamId(teamId); return statusPages.map((sp) => this.normalizeTheme(sp)); }; updateStatusPage = async (id: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise => { - const updated = await this.statusPagesRepository.updateById(id, teamId, image, this.normalizeInput(data)); + const normalizedData = this.normalizeCustomDomainInput(this.normalizeInput(data)); + const updated = await this.statusPagesRepository.updateById(id, teamId, image, normalizedData); return this.normalizeTheme(updated); }; diff --git a/server/src/types/statusPage.ts b/server/src/types/statusPage.ts index 0ef4d72a9..db08b7398 100644 --- a/server/src/types/statusPage.ts +++ b/server/src/types/statusPage.ts @@ -26,6 +26,7 @@ export interface StatusPage { type: StatusPageType[]; companyName: string; url: string; + customDomain?: string | null; timezone?: string; color: string; monitors: string[]; diff --git a/server/src/utils/statusPageDomain.ts b/server/src/utils/statusPageDomain.ts new file mode 100644 index 000000000..ec730a806 --- /dev/null +++ b/server/src/utils/statusPageDomain.ts @@ -0,0 +1,29 @@ +export const normalizeStatusPageDomain = (value?: string | null): string | null => { + if (typeof value !== "string") { + return null; + } + + const trimmed = value.trim().toLowerCase(); + if (!trimmed) { + return null; + } + + // Strip scheme, path, and port if a full URL was pasted. + const withoutScheme = trimmed.replace(/^https?:\/\//, ""); + const hostname = withoutScheme.split("/")[0]?.split(":")[0] ?? ""; + + return hostname || null; +}; + +export const resolveStatusPageDomainFromRequest = (hostHeader?: string | null, queryDomain?: string | null): string | null => { + const fromQuery = normalizeStatusPageDomain(queryDomain); + if (fromQuery) { + return fromQuery; + } + + if (!hostHeader) { + return null; + } + + return normalizeStatusPageDomain(hostHeader.split(":")[0]); +}; diff --git a/server/src/validation/statusPageValidation.ts b/server/src/validation/statusPageValidation.ts index 6a42d340c..8d7e8edf9 100644 --- a/server/src/validation/statusPageValidation.ts +++ b/server/src/validation/statusPageValidation.ts @@ -1,6 +1,7 @@ import { z } from "zod"; -import { booleanCoercion } from "./shared.js"; +import { booleanCoercion, dnsHostnameRegex } from "./shared.js"; import { StatusPageTypes, StatusPageThemes, StatusPageThemeModes } from "@/types/statusPage.js"; +import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; //**************************************** // Status Page Validations @@ -15,6 +16,20 @@ export const getStatusPageQueryValidation = z.object({ timeFrame: z.coerce.number().optional(), }); +export const resolveStatusPageQueryValidation = getStatusPageQueryValidation.extend({ + domain: z.string().optional(), +}); + +const customDomainValidation = z.preprocess( + (val) => { + if (val === undefined || val === null) { + return undefined; + } + return normalizeStatusPageDomain(String(val)); + }, + z.union([z.string().regex(dnsHostnameRegex, "Enter a valid domain name (e.g. status.example.com)"), z.null()]).optional() +); + export const createStatusPageBodyValidation = z .object({ type: z.union([z.enum(StatusPageTypes), z.array(z.enum(StatusPageTypes))]).transform((val) => (Array.isArray(val) ? val : [val])), @@ -22,6 +37,7 @@ export const createStatusPageBodyValidation = z url: z.string().regex(/^[a-zA-Z0-9_-]+$/, { message: "URL can only contain letters, numbers, underscores, and hyphens", }), + customDomain: customDomainValidation, timezone: z.string().optional(), color: z.string().optional(), monitors: z.array(z.string().regex(/^[0-9a-fA-F]{24}$/, "Must be a valid monitor ID")).min(1, "At least one monitor is required"), diff --git a/server/test/unit/services/statusPageService.test.ts b/server/test/unit/services/statusPageService.test.ts index 2deac9897..49879cc94 100644 --- a/server/test/unit/services/statusPageService.test.ts +++ b/server/test/unit/services/statusPageService.test.ts @@ -26,20 +26,22 @@ const createRepo = () => ({ create: jest.fn().mockResolvedValue(makeStatusPage()), findByUrl: jest.fn().mockResolvedValue(makeStatusPage()), + findByCustomDomain: jest.fn().mockResolvedValue(makeStatusPage()), findByTeamId: jest.fn().mockResolvedValue([makeStatusPage()]), updateById: jest.fn().mockResolvedValue(makeStatusPage()), deleteById: jest.fn().mockResolvedValue(makeStatusPage()), removeMonitorFromStatusPages: jest.fn().mockResolvedValue(1), }) as unknown as jest.Mocked; -const createSettingsService = (themesEnabled: boolean) => +const createSettingsService = (themesEnabled: boolean, clientHost = "http://localhost:5173") => ({ areStatusPageThemesEnabled: jest.fn().mockReturnValue(themesEnabled), + getSettings: jest.fn().mockReturnValue({ clientHost }), }) as unknown as jest.Mocked; -const createService = (themesEnabled = true) => { +const createService = (themesEnabled = true, clientHost = "http://localhost:5173") => { const repo = createRepo(); - const settingsService = createSettingsService(themesEnabled); + const settingsService = createSettingsService(themesEnabled, clientHost); const service = new StatusPageService(repo, settingsService); return { service, repo, settingsService }; }; @@ -99,6 +101,41 @@ describe("StatusPageService", () => { }); }); + describe("getStatusPageByCustomDomain", () => { + it("delegates to repository", async () => { + const { service, repo } = createService(true); + + const result = await service.getStatusPageByCustomDomain("status.example.com"); + + expect(repo.findByCustomDomain).toHaveBeenCalledWith("status.example.com"); + expect(result).toEqual(makeStatusPage()); + }); + }); + + describe("createStatusPage custom domain validation", () => { + it("rejects custom domains that match the Checkmate instance host", async () => { + const { service } = createService(true, "https://checkmate.example.com"); + + await expect( + service.createStatusPage("user-1", "team-1", undefined, { + customDomain: "checkmate.example.com", + }) + ).rejects.toMatchObject({ + status: 400, + }); + }); + + it("normalizes custom domains before create", async () => { + const { service, repo } = createService(true); + + await service.createStatusPage("user-1", "team-1", undefined, { + customDomain: "https://Status.Example.COM", + }); + + expect(repo.create).toHaveBeenCalledWith("user-1", "team-1", undefined, expect.objectContaining({ customDomain: "status.example.com" })); + }); + }); + describe("getStatusPagesByTeamId", () => { it("delegates to repository", async () => { const { service, repo } = createService(true); diff --git a/server/test/unit/utils/statusPageDomain.test.ts b/server/test/unit/utils/statusPageDomain.test.ts new file mode 100644 index 000000000..37cd03633 --- /dev/null +++ b/server/test/unit/utils/statusPageDomain.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from "@jest/globals"; +import { normalizeStatusPageDomain, resolveStatusPageDomainFromRequest } from "../../../src/utils/statusPageDomain.ts"; + +describe("statusPageDomain utils", () => { + describe("normalizeStatusPageDomain", () => { + it("returns null for empty values", () => { + expect(normalizeStatusPageDomain("")).toBeNull(); + expect(normalizeStatusPageDomain(" ")).toBeNull(); + expect(normalizeStatusPageDomain(null)).toBeNull(); + }); + + it("normalizes hostnames", () => { + expect(normalizeStatusPageDomain("Status.Example.COM")).toBe("status.example.com"); + expect(normalizeStatusPageDomain("https://status.example.com/path")).toBe("status.example.com"); + expect(normalizeStatusPageDomain("status.example.com:443")).toBe("status.example.com"); + }); + }); + + describe("resolveStatusPageDomainFromRequest", () => { + it("prefers the query domain over the host header", () => { + expect(resolveStatusPageDomainFromRequest("checkmate.example.com", "status.example.com")).toBe("status.example.com"); + }); + + it("falls back to the host header", () => { + expect(resolveStatusPageDomainFromRequest("status.example.com:8443", undefined)).toBe("status.example.com"); + }); + }); +}); From e390bd764f9106134001ee5f195ff38f3fd5e9af Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Sun, 7 Jun 2026 22:42:58 -0400 Subject: [PATCH 2/9] Format openapi.json for CI format-check. --- server/openapi.json | 24555 +++++++++++++++++++----------------------- 1 file changed, 11111 insertions(+), 13444 deletions(-) diff --git a/server/openapi.json b/server/openapi.json index d1900f322..60d2d3026 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -1,13446 +1,11113 @@ { - "openapi": "3.0.0", - "info": { - "title": "Checkmate API", - "version": "1.0.0", - "description": "Generated from Zod validation schemas. Source of truth: server/src/validation/*.ts" - }, - "servers": [ - { - "url": "/api/v1", - "description": "Current server" - } - ], - "tags": [ - { - "name": "auth", - "description": "Sign up, log in, password reset, and the authenticated user's profile." - }, - { - "name": "monitors", - "description": "Configure and inspect monitors (HTTP, port, ping, hardware, docker, game, gRPC) for the caller's team." - }, - { - "name": "checks", - "description": "Individual monitoring check results, including history, summaries, and bulk deletes." - }, - { - "name": "geo-checks", - "description": "Geographic check results for monitors with multi-region probing enabled." - }, - { - "name": "incidents", - "description": "Downtime incidents derived from monitor state changes, including filtering and CSV export." - }, - { - "name": "notifications", - "description": "Notification channels (email, webhook, Slack, Discord, PagerDuty, Matrix, Teams, Telegram, Pushover, Twilio) and test alerts." - }, - { - "name": "maintenance-window", - "description": "Scheduled maintenance windows during which monitors do not generate incidents or alerts." - }, - { - "name": "status-page", - "description": "Public status pages, their configuration, and the monitors they expose." - }, - { - "name": "settings", - "description": "Global application settings (admin/superadmin)." - }, - { - "name": "invite", - "description": "Team invitations and accepting them." - }, - { - "name": "queue", - "description": "Background job queue introspection and admin actions (admin/superadmin)." - }, - { - "name": "diagnostic", - "description": "System diagnostics for the running server (admin/superadmin)." - }, - { - "name": "logs", - "description": "Application logs for the running server (admin/superadmin)." - } - ], - "components": { - "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT" - } - }, - "schemas": { - "AuthPayload": { - "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - }, - "token": { - "type": "string" - } - }, - "required": [ - "user" - ], - "example": { - "user": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": [ - "admin" - ], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - }, - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "User": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "email": { - "type": "string" - }, - "role": { - "type": "array", - "items": { - "type": "string" - } - }, - "teamId": { - "type": "string" - }, - "profileImage": { - "type": "string", - "nullable": true - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "_id", - "firstName", - "lastName", - "email", - "role", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - }, - "example": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": [ - "admin" - ], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - } - }, - "Incident": { - "type": "object", - "properties": { - "id": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789c" - }, - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "teamId": { - "type": "string", - "example": "65f1c2a4d8b9e01234567890" - }, - "startTime": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "endTime": { - "type": "string", - "nullable": true, - "example": "2026-04-15T03:34:00.000Z" - }, - "status": { - "type": "boolean", - "example": true, - "description": "true = resolved, false = ongoing" - }, - "message": { - "type": "string", - "nullable": true, - "example": "HTTP 503 from origin" - }, - "statusCode": { - "type": "number", - "nullable": true, - "example": 503 - }, - "resolutionType": { - "type": "string", - "nullable": true, - "enum": [ - "automatic", - "manual", - null - ], - "example": "automatic" - }, - "resolvedBy": { - "type": "string", - "nullable": true - }, - "resolvedByEmail": { - "type": "string", - "nullable": true - }, - "comment": { - "type": "string", - "nullable": true - }, - "createdAt": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "updatedAt": { - "type": "string", - "example": "2026-04-15T03:34:00.000Z" - } - }, - "required": [ - "id", - "monitorId", - "teamId", - "startTime", - "endTime", - "status", - "resolutionType", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - } - }, - "IncidentSummary": { - "type": "object", - "properties": { - "total": { - "type": "number", - "example": 12 - }, - "totalActive": { - "type": "number", - "example": 1 - }, - "totalManualResolutions": { - "type": "number", - "example": 2 - }, - "totalAutomaticResolutions": { - "type": "number", - "example": 9 - }, - "avgResolutionTimeHours": { - "type": "number", - "example": 0.5 - }, - "topMonitor": { - "type": "object", - "nullable": true, - "properties": { - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "monitorName": { - "type": "string", - "nullable": true, - "example": "Marketing site" - }, - "incidentCount": { - "type": "number", - "example": 4 - } - }, - "required": [ - "monitorId", - "monitorName", - "incidentCount" - ] - }, - "latestIncidents": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncidentSummaryItem" - } - } - }, - "required": [ - "total", - "totalActive", - "totalManualResolutions", - "totalAutomaticResolutions", - "avgResolutionTimeHours", - "topMonitor", - "latestIncidents" - ] - }, - "IncidentSummaryItem": { - "type": "object", - "properties": { - "id": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789c" - }, - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "monitorName": { - "type": "string", - "nullable": true, - "example": "Marketing site" - }, - "status": { - "type": "boolean", - "example": true - }, - "startTime": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "endTime": { - "type": "string", - "nullable": true, - "example": "2026-04-15T03:34:00.000Z" - }, - "resolutionType": { - "type": "string", - "nullable": true, - "enum": [ - "automatic", - "manual", - null - ], - "example": "automatic" - }, - "message": { - "type": "string", - "nullable": true, - "example": "HTTP 503 from origin" - }, - "statusCode": { - "type": "number", - "nullable": true, - "example": 503 - }, - "createdAt": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - } - }, - "required": [ - "id", - "monitorId", - "monitorName", - "status", - "startTime", - "endTime", - "resolutionType", - "message", - "statusCode", - "createdAt" - ] - }, - "Monitor": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "url": { - "type": "string" - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean" - }, - "interval": { - "type": "number" - }, - "status": { - "type": "string", - "enum": [ - "up", - "down", - "paused", - "initializing", - "maintenance", - "breached" - ] - }, - "statusWindowSize": { - "type": "number" - }, - "statusWindowThreshold": { - "type": "number" - }, - "ignoreTlsErrors": { - "type": "boolean" - }, - "useAdvancedMatching": { - "type": "boolean" - }, - "jsonPath": { - "type": "string" - }, - "expectedValue": { - "type": "string" - }, - "matchMethod": { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "secret": { - "type": "string" - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "gameId": { - "type": "string" - }, - "grpcServiceName": { - "type": "string" - }, - "group": { - "type": "string", - "nullable": true - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - }, - "geoCheckInterval": { - "type": "number" - }, - "dnsServer": { - "type": "string" - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - }, - "teamId": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "_id", - "name", - "type", - "url", - "isActive", - "interval", - "status", - "statusWindowSize", - "statusWindowThreshold", - "ignoreTlsErrors", - "useAdvancedMatching", - "notifications", - "tags", - "cpuAlertThreshold", - "memoryAlertThreshold", - "diskAlertThreshold", - "tempAlertThreshold", - "selectedDisks", - "geoCheckEnabled", - "geoCheckLocations", - "geoCheckInterval", - "teamId", - "userId", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - }, - "example": { - "_id": "65f1c2a4d8b9e0123456789a", - "name": "Marketing site", - "description": "Production marketing site monitored from the EU region", - "type": "http", - "url": "https://www.example.com", - "port": 443, - "isActive": true, - "interval": 60000, - "status": "up", - "statusWindowSize": 5, - "statusWindowThreshold": 3, - "ignoreTlsErrors": false, - "useAdvancedMatching": false, - "notifications": [ - "65f1c2a4d8b9e0123456789b" - ], - "cpuAlertThreshold": 90, - "memoryAlertThreshold": 90, - "diskAlertThreshold": 90, - "tempAlertThreshold": 80, - "selectedDisks": [], - "geoCheckEnabled": false, - "geoCheckLocations": [], - "geoCheckInterval": 300000, - "teamId": "65f1c2a4d8b9e01234567890", - "userId": "65f1c2a4d8b9e01234567891", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - } - }, - "NotificationChannelBody": { - "oneOf": [ - { - "$ref": "#/components/schemas/EmailNotification" - }, - { - "$ref": "#/components/schemas/WebhookNotification" - }, - { - "$ref": "#/components/schemas/SlackNotification" - }, - { - "$ref": "#/components/schemas/DiscordNotification" - }, - { - "$ref": "#/components/schemas/PagerDutyNotification" - }, - { - "$ref": "#/components/schemas/MatrixNotification" - }, - { - "$ref": "#/components/schemas/TeamsNotification" - }, - { - "$ref": "#/components/schemas/TelegramNotification" - }, - { - "$ref": "#/components/schemas/PushoverNotification" - }, - { - "$ref": "#/components/schemas/TwilioNotification" - }, - { - "$ref": "#/components/schemas/NtfyNotification" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "email": "#/components/schemas/EmailNotification", - "webhook": "#/components/schemas/WebhookNotification", - "slack": "#/components/schemas/SlackNotification", - "discord": "#/components/schemas/DiscordNotification", - "pager_duty": "#/components/schemas/PagerDutyNotification", - "matrix": "#/components/schemas/MatrixNotification", - "teams": "#/components/schemas/TeamsNotification", - "telegram": "#/components/schemas/TelegramNotification", - "pushover": "#/components/schemas/PushoverNotification", - "twilio": "#/components/schemas/TwilioNotification", - "ntfy": "#/components/schemas/NtfyNotification" - } - } - }, - "EmailNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "email" - ] - }, - "address": { - "type": "string", - "format": "email" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "Ops on-call email", - "type": "email", - "address": "alerts@example.com" - } - }, - "WebhookNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "webhook" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "Custom webhook", - "type": "webhook", - "address": "https://example.com/hooks/checkmate" - } - }, - "SlackNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "slack" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "#alerts", - "type": "slack", - "address": "https://hooks.slack.com/services/T000/B000/XXXX" - } - }, - "DiscordNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "discord" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "#status", - "type": "discord", - "address": "https://discord.com/api/webhooks/123/abc" - } - }, - "PagerDutyNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "pager_duty" - ] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "PagerDuty primary", - "type": "pager_duty", - "address": "R01XXXXXXXXXXXXXXXXXXXXXXX" - } - }, - "MatrixNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "matrix" - ] - }, - "address": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "homeserverUrl": { - "type": "string", - "format": "uri" - }, - "roomId": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "homeserverUrl", - "roomId", - "accessToken" - ], - "example": { - "notificationName": "Matrix room", - "type": "matrix", - "homeserverUrl": "https://matrix.example.com", - "roomId": "!abc123:example.com", - "accessToken": "syt_xxx" - } - }, - "TeamsNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "teams" - ] - }, - "address": { - "type": "string", - "format": "uri" - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "Teams ops channel", - "type": "teams", - "address": "https://outlook.office.com/webhook/..." - } - }, - "TelegramNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "telegram" - ] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "address", - "accessToken" - ], - "example": { - "notificationName": "Telegram bot", - "type": "telegram", - "address": "-1001234567890", - "accessToken": "123456:ABC-DEF" - } - }, - "PushoverNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "pushover" - ] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "address", - "accessToken" - ], - "example": { - "notificationName": "Pushover personal", - "type": "pushover", - "address": "u1234567890abcdef", - "accessToken": "a1234567890abcdef" - } - }, - "TwilioNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "twilio" - ] - }, - "accountSid": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - }, - "phone": { - "type": "string", - "minLength": 1 - }, - "twilioPhoneNumber": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "accountSid", - "accessToken", - "phone", - "twilioPhoneNumber" - ], - "example": { - "notificationName": "Twilio SMS", - "type": "twilio", - "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "accessToken": "your-auth-token", - "phone": "+15551234567", - "twilioPhoneNumber": "+15557654321" - } - }, - "NtfyNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "ntfy" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "topic": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "address", - "topic" - ], - "example": { - "notificationName": "ntfy topic", - "type": "ntfy", - "address": "https://ntfy.sh", - "topic": "checkmate-alerts" - } - } - }, - "parameters": {} - }, - "paths": { - "/auth/register": { - "post": { - "tags": [ - "auth" - ], - "summary": "Register a new user (first user becomes superadmin)", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "profileImage": { - "type": "string", - "format": "binary" - }, - "inviteToken": { - "type": "string", - "default": "" - } - }, - "required": [ - "firstName", - "lastName", - "email", - "password", - "profileImage" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/AuthPayload" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/login": { - "post": { - "tags": [ - "auth" - ], - "summary": "Log in", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "email", - "password" - ] - }, - "example": { - "email": "ada@example.com", - "password": "S3cure!Passw0rd" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/AuthPayload" - } - }, - "required": [ - "success", - "msg", - "data" - ] - }, - "example": { - "success": true, - "msg": "OK", - "data": { - "user": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": [ - "admin" - ], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - }, - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - } - } - } - }, - "401": { - "description": "Invalid credentials", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/recovery/request": { - "post": { - "tags": [ - "auth" - ], - "summary": "Request a password recovery email", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - } - }, - "required": [ - "email" - ] - }, - "example": { - "email": "ada@example.com" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/recovery/validate": { - "post": { - "tags": [ - "auth" - ], - "summary": "Validate a password recovery token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "recoveryToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "recoveryToken" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/recovery/reset": { - "post": { - "tags": [ - "auth" - ], - "summary": "Reset password using a recovery token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "recoveryToken": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "confirm": { - "type": "string" - } - }, - "required": [ - "recoveryToken", - "password" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users/superadmin": { - "get": { - "tags": [ - "auth" - ], - "summary": "Check whether a superadmin user exists", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "superAdminExists": { - "type": "boolean" - } - }, - "required": [ - "superAdminExists" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users": { - "get": { - "tags": [ - "auth" - ], - "summary": "List all users (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "post": { - "tags": [ - "auth" - ], - "summary": "Create a new user (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - }, - "profileImage": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "firstName", - "lastName", - "email", - "password", - "role", - "profileImage" - ] - } - } - } - }, - "responses": { - "201": { - "description": "User created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users/{userId}": { - "get": { - "tags": [ - "auth" - ], - "summary": "Get a user by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "404": { - "description": "User not found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "auth" - ], - "summary": "Edit a user (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - } - }, - "required": [ - "firstName", - "lastName", - "role" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "auth" - ], - "summary": "Delete a user (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users/{userId}/password": { - "patch": { - "tags": [ - "auth" - ], - "summary": "Change a user's password (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - } - }, - "required": [ - "password" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/user": { - "patch": { - "tags": [ - "auth" - ], - "summary": "Edit the currently authenticated user", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "profilePicture": { - "type": "string" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "newPassword": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "profileImage": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "profileImage" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "auth" - ], - "summary": "Delete the currently authenticated user", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/checks/team/summary": { - "get": { - "tags": [ - "checks" - ], - "summary": "Aggregate check summary for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/checks/team": { - "get": { - "tags": [ - "checks" - ], - "summary": "List checks across the team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "all", - "up", - "down", - "resolve" - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "checks" - ], - "summary": "Delete all checks for the team (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "deletedCount": { - "type": "number" - } - }, - "required": [ - "deletedCount" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/checks/{monitorId}": { - "get": { - "tags": [ - "checks" - ], - "summary": "List checks for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "all", - "up", - "down", - "resolve" - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "checks" - ], - "summary": "Delete checks for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/diagnostic/system": { - "get": { - "tags": [ - "diagnostic" - ], - "summary": "Get system diagnostics (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/geo-checks/{monitorId}": { - "get": { - "tags": [ - "geo-checks" - ], - "summary": "Get geo check results for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "all", - "up", - "down", - "resolve" - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/team": { - "get": { - "tags": [ - "incidents" - ], - "summary": "List incidents for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ], - "default": "all" - }, - "required": false, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "integer", - "nullable": true, - "minimum": 0 - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "monitorId", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "manual", - "automatic" - ] - }, - "required": false, - "name": "resolutionType", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Incident" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/team/summary": { - "get": { - "tags": [ - "incidents" - ], - "summary": "Incident summary for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": false, - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/IncidentSummary" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/{incidentId}": { - "get": { - "tags": [ - "incidents" - ], - "summary": "Get an incident by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string" - }, - "required": true, - "name": "incidentId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "incident": { - "$ref": "#/components/schemas/Incident" - }, - "monitor": { - "nullable": true - }, - "user": { - "nullable": true - } - }, - "required": [ - "incident" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/{incidentId}/resolve": { - "put": { - "tags": [ - "incidents" - ], - "summary": "Manually resolve an incident (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string" - }, - "required": true, - "name": "incidentId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/invite/send": { - "post": { - "tags": [ - "invite" - ], - "summary": "Send an invite email (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - }, - "teamId": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "email", - "role", - "teamId" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/invite/verify": { - "post": { - "tags": [ - "invite" - ], - "summary": "Verify an invite token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "token": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "token" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "role": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "email" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/invite": { - "post": { - "tags": [ - "invite" - ], - "summary": "Create an invite token (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - }, - "teamId": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "email", - "role", - "teamId" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "token": { - "type": "string" - } - }, - "required": [ - "token" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/logs": { - "get": { - "tags": [ - "logs" - ], - "summary": "Get application logs (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window": { - "post": { - "tags": [ - "maintenance-window" - ], - "summary": "Create one or more maintenance windows", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitors": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "name": { - "type": "string", - "minLength": 1 - }, - "active": { - "type": "boolean" - }, - "duration": { - "type": "number", - "minimum": 1 - }, - "durationUnit": { - "type": "string", - "enum": [ - "seconds", - "minutes", - "hours", - "days" - ] - }, - "start": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "end": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "repeat": { - "type": "number", - "minimum": 0 - }, - "expiry": { - "type": "string", - "nullable": true, - "format": "date-time" - } - }, - "required": [ - "monitors", - "name", - "duration", - "durationUnit", - "start", - "end", - "repeat" - ], - "additionalProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window/team": { - "get": { - "tags": [ - "maintenance-window" - ], - "summary": "List maintenance windows for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "active", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "field", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": false, - "name": "order", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window/monitor/{monitorId}": { - "get": { - "tags": [ - "maintenance-window" - ], - "summary": "List maintenance windows for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window/{id}": { - "get": { - "tags": [ - "maintenance-window" - ], - "summary": "Get a maintenance window by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "maintenance-window" - ], - "summary": "Edit a maintenance window", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "active": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "repeat": { - "type": "number" - }, - "start": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "end": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "expiry": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "monitors": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "duration": { - "type": "number" - }, - "durationUnit": { - "type": "string", - "enum": [ - "seconds", - "minutes", - "hours", - "days" - ] - } - }, - "additionalProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "maintenance-window" - ], - "summary": "Delete a maintenance window", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/team": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List monitors for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - } - } - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "required": false, - "name": "tags", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Monitor" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/team/with-checks": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List team monitors with their most recent checks (paginated)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "integer", - "nullable": true, - "minimum": 0 - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "field", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": false, - "name": "order", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - } - } - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "required": false, - "name": "tags", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "explain", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/team/groups": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List monitor groups for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/uptime/details/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get uptime details for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "normalize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/hardware/details/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get hardware metrics detail for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/pagespeed/details/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get PageSpeed detail for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/{monitorId}/geo-checks": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get geo check results for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": false, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "numToDisplay", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "normalize", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/pause/{monitorId}": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Toggle pause state for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/certificate/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get SSL certificate info for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "certificateDate": { - "type": "string" - } - }, - "required": [ - "certificateDate" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/notifications": { - "patch": { - "tags": [ - "monitors" - ], - "summary": "Bulk update notifications across monitors", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitorIds": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1, - "maxItems": 100 - }, - "notificationIds": { - "type": "array", - "items": { - "type": "string" - }, - "maxItems": 100 - }, - "action": { - "type": "string", - "enum": [ - "add", - "remove", - "set" - ] - } - }, - "required": [ - "monitorIds", - "notificationIds", - "action" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "modifiedCount": { - "type": "number" - } - }, - "required": [ - "modifiedCount" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Create a new monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "name": { - "type": "string", - "minLength": 1 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "url": { - "type": "string", - "minLength": 1 - }, - "ignoreTlsErrors": { - "type": "boolean", - "default": false - }, - "useAdvancedMatching": { - "type": "boolean", - "default": false - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean" - }, - "interval": { - "type": "number" - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "secret": { - "type": "string" - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ], - "default": "" - }, - "strategy": { - "type": "string", - "enum": [ - "desktop", - "mobile" - ] - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - } - }, - "required": [ - "name", - "type", - "url" - ] - } - } - } - }, - "responses": { - "200": { - "description": "Monitor created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "monitors" - ], - "summary": "Delete every monitor (superadmin only)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/demo": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Insert preconfigured demo monitors", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "number" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/export/json": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Export all team monitors as JSON", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/import/json": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Import monitors from JSON", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "teamId": { - "type": "string" - }, - "name": { - "type": "string", - "minLength": 1 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "status": { - "type": "string", - "enum": [ - "up", - "down", - "paused", - "initializing", - "maintenance", - "breached" - ], - "default": "initializing" - }, - "statusWindow": { - "type": "array", - "items": { - "type": "boolean" - }, - "default": [] - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "ignoreTlsErrors": { - "type": "boolean", - "default": false - }, - "useAdvancedMatching": { - "type": "boolean", - "default": false - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "url": { - "type": "string", - "minLength": 1 - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean", - "default": true - }, - "interval": { - "type": "number", - "default": 60000 - }, - "uptimePercentage": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "secret": { - "type": "string" - }, - "cpuAlertThreshold": { - "type": "number", - "default": 100 - }, - "cpuAlertCounter": { - "type": "number", - "default": 5 - }, - "memoryAlertThreshold": { - "type": "number", - "default": 100 - }, - "memoryAlertCounter": { - "type": "number", - "default": 5 - }, - "diskAlertThreshold": { - "type": "number", - "default": 100 - }, - "diskAlertCounter": { - "type": "number", - "default": 5 - }, - "tempAlertThreshold": { - "type": "number", - "default": 100 - }, - "tempAlertCounter": { - "type": "number", - "default": 5 - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ], - "default": "" - }, - "strategy": { - "type": "string", - "enum": [ - "desktop", - "mobile" - ] - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - } - ], - "default": null - }, - "geoCheckEnabled": { - "type": "boolean", - "default": false - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - "default": [] - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000, - "default": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "name", - "type", - "url" - ] - }, - "minItems": 1 - } - }, - "required": [ - "monitors" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "imported": { - "type": "number" - } - }, - "required": [ - "imported" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/games": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List supported game-server types", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get a monitor by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "monitors" - ], - "summary": "Edit a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "url": { - "type": "string" - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "interval": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "secret": { - "type": "string" - }, - "ignoreTlsErrors": { - "type": "boolean" - }, - "useAdvancedMatching": { - "type": "boolean" - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "port": { - "type": "number", - "minimum": 1, - "maximum": 65535 - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "strategy": { - "type": "string", - "enum": [ - "desktop", - "mobile" - ] - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "monitors" - ], - "summary": "Delete a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications": { - "post": { - "tags": [ - "notifications" - ], - "summary": "Create a notification channel", - "description": "Create a notification channel of any supported type. The `type` field discriminates the body shape.", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/test/all": { - "post": { - "tags": [ - "notifications" - ], - "summary": "Send a test alert through every notification channel for the team", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitorId": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "monitorId" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/test": { - "post": { - "tags": [ - "notifications" - ], - "summary": "Send a test alert through a single notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - }, - "required": [ - "success" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/team": { - "get": { - "tags": [ - "notifications" - ], - "summary": "List notification channels for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/{id}": { - "get": { - "tags": [ - "notifications" - ], - "summary": "Get a notification channel by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "notifications" - ], - "summary": "Delete a notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "notifications" - ], - "summary": "Edit a notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/jobs": { - "get": { - "tags": [ - "queue" - ], - "summary": "List queued monitor jobs (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/metrics": { - "get": { - "tags": [ - "queue" - ], - "summary": "Get queue runtime metrics (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/all-metrics": { - "get": { - "tags": [ - "queue" - ], - "summary": "Get queue metrics across all monitors (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/flush": { - "post": { - "tags": [ - "queue" - ], - "summary": "Flush the monitor job queue (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/settings": { - "get": { - "tags": [ - "settings" - ], - "summary": "Get application settings", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "settings" - ], - "summary": "Update application settings (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "checkTTL": { - "type": "integer", - "minimum": 1, - "maximum": 366 - }, - "systemEmailPort": { - "type": "number", - "nullable": true - }, - "pagespeedApiKey": { - "type": "string", - "nullable": true - }, - "language": { - "type": "string" - }, - "timezone": { - "type": "string" - }, - "systemEmailHost": { - "type": "string", - "nullable": true - }, - "systemEmailAddress": { - "type": "string", - "nullable": true - }, - "systemEmailDisplayName": { - "type": "string", - "nullable": true, - "maxLength": 100 - }, - "systemEmailPassword": { - "type": "string", - "nullable": true - }, - "systemEmailUser": { - "type": "string", - "nullable": true - }, - "systemEmailConnectionHost": { - "type": "string", - "nullable": true - }, - "systemEmailTLSServername": { - "type": "string", - "nullable": true - }, - "showURL": { - "type": "boolean" - }, - "systemEmailSecure": { - "type": "boolean" - }, - "systemEmailPool": { - "type": "boolean" - }, - "systemEmailIgnoreTLS": { - "type": "boolean" - }, - "systemEmailRequireTLS": { - "type": "boolean" - }, - "systemEmailRejectUnauthorized": { - "type": "boolean" - }, - "globalThresholds": { - "type": "object", - "properties": { - "cpu": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "memory": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "disk": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "temperature": { - "type": "number", - "minimum": 1, - "maximum": 150 - } - } - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/settings/test-email": { - "post": { - "tags": [ - "settings" - ], - "summary": "Send a test email using current SMTP settings (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "to": { - "type": "string", - "minLength": 1 - }, - "systemEmailHost": { - "type": "string" - }, - "systemEmailPort": { - "type": "number" - }, - "systemEmailSecure": { - "type": "boolean" - }, - "systemEmailPool": { - "type": "boolean" - }, - "systemEmailAddress": { - "type": "string" - }, - "systemEmailDisplayName": { - "type": "string" - }, - "systemEmailPassword": { - "type": "string" - }, - "systemEmailUser": { - "type": "string" - }, - "systemEmailConnectionHost": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "systemEmailIgnoreTLS": { - "type": "boolean" - }, - "systemEmailRequireTLS": { - "type": "boolean" - }, - "systemEmailRejectUnauthorized": { - "type": "boolean" - }, - "systemEmailTLSServername": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "to" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/team": { - "get": { - "tags": [ - "status-page" - ], - "summary": "List status pages for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page": { - "post": { - "tags": [ - "status-page" - ], - "summary": "Create a status page (logo upload optional)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "type": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "companyName": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "pattern": "^[a-zA-Z0-9_-]+$" - }, - "customDomain": { - "anyOf": [ - { - "type": "string", - "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" - }, - { - "nullable": true - } - ] - }, - "timezone": { - "type": "string" - }, - "color": { - "type": "string" - }, - "monitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - }, - "minItems": 1 - }, - "subMonitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - } - }, - "deleteSubmonitors": { - "type": "boolean" - }, - "isPublished": { - "type": "boolean" - }, - "showCharts": { - "type": "boolean" - }, - "showUptimePercentage": { - "type": "boolean" - }, - "showAdminLoginLink": { - "type": "boolean" - }, - "showInfrastructure": { - "type": "boolean" - }, - "removeLogo": { - "anyOf": [ - { - "type": "string", - "enum": [ - "true" - ] - }, - { - "type": "string", - "enum": [ - "false" - ] - } - ] - }, - "theme": { - "type": "string", - "enum": [ - "refined", - "modern", - "bold", - "editorial" - ] - }, - "themeMode": { - "type": "string", - "enum": [ - "auto", - "light", - "dark" - ] - }, - "logo": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "type", - "companyName", - "url", - "monitors", - "isPublished", - "showUptimePercentage", - "logo" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/{id}": { - "put": { - "tags": [ - "status-page" - ], - "summary": "Update a status page (logo upload optional)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "type": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "companyName": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "pattern": "^[a-zA-Z0-9_-]+$" - }, - "customDomain": { - "anyOf": [ - { - "type": "string", - "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" - }, - { - "nullable": true - } - ] - }, - "timezone": { - "type": "string" - }, - "color": { - "type": "string" - }, - "monitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - }, - "minItems": 1 - }, - "subMonitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - } - }, - "deleteSubmonitors": { - "type": "boolean" - }, - "isPublished": { - "type": "boolean" - }, - "showCharts": { - "type": "boolean" - }, - "showUptimePercentage": { - "type": "boolean" - }, - "showAdminLoginLink": { - "type": "boolean" - }, - "showInfrastructure": { - "type": "boolean" - }, - "removeLogo": { - "anyOf": [ - { - "type": "string", - "enum": [ - "true" - ] - }, - { - "type": "string", - "enum": [ - "false" - ] - } - ] - }, - "theme": { - "type": "string", - "enum": [ - "refined", - "modern", - "bold", - "editorial" - ] - }, - "themeMode": { - "type": "string", - "enum": [ - "auto", - "light", - "dark" - ] - }, - "logo": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "type", - "companyName", - "url", - "monitors", - "isPublished", - "showUptimePercentage", - "logo" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "status-page" - ], - "summary": "Delete a status page", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/resolve": { - "get": { - "tags": [ - "status-page" - ], - "summary": "Resolve a published status page by custom domain", - "parameters": [ - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "required": true, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "timeFrame", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "domain", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "404": { - "description": "Status page not found" - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/{url}": { - "get": { - "tags": [ - "status-page" - ], - "summary": "Get a public status page by its URL slug", - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "url", - "in": "path" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "required": true, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "timeFrame", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "404": { - "description": "Status page not found" - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - } - } + "openapi": "3.0.0", + "info": { + "title": "Checkmate API", + "version": "1.0.0", + "description": "Generated from Zod validation schemas. Source of truth: server/src/validation/*.ts" + }, + "servers": [ + { + "url": "/api/v1", + "description": "Current server" + } + ], + "tags": [ + { + "name": "auth", + "description": "Sign up, log in, password reset, and the authenticated user's profile." + }, + { + "name": "monitors", + "description": "Configure and inspect monitors (HTTP, port, ping, hardware, docker, game, gRPC) for the caller's team." + }, + { + "name": "checks", + "description": "Individual monitoring check results, including history, summaries, and bulk deletes." + }, + { + "name": "geo-checks", + "description": "Geographic check results for monitors with multi-region probing enabled." + }, + { + "name": "incidents", + "description": "Downtime incidents derived from monitor state changes, including filtering and CSV export." + }, + { + "name": "notifications", + "description": "Notification channels (email, webhook, Slack, Discord, PagerDuty, Matrix, Teams, Telegram, Pushover, Twilio) and test alerts." + }, + { + "name": "maintenance-window", + "description": "Scheduled maintenance windows during which monitors do not generate incidents or alerts." + }, + { + "name": "status-page", + "description": "Public status pages, their configuration, and the monitors they expose." + }, + { + "name": "settings", + "description": "Global application settings (admin/superadmin)." + }, + { + "name": "invite", + "description": "Team invitations and accepting them." + }, + { + "name": "queue", + "description": "Background job queue introspection and admin actions (admin/superadmin)." + }, + { + "name": "diagnostic", + "description": "System diagnostics for the running server (admin/superadmin)." + }, + { + "name": "logs", + "description": "Application logs for the running server (admin/superadmin)." + } + ], + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT" + } + }, + "schemas": { + "AuthPayload": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + }, + "token": { + "type": "string" + } + }, + "required": ["user"], + "example": { + "user": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": ["admin"], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + }, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + }, + "User": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "array", + "items": { + "type": "string" + } + }, + "teamId": { + "type": "string" + }, + "profileImage": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": ["_id", "firstName", "lastName", "email", "role", "createdAt", "updatedAt"], + "additionalProperties": { + "nullable": true + }, + "example": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": ["admin"], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + } + }, + "Incident": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789c" + }, + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "teamId": { + "type": "string", + "example": "65f1c2a4d8b9e01234567890" + }, + "startTime": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "endTime": { + "type": "string", + "nullable": true, + "example": "2026-04-15T03:34:00.000Z" + }, + "status": { + "type": "boolean", + "example": true, + "description": "true = resolved, false = ongoing" + }, + "message": { + "type": "string", + "nullable": true, + "example": "HTTP 503 from origin" + }, + "statusCode": { + "type": "number", + "nullable": true, + "example": 503 + }, + "resolutionType": { + "type": "string", + "nullable": true, + "enum": ["automatic", "manual", null], + "example": "automatic" + }, + "resolvedBy": { + "type": "string", + "nullable": true + }, + "resolvedByEmail": { + "type": "string", + "nullable": true + }, + "comment": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "updatedAt": { + "type": "string", + "example": "2026-04-15T03:34:00.000Z" + } + }, + "required": ["id", "monitorId", "teamId", "startTime", "endTime", "status", "resolutionType", "createdAt", "updatedAt"], + "additionalProperties": { + "nullable": true + } + }, + "IncidentSummary": { + "type": "object", + "properties": { + "total": { + "type": "number", + "example": 12 + }, + "totalActive": { + "type": "number", + "example": 1 + }, + "totalManualResolutions": { + "type": "number", + "example": 2 + }, + "totalAutomaticResolutions": { + "type": "number", + "example": 9 + }, + "avgResolutionTimeHours": { + "type": "number", + "example": 0.5 + }, + "topMonitor": { + "type": "object", + "nullable": true, + "properties": { + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "monitorName": { + "type": "string", + "nullable": true, + "example": "Marketing site" + }, + "incidentCount": { + "type": "number", + "example": 4 + } + }, + "required": ["monitorId", "monitorName", "incidentCount"] + }, + "latestIncidents": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IncidentSummaryItem" + } + } + }, + "required": [ + "total", + "totalActive", + "totalManualResolutions", + "totalAutomaticResolutions", + "avgResolutionTimeHours", + "topMonitor", + "latestIncidents" + ] + }, + "IncidentSummaryItem": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789c" + }, + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "monitorName": { + "type": "string", + "nullable": true, + "example": "Marketing site" + }, + "status": { + "type": "boolean", + "example": true + }, + "startTime": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "endTime": { + "type": "string", + "nullable": true, + "example": "2026-04-15T03:34:00.000Z" + }, + "resolutionType": { + "type": "string", + "nullable": true, + "enum": ["automatic", "manual", null], + "example": "automatic" + }, + "message": { + "type": "string", + "nullable": true, + "example": "HTTP 503 from origin" + }, + "statusCode": { + "type": "number", + "nullable": true, + "example": 503 + }, + "createdAt": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + } + }, + "required": ["id", "monitorId", "monitorName", "status", "startTime", "endTime", "resolutionType", "message", "statusCode", "createdAt"] + }, + "Monitor": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "url": { + "type": "string" + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "status": { + "type": "string", + "enum": ["up", "down", "paused", "initializing", "maintenance", "breached"] + }, + "statusWindowSize": { + "type": "number" + }, + "statusWindowThreshold": { + "type": "number" + }, + "ignoreTlsErrors": { + "type": "boolean" + }, + "useAdvancedMatching": { + "type": "boolean" + }, + "jsonPath": { + "type": "string" + }, + "expectedValue": { + "type": "string" + }, + "matchMethod": { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "gameId": { + "type": "string" + }, + "grpcServiceName": { + "type": "string" + }, + "group": { + "type": "string", + "nullable": true + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + }, + "geoCheckInterval": { + "type": "number" + }, + "dnsServer": { + "type": "string" + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + }, + "teamId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "_id", + "name", + "type", + "url", + "isActive", + "interval", + "status", + "statusWindowSize", + "statusWindowThreshold", + "ignoreTlsErrors", + "useAdvancedMatching", + "notifications", + "tags", + "cpuAlertThreshold", + "memoryAlertThreshold", + "diskAlertThreshold", + "tempAlertThreshold", + "selectedDisks", + "geoCheckEnabled", + "geoCheckLocations", + "geoCheckInterval", + "teamId", + "userId", + "createdAt", + "updatedAt" + ], + "additionalProperties": { + "nullable": true + }, + "example": { + "_id": "65f1c2a4d8b9e0123456789a", + "name": "Marketing site", + "description": "Production marketing site monitored from the EU region", + "type": "http", + "url": "https://www.example.com", + "port": 443, + "isActive": true, + "interval": 60000, + "status": "up", + "statusWindowSize": 5, + "statusWindowThreshold": 3, + "ignoreTlsErrors": false, + "useAdvancedMatching": false, + "notifications": ["65f1c2a4d8b9e0123456789b"], + "cpuAlertThreshold": 90, + "memoryAlertThreshold": 90, + "diskAlertThreshold": 90, + "tempAlertThreshold": 80, + "selectedDisks": [], + "geoCheckEnabled": false, + "geoCheckLocations": [], + "geoCheckInterval": 300000, + "teamId": "65f1c2a4d8b9e01234567890", + "userId": "65f1c2a4d8b9e01234567891", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + } + }, + "NotificationChannelBody": { + "oneOf": [ + { + "$ref": "#/components/schemas/EmailNotification" + }, + { + "$ref": "#/components/schemas/WebhookNotification" + }, + { + "$ref": "#/components/schemas/SlackNotification" + }, + { + "$ref": "#/components/schemas/DiscordNotification" + }, + { + "$ref": "#/components/schemas/PagerDutyNotification" + }, + { + "$ref": "#/components/schemas/MatrixNotification" + }, + { + "$ref": "#/components/schemas/TeamsNotification" + }, + { + "$ref": "#/components/schemas/TelegramNotification" + }, + { + "$ref": "#/components/schemas/PushoverNotification" + }, + { + "$ref": "#/components/schemas/TwilioNotification" + }, + { + "$ref": "#/components/schemas/NtfyNotification" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "email": "#/components/schemas/EmailNotification", + "webhook": "#/components/schemas/WebhookNotification", + "slack": "#/components/schemas/SlackNotification", + "discord": "#/components/schemas/DiscordNotification", + "pager_duty": "#/components/schemas/PagerDutyNotification", + "matrix": "#/components/schemas/MatrixNotification", + "teams": "#/components/schemas/TeamsNotification", + "telegram": "#/components/schemas/TelegramNotification", + "pushover": "#/components/schemas/PushoverNotification", + "twilio": "#/components/schemas/TwilioNotification", + "ntfy": "#/components/schemas/NtfyNotification" + } + } + }, + "EmailNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["email"] + }, + "address": { + "type": "string", + "format": "email" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "Ops on-call email", + "type": "email", + "address": "alerts@example.com" + } + }, + "WebhookNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["webhook"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "Custom webhook", + "type": "webhook", + "address": "https://example.com/hooks/checkmate" + } + }, + "SlackNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["slack"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "#alerts", + "type": "slack", + "address": "https://hooks.slack.com/services/T000/B000/XXXX" + } + }, + "DiscordNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["discord"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "#status", + "type": "discord", + "address": "https://discord.com/api/webhooks/123/abc" + } + }, + "PagerDutyNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["pager_duty"] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "PagerDuty primary", + "type": "pager_duty", + "address": "R01XXXXXXXXXXXXXXXXXXXXXXX" + } + }, + "MatrixNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["matrix"] + }, + "address": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "homeserverUrl": { + "type": "string", + "format": "uri" + }, + "roomId": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "homeserverUrl", "roomId", "accessToken"], + "example": { + "notificationName": "Matrix room", + "type": "matrix", + "homeserverUrl": "https://matrix.example.com", + "roomId": "!abc123:example.com", + "accessToken": "syt_xxx" + } + }, + "TeamsNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["teams"] + }, + "address": { + "type": "string", + "format": "uri" + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "Teams ops channel", + "type": "teams", + "address": "https://outlook.office.com/webhook/..." + } + }, + "TelegramNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["telegram"] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "address", "accessToken"], + "example": { + "notificationName": "Telegram bot", + "type": "telegram", + "address": "-1001234567890", + "accessToken": "123456:ABC-DEF" + } + }, + "PushoverNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["pushover"] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "address", "accessToken"], + "example": { + "notificationName": "Pushover personal", + "type": "pushover", + "address": "u1234567890abcdef", + "accessToken": "a1234567890abcdef" + } + }, + "TwilioNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["twilio"] + }, + "accountSid": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + }, + "phone": { + "type": "string", + "minLength": 1 + }, + "twilioPhoneNumber": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "accountSid", "accessToken", "phone", "twilioPhoneNumber"], + "example": { + "notificationName": "Twilio SMS", + "type": "twilio", + "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "accessToken": "your-auth-token", + "phone": "+15551234567", + "twilioPhoneNumber": "+15557654321" + } + }, + "NtfyNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["ntfy"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "topic": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "address", "topic"], + "example": { + "notificationName": "ntfy topic", + "type": "ntfy", + "address": "https://ntfy.sh", + "topic": "checkmate-alerts" + } + } + }, + "parameters": {} + }, + "paths": { + "/auth/register": { + "post": { + "tags": ["auth"], + "summary": "Register a new user (first user becomes superadmin)", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "profileImage": { + "type": "string", + "format": "binary" + }, + "inviteToken": { + "type": "string", + "default": "" + } + }, + "required": ["firstName", "lastName", "email", "password", "profileImage"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/AuthPayload" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/login": { + "post": { + "tags": ["auth"], + "summary": "Log in", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 1 + } + }, + "required": ["email", "password"] + }, + "example": { + "email": "ada@example.com", + "password": "S3cure!Passw0rd" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/AuthPayload" + } + }, + "required": ["success", "msg", "data"] + }, + "example": { + "success": true, + "msg": "OK", + "data": { + "user": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": ["admin"], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + }, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + } + } + } + }, + "401": { + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/recovery/request": { + "post": { + "tags": ["auth"], + "summary": "Request a password recovery email", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + } + }, + "required": ["email"] + }, + "example": { + "email": "ada@example.com" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/recovery/validate": { + "post": { + "tags": ["auth"], + "summary": "Validate a password recovery token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "recoveryToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["recoveryToken"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/recovery/reset": { + "post": { + "tags": ["auth"], + "summary": "Reset password using a recovery token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "recoveryToken": { + "type": "string", + "minLength": 1 + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "confirm": { + "type": "string" + } + }, + "required": ["recoveryToken", "password"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users/superadmin": { + "get": { + "tags": ["auth"], + "summary": "Check whether a superadmin user exists", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "superAdminExists": { + "type": "boolean" + } + }, + "required": ["superAdminExists"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users": { + "get": { + "tags": ["auth"], + "summary": "List all users (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "post": { + "tags": ["auth"], + "summary": "Create a new user (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + }, + "profileImage": { + "type": "string", + "format": "binary" + } + }, + "required": ["firstName", "lastName", "email", "password", "role", "profileImage"] + } + } + } + }, + "responses": { + "201": { + "description": "User created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users/{userId}": { + "get": { + "tags": ["auth"], + "summary": "Get a user by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "404": { + "description": "User not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["auth"], + "summary": "Edit a user (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + } + }, + "required": ["firstName", "lastName", "role"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["auth"], + "summary": "Delete a user (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users/{userId}/password": { + "patch": { + "tags": ["auth"], + "summary": "Change a user's password (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + } + }, + "required": ["password"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/user": { + "patch": { + "tags": ["auth"], + "summary": "Edit the currently authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "profilePicture": { + "type": "string" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "newPassword": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "profileImage": { + "type": "string", + "format": "binary" + } + }, + "required": ["profileImage"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["auth"], + "summary": "Delete the currently authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/checks/team/summary": { + "get": { + "tags": ["checks"], + "summary": "Aggregate check summary for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/checks/team": { + "get": { + "tags": ["checks"], + "summary": "List checks across the team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["all", "up", "down", "resolve"] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["checks"], + "summary": "Delete all checks for the team (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "deletedCount": { + "type": "number" + } + }, + "required": ["deletedCount"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/checks/{monitorId}": { + "get": { + "tags": ["checks"], + "summary": "List checks for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["all", "up", "down", "resolve"] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["checks"], + "summary": "Delete checks for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/diagnostic/system": { + "get": { + "tags": ["diagnostic"], + "summary": "Get system diagnostics (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/geo-checks/{monitorId}": { + "get": { + "tags": ["geo-checks"], + "summary": "Get geo check results for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["all", "up", "down", "resolve"] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/team": { + "get": { + "tags": ["incidents"], + "summary": "List incidents for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"], + "default": "all" + }, + "required": false, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "integer", + "nullable": true, + "minimum": 0 + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "monitorId", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["manual", "automatic"] + }, + "required": false, + "name": "resolutionType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Incident" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/team/summary": { + "get": { + "tags": ["incidents"], + "summary": "Incident summary for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": false, + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/IncidentSummary" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/{incidentId}": { + "get": { + "tags": ["incidents"], + "summary": "Get an incident by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string" + }, + "required": true, + "name": "incidentId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "incident": { + "$ref": "#/components/schemas/Incident" + }, + "monitor": { + "nullable": true + }, + "user": { + "nullable": true + } + }, + "required": ["incident"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/{incidentId}/resolve": { + "put": { + "tags": ["incidents"], + "summary": "Manually resolve an incident (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string" + }, + "required": true, + "name": "incidentId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/invite/send": { + "post": { + "tags": ["invite"], + "summary": "Send an invite email (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + }, + "teamId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["email", "role", "teamId"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/invite/verify": { + "post": { + "tags": ["invite"], + "summary": "Verify an invite token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "token": { + "type": "string", + "minLength": 1 + } + }, + "required": ["token"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "role": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["email"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/invite": { + "post": { + "tags": ["invite"], + "summary": "Create an invite token (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + }, + "teamId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["email", "role", "teamId"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + }, + "required": ["token"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/logs": { + "get": { + "tags": ["logs"], + "summary": "Get application logs (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window": { + "post": { + "tags": ["maintenance-window"], + "summary": "Create one or more maintenance windows", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitors": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "name": { + "type": "string", + "minLength": 1 + }, + "active": { + "type": "boolean" + }, + "duration": { + "type": "number", + "minimum": 1 + }, + "durationUnit": { + "type": "string", + "enum": ["seconds", "minutes", "hours", "days"] + }, + "start": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "end": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "repeat": { + "type": "number", + "minimum": 0 + }, + "expiry": { + "type": "string", + "nullable": true, + "format": "date-time" + } + }, + "required": ["monitors", "name", "duration", "durationUnit", "start", "end", "repeat"], + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window/team": { + "get": { + "tags": ["maintenance-window"], + "summary": "List maintenance windows for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "active", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "field", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": false, + "name": "order", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window/monitor/{monitorId}": { + "get": { + "tags": ["maintenance-window"], + "summary": "List maintenance windows for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window/{id}": { + "get": { + "tags": ["maintenance-window"], + "summary": "Get a maintenance window by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["maintenance-window"], + "summary": "Edit a maintenance window", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "active": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "repeat": { + "type": "number" + }, + "start": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "end": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "expiry": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "monitors": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "duration": { + "type": "number" + }, + "durationUnit": { + "type": "string", + "enum": ["seconds", "minutes", "hours", "days"] + } + }, + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["maintenance-window"], + "summary": "Delete a maintenance window", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/team": { + "get": { + "tags": ["monitors"], + "summary": "List monitors for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + } + } + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "required": false, + "name": "tags", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Monitor" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/team/with-checks": { + "get": { + "tags": ["monitors"], + "summary": "List team monitors with their most recent checks (paginated)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "integer", + "nullable": true, + "minimum": 0 + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "field", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": false, + "name": "order", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + } + } + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "required": false, + "name": "tags", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "explain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/team/groups": { + "get": { + "tags": ["monitors"], + "summary": "List monitor groups for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/uptime/details/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get uptime details for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "normalize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/hardware/details/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get hardware metrics detail for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/pagespeed/details/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get PageSpeed detail for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/{monitorId}/geo-checks": { + "get": { + "tags": ["monitors"], + "summary": "Get geo check results for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": false, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "numToDisplay", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "normalize", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/pause/{monitorId}": { + "post": { + "tags": ["monitors"], + "summary": "Toggle pause state for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/certificate/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get SSL certificate info for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "certificateDate": { + "type": "string" + } + }, + "required": ["certificateDate"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/notifications": { + "patch": { + "tags": ["monitors"], + "summary": "Bulk update notifications across monitors", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitorIds": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 100 + }, + "notificationIds": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 100 + }, + "action": { + "type": "string", + "enum": ["add", "remove", "set"] + } + }, + "required": ["monitorIds", "notificationIds", "action"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "modifiedCount": { + "type": "number" + } + }, + "required": ["modifiedCount"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors": { + "post": { + "tags": ["monitors"], + "summary": "Create a new monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "url": { + "type": "string", + "minLength": 1 + }, + "ignoreTlsErrors": { + "type": "boolean", + "default": false + }, + "useAdvancedMatching": { + "type": "boolean", + "default": false + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ], + "default": "" + }, + "strategy": { + "type": "string", + "enum": ["desktop", "mobile"] + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + } + }, + "required": ["name", "type", "url"] + } + } + } + }, + "responses": { + "200": { + "description": "Monitor created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["monitors"], + "summary": "Delete every monitor (superadmin only)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/demo": { + "post": { + "tags": ["monitors"], + "summary": "Insert preconfigured demo monitors", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "number" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/export/json": { + "get": { + "tags": ["monitors"], + "summary": "Export all team monitors as JSON", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/import/json": { + "post": { + "tags": ["monitors"], + "summary": "Import monitors from JSON", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "status": { + "type": "string", + "enum": ["up", "down", "paused", "initializing", "maintenance", "breached"], + "default": "initializing" + }, + "statusWindow": { + "type": "array", + "items": { + "type": "boolean" + }, + "default": [] + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "ignoreTlsErrors": { + "type": "boolean", + "default": false + }, + "useAdvancedMatching": { + "type": "boolean", + "default": false + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "url": { + "type": "string", + "minLength": 1 + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean", + "default": true + }, + "interval": { + "type": "number", + "default": 60000 + }, + "uptimePercentage": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "secret": { + "type": "string" + }, + "cpuAlertThreshold": { + "type": "number", + "default": 100 + }, + "cpuAlertCounter": { + "type": "number", + "default": 5 + }, + "memoryAlertThreshold": { + "type": "number", + "default": 100 + }, + "memoryAlertCounter": { + "type": "number", + "default": 5 + }, + "diskAlertThreshold": { + "type": "number", + "default": 100 + }, + "diskAlertCounter": { + "type": "number", + "default": 5 + }, + "tempAlertThreshold": { + "type": "number", + "default": 100 + }, + "tempAlertCounter": { + "type": "number", + "default": 5 + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ], + "default": "" + }, + "strategy": { + "type": "string", + "enum": ["desktop", "mobile"] + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + } + ], + "default": null + }, + "geoCheckEnabled": { + "type": "boolean", + "default": false + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + "default": [] + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000, + "default": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": ["name", "type", "url"] + }, + "minItems": 1 + } + }, + "required": ["monitors"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "imported": { + "type": "number" + } + }, + "required": ["imported"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/games": { + "get": { + "tags": ["monitors"], + "summary": "List supported game-server types", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get a monitor by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["monitors"], + "summary": "Edit a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "url": { + "type": "string" + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "interval": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + }, + "ignoreTlsErrors": { + "type": "boolean" + }, + "useAdvancedMatching": { + "type": "boolean" + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "port": { + "type": "number", + "minimum": 1, + "maximum": 65535 + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "strategy": { + "type": "string", + "enum": ["desktop", "mobile"] + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["monitors"], + "summary": "Delete a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications": { + "post": { + "tags": ["notifications"], + "summary": "Create a notification channel", + "description": "Create a notification channel of any supported type. The `type` field discriminates the body shape.", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/test/all": { + "post": { + "tags": ["notifications"], + "summary": "Send a test alert through every notification channel for the team", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitorId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["monitorId"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/test": { + "post": { + "tags": ["notifications"], + "summary": "Send a test alert through a single notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + }, + "required": ["success"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/team": { + "get": { + "tags": ["notifications"], + "summary": "List notification channels for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/{id}": { + "get": { + "tags": ["notifications"], + "summary": "Get a notification channel by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["notifications"], + "summary": "Delete a notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["notifications"], + "summary": "Edit a notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/jobs": { + "get": { + "tags": ["queue"], + "summary": "List queued monitor jobs (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/metrics": { + "get": { + "tags": ["queue"], + "summary": "Get queue runtime metrics (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/all-metrics": { + "get": { + "tags": ["queue"], + "summary": "Get queue metrics across all monitors (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/flush": { + "post": { + "tags": ["queue"], + "summary": "Flush the monitor job queue (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/settings": { + "get": { + "tags": ["settings"], + "summary": "Get application settings", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["settings"], + "summary": "Update application settings (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "checkTTL": { + "type": "integer", + "minimum": 1, + "maximum": 366 + }, + "systemEmailPort": { + "type": "number", + "nullable": true + }, + "pagespeedApiKey": { + "type": "string", + "nullable": true + }, + "language": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "systemEmailHost": { + "type": "string", + "nullable": true + }, + "systemEmailAddress": { + "type": "string", + "nullable": true + }, + "systemEmailDisplayName": { + "type": "string", + "nullable": true, + "maxLength": 100 + }, + "systemEmailPassword": { + "type": "string", + "nullable": true + }, + "systemEmailUser": { + "type": "string", + "nullable": true + }, + "systemEmailConnectionHost": { + "type": "string", + "nullable": true + }, + "systemEmailTLSServername": { + "type": "string", + "nullable": true + }, + "showURL": { + "type": "boolean" + }, + "systemEmailSecure": { + "type": "boolean" + }, + "systemEmailPool": { + "type": "boolean" + }, + "systemEmailIgnoreTLS": { + "type": "boolean" + }, + "systemEmailRequireTLS": { + "type": "boolean" + }, + "systemEmailRejectUnauthorized": { + "type": "boolean" + }, + "globalThresholds": { + "type": "object", + "properties": { + "cpu": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "memory": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "disk": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "temperature": { + "type": "number", + "minimum": 1, + "maximum": 150 + } + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/settings/test-email": { + "post": { + "tags": ["settings"], + "summary": "Send a test email using current SMTP settings (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "to": { + "type": "string", + "minLength": 1 + }, + "systemEmailHost": { + "type": "string" + }, + "systemEmailPort": { + "type": "number" + }, + "systemEmailSecure": { + "type": "boolean" + }, + "systemEmailPool": { + "type": "boolean" + }, + "systemEmailAddress": { + "type": "string" + }, + "systemEmailDisplayName": { + "type": "string" + }, + "systemEmailPassword": { + "type": "string" + }, + "systemEmailUser": { + "type": "string" + }, + "systemEmailConnectionHost": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "systemEmailIgnoreTLS": { + "type": "boolean" + }, + "systemEmailRequireTLS": { + "type": "boolean" + }, + "systemEmailRejectUnauthorized": { + "type": "boolean" + }, + "systemEmailTLSServername": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["to"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/team": { + "get": { + "tags": ["status-page"], + "summary": "List status pages for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page": { + "post": { + "tags": ["status-page"], + "summary": "Create a status page (logo upload optional)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "type": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "companyName": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "customDomain": { + "anyOf": [ + { + "type": "string", + "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" + }, + { + "nullable": true + } + ] + }, + "timezone": { + "type": "string" + }, + "color": { + "type": "string" + }, + "monitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1 + }, + "subMonitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + } + }, + "deleteSubmonitors": { + "type": "boolean" + }, + "isPublished": { + "type": "boolean" + }, + "showCharts": { + "type": "boolean" + }, + "showUptimePercentage": { + "type": "boolean" + }, + "showAdminLoginLink": { + "type": "boolean" + }, + "showInfrastructure": { + "type": "boolean" + }, + "removeLogo": { + "anyOf": [ + { + "type": "string", + "enum": ["true"] + }, + { + "type": "string", + "enum": ["false"] + } + ] + }, + "theme": { + "type": "string", + "enum": ["refined", "modern", "bold", "editorial"] + }, + "themeMode": { + "type": "string", + "enum": ["auto", "light", "dark"] + }, + "logo": { + "type": "string", + "format": "binary" + } + }, + "required": ["type", "companyName", "url", "monitors", "isPublished", "showUptimePercentage", "logo"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/{id}": { + "put": { + "tags": ["status-page"], + "summary": "Update a status page (logo upload optional)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "type": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "companyName": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "customDomain": { + "anyOf": [ + { + "type": "string", + "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" + }, + { + "nullable": true + } + ] + }, + "timezone": { + "type": "string" + }, + "color": { + "type": "string" + }, + "monitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1 + }, + "subMonitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + } + }, + "deleteSubmonitors": { + "type": "boolean" + }, + "isPublished": { + "type": "boolean" + }, + "showCharts": { + "type": "boolean" + }, + "showUptimePercentage": { + "type": "boolean" + }, + "showAdminLoginLink": { + "type": "boolean" + }, + "showInfrastructure": { + "type": "boolean" + }, + "removeLogo": { + "anyOf": [ + { + "type": "string", + "enum": ["true"] + }, + { + "type": "string", + "enum": ["false"] + } + ] + }, + "theme": { + "type": "string", + "enum": ["refined", "modern", "bold", "editorial"] + }, + "themeMode": { + "type": "string", + "enum": ["auto", "light", "dark"] + }, + "logo": { + "type": "string", + "format": "binary" + } + }, + "required": ["type", "companyName", "url", "monitors", "isPublished", "showUptimePercentage", "logo"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["status-page"], + "summary": "Delete a status page", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/resolve": { + "get": { + "tags": ["status-page"], + "summary": "Resolve a published status page by custom domain", + "parameters": [ + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "required": true, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "timeFrame", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "domain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "404": { + "description": "Status page not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/{url}": { + "get": { + "tags": ["status-page"], + "summary": "Get a public status page by its URL slug", + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "url", + "in": "path" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "required": true, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "timeFrame", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "404": { + "description": "Status page not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + } + } } From 187c8eaba1af4985d9ad3035c936266d31c11f62 Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:03:34 -0400 Subject: [PATCH 3/9] chore: format openapi.json with prettier --- server/openapi.json | 24607 +++++++++++++++++++----------------------- 1 file changed, 11137 insertions(+), 13470 deletions(-) diff --git a/server/openapi.json b/server/openapi.json index 2681d7e9a..f3a6a2505 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -1,13472 +1,11139 @@ { - "openapi": "3.0.0", - "info": { - "title": "Checkmate API", - "version": "1.0.0", - "description": "Generated from Zod validation schemas. Source of truth: server/src/api/validation/*.ts" - }, - "servers": [ - { - "url": "/api/v1", - "description": "Current server" - } - ], - "tags": [ - { - "name": "auth", - "description": "Sign up, log in, password reset, and the authenticated user's profile." - }, - { - "name": "monitors", - "description": "Configure and inspect monitors (HTTP, port, ping, hardware, docker, game, gRPC) for the caller's team." - }, - { - "name": "checks", - "description": "Individual monitoring check results, including history, summaries, and bulk deletes." - }, - { - "name": "geo-checks", - "description": "Geographic check results for monitors with multi-region probing enabled." - }, - { - "name": "incidents", - "description": "Downtime incidents derived from monitor state changes, including filtering and CSV export." - }, - { - "name": "notifications", - "description": "Notification channels (email, webhook, Slack, Discord, PagerDuty, Matrix, Teams, Telegram, Pushover, Twilio) and test alerts." - }, - { - "name": "maintenance-window", - "description": "Scheduled maintenance windows during which monitors do not generate incidents or alerts." - }, - { - "name": "status-page", - "description": "Public status pages, their configuration, and the monitors they expose." - }, - { - "name": "settings", - "description": "Global application settings (admin/superadmin)." - }, - { - "name": "invite", - "description": "Team invitations and accepting them." - }, - { - "name": "queue", - "description": "Background job queue introspection and admin actions (admin/superadmin)." - }, - { - "name": "diagnostic", - "description": "System diagnostics for the running server (admin/superadmin)." - }, - { - "name": "logs", - "description": "Application logs for the running server (admin/superadmin)." - } - ], - "components": { - "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT" - } - }, - "schemas": { - "AuthPayload": { - "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - }, - "token": { - "type": "string" - } - }, - "required": [ - "user" - ], - "example": { - "user": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": [ - "admin" - ], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - }, - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "User": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "email": { - "type": "string" - }, - "role": { - "type": "array", - "items": { - "type": "string" - } - }, - "teamId": { - "type": "string" - }, - "profileImage": { - "type": "string", - "nullable": true - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "_id", - "firstName", - "lastName", - "email", - "role", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - }, - "example": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": [ - "admin" - ], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - } - }, - "Incident": { - "type": "object", - "properties": { - "id": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789c" - }, - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "teamId": { - "type": "string", - "example": "65f1c2a4d8b9e01234567890" - }, - "startTime": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "endTime": { - "type": "string", - "nullable": true, - "example": "2026-04-15T03:34:00.000Z" - }, - "status": { - "type": "boolean", - "example": true, - "description": "true = resolved, false = ongoing" - }, - "message": { - "type": "string", - "nullable": true, - "example": "HTTP 503 from origin" - }, - "statusCode": { - "type": "number", - "nullable": true, - "example": 503 - }, - "resolutionType": { - "type": "string", - "nullable": true, - "enum": [ - "automatic", - "manual", - null - ], - "example": "automatic" - }, - "resolvedBy": { - "type": "string", - "nullable": true - }, - "resolvedByEmail": { - "type": "string", - "nullable": true - }, - "comment": { - "type": "string", - "nullable": true - }, - "createdAt": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "updatedAt": { - "type": "string", - "example": "2026-04-15T03:34:00.000Z" - } - }, - "required": [ - "id", - "monitorId", - "teamId", - "startTime", - "endTime", - "status", - "resolutionType", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - } - }, - "IncidentSummary": { - "type": "object", - "properties": { - "total": { - "type": "number", - "example": 12 - }, - "totalActive": { - "type": "number", - "example": 1 - }, - "totalManualResolutions": { - "type": "number", - "example": 2 - }, - "totalAutomaticResolutions": { - "type": "number", - "example": 9 - }, - "avgResolutionTimeHours": { - "type": "number", - "example": 0.5 - }, - "topMonitor": { - "type": "object", - "nullable": true, - "properties": { - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "monitorName": { - "type": "string", - "nullable": true, - "example": "Marketing site" - }, - "incidentCount": { - "type": "number", - "example": 4 - } - }, - "required": [ - "monitorId", - "monitorName", - "incidentCount" - ] - }, - "latestIncidents": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncidentSummaryItem" - } - } - }, - "required": [ - "total", - "totalActive", - "totalManualResolutions", - "totalAutomaticResolutions", - "avgResolutionTimeHours", - "topMonitor", - "latestIncidents" - ] - }, - "IncidentSummaryItem": { - "type": "object", - "properties": { - "id": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789c" - }, - "monitorId": { - "type": "string", - "example": "65f1c2a4d8b9e0123456789a" - }, - "monitorName": { - "type": "string", - "nullable": true, - "example": "Marketing site" - }, - "status": { - "type": "boolean", - "example": true - }, - "startTime": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - }, - "endTime": { - "type": "string", - "nullable": true, - "example": "2026-04-15T03:34:00.000Z" - }, - "resolutionType": { - "type": "string", - "nullable": true, - "enum": [ - "automatic", - "manual", - null - ], - "example": "automatic" - }, - "message": { - "type": "string", - "nullable": true, - "example": "HTTP 503 from origin" - }, - "statusCode": { - "type": "number", - "nullable": true, - "example": 503 - }, - "createdAt": { - "type": "string", - "example": "2026-04-15T03:21:00.000Z" - } - }, - "required": [ - "id", - "monitorId", - "monitorName", - "status", - "startTime", - "endTime", - "resolutionType", - "message", - "statusCode", - "createdAt" - ] - }, - "Monitor": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "url": { - "type": "string" - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean" - }, - "interval": { - "type": "number" - }, - "status": { - "type": "string", - "enum": [ - "up", - "down", - "paused", - "initializing", - "maintenance", - "breached" - ] - }, - "statusWindowSize": { - "type": "number" - }, - "statusWindowThreshold": { - "type": "number" - }, - "ignoreTlsErrors": { - "type": "boolean" - }, - "useAdvancedMatching": { - "type": "boolean" - }, - "jsonPath": { - "type": "string" - }, - "expectedValue": { - "type": "string" - }, - "matchMethod": { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "customUpCodes": { - "type": "array", - "items": { - "type": "number" - } - }, - "secret": { - "type": "string" - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "gameId": { - "type": "string" - }, - "grpcServiceName": { - "type": "string" - }, - "group": { - "type": "string", - "nullable": true - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - }, - "geoCheckInterval": { - "type": "number" - }, - "dnsServer": { - "type": "string" - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - }, - "teamId": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "_id", - "name", - "type", - "url", - "isActive", - "interval", - "status", - "statusWindowSize", - "statusWindowThreshold", - "ignoreTlsErrors", - "useAdvancedMatching", - "notifications", - "tags", - "cpuAlertThreshold", - "memoryAlertThreshold", - "diskAlertThreshold", - "tempAlertThreshold", - "selectedDisks", - "geoCheckEnabled", - "geoCheckLocations", - "geoCheckInterval", - "teamId", - "userId", - "createdAt", - "updatedAt" - ], - "additionalProperties": { - "nullable": true - }, - "example": { - "_id": "65f1c2a4d8b9e0123456789a", - "name": "Marketing site", - "description": "Production marketing site monitored from the EU region", - "type": "http", - "url": "https://www.example.com", - "port": 443, - "isActive": true, - "interval": 60000, - "status": "up", - "statusWindowSize": 5, - "statusWindowThreshold": 3, - "ignoreTlsErrors": false, - "useAdvancedMatching": false, - "notifications": [ - "65f1c2a4d8b9e0123456789b" - ], - "cpuAlertThreshold": 90, - "memoryAlertThreshold": 90, - "diskAlertThreshold": 90, - "tempAlertThreshold": 80, - "selectedDisks": [], - "geoCheckEnabled": false, - "geoCheckLocations": [], - "geoCheckInterval": 300000, - "teamId": "65f1c2a4d8b9e01234567890", - "userId": "65f1c2a4d8b9e01234567891", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - } - }, - "NotificationChannelBody": { - "oneOf": [ - { - "$ref": "#/components/schemas/EmailNotification" - }, - { - "$ref": "#/components/schemas/WebhookNotification" - }, - { - "$ref": "#/components/schemas/SlackNotification" - }, - { - "$ref": "#/components/schemas/DiscordNotification" - }, - { - "$ref": "#/components/schemas/PagerDutyNotification" - }, - { - "$ref": "#/components/schemas/MatrixNotification" - }, - { - "$ref": "#/components/schemas/TeamsNotification" - }, - { - "$ref": "#/components/schemas/TelegramNotification" - }, - { - "$ref": "#/components/schemas/PushoverNotification" - }, - { - "$ref": "#/components/schemas/TwilioNotification" - }, - { - "$ref": "#/components/schemas/NtfyNotification" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "email": "#/components/schemas/EmailNotification", - "webhook": "#/components/schemas/WebhookNotification", - "slack": "#/components/schemas/SlackNotification", - "discord": "#/components/schemas/DiscordNotification", - "pager_duty": "#/components/schemas/PagerDutyNotification", - "matrix": "#/components/schemas/MatrixNotification", - "teams": "#/components/schemas/TeamsNotification", - "telegram": "#/components/schemas/TelegramNotification", - "pushover": "#/components/schemas/PushoverNotification", - "twilio": "#/components/schemas/TwilioNotification", - "ntfy": "#/components/schemas/NtfyNotification" - } - } - }, - "EmailNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "email" - ] - }, - "address": { - "type": "string", - "format": "email" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "Ops on-call email", - "type": "email", - "address": "alerts@example.com" - } - }, - "WebhookNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "webhook" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "Custom webhook", - "type": "webhook", - "address": "https://example.com/hooks/checkmate" - } - }, - "SlackNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "slack" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "#alerts", - "type": "slack", - "address": "https://hooks.slack.com/services/T000/B000/XXXX" - } - }, - "DiscordNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "discord" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "#status", - "type": "discord", - "address": "https://discord.com/api/webhooks/123/abc" - } - }, - "PagerDutyNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "pager_duty" - ] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "homeserverUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "roomId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "accessToken": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "PagerDuty primary", - "type": "pager_duty", - "address": "R01XXXXXXXXXXXXXXXXXXXXXXX" - } - }, - "MatrixNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "matrix" - ] - }, - "address": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "homeserverUrl": { - "type": "string", - "format": "uri" - }, - "roomId": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "homeserverUrl", - "roomId", - "accessToken" - ], - "example": { - "notificationName": "Matrix room", - "type": "matrix", - "homeserverUrl": "https://matrix.example.com", - "roomId": "!abc123:example.com", - "accessToken": "syt_xxx" - } - }, - "TeamsNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "teams" - ] - }, - "address": { - "type": "string", - "format": "uri" - } - }, - "required": [ - "notificationName", - "type", - "address" - ], - "example": { - "notificationName": "Teams ops channel", - "type": "teams", - "address": "https://outlook.office.com/webhook/..." - } - }, - "TelegramNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "telegram" - ] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "address", - "accessToken" - ], - "example": { - "notificationName": "Telegram bot", - "type": "telegram", - "address": "-1001234567890", - "accessToken": "123456:ABC-DEF" - } - }, - "PushoverNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "pushover" - ] - }, - "address": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "address", - "accessToken" - ], - "example": { - "notificationName": "Pushover personal", - "type": "pushover", - "address": "u1234567890abcdef", - "accessToken": "a1234567890abcdef" - } - }, - "TwilioNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "twilio" - ] - }, - "accountSid": { - "type": "string", - "minLength": 1 - }, - "accessToken": { - "type": "string", - "minLength": 1 - }, - "phone": { - "type": "string", - "minLength": 1 - }, - "twilioPhoneNumber": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "accountSid", - "accessToken", - "phone", - "twilioPhoneNumber" - ], - "example": { - "notificationName": "Twilio SMS", - "type": "twilio", - "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "accessToken": "your-auth-token", - "phone": "+15551234567", - "twilioPhoneNumber": "+15557654321" - } - }, - "NtfyNotification": { - "type": "object", - "properties": { - "notificationName": { - "type": "string", - "minLength": 1 - }, - "type": { - "type": "string", - "enum": [ - "ntfy" - ] - }, - "address": { - "type": "string", - "format": "uri" - }, - "topic": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "notificationName", - "type", - "address", - "topic" - ], - "example": { - "notificationName": "ntfy topic", - "type": "ntfy", - "address": "https://ntfy.sh", - "topic": "checkmate-alerts" - } - } - }, - "parameters": {} - }, - "paths": { - "/auth/register": { - "post": { - "tags": [ - "auth" - ], - "summary": "Register a new user (first user becomes superadmin)", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "profileImage": { - "type": "string", - "format": "binary" - }, - "inviteToken": { - "type": "string", - "default": "" - } - }, - "required": [ - "firstName", - "lastName", - "email", - "password", - "profileImage" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/AuthPayload" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/login": { - "post": { - "tags": [ - "auth" - ], - "summary": "Log in", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "email", - "password" - ] - }, - "example": { - "email": "ada@example.com", - "password": "S3cure!Passw0rd" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/AuthPayload" - } - }, - "required": [ - "success", - "msg", - "data" - ] - }, - "example": { - "success": true, - "msg": "OK", - "data": { - "user": { - "_id": "65f1c2a4d8b9e0123456789a", - "firstName": "Ada", - "lastName": "Lovelace", - "email": "ada@example.com", - "role": [ - "admin" - ], - "teamId": "65f1c2a4d8b9e01234567890", - "createdAt": "2026-04-01T10:00:00.000Z", - "updatedAt": "2026-04-15T14:30:00.000Z" - }, - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - } - } - } - }, - "401": { - "description": "Invalid credentials", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/recovery/request": { - "post": { - "tags": [ - "auth" - ], - "summary": "Request a password recovery email", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - } - }, - "required": [ - "email" - ] - }, - "example": { - "email": "ada@example.com" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/recovery/validate": { - "post": { - "tags": [ - "auth" - ], - "summary": "Validate a password recovery token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "recoveryToken": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "recoveryToken" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/recovery/reset": { - "post": { - "tags": [ - "auth" - ], - "summary": "Reset password using a recovery token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "recoveryToken": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "confirm": { - "type": "string" - } - }, - "required": [ - "recoveryToken", - "password" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users/superadmin": { - "get": { - "tags": [ - "auth" - ], - "summary": "Check whether a superadmin user exists", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "superAdminExists": { - "type": "boolean" - } - }, - "required": [ - "superAdminExists" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users": { - "get": { - "tags": [ - "auth" - ], - "summary": "List all users (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "post": { - "tags": [ - "auth" - ], - "summary": "Create a new user (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - }, - "profileImage": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "firstName", - "lastName", - "email", - "password", - "role", - "profileImage" - ] - } - } - } - }, - "responses": { - "201": { - "description": "User created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users/{userId}": { - "get": { - "tags": [ - "auth" - ], - "summary": "Get a user by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "404": { - "description": "User not found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "auth" - ], - "summary": "Edit a user (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - } - }, - "required": [ - "firstName", - "lastName", - "role" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "auth" - ], - "summary": "Delete a user (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/users/{userId}/password": { - "patch": { - "tags": [ - "auth" - ], - "summary": "Change a user's password (superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "userId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - } - }, - "required": [ - "password" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/auth/user": { - "patch": { - "tags": [ - "auth" - ], - "summary": "Edit the currently authenticated user", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "firstName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "lastName": { - "type": "string", - "maxLength": 50, - "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" - }, - "email": { - "type": "string", - "format": "email" - }, - "profilePicture": { - "type": "string" - }, - "password": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "newPassword": { - "type": "string", - "minLength": 8, - "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" - }, - "profileImage": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "profileImage" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/User" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "auth" - ], - "summary": "Delete the currently authenticated user", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/checks/team/summary": { - "get": { - "tags": [ - "checks" - ], - "summary": "Aggregate check summary for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/checks/team": { - "get": { - "tags": [ - "checks" - ], - "summary": "List checks across the team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "all", - "up", - "down", - "resolve" - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "checks" - ], - "summary": "Delete all checks for the team (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "deletedCount": { - "type": "number" - } - }, - "required": [ - "deletedCount" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/checks/{monitorId}": { - "get": { - "tags": [ - "checks" - ], - "summary": "List checks for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "all", - "up", - "down", - "resolve" - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "checks" - ], - "summary": "Delete checks for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/diagnostic/system": { - "get": { - "tags": [ - "diagnostic" - ], - "summary": "Get system diagnostics (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/geo-checks/{monitorId}": { - "get": { - "tags": [ - "geo-checks" - ], - "summary": "Get geo check results for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "all", - "up", - "down", - "resolve" - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "ack", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/team": { - "get": { - "tags": [ - "incidents" - ], - "summary": "List incidents for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": true, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ], - "default": "all" - }, - "required": false, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "integer", - "nullable": true, - "minimum": 0 - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "monitorId", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "manual", - "automatic" - ] - }, - "required": false, - "name": "resolutionType", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Incident" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/team/summary": { - "get": { - "tags": [ - "incidents" - ], - "summary": "Incident summary for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": false, - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/IncidentSummary" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/{incidentId}": { - "get": { - "tags": [ - "incidents" - ], - "summary": "Get an incident by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string" - }, - "required": true, - "name": "incidentId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "incident": { - "$ref": "#/components/schemas/Incident" - }, - "monitor": { - "nullable": true - }, - "user": { - "nullable": true - } - }, - "required": [ - "incident" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/incidents/{incidentId}/resolve": { - "put": { - "tags": [ - "incidents" - ], - "summary": "Manually resolve an incident (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string" - }, - "required": true, - "name": "incidentId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/invite/send": { - "post": { - "tags": [ - "invite" - ], - "summary": "Send an invite email (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - }, - "teamId": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "email", - "role", - "teamId" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/invite/verify": { - "post": { - "tags": [ - "invite" - ], - "summary": "Verify an invite token", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "token": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "token" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "role": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "email" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/invite": { - "post": { - "tags": [ - "invite" - ], - "summary": "Create an invite token (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "role": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "user", - "admin", - "superadmin", - "demo" - ] - }, - "minItems": 1 - }, - "teamId": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "email", - "role", - "teamId" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "token": { - "type": "string" - } - }, - "required": [ - "token" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/logs": { - "get": { - "tags": [ - "logs" - ], - "summary": "Get application logs (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window": { - "post": { - "tags": [ - "maintenance-window" - ], - "summary": "Create one or more maintenance windows", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitors": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "name": { - "type": "string", - "minLength": 1 - }, - "active": { - "type": "boolean" - }, - "duration": { - "type": "number", - "minimum": 1 - }, - "durationUnit": { - "type": "string", - "enum": [ - "seconds", - "minutes", - "hours", - "days" - ] - }, - "start": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "end": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "repeat": { - "type": "number", - "minimum": 0 - }, - "expiry": { - "type": "string", - "nullable": true, - "format": "date-time" - } - }, - "required": [ - "monitors", - "name", - "duration", - "durationUnit", - "start", - "end", - "repeat" - ], - "additionalProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window/team": { - "get": { - "tags": [ - "maintenance-window" - ], - "summary": "List maintenance windows for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "active", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "field", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": false, - "name": "order", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window/monitor/{monitorId}": { - "get": { - "tags": [ - "maintenance-window" - ], - "summary": "List maintenance windows for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/maintenance-window/{id}": { - "get": { - "tags": [ - "maintenance-window" - ], - "summary": "Get a maintenance window by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "maintenance-window" - ], - "summary": "Edit a maintenance window", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "active": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "repeat": { - "type": "number" - }, - "start": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "end": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "expiry": { - "type": "string", - "nullable": true, - "format": "date-time" - }, - "monitors": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "duration": { - "type": "number" - }, - "durationUnit": { - "type": "string", - "enum": [ - "seconds", - "minutes", - "hours", - "days" - ] - } - }, - "additionalProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "maintenance-window" - ], - "summary": "Delete a maintenance window", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/team": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List monitors for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - } - } - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "required": false, - "name": "tags", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Monitor" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/team/with-checks": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List team monitors with their most recent checks (paginated)", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "integer", - "nullable": true, - "minimum": 0 - }, - "required": false, - "name": "page", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "required": false, - "name": "rowsPerPage", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "required": false, - "name": "filter", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "field", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": false, - "name": "order", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - } - } - ] - }, - "required": false, - "name": "type", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "required": false, - "name": "tags", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "explain", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/team/groups": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List monitor groups for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/uptime/details/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get uptime details for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": true, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "normalize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/hardware/details/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get hardware metrics detail for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/pagespeed/details/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get PageSpeed detail for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/{monitorId}/geo-checks": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get geo check results for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "required": false, - "name": "sortOrder", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "recent", - "hour", - "day", - "week", - "month", - "all" - ] - }, - "required": false, - "name": "dateRange", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "numToDisplay", - "in": "query" - }, - { - "schema": { - "type": "boolean" - }, - "required": false, - "name": "normalize", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - } - ] - }, - "required": false, - "name": "continent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/pause/{monitorId}": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Toggle pause state for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/certificate/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get SSL certificate info for a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "certificateDate": { - "type": "string" - } - }, - "required": [ - "certificateDate" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/notifications": { - "patch": { - "tags": [ - "monitors" - ], - "summary": "Bulk update notifications across monitors", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitorIds": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1, - "maxItems": 100 - }, - "notificationIds": { - "type": "array", - "items": { - "type": "string" - }, - "maxItems": 100 - }, - "action": { - "type": "string", - "enum": [ - "add", - "remove", - "set" - ] - } - }, - "required": [ - "monitorIds", - "notificationIds", - "action" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "modifiedCount": { - "type": "number" - } - }, - "required": [ - "modifiedCount" - ] - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Create a new monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "name": { - "type": "string", - "minLength": 1 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "url": { - "type": "string", - "minLength": 1 - }, - "ignoreTlsErrors": { - "type": "boolean", - "default": false - }, - "useAdvancedMatching": { - "type": "boolean", - "default": false - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean" - }, - "interval": { - "type": "number" - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "customUpCodes": { - "type": "array", - "items": { - "type": "number" - }, - "default": [] - }, - "secret": { - "type": "string" - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ], - "default": "" - }, - "strategy": { - "type": "string", - "enum": [ - "desktop", - "mobile" - ] - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - } - }, - "required": [ - "name", - "type", - "url" - ] - } - } - } - }, - "responses": { - "200": { - "description": "Monitor created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "monitors" - ], - "summary": "Delete every monitor (superadmin only)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/demo": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Insert preconfigured demo monitors", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "number" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/export/json": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Export all team monitors as JSON", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/import/json": { - "post": { - "tags": [ - "monitors" - ], - "summary": "Import monitors from JSON", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "teamId": { - "type": "string" - }, - "name": { - "type": "string", - "minLength": 1 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "status": { - "type": "string", - "enum": [ - "up", - "down", - "paused", - "initializing", - "maintenance", - "breached" - ], - "default": "initializing" - }, - "statusWindow": { - "type": "array", - "items": { - "type": "boolean" - }, - "default": [] - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "ignoreTlsErrors": { - "type": "boolean", - "default": false - }, - "useAdvancedMatching": { - "type": "boolean", - "default": false - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "url": { - "type": "string", - "minLength": 1 - }, - "port": { - "type": "number" - }, - "isActive": { - "type": "boolean", - "default": true - }, - "interval": { - "type": "number", - "default": 60000 - }, - "uptimePercentage": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "customUpCodes": { - "type": "array", - "items": { - "type": "number" - }, - "default": [] - }, - "secret": { - "type": "string" - }, - "cpuAlertThreshold": { - "type": "number", - "default": 100 - }, - "cpuAlertCounter": { - "type": "number", - "default": 5 - }, - "memoryAlertThreshold": { - "type": "number", - "default": 100 - }, - "memoryAlertCounter": { - "type": "number", - "default": 5 - }, - "diskAlertThreshold": { - "type": "number", - "default": 100 - }, - "diskAlertCounter": { - "type": "number", - "default": 5 - }, - "tempAlertThreshold": { - "type": "number", - "default": 100 - }, - "tempAlertCounter": { - "type": "number", - "default": 5 - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ], - "default": "" - }, - "strategy": { - "type": "string", - "enum": [ - "desktop", - "mobile" - ] - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - } - ], - "default": null - }, - "geoCheckEnabled": { - "type": "boolean", - "default": false - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - }, - "default": [] - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000, - "default": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - }, - "required": [ - "name", - "type", - "url" - ] - }, - "minItems": 1 - } - }, - "required": [ - "monitors" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "imported": { - "type": "number" - } - }, - "required": [ - "imported" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/games": { - "get": { - "tags": [ - "monitors" - ], - "summary": "List supported game-server types", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/monitors/{monitorId}": { - "get": { - "tags": [ - "monitors" - ], - "summary": "Get a monitor by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "monitors" - ], - "summary": "Edit a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "http", - "ping", - "pagespeed", - "hardware", - "docker", - "port", - "game", - "grpc", - "websocket", - "dns", - "unknown" - ] - }, - "url": { - "type": "string" - }, - "statusWindowSize": { - "type": "number", - "minimum": 1, - "maximum": 20, - "default": 5 - }, - "statusWindowThreshold": { - "type": "number", - "minimum": 1, - "maximum": 100, - "default": 60 - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "interval": { - "type": "number" - }, - "notifications": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "customUpCodes": { - "type": "array", - "items": { - "type": "number" - } - }, - "secret": { - "type": "string" - }, - "ignoreTlsErrors": { - "type": "boolean" - }, - "useAdvancedMatching": { - "type": "boolean" - }, - "jsonPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "expectedValue": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "matchMethod": { - "anyOf": [ - { - "type": "string", - "enum": [ - "equal", - "include", - "regex" - ] - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "port": { - "type": "number", - "minimum": 1, - "maximum": 65535 - }, - "cpuAlertThreshold": { - "type": "number" - }, - "memoryAlertThreshold": { - "type": "number" - }, - "diskAlertThreshold": { - "type": "number" - }, - "tempAlertThreshold": { - "type": "number" - }, - "gameId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "grpcServiceName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "strategy": { - "type": "string", - "enum": [ - "desktop", - "mobile" - ] - }, - "selectedDisks": { - "type": "array", - "items": { - "type": "string" - } - }, - "group": { - "anyOf": [ - { - "type": "string", - "maxLength": 50 - }, - { - "nullable": true - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "geoCheckEnabled": { - "type": "boolean" - }, - "geoCheckLocations": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "EU", - "NA", - "AS", - "SA", - "AF", - "OC" - ] - } - }, - "geoCheckInterval": { - "type": "number", - "minimum": 300000 - }, - "dnsServer": { - "type": "string", - "minLength": 1 - }, - "dnsRecordType": { - "type": "string", - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "TXT", - "NS" - ] - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "monitors" - ], - "summary": "Delete a monitor", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "monitorId", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/Monitor" - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications": { - "post": { - "tags": [ - "notifications" - ], - "summary": "Create a notification channel", - "description": "Create a notification channel of any supported type. The `type` field discriminates the body shape.", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/test/all": { - "post": { - "tags": [ - "notifications" - ], - "summary": "Send a test alert through every notification channel for the team", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "monitorId": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "monitorId" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/test": { - "post": { - "tags": [ - "notifications" - ], - "summary": "Send a test alert through a single notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - }, - "required": [ - "success" - ], - "additionalProperties": { - "nullable": true - } - } - }, - "required": [ - "success", - "msg", - "data" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/team": { - "get": { - "tags": [ - "notifications" - ], - "summary": "List notification channels for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/notifications/{id}": { - "get": { - "tags": [ - "notifications" - ], - "summary": "Get a notification channel by id", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "notifications" - ], - "summary": "Delete a notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "notifications" - ], - "summary": "Edit a notification channel", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationChannelBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/jobs": { - "get": { - "tags": [ - "queue" - ], - "summary": "List queued monitor jobs (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/metrics": { - "get": { - "tags": [ - "queue" - ], - "summary": "Get queue runtime metrics (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/all-metrics": { - "get": { - "tags": [ - "queue" - ], - "summary": "Get queue metrics across all monitors (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/queue/flush": { - "post": { - "tags": [ - "queue" - ], - "summary": "Flush the monitor job queue (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/settings": { - "get": { - "tags": [ - "settings" - ], - "summary": "Get application settings", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "patch": { - "tags": [ - "settings" - ], - "summary": "Update application settings (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "checkTTL": { - "type": "integer", - "minimum": 1, - "maximum": 366 - }, - "systemEmailPort": { - "type": "number", - "nullable": true - }, - "pagespeedApiKey": { - "type": "string", - "nullable": true - }, - "language": { - "type": "string" - }, - "timezone": { - "type": "string" - }, - "systemEmailHost": { - "type": "string", - "nullable": true - }, - "systemEmailAddress": { - "type": "string", - "nullable": true - }, - "systemEmailDisplayName": { - "type": "string", - "nullable": true, - "maxLength": 100 - }, - "systemEmailPassword": { - "type": "string", - "nullable": true - }, - "systemEmailUser": { - "type": "string", - "nullable": true - }, - "systemEmailConnectionHost": { - "type": "string", - "nullable": true - }, - "systemEmailTLSServername": { - "type": "string", - "nullable": true - }, - "showURL": { - "type": "boolean" - }, - "systemEmailSecure": { - "type": "boolean" - }, - "systemEmailPool": { - "type": "boolean" - }, - "systemEmailIgnoreTLS": { - "type": "boolean" - }, - "systemEmailRequireTLS": { - "type": "boolean" - }, - "systemEmailRejectUnauthorized": { - "type": "boolean" - }, - "globalThresholds": { - "type": "object", - "properties": { - "cpu": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "memory": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "disk": { - "type": "number", - "minimum": 1, - "maximum": 100 - }, - "temperature": { - "type": "number", - "minimum": 1, - "maximum": 150 - } - } - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/settings/test-email": { - "post": { - "tags": [ - "settings" - ], - "summary": "Send a test email using current SMTP settings (admin/superadmin)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "to": { - "type": "string", - "minLength": 1 - }, - "systemEmailHost": { - "type": "string" - }, - "systemEmailPort": { - "type": "number" - }, - "systemEmailSecure": { - "type": "boolean" - }, - "systemEmailPool": { - "type": "boolean" - }, - "systemEmailAddress": { - "type": "string" - }, - "systemEmailDisplayName": { - "type": "string" - }, - "systemEmailPassword": { - "type": "string" - }, - "systemEmailUser": { - "type": "string" - }, - "systemEmailConnectionHost": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - }, - "systemEmailIgnoreTLS": { - "type": "boolean" - }, - "systemEmailRequireTLS": { - "type": "boolean" - }, - "systemEmailRejectUnauthorized": { - "type": "boolean" - }, - "systemEmailTLSServername": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": [ - "" - ] - } - ] - } - }, - "required": [ - "to" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/team": { - "get": { - "tags": [ - "status-page" - ], - "summary": "List status pages for the caller's team", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page": { - "post": { - "tags": [ - "status-page" - ], - "summary": "Create a status page (logo upload optional)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "type": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "companyName": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "pattern": "^[a-zA-Z0-9_-]+$" - }, - "customDomain": { - "anyOf": [ - { - "type": "string", - "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" - }, - { - "nullable": true - } - ] - }, - "timezone": { - "type": "string" - }, - "color": { - "type": "string" - }, - "monitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - }, - "minItems": 1 - }, - "subMonitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - } - }, - "deleteSubmonitors": { - "type": "boolean" - }, - "isPublished": { - "type": "boolean" - }, - "showCharts": { - "type": "boolean" - }, - "showUptimePercentage": { - "type": "boolean" - }, - "showAdminLoginLink": { - "type": "boolean" - }, - "showInfrastructure": { - "type": "boolean" - }, - "removeLogo": { - "anyOf": [ - { - "type": "string", - "enum": [ - "true" - ] - }, - { - "type": "string", - "enum": [ - "false" - ] - } - ] - }, - "theme": { - "type": "string", - "enum": [ - "refined", - "modern", - "bold", - "editorial" - ] - }, - "themeMode": { - "type": "string", - "enum": [ - "auto", - "light", - "dark" - ] - }, - "logo": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "type", - "companyName", - "url", - "monitors", - "isPublished", - "showUptimePercentage", - "logo" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/{id}": { - "put": { - "tags": [ - "status-page" - ], - "summary": "Update a status page (logo upload optional)", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "type": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "companyName": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "pattern": "^[a-zA-Z0-9_-]+$" - }, - "customDomain": { - "anyOf": [ - { - "type": "string", - "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" - }, - { - "nullable": true - } - ] - }, - "timezone": { - "type": "string" - }, - "color": { - "type": "string" - }, - "monitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - }, - "minItems": 1 - }, - "subMonitors": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" - } - }, - "deleteSubmonitors": { - "type": "boolean" - }, - "isPublished": { - "type": "boolean" - }, - "showCharts": { - "type": "boolean" - }, - "showUptimePercentage": { - "type": "boolean" - }, - "showAdminLoginLink": { - "type": "boolean" - }, - "showInfrastructure": { - "type": "boolean" - }, - "removeLogo": { - "anyOf": [ - { - "type": "string", - "enum": [ - "true" - ] - }, - { - "type": "string", - "enum": [ - "false" - ] - } - ] - }, - "theme": { - "type": "string", - "enum": [ - "refined", - "modern", - "bold", - "editorial" - ] - }, - "themeMode": { - "type": "string", - "enum": [ - "auto", - "light", - "dark" - ] - }, - "logo": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "type", - "companyName", - "url", - "monitors", - "isPublished", - "showUptimePercentage", - "logo" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - }, - "delete": { - "tags": [ - "status-page" - ], - "summary": "Delete a status page", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - } - }, - "required": [ - "success", - "msg" - ] - }, - "example": { - "success": true, - "msg": "OK" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/resolve": { - "get": { - "tags": [ - "status-page" - ], - "summary": "Resolve a published status page by custom domain", - "parameters": [ - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "required": true, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "timeFrame", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "domain", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "404": { - "description": "Status page not found" - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - }, - "/status-page/{url}": { - "get": { - "tags": [ - "status-page" - ], - "summary": "Get a public status page by its URL slug", - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "url", - "in": "path" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "uptime", - "infrastructure" - ] - } - } - ] - }, - "required": true, - "name": "type", - "in": "query" - }, - { - "schema": { - "type": "number", - "nullable": true - }, - "required": false, - "name": "timeFrame", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - true - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - }, - "404": { - "description": "Status page not found" - }, - "500": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "enum": [ - false - ] - }, - "msg": { - "type": "string" - }, - "data": { - "nullable": true - } - }, - "required": [ - "success", - "msg" - ] - } - } - } - } - } - } - } - } + "openapi": "3.0.0", + "info": { + "title": "Checkmate API", + "version": "1.0.0", + "description": "Generated from Zod validation schemas. Source of truth: server/src/api/validation/*.ts" + }, + "servers": [ + { + "url": "/api/v1", + "description": "Current server" + } + ], + "tags": [ + { + "name": "auth", + "description": "Sign up, log in, password reset, and the authenticated user's profile." + }, + { + "name": "monitors", + "description": "Configure and inspect monitors (HTTP, port, ping, hardware, docker, game, gRPC) for the caller's team." + }, + { + "name": "checks", + "description": "Individual monitoring check results, including history, summaries, and bulk deletes." + }, + { + "name": "geo-checks", + "description": "Geographic check results for monitors with multi-region probing enabled." + }, + { + "name": "incidents", + "description": "Downtime incidents derived from monitor state changes, including filtering and CSV export." + }, + { + "name": "notifications", + "description": "Notification channels (email, webhook, Slack, Discord, PagerDuty, Matrix, Teams, Telegram, Pushover, Twilio) and test alerts." + }, + { + "name": "maintenance-window", + "description": "Scheduled maintenance windows during which monitors do not generate incidents or alerts." + }, + { + "name": "status-page", + "description": "Public status pages, their configuration, and the monitors they expose." + }, + { + "name": "settings", + "description": "Global application settings (admin/superadmin)." + }, + { + "name": "invite", + "description": "Team invitations and accepting them." + }, + { + "name": "queue", + "description": "Background job queue introspection and admin actions (admin/superadmin)." + }, + { + "name": "diagnostic", + "description": "System diagnostics for the running server (admin/superadmin)." + }, + { + "name": "logs", + "description": "Application logs for the running server (admin/superadmin)." + } + ], + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT" + } + }, + "schemas": { + "AuthPayload": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + }, + "token": { + "type": "string" + } + }, + "required": ["user"], + "example": { + "user": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": ["admin"], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + }, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + }, + "User": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "array", + "items": { + "type": "string" + } + }, + "teamId": { + "type": "string" + }, + "profileImage": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": ["_id", "firstName", "lastName", "email", "role", "createdAt", "updatedAt"], + "additionalProperties": { + "nullable": true + }, + "example": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": ["admin"], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + } + }, + "Incident": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789c" + }, + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "teamId": { + "type": "string", + "example": "65f1c2a4d8b9e01234567890" + }, + "startTime": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "endTime": { + "type": "string", + "nullable": true, + "example": "2026-04-15T03:34:00.000Z" + }, + "status": { + "type": "boolean", + "example": true, + "description": "true = resolved, false = ongoing" + }, + "message": { + "type": "string", + "nullable": true, + "example": "HTTP 503 from origin" + }, + "statusCode": { + "type": "number", + "nullable": true, + "example": 503 + }, + "resolutionType": { + "type": "string", + "nullable": true, + "enum": ["automatic", "manual", null], + "example": "automatic" + }, + "resolvedBy": { + "type": "string", + "nullable": true + }, + "resolvedByEmail": { + "type": "string", + "nullable": true + }, + "comment": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "updatedAt": { + "type": "string", + "example": "2026-04-15T03:34:00.000Z" + } + }, + "required": ["id", "monitorId", "teamId", "startTime", "endTime", "status", "resolutionType", "createdAt", "updatedAt"], + "additionalProperties": { + "nullable": true + } + }, + "IncidentSummary": { + "type": "object", + "properties": { + "total": { + "type": "number", + "example": 12 + }, + "totalActive": { + "type": "number", + "example": 1 + }, + "totalManualResolutions": { + "type": "number", + "example": 2 + }, + "totalAutomaticResolutions": { + "type": "number", + "example": 9 + }, + "avgResolutionTimeHours": { + "type": "number", + "example": 0.5 + }, + "topMonitor": { + "type": "object", + "nullable": true, + "properties": { + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "monitorName": { + "type": "string", + "nullable": true, + "example": "Marketing site" + }, + "incidentCount": { + "type": "number", + "example": 4 + } + }, + "required": ["monitorId", "monitorName", "incidentCount"] + }, + "latestIncidents": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IncidentSummaryItem" + } + } + }, + "required": [ + "total", + "totalActive", + "totalManualResolutions", + "totalAutomaticResolutions", + "avgResolutionTimeHours", + "topMonitor", + "latestIncidents" + ] + }, + "IncidentSummaryItem": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789c" + }, + "monitorId": { + "type": "string", + "example": "65f1c2a4d8b9e0123456789a" + }, + "monitorName": { + "type": "string", + "nullable": true, + "example": "Marketing site" + }, + "status": { + "type": "boolean", + "example": true + }, + "startTime": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + }, + "endTime": { + "type": "string", + "nullable": true, + "example": "2026-04-15T03:34:00.000Z" + }, + "resolutionType": { + "type": "string", + "nullable": true, + "enum": ["automatic", "manual", null], + "example": "automatic" + }, + "message": { + "type": "string", + "nullable": true, + "example": "HTTP 503 from origin" + }, + "statusCode": { + "type": "number", + "nullable": true, + "example": 503 + }, + "createdAt": { + "type": "string", + "example": "2026-04-15T03:21:00.000Z" + } + }, + "required": ["id", "monitorId", "monitorName", "status", "startTime", "endTime", "resolutionType", "message", "statusCode", "createdAt"] + }, + "Monitor": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "url": { + "type": "string" + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "status": { + "type": "string", + "enum": ["up", "down", "paused", "initializing", "maintenance", "breached"] + }, + "statusWindowSize": { + "type": "number" + }, + "statusWindowThreshold": { + "type": "number" + }, + "ignoreTlsErrors": { + "type": "boolean" + }, + "useAdvancedMatching": { + "type": "boolean" + }, + "jsonPath": { + "type": "string" + }, + "expectedValue": { + "type": "string" + }, + "matchMethod": { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + } + }, + "secret": { + "type": "string" + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "gameId": { + "type": "string" + }, + "grpcServiceName": { + "type": "string" + }, + "group": { + "type": "string", + "nullable": true + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + }, + "geoCheckInterval": { + "type": "number" + }, + "dnsServer": { + "type": "string" + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + }, + "teamId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "_id", + "name", + "type", + "url", + "isActive", + "interval", + "status", + "statusWindowSize", + "statusWindowThreshold", + "ignoreTlsErrors", + "useAdvancedMatching", + "notifications", + "tags", + "cpuAlertThreshold", + "memoryAlertThreshold", + "diskAlertThreshold", + "tempAlertThreshold", + "selectedDisks", + "geoCheckEnabled", + "geoCheckLocations", + "geoCheckInterval", + "teamId", + "userId", + "createdAt", + "updatedAt" + ], + "additionalProperties": { + "nullable": true + }, + "example": { + "_id": "65f1c2a4d8b9e0123456789a", + "name": "Marketing site", + "description": "Production marketing site monitored from the EU region", + "type": "http", + "url": "https://www.example.com", + "port": 443, + "isActive": true, + "interval": 60000, + "status": "up", + "statusWindowSize": 5, + "statusWindowThreshold": 3, + "ignoreTlsErrors": false, + "useAdvancedMatching": false, + "notifications": ["65f1c2a4d8b9e0123456789b"], + "cpuAlertThreshold": 90, + "memoryAlertThreshold": 90, + "diskAlertThreshold": 90, + "tempAlertThreshold": 80, + "selectedDisks": [], + "geoCheckEnabled": false, + "geoCheckLocations": [], + "geoCheckInterval": 300000, + "teamId": "65f1c2a4d8b9e01234567890", + "userId": "65f1c2a4d8b9e01234567891", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + } + }, + "NotificationChannelBody": { + "oneOf": [ + { + "$ref": "#/components/schemas/EmailNotification" + }, + { + "$ref": "#/components/schemas/WebhookNotification" + }, + { + "$ref": "#/components/schemas/SlackNotification" + }, + { + "$ref": "#/components/schemas/DiscordNotification" + }, + { + "$ref": "#/components/schemas/PagerDutyNotification" + }, + { + "$ref": "#/components/schemas/MatrixNotification" + }, + { + "$ref": "#/components/schemas/TeamsNotification" + }, + { + "$ref": "#/components/schemas/TelegramNotification" + }, + { + "$ref": "#/components/schemas/PushoverNotification" + }, + { + "$ref": "#/components/schemas/TwilioNotification" + }, + { + "$ref": "#/components/schemas/NtfyNotification" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "email": "#/components/schemas/EmailNotification", + "webhook": "#/components/schemas/WebhookNotification", + "slack": "#/components/schemas/SlackNotification", + "discord": "#/components/schemas/DiscordNotification", + "pager_duty": "#/components/schemas/PagerDutyNotification", + "matrix": "#/components/schemas/MatrixNotification", + "teams": "#/components/schemas/TeamsNotification", + "telegram": "#/components/schemas/TelegramNotification", + "pushover": "#/components/schemas/PushoverNotification", + "twilio": "#/components/schemas/TwilioNotification", + "ntfy": "#/components/schemas/NtfyNotification" + } + } + }, + "EmailNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["email"] + }, + "address": { + "type": "string", + "format": "email" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "Ops on-call email", + "type": "email", + "address": "alerts@example.com" + } + }, + "WebhookNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["webhook"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "Custom webhook", + "type": "webhook", + "address": "https://example.com/hooks/checkmate" + } + }, + "SlackNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["slack"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "#alerts", + "type": "slack", + "address": "https://hooks.slack.com/services/T000/B000/XXXX" + } + }, + "DiscordNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["discord"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "#status", + "type": "discord", + "address": "https://discord.com/api/webhooks/123/abc" + } + }, + "PagerDutyNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["pager_duty"] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "homeserverUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "roomId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "accessToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "PagerDuty primary", + "type": "pager_duty", + "address": "R01XXXXXXXXXXXXXXXXXXXXXXX" + } + }, + "MatrixNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["matrix"] + }, + "address": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "homeserverUrl": { + "type": "string", + "format": "uri" + }, + "roomId": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "homeserverUrl", "roomId", "accessToken"], + "example": { + "notificationName": "Matrix room", + "type": "matrix", + "homeserverUrl": "https://matrix.example.com", + "roomId": "!abc123:example.com", + "accessToken": "syt_xxx" + } + }, + "TeamsNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["teams"] + }, + "address": { + "type": "string", + "format": "uri" + } + }, + "required": ["notificationName", "type", "address"], + "example": { + "notificationName": "Teams ops channel", + "type": "teams", + "address": "https://outlook.office.com/webhook/..." + } + }, + "TelegramNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["telegram"] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "address", "accessToken"], + "example": { + "notificationName": "Telegram bot", + "type": "telegram", + "address": "-1001234567890", + "accessToken": "123456:ABC-DEF" + } + }, + "PushoverNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["pushover"] + }, + "address": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "address", "accessToken"], + "example": { + "notificationName": "Pushover personal", + "type": "pushover", + "address": "u1234567890abcdef", + "accessToken": "a1234567890abcdef" + } + }, + "TwilioNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["twilio"] + }, + "accountSid": { + "type": "string", + "minLength": 1 + }, + "accessToken": { + "type": "string", + "minLength": 1 + }, + "phone": { + "type": "string", + "minLength": 1 + }, + "twilioPhoneNumber": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "accountSid", "accessToken", "phone", "twilioPhoneNumber"], + "example": { + "notificationName": "Twilio SMS", + "type": "twilio", + "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "accessToken": "your-auth-token", + "phone": "+15551234567", + "twilioPhoneNumber": "+15557654321" + } + }, + "NtfyNotification": { + "type": "object", + "properties": { + "notificationName": { + "type": "string", + "minLength": 1 + }, + "type": { + "type": "string", + "enum": ["ntfy"] + }, + "address": { + "type": "string", + "format": "uri" + }, + "topic": { + "type": "string", + "minLength": 1 + } + }, + "required": ["notificationName", "type", "address", "topic"], + "example": { + "notificationName": "ntfy topic", + "type": "ntfy", + "address": "https://ntfy.sh", + "topic": "checkmate-alerts" + } + } + }, + "parameters": {} + }, + "paths": { + "/auth/register": { + "post": { + "tags": ["auth"], + "summary": "Register a new user (first user becomes superadmin)", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "profileImage": { + "type": "string", + "format": "binary" + }, + "inviteToken": { + "type": "string", + "default": "" + } + }, + "required": ["firstName", "lastName", "email", "password", "profileImage"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/AuthPayload" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/login": { + "post": { + "tags": ["auth"], + "summary": "Log in", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 1 + } + }, + "required": ["email", "password"] + }, + "example": { + "email": "ada@example.com", + "password": "S3cure!Passw0rd" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/AuthPayload" + } + }, + "required": ["success", "msg", "data"] + }, + "example": { + "success": true, + "msg": "OK", + "data": { + "user": { + "_id": "65f1c2a4d8b9e0123456789a", + "firstName": "Ada", + "lastName": "Lovelace", + "email": "ada@example.com", + "role": ["admin"], + "teamId": "65f1c2a4d8b9e01234567890", + "createdAt": "2026-04-01T10:00:00.000Z", + "updatedAt": "2026-04-15T14:30:00.000Z" + }, + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } + } + } + } + }, + "401": { + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/recovery/request": { + "post": { + "tags": ["auth"], + "summary": "Request a password recovery email", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + } + }, + "required": ["email"] + }, + "example": { + "email": "ada@example.com" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/recovery/validate": { + "post": { + "tags": ["auth"], + "summary": "Validate a password recovery token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "recoveryToken": { + "type": "string", + "minLength": 1 + } + }, + "required": ["recoveryToken"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/recovery/reset": { + "post": { + "tags": ["auth"], + "summary": "Reset password using a recovery token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "recoveryToken": { + "type": "string", + "minLength": 1 + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "confirm": { + "type": "string" + } + }, + "required": ["recoveryToken", "password"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users/superadmin": { + "get": { + "tags": ["auth"], + "summary": "Check whether a superadmin user exists", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "superAdminExists": { + "type": "boolean" + } + }, + "required": ["superAdminExists"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users": { + "get": { + "tags": ["auth"], + "summary": "List all users (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "post": { + "tags": ["auth"], + "summary": "Create a new user (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + }, + "profileImage": { + "type": "string", + "format": "binary" + } + }, + "required": ["firstName", "lastName", "email", "password", "role", "profileImage"] + } + } + } + }, + "responses": { + "201": { + "description": "User created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users/{userId}": { + "get": { + "tags": ["auth"], + "summary": "Get a user by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "404": { + "description": "User not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["auth"], + "summary": "Edit a user (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + } + }, + "required": ["firstName", "lastName", "role"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["auth"], + "summary": "Delete a user (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/users/{userId}/password": { + "patch": { + "tags": ["auth"], + "summary": "Change a user's password (superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "userId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + } + }, + "required": ["password"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/auth/user": { + "patch": { + "tags": ["auth"], + "summary": "Edit the currently authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "lastName": { + "type": "string", + "maxLength": 50, + "pattern": "^(?=.*[\\p{L}\\p{Sc}])[\\p{L}\\p{Sc}\\s'\\-().]+$/u" + }, + "email": { + "type": "string", + "format": "email" + }, + "profilePicture": { + "type": "string" + }, + "password": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "newPassword": { + "type": "string", + "minLength": 8, + "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/])[A-Za-z0-9!?@#$%^&*()\\-_=+[\\]{};:'\",.~`|\\\\/]+$" + }, + "profileImage": { + "type": "string", + "format": "binary" + } + }, + "required": ["profileImage"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["auth"], + "summary": "Delete the currently authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/checks/team/summary": { + "get": { + "tags": ["checks"], + "summary": "Aggregate check summary for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/checks/team": { + "get": { + "tags": ["checks"], + "summary": "List checks across the team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["all", "up", "down", "resolve"] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["checks"], + "summary": "Delete all checks for the team (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "deletedCount": { + "type": "number" + } + }, + "required": ["deletedCount"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/checks/{monitorId}": { + "get": { + "tags": ["checks"], + "summary": "List checks for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["all", "up", "down", "resolve"] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["checks"], + "summary": "Delete checks for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/diagnostic/system": { + "get": { + "tags": ["diagnostic"], + "summary": "Get system diagnostics (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/geo-checks/{monitorId}": { + "get": { + "tags": ["geo-checks"], + "summary": "Get geo check results for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["all", "up", "down", "resolve"] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "ack", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/team": { + "get": { + "tags": ["incidents"], + "summary": "List incidents for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": true, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"], + "default": "all" + }, + "required": false, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "integer", + "nullable": true, + "minimum": 0 + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "monitorId", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["manual", "automatic"] + }, + "required": false, + "name": "resolutionType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Incident" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/team/summary": { + "get": { + "tags": ["incidents"], + "summary": "Incident summary for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": false, + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/IncidentSummary" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/{incidentId}": { + "get": { + "tags": ["incidents"], + "summary": "Get an incident by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string" + }, + "required": true, + "name": "incidentId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "incident": { + "$ref": "#/components/schemas/Incident" + }, + "monitor": { + "nullable": true + }, + "user": { + "nullable": true + } + }, + "required": ["incident"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/incidents/{incidentId}/resolve": { + "put": { + "tags": ["incidents"], + "summary": "Manually resolve an incident (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string" + }, + "required": true, + "name": "incidentId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/invite/send": { + "post": { + "tags": ["invite"], + "summary": "Send an invite email (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + }, + "teamId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["email", "role", "teamId"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/invite/verify": { + "post": { + "tags": ["invite"], + "summary": "Verify an invite token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "token": { + "type": "string", + "minLength": 1 + } + }, + "required": ["token"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "role": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["email"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/invite": { + "post": { + "tags": ["invite"], + "summary": "Create an invite token (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "role": { + "type": "array", + "items": { + "type": "string", + "enum": ["user", "admin", "superadmin", "demo"] + }, + "minItems": 1 + }, + "teamId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["email", "role", "teamId"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + }, + "required": ["token"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/logs": { + "get": { + "tags": ["logs"], + "summary": "Get application logs (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window": { + "post": { + "tags": ["maintenance-window"], + "summary": "Create one or more maintenance windows", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitors": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "name": { + "type": "string", + "minLength": 1 + }, + "active": { + "type": "boolean" + }, + "duration": { + "type": "number", + "minimum": 1 + }, + "durationUnit": { + "type": "string", + "enum": ["seconds", "minutes", "hours", "days"] + }, + "start": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "end": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "repeat": { + "type": "number", + "minimum": 0 + }, + "expiry": { + "type": "string", + "nullable": true, + "format": "date-time" + } + }, + "required": ["monitors", "name", "duration", "durationUnit", "start", "end", "repeat"], + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window/team": { + "get": { + "tags": ["maintenance-window"], + "summary": "List maintenance windows for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "active", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "field", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": false, + "name": "order", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window/monitor/{monitorId}": { + "get": { + "tags": ["maintenance-window"], + "summary": "List maintenance windows for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/maintenance-window/{id}": { + "get": { + "tags": ["maintenance-window"], + "summary": "Get a maintenance window by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["maintenance-window"], + "summary": "Edit a maintenance window", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "active": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "repeat": { + "type": "number" + }, + "start": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "end": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "expiry": { + "type": "string", + "nullable": true, + "format": "date-time" + }, + "monitors": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "duration": { + "type": "number" + }, + "durationUnit": { + "type": "string", + "enum": ["seconds", "minutes", "hours", "days"] + } + }, + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["maintenance-window"], + "summary": "Delete a maintenance window", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/team": { + "get": { + "tags": ["monitors"], + "summary": "List monitors for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + } + } + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "required": false, + "name": "tags", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Monitor" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/team/with-checks": { + "get": { + "tags": ["monitors"], + "summary": "List team monitors with their most recent checks (paginated)", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "integer", + "nullable": true, + "minimum": 0 + }, + "required": false, + "name": "page", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "required": false, + "name": "rowsPerPage", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "required": false, + "name": "filter", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "field", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": false, + "name": "order", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + } + } + ] + }, + "required": false, + "name": "type", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "required": false, + "name": "tags", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "explain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/team/groups": { + "get": { + "tags": ["monitors"], + "summary": "List monitor groups for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/uptime/details/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get uptime details for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": true, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "normalize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/hardware/details/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get hardware metrics detail for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/pagespeed/details/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get PageSpeed detail for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/{monitorId}/geo-checks": { + "get": { + "tags": ["monitors"], + "summary": "Get geo check results for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["asc", "desc"] + }, + "required": false, + "name": "sortOrder", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": ["recent", "hour", "day", "week", "month", "all"] + }, + "required": false, + "name": "dateRange", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "numToDisplay", + "in": "query" + }, + { + "schema": { + "type": "boolean" + }, + "required": false, + "name": "normalize", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + } + ] + }, + "required": false, + "name": "continent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/pause/{monitorId}": { + "post": { + "tags": ["monitors"], + "summary": "Toggle pause state for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/certificate/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get SSL certificate info for a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "certificateDate": { + "type": "string" + } + }, + "required": ["certificateDate"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/notifications": { + "patch": { + "tags": ["monitors"], + "summary": "Bulk update notifications across monitors", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitorIds": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 100 + }, + "notificationIds": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 100 + }, + "action": { + "type": "string", + "enum": ["add", "remove", "set"] + } + }, + "required": ["monitorIds", "notificationIds", "action"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "modifiedCount": { + "type": "number" + } + }, + "required": ["modifiedCount"] + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors": { + "post": { + "tags": ["monitors"], + "summary": "Create a new monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "url": { + "type": "string", + "minLength": 1 + }, + "ignoreTlsErrors": { + "type": "boolean", + "default": false + }, + "useAdvancedMatching": { + "type": "boolean", + "default": false + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [] + }, + "secret": { + "type": "string" + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ], + "default": "" + }, + "strategy": { + "type": "string", + "enum": ["desktop", "mobile"] + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + } + }, + "required": ["name", "type", "url"] + } + } + } + }, + "responses": { + "200": { + "description": "Monitor created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["monitors"], + "summary": "Delete every monitor (superadmin only)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/demo": { + "post": { + "tags": ["monitors"], + "summary": "Insert preconfigured demo monitors", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "number" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/export/json": { + "get": { + "tags": ["monitors"], + "summary": "Export all team monitors as JSON", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/import/json": { + "post": { + "tags": ["monitors"], + "summary": "Import monitors from JSON", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "status": { + "type": "string", + "enum": ["up", "down", "paused", "initializing", "maintenance", "breached"], + "default": "initializing" + }, + "statusWindow": { + "type": "array", + "items": { + "type": "boolean" + }, + "default": [] + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "ignoreTlsErrors": { + "type": "boolean", + "default": false + }, + "useAdvancedMatching": { + "type": "boolean", + "default": false + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "url": { + "type": "string", + "minLength": 1 + }, + "port": { + "type": "number" + }, + "isActive": { + "type": "boolean", + "default": true + }, + "interval": { + "type": "number", + "default": 60000 + }, + "uptimePercentage": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [] + }, + "secret": { + "type": "string" + }, + "cpuAlertThreshold": { + "type": "number", + "default": 100 + }, + "cpuAlertCounter": { + "type": "number", + "default": 5 + }, + "memoryAlertThreshold": { + "type": "number", + "default": 100 + }, + "memoryAlertCounter": { + "type": "number", + "default": 5 + }, + "diskAlertThreshold": { + "type": "number", + "default": 100 + }, + "diskAlertCounter": { + "type": "number", + "default": 5 + }, + "tempAlertThreshold": { + "type": "number", + "default": 100 + }, + "tempAlertCounter": { + "type": "number", + "default": 5 + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ], + "default": "" + }, + "strategy": { + "type": "string", + "enum": ["desktop", "mobile"] + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + } + ], + "default": null + }, + "geoCheckEnabled": { + "type": "boolean", + "default": false + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + }, + "default": [] + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000, + "default": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": ["name", "type", "url"] + }, + "minItems": 1 + } + }, + "required": ["monitors"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "imported": { + "type": "number" + } + }, + "required": ["imported"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/games": { + "get": { + "tags": ["monitors"], + "summary": "List supported game-server types", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/monitors/{monitorId}": { + "get": { + "tags": ["monitors"], + "summary": "Get a monitor by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["monitors"], + "summary": "Edit a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] + }, + "url": { + "type": "string" + }, + "statusWindowSize": { + "type": "number", + "minimum": 1, + "maximum": 20, + "default": 5 + }, + "statusWindowThreshold": { + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 60 + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "interval": { + "type": "number" + }, + "notifications": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + } + }, + "secret": { + "type": "string" + }, + "ignoreTlsErrors": { + "type": "boolean" + }, + "useAdvancedMatching": { + "type": "boolean" + }, + "jsonPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "expectedValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "matchMethod": { + "anyOf": [ + { + "type": "string", + "enum": ["equal", "include", "regex"] + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "port": { + "type": "number", + "minimum": 1, + "maximum": 65535 + }, + "cpuAlertThreshold": { + "type": "number" + }, + "memoryAlertThreshold": { + "type": "number" + }, + "diskAlertThreshold": { + "type": "number" + }, + "tempAlertThreshold": { + "type": "number" + }, + "gameId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "grpcServiceName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "strategy": { + "type": "string", + "enum": ["desktop", "mobile"] + }, + "selectedDisks": { + "type": "array", + "items": { + "type": "string" + } + }, + "group": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "nullable": true + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "geoCheckEnabled": { + "type": "boolean" + }, + "geoCheckLocations": { + "type": "array", + "items": { + "type": "string", + "enum": ["EU", "NA", "AS", "SA", "AF", "OC"] + } + }, + "geoCheckInterval": { + "type": "number", + "minimum": 300000 + }, + "dnsServer": { + "type": "string", + "minLength": 1 + }, + "dnsRecordType": { + "type": "string", + "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["monitors"], + "summary": "Delete a monitor", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "monitorId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Monitor" + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications": { + "post": { + "tags": ["notifications"], + "summary": "Create a notification channel", + "description": "Create a notification channel of any supported type. The `type` field discriminates the body shape.", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/test/all": { + "post": { + "tags": ["notifications"], + "summary": "Send a test alert through every notification channel for the team", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "monitorId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["monitorId"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/test": { + "post": { + "tags": ["notifications"], + "summary": "Send a test alert through a single notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + }, + "required": ["success"], + "additionalProperties": { + "nullable": true + } + } + }, + "required": ["success", "msg", "data"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/team": { + "get": { + "tags": ["notifications"], + "summary": "List notification channels for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/notifications/{id}": { + "get": { + "tags": ["notifications"], + "summary": "Get a notification channel by id", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["notifications"], + "summary": "Delete a notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["notifications"], + "summary": "Edit a notification channel", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationChannelBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/jobs": { + "get": { + "tags": ["queue"], + "summary": "List queued monitor jobs (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/metrics": { + "get": { + "tags": ["queue"], + "summary": "Get queue runtime metrics (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/all-metrics": { + "get": { + "tags": ["queue"], + "summary": "Get queue metrics across all monitors (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/queue/flush": { + "post": { + "tags": ["queue"], + "summary": "Flush the monitor job queue (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/settings": { + "get": { + "tags": ["settings"], + "summary": "Get application settings", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "patch": { + "tags": ["settings"], + "summary": "Update application settings (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "checkTTL": { + "type": "integer", + "minimum": 1, + "maximum": 366 + }, + "systemEmailPort": { + "type": "number", + "nullable": true + }, + "pagespeedApiKey": { + "type": "string", + "nullable": true + }, + "language": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "systemEmailHost": { + "type": "string", + "nullable": true + }, + "systemEmailAddress": { + "type": "string", + "nullable": true + }, + "systemEmailDisplayName": { + "type": "string", + "nullable": true, + "maxLength": 100 + }, + "systemEmailPassword": { + "type": "string", + "nullable": true + }, + "systemEmailUser": { + "type": "string", + "nullable": true + }, + "systemEmailConnectionHost": { + "type": "string", + "nullable": true + }, + "systemEmailTLSServername": { + "type": "string", + "nullable": true + }, + "showURL": { + "type": "boolean" + }, + "systemEmailSecure": { + "type": "boolean" + }, + "systemEmailPool": { + "type": "boolean" + }, + "systemEmailIgnoreTLS": { + "type": "boolean" + }, + "systemEmailRequireTLS": { + "type": "boolean" + }, + "systemEmailRejectUnauthorized": { + "type": "boolean" + }, + "globalThresholds": { + "type": "object", + "properties": { + "cpu": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "memory": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "disk": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "temperature": { + "type": "number", + "minimum": 1, + "maximum": 150 + } + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/settings/test-email": { + "post": { + "tags": ["settings"], + "summary": "Send a test email using current SMTP settings (admin/superadmin)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "to": { + "type": "string", + "minLength": 1 + }, + "systemEmailHost": { + "type": "string" + }, + "systemEmailPort": { + "type": "number" + }, + "systemEmailSecure": { + "type": "boolean" + }, + "systemEmailPool": { + "type": "boolean" + }, + "systemEmailAddress": { + "type": "string" + }, + "systemEmailDisplayName": { + "type": "string" + }, + "systemEmailPassword": { + "type": "string" + }, + "systemEmailUser": { + "type": "string" + }, + "systemEmailConnectionHost": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + }, + "systemEmailIgnoreTLS": { + "type": "boolean" + }, + "systemEmailRequireTLS": { + "type": "boolean" + }, + "systemEmailRejectUnauthorized": { + "type": "boolean" + }, + "systemEmailTLSServername": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "enum": [""] + } + ] + } + }, + "required": ["to"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/team": { + "get": { + "tags": ["status-page"], + "summary": "List status pages for the caller's team", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page": { + "post": { + "tags": ["status-page"], + "summary": "Create a status page (logo upload optional)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "type": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "companyName": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "customDomain": { + "anyOf": [ + { + "type": "string", + "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" + }, + { + "nullable": true + } + ] + }, + "timezone": { + "type": "string" + }, + "color": { + "type": "string" + }, + "monitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1 + }, + "subMonitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + } + }, + "deleteSubmonitors": { + "type": "boolean" + }, + "isPublished": { + "type": "boolean" + }, + "showCharts": { + "type": "boolean" + }, + "showUptimePercentage": { + "type": "boolean" + }, + "showAdminLoginLink": { + "type": "boolean" + }, + "showInfrastructure": { + "type": "boolean" + }, + "removeLogo": { + "anyOf": [ + { + "type": "string", + "enum": ["true"] + }, + { + "type": "string", + "enum": ["false"] + } + ] + }, + "theme": { + "type": "string", + "enum": ["refined", "modern", "bold", "editorial"] + }, + "themeMode": { + "type": "string", + "enum": ["auto", "light", "dark"] + }, + "logo": { + "type": "string", + "format": "binary" + } + }, + "required": ["type", "companyName", "url", "monitors", "isPublished", "showUptimePercentage", "logo"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/{id}": { + "put": { + "tags": ["status-page"], + "summary": "Update a status page (logo upload optional)", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "type": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "companyName": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "customDomain": { + "anyOf": [ + { + "type": "string", + "pattern": "^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$" + }, + { + "nullable": true + } + ] + }, + "timezone": { + "type": "string" + }, + "color": { + "type": "string" + }, + "monitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1 + }, + "subMonitors": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + } + }, + "deleteSubmonitors": { + "type": "boolean" + }, + "isPublished": { + "type": "boolean" + }, + "showCharts": { + "type": "boolean" + }, + "showUptimePercentage": { + "type": "boolean" + }, + "showAdminLoginLink": { + "type": "boolean" + }, + "showInfrastructure": { + "type": "boolean" + }, + "removeLogo": { + "anyOf": [ + { + "type": "string", + "enum": ["true"] + }, + { + "type": "string", + "enum": ["false"] + } + ] + }, + "theme": { + "type": "string", + "enum": ["refined", "modern", "bold", "editorial"] + }, + "themeMode": { + "type": "string", + "enum": ["auto", "light", "dark"] + }, + "logo": { + "type": "string", + "format": "binary" + } + }, + "required": ["type", "companyName", "url", "monitors", "isPublished", "showUptimePercentage", "logo"] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + }, + "delete": { + "tags": ["status-page"], + "summary": "Delete a status page", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + } + }, + "required": ["success", "msg"] + }, + "example": { + "success": true, + "msg": "OK" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/resolve": { + "get": { + "tags": ["status-page"], + "summary": "Resolve a published status page by custom domain", + "parameters": [ + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "required": true, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "timeFrame", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "required": false, + "name": "domain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "404": { + "description": "Status page not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + }, + "/status-page/{url}": { + "get": { + "tags": ["status-page"], + "summary": "Get a public status page by its URL slug", + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "name": "url", + "in": "path" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": ["uptime", "infrastructure"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["uptime", "infrastructure"] + } + } + ] + }, + "required": true, + "name": "type", + "in": "query" + }, + { + "schema": { + "type": "number", + "nullable": true + }, + "required": false, + "name": "timeFrame", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [true] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + }, + "404": { + "description": "Status page not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [false] + }, + "msg": { + "type": "string" + }, + "data": { + "nullable": true + } + }, + "required": ["success", "msg"] + } + } + } + } + } + } + } + } } From 0aef8b652f53c21c6127c527d3e51a4616bab213 Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:58:45 -0400 Subject: [PATCH 4/9] fix: use partial index for status page customDomain Replace the sparse unique index with a partial index so multiple status pages without a custom domain no longer collide on null values. --- .../status-page-repository.mongo.ts | 28 +++++++++++++++---- .../domain/status-pages/status-page.model.ts | 11 ++++++-- .../unit/services/statusPageService.test.ts | 9 ++++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/server/src/domain/status-pages/status-page-repository.mongo.ts b/server/src/domain/status-pages/status-page-repository.mongo.ts index 78e43a3bd..2dedca4ef 100644 --- a/server/src/domain/status-pages/status-page-repository.mongo.ts +++ b/server/src/domain/status-pages/status-page-repository.mongo.ts @@ -78,9 +78,10 @@ class MongoStatusPagesRepository implements IStatusPagesRepository { create = async (userId: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise => { const { logo, customDomain, ...restData } = data; void logo; + const normalizedCustomDomain = normalizeStatusPageDomain(customDomain); const statusPage = new StatusPageModel({ ...restData, - customDomain: normalizeStatusPageDomain(customDomain), + ...(normalizedCustomDomain ? { customDomain: normalizedCustomDomain } : {}), userId, teamId, }); @@ -133,20 +134,35 @@ class MongoStatusPagesRepository implements IStatusPagesRepository { ): Promise => { const { logo, removeLogo, customDomain, ...restPatch } = patch; void logo; - const updateData: StatusPageUpdateData = { ...restPatch }; + const setData: StatusPageUpdateData = { ...restPatch }; + const unsetData: Record = {}; + if (customDomain !== undefined) { - updateData.customDomain = normalizeStatusPageDomain(customDomain); + const normalizedCustomDomain = normalizeStatusPageDomain(customDomain); + if (normalizedCustomDomain) { + setData.customDomain = normalizedCustomDomain; + } else { + unsetData.customDomain = 1; + } } if (image) { - updateData.logo = { + setData.logo = { data: image.buffer as Buffer, contentType: image.mimetype, }; } else if (removeLogo === "true") { - updateData.logo = null; + setData.logo = null; } - const statusPage = await StatusPageModel.findOneAndUpdate({ teamId, _id: id }, updateData, { + const updateQuery = + unsetData.customDomain !== undefined + ? { + $set: setData, + $unset: unsetData, + } + : setData; + + const statusPage = await StatusPageModel.findOneAndUpdate({ teamId, _id: id }, updateQuery, { new: true, }); diff --git a/server/src/domain/status-pages/status-page.model.ts b/server/src/domain/status-pages/status-page.model.ts index bd6801318..3337fe998 100644 --- a/server/src/domain/status-pages/status-page.model.ts +++ b/server/src/domain/status-pages/status-page.model.ts @@ -67,11 +67,8 @@ const StatusPageSchema = new Schema( }, customDomain: { type: String, - default: null, lowercase: true, trim: true, - sparse: true, - unique: true, }, timezone: { type: String, @@ -136,6 +133,14 @@ const StatusPageSchema = new Schema( { timestamps: true } ); +StatusPageSchema.index( + { customDomain: 1 }, + { + unique: true, + partialFilterExpression: { customDomain: { $type: "string" } }, + } +); + const StatusPageModel = model("StatusPage", StatusPageSchema); export type { StatusPageDocument }; diff --git a/server/test/unit/services/statusPageService.test.ts b/server/test/unit/services/statusPageService.test.ts index 7359b015a..b2c2cdcee 100644 --- a/server/test/unit/services/statusPageService.test.ts +++ b/server/test/unit/services/statusPageService.test.ts @@ -134,6 +134,15 @@ describe("StatusPageService", () => { expect(repo.create).toHaveBeenCalledWith("user-1", "team-1", undefined, expect.objectContaining({ customDomain: "status.example.com" })); }); + + it("allows multiple status pages without a custom domain", async () => { + const { service, repo } = createService(true); + + await service.createStatusPage("user-1", "team-1", undefined, { companyName: "First" }); + await service.createStatusPage("user-1", "team-1", undefined, { companyName: "Second" }); + + expect(repo.create).toHaveBeenCalledTimes(2); + }); }); describe("getStatusPagesByTeamId", () => { From 6a1ab622b3b947994499e8746c1ebd4272fd135c Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:58:50 -0400 Subject: [PATCH 5/9] fix: scope custom domain CORS to public status page routes Only allow registered custom domain origins on public GET/OPTIONS status page API routes instead of the entire application API surface. --- .../api/middleware/statusPagePublicApiPath.ts | 24 +++++++++++++++++++ server/src/app.ts | 23 +++++++++++------- .../statusPagePublicApiPath.test.ts | 19 +++++++++++++++ 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 server/src/api/middleware/statusPagePublicApiPath.ts create mode 100644 server/test/unit/middleware/statusPagePublicApiPath.test.ts diff --git a/server/src/api/middleware/statusPagePublicApiPath.ts b/server/src/api/middleware/statusPagePublicApiPath.ts new file mode 100644 index 000000000..a4b5e42d1 --- /dev/null +++ b/server/src/api/middleware/statusPagePublicApiPath.ts @@ -0,0 +1,24 @@ +const PUBLIC_STATUS_PAGE_API_PREFIX = "/api/v1/status-page"; + +export const isPublicStatusPageApiPath = (method: string, path: string): boolean => { + if (!path.startsWith(PUBLIC_STATUS_PAGE_API_PREFIX)) { + return false; + } + + if (method !== "GET" && method !== "OPTIONS") { + return false; + } + + const subPath = path.slice(PUBLIC_STATUS_PAGE_API_PREFIX.length).split("?")[0] ?? ""; + const slug = subPath.replace(/^\//, ""); + + if (slug === "resolve") { + return true; + } + + if (!slug || slug === "team" || slug.includes("/")) { + return false; + } + + return true; +}; diff --git a/server/src/app.ts b/server/src/app.ts index 5e61a0ab0..3bafd4aec 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -13,6 +13,7 @@ import { InitializedServices } from "@/config/services.js"; import { InitializedControllers } from "@/config/controllers.js"; import { EnvConfig } from "@/domain/app-settings/app-settings.service.js"; import { createStatusPageCorsOrigin } from "@/api/middleware/statusPageCorsOrigin.js"; +import { isPublicStatusPageApiPath } from "@/api/middleware/statusPagePublicApiPath.js"; export const createApp = ({ services, @@ -29,17 +30,23 @@ export const createApp = ({ }) => { const allowedOrigin = envSettings.clientHost; const app = express(); + const defaultCorsOptions = { + origin: allowedOrigin, + methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS", + allowedHeaders: ["Content-Type", "Authorization", "Accept-Language"], + credentials: true, + } as const; + const publicStatusPageCorsOrigin = createStatusPageCorsOrigin(allowedOrigin, services.statusPagesRepository); app.use(generalApiLimiter); - app.use( - cors({ - origin: createStatusPageCorsOrigin(allowedOrigin, services.statusPagesRepository), - methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS", - allowedHeaders: ["Content-Type", "Authorization", "Accept-Language"], - credentials: true, - }) - ); + app.use((req, res, next) => { + const corsOptions = isPublicStatusPageApiPath(req.method, req.path) + ? { ...defaultCorsOptions, origin: publicStatusPageCorsOrigin } + : defaultCorsOptions; + + return cors(corsOptions)(req, res, next); + }); app.use(express.static(frontendPath)); diff --git a/server/test/unit/middleware/statusPagePublicApiPath.test.ts b/server/test/unit/middleware/statusPagePublicApiPath.test.ts new file mode 100644 index 000000000..95a799593 --- /dev/null +++ b/server/test/unit/middleware/statusPagePublicApiPath.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from "@jest/globals"; +import { isPublicStatusPageApiPath } from "../../../src/api/middleware/statusPagePublicApiPath.ts"; + +describe("isPublicStatusPageApiPath", () => { + it("allows public resolve and slug routes", () => { + expect(isPublicStatusPageApiPath("GET", "/api/v1/status-page/resolve")).toBe(true); + expect(isPublicStatusPageApiPath("OPTIONS", "/api/v1/status-page/resolve")).toBe(true); + expect(isPublicStatusPageApiPath("GET", "/api/v1/status-page/my-status-page")).toBe(true); + expect(isPublicStatusPageApiPath("GET", "/api/v1/status-page/my-status-page?type=uptime")).toBe(true); + }); + + it("rejects authenticated and mutating status page routes", () => { + expect(isPublicStatusPageApiPath("GET", "/api/v1/status-page/team")).toBe(false); + expect(isPublicStatusPageApiPath("POST", "/api/v1/status-page")).toBe(false); + expect(isPublicStatusPageApiPath("PUT", "/api/v1/status-page/64b1f2a3c4d5e6f7a8b9c0d1")).toBe(false); + expect(isPublicStatusPageApiPath("DELETE", "/api/v1/status-page/64b1f2a3c4d5e6f7a8b9c0d1")).toBe(false); + expect(isPublicStatusPageApiPath("GET", "/api/v1/monitors")).toBe(false); + }); +}); From 120708ed47c56027175f08cb4d9efc98b595d809 Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:58:59 -0400 Subject: [PATCH 6/9] perf: cache custom domain CORS origin lookups Avoid hitting the database on every cross-origin request by caching published custom domain checks for five minutes. --- .../api/middleware/statusPageCorsOrigin.ts | 22 ++++++- .../middleware/statusPageCorsOrigin.test.ts | 60 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 server/test/unit/middleware/statusPageCorsOrigin.test.ts diff --git a/server/src/api/middleware/statusPageCorsOrigin.ts b/server/src/api/middleware/statusPageCorsOrigin.ts index 7a48ca45f..acc515bf9 100644 --- a/server/src/api/middleware/statusPageCorsOrigin.ts +++ b/server/src/api/middleware/statusPageCorsOrigin.ts @@ -2,7 +2,16 @@ import type { CorsOptions } from "cors"; import type { IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; +const CUSTOM_DOMAIN_CORS_CACHE_TTL_MS = 5 * 60 * 1000; + +type CustomDomainCorsCacheEntry = { + allowed: boolean; + expiresAt: number; +}; + export const createStatusPageCorsOrigin = (clientHost: string, statusPagesRepository: IStatusPagesRepository): CorsOptions["origin"] => { + const cache = new Map(); + return (origin, callback) => { if (!origin) { callback(null, true); @@ -27,10 +36,21 @@ export const createStatusPageCorsOrigin = (clientHost: string, statusPagesReposi return; } + const cached = cache.get(customDomain); + if (cached && cached.expiresAt > Date.now()) { + callback(null, cached.allowed ? origin : false); + return; + } + statusPagesRepository .findByCustomDomain(customDomain) .then((statusPage) => { - callback(null, statusPage.isPublished ? origin : false); + const allowed = statusPage.isPublished; + cache.set(customDomain, { + allowed, + expiresAt: Date.now() + CUSTOM_DOMAIN_CORS_CACHE_TTL_MS, + }); + callback(null, allowed ? origin : false); }) .catch(() => { callback(null, false); diff --git a/server/test/unit/middleware/statusPageCorsOrigin.test.ts b/server/test/unit/middleware/statusPageCorsOrigin.test.ts new file mode 100644 index 000000000..b0f92cac4 --- /dev/null +++ b/server/test/unit/middleware/statusPageCorsOrigin.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, it, jest, beforeEach } from "@jest/globals"; +import { createStatusPageCorsOrigin } from "../../../src/api/middleware/statusPageCorsOrigin.ts"; +import type { IStatusPagesRepository } from "../../../src/domain/status-pages/status-page-repository.interface.ts"; +import type { StatusPage } from "../../../src/domain/status-pages/status-page.type.ts"; + +const makeStatusPage = (overrides?: Partial): StatusPage => + ({ + id: "sp-1", + isPublished: true, + customDomain: "status.example.com", + ...overrides, + }) as StatusPage; + +const createRepo = () => + ({ + findByCustomDomain: jest.fn().mockResolvedValue(makeStatusPage()), + }) as unknown as jest.Mocked>; + +const invokeOrigin = (originFn: ReturnType, origin: string): Promise => + new Promise((resolve, reject) => { + originFn?.(origin, (error, result) => { + if (error) { + reject(error); + return; + } + resolve(result ?? false); + }); + }); + +describe("createStatusPageCorsOrigin", () => { + let repo: jest.Mocked>; + + beforeEach(() => { + repo = createRepo(); + }); + + it("allows the configured client host without a repository lookup", async () => { + const originFn = createStatusPageCorsOrigin("https://checkmate.example.com", repo as IStatusPagesRepository); + + await expect(invokeOrigin(originFn, "https://checkmate.example.com")).resolves.toBe(true); + expect(repo.findByCustomDomain).not.toHaveBeenCalled(); + }); + + it("caches published custom domain lookups", async () => { + const originFn = createStatusPageCorsOrigin("https://checkmate.example.com", repo as IStatusPagesRepository); + + await expect(invokeOrigin(originFn, "https://status.example.com")).resolves.toBe("https://status.example.com"); + await expect(invokeOrigin(originFn, "https://status.example.com")).resolves.toBe("https://status.example.com"); + + expect(repo.findByCustomDomain).toHaveBeenCalledTimes(1); + expect(repo.findByCustomDomain).toHaveBeenCalledWith("status.example.com"); + }); + + it("rejects unpublished custom domains", async () => { + repo.findByCustomDomain.mockResolvedValue(makeStatusPage({ isPublished: false })); + const originFn = createStatusPageCorsOrigin("https://checkmate.example.com", repo as IStatusPagesRepository); + + await expect(invokeOrigin(originFn, "https://status.example.com")).resolves.toBe(false); + }); +}); From 8af13b04ecb4305ea11b37e42db649b262a664e5 Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:59:01 -0400 Subject: [PATCH 7/9] fix: derive custom domain URL protocol from client host Use the configured client host protocol instead of hardcoding https for custom domain status page links. --- client/src/Utils/statusPageUrl.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/client/src/Utils/statusPageUrl.ts b/client/src/Utils/statusPageUrl.ts index 9c898ee34..ff19f87c6 100644 --- a/client/src/Utils/statusPageUrl.ts +++ b/client/src/Utils/statusPageUrl.ts @@ -2,6 +2,23 @@ import { PUBLIC_STATUS_PAGE_PREFIX, type StatusPage } from "@/Types/StatusPage"; const CLIENT_HOST = import.meta.env.VITE_APP_CLIENT_HOST as string | undefined; +const getClientOriginProtocol = (): string => { + const source = + CLIENT_HOST || (typeof window !== "undefined" ? window.location.origin : undefined); + if (!source) { + return "https:"; + } + + try { + return new URL(source).protocol; + } catch { + return "https:"; + } +}; + +const buildCustomDomainOrigin = (customDomain: string): string => + `${getClientOriginProtocol()}//${customDomain}`; + export const getAppHostname = (): string | null => { const source = CLIENT_HOST || (typeof window !== "undefined" ? window.location.origin : undefined); @@ -33,7 +50,7 @@ export const getStatusPagePublicPath = ( statusPage: Pick ): string => { if (statusPage.customDomain) { - return `https://${statusPage.customDomain}`; + return buildCustomDomainOrigin(statusPage.customDomain); } return `${PUBLIC_STATUS_PAGE_PREFIX}/${statusPage.url}`; @@ -43,7 +60,7 @@ export const getStatusPagePublicUrl = ( statusPage: Pick ): string => { if (statusPage.customDomain) { - return `https://${statusPage.customDomain}`; + return buildCustomDomainOrigin(statusPage.customDomain); } if (typeof window !== "undefined") { From ef049b652155cf5920151166bf27d03ae2910870 Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:55:10 -0400 Subject: [PATCH 8/9] fix: resolve CORS TypeScript error and format server files Type defaultCorsOptions as CorsOptions so allowedHeaders is compatible with the cors middleware. Format files from develop merge for CI. --- server/src/api/middleware/handleErrors.ts | 3 +-- server/src/api/routes/authRoute.ts | 8 +++++++- server/src/app.ts | 6 +++--- server/test/unit/middleware/upload.test.ts | 5 ++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/server/src/api/middleware/handleErrors.ts b/server/src/api/middleware/handleErrors.ts index 2f817b2af..239349b90 100755 --- a/server/src/api/middleware/handleErrors.ts +++ b/server/src/api/middleware/handleErrors.ts @@ -7,8 +7,7 @@ import { AppError } from "@/utils/AppError.js"; const multerErrorStatus = (error: MulterError): number => (error.code === "LIMIT_FILE_SIZE" ? 413 : 400); const handleErrors = (error: unknown, req: Request, res: Response, _next: NextFunction) => { - const status = - error instanceof MulterError ? multerErrorStatus(error) : error instanceof AppError ? error.status || 500 : 500; + const status = error instanceof MulterError ? multerErrorStatus(error) : error instanceof AppError ? error.status || 500 : 500; const message = error instanceof AppError ? error.message : error instanceof Error ? error.message : "Server error"; const service = error instanceof AppError ? error.service : error instanceof MulterError ? "uploadMiddleware" : "unknownService"; const method = error instanceof AppError ? error.method : "unknownMethod"; diff --git a/server/src/api/routes/authRoute.ts b/server/src/api/routes/authRoute.ts index e8ed31f2e..3b202a502 100644 --- a/server/src/api/routes/authRoute.ts +++ b/server/src/api/routes/authRoute.ts @@ -30,7 +30,13 @@ class AuthRoutes { this.router.patch("/users/:userId/password", verifyJWT, isAllowed(["superadmin"]), this.authController.editUserPasswordById); this.router.delete("/users/:userId", verifyJWT, isAllowed(["admin", "superadmin"]), this.authController.deleteUserById); - this.router.patch("/user", verifyJWT, imageUpload.single("profileImage"), isAllowed(["admin", "superadmin", "user"]), this.authController.editUser); + this.router.patch( + "/user", + verifyJWT, + imageUpload.single("profileImage"), + isAllowed(["admin", "superadmin", "user"]), + this.authController.editUser + ); this.router.delete("/user", verifyJWT, isAllowed(["admin", "superadmin", "user"]), this.authController.deleteUser); } diff --git a/server/src/app.ts b/server/src/app.ts index 3bafd4aec..907c0f77d 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -1,6 +1,6 @@ import express from "express"; import path from "path"; -import cors from "cors"; +import cors, { type CorsOptions } from "cors"; import helmet from "helmet"; import compression from "compression"; import cookieParser from "cookie-parser"; @@ -30,12 +30,12 @@ export const createApp = ({ }) => { const allowedOrigin = envSettings.clientHost; const app = express(); - const defaultCorsOptions = { + const defaultCorsOptions: CorsOptions = { origin: allowedOrigin, methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS", allowedHeaders: ["Content-Type", "Authorization", "Accept-Language"], credentials: true, - } as const; + }; const publicStatusPageCorsOrigin = createStatusPageCorsOrigin(allowedOrigin, services.statusPagesRepository); app.use(generalApiLimiter); diff --git a/server/test/unit/middleware/upload.test.ts b/server/test/unit/middleware/upload.test.ts index bbdfb205c..dc172d3da 100644 --- a/server/test/unit/middleware/upload.test.ts +++ b/server/test/unit/middleware/upload.test.ts @@ -6,10 +6,9 @@ import { AppError } from "../../../src/utils/AppError.ts"; // Reaches into the multer instance config to exercise the fileFilter/limits in isolation. // Guards against regressing GHSA-9xvg-x28f-m78m (pre-auth DoS via unbounded uploads). -const config = (imageUpload as unknown as { fileFilter: Function; limits: { fileSize: number; files: number } }); +const config = imageUpload as unknown as { fileFilter: Function; limits: { fileSize: number; files: number } }; -const makeFile = (mimetype: string): Express.Multer.File => - ({ fieldname: "profileImage", originalname: "x", mimetype }) as Express.Multer.File; +const makeFile = (mimetype: string): Express.Multer.File => ({ fieldname: "profileImage", originalname: "x", mimetype }) as Express.Multer.File; const runFilter = (mimetype: string): Promise<{ error: unknown; accepted: unknown }> => new Promise((resolve) => { From 517139cbf48283af1c9573ca7acf2cfc62bcfcc4 Mon Sep 17 00:00:00 2001 From: Ian Troisi <56521951+Cincinnatus101010@users.noreply.github.com> Date: Thu, 11 Jun 2026 14:48:31 -0400 Subject: [PATCH 9/9] fix: cache negative custom domain CORS lookups Use a shorter TTL for rejected origins so unknown domains do not hit the database on every cross-origin request. --- .../api/middleware/statusPageCorsOrigin.ts | 19 ++++++++++++++----- .../middleware/statusPageCorsOrigin.test.ts | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/server/src/api/middleware/statusPageCorsOrigin.ts b/server/src/api/middleware/statusPageCorsOrigin.ts index acc515bf9..338c43472 100644 --- a/server/src/api/middleware/statusPageCorsOrigin.ts +++ b/server/src/api/middleware/statusPageCorsOrigin.ts @@ -2,16 +2,27 @@ import type { CorsOptions } from "cors"; import type { IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; -const CUSTOM_DOMAIN_CORS_CACHE_TTL_MS = 5 * 60 * 1000; +const CUSTOM_DOMAIN_CORS_POSITIVE_CACHE_TTL_MS = 5 * 60 * 1000; +const CUSTOM_DOMAIN_CORS_NEGATIVE_CACHE_TTL_MS = 60 * 1000; type CustomDomainCorsCacheEntry = { allowed: boolean; expiresAt: number; }; +const getCustomDomainCorsCacheTtlMs = (allowed: boolean): number => + allowed ? CUSTOM_DOMAIN_CORS_POSITIVE_CACHE_TTL_MS : CUSTOM_DOMAIN_CORS_NEGATIVE_CACHE_TTL_MS; + export const createStatusPageCorsOrigin = (clientHost: string, statusPagesRepository: IStatusPagesRepository): CorsOptions["origin"] => { const cache = new Map(); + const cacheOriginResult = (customDomain: string, allowed: boolean) => { + cache.set(customDomain, { + allowed, + expiresAt: Date.now() + getCustomDomainCorsCacheTtlMs(allowed), + }); + }; + return (origin, callback) => { if (!origin) { callback(null, true); @@ -46,13 +57,11 @@ export const createStatusPageCorsOrigin = (clientHost: string, statusPagesReposi .findByCustomDomain(customDomain) .then((statusPage) => { const allowed = statusPage.isPublished; - cache.set(customDomain, { - allowed, - expiresAt: Date.now() + CUSTOM_DOMAIN_CORS_CACHE_TTL_MS, - }); + cacheOriginResult(customDomain, allowed); callback(null, allowed ? origin : false); }) .catch(() => { + cacheOriginResult(customDomain, false); callback(null, false); }); }; diff --git a/server/test/unit/middleware/statusPageCorsOrigin.test.ts b/server/test/unit/middleware/statusPageCorsOrigin.test.ts index b0f92cac4..88a854845 100644 --- a/server/test/unit/middleware/statusPageCorsOrigin.test.ts +++ b/server/test/unit/middleware/statusPageCorsOrigin.test.ts @@ -56,5 +56,19 @@ describe("createStatusPageCorsOrigin", () => { const originFn = createStatusPageCorsOrigin("https://checkmate.example.com", repo as IStatusPagesRepository); await expect(invokeOrigin(originFn, "https://status.example.com")).resolves.toBe(false); + await expect(invokeOrigin(originFn, "https://status.example.com")).resolves.toBe(false); + + expect(repo.findByCustomDomain).toHaveBeenCalledTimes(1); + }); + + it("caches unknown custom domain lookups", async () => { + repo.findByCustomDomain.mockRejectedValue(new Error("Status page not found")); + const originFn = createStatusPageCorsOrigin("https://checkmate.example.com", repo as IStatusPagesRepository); + + await expect(invokeOrigin(originFn, "https://unknown.example.com")).resolves.toBe(false); + await expect(invokeOrigin(originFn, "https://unknown.example.com")).resolves.toBe(false); + + expect(repo.findByCustomDomain).toHaveBeenCalledTimes(1); + expect(repo.findByCustomDomain).toHaveBeenCalledWith("unknown.example.com"); }); });