Skip to content

Commit ddb825b

Browse files
committed
feat(billing): update grant logic to support legacy vs one-time referrals
- Rename calculateTotalReferralBonus to calculateTotalLegacyReferralBonus - Filter by is_legacy=true to only count grandfathered referrals - Use referral_legacy type for monthly renewal grants - Update test mocks to include referral_legacy in breakdown/principals
1 parent 146f0ba commit ddb825b

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

packages/billing/src/__tests__/usage-service.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ const mockBalance = {
1919
totalRemaining: 1000,
2020
totalDebt: 0,
2121
netBalance: 1000,
22-
breakdown: { free: 500, paid: 500, referral: 0, purchase: 0, admin: 0, organization: 0, ad: 0 },
23-
principals: { free: 500, paid: 500, referral: 0, purchase: 0, admin: 0, organization: 0, ad: 0 },
22+
breakdown: { free: 500, paid: 500, referral: 0, referral_legacy: 0, purchase: 0, admin: 0, organization: 0, ad: 0 },
23+
principals: { free: 500, paid: 500, referral: 0, referral_legacy: 0, purchase: 0, admin: 0, organization: 0, ad: 0 },
2424
}
2525

2626
describe('usage-service', () => {

packages/billing/src/grant-credits.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,13 @@ export async function getPreviousFreeGrantAmount(params: {
7171
}
7272

7373
/**
74-
* Calculates the total referral bonus credits a user should receive based on
75-
* their referral history (both as referrer and referred).
74+
* Calculates the total legacy referral bonus credits a user should receive based on
75+
* their legacy referral history (both as referrer and referred).
76+
* Only counts referrals where is_legacy = true (grandfathered users from old program).
7677
* @param userId The ID of the user.
77-
* @returns The total referral bonus credits earned.
78+
* @returns The total legacy referral bonus credits earned.
7879
*/
79-
export async function calculateTotalReferralBonus(params: {
80+
export async function calculateTotalLegacyReferralBonus(params: {
8081
userId: string
8182
logger: Logger
8283
}): Promise<number> {
@@ -89,19 +90,22 @@ export async function calculateTotalReferralBonus(params: {
8990
})
9091
.from(schema.referral)
9192
.where(
92-
or(
93-
eq(schema.referral.referrer_id, userId),
94-
eq(schema.referral.referred_id, userId),
93+
and(
94+
or(
95+
eq(schema.referral.referrer_id, userId),
96+
eq(schema.referral.referred_id, userId),
97+
),
98+
eq(schema.referral.is_legacy, true),
9599
),
96100
)
97101

98102
const totalBonus = parseInt(result[0]?.totalCredits ?? '0')
99-
logger.debug({ userId, totalBonus }, 'Calculated total referral bonus.')
103+
logger.debug({ userId, totalBonus }, 'Calculated total legacy referral bonus.')
100104
return totalBonus
101105
} catch (error) {
102106
logger.error(
103107
{ userId, error },
104-
'Error calculating total referral bonus. Returning 0.',
108+
'Error calculating total legacy referral bonus. Returning 0.',
105109
)
106110
return 0
107111
}
@@ -456,7 +460,7 @@ export async function triggerMonthlyResetAndGrant(params: {
456460
// Calculate grant amounts separately
457461
const [freeGrantAmount, referralBonus] = await Promise.all([
458462
getPreviousFreeGrantAmount(params),
459-
calculateTotalReferralBonus(params),
463+
calculateTotalLegacyReferralBonus(params),
460464
])
461465

462466
// Generate a deterministic operation ID based on userId and reset date to minute precision
@@ -481,14 +485,14 @@ export async function triggerMonthlyResetAndGrant(params: {
481485
tx,
482486
})
483487

484-
// Only grant referral credits if there are any
488+
// Only grant legacy referral credits if there are any (for grandfathered users)
485489
if (referralBonus > 0) {
486490
await executeGrantCreditOperation({
487491
...params,
488492
amount: referralBonus,
489-
type: 'referral',
490-
description: 'Monthly referral bonus',
491-
expiresAt: newResetDate, // Referral credits expire at next reset
493+
type: 'referral_legacy',
494+
description: 'Monthly referral bonus (legacy)',
495+
expiresAt: newResetDate, // Legacy referral credits expire at next reset
492496
operationId: referralOperationId,
493497
tx,
494498
})

0 commit comments

Comments
 (0)