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

234 lines
6.8 KiB
Markdown

# 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:
```python
# 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:
```python
path('inbox/broadcast/create/', views.BroadcastNotificationCreateView.as_view(),
name='broadcast_notification_create')
```
## Usage Examples
### Creating Personal Notifications (Existing Code)
```python
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)
```python
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)
```python
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
```python
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:
```python
# 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:
```python
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:**
```python
# Create a notification for a specific user
Notification.create_personal(user, "Test", "Personal notification")
# Verify only that user sees it
```
2. **Test General Notifications:**
```python
# Create a general notification
Notification.create_general("Announcement", "System-wide message")
# Verify all users see it
```
3. **Test Role-Based Notifications:**
```python
# 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:
```bash
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.