diff --git a/packages/server/modules/gatekeeper/domain/billing.ts b/packages/server/modules/gatekeeper/domain/billing.ts index cb74dfda6..e40500d8a 100644 --- a/packages/server/modules/gatekeeper/domain/billing.ts +++ b/packages/server/modules/gatekeeper/domain/billing.ts @@ -1,38 +1,68 @@ import { + TrialWorkspacePlans, + PaidWorkspacePlans, + UnpaidWorkspacePlans, WorkspacePlanBillingIntervals, - WorkspacePlans + WorkspacePricingPlans } from '@/modules/gatekeeper/domain/workspacePricing' -export type WorkspacePlanStatus = - | 'trial' - | 'valid' +export type UnpaidWorkspacePlanStatuses = 'valid' + +export type PaidWorkspacePlanStatuses = + | UnpaidWorkspacePlanStatuses // | 'paymentNeeded' // unsure if this is needed | 'paymentFailed' | 'cancelled' -export type WorkspacePlan = { +export type TrialWorkspacePlanStatuses = 'trial' + +export type PaidWorkspacePlan = { workspaceId: string - name: WorkspacePlans - status: WorkspacePlanStatus + name: PaidWorkspacePlans + status: PaidWorkspacePlanStatuses } +export type TrialWorkspacePlan = { + workspaceId: string + name: TrialWorkspacePlans + status: TrialWorkspacePlanStatuses +} + +export type UnpaidWorkspacePlan = { + workspaceId: string + name: UnpaidWorkspacePlans + status: UnpaidWorkspacePlanStatuses +} + +export type WorkspacePlan = PaidWorkspacePlan | TrialWorkspacePlan | UnpaidWorkspacePlan + export type GetWorkspacePlan = (args: { workspaceId: string }) => Promise +export type UpsertTrialWorkspacePlan = (args: { + workspacePlan: TrialWorkspacePlan +}) => Promise + +export type UpsertPaidWorkspacePlan = (args: { + workspacePlan: PaidWorkspacePlan +}) => Promise + export type UpsertWorkspacePlan = (args: { workspacePlan: WorkspacePlan }) => Promise export type SessionInput = { id: string - paymentStatus: 'paid' | 'unpaid' } +export type SessionPaymentStatus = 'paid' | 'unpaid' + export type CheckoutSession = SessionInput & { url: string workspaceId: string - workspacePlan: WorkspacePlans + workspacePlan: PaidWorkspacePlans + paymentStatus: SessionPaymentStatus billingInterval: WorkspacePlanBillingIntervals } @@ -44,11 +74,38 @@ export type GetCheckoutSession = (args: { sessionId: string }) => Promise +export type UpdateCheckoutSessionStatus = (args: { + sessionId: string + paymentStatus: SessionPaymentStatus +}) => Promise + export type CreateCheckoutSession = (args: { workspaceId: string workspaceSlug: string seatCount: number guestCount: number - workspacePlan: WorkspacePlans + workspacePlan: PaidWorkspacePlans billingInterval: WorkspacePlanBillingIntervals }) => Promise + +export type WorkspaceSubscription = { + workspaceId: string + createdAt: Date + billingInterval: WorkspacePlanBillingIntervals + subscriptionData: SubscriptionData +} + +// this abstracts the stripe sub data +export type SubscriptionData = { + subscriptionId: string + customerId: string + products: { + workspacePlan: WorkspacePricingPlans + priceId: string + quantity: number + }[] +} + +export type SaveWorkspaceSubscription = (args: { + workspaceSubscription: WorkspaceSubscription +}) => Promise diff --git a/packages/server/modules/gatekeeper/domain/workspacePricing.ts b/packages/server/modules/gatekeeper/domain/workspacePricing.ts index 659cb6de4..d9c9e5230 100644 --- a/packages/server/modules/gatekeeper/domain/workspacePricing.ts +++ b/packages/server/modules/gatekeeper/domain/workspacePricing.ts @@ -47,24 +47,39 @@ export const workspacePricingPlanInformation = { features, limits } type WorkspaceLimits = Record -type WorkspacePricingPlan = WorkspaceFeatures & WorkspaceLimits +type WorkspacePlanFeaturesAndLimits = WorkspaceFeatures & WorkspaceLimits const baseFeatures = { domainBasedSecurityPolicies: true } -export const workspacePlans = z.union([ - z.literal('team'), +export const trialWorkspacePlans = z.literal('team') + +export type TrialWorkspacePlans = z.infer + +export const paidWorkspacePlans = z.union([ + trialWorkspacePlans, z.literal('pro'), z.literal('business') - // this will be usefull in the enterprise and self hoster deployments - // z.literal('unlimited') ]) + +export type PaidWorkspacePlans = z.infer + +// these are not publicly exposed for general use on billing enabled servers +export const unpaidWorkspacePlans = z.union([ + z.literal('unlimited'), + z.literal('academia') +]) + +export type UnpaidWorkspacePlans = z.infer + +export const workspacePlans = z.union([paidWorkspacePlans, unpaidWorkspacePlans]) + // this includes the plans your workspace can be on export type WorkspacePlans = z.infer // this includes the pricing plans a customer can sub to -export type WorkspacePricingPlans = WorkspacePlans | 'guest' +export type WorkspacePricingPlans = PaidWorkspacePlans | 'guest' export const workspacePlanBillingIntervals = z.union([ z.literal('monthly'), @@ -74,7 +89,7 @@ export type WorkspacePlanBillingIntervals = z.infer< typeof workspacePlanBillingIntervals > -const team: WorkspacePricingPlan = { +const team: WorkspacePlanFeaturesAndLimits = { ...baseFeatures, oidcSso: false, workspaceDataRegionSpecificity: false, @@ -82,7 +97,7 @@ const team: WorkspacePricingPlan = { uploadSize: 500 } -const pro: WorkspacePricingPlan = { +const pro: WorkspacePlanFeaturesAndLimits = { ...baseFeatures, oidcSso: true, workspaceDataRegionSpecificity: false, @@ -90,7 +105,7 @@ const pro: WorkspacePricingPlan = { uploadSize: 1000 } -const business: WorkspacePricingPlan = { +const business: WorkspacePlanFeaturesAndLimits = { ...baseFeatures, oidcSso: true, workspaceDataRegionSpecificity: true, @@ -98,22 +113,41 @@ const business: WorkspacePricingPlan = { uploadSize: 1000 } -// const unlimited: WorkspacePricingPlan = { -// ...baseFeatures, -// oidcSso: true, -// workspaceDataRegionSpecificity: true, -// automateMinutes: null, -// uploadSize: 1000 -// } +const unlimited: WorkspacePlanFeaturesAndLimits = { + ...baseFeatures, + oidcSso: true, + workspaceDataRegionSpecificity: true, + automateMinutes: null, + uploadSize: 1000 +} -const workspacePricingPlans: Record = { +const academia: WorkspacePlanFeaturesAndLimits = { + ...baseFeatures, + oidcSso: true, + workspaceDataRegionSpecificity: false, + automateMinutes: null, + uploadSize: 100 +} + +const paidWorkspacePlanFeatures: Record< + PaidWorkspacePlans, + WorkspacePlanFeaturesAndLimits +> = { team, pro, business - //unlimited + // unlimited +} + +export const unpaidWorkspacePlanFeatures: Record< + UnpaidWorkspacePlans, + WorkspacePlanFeaturesAndLimits +> = { + academia, + unlimited } export const pricingTable = { workspacePricingPlanInformation, - workspacePricingPlans + workspacePlanInformation: paidWorkspacePlanFeatures }