diff --git a/apps/webapp/app/models/organization.server.ts b/apps/webapp/app/models/organization.server.ts index 049ba3412..b9cd102d7 100644 --- a/apps/webapp/app/models/organization.server.ts +++ b/apps/webapp/app/models/organization.server.ts @@ -77,7 +77,7 @@ export async function createOrganization( } export async function createEnvironment( - organization: Pick, + organization: Pick, project: Pick, type: RuntimeEnvironment["type"], member?: OrgMember, @@ -95,7 +95,7 @@ export async function createEnvironment( pkApiKey, shortcode, autoEnableInternalSources: type !== "DEVELOPMENT", - maximumConcurrencyLimit: env.DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT, + maximumConcurrencyLimit: organization.maximumConcurrencyLimit / 3, organization: { connect: { id: organization.id, diff --git a/apps/webapp/app/models/project.server.ts b/apps/webapp/app/models/project.server.ts index f285901d9..35c1126eb 100644 --- a/apps/webapp/app/models/project.server.ts +++ b/apps/webapp/app/models/project.server.ts @@ -4,17 +4,21 @@ import { prisma } from "~/db.server"; import type { Project } from "@trigger.dev/database"; import { Organization, createEnvironment } from "./organization.server"; import { env } from "~/env.server"; +import { BillingService } from "~/services/billing.v3.server"; export type { Project } from "@trigger.dev/database"; const externalRefGenerator = customAlphabet("abcdefghijklmnopqrstuvwxyz", 20); +type Options = { + organizationSlug: string; + name: string; + userId: string; + version: "v2" | "v3"; + isManagedCloud: boolean; +}; + export async function createProject( - { - organizationSlug, - name, - userId, - version, - }: { organizationSlug: string; name: string; userId: string; version: "v2" | "v3" }, + { organizationSlug, name, userId, version, isManagedCloud }: Options, attemptCount = 0 ): Promise { //check the user has permissions to do this @@ -58,6 +62,7 @@ export async function createProject( name, userId, version, + isManagedCloud, }, attemptCount + 1 ); @@ -89,6 +94,13 @@ export async function createProject( if (version === "v2") { await createEnvironment(organization, project, "STAGING"); + } else { + //staging is only available on certain plans + const billingService = new BillingService(isManagedCloud); + const plan = await billingService.currentPlan(organization.id); + if (plan?.v3Subscription.plan?.limits.hasStagingEnvironment) { + await createEnvironment(organization, project, "STAGING"); + } } for (const member of project.organization.members) { diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.apikeys/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.apikeys/route.tsx index 7ffd1e5d9..1dc2f0d43 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.apikeys/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.apikeys/route.tsx @@ -57,73 +57,6 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { } }; -export const action = async ({ request, params }: ActionFunctionArgs) => { - const userId = await requireUserId(request); - const { organizationSlug, projectParam } = ProjectParamSchema.parse(params); - - if (request.method.toUpperCase() !== "POST") { - return { status: 405, body: "Method Not Allowed" }; - } - - const project = await prisma.project.findUnique({ - where: { - slug: params.projectParam, - organization: { - members: { - some: { - userId, - }, - }, - }, - }, - select: { - id: true, - organizationId: true, - environments: { - select: { - type: true, - }, - }, - }, - }); - - if (!project) { - return redirectWithErrorMessage( - v3ApiKeysPath({ slug: organizationSlug }, { slug: projectParam }), - request, - "Project not found" - ); - } - - if (project.environments.some((env) => env.type === "STAGING")) { - return redirectWithErrorMessage( - v3ApiKeysPath({ slug: organizationSlug }, { slug: projectParam }), - request, - "You already have a staging environment" - ); - } - - const environment = await createEnvironment( - { id: project.organizationId }, - { id: project.id }, - "STAGING" - ); - - if (!environment) { - return redirectWithErrorMessage( - v3ApiKeysPath({ slug: organizationSlug }, { slug: projectParam }), - request, - "Failed to create staging environment" - ); - } - - return redirectWithSuccessMessage( - v3ApiKeysPath({ slug: organizationSlug }, { slug: projectParam }), - request, - "Staging environment created" - ); -}; - export default function Page() { const { environments, hasStaging } = useTypedLoaderData(); const { isManagedCloud } = useFeatures(); @@ -216,6 +149,7 @@ export default function Page() { {!hasStaging && ( + // todo take you to the plans page { } try { + const { isManagedCloud } = featuresForRequest(request); const project = await createProject({ organizationSlug: organizationSlug, name: submission.value.projectName, userId, version: submission.value.projectVersion, + isManagedCloud, }); return redirectWithSuccessMessage(