Skip to content

Commit

Permalink
feat(server): support ai plan
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo committed Mar 20, 2024
1 parent 4a2cbb8 commit adbb78f
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:
- A unique constraint covering the columns `[user_id,plan]` on the table `user_subscriptions` will be added. If there are existing duplicate values, this will fail.
*/
-- DropIndex
DROP INDEX "user_subscriptions_user_id_key";

-- CreateIndex
CREATE UNIQUE INDEX "user_subscriptions_user_id_plan_key" ON "user_subscriptions"("user_id", "plan");
5 changes: 3 additions & 2 deletions packages/backend/server/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ model User {
features UserFeatures[]
customer UserStripeCustomer?
subscription UserSubscription?
subscriptions UserSubscription[]
invoices UserInvoice[]
workspacePermissions WorkspaceUserPermission[]
pagePermissions WorkspacePageUserPermission[]
Expand Down Expand Up @@ -369,7 +369,7 @@ model UserStripeCustomer {

model UserSubscription {
id Int @id @default(autoincrement()) @db.Integer
userId String @unique @map("user_id") @db.VarChar(36)
userId String @map("user_id") @db.VarChar(36)
plan String @db.VarChar(20)
// yearly/monthly
recurring String @db.VarChar(20)
Expand All @@ -395,6 +395,7 @@ model UserSubscription {
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, plan])
@@map("user_subscriptions")
}

Expand Down
60 changes: 55 additions & 5 deletions packages/backend/server/src/plugins/payment/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class SubscriptionResolver {
}

// extend it when new plans are added
const fixedPlans = [SubscriptionPlan.Pro];
const fixedPlans = [SubscriptionPlan.Pro, SubscriptionPlan.AI];

return fixedPlans.reduce((prices, plan) => {
const price = findPrice(plan);
Expand Down Expand Up @@ -242,29 +242,55 @@ export class SubscriptionResolver {
@Mutation(() => UserSubscriptionType)
async cancelSubscription(
@CurrentUser() user: CurrentUser,
@Args({
name: 'plan',
type: () => SubscriptionPlan,
nullable: true,
defaultValue: SubscriptionPlan.Pro,
})
plan: SubscriptionPlan,
@Args('idempotencyKey') idempotencyKey: string
) {
return this.service.cancelSubscription(idempotencyKey, user.id);
return this.service.cancelSubscription(idempotencyKey, user.id, plan);
}

@Mutation(() => UserSubscriptionType)
async resumeSubscription(
@CurrentUser() user: CurrentUser,
@Args({
name: 'plan',
type: () => SubscriptionPlan,
nullable: true,
defaultValue: SubscriptionPlan.Pro,
})
plan: SubscriptionPlan,
@Args('idempotencyKey') idempotencyKey: string
) {
return this.service.resumeCanceledSubscription(idempotencyKey, user.id);
return this.service.resumeCanceledSubscription(
idempotencyKey,
user.id,
plan
);
}

@Mutation(() => UserSubscriptionType)
async updateSubscriptionRecurring(
@CurrentUser() user: CurrentUser,
@Args({ name: 'recurring', type: () => SubscriptionRecurring })
recurring: SubscriptionRecurring,
@Args({
name: 'plan',
type: () => SubscriptionPlan,
nullable: true,
defaultValue: SubscriptionPlan.Pro,
})
plan: SubscriptionPlan,
@Args('idempotencyKey') idempotencyKey: string
) {
return this.service.updateSubscriptionRecurring(
idempotencyKey,
user.id,
plan,
recurring
);
}
Expand All @@ -277,7 +303,10 @@ export class UserSubscriptionResolver {
private readonly db: PrismaClient
) {}

@ResolveField(() => UserSubscriptionType, { nullable: true })
@ResolveField(() => UserSubscriptionType, {
nullable: true,
deprecationReason: 'use `UserType.subscriptions`',
})
async subscription(
@Context() ctx: { isAdminQuery: boolean },
@CurrentUser() me: User,
Expand Down Expand Up @@ -311,12 +340,33 @@ export class UserSubscriptionResolver {

return this.db.userSubscription.findUnique({
where: {
userId: user.id,
userId_plan: {
userId: user.id,
plan: SubscriptionPlan.Pro,
},
status: SubscriptionStatus.Active,
},
});
}

@ResolveField(() => [UserSubscriptionType])
async subscriptions(
@CurrentUser() me: User,
@Parent() user: User
): Promise<UserSubscription[]> {
if (me.id !== user.id) {
throw new ForbiddenException(
'You are not allowed to access this subscription.'
);
}

return this.db.userSubscription.findMany({
where: {
userId: user.id,
},
});
}

@ResolveField(() => [UserInvoiceType])
async invoices(
@CurrentUser() me: User,
Expand Down
Loading

0 comments on commit adbb78f

Please sign in to comment.