Repository: liberapay/liberapay.com

Issue:
Wrong pending notifications count
I've been made aware that a user was seeing a "2" for the pending notifications count in the navbar while having no new notifications in reality.

I think I may have forgotten to update `pending_notifs` the last time I deleted notifications in a `branch.sql`.


Discussion:
I've used the following query to recompute the notifications counts:

```sql
WITH p AS (
         SELECT p.id
              , ( SELECT count(*)
                    FROM notifications n
                   WHERE n.participant = p.id
                     AND n.is_new
                ) AS pending_notifs
           FROM participants p
     )
UPDATE participants p2
   SET pending_notifs = p.pending_notifs
  FROM p
 WHERE p.id = p2.id
   AND p.pending_notifs <> p2.pending_notifs;
```

Keeping this issue open for the possible future implementation of an automatic detection and/or correction mechanism.

Resolving patch:
diff --git a/liberapay/models/participant.py b/liberapay/models/participant.py
--- a/liberapay/models/participant.py
+++ b/liberapay/models/participant.py
@@ -1392,14 +1392,7 @@ def notify(self, event, force_email=False, email=True, web=True, idem_key=None,
         """, locals())
         if not web:
             return n_id
-        # Update the participant's `pending_notifs` count
-        pending_notifs = self.db.one("""
-            UPDATE participants
-               SET pending_notifs = pending_notifs + 1
-             WHERE id = %(p_id)s
-         RETURNING pending_notifs;
-        """, locals())
-        self.set_attributes(pending_notifs=pending_notifs)
+        self.set_attributes(pending_notifs=self.pending_notifs + 1)
         return n_id
 
     def mark_notification_as_read(self, n_id):
@@ -1411,16 +1404,7 @@ def mark_notification_as_read(self, n_id):
                AND id = %(n_id)s
                AND is_new
                AND web;
-            UPDATE participants
-               SET pending_notifs = (
-                       SELECT count(*)
-                         FROM notifications
-                        WHERE participant = %(p_id)s
-                          AND web
-                          AND is_new
-                   )
-             WHERE id = %(p_id)s
-         RETURNING pending_notifs;
+            SELECT pending_notifs FROM participants WHERE id = %(p_id)s;
         """, locals())
         self.set_attributes(pending_notifs=r)
 
@@ -1440,16 +1424,7 @@ def mark_notifications_as_read(self, event=None, until=None):
                AND is_new
                AND web
                {0};
-            UPDATE participants
-               SET pending_notifs = (
-                       SELECT count(*)
-                         FROM notifications
-                        WHERE participant = %(p_id)s
-                          AND web
-                          AND is_new
-                   )
-             WHERE id = %(p_id)s
-         RETURNING pending_notifs;
+            SELECT pending_notifs FROM participants WHERE id = %(p_id)s;
         """.format(sql_filter), locals())
         self.set_attributes(pending_notifs=r)
 
@@ -1462,16 +1437,7 @@ def remove_notification(self, n_id):
              WHERE id = %(n_id)s
                AND participant = %(p_id)s
                AND web;
-            UPDATE participants
-               SET pending_notifs = (
-                       SELECT count(*)
-                         FROM notifications
-                        WHERE participant = %(p_id)s
-                          AND web
-                          AND is_new
-                   )
-             WHERE id = %(p_id)s
-         RETURNING pending_notifs;
+            SELECT pending_notifs FROM participants WHERE id = %(p_id)s;
         """, locals())
         self.set_attributes(pending_notifs=r)
 


Test patch: