fix: embed DECAY_LAMBDA as SQL literal to avoid pg type inference failure
All checks were successful
Build and Push Backend Image / build (push) Successful in 45s
Build and Push Frontend Image / build (push) Successful in 1m12s

PostgreSQL cannot resolve the type of a parameterized $1 = 0.005 in
-$1 * EXTRACT(EPOCH ...) and fails with an operator type error. Using
sql.raw() embeds the constant directly in the query string so userId
is the only parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 19:54:50 +01:00
parent 8085b40af8
commit 52aa00dd13
2 changed files with 5 additions and 2 deletions

View File

@@ -62,7 +62,7 @@ export async function revokePoints(
export async function calculateWeightedScore(db: DB, userId: string): Promise<number> { export async function calculateWeightedScore(db: DB, userId: string): Promise<number> {
const result = await db.execute(sql` const result = await db.execute(sql`
SELECT SUM( SELECT SUM(
points * EXP(-${DECAY_LAMBDA} * EXTRACT(EPOCH FROM (NOW() - date_created)) / 86400) points * EXP(${sql.raw(String(-DECAY_LAMBDA))} * EXTRACT(EPOCH FROM (NOW() - date_created)) / 86400)
) as weighted_score ) as weighted_score
FROM user_points FROM user_points
WHERE user_id = ${userId} WHERE user_id = ${userId}

View File

@@ -17,7 +17,10 @@ export function startGamificationWorker(): Worker {
"gamification", "gamification",
async (bullJob) => { async (bullJob) => {
const data = bullJob.data as GamificationJobData; const data = bullJob.data as GamificationJobData;
log.info({ jobId: bullJob.id, job: data.job, userId: data.userId }, "Processing gamification job"); log.info(
{ jobId: bullJob.id, job: data.job, userId: data.userId },
"Processing gamification job",
);
switch (data.job) { switch (data.job) {
case "awardPoints": case "awardPoints":