Sistema de Notificaciones y Baja One-Click

This commit is contained in:
2026-03-12 13:52:33 -03:00
parent f1a9bb9099
commit 96fca4d9c7
21 changed files with 1384 additions and 79 deletions

View File

@@ -0,0 +1,39 @@
using MotoresArgentinosV2.Core.DTOs;
namespace MotoresArgentinosV2.Core.Interfaces;
/// <summary>
/// Servicio para gestionar preferencias de notificación por email y tokens de baja.
/// </summary>
public interface INotificationPreferenceService
{
/// <summary>
/// Retorna las preferencias actuales del usuario (todas las categorías).
/// </summary>
Task<NotificationPreferencesDto> GetPreferencesAsync(int userId);
/// <summary>
/// Guarda las preferencias enviadas desde el perfil del usuario.
/// </summary>
Task UpdatePreferencesAsync(int userId, UpdateNotificationPreferencesDto dto);
/// <summary>
/// Verifica si un usuario tiene habilitada una categoría de correo.
/// Usa para chequear ANTES de enviar cada notificación del sistema.
/// </summary>
Task<bool> IsEnabledAsync(int userId, string category);
/// <summary>
/// Genera (o reutiliza) un token de baja firmado para incluir en el footer de un correo.
/// </summary>
Task<string> GetOrCreateUnsubscribeTokenAsync(int userId, string category);
/// <summary>
/// Procesa la baja del usuario desde el enlace one-click (sin login).
/// Valida el token y actualiza la preferencia correspondiente.
/// </summary>
/// <returns>
/// (Success, CategoryLabel) indicando si se procesó OK y el nombre legible de la categoría.
/// </returns>
Task<(bool Success, string CategoryLabel)> UnsubscribeAsync(string token);
}

View File

@@ -2,13 +2,30 @@ namespace MotoresArgentinosV2.Core.Interfaces;
public interface INotificationService
{
Task SendChatNotificationEmailAsync(string toEmail, string fromUser, string message, int adId);
Task SendAdStatusChangedEmailAsync(string toEmail, string adTitle, string status, string? reason = null);
// Categoría: "mensajes"
Task SendChatNotificationEmailAsync(string toEmail, string fromUser, string message, int adId, string? unsubscribeUrl = null);
// Categoría: "sistema"
Task SendAdStatusChangedEmailAsync(string toEmail, string adTitle, string status, string? reason = null, string? unsubscribeUrl = null);
// SIN baja — correo crítico de seguridad, siempre se envía
Task SendSecurityAlertEmailAsync(string toEmail, string actionDescription);
Task SendExpirationWarningEmailAsync(string toEmail, string userName, string adTitle, DateTime expirationDate);
Task SendAdExpiredEmailAsync(string toEmail, string userName, string adTitle);
Task SendWeeklyPerformanceEmailAsync(string toEmail, string userName, string adTitle, int views, int favorites);
Task SendPaymentReminderEmailAsync(string toEmail, string userName, string adTitle, string link);
// Categoría: "sistema"
Task SendExpirationWarningEmailAsync(string toEmail, string userName, string adTitle, DateTime expirationDate, string? unsubscribeUrl = null);
// Categoría: "sistema"
Task SendAdExpiredEmailAsync(string toEmail, string userName, string adTitle, string? unsubscribeUrl = null);
// Categoría: "rendimiento"
Task SendWeeklyPerformanceEmailAsync(string toEmail, string userName, string adTitle, int views, int favorites, string? unsubscribeUrl = null);
// Categoría: "marketing"
Task SendPaymentReminderEmailAsync(string toEmail, string userName, string adTitle, string link, string? unsubscribeUrl = null);
// SIN baja — recibo de pago transaccional, siempre se envía
Task SendPaymentReceiptEmailAsync(string toEmail, string userName, string adTitle, decimal amount, string operationCode);
Task SendUnreadMessagesReminderEmailAsync(string toEmail, string userName, int unreadCount);
// Categoría: "mensajes"
Task SendUnreadMessagesReminderEmailAsync(string toEmail, string userName, int unreadCount, string? unsubscribeUrl = null);
}