From 353a7e8e0dea5e849dffde5d7c826c249e0b7a19 Mon Sep 17 00:00:00 2001 From: RefRexi <119524317+RefRexi@users.noreply.github.com> Date: Tue, 15 Apr 2025 13:30:44 +0200 Subject: [PATCH 1/2] fix: dynamic route for team transfer (#1730) fix: dynamic route handling for /team/verify/transfer/:token --- ....verify.transfer.token.tsx => team.verify.transfer.$token.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/remix/app/routes/_unauthenticated+/{team.verify.transfer.token.tsx => team.verify.transfer.$token.tsx} (100%) diff --git a/apps/remix/app/routes/_unauthenticated+/team.verify.transfer.token.tsx b/apps/remix/app/routes/_unauthenticated+/team.verify.transfer.$token.tsx similarity index 100% rename from apps/remix/app/routes/_unauthenticated+/team.verify.transfer.token.tsx rename to apps/remix/app/routes/_unauthenticated+/team.verify.transfer.$token.tsx From f1526315f56f16c29ee174929e45c4c79fd67b25 Mon Sep 17 00:00:00 2001 From: Catalin Pit Date: Tue, 15 Apr 2025 14:32:15 +0300 Subject: [PATCH 2/2] feat: limit free teams platform plan (#1673) This pull request removes the `id` field from `IsDocumentPlatformOptions` in `is-document-platform.ts` and updates the billing logic in `create-team.ts`: platform plan users create their first team free, but pay for subsequent teams; non-platform users need an active team subscription if billing is enabled. --- packages/lib/server-only/team/create-team.ts | 26 +++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/lib/server-only/team/create-team.ts b/packages/lib/server-only/team/create-team.ts index 210187c5c..22e17d656 100644 --- a/packages/lib/server-only/team/create-team.ts +++ b/packages/lib/server-only/team/create-team.ts @@ -5,6 +5,7 @@ import { z } from 'zod'; import { createTeamCustomer } from '@documenso/ee/server-only/stripe/create-team-customer'; import { getTeamRelatedPrices } from '@documenso/ee/server-only/stripe/get-team-related-prices'; import { mapStripeSubscriptionToPrismaUpsertAction } from '@documenso/ee/server-only/stripe/webhook/on-subscription-updated'; +import { isDocumentPlatform as isUserPlatformPlan } from '@documenso/ee/server-only/util/is-document-platform'; import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing'; @@ -60,6 +61,11 @@ export const createTeam = async ({ }, }); + const isPlatformPlan = await isUserPlatformPlan({ + userId: user.id, + teamId: null, + }); + let isPaymentRequired = IS_BILLING_ENABLED(); let customerId: string | null = null; @@ -68,7 +74,25 @@ export const createTeam = async ({ prices.map((price) => price.id), ); - isPaymentRequired = !subscriptionsContainsActivePlan(user.subscriptions, teamRelatedPriceIds); + const hasTeamRelatedSubscription = subscriptionsContainsActivePlan( + user.subscriptions, + teamRelatedPriceIds, + ); + + if (isPlatformPlan) { + // For platform users, check if they already have any teams + const existingTeams = await prisma.team.findMany({ + where: { + ownerUserId: userId, + }, + }); + + // Payment is required if they already have any team + isPaymentRequired = existingTeams.length > 0; + } else { + // For non-platform users, payment is required if they don't have a team-related subscription + isPaymentRequired = !hasTeamRelatedSubscription; + } customerId = await createTeamCustomer({ name: user.name ?? teamName,