72f3a4b128
* v3 subscription endpoints * Use pnpm linked billing package during development * Moved v2 billing components into a subfolder * Select plan using the real data * Improved v3 plan display * Use new api response that doesn’t require a Stripe call * Free flow is working * Added GitHub modal and verified badge * Deleted old request v3 access component/route * Allow setting classes on the Tooltip button * Paid plans working * Redirect from select plan if you’ve got v3 enabled * Loading state improvements * New admin API endpoint to set concurrency across multiple environments * When projects are created, conditionally create staging based on the plan * New billing page working with side menu and stripe portal * Layout, formatting and some plan state improvements/fixes * Don’t show the period if you’re on the free plan * Temporary upgrade callout * Refactored the platform code so it’s easier to call and doesn’t require a isManagedCloud check * Send taskIdentifier to OpenMeter * Side menu * Upgrade prompts * More improvements to the app-wide usage indicators * Early work on usage graphs * Added the usage bar for v3 * Moved code to presenter and now using defer * Added the tasks table to usage * Improved the v3 usage bar if theres’ no usage on a paid plan * If no run data, still render a graph * Usage page errors when defered loading fails * Don’t show the public API key for v3, they’re not used and probably never will be * Improved the upgrade callout and API keys page layout * Only show the “reveal all” toggle if you have environment variables in the table * Replaced Upgrade callout with a more generic InfoPanel component * better panel width * Show conditional upgrade prompts based on plan and number of schedules used * Removed duplicate class * Wider blank state panels for the scheduled page * Wider info panel for the env var page * Blank state now using the info panel * Platform alerts prompt now using the InfoPanel * Deploy blank state uses InfoPanel * Github verified badge padding adjustment * Improved the layout of the page, some style tweaks, organized imports * Better default tooltip style * could be undefined fix * text fix + style updates * Changed the billing icon in the side menu * Billing page layout and style improvements * plan tooltips don’t use dark variant * Don’t highlight the plan on the billing page * Tooltip underlines stand out more * Fixed padding in the PageTitle * Tooltips use the correct cursor * Improved the plan banner on the billing page * Fixed Header1 inconsistent font weight * Fixed issue where input field focus states were being clipped * Fixed large button not having large text size * Added a link to the Get in touch copy and improved the connect to GitHub modal * Select plan page uses the MainCenteredContainer * Better logging from the Loops endpoint because this error finally got hit * Move the ingestion of compute to the platform * Reporting usage of invocations moved to the platform * Get the entitlement before triggering a non-dev task * Contact us enterprise plan button opens the feedback form * Removed Github discussions link from the Feedback panel * Swapped billing icon for credit card * Show a Unlock staging panel on the env var page * Updated staging environment colour * Show a prompt to upgrade to get staging in the new env var modal * Improved the edit env var modal * Implement ability to disable org concurrency * Use common logic for the plans * Use the billing server to get the schedule limits * Some schedules page fixes * More convenient way of getting a limit * Use the new schedule limit * Team member limiting * Made the limit visible on the team page * Limit alerts * Added an index for TaskRun.scheduleId * Remove console.log on schedules page * Added durations to the run table * Tabular numbers * Improved the usage page formatting * Only admins see the compute column on the run table * Include the base cost on the usage stats * Moved the status to the sidebar * Optional table header tooltip * Allow InfoIconTooltips to have customizable content styles * Added a tooltip to the duration header, changed no test to a dash * Removed all references to signing up to v3 from the docs * Switched @trigger.dev/billing to @trigger.dev/platform * Passing up the variant for the InfoIconTooltip * table tooltip max-width fixed * Switch to the published @trigger.dev/platform 1.0.11 * v2 usage page title changed to include “v2" * code theme has a transparent background so it works on any background * duration columns now grouped together nicely at wide screen size * Last duration column fills the width properly * Fix for the per run price being in cents not dollars * Show the total cost with 8 decimal places * Show 8 decimal places in the usage graph tooltip * Moved the UpgradePrompt to the v3 folder * Prepare to use Shadcns chart helpers * Much nicer chart * Small tweaks to the graph * Fix run table col spans for empty/loading messages * We don’t need isManagedCloud in createProject * Hide v3 usage/billing pages if there aren’t v3 projects in your org * Removed unused tooltipStyle * Usage bar now says “Included usage” instead of “Tier limit” if you’re paying * Get the plan/usage data in parallel * The usage page now has a month dropdown and all data is for that calendar month * Ensure the passed date is the 1st of the month * Use the machine presets from the platform package --------- Co-authored-by: James Ritchie <james@jamesritchie.co.uk> Co-authored-by: Eric Allam <eallam@icloud.com>
118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
import type {
|
|
Organization,
|
|
OrgMember,
|
|
Project,
|
|
RuntimeEnvironment,
|
|
User,
|
|
} from "@trigger.dev/database";
|
|
import { customAlphabet } from "nanoid";
|
|
import slug from "slug";
|
|
import { prisma, PrismaClientOrTransaction } from "~/db.server";
|
|
import { generate } from "random-words";
|
|
import { createApiKeyForEnv, createPkApiKeyForEnv, envSlug } from "./api-key.server";
|
|
import { env } from "~/env.server";
|
|
import { featuresForUrl } from "~/features.server";
|
|
|
|
export type { Organization };
|
|
|
|
const nanoid = customAlphabet("1234567890abcdef", 4);
|
|
|
|
export async function createOrganization(
|
|
{
|
|
title,
|
|
userId,
|
|
companySize,
|
|
}: Pick<Organization, "title" | "companySize"> & {
|
|
userId: User["id"];
|
|
},
|
|
attemptCount = 0
|
|
): Promise<Organization> {
|
|
if (typeof process.env.BLOCKED_USERS === "string" && process.env.BLOCKED_USERS.includes(userId)) {
|
|
throw new Error("Organization could not be created.");
|
|
}
|
|
|
|
const uniqueOrgSlug = `${slug(title)}-${nanoid(4)}`;
|
|
|
|
const orgWithSameSlug = await prisma.organization.findFirst({
|
|
where: { slug: uniqueOrgSlug },
|
|
});
|
|
|
|
if (attemptCount > 100) {
|
|
throw new Error(`Unable to create organization with slug ${uniqueOrgSlug} after 100 attempts`);
|
|
}
|
|
|
|
if (orgWithSameSlug) {
|
|
return createOrganization(
|
|
{
|
|
title,
|
|
userId,
|
|
companySize,
|
|
},
|
|
attemptCount + 1
|
|
);
|
|
}
|
|
|
|
const features = featuresForUrl(new URL(env.APP_ORIGIN));
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title,
|
|
slug: uniqueOrgSlug,
|
|
companySize,
|
|
maximumConcurrencyLimit: env.DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT,
|
|
members: {
|
|
create: {
|
|
userId: userId,
|
|
role: "ADMIN",
|
|
},
|
|
},
|
|
v3Enabled: features.v3Enabled && !features.isManagedCloud,
|
|
},
|
|
include: {
|
|
members: true,
|
|
},
|
|
});
|
|
|
|
return { ...organization };
|
|
}
|
|
|
|
export async function createEnvironment(
|
|
organization: Pick<Organization, "id" | "maximumConcurrencyLimit">,
|
|
project: Pick<Project, "id">,
|
|
type: RuntimeEnvironment["type"],
|
|
member?: OrgMember,
|
|
prismaClient: PrismaClientOrTransaction = prisma
|
|
) {
|
|
const slug = envSlug(type);
|
|
const apiKey = createApiKeyForEnv(type);
|
|
const pkApiKey = createPkApiKeyForEnv(type);
|
|
const shortcode = createShortcode().join("-");
|
|
|
|
return await prismaClient.runtimeEnvironment.create({
|
|
data: {
|
|
slug,
|
|
apiKey,
|
|
pkApiKey,
|
|
shortcode,
|
|
autoEnableInternalSources: type !== "DEVELOPMENT",
|
|
maximumConcurrencyLimit: organization.maximumConcurrencyLimit / 3,
|
|
organization: {
|
|
connect: {
|
|
id: organization.id,
|
|
},
|
|
},
|
|
project: {
|
|
connect: {
|
|
id: project.id,
|
|
},
|
|
},
|
|
orgMember: member ? { connect: { id: member.id } } : undefined,
|
|
type,
|
|
},
|
|
});
|
|
}
|
|
|
|
function createShortcode() {
|
|
return generate({ exactly: 2 });
|
|
}
|