Skip to content

Fix #155 Added notification system#168

Merged
bhavik-mangla merged 1 commit intoAOSSIE-Org:mainfrom
DeveloperAmrit:fix-155-notification-system-3
Jan 8, 2026
Merged

Fix #155 Added notification system#168
bhavik-mangla merged 1 commit intoAOSSIE-Org:mainfrom
DeveloperAmrit:fix-155-notification-system-3

Conversation

@DeveloperAmrit
Copy link
Contributor

@DeveloperAmrit DeveloperAmrit commented Jan 1, 2026

Fixes #155 second part. Added notification system that notifies for

Comments: Updated comment_controller.go to notify users when someone replies to their comment or comments on their transcript.

Badges: Updated gamification_controller.go to notify users when they earn a new badge.

Tournaments: Updated team_debate_controller.go to notify team members when a team debate starts.

Leaderboard/Rating: Updated rating_service.go to notify users when their rating increases after a debate.

Team Join: Updated team_controller.go to notify the captain when a new member joins the team.

Video

Screen.Recording.2026-01-08.at.7.56.46.PM.mov

Summary by CodeRabbit

  • New Features
    • Added notification center to keep users informed of activities including comments, badges, tournaments, and leaderboard updates.
    • Bell icon in header displays unread notification count.
    • Mark notifications as read individually or in bulk; delete notifications as needed.
    • New user profile popover displaying account details and sign-out option.
    • Notifications automatically refresh every 60 seconds.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 1, 2026

📝 Walkthrough

Walkthrough

Implements a comprehensive notification system spanning backend persistence and frontend UI integration. Adds notification models, service layer, and CRUD endpoints. Integrates notification creation into comment workflows, badge awards, team joins, team debates, and rating updates. Frontend includes notification polling, read-status management, deletion, and user profile popover.

Changes

Cohort / File(s) Summary
Backend Notification Infrastructure
backend/models/notification.go, backend/services/notification_service.go, backend/controllers/notification_controller.go, backend/routes/notification.go
Introduces new Notification model with NotificationType enum (comment, badge, tournament, leaderboard, system) and BSON/JSON serialization. Implements CreateNotification service to persist records to MongoDB. Adds four HTTP handlers (GET, PUT, PUT, DELETE) for retrieving, marking as read, bulk-reading, and deleting notifications with token-based auth and error handling. Route handlers delegate to controllers.
Backend Routing
backend/cmd/server/main.go
Registers four notification routes (GET /notifications, PUT /notifications/:id/read, PUT /notifications/read-all, DELETE /notifications/:id) under authenticated router group.
Backend Notification Integration
backend/controllers/comment_controller.go, backend/controllers/gamification_controller.go, backend/controllers/team_controller.go, backend/controllers/team_debate_controller.go, backend/services/rating_service.go
Adds asynchronous notification creation across multiple workflows: comment replies notify parent author or transcript owner; badge awards notify recipient; team joins notify captain; team debates notify all members of both teams; rating increases notify involved users. All use goroutines to avoid blocking request handling.
Frontend Notification Service
frontend/src/services/notificationService.ts
Implements Notification interface and four API helper functions: getNotifications (polling), markNotificationAsRead, markAllNotificationsAsRead, deleteNotification. Uses Bearer token authentication and localStorage for token retrieval.
Frontend Header UI
frontend/src/components/Header.tsx
Replaces basic header with feature-rich component featuring notification popover (scrollable list with title, message, timestamp, read indicator, delete button) with 60-second polling, individual/bulk read marking, and navigation on click; adds user profile popover displaying avatar, name, email, user ID, rating, and logout button. Includes unread badge on bell icon.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Frontend as Frontend<br/>(Header.tsx)
    participant API as Backend API<br/>(Controller)
    participant Svc as Services<br/>(Notification)
    participant DB as MongoDB<br/>(notifications)

    Note over Frontend,DB: Notification Creation Flow<br/>(e.g., Comment Posted)
    User->>API: POST /comments
    API->>Svc: services.CreateNotification(...)
    Svc->>DB: Insert notification record
    DB-->>Svc: Success
    Svc-->>API: Returns error or nil
    API-->>User: 200 OK (comment posted)

    Note over Frontend,DB: Notification Consumption Flow
    Frontend->>Frontend: useEffect interval (60s)
    Frontend->>API: GET /notifications
    API->>DB: Query notifications for user
    DB-->>API: Return sorted notifications
    API-->>Frontend: JSON array
    Frontend->>Frontend: Update state, compute unreadCount
    User->>Frontend: Click notification
    Frontend->>API: PUT /notifications/{id}/read
    API->>DB: Update isRead = true
    DB-->>API: Success
    API-->>Frontend: Success message
    Frontend->>Frontend: Mark item visually, update badge
    
    alt User deletes notification
        User->>Frontend: Click delete button
        Frontend->>API: DELETE /notifications/{id}
        API->>DB: Delete record
        DB-->>API: Success
        API-->>Frontend: Success message
        Frontend->>Frontend: Remove from list, update unreadCount
    end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Poem

🔔 Hop, hop! The bell now rings with cheer,
Notifications bringing news so dear,
Comments, badges, tournaments abound,
Users notified with every sound!
A fluffy system, hopping through the code,
Where users smile down every notification road! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly references issue #155 and accurately describes the main change: implementing a notification system that was previously not working.
Linked Issues check ✅ Passed The PR implements all core notification requirements from issue #155: comments, badges, tournaments, leaderboard/rating updates, and adds a user profile popover with name, email, and logout.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the notification system and profile icon feature specified in issue #155; no unrelated modifications detected.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
backend/controllers/comment_controller.go (1)

100-143: Consider logging notification creation failures.

The goroutine correctly uses context.Background() for the async notification task. However, errors from services.CreateNotification are silently discarded, which could make debugging notification delivery issues difficult.

🔎 Proposed improvement
 go func() {
     if req.ParentID != nil && *req.ParentID != "" {
         // Notify parent comment author
         var parent models.Comment
         if err := db.MongoDatabase.Collection("comments").FindOne(context.Background(), bson.M{"_id": comment.ParentID}).Decode(&parent); err == nil {
             if parent.UserID != userID {
-                services.CreateNotification(
+                if err := services.CreateNotification(
                     parent.UserID,
                     models.NotificationTypeComment,
                     "New Reply",
                     user.DisplayName+" replied to your comment",
                     "/debate/"+req.TranscriptID,
-                )
+                ); err != nil {
+                    log.Printf("Failed to create reply notification: %v", err)
+                }
             }
         }
     } else {
         // ... similar handling for transcript owner notification
     }
 }()

Also, note the different link patterns: /debate/ for replies (line 112) vs /view-debate/ for new comments (line 138). Please verify this inconsistency is intentional.

backend/services/notification_service.go (1)

13-28: Consider adding a timeout for the database operation.

Using context.Background() without a timeout means the insert could hang indefinitely if MongoDB is unresponsive. Since this function is often called asynchronously, a timeout would prevent goroutine leaks.

🔎 Proposed improvement
 func CreateNotification(userID primitive.ObjectID, notifType models.NotificationType, title, message, link string) error {
+    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+    defer cancel()
+
     notification := models.Notification{
         ID:        primitive.NewObjectID(),
         UserID:    userID,
         Type:      notifType,
         Title:     title,
         Message:   message,
         Link:      link,
         IsRead:    false,
         CreatedAt: time.Now(),
     }

     collection := db.GetCollection("notifications")
-    _, err := collection.InsertOne(context.Background(), notification)
+    _, err := collection.InsertOne(ctx, notification)
     return err
 }
backend/controllers/notification_controller.go (1)

35-55: Consider adding pagination for notification fetching.

Fetching all notifications without pagination could become problematic for active users who accumulate many notifications over time, leading to large response payloads and slower queries.

🔎 Example pagination approach
 func GetNotificationsHandler(c *gin.Context) {
     // ... auth code ...

+    // Parse pagination params
+    limit := 50 // default
+    if l := c.Query("limit"); l != "" {
+        if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 && parsed <= 100 {
+            limit = parsed
+        }
+    }
+
     collection := db.GetCollection("notifications")
-    opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
+    opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}}).SetLimit(int64(limit))
     cursor, err := collection.Find(context.Background(), bson.M{"userId": userID}, opts)
frontend/src/services/notificationService.ts (1)

30-70: Mutation operations don't validate response status.

The markNotificationAsRead, markAllNotificationsAsRead, and deleteNotification functions don't check response.ok, so server errors (4xx/5xx) are silently ignored. While this may be acceptable for a fire-and-forget UX, it could mask issues.

🔎 Proposed improvement
 export const markNotificationAsRead = async (id: string): Promise<void> => {
   const token = localStorage.getItem('token');
   if (!token) return;
   
   try {
-    await fetch(`${API_URL}/notifications/${id}/read`, {
+    const response = await fetch(`${API_URL}/notifications/${id}/read`, {
       method: 'PUT',
       headers: { Authorization: `Bearer ${token}` }
     });
+    if (!response.ok) throw new Error('Failed to mark notification as read');
   } catch (error) {
     console.error('Error marking notification as read:', error);
   }
 };
frontend/src/components/Header.tsx (1)

46-51: Missing dependency in useEffect may cause stale closure.

The fetchNotifications function is called inside the effect but not listed in the dependency array. While it currently works because fetchNotifications only captures user, this could cause subtle bugs if the function changes. Consider using useCallback or moving the fetch logic inline.

🔎 Proposed fix using useCallback
+import { useCallback } from "react";

-const fetchNotifications = async () => {
+const fetchNotifications = useCallback(async () => {
   if (user) {
     const data = await getNotifications();
     setNotifications(data);
     setUnreadCount(data.filter(n => !n.isRead).length);
   }
-};
+}, [user]);

 useEffect(() => {
   fetchNotifications();
   const interval = setInterval(fetchNotifications, 60000);
   return () => clearInterval(interval);
-}, [user]);
+}, [fetchNotifications]);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8db72 and e77b685.

📒 Files selected for processing (13)
  • backend/cmd/server/main.go
  • backend/controllers/comment_controller.go
  • backend/controllers/gamification_controller.go
  • backend/controllers/notification_controller.go
  • backend/controllers/team_controller.go
  • backend/controllers/team_debate_controller.go
  • backend/main
  • backend/models/notification.go
  • backend/routes/notification.go
  • backend/services/notification_service.go
  • backend/services/rating_service.go
  • frontend/src/components/Header.tsx
  • frontend/src/services/notificationService.ts
🧰 Additional context used
🧬 Code graph analysis (10)
backend/services/notification_service.go (3)
backend/models/notification.go (2)
  • NotificationType (9-9)
  • Notification (19-28)
frontend/src/services/notificationService.ts (1)
  • Notification (3-12)
backend/db/db.go (1)
  • GetCollection (23-25)
backend/routes/notification.go (1)
backend/controllers/notification_controller.go (4)
  • GetNotificationsHandler (19-55)
  • MarkNotificationAsReadHandler (58-97)
  • MarkAllNotificationsAsReadHandler (100-127)
  • DeleteNotificationHandler (130-168)
backend/controllers/comment_controller.go (4)
backend/models/comment.go (2)
  • Comment (11-23)
  • DebatePost (48-64)
backend/db/db.go (1)
  • MongoDatabase (18-18)
backend/services/notification_service.go (1)
  • CreateNotification (14-29)
backend/models/notification.go (1)
  • NotificationTypeComment (12-12)
backend/controllers/notification_controller.go (4)
backend/utils/auth.go (1)
  • ValidateTokenAndFetchEmail (133-146)
backend/utils/user.go (1)
  • GetUserIDFromEmail (15-28)
backend/db/db.go (1)
  • GetCollection (23-25)
backend/models/notification.go (1)
  • Notification (19-28)
frontend/src/services/notificationService.ts (1)
backend/models/notification.go (1)
  • Notification (19-28)
backend/controllers/team_debate_controller.go (2)
backend/services/notification_service.go (1)
  • CreateNotification (14-29)
backend/models/notification.go (1)
  • NotificationTypeTournament (14-14)
backend/services/rating_service.go (2)
backend/services/notification_service.go (1)
  • CreateNotification (14-29)
backend/models/notification.go (1)
  • NotificationTypeLeaderboard (15-15)
backend/cmd/server/main.go (1)
backend/routes/notification.go (4)
  • GetNotificationsRouteHandler (9-11)
  • MarkNotificationAsReadRouteHandler (13-15)
  • MarkAllNotificationsAsReadRouteHandler (17-19)
  • DeleteNotificationRouteHandler (21-23)
frontend/src/components/Header.tsx (3)
frontend/src/state/userAtom.ts (1)
  • userAtom (4-4)
frontend/src/context/authContext.tsx (1)
  • AuthContext (35-37)
frontend/src/services/notificationService.ts (5)
  • Notification (3-12)
  • getNotifications (14-28)
  • markNotificationAsRead (30-42)
  • deleteNotification (58-70)
  • markAllNotificationsAsRead (44-56)
backend/controllers/team_controller.go (2)
backend/services/notification_service.go (1)
  • CreateNotification (14-29)
backend/models/notification.go (1)
  • NotificationTypeSystem (16-16)
🔇 Additional comments (6)
backend/cmd/server/main.go (1)

157-161: LGTM!

The notification routes are properly registered under the authenticated group with appropriate HTTP methods for each operation.

backend/routes/notification.go (1)

1-23: LGTM!

The route handler wrappers follow a clean delegation pattern to the controllers. This maintains separation between routing and business logic.

backend/models/notification.go (1)

1-28: LGTM!

The notification model is well-structured with appropriate BSON/JSON tags. The NotificationType constants align correctly with the frontend interface definition.

backend/controllers/notification_controller.go (1)

57-168: LGTM!

The handlers correctly enforce ownership by filtering on userId in addition to _id, preventing unauthorized access to other users' notifications. Error handling is consistent across all operations.

frontend/src/services/notificationService.ts (1)

1-28: LGTM!

The Notification interface aligns with the backend model, and getNotifications properly handles errors with fallback to an empty array.

frontend/src/components/Header.tsx (1)

127-238: Well-implemented notification and profile popovers.

The notification UI provides good UX with read/unread indicators, delete on hover, and mark-all-read functionality. The user profile popover addresses the issue requirement for profile icon behavior with name, email, and logout option.

Comment on lines +149 to +158
// Create notification for the badge
go func() {
services.CreateNotification(
targetUserID,
models.NotificationTypeBadge,
"New Badge Earned!",
fmt.Sprintf("You have earned the %s badge!", req.BadgeName),
"/profile",
)
}()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Log errors from CreateNotification to avoid silent failures.

Similar to other notification calls in this PR, the goroutine ignores errors from CreateNotification, which means badge award notifications may fail silently.

🔎 Proposed fix to add error logging
 	// Create notification for the badge
 	go func() {
-		services.CreateNotification(
+		err := services.CreateNotification(
 			targetUserID,
 			models.NotificationTypeBadge,
 			"New Badge Earned!",
 			fmt.Sprintf("You have earned the %s badge!", req.BadgeName),
 			"/profile",
 		)
+		if err != nil {
+			log.Printf("Failed to create badge notification for user %s: %v", targetUserID.Hex(), err)
+		}
 	}()
🤖 Prompt for AI Agents
In backend/controllers/gamification_controller.go around lines 149-158, the
goroutine calling CreateNotification ignores its returned error, causing silent
failures; modify the goroutine to capture the error returned by
services.CreateNotification, check if err != nil and log the error (using the
project's logger or log.Printf/log.Errorf) with context (e.g.,
"CreateNotification failed for user <targetUserID>: %v") so notification
creation failures are visible.

Comment on lines +385 to +394
// Notify team captain
go func() {
services.CreateNotification(
team.CaptainID,
models.NotificationTypeSystem,
"New Team Member",
user.DisplayName+" has joined your team "+team.Name,
"/team/"+teamID,
)
}()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Log errors from CreateNotification to avoid silent failures.

The goroutine ignores any error returned by CreateNotification. If notification creation fails (e.g., database issue), the captain won't receive the notification and there will be no trace of the failure.

🔎 Proposed fix to add error logging
 	// Notify team captain
 	go func() {
-		services.CreateNotification(
+		err := services.CreateNotification(
 			team.CaptainID,
 			models.NotificationTypeSystem,
 			"New Team Member",
 			user.DisplayName+" has joined your team "+team.Name,
 			"/team/"+teamID,
 		)
+		if err != nil {
+			log.Printf("Failed to create notification for team captain %s: %v", team.CaptainID.Hex(), err)
+		}
 	}()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Notify team captain
go func() {
services.CreateNotification(
team.CaptainID,
models.NotificationTypeSystem,
"New Team Member",
user.DisplayName+" has joined your team "+team.Name,
"/team/"+teamID,
)
}()
// Notify team captain
go func() {
err := services.CreateNotification(
team.CaptainID,
models.NotificationTypeSystem,
"New Team Member",
user.DisplayName+" has joined your team "+team.Name,
"/team/"+teamID,
)
if err != nil {
log.Printf("Failed to create notification for team captain %s: %v", team.CaptainID.Hex(), err)
}
}()

Comment on lines +98 to +110
// Notify all members of both teams
go func() {
allMembers := append(team1.Members, team2.Members...)
for _, member := range allMembers {
services.CreateNotification(
member.UserID,
models.NotificationTypeTournament,
"Team Debate Started",
"Your team debate on '"+req.Topic+"' has started!",
"/team-debate/"+debate.ID.Hex(),
)
}
}()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Log errors from CreateNotification to track individual notification failures.

The loop notifies all team members but ignores errors from CreateNotification. If notification creation fails for specific members, there will be no record of which users didn't receive the notification.

🔎 Proposed fix to add error logging
 	// Notify all members of both teams
 	go func() {
 		allMembers := append(team1.Members, team2.Members...)
 		for _, member := range allMembers {
-			services.CreateNotification(
+			err := services.CreateNotification(
 				member.UserID,
 				models.NotificationTypeTournament,
 				"Team Debate Started",
 				"Your team debate on '"+req.Topic+"' has started!",
 				"/team-debate/"+debate.ID.Hex(),
 			)
+			if err != nil {
+				log.Printf("Failed to create tournament notification for user %s: %v", member.UserID.Hex(), err)
+			}
 		}
 	}()
🤖 Prompt for AI Agents
In backend/controllers/team_debate_controller.go around lines 98 to 110, the
goroutine that calls services.CreateNotification ignores returned errors; update
the loop to capture the error from CreateNotification and log it (including
member.UserID, debate.ID.Hex(), req.Topic and the error) so individual
notification failures are traceable — perform the error check inside the
goroutine and use the controller's logger or a package logger (e.g. log.Printf
or c.logger.Errorf) to record a clear message when CreateNotification returns an
error.

Comment on lines +118 to +139
// Notify users about rating updates
go func() {
if userPlayer.Rating > preUserRating {
CreateNotification(
userID,
models.NotificationTypeLeaderboard,
"Rating Increased",
fmt.Sprintf("Your rating increased by %.1f points!", userPlayer.Rating-preUserRating),
"/leaderboard",
)
}

if opponentPlayer.Rating > preOpponentRating {
CreateNotification(
opponentID,
models.NotificationTypeLeaderboard,
"Rating Increased",
fmt.Sprintf("Your rating increased by %.1f points!", opponentPlayer.Rating-preOpponentRating),
"/leaderboard",
)
}
}()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Log errors from CreateNotification to avoid silent failures.

Both notification calls in the goroutine ignore errors from CreateNotification. Rating increase notifications may fail silently without any logging.

🔎 Proposed fix to add error logging
 	// Notify users about rating updates
 	go func() {
 		if userPlayer.Rating > preUserRating {
-			CreateNotification(
+			err := CreateNotification(
 				userID,
 				models.NotificationTypeLeaderboard,
 				"Rating Increased",
 				fmt.Sprintf("Your rating increased by %.1f points!", userPlayer.Rating-preUserRating),
 				"/leaderboard",
 			)
+			if err != nil {
+				log.Printf("Failed to create rating notification for user %s: %v", userID.Hex(), err)
+			}
 		}
 
 		if opponentPlayer.Rating > preOpponentRating {
-			CreateNotification(
+			err := CreateNotification(
 				opponentID,
 				models.NotificationTypeLeaderboard,
 				"Rating Increased",
 				fmt.Sprintf("Your rating increased by %.1f points!", opponentPlayer.Rating-preOpponentRating),
 				"/leaderboard",
 			)
+			if err != nil {
+				log.Printf("Failed to create rating notification for opponent %s: %v", opponentID.Hex(), err)
+			}
 		}
 	}()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Notify users about rating updates
go func() {
if userPlayer.Rating > preUserRating {
CreateNotification(
userID,
models.NotificationTypeLeaderboard,
"Rating Increased",
fmt.Sprintf("Your rating increased by %.1f points!", userPlayer.Rating-preUserRating),
"/leaderboard",
)
}
if opponentPlayer.Rating > preOpponentRating {
CreateNotification(
opponentID,
models.NotificationTypeLeaderboard,
"Rating Increased",
fmt.Sprintf("Your rating increased by %.1f points!", opponentPlayer.Rating-preOpponentRating),
"/leaderboard",
)
}
}()
// Notify users about rating updates
go func() {
if userPlayer.Rating > preUserRating {
err := CreateNotification(
userID,
models.NotificationTypeLeaderboard,
"Rating Increased",
fmt.Sprintf("Your rating increased by %.1f points!", userPlayer.Rating-preUserRating),
"/leaderboard",
)
if err != nil {
log.Printf("Failed to create rating notification for user %s: %v", userID.Hex(), err)
}
}
if opponentPlayer.Rating > preOpponentRating {
err := CreateNotification(
opponentID,
models.NotificationTypeLeaderboard,
"Rating Increased",
fmt.Sprintf("Your rating increased by %.1f points!", opponentPlayer.Rating-preOpponentRating),
"/leaderboard",
)
if err != nil {
log.Printf("Failed to create rating notification for opponent %s: %v", opponentID.Hex(), err)
}
}
}()
🤖 Prompt for AI Agents
In backend/services/rating_service.go around lines 118-139, the goroutine sends
two CreateNotification calls but ignores their returned errors; update each call
to capture the error return and log any failure (include context such as
userID/opponentID, notification type/title and the error) so notification
failures are not silent; use the package logger used elsewhere in this file (or
log.Printf if none) and keep the calls inside the goroutine so they don't block
the main flow.

Comment on lines +68 to +77
const handleDeleteNotification = async (e: React.MouseEvent, id: string) => {
e.stopPropagation();
await deleteNotification(id);
setNotifications(prev => prev.filter(n => n.id !== id));
// Update unread count if the deleted notification was unread
const notification = notifications.find(n => n.id === id);
if (notification && !notification.isRead) {
setUnreadCount(prev => Math.max(0, prev - 1));
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential stale state when checking unread status after deletion.

Line 73 accesses notifications after the async deleteNotification call, but the closure captures the state at the time of the click. If notifications changed during the async operation, this could lead to incorrect unreadCount updates.

🔎 Proposed fix
 const handleDeleteNotification = async (e: React.MouseEvent, id: string) => {
   e.stopPropagation();
+  // Find notification before async operation to avoid stale state
+  const notification = notifications.find(n => n.id === id);
+  const wasUnread = notification && !notification.isRead;
+  
   await deleteNotification(id);
   setNotifications(prev => prev.filter(n => n.id !== id));
-  // Update unread count if the deleted notification was unread
-  const notification = notifications.find(n => n.id === id);
-  if (notification && !notification.isRead) {
+  if (wasUnread) {
     setUnreadCount(prev => Math.max(0, prev - 1));
   }
 };

@bhavik-mangla
Copy link
Contributor

@DeveloperAmrit I see so many PRs
but they lack testing, you have implemented notifications system but where have u tested it?

@DeveloperAmrit
Copy link
Contributor Author

DeveloperAmrit commented Jan 8, 2026

@bhavik-mangla Here is the long video demonstrating it. I have tested them locally with two different accounts parallelly

Screen.Recording.2026-01-08.at.7.56.46.PM.mov

@bhavik-mangla bhavik-mangla merged commit b0bfbb2 into AOSSIE-Org:main Jan 8, 2026
1 check passed
@bhavik-mangla
Copy link
Contributor

good work @DeveloperAmrit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing feature: Profile icon and notification bell is not working

2 participants