From f34151bc1267b17e663098522ddcd1c2891e08b4 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Fri, 18 Sep 2026 02:39:33 -0600 Subject: [PATCH] refactor(billing): drop the runTrialExpirationJob endpoint Removes the manual trigger and the root guard it needed. The cron job is the only caller now, so processTrialExpirations goes back to module private. --- apps/dokploy/server/api/routers/stripe.ts | 28 ------------------- .../server/utils/trial-notifications.ts | 2 +- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/apps/dokploy/server/api/routers/stripe.ts b/apps/dokploy/server/api/routers/stripe.ts index 76d07eaf4..944c86c8f 100644 --- a/apps/dokploy/server/api/routers/stripe.ts +++ b/apps/dokploy/server/api/routers/stripe.ts @@ -28,7 +28,6 @@ import { STARTUP_PRODUCT_ID, WEBSITE_URL, } from "@/server/utils/stripe"; -import { processTrialExpirations } from "@/server/utils/trial-notifications"; import { adminProcedure, createTRPCRouter, @@ -36,27 +35,6 @@ import { withPermission, } from "../trpc"; -// These reach every trialing customer on the platform, so an org admin is not -// enough; only the Dokploy Cloud root account may run them. -const assertRootAccess = (ctx: { - user: { id: string }; - session?: { impersonatedBy?: string | null } | null; -}) => { - if (!IS_CLOUD) { - throw new TRPCError({ - code: "BAD_REQUEST", - message: "This feature is only available in Dokploy Cloud", - }); - } - const rootId = process.env.USER_ADMIN_ID; - if ( - !rootId || - (ctx.user.id !== rootId && ctx.session?.impersonatedBy !== rootId) - ) { - throw new TRPCError({ code: "FORBIDDEN", message: "Root access required" }); - } -}; - export const stripeRouter = createTRPCRouter({ /** Returns the current billing plan for the user's organization. Used to gate features like chat (Startup only). */ getCurrentPlan: protectedProcedure.query(async ({ ctx }) => { @@ -444,12 +422,6 @@ export const stripeRouter = createTRPCRouter({ return { ok: true }; }), - runTrialExpirationJob: adminProcedure.mutation(async ({ ctx }) => { - assertRootAccess(ctx); - - return processTrialExpirations(); - }), - getInvoices: adminProcedure.query(async ({ ctx }) => { const user = await findUserById(ctx.user.ownerId); const stripeCustomerId = user.stripeCustomerId; diff --git a/apps/dokploy/server/utils/trial-notifications.ts b/apps/dokploy/server/utils/trial-notifications.ts index e66307d6c..2a7b9c90e 100644 --- a/apps/dokploy/server/utils/trial-notifications.ts +++ b/apps/dokploy/server/utils/trial-notifications.ts @@ -117,7 +117,7 @@ const processSubscription = async ( return true; }; -export const processTrialExpirations = async () => { +const processTrialExpirations = async () => { const stripe = getStripeClient(); let sent = 0; let scanned = 0;