Moving to supporting more than one sub

This commit is contained in:
Owen
2026-02-04 17:54:29 -08:00
parent 4613aae47d
commit 72d46b7352
5 changed files with 49 additions and 39 deletions

View File

@@ -12,7 +12,7 @@
*/
import { getTierPriceSet } from "@server/lib/billing/tiers";
import { getOrgSubscriptionData } from "#private/routers/billing/getOrgSubscription";
import { getOrgSubscriptionsData } from "@server/private/routers/billing/getOrgSubscriptions";
import { build } from "@server/build";
export async function getOrgTierData(
@@ -25,22 +25,32 @@ export async function getOrgTierData(
return { tier, active };
}
const { subscription, items } = await getOrgSubscriptionData(orgId);
// TODO: THIS IS INEFFICIENT!!! WE SHOULD IMPROVE HOW WE STORE TIERS WITH SUBSCRIPTIONS AND RETRIEVE THEM
if (items && items.length > 0) {
const tierPriceSet = getTierPriceSet();
// Iterate through tiers in order (earlier keys are higher tiers)
for (const [tierId, priceId] of Object.entries(tierPriceSet)) {
// Check if any subscription item matches this tier's price ID
const matchingItem = items.find((item) => item.priceId === priceId);
if (matchingItem) {
tier = tierId;
break;
const subscriptionsWithItems = await getOrgSubscriptionsData(orgId);
for (const { subscription, items } of subscriptionsWithItems) {
if (items && items.length > 0) {
const tierPriceSet = getTierPriceSet();
// Iterate through tiers in order (earlier keys are higher tiers)
for (const [tierId, priceId] of Object.entries(tierPriceSet)) {
// Check if any subscription item matches this tier's price ID
const matchingItem = items.find((item) => item.priceId === priceId);
if (matchingItem) {
tier = tierId;
break;
}
}
}
}
if (subscription && subscription.status === "active") {
active = true;
if (subscription && subscription.status === "active") {
active = true;
}
// If we found a tier and active subscription, we can stop
if (tier && active) {
break;
}
}
return { tier, active };
}

View File

@@ -48,7 +48,7 @@ registry.registerPath({
responses: {}
});
export async function getOrgSubscription(
export async function getOrgSubscriptions(
req: Request,
res: Response,
next: NextFunction
@@ -66,12 +66,9 @@ export async function getOrgSubscription(
const { orgId } = parsedParams.data;
let subscriptionData = null;
let itemsData: SubscriptionItem[] = [];
let subscriptions = null;
try {
const { subscription, items } = await getOrgSubscriptionData(orgId);
subscriptionData = subscription;
itemsData = items;
subscriptions = await getOrgSubscriptionsData(orgId);
} catch (err) {
if ((err as Error).message === "Not found") {
return next(
@@ -86,8 +83,7 @@ export async function getOrgSubscription(
return response<GetOrgSubscriptionResponse>(res, {
data: {
subscription: subscriptionData,
items: itemsData
subscriptions
},
success: true,
error: false,
@@ -102,9 +98,9 @@ export async function getOrgSubscription(
}
}
export async function getOrgSubscriptionData(
export async function getOrgSubscriptionsData(
orgId: string
): Promise<{ subscription: Subscription | null; items: SubscriptionItem[] }> {
): Promise<Array<{ subscription: Subscription; items: SubscriptionItem[] }>> {
const org = await db
.select()
.from(orgs)
@@ -122,21 +118,21 @@ export async function getOrgSubscriptionData(
.where(eq(customers.orgId, orgId))
.limit(1);
let subscription = null;
let items: SubscriptionItem[] = [];
const subscriptionsWithItems: Array<{
subscription: Subscription;
items: SubscriptionItem[];
}> = [];
if (customer.length > 0) {
// Get subscription for customer
// Get all subscriptions for customer
const subs = await db
.select()
.from(subscriptions)
.where(eq(subscriptions.customerId, customer[0].customerId))
.limit(1);
.where(eq(subscriptions.customerId, customer[0].customerId));
if (subs.length > 0) {
subscription = subs[0];
// Get subscription items
items = await db
for (const subscription of subs) {
// Get subscription items for each subscription
const items = await db
.select()
.from(subscriptionItems)
.where(
@@ -145,8 +141,13 @@ export async function getOrgSubscriptionData(
subscription.subscriptionId
)
);
subscriptionsWithItems.push({
subscription,
items
});
}
}
return { subscription, items };
return subscriptionsWithItems;
}

View File

@@ -13,6 +13,6 @@
export * from "./createCheckoutSessionSAAS";
export * from "./createPortalSession";
export * from "./getOrgSubscription";
export * from "./getOrgSubscriptions";
export * from "./getOrgUsage";
export * from "./internalGetOrgTier";

View File

@@ -175,10 +175,10 @@ if (build === "saas") {
);
authenticated.get(
"/org/:orgId/billing/subscription",
"/org/:orgId/billing/subscriptions",
verifyOrgAccess,
verifyUserHasAction(ActionsEnum.billing),
billing.getOrgSubscription
billing.getOrgSubscriptions
);
authenticated.get(

View File

@@ -1,8 +1,7 @@
import { Limit, Subscription, SubscriptionItem, Usage } from "@server/db";
export type GetOrgSubscriptionResponse = {
subscription: Subscription | null;
items: SubscriptionItem[];
subscriptions: Array<{ subscription: Subscription; items: SubscriptionItem[] }>;
};
export type GetOrgUsageResponse = {