fix: credit balance issues (#21904)

* fix creating user balance

* fix org check if teamId is given

* adjust hasAvailableCredits function

* improve comments

* fix creditBalance.create

* adjust test

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
This commit is contained in:
Carina Wollendorfer
2025-06-24 09:18:14 +02:00
committed by GitHub
co-authored by CarinaWolli
parent a37f1d9798
commit c215dc5864
4 changed files with 22 additions and 3 deletions
+1 -1
View File
@@ -121,7 +121,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
if (!orgId) {
orgId = await getOrgIdFromMemberOrTeamId({
memberId: parsedUserId,
...(!parsedTeamId ? { memberId: parsedUserId } : {}),
teamId: parsedTeamId,
});
}
@@ -191,6 +191,7 @@ describe("CreditService", () => {
teamId: 1,
availableCredits: 0,
creditType: CreditType.ADDITIONAL,
limitReached: true,
});
});
});
+10 -1
View File
@@ -130,6 +130,9 @@ export class CreditService {
});
}
/*
also returns true if team has no available credits but limitReachedAt is not yet set
*/
async hasAvailableCredits({ userId, teamId }: { userId?: number | null; teamId?: number | null }) {
return await prisma.$transaction(async (tx) => {
if (!IS_SMS_CREDITS_ENABLED) return true;
@@ -160,12 +163,14 @@ export class CreditService {
);
return true;
}
// limtReachedAt is set and still no available credits
return false;
}
if (userId) {
const teamWithAvailableCredits = await this._getTeamWithAvailableCredits({ userId, tx });
if (teamWithAvailableCredits && teamWithAvailableCredits?.availableCredits > 0) return true;
if (teamWithAvailableCredits && !teamWithAvailableCredits.limitReached) return true;
const userCredits = await this._getAllCredits({ userId, tx });
@@ -182,6 +187,9 @@ export class CreditService {
});
}
/*
If user has memberships, it always returns a team, even if all have limit reached. In that case, limitReached: true is returned
*/
protected async _getTeamWithAvailableCredits({ userId, tx }: { userId: number; tx: PrismaTransaction }) {
const memberships = await MembershipRepository.findAllAcceptedMemberships(userId, tx);
@@ -226,6 +234,7 @@ export class CreditService {
teamId: memberships[0].teamId,
availableCredits: 0,
creditType: CreditType.ADDITIONAL,
limitReached: true,
};
}
+10 -1
View File
@@ -180,8 +180,17 @@ export class CreditsRepository {
}
static async createCreditBalance(data: Prisma.CreditBalanceUncheckedCreateInput, tx?: PrismaTransaction) {
const { teamId, userId } = data;
if (!teamId && !userId) {
throw new Error("Team or user ID is required");
}
return (tx ?? prisma).creditBalance.create({
data,
data: {
...data,
...(!teamId ? { userId } : {}),
},
});
}