Fix notification badge: exclude archived from count, recalculate on archive, update trigger

This commit is contained in:
Patrick Britton 2026-02-06 15:44:58 -06:00
parent d83cdb3778
commit a94c91da24
2 changed files with 32 additions and 1 deletions

View file

@ -257,6 +257,15 @@ func (r *NotificationRepository) ArchiveNotifications(ctx context.Context, ids [
UPDATE public.notifications SET archived_at = NOW(), is_read = TRUE
WHERE id = ANY($1::uuid[]) AND user_id = $2::uuid
`, ids, userID)
if err != nil {
return err
}
// Recalculate badge count excluding archived
_, err = r.pool.Exec(ctx, `
UPDATE profiles SET unread_notification_count = (
SELECT COUNT(*) FROM notifications WHERE user_id = $1::uuid AND is_read = FALSE AND archived_at IS NULL
) WHERE id = $1::uuid
`, userID)
return err
}
@ -265,6 +274,13 @@ func (r *NotificationRepository) ArchiveAllNotifications(ctx context.Context, us
UPDATE public.notifications SET archived_at = NOW(), is_read = TRUE
WHERE user_id = $1::uuid AND archived_at IS NULL
`, userID)
if err != nil {
return err
}
// Reset badge count — all notifications are now archived and read
_, err = r.pool.Exec(ctx, `
UPDATE profiles SET unread_notification_count = 0 WHERE id = $1::uuid
`, userID)
return err
}
@ -272,7 +288,7 @@ func (r *NotificationRepository) GetUnreadCount(ctx context.Context, userID stri
var count int
err := r.pool.QueryRow(ctx, `
SELECT COUNT(*) FROM public.notifications
WHERE user_id = $1::uuid AND is_read = FALSE
WHERE user_id = $1::uuid AND is_read = FALSE AND archived_at IS NULL
`, userID).Scan(&count)
return count, err
}

View file

@ -0,0 +1,15 @@
CREATE OR REPLACE FUNCTION update_unread_notification_count()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' AND NEW.archived_at IS NULL THEN
UPDATE profiles SET unread_notification_count = unread_notification_count + 1 WHERE id = NEW.user_id;
ELSIF TG_OP = 'UPDATE' THEN
IF OLD.is_read = FALSE AND (NEW.is_read = TRUE OR NEW.archived_at IS NOT NULL) THEN
UPDATE profiles SET unread_notification_count = GREATEST(0, unread_notification_count - 1) WHERE id = NEW.user_id;
END IF;
ELSIF TG_OP = 'DELETE' AND OLD.is_read = FALSE AND OLD.archived_at IS NULL THEN
UPDATE profiles SET unread_notification_count = GREATEST(0, unread_notification_count - 1) WHERE id = OLD.user_id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;