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:
2026-04-02 11:04:41 +02:00
parent 03b96e8584
commit 9713412d42
21 changed files with 1171 additions and 1595 deletions

View File

@@ -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()));
}
}