Refactor notification service and map API views for improved readability and maintainability; add code complexity management guidelines

This commit is contained in:
pacnpal
2025-08-30 09:03:11 -04:00
parent 04394b9976
commit fb6726f89a
4 changed files with 280 additions and 247 deletions

View File

@@ -8,14 +8,14 @@ for various events including submission approvals/rejections.
from django.utils import timezone
from django.contrib.contenttypes.models import ContentType
from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.conf import settings
from django.db import models
from typing import Optional, Dict, Any, List
from datetime import datetime, timedelta
import logging
from apps.accounts.models.notifications import UserNotification, NotificationPreference
from apps.accounts.models import User
from apps.accounts.models import User, UserNotification, NotificationPreference
from apps.email_service.services import EmailService
logger = logging.getLogger(__name__)
@@ -32,7 +32,7 @@ class NotificationService:
related_object: Optional[Any] = None,
priority: str = UserNotification.Priority.NORMAL,
extra_data: Optional[Dict[str, Any]] = None,
expires_at: Optional[timezone.datetime] = None,
expires_at: Optional[datetime] = None,
) -> UserNotification:
"""
Create a new notification for a user.
@@ -220,17 +220,13 @@ class NotificationService:
):
NotificationService._send_email_notification(notification)
# Send push notification if enabled
if preferences.should_send_notification(notification.notification_type, "push"):
NotificationService._send_push_notification(notification)
# In-app notifications are always created (the notification object itself)
# The frontend will check preferences when displaying them
# Toast notifications are always created (the notification object itself)
# The frontend will display them as toast notifications based on preferences
@staticmethod
def _send_email_notification(notification: UserNotification) -> None:
"""
Send email notification to user.
Send email notification to user using the custom ForwardEmail service.
Args:
notification: The notification to send via email
@@ -251,14 +247,12 @@ class NotificationService:
html_message = render_to_string("emails/notification.html", context)
plain_message = render_to_string("emails/notification.txt", context)
# Send email
send_mail(
# Send email using custom ForwardEmail service
EmailService.send_email(
to=user.email,
subject=subject,
message=plain_message,
html_message=html_message,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[user.email],
fail_silently=False,
text=plain_message,
html=html_message,
)
# Mark as sent
@@ -275,28 +269,6 @@ class NotificationService:
f"Failed to send email notification {notification.id}: {str(e)}"
)
@staticmethod
def _send_push_notification(notification: UserNotification) -> None:
"""
Send push notification to user.
Args:
notification: The notification to send via push
"""
try:
# TODO: Implement push notification service (Firebase, etc.)
# For now, just mark as sent
notification.push_sent = True
notification.push_sent_at = timezone.now()
notification.save(update_fields=["push_sent", "push_sent_at"])
logger.info(f"Push notification sent for notification {notification.id}")
except Exception as e:
logger.error(
f"Failed to send push notification {notification.id}: {str(e)}"
)
@staticmethod
def get_user_notifications(
user: User,
@@ -366,7 +338,7 @@ class NotificationService:
Returns:
int: Number of notifications deleted
"""
cutoff_date = timezone.now() - timezone.timedelta(days=days)
cutoff_date = timezone.now() - timedelta(days=days)
old_notifications = UserNotification.objects.filter(
is_read=True, read_at__lt=cutoff_date