Init Commit

This commit is contained in:
2026-01-29 13:43:44 -03:00
commit b9aa8478db
126 changed files with 20649 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace MotoresArgentinosV2.Core.DTOs;
public class CreateAdRequestDto
{
[Required]
[Range(1, 3, ErrorMessage = "Tipo de vehículo inválido")]
[JsonPropertyName("vehicleTypeID")]
public int VehicleTypeID { get; set; }
[Required]
[JsonPropertyName("brandID")]
public int BrandID { get; set; }
[JsonPropertyName("modelID")]
public int ModelID { get; set; }
[Required]
[StringLength(100, MinimumLength = 1, ErrorMessage = "La versión debe tener entre 1 y 100 caracteres.")]
[RegularExpression(@"^[a-zA-Z0-9\s\-\.\(\),/áéíóúÁÉÍÓÚñÑ]+$", ErrorMessage = "Caracteres no permitidos en el nombre de versión.")]
[JsonPropertyName("versionName")]
public string VersionName { get; set; } = string.Empty;
[Range(1900, 2100)]
[JsonPropertyName("year")]
public int Year { get; set; }
[Range(0, 2000000)]
[JsonPropertyName("km")]
public int KM { get; set; }
[Range(0, 999999999)]
[JsonPropertyName("price")]
public decimal Price { get; set; }
[Required]
[StringLength(3, MinimumLength = 3)]
[RegularExpression(@"^(ARS|USD)$", ErrorMessage = "Moneda inválida.")]
[JsonPropertyName("currency")]
public string Currency { get; set; } = "ARS";
[StringLength(1000, ErrorMessage = "La descripción no puede superar los 1000 caracteres.")]
[RegularExpression(@"^(?!.*<script>).*$", ErrorMessage = "Contenido no permitido.")]
[JsonPropertyName("description")]
public string Description { get; set; } = string.Empty;
[JsonPropertyName("isFeatured")]
public bool IsFeatured { get; set; }
[StringLength(50)]
[JsonPropertyName("fuelType")]
public string? FuelType { get; set; }
[StringLength(50)]
[JsonPropertyName("color")]
public string? Color { get; set; }
[StringLength(50)]
[JsonPropertyName("segment")]
public string? Segment { get; set; }
[StringLength(100)]
[JsonPropertyName("location")]
public string? Location { get; set; }
[StringLength(50)]
[JsonPropertyName("condition")]
public string? Condition { get; set; }
[JsonPropertyName("doorCount")]
public int? DoorCount { get; set; }
[StringLength(50)]
[JsonPropertyName("transmission")]
public string? Transmission { get; set; }
[StringLength(50)]
[JsonPropertyName("steering")]
public string? Steering { get; set; }
// --- Contacto Personalizado ---
[StringLength(50)]
[RegularExpression(@"^\+?[0-9\s\-\(\)]+$", ErrorMessage = "Formato de teléfono inválido.")]
[JsonPropertyName("contactPhone")]
public string? ContactPhone { get; set; }
[StringLength(100)]
[EmailAddress(ErrorMessage = "Formato de email inválido.")]
[JsonPropertyName("contactEmail")]
public string? ContactEmail { get; set; }
[JsonPropertyName("displayContactInfo")]
public bool DisplayContactInfo { get; set; } = true;
// --- Admin Only ---
[JsonPropertyName("targetUserID")]
public int? TargetUserID { get; set; }
[StringLength(100)]
[EmailAddress(ErrorMessage = "Email de usuario fantasma inválido.")]
[JsonPropertyName("ghostUserEmail")]
public string? GhostUserEmail { get; set; }
[StringLength(100)]
[JsonPropertyName("ghostFirstName")]
public string? GhostFirstName { get; set; }
[StringLength(100)]
[JsonPropertyName("ghostLastName")]
public string? GhostLastName { get; set; }
[StringLength(50)]
[RegularExpression(@"^\+?[0-9\s\-\(\)]+$", ErrorMessage = "Teléfono de usuario fantasma inválido.")]
[JsonPropertyName("ghostUserPhone")]
public string? GhostUserPhone { get; set; }
}

View File

@@ -0,0 +1,50 @@
namespace MotoresArgentinosV2.Core.DTOs;
public class LoginRequest
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
public class MigrateRequest
{
public string Username { get; set; } = string.Empty;
public string NewPassword { get; set; } = string.Empty;
}
public class MFARequest
{
public string Username { get; set; } = string.Empty;
public string Code { get; set; } = string.Empty;
}
public class RegisterRequest
{
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string PhoneNumber { get; set; } = string.Empty;
}
public class VerifyEmailRequest
{
public string Token { get; set; } = string.Empty;
}
public class ResendVerificationRequest
{
public string Email { get; set; } = string.Empty;
}
public class ForgotPasswordRequest
{
public string Email { get; set; } = string.Empty;
}
public class ResetPasswordRequest
{
public string Token { get; set; } = string.Empty;
public string NewPassword { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,13 @@
namespace MotoresArgentinosV2.Core.DTOs;
public class AvisoWebDto
{
public string NombreAviso { get; set; } = string.Empty;
public DateTime? FechaInicio { get; set; }
public decimal ImporteAviso { get; set; }
public string? Estado { get; set; }
// Agrego campos extra útiles si existen (deducidos)
public int? NroOperacion { get; set; }
public string? Razon { get; set; }
}

View File

@@ -0,0 +1,66 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace MotoresArgentinosV2.Core.DTOs;
public class DatosAvisoDto
{
// --- Bytes (TinyInt en SQL) ---
[Column("ID_TIPOAVI")]
public byte IdTipoavi { get; set; }
[Column("ID_SUBRUBRO")]
public byte IdSubrubro { get; set; }
// --- Shorts (SmallInt en SQL) ---
// ESTE ERA EL CAUSANTE DEL ERROR PRINCIPAL
[Column("ID_RUBRO")]
public short IdRubro { get; set; }
// --- Ints (Int32 en SQL) ---
[Column("ID_COMBINADO")]
public int IdCombinado { get; set; }
[Column("PORCENTAJE_COMBINADO")]
public int PorcentajeCombinado { get; set; }
[Column("CANTIDAD_DIAS")]
public int CantidadDias { get; set; }
[Column("DIAS_CORRIDOS")]
public int DiasCorridos { get; set; }
[Column("PALABRAS")]
public int Palabras { get; set; }
[Column("CENTIMETROS")]
public int Centimetros { get; set; }
[Column("COLUMNAS")]
public int Columnas { get; set; }
[Column("TOTAL_AVISOS")]
public int TotalAvisos { get; set; }
[Column("DESTACADO")]
public int Destacado { get; set; }
[Column("PAQUETE")]
public int Paquete { get; set; }
// --- Decimales ---
[Column("IMPORTE_SINIVA")]
public decimal ImporteSiniva { get; set; }
[Column("IMPORTE_TOTSINIVA")]
public decimal ImporteTotsiniva { get; set; }
// --- Strings ---
[Column("NOMAVI")]
public string Nomavi { get; set; } = string.Empty;
[Column("TEXTOAVI")]
public string Textoavi { get; set; } = string.Empty;
[Column("DESCRIPCION")]
public string Descripcion { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,70 @@
namespace MotoresArgentinosV2.Core.DTOs;
/// <summary>
/// DTO para insertar un aviso mediante el SP spInsertaAvisos
/// </summary>
public class InsertarAvisoDto
{
// Datos básicos
public string Tipo { get; set; } = string.Empty;
public int NroOperacion { get; set; }
public int IdCliente { get; set; }
public int Tipodoc { get; set; }
public string NroDoc { get; set; } = string.Empty;
public string Razon { get; set; } = string.Empty;
// Ubicación del cliente
public string Calle { get; set; } = string.Empty;
public string Numero { get; set; } = string.Empty;
public string Localidad { get; set; } = string.Empty;
public string CodigoPostal { get; set; } = string.Empty;
// Contacto
public string Telefono { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
// Impuestos
public byte IdTipoiva { get; set; }
public decimal PorcentajeIva1 { get; set; }
public decimal PorcentajeIva2 { get; set; }
public decimal PorcentajePercepcion { get; set; }
// Datos del aviso
public byte IdTipoaviso { get; set; }
public string Nombreaviso { get; set; } = string.Empty;
public short IdRubro { get; set; }
public byte IdSubrubro { get; set; }
public byte IdCombinado { get; set; }
public decimal PorcentajeCombinado { get; set; }
// Publicación
public DateTime FechaInicio { get; set; }
public byte CantDias { get; set; }
public bool DiasCorridos { get; set; }
public byte Palabras { get; set; }
public decimal Centimetros { get; set; }
public byte Columnas { get; set; }
// Pago
public byte IdTarjeta { get; set; }
public string NroTarjeta { get; set; } = string.Empty;
public int CvcTarjeta { get; set; }
public DateTime Vencimiento { get; set; }
// Dirección de envío (si aplica)
public string CalleEnvio { get; set; } = string.Empty;
public string NumeroEnvio { get; set; } = string.Empty;
public string LocalidadEnvio { get; set; } = string.Empty;
// Importes
public decimal Tarifa { get; set; }
public decimal ImporteAviso { get; set; }
public decimal ImporteIva1 { get; set; }
public decimal ImporteIva2 { get; set; }
public decimal ImportePercepcion { get; set; }
// Extras
public int Cantavi { get; set; } = 1;
public int Paquete { get; set; } = 0;
public bool Destacado { get; set; } = false;
}

View File

@@ -0,0 +1,38 @@
using System.ComponentModel.DataAnnotations;
namespace MotoresArgentinosV2.Core.DTOs;
public class CreatePaymentRequestDto
{
[Required]
public int AdId { get; set; } // ID del aviso que se está pagando
[Required]
public string Token { get; set; } = string.Empty; // Token de la tarjeta generado en el front
[Required]
public string PaymentMethodId { get; set; } = string.Empty; // ej: "visa", "master"
[Required]
public int Installments { get; set; } // Cuotas
[Required]
public string IssuerId { get; set; } = string.Empty; // Banco emisor
[Required]
public decimal TransactionAmount { get; set; }
[Required]
[EmailAddress]
public string PayerEmail { get; set; } = string.Empty;
public string? Description { get; set; }
}
public class PaymentResponseDto
{
public long PaymentId { get; set; }
public string Status { get; set; } = string.Empty; // approved, rejected, in_process
public string StatusDetail { get; set; } = string.Empty;
public string OperationCode { get; set; } = string.Empty; // Nuestro ID interno (M2-...)
}

View File

@@ -0,0 +1,32 @@
namespace MotoresArgentinosV2.Core.DTOs;
public class UserDetailDto
{
public int UserID { get; set; }
public string UserName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? PhoneNumber { get; set; }
public byte UserType { get; set; }
public bool IsBlocked { get; set; }
public byte MigrationStatus { get; set; }
public bool IsEmailVerified { get; set; }
public DateTime CreatedAt { get; set; }
}
public class UserUpdateDto
{
public string UserName { get; set; } = string.Empty;
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? PhoneNumber { get; set; }
public byte UserType { get; set; }
}
public class ProfileUpdateDto
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? PhoneNumber { get; set; }
}

View File

@@ -0,0 +1,41 @@
namespace MotoresArgentinosV2.Core.DTOs;
public class UsuarioLegacyDto
{
// Mapeo tentativo basado en convenciones v_particulares
public int Part_Id { get; set; }
public string Part_Usu_Nombre { get; set; } = string.Empty;
public string? Part_Nombre { get; set; } // O razon social
public string? Part_Apellido { get; set; }
public string? Part_Email { get; set; }
public string? Part_Telefono { get; set; }
// Dirección
public string? Part_Calle { get; set; }
public string? Part_Nro { get; set; }
public string? Part_Localidad { get; set; }
public string? Part_CP { get; set; }
// Fiscal
public int? Part_TipoDoc { get; set; }
public string? Part_NroDoc { get; set; }
public int? Part_IdIVA { get; set; }
}
public class AgenciaLegacyDto
{
// Mapeo tentativo basado en convenciones v_agencias
public int Agen_Id { get; set; }
public string Agen_usuario { get; set; } = string.Empty;
public string? Agen_Nombre { get; set; } // Razon social
public string? Agen_Email { get; set; }
public string? Agen_Telefono { get; set; }
// Dirección
public string? Agen_Domicilio { get; set; }
public string? Agen_Localidad { get; set; }
// Fiscal
public string? Agen_Cuit { get; set; }
public int? Agen_IdIVA { get; set; }
}

View File

@@ -0,0 +1,209 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
namespace MotoresArgentinosV2.Core.Entities;
public class Brand
{
public int BrandID { get; set; }
public int VehicleTypeID { get; set; }
public string Name { get; set; } = string.Empty;
public int? LegacyID { get; set; }
}
public class Model
{
public int ModelID { get; set; }
public int BrandID { get; set; }
public string Name { get; set; } = string.Empty;
public int? LegacyID { get; set; }
}
public enum UserMigrationStatus : byte { LegacyPending = 0, MigratedActive = 1 }
public enum AdStatusEnum
{
Draft = 1,
PaymentPending = 2,
ModerationPending = 3,
Active = 4,
Rejected = 5,
Paused = 6,
Sold = 7,
Expired = 8,
Deleted = 9,
Reserved = 10
}
public class User
{
public int UserID { get; set; }
public string UserName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string PasswordHash { get; set; } = string.Empty;
public string? PasswordSalt { get; set; }
public byte MigrationStatus { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? PhoneNumber { get; set; }
public byte UserType { get; set; } = 1; // 1: Particular, 3: Admin
public string? MFASecret { get; set; }
public bool IsMFAEnabled { get; set; }
// Email Verification
public bool IsEmailVerified { get; set; }
public string? VerificationToken { get; set; }
public DateTime? VerificationTokenExpiresAt { get; set; }
public DateTime? LastVerificationEmailSentAt { get; set; }
// Password Reset
public string? PasswordResetToken { get; set; }
public DateTime? PasswordResetTokenExpiresAt { get; set; }
public DateTime? LastPasswordResetEmailSentAt { get; set; }
// Bloqueo de usuario
public bool IsBlocked { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
// Relación con Refresh Tokens
public ICollection<RefreshToken> RefreshTokens { get; set; } = new List<RefreshToken>();
// Notificaciones de recordatorio de mensajes no leídos
public DateTime? LastUnreadMessageReminderSentAt { get; set; }
}
public class AuditLog
{
public int AuditLogID { get; set; }
public string Action { get; set; } = string.Empty;
public string Entity { get; set; } = string.Empty;
public int EntityID { get; set; }
public int UserID { get; set; }
public string Details { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
public class Ad
{
public int AdID { get; set; }
public int UserID { get; set; }
public User User { get; set; } = null!;
public int VehicleTypeID { get; set; }
public int BrandID { get; set; }
public Brand Brand { get; set; } = null!;
public int ModelID { get; set; }
public Model Model { get; set; } = null!;
public string? VersionName { get; set; }
public int Year { get; set; }
public int KM { get; set; }
public string? FuelType { get; set; }
public string? Color { get; set; }
public string? Segment { get; set; }
public decimal Price { get; set; }
public string Currency { get; set; } = "USD";
public string? Description { get; set; }
public string? Location { get; set; }
public string? Condition { get; set; }
public int? DoorCount { get; set; }
public string? Transmission { get; set; }
public string? Steering { get; set; }
public string? ContactPhone { get; set; }
public string? ContactEmail { get; set; }
public bool DisplayContactInfo { get; set; } = true;
public bool IsFeatured { get; set; }
public int StatusID { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? PublishedAt { get; set; }
public DateTime? ExpiresAt { get; set; }
public int? LegacyAdID { get; set; }
public DateTime? DeletedAt { get; set; }
public int ViewsCounter { get; set; }
public ICollection<AdPhoto> Photos { get; set; } = new List<AdPhoto>();
public ICollection<AdFeature> Features { get; set; } = new List<AdFeature>();
public ICollection<ChatMessage> Messages { get; set; } = new List<ChatMessage>();
// CAMPOS DE CONTROL DE NOTIFICACIONES
public DateTime? LastPerformanceEmailSentAt { get; set; } // Para el resumen semanal
public DateTime? PaymentReminderSentAt { get; set; } // Para carrito abandonado
public bool ExpirationWarningSent { get; set; } // Para aviso por vencer
}
public class AdPhoto
{
public int PhotoID { get; set; }
public int AdID { get; set; }
public string FilePath { get; set; } = string.Empty;
public bool IsCover { get; set; }
public int SortOrder { get; set; }
public Ad Ad { get; set; } = null!;
}
public class AdFeature
{
public int AdID { get; set; }
public string FeatureKey { get; set; } = string.Empty;
public string? FeatureValue { get; set; }
}
public class TransactionRecord
{
public int TransactionID { get; set; }
public int AdID { get; set; }
public Ad Ad { get; set; } = null!;
public string OperationCode { get; set; } = string.Empty;
public int PaymentMethodID { get; set; }
public decimal Amount { get; set; }
public string Status { get; set; } = "PENDING";
public string? ProviderPaymentId { get; set; }
public string? ProviderResponse { get; set; }
public string? SnapshotUserEmail { get; set; }
public string? SnapshotUserName { get; set; }
public string? SnapshotAdTitle { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
}
public class Favorite
{
public int UserID { get; set; }
public int AdID { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
public class ChatMessage
{
[Key]
public int MessageID { get; set; }
public int AdID { get; set; }
[ForeignKey("AdID")]
[JsonIgnore]
public Ad? Ad { get; set; }
public int SenderID { get; set; }
public int ReceiverID { get; set; }
public string MessageText { get; set; } = string.Empty;
public DateTime SentAt { get; set; } = DateTime.UtcNow;
public bool IsRead { get; set; } = false;
}
public class PaymentMethod
{
public int PaymentMethodID { get; set; }
public string Name { get; set; } = string.Empty;
}
public class AdViewLog
{
public int Id { get; set; }
public int AdID { get; set; }
public string IPAddress { get; set; } = string.Empty;
public DateTime ViewDate { get; set; } = DateTime.UtcNow;
}

View File

@@ -0,0 +1,18 @@
namespace MotoresArgentinosV2.Core.Entities;
/// <summary>
/// Entidad que representa un medio de pago disponible
/// Tabla legacy: mediodepago (DB: autos)
/// </summary>
public class MedioDePago
{
/// <summary>
/// Identificador único del medio de pago
/// </summary>
public byte Id { get; set; }
/// <summary>
/// Nombre del medio de pago (ej: Visa, MasterCard, etc.)
/// </summary>
public string Mediodepago { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,163 @@
namespace MotoresArgentinosV2.Core.Entities;
/// <summary>
/// Entidad que representa una operación de pago
/// Tabla legacy: operaciones (DB: autos)
/// </summary>
public class Operacion
{
/// <summary>
/// Identificador único de la operación (IDENTITY)
/// </summary>
public int Id { get; set; }
/// <summary>
/// Fecha de la operación
/// </summary>
public DateTime? Fecha { get; set; }
/// <summary>
/// Motivo de la operación
/// </summary>
public string? Motivo { get; set; }
/// <summary>
/// Moneda utilizada
/// </summary>
public string? Moneda { get; set; }
/// <summary>
/// Dirección de entrega
/// </summary>
public string? Direccionentrega { get; set; }
/// <summary>
/// Código de validación de domicilio
/// </summary>
public string? Validaciondomicilio { get; set; }
/// <summary>
/// Código de pedido
/// </summary>
public string? Codigopedido { get; set; }
/// <summary>
/// Nombre para la entrega
/// </summary>
public string? Nombreentrega { get; set; }
/// <summary>
/// Fecha y hora de la transacción
/// </summary>
public string? Fechahora { get; set; }
/// <summary>
/// Teléfono del comprador
/// </summary>
public string? Telefonocomprador { get; set; }
/// <summary>
/// Barrio de entrega
/// </summary>
public string? Barrioentrega { get; set; }
/// <summary>
/// Código de autorización de la transacción
/// </summary>
public string? Codautorizacion { get; set; }
/// <summary>
/// País de entrega
/// </summary>
public string? Paisentrega { get; set; }
/// <summary>
/// Cantidad de cuotas
/// </summary>
public string? Cuotas { get; set; }
/// <summary>
/// Validación de fecha de nacimiento
/// </summary>
public string? Validafechanac { get; set; }
/// <summary>
/// Validación de número de documento
/// </summary>
public string? Validanrodoc { get; set; }
/// <summary>
/// Titular de la tarjeta
/// </summary>
public string? Titular { get; set; }
/// <summary>
/// Número de pedido
/// </summary>
public string? Pedido { get; set; }
/// <summary>
/// Código postal de entrega
/// </summary>
public string? Zipentrega { get; set; }
/// <summary>
/// Monto de la transacción
/// </summary>
public string? Monto { get; set; }
/// <summary>
/// Tipo de tarjeta utilizada
/// </summary>
public string? Tarjeta { get; set; }
/// <summary>
/// Fecha de entrega
/// </summary>
public string? Fechaentrega { get; set; }
/// <summary>
/// Email del comprador
/// </summary>
public string? Emailcomprador { get; set; }
/// <summary>
/// Validación número de puerta
/// </summary>
public string? Validanropuerta { get; set; }
/// <summary>
/// Ciudad de entrega
/// </summary>
public string? Ciudadentrega { get; set; }
/// <summary>
/// Validación tipo de documento
/// </summary>
public string? Validatipodoc { get; set; }
/// <summary>
/// Número de operación
/// </summary>
public string? Noperacion { get; set; }
/// <summary>
/// Estado de la entrega
/// </summary>
public string? Estadoentrega { get; set; }
/// <summary>
/// Resultado de la operación (APROBADA/RECHAZADA)
/// </summary>
public string? Resultado { get; set; }
/// <summary>
/// Mensaje sobre la entrega
/// </summary>
public string? Mensajeentrega { get; set; }
/// <summary>
/// Precio neto de la operación
/// </summary>
public int? Precioneto { get; set; }
}

View File

@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
namespace MotoresArgentinosV2.Core.Entities;
public class RefreshToken
{
[Key]
public int Id { get; set; }
public string Token { get; set; } = string.Empty;
public DateTime Expires { get; set; }
public DateTime Created { get; set; } = DateTime.UtcNow;
public string? CreatedByIp { get; set; }
public DateTime? Revoked { get; set; }
public string? RevokedByIp { get; set; }
public string? ReplacedByToken { get; set; }
public bool IsActive => Revoked == null && !IsExpired;
public bool IsExpired => DateTime.UtcNow >= Expires;
public int UserId { get; set; }
public User User { get; set; } = null!;
}

View File

@@ -0,0 +1,8 @@
using MotoresArgentinosV2.Core.DTOs;
namespace MotoresArgentinosV2.Core.Interfaces;
public interface IAdSyncService
{
Task<bool> SyncAdToLegacyAsync(int adId);
}

View File

@@ -0,0 +1,28 @@
using MotoresArgentinosV2.Core.DTOs;
namespace MotoresArgentinosV2.Core.Interfaces;
/// <summary>
/// Interfaz para servicios que interactúan con stored procedures legacy
/// relacionados con avisos
/// </summary>
public interface IAvisosLegacyService
{
/// <summary>
/// Ejecuta el SP spDatosAvisos para obtener tarifas y configuración
/// </summary>
/// <param name="tarea">Tipo de tarea (EMOTORES, EREPUESTOS, EAUTOS, etc.)</param>
/// <param name="paquete">ID del paquete (opcional)</param>
/// <returns>Lista de configuraciones de avisos disponibles</returns>
Task<List<DatosAvisoDto>> ObtenerDatosAvisosAsync(string tarea, int paquete = 0);
/// <summary>
/// Ejecuta el SP spInsertaAvisos para crear un nuevo aviso
/// </summary>
/// <param name="aviso">Datos del aviso a crear</param>
/// <returns>True si se insertó correctamente</returns>
Task<bool> InsertarAvisoAsync(InsertarAvisoDto aviso);
Task<List<DatosAvisoDto>> ObtenerTarifasAsync(string formulario, int paquete);
Task<List<AvisoWebDto>> ObtenerAvisosPorClienteAsync(string nroDocumento);
}

View File

@@ -0,0 +1,6 @@
namespace MotoresArgentinosV2.Core.Interfaces;
public interface IEmailService
{
Task SendEmailAsync(string to, string subject, string htmlBody);
}

View File

@@ -0,0 +1,20 @@
using MotoresArgentinosV2.Core.DTOs;
using MotoresArgentinosV2.Core.Entities;
namespace MotoresArgentinosV2.Core.Interfaces;
public interface IIdentityService
{
Task<(User? User, string? MigrationMessage)> AuthenticateAsync(string username, string password);
Task<bool> MigratePasswordAsync(string username, string newPassword);
// métodos para registro
Task<(bool Success, string Message)> RegisterUserAsync(RegisterRequest request);
Task<(bool Success, string Message)> VerifyEmailAsync(string token);
Task<(bool Success, string Message)> ResendVerificationEmailAsync(string email);
Task<(bool Success, string Message)> ForgotPasswordAsync(string email);
Task<(bool Success, string Message)> ResetPasswordAsync(string token, string newPassword);
Task<(bool Success, string Message)> ChangePasswordAsync(int userId, string current, string newPwd);
Task<User> CreateGhostUserAsync(string email, string firstName, string lastName, string phone);
}

View File

@@ -0,0 +1,16 @@
namespace MotoresArgentinosV2.Core.Interfaces;
public record AdPriceResult(decimal BasePrice, decimal Tax, decimal TotalPrice, string Currency);
public interface ILegacyPaymentService
{
/// <summary>
/// Consulta el precio en el sistema legacy (SPDATOSAVISOS)
/// </summary>
Task<AdPriceResult> GetAdPriceAsync(string category, bool isFeatured);
/// <summary>
/// Finaliza la operación tras el pago (Simula callback de Decidir y ejecuta spInsertaAvisos)
/// </summary>
Task<bool> ProcessPaymentResponseAsync(string operationCode, string status, string providerData);
}

View File

@@ -0,0 +1,14 @@
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);
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);
Task SendPaymentReceiptEmailAsync(string toEmail, string userName, string adTitle, decimal amount, string operationCode);
Task SendUnreadMessagesReminderEmailAsync(string toEmail, string userName, int unreadCount);
}

View File

@@ -0,0 +1,38 @@
using MotoresArgentinosV2.Core.Entities;
namespace MotoresArgentinosV2.Core.Interfaces;
/// <summary>
/// Interfaz para servicios que interactúan con stored procedures legacy
/// relacionados con operaciones de pago
/// </summary>
public interface IOperacionesLegacyService
{
/// <summary>
/// Ejecuta el SP sp_inserta_operaciones para registrar una nueva operación
/// </summary>
/// <param name="operacion">Datos de la operación a registrar</param>
/// <returns>True si se insertó correctamente</returns>
Task<bool> InsertarOperacionAsync(Operacion operacion);
/// <summary>
/// Obtiene operaciones por número de operación
/// </summary>
/// <param name="noperacion">Número de operación a buscar</param>
/// <returns>Lista de operaciones encontradas</returns>
Task<List<Operacion>> ObtenerOperacionesPorNumeroAsync(string noperacion);
/// <summary>
/// Obtiene operaciones en un rango de fechas
/// </summary>
/// <param name="fechaInicio">Fecha inicial</param>
/// <param name="fechaFin">Fecha final</param>
/// <returns>Lista de operaciones en el rango</returns>
Task<List<Operacion>> ObtenerOperacionesPorFechasAsync(DateTime fechaInicio, DateTime fechaFin);
/// <summary>
/// Obtiene todos los medios de pago disponibles
/// </summary>
/// <returns>Lista de medios de pago</returns>
Task<List<MedioDePago>> ObtenerMediosDePagoAsync();
}

View File

@@ -0,0 +1,7 @@
namespace MotoresArgentinosV2.Core.Interfaces;
public interface IPasswordService
{
string HashPassword(string password);
bool VerifyPassword(string password, string hash, string? salt, bool isLegacy);
}

View File

@@ -0,0 +1,10 @@
using MotoresArgentinosV2.Core.DTOs;
namespace MotoresArgentinosV2.Core.Interfaces;
public interface IPaymentService
{
Task<PaymentResponseDto> ProcessPaymentAsync(CreatePaymentRequestDto request, int userId);
Task ProcessWebhookAsync(string topic, string id);
Task<PaymentResponseDto> CheckPaymentStatusAsync(int adId);
}

View File

@@ -0,0 +1,15 @@
using MotoresArgentinosV2.Core.Entities;
namespace MotoresArgentinosV2.Core.Interfaces;
public interface ITokenService
{
string GenerateJwtToken(User user);
RefreshToken GenerateRefreshToken(string ipAddress);
string GenerateMFACode(); // Legacy email code
// TOTP (Google Authenticator)
string GenerateBase32Secret();
string GetQrCodeUri(string userEmail, string secret);
bool ValidateTOTP(string secret, string code);
}

View File

@@ -0,0 +1,9 @@
using MotoresArgentinosV2.Core.DTOs;
namespace MotoresArgentinosV2.Core.Interfaces;
public interface IUsuariosLegacyService
{
Task<UsuarioLegacyDto?> ObtenerParticularPorUsuarioAsync(string nombreUsuario);
Task<AgenciaLegacyDto?> ObtenerAgenciaPorUsuarioAsync(string nombreUsuario);
}

View File

@@ -0,0 +1,11 @@
namespace MotoresArgentinosV2.Core.Models;
public class MailSettings
{
public string SmtpHost { get; set; } = string.Empty;
public int SmtpPort { get; set; }
public string SmtpUser { get; set; } = string.Empty;
public string SmtpPass { get; set; } = string.Empty;
public string SenderEmail { get; set; } = string.Empty;
public string SenderName { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>