refactor: streamline user payment retrieval by utilizing a subquery for latest active payments

This commit is contained in:
javayhu 2025-08-10 15:54:46 +08:00
parent 0be53d3251
commit 064576f48e

View File

@ -569,35 +569,36 @@ export async function distributeCreditsToAllUsers() {
// Get all users with their current active payments/subscriptions in a single query // Get all users with their current active payments/subscriptions in a single query
// This uses a LEFT JOIN to get users and their latest active payment in one query // This uses a LEFT JOIN to get users and their latest active payment in one query
const latestPaymentQuery = db
.select({
userId: payment.userId,
priceId: payment.priceId,
status: payment.status,
createdAt: payment.createdAt,
rowNumber:
sql<number>`ROW_NUMBER() OVER (PARTITION BY ${payment.userId} ORDER BY ${payment.createdAt} DESC)`.as(
'row_number'
),
})
.from(payment)
.where(or(eq(payment.status, 'active'), eq(payment.status, 'trialing')))
.as('latest_payment');
const usersWithPayments = await db const usersWithPayments = await db
.select({ .select({
userId: user.id, userId: user.id,
email: user.email, email: user.email,
name: user.name, name: user.name,
priceId: payment.priceId, priceId: latestPaymentQuery.priceId,
paymentStatus: payment.status, paymentStatus: latestPaymentQuery.status,
paymentCreatedAt: payment.createdAt, paymentCreatedAt: latestPaymentQuery.createdAt,
}) })
.from(user) .from(user)
.leftJoin( .leftJoin(
// Subquery to get the latest active payment for each user latestPaymentQuery,
db
.select({
userId: payment.userId,
priceId: payment.priceId,
status: payment.status,
createdAt: payment.createdAt,
rowNumber:
sql<number>`ROW_NUMBER() OVER (PARTITION BY ${payment.userId} ORDER BY ${payment.createdAt} DESC)`.as(
'row_number'
),
})
.from(payment)
.where(or(eq(payment.status, 'active'), eq(payment.status, 'trialing')))
.as('latest_payment'),
and( and(
eq(user.id, sql`latest_payment.user_id`), eq(user.id, latestPaymentQuery.userId),
eq(sql`latest_payment.row_number`, 1) eq(latestPaymentQuery.rowNumber, 1)
) )
) )
.where(or(isNull(user.banned), eq(user.banned, false))); .where(or(isNull(user.banned), eq(user.banned, false)));