import { PaidWorkspacePlan, PaidWorkspacePlans, TrialWorkspacePlan, UnpaidWorkspacePlan, WorkspacePlan, WorkspacePlanBillingIntervals, WorkspacePricingPlans } from '@/modules/gatekeeperCore/domain/billing' import { OverrideProperties } from 'type-fest' import { z } from 'zod' export type GetWorkspacePlan = (args: { workspaceId: string }) => Promise export type UpsertTrialWorkspacePlan = (args: { workspacePlan: TrialWorkspacePlan }) => Promise export type UpsertPaidWorkspacePlan = (args: { workspacePlan: PaidWorkspacePlan }) => Promise export type UpsertUnpaidWorkspacePlan = (args: { workspacePlan: UnpaidWorkspacePlan }) => Promise export type UpsertWorkspacePlan = (args: { workspacePlan: WorkspacePlan }) => Promise export type SessionInput = { id: string } export type SessionPaymentStatus = 'paid' | 'unpaid' export type CheckoutSession = SessionInput & { url: string workspaceId: string workspacePlan: PaidWorkspacePlans paymentStatus: SessionPaymentStatus billingInterval: WorkspacePlanBillingIntervals createdAt: Date updatedAt: Date } export type SaveCheckoutSession = (args: { checkoutSession: CheckoutSession }) => Promise export type GetCheckoutSession = (args: { sessionId: string }) => Promise export type DeleteCheckoutSession = (args: { checkoutSessionId: string }) => Promise export type GetWorkspaceCheckoutSession = (args: { workspaceId: string }) => Promise export type UpdateCheckoutSessionStatus = (args: { sessionId: string paymentStatus: SessionPaymentStatus }) => Promise export type CreateCheckoutSession = (args: { workspaceId: string workspaceSlug: string seatCount: number guestCount: number workspacePlan: PaidWorkspacePlans billingInterval: WorkspacePlanBillingIntervals isCreateFlow: boolean }) => Promise export type WorkspaceSubscription = { workspaceId: string createdAt: Date updatedAt: Date currentBillingCycleEnd: Date billingInterval: WorkspacePlanBillingIntervals subscriptionData: SubscriptionData } const subscriptionProduct = z.object({ productId: z.string(), subscriptionItemId: z.string(), priceId: z.string(), quantity: z.number() }) export type SubscriptionProduct = z.infer export const subscriptionData = z.object({ subscriptionId: z.string().min(1), customerId: z.string().min(1), cancelAt: z.date().nullable(), status: z.union([ z.literal('incomplete'), z.literal('incomplete_expired'), z.literal('trialing'), z.literal('active'), z.literal('past_due'), z.literal('canceled'), z.literal('unpaid'), z.literal('paused') ]), products: subscriptionProduct.array() }) export const calculateSubscriptionSeats = ({ subscriptionData, guestSeatProductId }: { subscriptionData: SubscriptionData guestSeatProductId: string }): { plan: number; guest: number } => { const guestProduct = subscriptionData.products.find( (p) => p.productId === guestSeatProductId ) const planProduct = subscriptionData.products.find( (p) => p.productId !== guestSeatProductId ) return { guest: guestProduct?.quantity || 0, plan: planProduct?.quantity || 0 } } // this abstracts the stripe sub data export type SubscriptionData = z.infer export type UpsertWorkspaceSubscription = (args: { workspaceSubscription: WorkspaceSubscription }) => Promise export type GetWorkspaceSubscription = (args: { workspaceId: string }) => Promise export type GetWorkspaceSubscriptions = () => Promise export type GetWorkspaceSubscriptionBySubscriptionId = (args: { subscriptionId: string }) => Promise export type GetSubscriptionData = (args: { subscriptionId: string }) => Promise export type GetWorkspacePlanPrice = (args: { workspacePlan: WorkspacePricingPlans billingInterval: WorkspacePlanBillingIntervals }) => string export type GetWorkspacePlanProductId = (args: { workspacePlan: WorkspacePricingPlans }) => string export type SubscriptionDataInput = OverrideProperties< SubscriptionData, { products: OverrideProperties[] } > export type ReconcileSubscriptionData = (args: { subscriptionData: SubscriptionDataInput applyProrotation: boolean }) => Promise