# Dominio Notification ## Propósito Orquesta notificaciones de negocio por correo a partir de eventos de otros dominios. ## Eventos atendidos - `UserRegistered`: dispara el correo de bienvenida. - `PasswordResetRequested`: envía el código de recuperación si el intento sigue pendiente. - `PurchasePaid`: envía la confirmación de compra y adjunta los tickets generados, cuando corresponde. ## Componentes Los listeners delegan en `NotificationMailService`. Este servicio carga el contexto necesario, renderiza las vistas y envía mediante `Integration/MailService`. `IdempotentEmailDeliveryService` coordina los envíos automáticos mediante la tabla `email_deliveries`. Cada correo utiliza una clave de negocio única: - bienvenida: `welcome:{tenant_code}:{user_id}`; - recuperación: `password-reset:{attempt_id}`; - compra confirmada: `purchase-confirmed:{purchase_id}`; - reprogramación: `event-date-rescheduled:{source_event_date_id}:{destination_event_date_id}:{purchase_id}`; - suspensión: `event-date-suspended:{event_date_id}:{purchase_id}`. Los correos de prueba y de validación de una integración SMTP no usan esta capa, porque su reenvío explícito es parte de su comportamiento esperado. ## API y dependencias No expone rutas HTTP. Consume datos de `Auth`, `Tenant`, `Purchase` y `Ticket`, y delega la entrega al dominio `Integration`. ## Consideraciones - Los listeners reciben identificadores y vuelven a cargar los modelos, evitando transportar entidades obsoletas. - La recuperación no se envía si el intento dejó de estar pendiente. - Los correos de cuenta (bienvenida y recuperación de contraseña) usan la identidad visual del `WebsiteType` asociado al tenant, con fallback al tenant si no tiene uno configurado. - El correo transaccional de compra confirmada usa la identidad visual del tenant y adjunta un único PDF cuando la compra generó tickets. - Los handlers deben permanecer idempotentes o tolerantes a reintentos de cola. - Una entrega queda en estado `processing` mientras un worker posee su claim. Si el worker se interrumpe, el claim vence según `EMAIL_DELIVERY_LEASE_SECONDS` y otro intento puede recuperarlo. - Los fallos quedan registrados como `failed` y pueden ser retomados por los reintentos de la cola. Los envíos exitosos permanecen como `sent` y las llamadas posteriores con la misma clave no vuelven a enviar el correo. - SMTP no ofrece una confirmación transaccional junto con la base de datos. Una interrupción ocurrida después de entregar el correo y antes de registrar `sent` puede producir un duplicado excepcional al recuperar el claim.