feat: Implement initial schema and add various API, service, and management command enhancements across the application.

This commit is contained in:
pacnpal
2026-01-01 15:13:01 -05:00
parent c95f99ca10
commit b243b17af7
413 changed files with 11164 additions and 17433 deletions

View File

@@ -139,7 +139,9 @@ class NotificationService:
UserNotification: The created notification
"""
title = f"Your {submission_type} needs attention"
message = f"Your {submission_type} submission has been reviewed and needs some changes before it can be approved."
message = (
f"Your {submission_type} submission has been reviewed and needs some changes before it can be approved."
)
message += f"\n\nReason: {rejection_reason}"
if additional_message:
@@ -216,9 +218,7 @@ class NotificationService:
preferences = NotificationPreference.objects.create(user=user)
# Send email notification if enabled
if preferences.should_send_notification(
notification.notification_type, "email"
):
if preferences.should_send_notification(notification.notification_type, "email"):
NotificationService._send_email_notification(notification)
# Toast notifications are always created (the notification object itself)
@@ -261,14 +261,10 @@ class NotificationService:
notification.email_sent_at = timezone.now()
notification.save(update_fields=["email_sent", "email_sent_at"])
logger.info(
f"Email notification sent to {user.email} for notification {notification.id}"
)
logger.info(f"Email notification sent to {user.email} for notification {notification.id}")
except Exception as e:
logger.error(
f"Failed to send email notification {notification.id}: {str(e)}"
)
logger.error(f"Failed to send email notification {notification.id}: {str(e)}")
@staticmethod
def get_user_notifications(
@@ -298,9 +294,7 @@ class NotificationService:
queryset = queryset.filter(notification_type__in=notification_types)
# Exclude expired notifications
queryset = queryset.filter(
models.Q(expires_at__isnull=True) | models.Q(expires_at__gt=timezone.now())
)
queryset = queryset.filter(models.Q(expires_at__isnull=True) | models.Q(expires_at__gt=timezone.now()))
if limit:
queryset = queryset[:limit]
@@ -308,9 +302,7 @@ class NotificationService:
return list(queryset)
@staticmethod
def mark_notifications_read(
user: User, notification_ids: list[int] | None = None
) -> int:
def mark_notifications_read(user: User, notification_ids: list[int] | None = None) -> int:
"""
Mark notifications as read for a user.
@@ -341,9 +333,7 @@ class NotificationService:
"""
cutoff_date = timezone.now() - timedelta(days=days)
old_notifications = UserNotification.objects.filter(
is_read=True, read_at__lt=cutoff_date
)
old_notifications = UserNotification.objects.filter(is_read=True, read_at__lt=cutoff_date)
count = old_notifications.count()
old_notifications.delete()