Best practices and rules for the notification system in the app - do you have any advice?

I'm looking for ideas for functional and optimized notifications in the app that won't kill it :) In the simplest terms: - many operations of different types are executed in the application: on the one hand, project management, where people involved in the project should get relevant notifications (about status changes, changes in the project, their opening or closing, etc.), on the other hand, there are general notifications or notifications about user-related elements (e.g., a particular user is not involved only in the project but has oversight of individual resources or manages people and some notifications about their actions should also receive) - users can be in one in many roles within projects and not all notifications apply to them - each notification can be delivered to multiple users and their read status should be managed (i.e. if a particular notification has been read by a specific user then it gets the status "read") - notifications within a single project can be really many and concern individual elements in projects, so it would be good, however, for notifications to group in a sense (instead of sending 20 notifications about changes in the project, it is better to send one notification about 20 changes; here note: taking into note the above, it may be that the notification was read by one user after 5 changes, by another after 10, and another user has not yet read any of the 20) - users should be able to "turn off" notifications, i.e. they can decide that a certain type of notification does not interest them - the user should also be able to change a notification from "read" to "unread" in a situation in which he should return to a given notification Therefore, I would like to ask you for advice (I do not expect you to show me step by step what to do, but perhaps you can suggest how to prepare for this from the beginning to avoid problems later and not have to rebuild the entire notification system from scratch). I imagine that there should be an entity that collects these notifications, and perhaps to each entity element should simply be assigned all users who have read the status. This is where the read issue comes in - and I imagine that there should be an middle entity. But won't such a solution make the database grow to an incredibly large size? There won't be many users, let's say 50, but if each of them gets 40 notifications a day, then for 3 months this will accumulate a very heavy database of up to 180,000 notifications and this already sounds like "too much" (at the same time I imagine that old notifications, above let's say these 90 days, should be deleted to clean up the database from time to time). Another question is how to create the notification entity itself. If a user within a project has changed 10 items (for example, in one go), how to notify the user about what specific changes have been made? What fields should the entity have so that it can be easily managed and operated on these changes. Would it be best to create an entity with categories of notifications so that it would be possible, for example, to group or filter them, or should it be an enumaration (this in turn limits later development of the notification system). What is the best way to handle these notifications? Should it be Pusher or perhaps I should think about another tool to get instant notifications? I'd love to hear about your experiences and advice on how to approach this as sensibly as possible so that I don't have to go back to the beginning in a while to fix a wrong assumption. I would appreciate any advice! :)
2 answers

Hi Lukasz,

Designing a robust and optimized notification system that meets your requirements can be challenging but achievable. 

  1. Data Model and Entities:

    • Create a "Notification" entity that represents individual notifications. This entity should have attributes like "Message," "Link" (for redirection), "ReadStatus," "Timestamp," etc.
    • Consider creating a separate "NotificationReadStatus" entity as a middle entity between "User" and "Notification" to manage the read status for each user.
    • To avoid excessive database growth, consider implementing a data retention policy where old notifications are automatically deleted after a certain period (e.g., 90 days) (if needed).
  2. Notification Categorization:

    • Use a "Category" attribute in the "Notification" entity to classify notifications based on the type of operation or project. This will help in grouping and filtering notifications later.
    • You can use an enumeration for predefined categories or a separate entity for dynamic categorization, depending on your flexibility needs.
  3. Managing Multiple Users and Roles:

    • Use associations to connect users with relevant notifications. Users should only receive notifications relevant to their roles or projects.
    • Implement logic to determine which users should receive specific notifications based on their roles and projects.
  4. Notification Grouping:

    • For multiple related changes in a project, consider sending a single consolidated notification rather than individual notifications. This will reduce the number of notifications generated and received.
  5. Notification Status and Interaction:

    • Implement logic to manage the "ReadStatus" attribute for each user, indicating whether a notification has been read or not.
    • Allow users to change the "ReadStatus" of a notification (from read to unread) if they need to revisit it later.
  6. Notification Delivery and Performance:

    • For instant notifications, consider using WebSockets or server-sent events (SSE) to push notifications to the users in real-time. Tools like Pusher can be useful for this purpose.
    • For non-real-time notifications, you can use background processes or scheduled jobs to periodically check for new notifications and deliver them to users.

Hi Abrar Ahmed,

If you want to be able to manage "NotificationreadStatus", you can use such a solution in the domain model, it will allow you to manage this status for each message separately.