From 66c8fe94284eb3dadbae55b02d867123e080fb65 Mon Sep 17 00:00:00 2001 From: Trey t Date: Sun, 7 Dec 2025 09:14:41 -0600 Subject: [PATCH] Fix PostgreSQL query parameter encoding for notification hour check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WHERE clause with `? = ?` comparing two bound parameters caused PostgreSQL to fail with "unable to encode into text format" error. Fixed by moving the comparison to Go code and building the query conditionally. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- internal/worker/jobs/handler.go | 38 ++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/internal/worker/jobs/handler.go b/internal/worker/jobs/handler.go index 18c2544..bffedad 100644 --- a/internal/worker/jobs/handler.go +++ b/internal/worker/jobs/handler.go @@ -71,12 +71,21 @@ func (h *Handler) HandleTaskReminder(ctx context.Context, task *asynq.Task) erro // Step 1: Find users who should receive notifications THIS hour // Users with custom hour matching current hour, OR users with no custom hour when current hour is system default var eligibleUserIDs []uint - err := h.db.Model(&models.NotificationPreference{}). + + // Build query based on whether current hour is system default + query := h.db.Model(&models.NotificationPreference{}). Select("user_id"). - Where("task_due_soon = true"). - Where("(task_due_soon_hour = ? OR (task_due_soon_hour IS NULL AND ? = ?))", - currentHour, currentHour, systemDefaultHour). - Pluck("user_id", &eligibleUserIDs).Error + Where("task_due_soon = true") + + if currentHour == systemDefaultHour { + // Current hour is the system default, so include users with custom hour OR no custom hour (NULL) + query = query.Where("(task_due_soon_hour = ? OR task_due_soon_hour IS NULL)", currentHour) + } else { + // Current hour is not system default, so only include users with this specific custom hour + query = query.Where("task_due_soon_hour = ?", currentHour) + } + + err := query.Pluck("user_id", &eligibleUserIDs).Error if err != nil { log.Error().Err(err).Msg("Failed to query eligible users for task reminders") @@ -175,12 +184,21 @@ func (h *Handler) HandleOverdueReminder(ctx context.Context, task *asynq.Task) e // Step 1: Find users who should receive notifications THIS hour // Users with custom hour matching current hour, OR users with no custom hour when current hour is system default var eligibleUserIDs []uint - err := h.db.Model(&models.NotificationPreference{}). + + // Build query based on whether current hour is system default + query := h.db.Model(&models.NotificationPreference{}). Select("user_id"). - Where("task_overdue = true"). - Where("(task_overdue_hour = ? OR (task_overdue_hour IS NULL AND ? = ?))", - currentHour, currentHour, systemDefaultHour). - Pluck("user_id", &eligibleUserIDs).Error + Where("task_overdue = true") + + if currentHour == systemDefaultHour { + // Current hour is the system default, so include users with custom hour OR no custom hour (NULL) + query = query.Where("(task_overdue_hour = ? OR task_overdue_hour IS NULL)", currentHour) + } else { + // Current hour is not system default, so only include users with this specific custom hour + query = query.Where("task_overdue_hour = ?", currentHour) + } + + err := query.Pluck("user_id", &eligibleUserIDs).Error if err != nil { log.Error().Err(err).Msg("Failed to query eligible users for overdue reminders")