allow organizations to have multiple subscriptions. although only 1 can be active at a time

This commit is contained in:
m5r
2021-10-03 18:19:45 +02:00
parent 22e2b21b14
commit 3a3d526e77
6 changed files with 65 additions and 37 deletions

View File

@ -1,6 +1,6 @@
import { Queue } from "quirrel/blitz";
import db, { MembershipRole } from "../../../../db";
import db, { MembershipRole, SubscriptionStatus } from "../../../../db";
import appLogger from "../../../../integrations/logger";
import { cancelPaddleSubscription } from "../../../../integrations/paddle";
@ -17,7 +17,11 @@ const deleteUserData = Queue<Payload>("api/queue/delete-user-data", async ({ use
memberships: {
include: {
organization: {
include: { subscription: true },
include: {
subscriptions: {
where: { status: { not: SubscriptionStatus.deleted } },
},
},
},
},
},
@ -33,8 +37,12 @@ const deleteUserData = Queue<Payload>("api/queue/delete-user-data", async ({ use
await db.organization.delete({ where: { id: organization.id } });
await db.user.delete({ where: { id: user.id } });
if (organization.subscription) {
await cancelPaddleSubscription({ subscriptionId: organization.subscription.paddleSubscriptionId });
if (organization.subscriptions.length > 0) {
await Promise.all(
organization.subscriptions.map((subscription) =>
cancelPaddleSubscription({ subscriptionId: subscription.paddleSubscriptionId }),
),
);
}
break;

View File

@ -18,7 +18,7 @@ export const subscriptionCreatedQueue = Queue<Payload>("api/queue/subscription-c
const organization = await db.organization.findFirst({
where: { id: organizationId },
include: {
subscription: true,
subscriptions: true,
memberships: {
include: { user: true },
},
@ -28,29 +28,26 @@ export const subscriptionCreatedQueue = Queue<Payload>("api/queue/subscription-c
throw new NotFoundError();
}
const isReturningSubscriber = organization.subscriptions.length > 0;
const orgOwner = organization.memberships.find((membership) => membership.role === MembershipRole.OWNER);
const email = orgOwner!.user!.email;
await db.organization.update({
where: { id: organizationId },
await db.subscription.create({
data: {
subscription: {
create: {
paddleSubscriptionId: event.subscriptionId,
paddlePlanId: event.productId,
paddleCheckoutId: event.checkoutId,
nextBillDate: event.nextPaymentDate,
status: translateSubscriptionStatus(event.status),
lastEventTime: event.eventTime,
updateUrl: event.updateUrl,
cancelUrl: event.cancelUrl,
currency: event.currency,
unitPrice: event.unitPrice,
},
},
organizationId,
paddleSubscriptionId: event.subscriptionId,
paddlePlanId: event.productId,
paddleCheckoutId: event.checkoutId,
nextBillDate: event.nextPaymentDate,
status: translateSubscriptionStatus(event.status),
lastEventTime: event.eventTime,
updateUrl: event.updateUrl,
cancelUrl: event.cancelUrl,
currency: event.currency,
unitPrice: event.unitPrice,
},
});
if (!!organization.subscription) {
if (isReturningSubscriber) {
sendEmail({
subject: "Welcome back to Shellphone",
body: "Welcome back to Shellphone",
@ -58,15 +55,17 @@ export const subscriptionCreatedQueue = Queue<Payload>("api/queue/subscription-c
}).catch((error) => {
logger.error(error);
});
} else {
sendEmail({
subject: "Welcome to Shellphone",
body: `Welcome to Shellphone`,
recipients: [email],
}).catch((error) => {
logger.error(error);
});
return;
}
sendEmail({
subject: "Welcome to Shellphone",
body: `Welcome to Shellphone`,
recipients: [email],
}).catch((error) => {
logger.error(error);
});
});
export default subscriptionCreatedQueue;

View File

@ -42,6 +42,7 @@ export const subscriptionPaymentSucceededQueue = Queue<Payload>(
},
});
},
{ retry: ["30s", "1m", "5m"] },
);
export default subscriptionPaymentSucceededQueue;