diff --git a/packages/api/src/env.ts b/packages/api/src/env.ts index a7c67f813..77d6c73f4 100644 --- a/packages/api/src/env.ts +++ b/packages/api/src/env.ts @@ -14,6 +14,7 @@ export const env = createEnv({ UNKEY_API_ID: z.string(), SLACK_FEEDBACK_WEBHOOK_URL: z.string().optional(), EXTERNAL_REPORT_SALT: z.string().optional(), + SELF_HOST: z.stringbool().prefault("false"), }, runtimeEnv: { @@ -28,6 +29,7 @@ export const env = createEnv({ UNKEY_API_ID: process.env.UNKEY_API_ID, SLACK_FEEDBACK_WEBHOOK_URL: process.env.SLACK_FEEDBACK_WEBHOOK_URL, EXTERNAL_REPORT_SALT: process.env.EXTERNAL_REPORT_SALT, + SELF_HOST: process.env.SELF_HOST, }, skipValidation: process.env.NODE_ENV === "test", }); diff --git a/packages/api/src/router/monitor.ts b/packages/api/src/router/monitor.ts index d91fc5321..08f0fadfe 100644 --- a/packages/api/src/router/monitor.ts +++ b/packages/api/src/router/monitor.ts @@ -32,10 +32,15 @@ import { } from "@openstatus/services/monitor"; import { z } from "zod"; +import { env } from "../env"; import { toServiceCtx, toTRPCError } from "../service-adapter"; import { createTRPCRouter, protectedProcedure } from "../trpc"; import { testDns, testHttp, testTcp } from "./checker"; +// self-host has no access to the openstatus checker fleet, so the pre-save +// endpoint test can never succeed — skip it entirely. +const isSelfHost = env.SELF_HOST; + // tRPC-side input schemas. These preserve the existing wire contract exactly. const headerPair = z.object({ key: z.string(), value: z.string() }); @@ -315,7 +320,7 @@ export const monitorRouter = createTRPCRouter({ // Pre-save endpoint check — kept at the tRPC layer because the // `testHttp` / `testTcp` / `testDns` helpers hit external URLs and // are tRPC-specific UX; services unconditionally save. - if (!input.skipCheck && input.active) { + if (!isSelfHost && !input.skipCheck && input.active) { if (input.jobType === "http") { await testHttp({ url: input.url, @@ -379,7 +384,7 @@ export const monitorRouter = createTRPCRouter({ .input(newMonitorTRPCInput) .mutation(async ({ ctx, input }) => { try { - if (!input.skipCheck) { + if (!isSelfHost && !input.skipCheck) { if (input.jobType === "http") { await testHttp({ url: input.url,