fix(server): separate active subscriptions (#13077)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved accuracy of subscription management by ensuring only active
or trialing subscriptions are considered in all relevant user,
workspace, and license actions.
* Enhanced consistency in subscription retrieval for workspace member
updates and subscription-related operations.

* **Refactor**
* Updated internal subscription retrieval methods to distinguish between
general and active subscriptions for more precise handling across the
app.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Yii
2025-07-08 11:02:08 +08:00
committed by GitHub
parent b9b336f728
commit 61da63a4a0
7 changed files with 40 additions and 8 deletions

View File

@@ -79,7 +79,7 @@ export class LicenseController {
});
}
const subscription = await this.manager.getSubscription({
const subscription = await this.manager.getActiveSubscription({
key: license.key,
plan: SubscriptionPlan.SelfHostedTeam,
});
@@ -140,7 +140,7 @@ export class LicenseController {
},
});
const subscription = await this.manager.getSubscription({
const subscription = await this.manager.getActiveSubscription({
key,
plan: SubscriptionPlan.SelfHostedTeam,
});

View File

@@ -84,9 +84,14 @@ export abstract class SubscriptionManager {
subscription: KnownStripeSubscription
): Promise<void>;
abstract getActiveSubscription(
identity: z.infer<typeof SubscriptionIdentity>
): Promise<Subscription | null>;
abstract getSubscription(
identity: z.infer<typeof SubscriptionIdentity>
): Promise<Subscription | null>;
abstract cancelSubscription(
subscription: Subscription
): Promise<Subscription>;

View File

@@ -186,6 +186,14 @@ export class SelfhostTeamSubscriptionManager extends SubscriptionManager {
}
getSubscription(identity: z.infer<typeof SelfhostTeamSubscriptionIdentity>) {
return this.db.subscription.findFirst({
where: { targetId: identity.key },
});
}
getActiveSubscription(
identity: z.infer<typeof SelfhostTeamSubscriptionIdentity>
) {
return this.db.subscription.findFirst({
where: {
targetId: identity.key,

View File

@@ -198,6 +198,15 @@ export class UserSubscriptionManager extends SubscriptionManager {
}
async getSubscription(args: z.infer<typeof UserSubscriptionIdentity>) {
return this.db.subscription.findFirst({
where: {
targetId: args.userId,
plan: args.plan,
},
});
}
async getActiveSubscription(args: z.infer<typeof UserSubscriptionIdentity>) {
return this.db.subscription.findFirst({
where: {
targetId: args.userId,

View File

@@ -202,6 +202,16 @@ export class WorkspaceSubscriptionManager extends SubscriptionManager {
}
getSubscription(identity: z.infer<typeof WorkspaceSubscriptionIdentity>) {
return this.db.subscription.findFirst({
where: {
targetId: identity.workspaceId,
},
});
}
getActiveSubscription(
identity: z.infer<typeof WorkspaceSubscriptionIdentity>
) {
return this.db.subscription.findFirst({
where: {
targetId: identity.workspaceId,
@@ -277,7 +287,7 @@ export class WorkspaceSubscriptionManager extends SubscriptionManager {
@OnEvent('workspace.members.updated')
async onMembersUpdated({ workspaceId }: Events['workspace.members.updated']) {
const count = await this.models.workspaceUser.chargedCount(workspaceId);
const subscription = await this.getSubscription({
const subscription = await this.getActiveSubscription({
plan: SubscriptionPlan.Team,
workspaceId,
});

View File

@@ -528,7 +528,7 @@ export class WorkspaceSubscriptionResolver {
description: 'The team subscription of the workspace, if exists.',
})
async subscription(@Parent() workspace: WorkspaceType) {
return this.service.getSubscription({
return this.service.getActiveSubscription({
plan: SubscriptionPlan.Team,
workspaceId: workspace.id,
});

View File

@@ -159,7 +159,7 @@ export class SubscriptionService {
this.assertSubscriptionIdentity(identity);
const manager = this.select(identity.plan);
const subscription = await manager.getSubscription(identity);
const subscription = await manager.getActiveSubscription(identity);
if (!subscription) {
throw new SubscriptionNotExists({ plan: identity.plan });
@@ -205,7 +205,7 @@ export class SubscriptionService {
const manager = this.select(identity.plan);
const subscription = await manager.getSubscription(identity);
const subscription = await manager.getActiveSubscription(identity);
if (!subscription) {
throw new SubscriptionNotExists({ plan: identity.plan });
@@ -252,7 +252,7 @@ export class SubscriptionService {
this.assertSubscriptionIdentity(identity);
const manager = this.select(identity.plan);
const subscription = await manager.getSubscription(identity);
const subscription = await manager.getActiveSubscription(identity);
if (!subscription) {
throw new SubscriptionNotExists({ plan: identity.plan });
@@ -304,7 +304,7 @@ export class SubscriptionService {
) {
this.assertSubscriptionIdentity(identity);
const subscription = await this.select(identity.plan).getSubscription(
const subscription = await this.select(identity.plan).getActiveSubscription(
identity
);