agdar/USER_SPECIFIC_NOTIFICATIONS_IMPLEMENTATION.md
Marwan Alwali a4665842c9 update
2025-11-23 10:58:07 +03:00

6.8 KiB

User-Specific Notifications Implementation

Overview

The notifications system has been enhanced to support three types of notifications:

  1. Personal Notifications - Targeted to a specific user
  2. General Notifications - System-wide announcements visible to all users
  3. Role-Based Notifications - Visible to all users with specific roles

Changes Made

1. Model Updates (notifications/models.py)

New Fields Added to Notification Model:

  • user - Made nullable (null=True, blank=True) to support general/role-based notifications
  • is_general - Boolean field to mark system-wide announcements
  • target_roles - JSONField containing list of role codes for role-based notifications

New Class Methods:

# Get all notifications for a user (personal, general, and role-based)
Notification.get_for_user(user)

# Create a personal notification
Notification.create_personal(user, title, message, notification_type='INFO', ...)

# Create a general notification (visible to all users)
Notification.create_general(title, message, notification_type='INFO', ...)

# Create a role-based notification
Notification.create_role_based(roles, title, message, notification_type='INFO', ...)

2. Database Migration

Migration file: notifications/migrations/0003_add_general_and_role_based_notifications.py

Changes:

  • Added is_general field (default=False)
  • Added target_roles field (default=[])
  • Modified user field to be nullable

3. Views Updates (notifications/views.py)

Updated Views:

  • NotificationListView - Now uses Notification.get_for_user() to fetch all relevant notifications
  • NotificationDropdownView - Updated to use get_for_user() method
  • get_unread_count() and mark_all_as_read() - Updated to work with the new filtering

New View:

  • BroadcastNotificationCreateView - Admin-only view to create general or role-based notifications

4. Forms (notifications/forms.py)

New Form:

BroadcastNotificationForm - Form for creating broadcast notifications with:

  • Broadcast type selection (General or Role-Based)
  • Target roles selection (for role-based notifications)
  • Title, message, notification type, and action URL fields
  • Validation to ensure roles are selected for role-based notifications

5. URLs (notifications/urls.py)

New route added:

path('inbox/broadcast/create/', views.BroadcastNotificationCreateView.as_view(), 
     name='broadcast_notification_create')

Usage Examples

Creating Personal Notifications (Existing Code)

from notifications.models import Notification

# Create a personal notification for a specific user
Notification.create_personal(
    user=some_user,
    title="Appointment Reminder",
    message="You have an appointment tomorrow at 10:00 AM",
    notification_type='INFO',
    action_url='/appointments/123/'
)

Creating General Notifications (New)

from notifications.models import Notification

# Create a system-wide announcement
Notification.create_general(
    title="System Maintenance",
    message="The system will be under maintenance on Saturday from 2-4 AM",
    notification_type='WARNING'
)

Creating Role-Based Notifications (New)

from notifications.models import Notification
from core.models import User

# Notify all admins and front desk staff
Notification.create_role_based(
    roles=[User.Role.ADMIN, User.Role.FRONT_DESK],
    title="New Patient Registration",
    message="A new patient has been registered and requires file setup",
    notification_type='INFO',
    action_url='/patients/new/'
)

Querying Notifications

from notifications.models import Notification

# Get all notifications for a user (personal + general + role-based)
user_notifications = Notification.get_for_user(request.user)

# Get unread count
unread_count = Notification.get_unread_count(request.user)

# Mark all as read
Notification.mark_all_as_read(request.user)

Admin Interface

Admins can create broadcast notifications through the web interface:

  1. Navigate to /notifications/inbox/broadcast/create/
  2. Select broadcast type:
    • General: Visible to all users
    • Role-Based: Select specific roles
  3. Fill in title, message, type, and optional action URL
  4. Submit to create the notification

Backward Compatibility

Fully backward compatible - All existing code that creates personal notifications continues to work without modification:

# This still works exactly as before
Notification.objects.create(
    user=some_user,
    title="Test",
    message="Test message",
    notification_type='INFO'
)

Database Query Optimization

The get_for_user() method uses a single optimized query with OR conditions:

Q(user=user) |  # Personal notifications
Q(is_general=True) |  # General notifications
Q(target_roles__contains=[user.role])  # Role-based notifications

This ensures efficient retrieval of all relevant notifications in one database query.

Notification Types

Each notification can be one of four types:

  • INFO - Informational (blue)
  • SUCCESS - Success message (green)
  • WARNING - Warning (yellow/orange)
  • ERROR - Error or critical alert (red)

Security

  • Only users with ADMIN role can create broadcast notifications
  • Personal notifications are only visible to the targeted user
  • General notifications are visible to all authenticated users
  • Role-based notifications are only visible to users with matching roles

Testing

To test the implementation:

  1. Test Personal Notifications:

    # Create a notification for a specific user
    Notification.create_personal(user, "Test", "Personal notification")
    # Verify only that user sees it
    
  2. Test General Notifications:

    # Create a general notification
    Notification.create_general("Announcement", "System-wide message")
    # Verify all users see it
    
  3. Test Role-Based Notifications:

    # Create notification for admins only
    Notification.create_role_based(['ADMIN'], "Admin Alert", "Admin-only message")
    # Verify only admin users see it
    

Migration Instructions

The migration has already been applied. If deploying to a new environment:

python3 manage.py migrate notifications

Summary

The notification system now supports:

  • User-specific (personal) notifications
  • System-wide (general) notifications
  • Role-based notifications
  • Backward compatibility with existing code
  • Efficient database queries
  • Admin interface for creating broadcasts
  • Proper filtering in all views

Users will now only see notifications that are:

  1. Specifically addressed to them (personal)
  2. Marked as general (system-wide)
  3. Targeted to their role (role-based)

This solves the issue where users were seeing everyone's notifications.