When projects are created, conditionally create staging based on the plan

This commit is contained in:
Matt Aitken
2024-06-26 22:38:28 +01:00
parent 6869e671a3
commit 970bd7385c
4 changed files with 23 additions and 75 deletions
@@ -77,7 +77,7 @@ export async function createOrganization(
}
export async function createEnvironment(
organization: Pick<Organization, "id">,
organization: Pick<Organization, "id" | "maximumConcurrencyLimit">,
project: Pick<Project, "id">,
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,
+18 -6
View File
@@ -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<Project & { organization: Organization }> {
//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) {
@@ -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<typeof loader>();
const { isManagedCloud } = useFeatures();
@@ -216,6 +149,7 @@ export default function Page() {
</Table>
{!hasStaging && (
// todo take you to the plans page
<Callout
variant="info"
cta={
@@ -101,11 +101,13 @@ export const action: ActionFunction = async ({ request, params }) => {
}
try {
const { isManagedCloud } = featuresForRequest(request);
const project = await createProject({
organizationSlug: organizationSlug,
name: submission.value.projectName,
userId,
version: submission.value.projectVersion,
isManagedCloud,
});
return redirectWithSuccessMessage(