Remove service interfaces — use concrete classes directly
Each domain had a single-implementation interface (e.g. AdminService interface + AdminServiceImpl). Merged implementation into the service class and deleted the redundant interfaces per KISS principle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,95 @@
|
||||
package com.recipeapp.auth;
|
||||
|
||||
import com.recipeapp.auth.dto.*;
|
||||
import com.recipeapp.auth.entity.UserAccount;
|
||||
import com.recipeapp.common.ConflictException;
|
||||
import com.recipeapp.common.ResourceNotFoundException;
|
||||
import com.recipeapp.common.ValidationException;
|
||||
import com.recipeapp.household.HouseholdMemberRepository;
|
||||
import com.recipeapp.household.entity.HouseholdMember;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public interface AuthService {
|
||||
UserResponse signup(SignupRequest request);
|
||||
UserResponse login(LoginRequest request);
|
||||
UserResponse getCurrentUser(String email);
|
||||
UserResponse updateProfile(String email, UpdateProfileRequest request);
|
||||
@Service
|
||||
public class AuthService {
|
||||
|
||||
private final UserAccountRepository userAccountRepository;
|
||||
private final HouseholdMemberRepository householdMemberRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
public AuthService(UserAccountRepository userAccountRepository,
|
||||
HouseholdMemberRepository householdMemberRepository,
|
||||
PasswordEncoder passwordEncoder) {
|
||||
this.userAccountRepository = userAccountRepository;
|
||||
this.householdMemberRepository = householdMemberRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UserResponse signup(SignupRequest request) {
|
||||
if (userAccountRepository.existsByEmailIgnoreCase(request.email())) {
|
||||
throw new ConflictException("Email already registered");
|
||||
}
|
||||
var user = new UserAccount(
|
||||
request.email(),
|
||||
request.displayName(),
|
||||
passwordEncoder.encode(request.password())
|
||||
);
|
||||
user = userAccountRepository.save(user);
|
||||
return UserResponse.basic(user.getId(), user.getEmail(), user.getDisplayName());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public UserResponse login(LoginRequest request) {
|
||||
UserAccount user = userAccountRepository.findByEmailIgnoreCase(request.email())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Invalid email or password"));
|
||||
|
||||
if (!user.isActive()) {
|
||||
throw new ValidationException("Account is deactivated");
|
||||
}
|
||||
if (!passwordEncoder.matches(request.password(), user.getPasswordHash())) {
|
||||
throw new ValidationException("Invalid email or password");
|
||||
}
|
||||
return toUserResponse(user);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public UserResponse getCurrentUser(String email) {
|
||||
UserAccount user = userAccountRepository.findByEmailIgnoreCase(email)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("User not found"));
|
||||
return toUserResponse(user);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UserResponse updateProfile(String email, UpdateProfileRequest request) {
|
||||
UserAccount user = userAccountRepository.findByEmailIgnoreCase(email)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("User not found"));
|
||||
|
||||
if (request.displayName() != null) {
|
||||
user.setDisplayName(request.displayName());
|
||||
}
|
||||
if (request.newPassword() != null) {
|
||||
if (request.currentPassword() == null) {
|
||||
throw new ValidationException("Current password is required to set a new password");
|
||||
}
|
||||
if (!passwordEncoder.matches(request.currentPassword(), user.getPasswordHash())) {
|
||||
throw new ValidationException("Current password is incorrect");
|
||||
}
|
||||
user.setPasswordHash(passwordEncoder.encode(request.newPassword()));
|
||||
}
|
||||
user = userAccountRepository.save(user);
|
||||
return UserResponse.basic(user.getId(), user.getEmail(), user.getDisplayName());
|
||||
}
|
||||
|
||||
private UserResponse toUserResponse(UserAccount user) {
|
||||
return householdMemberRepository.findByUserEmailIgnoreCase(user.getEmail())
|
||||
.map(member -> UserResponse.withHousehold(
|
||||
user.getId(), user.getEmail(), user.getDisplayName(),
|
||||
member.getHousehold().getId(), member.getHousehold().getName(),
|
||||
member.getRole(), user.getSystemRole()))
|
||||
.orElse(UserResponse.withHousehold(
|
||||
user.getId(), user.getEmail(), user.getDisplayName(),
|
||||
null, null, null, user.getSystemRole()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user