diff --git a/src/main/java/org/nkcoder/notification/NotificationService.java b/src/main/java/org/nkcoder/notification/NotificationService.java index 1201660..a46fa76 100644 --- a/src/main/java/org/nkcoder/notification/NotificationService.java +++ b/src/main/java/org/nkcoder/notification/NotificationService.java @@ -1,16 +1,20 @@ package org.nkcoder.notification; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @Service public class NotificationService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + public void sendWelcomeEmail(String email, String userName) { // TODO: implement email sending - System.out.println("Sending Welcome email to " + email + ", for user: " + userName); + logger.info("Sending Welcome email to {}, for user: {}", email, userName); } public void sendPasswordResetEmail(String email, String userName) { // TODO: implement password reset email - System.out.println("Sending password reset email to " + email + ", for user: " + userName); + logger.info("Sending password reset email to {}, for user: {}", email, userName); } } diff --git a/src/main/java/org/nkcoder/user/application/service/AuthApplicationService.java b/src/main/java/org/nkcoder/user/application/service/AuthApplicationService.java index 8016269..8f6451a 100644 --- a/src/main/java/org/nkcoder/user/application/service/AuthApplicationService.java +++ b/src/main/java/org/nkcoder/user/application/service/AuthApplicationService.java @@ -1,6 +1,8 @@ package org.nkcoder.user.application.service; import java.time.LocalDateTime; +import org.nkcoder.shared.kernel.domain.event.DomainEventPublisher; +import org.nkcoder.shared.kernel.domain.event.UserRegisteredEvent; import org.nkcoder.shared.kernel.exception.AuthenticationException; import org.nkcoder.shared.kernel.exception.ValidationException; import org.nkcoder.user.application.dto.command.LoginCommand; @@ -27,7 +29,6 @@ /** Application service for authentication use cases. Orchestrates domain objects and infrastructure services. */ @Service -@Transactional public class AuthApplicationService { private static final Logger logger = LoggerFactory.getLogger(AuthApplicationService.class); @@ -42,6 +43,7 @@ public class AuthApplicationService { private final TokenGenerator tokenGenerator; private final AuthenticationService authenticationService; private final TokenRotationService tokenRotationService; + private final DomainEventPublisher eventPublisher; public AuthApplicationService( UserRepository userRepository, @@ -49,15 +51,18 @@ public AuthApplicationService( PasswordEncoder passwordEncoder, TokenGenerator tokenGenerator, AuthenticationService authenticationService, - TokenRotationService tokenRotationService) { + TokenRotationService tokenRotationService, + DomainEventPublisher eventPublisher) { this.userRepository = userRepository; this.refreshTokenRepository = refreshTokenRepository; this.passwordEncoder = passwordEncoder; this.tokenGenerator = tokenGenerator; this.authenticationService = authenticationService; this.tokenRotationService = tokenRotationService; + this.eventPublisher = eventPublisher; } + @Transactional public AuthResult register(RegisterCommand command) { logger.debug("Registering new user with email: {}", command.email()); @@ -75,6 +80,9 @@ public AuthResult register(RegisterCommand command) { user = userRepository.save(user); logger.debug("User registered with ID: {}", user.getId().value()); + eventPublisher.publish(new UserRegisteredEvent( + user.getId().value(), user.getEmail().value(), user.getName().value())); + // Generate tokens TokenFamily tokenFamily = TokenFamily.generate(); TokenPair tokens = tokenRotationService.generateTokens(user, tokenFamily); @@ -85,6 +93,7 @@ public AuthResult register(RegisterCommand command) { return AuthResult.of(user.getId().value(), user.getEmail().value(), user.getRole(), tokens); } + @Transactional() public AuthResult login(LoginCommand command) { logger.debug("Logging in user with email: {}", command.email()); @@ -151,6 +160,7 @@ public AuthResult refreshTokens(RefreshTokenCommand command) { } } + @Transactional public void logout(String refreshToken) { logger.debug("Logging out user (all devices)"); @@ -163,6 +173,7 @@ public void logout(String refreshToken) { }); } + @Transactional public void logoutSingle(String refreshToken) { logger.debug("Logging out user (single device)"); @@ -171,6 +182,7 @@ public void logoutSingle(String refreshToken) { logger.debug("Logged out from current device"); } + @Transactional public void cleanupExpiredTokens() { logger.debug("Cleaning up expired refresh tokens"); refreshTokenRepository.deleteExpiredTokens(LocalDateTime.now()); diff --git a/src/test/java/org/nkcoder/user/application/service/AuthApplicationServiceTest.java b/src/test/java/org/nkcoder/user/application/service/AuthApplicationServiceTest.java index c0e3c73..d7e6381 100644 --- a/src/test/java/org/nkcoder/user/application/service/AuthApplicationServiceTest.java +++ b/src/test/java/org/nkcoder/user/application/service/AuthApplicationServiceTest.java @@ -18,6 +18,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.nkcoder.shared.kernel.domain.event.DomainEventPublisher; import org.nkcoder.shared.kernel.exception.AuthenticationException; import org.nkcoder.shared.kernel.exception.ValidationException; import org.nkcoder.user.application.dto.command.LoginCommand; @@ -62,6 +63,9 @@ class AuthApplicationServiceTest { @Mock private TokenRotationService tokenRotationService; + @Mock + private DomainEventPublisher eventPublisher; + private AuthApplicationService authApplicationService; @BeforeEach @@ -72,7 +76,8 @@ void setUp() { passwordEncoder, tokenGenerator, authenticationService, - tokenRotationService); + tokenRotationService, + eventPublisher); } @Nested