Skip to content

Commit 002c441

Browse files
authored
feat(webapp): self serve schedules add-on (#3811)
Adds the purchase UI for extra schedules, mirroring preview branches ## Changes - `setSchedulesAddOn` platform client + `SetSchedulesAddOnService` (purchase + quota-increase via Plain). - `ScheduleListPresenter` surfaces add-on / quota / pricing; `checkSchedule` counts purchased schedules toward the limit (`base + purchased`). - `PurchaseSchedulesModal` on the Schedules page — bought in **bundles of 1,000 ($10/mo each)**; bundle increments enforced client-side and in the action's zod schema.
1 parent 4783419 commit 002c441

6 files changed

Lines changed: 531 additions & 14 deletions

File tree

apps/webapp/app/presenters/v3/ScheduleListPresenter.server.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { type RuntimeEnvironmentType, type ScheduleType } from "@trigger.dev/dat
22
import { type ScheduleListFilters } from "~/components/runs/v3/ScheduleFilters";
33
import { displayableEnvironment } from "~/models/runtimeEnvironment.server";
44
import { getTaskIdentifiers } from "~/models/task.server";
5-
import { getLimit } from "~/services/platform.v3.server";
5+
import { getCurrentPlan, getLimit, getPlans } from "~/services/platform.v3.server";
66
import { findCurrentWorkerFromEnvironment } from "~/v3/models/workerDeployment.server";
77
import { ServiceValidationError } from "~/v3/services/baseService.server";
88
import { CheckScheduleService } from "~/v3/services/checkSchedule.server";
@@ -104,6 +104,25 @@ export class ScheduleListPresenter extends BasePresenter {
104104
});
105105

106106
const limit = await getLimit(project.organizationId, "schedules", 100_000_000);
107+
const [currentPlan, plans] = await Promise.all([
108+
getCurrentPlan(project.organizationId),
109+
getPlans(),
110+
]);
111+
112+
const extraSchedules = currentPlan?.v3Subscription?.addOns?.schedules?.purchased ?? 0;
113+
const canPurchaseSchedules =
114+
currentPlan?.v3Subscription?.plan?.limits.schedules.canExceed === true;
115+
const maxScheduleQuota = currentPlan?.v3Subscription?.addOns?.schedules?.quota ?? 0;
116+
const planScheduleLimit = limit - extraSchedules;
117+
const schedulePricing = plans?.addOnPricing.schedules ?? null;
118+
119+
const purchaseInfo = {
120+
canPurchaseSchedules,
121+
extraSchedules,
122+
maxScheduleQuota,
123+
planScheduleLimit,
124+
schedulePricing,
125+
};
107126

108127
//get the latest BackgroundWorker
109128
const latestWorker = await findCurrentWorkerFromEnvironment(environment, this._replica);
@@ -119,6 +138,7 @@ export class ScheduleListPresenter extends BasePresenter {
119138
used: schedulesCount,
120139
limit,
121140
},
141+
...purchaseInfo,
122142
filters: {
123143
tasks,
124144
search,
@@ -314,6 +334,7 @@ export class ScheduleListPresenter extends BasePresenter {
314334
used: schedulesCount,
315335
limit,
316336
},
337+
...purchaseInfo,
317338
filters: {
318339
tasks,
319340
search,

0 commit comments

Comments
 (0)