diff --git a/sources/core/pom.xml b/sources/core/pom.xml
index cafd86c..6893e4e 100644
--- a/sources/core/pom.xml
+++ b/sources/core/pom.xml
@@ -22,12 +22,12 @@
+ * Implement this interface to receive callbacks during the SMS dispatch process. To enable discovery + * and registration by the integration framework, annotate your implementation class with + * {@link tools.dynamia.integration.sterotypes.Listener}. + *
+ *+ * Typical implementations may log audit trails, collect metrics, or alter message metadata before + * sending. Note: method names reflect existing API and should not be changed for compatibility. + *
* * @author Mario Serrano Leones */ public interface SMSServiceListener { + /** + * Callback invoked right before an {@link SMSMessage} is sent. + *+ * Use this hook to validate, enrich, or log the message prior to delivery. Avoid long-running + * operations to prevent delaying the sending process. + *
+ * + * @param message The SMS message about to be sent. Never null. + */ void onMessageSending(SMSMessage message); + /** + * Callback invoked immediately after an {@link SMSMessage} has been sent. + *+ * Despite the name "Sended" kept for backward compatibility, this method indicates that the + * sending operation was executed. Implementations may record provider responses or update + * delivery tracking. This does not necessarily guarantee final delivery to the recipient. + *
+ * + * @param message The SMS message that was processed by the sender. Never null. + */ void onMessageSended(SMSMessage message); diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java index 5de5fde..6104e9a 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java @@ -1,4 +1,3 @@ - /* * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1 * Colombia / South America @@ -18,113 +17,178 @@ package tools.dynamia.modules.email.services; -import org.springframework.transaction.annotation.Transactional; import tools.dynamia.modules.email.EmailMessage; import tools.dynamia.modules.email.EmailSendResult; import tools.dynamia.modules.email.domain.EmailAccount; import tools.dynamia.modules.email.domain.EmailAddress; import tools.dynamia.modules.email.domain.EmailTemplate; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; /** - * Email service for sending emails + * Email service for sending emails and managing email-related resources. + *+ * This service defines the contract to send emails synchronously and asynchronously, resolve + * preferred/notification accounts, manage templates, log addresses, and control internal caches. + * Implementations may rely on Spring's async and scheduling infrastructure. + *
* * @author Mario Serrano Leones */ public interface EmailService { /** - * Send email message asynchronously. Default implementation use Spring Scheduling and Async API. Make sure your - * application has {@link org.springframework.scheduling.annotation.EnableAsync} and - * {@link org.springframework.scheduling.annotation.EnableScheduling} configured. + * Sends an email message asynchronously. + *+ * Default implementations are expected to use Spring's {@code @EnableAsync} and scheduling facilities. + * Ensure your application has {@link org.springframework.scheduling.annotation.EnableAsync} and + * {@link org.springframework.scheduling.annotation.EnableScheduling} enabled so the task executor handles + * background execution properly. + *
* - * @param message + * @param message Fully built {@link EmailMessage} to be sent, including recipients, subject, content, + * attachments, and any headers. + * @return a {@link CompletableFuture} that completes with an {@link EmailSendResult} indicating success or failure. + * The future is completed exceptionally if an unrecoverable error occurs during dispatch. */ - Future+ * This is a convenience method that internally creates an {@link EmailMessage} with a single recipient, + * subject, and content, and then delegates to {@link #send(EmailMessage)}. + *
* - * @param to - * @param subject - * @param content + * @param to Recipient email address (e.g., "user@example.com"). Must be a valid RFC 5322 address. + * @param subject Email subject line. + * @param content Email body content. Implementations may treat this as plain text or HTML depending on configuration. + * @return a {@link CompletableFuture} that completes with an {@link EmailSendResult} when sending finishes. */ - Future+ * Use this method when you need immediate feedback about delivery status. Consider timeouts and + * potential blocking behavior in your calling thread. + *
+ * + * @param mailMessage Fully built {@link EmailMessage} to be sent. + * @return the {@link EmailSendResult} containing delivery details, success flag, and error information if any. + */ EmailSendResult sendAndWait(EmailMessage mailMessage); /** - * Get preferred email account in current SaaS account + * Returns the preferred {@link EmailAccount} for the current SaaS account. * - * @return + * @return the preferred account, or {@code null} if none has been configured. */ EmailAccount getPreferredEmailAccount(); /** - * Get preferred email account in SaaS account ID + * Returns the preferred {@link EmailAccount} for the specified SaaS account id. * - * @return + * @param accountId SaaS account identifier. + * @return the preferred email account for {@code accountId}, or {@code null} if not configured. */ EmailAccount getPreferredEmailAccount(Long accountId); /** - * Find email template by name in current SaaS account. If autocreate is true a new blank email template is created + * Finds an {@link EmailTemplate} by name within the current SaaS account. + * If {@code autocreate} is {@code true} and the template does not exist, a new blank template will be created + * and returned. * - * @param name - * @param autocreate - * @return + * @param name Template name to search for. + * @param autocreate Whether to create a new template if one is not found. + * @return the existing or newly created {@link EmailTemplate}, or {@code null} if not found and {@code autocreate} + * is {@code false}. */ EmailTemplate getTemplateByName(String name, boolean autocreate); + /** + * Finds an {@link EmailTemplate} by name for a specific SaaS account id. + * If {@code autocreate} is {@code true} and the template does not exist, a new blank template will be created + * under that account. + * + * @param name Template name to search for. + * @param autocreate Whether to create a new template if one is not found. + * @param accountId SaaS account identifier. + * @return the existing or newly created {@link EmailTemplate}, or {@code null} if not found and {@code autocreate} + * is {@code false}. + */ EmailTemplate getTemplateByName(String name, boolean autocreate, Long accountId); /** - * Find email template by name + * Finds an {@link EmailTemplate} by name using default lookup rules for the current SaaS account. * - * @param name - * @return + * @param name Template name to search for. + * @return the matching {@link EmailTemplate}, or {@code null} if none exists. */ EmailTemplate getTemplateByName(String name); /** - * Log all email address from message + * Logs all email addresses present in the given {@link EmailMessage}. + *+ * Implementations should inspect TO, CC, BCC, REPLY-TO (and possibly FROM) fields and persist or update + * a registry of known {@link EmailAddress} entries associated with the supplied {@link EmailAccount}. + *
* - * @param message + * @param account The {@link EmailAccount} context in which addresses will be logged. + * @param message The {@link EmailMessage} whose addresses should be extracted and logged. */ void logEmailAddress(EmailAccount account, EmailMessage message); /** - * Log email address + * Logs a single email address with an optional tag for classification. * - * @param address - * @param tag + * @param account The {@link EmailAccount} context used to associate the address entry. + * @param address A valid email address string to log. + * @param tag A marker or label (e.g., "customer", "supplier", "notification") to categorize the address. */ void logEmailAddress(EmailAccount account, String address, String tag); /** - * Find a logged email address + * Retrieves a previously logged {@link EmailAddress} by its string representation. * - * @param address - * @return + * @param address Email address string to look up. + * @return the {@link EmailAddress} entity if found; otherwise {@code null}. */ EmailAddress getEmailAddress(String address); /** - * Clears the mail sender cache for the specified email account. + * Clears the internal mail-sender cache for the specified {@link EmailAccount}. + *+ * Implementations that cache mail sender instances (e.g., JavaMailSender) should discard and recreate them + * after configuration changes like credentials, host, or port updates. + *
* - * @param account The email account for which to clear the cache. + * @param account The email account whose cache entries should be invalidated. Must not be {@code null}. */ void clearCache(EmailAccount account); } diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java index cd02105..066d8b5 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java @@ -3,17 +3,35 @@ import tools.dynamia.modules.email.OTPMessage; import tools.dynamia.modules.email.OTPSendResult; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +/** + * Service interface to dispatch One-Time Password (OTP) messages. + *+ * Implementations may deliver OTP codes via email, SMS, or both, depending on configuration and + * the contents of the provided {@link OTPMessage}. The service abstracts transport selection, + * formatting, and delivery tracking, returning an asynchronous handle to inspect the result. + *
+ *+ * Typical usage: build an {@link OTPMessage} with target channels and the OTP value, then call {@link #send(OTPMessage)}. + *
+ */ public interface OTPService { - /** - * Send OTP message using email, sms or both service + * Sends an OTP message using email, SMS, or both channels. + *+ * The selected transport(s) depend on implementation and the {@link OTPMessage} fields (e.g., presence of + * email address, phone number, or explicit channel selection). Delivery may happen asynchronously; use the + * returned {@link Future} to check completion and obtain the {@link OTPSendResult}. + *
* - * @param message - * @return + * @param message Fully populated {@link OTPMessage} containing the OTP code, target recipient(s), preferred + * channel(s), expiration and metadata as required by the implementation. Must not be null. + * @return a {@link Future} that completes with {@link OTPSendResult} indicating success, failure, and relevant + * details (e.g., which channels were used). The future may complete exceptionally if an unrecoverable error occurs. */ - Future+ * Defines the contract to dispatch SMS messages using the configured provider. Implementations + * are responsible for formatting, transport selection, and returning a provider-specific response + * string that may include tracking identifiers or delivery status notes. + *
*/ public interface SMSService { /** * Sends an SMS message. + *+ * Implementations should validate destination numbers and message length according to provider limits + * (e.g., GSM-7 vs. Unicode, segmentation). The returned value is the raw response from the underlying + * SMS provider and can be used for logging or troubleshooting. + *
* - * @param message the SMS message to be sent - * @return the response from the SMS service + * @param message The {@link SMSMessage} to be sent, containing destination number, text content, and optional metadata. + * Must not be {@code null}. + * @return The response string from the SMS service/provider. The format depends on the implementation and provider; + * may include message ID or delivery status information. */ String send(SMSMessage message); } diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java index ddeaa11..865f2d1 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java @@ -88,11 +88,11 @@ public EmailServiceImpl(TemplateEngine templateEngine, CrudService crudService, private final LoggingService logger = new SLF4JLoggingService(EmailService.class); @Override - public Future