From 124a8c0b07ba21711e3844818fd8f84588006d00 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 6 Mar 2026 10:37:29 -0800 Subject: [PATCH 1/5] ping type globalping checks --- client/src/Pages/CreateMonitor/index.tsx | 2 +- client/src/Pages/Uptime/Details/index.tsx | 12 ++- .../geo-checks/MongoGeoChecksRepository.ts | 7 +- .../src/service/business/geoChecksService.ts | 2 +- server/src/service/business/monitorService.ts | 2 +- .../SuperSimpleQueue/SuperSimpleQueue.ts | 9 ++- .../SuperSimpleQueueHelper.ts | 11 ++- .../infrastructure/globalPingService.ts | 74 +++++++++++++------ server/src/types/geoCheck.ts | 1 + 9 files changed, 80 insertions(+), 40 deletions(-) diff --git a/client/src/Pages/CreateMonitor/index.tsx b/client/src/Pages/CreateMonitor/index.tsx index 34e141795..dac5189ba 100644 --- a/client/src/Pages/CreateMonitor/index.tsx +++ b/client/src/Pages/CreateMonitor/index.tsx @@ -885,7 +885,7 @@ const CreateMonitorPage = () => { /> )} - {watchedType === "http" && ( + {(watchedType === "http" || watchedType === "ping") && ( { ); const geoChecksUrl = useMemo(() => { - if (!monitorId || monitor?.type !== "http" || !monitor?.geoCheckEnabled) { + if ( + !monitorId || + (monitor?.type !== "http" && monitor?.type !== "ping") || + !monitor?.geoCheckEnabled + ) { return null; } const params = new URLSearchParams(); @@ -141,7 +145,11 @@ const UptimeDetailsPage = () => { // Fetch paginated geo checks for the table const geoChecksTableUrl = useMemo(() => { - if (!monitorId || monitor?.type !== "http" || !monitor?.geoCheckEnabled) { + if ( + !monitorId || + (monitor?.type !== "http" && monitor?.type !== "ping") || + !monitor?.geoCheckEnabled + ) { return null; } const params = new URLSearchParams(); diff --git a/server/src/repositories/geo-checks/MongoGeoChecksRepository.ts b/server/src/repositories/geo-checks/MongoGeoChecksRepository.ts index 7633fcf7c..e1db5ab1d 100644 --- a/server/src/repositories/geo-checks/MongoGeoChecksRepository.ts +++ b/server/src/repositories/geo-checks/MongoGeoChecksRepository.ts @@ -1,17 +1,18 @@ import { IGeoChecksRepository } from "./IGeoChecksRepository.js"; import type { GeoCheck, GeoCheckMetadata, GeoCheckResult, GroupedGeoCheck, GeoContinent, FlatGeoCheck } from "@/types/geoCheck.js"; -import type { GeoChecksQueryResult, FlatGeoChecksQueryResult } from "./IGeoChecksRepository.js"; +import type { FlatGeoChecksQueryResult } from "./IGeoChecksRepository.js"; import { GeoCheckModel, type GeoCheckDocument } from "@/db/models/index.js"; import mongoose from "mongoose"; import { getDateForRange } from "@/utils/dataUtils.js"; +import { ILogger } from "@/utils/logger.js"; const SERVICE_NAME = "GeoChecksRepository"; class MongoGeoChecksRepository implements IGeoChecksRepository { static SERVICE_NAME = SERVICE_NAME; - private logger: any; - constructor(logger: any) { + private logger: ILogger; + constructor(logger: ILogger) { this.logger = logger; } diff --git a/server/src/service/business/geoChecksService.ts b/server/src/service/business/geoChecksService.ts index 4a31348b0..f7c5b33ea 100644 --- a/server/src/service/business/geoChecksService.ts +++ b/server/src/service/business/geoChecksService.ts @@ -68,7 +68,7 @@ export class GeoChecksService implements IGeoChecksService { } // Step 1: Create measurement request - const measurementId = await this.globalPingService.createMeasurement(monitor.url, monitor.geoCheckLocations); + const measurementId = await this.globalPingService.createMeasurement(monitor.type, monitor.url, monitor.geoCheckLocations); if (!measurementId) { // GlobalPing API is down, skip this check diff --git a/server/src/service/business/monitorService.ts b/server/src/service/business/monitorService.ts index b94d99c90..fe211c598 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/service/business/monitorService.ts @@ -340,7 +340,7 @@ export class MonitorService implements IMonitorService { throw new AppError({ message: `Monitor with ID ${monitorId} not found.`, status: 404 }); } - if (monitor.type !== "http" || !monitor.geoCheckEnabled) { + if ((monitor.type !== "http" && monitor.type !== "ping") || !monitor.geoCheckEnabled) { return { groupedGeoChecks: [] }; } diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts index 2857f5b82..3fb67bcfc 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts @@ -125,8 +125,13 @@ export class SuperSimpleQueue implements ISuperSimpleQueue { data: monitor, }); + // Return early if we don't need geo checks + if (monitor.type !== "http" && monitor.type !== "ping") { + return; + } + // Add geo check job if enabled for HTTP monitors - if (monitor.geoCheckEnabled && monitor.type === "http") { + if (monitor.geoCheckEnabled) { this.scheduler.addJob({ id: `${monitorId}-geo`, template: "geo-check-job", @@ -175,7 +180,7 @@ export class SuperSimpleQueue implements ISuperSimpleQueue { // Handle geo check job lifecycle const geoJobId = `${monitor.id}-geo`; - if (monitor.geoCheckEnabled && monitor.type === "http") { + if (monitor.geoCheckEnabled && (monitor.type === "http" || monitor.type === "ping")) { // Check if geo job exists const existingGeoJob = await this.scheduler.getJob(geoJobId); if (existingGeoJob) { diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts index 011008b32..766f2d907 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts @@ -280,19 +280,18 @@ export class SuperSimpleQueueHelper implements ISuperSimpleQueueHelper { throw new AppError({ message: "No monitor id", service: SERVICE_NAME, method: "getGeoCheckJob" }); } - if (monitor.type !== "http") { + if (!monitor.geoCheckEnabled) { + return; + } + if (monitor.type !== "http" && monitor.type !== "ping") { this.logger.debug({ - message: `Monitor ${monitorId} is not HTTP type, skipping geo check`, + message: `Monitor ${monitorId} is not HTTP or Ping type, skipping geo check`, service: SERVICE_NAME, method: "getGeoCheckJob", }); return; } - if (!monitor.geoCheckEnabled) { - return; - } - if (!monitor.geoCheckLocations || monitor.geoCheckLocations.length === 0) { this.logger.warn({ message: `No geo check locations configured for monitor ${monitorId}`, diff --git a/server/src/service/infrastructure/globalPingService.ts b/server/src/service/infrastructure/globalPingService.ts index b58486ad3..ff67dfd99 100644 --- a/server/src/service/infrastructure/globalPingService.ts +++ b/server/src/service/infrastructure/globalPingService.ts @@ -1,4 +1,5 @@ import type { GeoContinent, GeoCheckResult, GeoCheckTimings, GeoCheckLocation } from "@/types/geoCheck.js"; +import { MonitorType } from "@/types/index.js"; import type { ILogger } from "@/utils/logger.js"; import got from "got"; @@ -8,7 +9,7 @@ const POLL_INTERVAL_MS = 2000; const MAX_POLL_TIMEOUT_MS = 30000; interface GlobalPingMeasurementRequest { - type: "http"; + type: "http" | "ping"; target: string; locations: Array<{ continent: GeoContinent }>; limit: number; @@ -44,13 +45,22 @@ interface GlobalPingProbeResult { firstByte: number; download: number; }; + stats?: { + min: number; + max: number; + avg: number; + total: number; + loss: number; + rcv: number; + drop: number; + }; rawOutput?: string; }; } export interface IGlobalPingService { readonly serviceName: string; - createMeasurement(url: string, locations: GeoContinent[]): Promise; + createMeasurement(monitorType: MonitorType, url: string, locations: GeoContinent[]): Promise; pollForResults(measurementId: string, timeoutMs?: number): Promise; } @@ -67,13 +77,16 @@ export class GlobalPingService implements IGlobalPingService { return GlobalPingService.SERVICE_NAME; } - async createMeasurement(url: string, locations: GeoContinent[]): Promise { + async createMeasurement(monitorType: MonitorType, url: string, locations: GeoContinent[]): Promise { try { + if (monitorType !== "http" && monitorType !== "ping") { + throw new Error(`Unsupported monitor type for GlobalPing: ${monitorType}`); + } // GlobalPing API expects target without protocol (http:// or https://) const cleanTarget = url.replace(/^https?:\/\//, ""); const requestBody: GlobalPingMeasurementRequest = { - type: "http", + type: monitorType, target: cleanTarget, locations: locations.map((continent) => ({ continent })), limit: locations.length, @@ -88,10 +101,9 @@ export class GlobalPingService implements IGlobalPingService { const measurementId = response.body.id; this.logger.debug({ - message: `Created GlobalPing measurement: ${measurementId}`, + message: `Created GlobalPing measurement: ${measurementId} for target: ${cleanTarget}`, service: SERVICE_NAME, method: "createMeasurement", - details: { measurementId, url, locations }, }); return measurementId; @@ -165,8 +177,7 @@ export class GlobalPingService implements IGlobalPingService { const successfulResults: GeoCheckResult[] = []; for (const probeResult of probeResults) { - // Skip failed or timeout results - if (probeResult.result.status !== "finished" || !probeResult.result.statusCode || !probeResult.result.timings) { + if (probeResult.result.status !== "finished") { continue; } @@ -180,23 +191,38 @@ export class GlobalPingService implements IGlobalPingService { latitude: probeResult.probe.latitude, }; - const timings: GeoCheckTimings = { - total: probeResult.result.timings.total, - dns: probeResult.result.timings.dns, - tcp: probeResult.result.timings.tcp, - tls: probeResult.result.timings.tls, - firstByte: probeResult.result.timings.firstByte, - download: probeResult.result.timings.download, - }; + // HTTP results have statusCode and timings, ping results have stats + if (probeResult.result.statusCode && probeResult.result.timings) { + const timings: GeoCheckTimings = { + total: probeResult.result.timings.total, + dns: probeResult.result.timings.dns, + tcp: probeResult.result.timings.tcp, + tls: probeResult.result.timings.tls, + firstByte: probeResult.result.timings.firstByte, + download: probeResult.result.timings.download, + }; - const result: GeoCheckResult = { - location, - status: probeResult.result.statusCode >= 200 && probeResult.result.statusCode < 300, - statusCode: probeResult.result.statusCode, - timings, - }; - - successfulResults.push(result); + successfulResults.push({ + location, + status: probeResult.result.statusCode >= 200 && probeResult.result.statusCode < 300, + statusCode: probeResult.result.statusCode, + timings, + }); + } else if (probeResult.result.stats) { + successfulResults.push({ + location, + status: probeResult.result.stats.loss === 0, + statusCode: probeResult.result.stats.loss === 0 ? 200 : 5000, + timings: { + total: probeResult.result.stats.avg, + dns: 0, + tcp: 0, + tls: 0, + firstByte: 0, + download: 0, + }, + }); + } } return successfulResults; diff --git a/server/src/types/geoCheck.ts b/server/src/types/geoCheck.ts index 548c4c65f..6a75592a9 100644 --- a/server/src/types/geoCheck.ts +++ b/server/src/types/geoCheck.ts @@ -33,6 +33,7 @@ export interface GeoCheckResult { status: boolean; statusCode: number; timings: GeoCheckTimings; + } export interface GeoCheck { From 2f1a164c26d3d139e5e31e54c57e08e9cdfe9626 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 6 Mar 2026 10:46:00 -0800 Subject: [PATCH 2/5] remove rtt --- client/src/Pages/Uptime/Details/index.tsx | 14 +++----------- client/src/Types/Monitor.ts | 9 +++++++++ .../src/service/business/geoChecksService.ts | 19 +++---------------- server/src/service/business/monitorService.ts | 3 ++- .../SuperSimpleQueue/SuperSimpleQueue.ts | 5 +++-- .../SuperSimpleQueueHelper.ts | 5 +++-- .../infrastructure/globalPingService.ts | 5 +++-- server/src/types/monitor.ts | 3 +++ 8 files changed, 29 insertions(+), 34 deletions(-) diff --git a/client/src/Pages/Uptime/Details/index.tsx b/client/src/Pages/Uptime/Details/index.tsx index bea41705f..8828aa29a 100644 --- a/client/src/Pages/Uptime/Details/index.tsx +++ b/client/src/Pages/Uptime/Details/index.tsx @@ -20,7 +20,7 @@ import { useState, useMemo } from "react"; import { useParams } from "react-router-dom"; import { useSelector } from "react-redux"; import { useGet } from "@/Hooks/UseApi"; -import type { MonitorDetailsResponse } from "@/Types/Monitor"; +import { type MonitorDetailsResponse, supportsGeoCheck } from "@/Types/Monitor"; import type { ChecksResponse } from "@/Types/Check"; import type { GeoChecksResult, @@ -122,11 +122,7 @@ const UptimeDetailsPage = () => { ); const geoChecksUrl = useMemo(() => { - if ( - !monitorId || - (monitor?.type !== "http" && monitor?.type !== "ping") || - !monitor?.geoCheckEnabled - ) { + if (!monitorId || !supportsGeoCheck(monitor?.type) || !monitor?.geoCheckEnabled) { return null; } const params = new URLSearchParams(); @@ -145,11 +141,7 @@ const UptimeDetailsPage = () => { // Fetch paginated geo checks for the table const geoChecksTableUrl = useMemo(() => { - if ( - !monitorId || - (monitor?.type !== "http" && monitor?.type !== "ping") || - !monitor?.geoCheckEnabled - ) { + if (!monitorId || !supportsGeoCheck(monitor?.type) || !monitor?.geoCheckEnabled) { return null; } const params = new URLSearchParams(); diff --git a/client/src/Types/Monitor.ts b/client/src/Types/Monitor.ts index 01cae62e9..b87e65bc6 100644 --- a/client/src/Types/Monitor.ts +++ b/client/src/Types/Monitor.ts @@ -16,6 +16,15 @@ export const MonitorTypes = [ ] as const; export type MonitorType = (typeof MonitorTypes)[number]; +export const GeoCheckSupportedTypes: readonly MonitorType[] = ["http", "ping"] as const; + +export const supportsGeoCheck = (type: MonitorType | undefined): boolean => { + if (!type) { + return false; + } + return GeoCheckSupportedTypes.includes(type); +}; + export const MonitorStatuses = [ "up", "down", diff --git a/server/src/service/business/geoChecksService.ts b/server/src/service/business/geoChecksService.ts index f7c5b33ea..f35826a8f 100644 --- a/server/src/service/business/geoChecksService.ts +++ b/server/src/service/business/geoChecksService.ts @@ -76,7 +76,6 @@ export class GeoChecksService implements IGeoChecksService { message: "Skipping geo check due to API unavailability", service: SERVICE_NAME, method: "buildGeoCheck", - details: { monitorId: monitor.id }, }); return null; } @@ -90,7 +89,6 @@ export class GeoChecksService implements IGeoChecksService { message: "No successful geo check results", service: SERVICE_NAME, method: "buildGeoCheck", - details: { monitorId: monitor.id, measurementId }, }); return null; } @@ -102,17 +100,16 @@ export class GeoChecksService implements IGeoChecksService { message: `Geo check completed for monitor ${monitor.id}`, service: SERVICE_NAME, method: "buildGeoCheck", - details: { monitorId: monitor.id, resultsCount: results.length }, }); return geoCheck; - } catch (error: any) { + } catch (error: unknown) { this.logger.error({ message: "Error executing geo check", service: SERVICE_NAME, method: "buildGeoCheck", - details: { monitorId: monitor.id, error: error.message }, - stack: error.stack, + details: { monitorId: monitor.id, error: error instanceof Error ? error.message : "Unknown error" }, + stack: error instanceof Error ? error.stack : undefined, }); return null; } @@ -172,19 +169,9 @@ export class GeoChecksService implements IGeoChecksService { const { sortOrder, dateRange, page, rowsPerPage, continent } = query; const continents = continent ? (Array.isArray(continent) ? continent : [continent]) : undefined; - - this.logger.debug({ - message: "getGeoChecksByMonitor query params", - service: SERVICE_NAME, - method: "getGeoChecksByMonitor", - details: { continent, continents, query }, - }); - const parsedPage = page ? parseInt(page) : page; const parsedRowsPerPage = rowsPerPage ? parseInt(rowsPerPage) : rowsPerPage; - const result = await this.geoChecksRepository.findByMonitorId(monitorId, sortOrder, dateRange, parsedPage, parsedRowsPerPage, continents); - return result; }; } diff --git a/server/src/service/business/monitorService.ts b/server/src/service/business/monitorService.ts index fe211c598..b197c04bd 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/service/business/monitorService.ts @@ -8,6 +8,7 @@ import type { PageSpeedDetailsResult, GamesMap, } from "@/types/monitor.js"; +import { supportsGeoCheck } from "@/types/monitor.js"; import type { GeoContinent } from "@/types/geoCheck.js"; import type { IChecksRepository, @@ -340,7 +341,7 @@ export class MonitorService implements IMonitorService { throw new AppError({ message: `Monitor with ID ${monitorId} not found.`, status: 404 }); } - if ((monitor.type !== "http" && monitor.type !== "ping") || !monitor.geoCheckEnabled) { + if (!supportsGeoCheck(monitor.type) || !monitor.geoCheckEnabled) { return { groupedGeoChecks: [] }; } diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts index 3fb67bcfc..a96e7855b 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.ts @@ -2,6 +2,7 @@ import { IMonitorsRepository } from "@/repositories/index.js"; import { ILogger } from "@/utils/logger.js"; import Scheduler from "super-simple-scheduler"; import { ISuperSimpleQueueHelper } from "@/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js"; +import { supportsGeoCheck } from "@/types/monitor.js"; const SERVICE_NAME = "JobQueue"; type QueueJobFailure = { @@ -126,7 +127,7 @@ export class SuperSimpleQueue implements ISuperSimpleQueue { }); // Return early if we don't need geo checks - if (monitor.type !== "http" && monitor.type !== "ping") { + if (!supportsGeoCheck(monitor.type)) { return; } @@ -180,7 +181,7 @@ export class SuperSimpleQueue implements ISuperSimpleQueue { // Handle geo check job lifecycle const geoJobId = `${monitor.id}-geo`; - if (monitor.geoCheckEnabled && (monitor.type === "http" || monitor.type === "ping")) { + if (monitor.geoCheckEnabled && supportsGeoCheck(monitor.type)) { // Check if geo job exists const existingGeoJob = await this.scheduler.getJob(geoJobId); if (existingGeoJob) { diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts index 766f2d907..eef0a75be 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts @@ -1,5 +1,6 @@ const SERVICE_NAME = "JobQueueHelper"; import type { Monitor } from "@/types/monitor.js"; +import { supportsGeoCheck } from "@/types/monitor.js"; import { AppError } from "@/utils/AppError.js"; import { INetworkService, INotificationsService, IStatusService, IncidentService, type IGeoChecksService } from "@/service/index.js"; import type { StatusChangeResult } from "@/types/index.js"; @@ -283,9 +284,9 @@ export class SuperSimpleQueueHelper implements ISuperSimpleQueueHelper { if (!monitor.geoCheckEnabled) { return; } - if (monitor.type !== "http" && monitor.type !== "ping") { + if (!supportsGeoCheck(monitor.type)) { this.logger.debug({ - message: `Monitor ${monitorId} is not HTTP or Ping type, skipping geo check`, + message: `Monitor ${monitorId} type does not support geo checks, skipping`, service: SERVICE_NAME, method: "getGeoCheckJob", }); diff --git a/server/src/service/infrastructure/globalPingService.ts b/server/src/service/infrastructure/globalPingService.ts index ff67dfd99..41f96b286 100644 --- a/server/src/service/infrastructure/globalPingService.ts +++ b/server/src/service/infrastructure/globalPingService.ts @@ -1,4 +1,5 @@ import type { GeoContinent, GeoCheckResult, GeoCheckTimings, GeoCheckLocation } from "@/types/geoCheck.js"; +import { supportsGeoCheck } from "@/types/monitor.js"; import { MonitorType } from "@/types/index.js"; import type { ILogger } from "@/utils/logger.js"; import got from "got"; @@ -9,7 +10,7 @@ const POLL_INTERVAL_MS = 2000; const MAX_POLL_TIMEOUT_MS = 30000; interface GlobalPingMeasurementRequest { - type: "http" | "ping"; + type: MonitorType; target: string; locations: Array<{ continent: GeoContinent }>; limit: number; @@ -79,7 +80,7 @@ export class GlobalPingService implements IGlobalPingService { async createMeasurement(monitorType: MonitorType, url: string, locations: GeoContinent[]): Promise { try { - if (monitorType !== "http" && monitorType !== "ping") { + if (!supportsGeoCheck(monitorType)) { throw new Error(`Unsupported monitor type for GlobalPing: ${monitorType}`); } // GlobalPing API expects target without protocol (http:// or https://) diff --git a/server/src/types/monitor.ts b/server/src/types/monitor.ts index a6ecc4ef4..efbaa9632 100644 --- a/server/src/types/monitor.ts +++ b/server/src/types/monitor.ts @@ -6,6 +6,9 @@ export type { GeoContinent } from "@/types/geoCheck.js"; export const MonitorTypes = ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "unknown"] as const; export type MonitorType = (typeof MonitorTypes)[number]; +export const GeoCheckSupportedTypes: readonly MonitorType[] = ["http", "ping"] as const; +export const supportsGeoCheck = (type: MonitorType): boolean => GeoCheckSupportedTypes.includes(type); + export const MonitorStatuses = ["up", "down", "paused", "initializing", "maintenance", "breached"] as const; export type MonitorStatus = (typeof MonitorStatuses)[number]; From 206e28d1b999b456f23a77fa4b5e1d71d0190f3e Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 6 Mar 2026 11:01:38 -0800 Subject: [PATCH 3/5] user helper --- client/src/Pages/CreateMonitor/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/Pages/CreateMonitor/index.tsx b/client/src/Pages/CreateMonitor/index.tsx index dac5189ba..9a310f3b1 100644 --- a/client/src/Pages/CreateMonitor/index.tsx +++ b/client/src/Pages/CreateMonitor/index.tsx @@ -32,7 +32,7 @@ import { import { SPACING, LAYOUT } from "@/Utils/Theme/constants"; import { useGet, usePost, usePatch, useDelete } from "@/Hooks/UseApi"; import { useMonitorForm } from "@/Hooks/useMonitorForm"; -import type { Monitor, MonitorType, GamesMap } from "@/Types/Monitor"; +import { type Monitor, type MonitorType, type GamesMap, supportsGeoCheck } from "@/Types/Monitor"; import type { Notification } from "@/Types/Notification"; import type { MonitorFormData } from "@/Validation/monitor"; @@ -885,7 +885,7 @@ const CreateMonitorPage = () => { /> )} - {(watchedType === "http" || watchedType === "ping") && ( + {supportsGeoCheck(watchedType) && ( Date: Fri, 6 Mar 2026 11:02:20 -0800 Subject: [PATCH 4/5] format --- client/src/Pages/CreateMonitor/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/src/Pages/CreateMonitor/index.tsx b/client/src/Pages/CreateMonitor/index.tsx index 9a310f3b1..22719986e 100644 --- a/client/src/Pages/CreateMonitor/index.tsx +++ b/client/src/Pages/CreateMonitor/index.tsx @@ -32,7 +32,12 @@ import { import { SPACING, LAYOUT } from "@/Utils/Theme/constants"; import { useGet, usePost, usePatch, useDelete } from "@/Hooks/UseApi"; import { useMonitorForm } from "@/Hooks/useMonitorForm"; -import { type Monitor, type MonitorType, type GamesMap, supportsGeoCheck } from "@/Types/Monitor"; +import { + type Monitor, + type MonitorType, + type GamesMap, + supportsGeoCheck, +} from "@/Types/Monitor"; import type { Notification } from "@/Types/Notification"; import type { MonitorFormData } from "@/Validation/monitor"; From 116eb80fc9ab485dc1593fc5a1f74a1105e0d35a Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 6 Mar 2026 11:07:48 -0800 Subject: [PATCH 5/5] format --- server/src/types/geoCheck.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/types/geoCheck.ts b/server/src/types/geoCheck.ts index 6a75592a9..548c4c65f 100644 --- a/server/src/types/geoCheck.ts +++ b/server/src/types/geoCheck.ts @@ -33,7 +33,6 @@ export interface GeoCheckResult { status: boolean; statusCode: number; timings: GeoCheckTimings; - } export interface GeoCheck {