Skip to content

Commit

Permalink
resolve: 충돌 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
EunChanNam committed Nov 14, 2023
2 parents 1b17d04 + 038bcf7 commit c437673
Show file tree
Hide file tree
Showing 35 changed files with 1,195 additions and 327 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## 개선 목적
1. 아키텍처 : 기존의 레이어드 아키텍처는 유지하지만, 기존 Domain 계층의 잘못된 의존관계를 바로 잡는다.
2. CI/CD : `github action` 을 통해서 CI/CD 를 구성하고 관리와 배포에 대한 자동화 환경을 구성한다.
3. 테스트 코드 : `Test Double` 을 활용하여 불필요한 통합 테스트 환경에서 벗어나며 단위테스트에 집중하고 테스트 성능을 향상시킨다, 통합테스트를 별도로 진행하며 RestDocs + Swagger 를 통해 API 명세를 진행한다.
3. 테스트 코드 : `Test Double` 을 활용하여 불필요한 통합 테스트 환경에서 벗어나며 단위테스트에 집중하고 테스트 성능을 향상시킨다.
5. 프로덕트 코드 리펙토링 : 코드를 살피며 객체지향적인 코드로 리팩토링한다

## 🛠️ 기술 스택
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
Expand Down Expand Up @@ -53,4 +55,9 @@ public void addInterceptors(final InterceptorRegistry registry) {
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new AuthInfoArgumentResolver(authTokenManager));
}

@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class HairStyleSearchService {

//메인 추천 로직
public ResponseWrapper<HairStyleResponse> recommendHair(List<Tag> tags, Long userId) {
User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);

validateUserHasFaceShapeTag(user);

Expand All @@ -50,7 +50,7 @@ public ResponseWrapper<HairStyleResponse> recommendHair(List<Tag> tags, Long use

//홈 화면 사용자 맞춤 추천 로직
public ResponseWrapper<HairStyleResponse> recommendHairByFaceShape(Long userId) {
User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);

HairRecommendCondition condition = subRecommend(user.getFaceShape(), user.getSex());
List<HairStyle> hairStyles = hairStyleQueryRepository.findByFaceShape(condition, getDefaultPageable());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private void saveNewPointLog(
@Transactional
public boolean usePoint(final PointUseRequest request, final Long userId) {

User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);

pointLogRepository.findByUserOrderByCreatedDateDesc(user)
.ifPresentOrElse(
Expand All @@ -62,7 +62,7 @@ public boolean usePoint(final PointUseRequest request, final Long userId) {

@Transactional
public boolean chargePoint(int dealAmount, Long userId) {
User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);
pointLogRepository.findByUserOrderByCreatedDateDesc(user)
.ifPresentOrElse(
lastPointLog -> saveNewPointLog(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private Review generateReview(ReviewCreateRequest request, List<String> photos,
public Long createReview(ReviewCreateRequest request, Long userId) {

List<String> photoUrls = photoService.uploadPhotos(request.files());
User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);
HairStyle hairStyle = hairStyleFindService.getById(request.hairStyleId());

Review review = generateReview(request, photoUrls, user, hairStyle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ public class UserFindService {

private final UserRepository userRepository;

public User findByUserId(Long userId) {
public User getById(Long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new WishHairException(ErrorCode.NOT_EXIST_KEY));
}

public User findByEmail(Email email) {
public User getByEmail(Email email) {
return userRepository.findByEmail(email)
.orElseThrow(() -> new WishHairException(ErrorCode.USER_NOT_FOUND_BY_EMAIL));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public MyPageResponse getMyPageInfo(Long userId) {
Pageable pageable = PageableGenerator.generateDateDescPageable(3);

List<ReviewResponse> reviewResponses = reviewSearchService.findLikingReviews(userId, pageable).getResult();
User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);

int point = pointLogRepository.findByUserOrderByCreatedDateDesc(user)
.map(PointLog::getPoint)
Expand All @@ -44,10 +44,10 @@ public MyPageResponse getMyPageInfo(Long userId) {
}

public UserInformation getUserInformation(Long userId) {
return toUserInformation(userFindService.findByUserId(userId));
return toUserInformation(userFindService.getById(userId));
}

public UserInfo getUserInfo(Long userId) {
return new UserInfo(userFindService.findByUserId(userId));
return new UserInfo(userFindService.getById(userId));
}
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
package com.inq.wishhair.wesharewishhair.user.application;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.inq.wishhair.wesharewishhair.auth.domain.TokenRepository;
import com.inq.wishhair.wesharewishhair.global.dto.response.SimpleResponseWrapper;
import com.inq.wishhair.wesharewishhair.global.exception.ErrorCode;
import com.inq.wishhair.wesharewishhair.global.exception.WishHairException;
import com.inq.wishhair.wesharewishhair.hairstyle.domain.hashtag.Tag;
import com.inq.wishhair.wesharewishhair.point.domain.PointLogRepository;
import com.inq.wishhair.wesharewishhair.review.application.ReviewService;
import com.inq.wishhair.wesharewishhair.user.application.utils.UserValidator;
import com.inq.wishhair.wesharewishhair.user.domain.AiConnector;
import com.inq.wishhair.wesharewishhair.user.domain.UserRepository;
import com.inq.wishhair.wesharewishhair.user.domain.entity.Email;
import com.inq.wishhair.wesharewishhair.user.domain.entity.Nickname;
import com.inq.wishhair.wesharewishhair.user.domain.entity.User;
import com.inq.wishhair.wesharewishhair.user.presentation.dto.request.PasswordRefreshRequest;
import com.inq.wishhair.wesharewishhair.user.presentation.dto.request.PasswordUpdateRequest;
import com.inq.wishhair.wesharewishhair.user.presentation.dto.request.SignUpRequest;
import com.inq.wishhair.wesharewishhair.user.presentation.dto.request.UserUpdateRequest;
import com.inq.wishhair.wesharewishhair.user.domain.entity.Email;
import com.inq.wishhair.wesharewishhair.user.domain.entity.FaceShape;
import com.inq.wishhair.wesharewishhair.user.domain.entity.Nickname;
import com.inq.wishhair.wesharewishhair.user.domain.entity.Password;
import com.inq.wishhair.wesharewishhair.user.domain.entity.User;
import com.inq.wishhair.wesharewishhair.user.domain.UserRepository;
import com.inq.wishhair.wesharewishhair.point.domain.PointLogRepository;
import com.inq.wishhair.wesharewishhair.user.application.utils.UserValidator;
import com.inq.wishhair.wesharewishhair.user.domain.AiConnector;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Transactional
public class UserService {

private final UserRepository userRepository;
private final UserFindService userFindService;
private final UserValidator userValidator;
private final PasswordEncoder passwordEncoder;
private final ReviewService reviewService;
private final TokenRepository tokenRepository;
private final AiConnector connector;
private final PointLogRepository pointLogRepository;

@Transactional
public Long createUser(SignUpRequest request) {

User user = generateUser(request);
Expand All @@ -52,61 +45,49 @@ public Long createUser(SignUpRequest request) {
return saveUser.getId();
}

@Transactional
public void deleteUser(Long userId) {
tokenRepository.deleteByUserId(userId);
reviewService.deleteReviewByWriter(userId);
pointLogRepository.deleteByUserId(userId);
userRepository.deleteById(userId);
}

@Transactional
public void refreshPassword(PasswordRefreshRequest request) {
User user = userFindService.findByEmail(new Email(request.getEmail()));
User user = userFindService.getByEmail(new Email(request.email()));

user.updatePassword(Password.encrypt(request.getNewPassword(), passwordEncoder));
user.updatePassword(request.newPassword());
}

@Transactional
public void updateUser(Long userId, UserUpdateRequest request) {
User user = userFindService.findByUserId(userId);
Nickname newNickname = new Nickname(request.getNickname());
User user = userFindService.getById(userId);

userValidator.validateNicknameIsNotDuplicated(newNickname);
userValidator.validateNicknameIsNotDuplicated(new Nickname(request.nickname()));

user.updateNickname(newNickname);
user.updateSex(request.getSex());
user.updateNickname(request.nickname());
user.updateSex(request.sex());
}

@Transactional
public SimpleResponseWrapper<String> updateFaceShape(Long userId, MultipartFile file) {
User user = userFindService.findByUserId(userId);
User user = userFindService.getById(userId);
Tag faceShapeTag = connector.detectFaceShape(file);

user.updateFaceShape(new FaceShape(faceShapeTag));
user.updateFaceShape(faceShapeTag);
return new SimpleResponseWrapper<>(user.getFaceShapeTag().getDescription());
}

@Transactional
public void updatePassword(Long userId, PasswordUpdateRequest request) {
User user = userFindService.findByUserId(userId);
confirmPassword(user, request.getOldPassword());
User user = userFindService.getById(userId);
user.confirmPassword(request.oldPassword());

user.updatePassword(Password.encrypt(request.getNewPassword(), passwordEncoder));
user.updatePassword(request.newPassword());
}

private User generateUser(SignUpRequest request) {
return User.createUser(
request.getEmail(),
Password.encrypt(request.getPw(), passwordEncoder),
request.getName(),
request.getNickname(),
request.getSex());
}

private void confirmPassword(User user, String password) {
if (!passwordEncoder.matches(password, user.getPasswordValue())) {
throw new WishHairException(ErrorCode.USER_WRONG_PASSWORD);
}
return User.of(
request.email(),
request.pw(),
request.name(),
request.nickname(),
request.sex());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Embeddable
public class Email {

private static final String EMAIL_PATTERN = "^[_a-z0-9-]+(.[_a-z0-9-]+)*@(?:\\w+\\.)+\\w+$";
private static final Pattern EMAIL_MATCHER = Pattern.compile(EMAIL_PATTERN);

Expand All @@ -28,13 +29,13 @@ public Email(String email) {
this.value = email;
}

private static void validateEmailPattern(String email) {
private void validateEmailPattern(String email) {
if (isNotValidPattern(email)) {
throw new WishHairException(ErrorCode.USER_INVALID_EMAIL);
}
}

private static boolean isNotValidPattern(String email) {
private boolean isNotValidPattern(String email) {
return !EMAIL_MATCHER.matcher(email).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.regex.Pattern;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.inq.wishhair.wesharewishhair.global.exception.ErrorCode;
Expand All @@ -23,26 +24,29 @@ public class Password {
private static final String PASSWORD_PATTERN = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*\\W).{8,20}$";
private static final Pattern PASSWORD_MATCHER = Pattern.compile(PASSWORD_PATTERN);

private static final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

@Column(name = "pw", nullable = false)
private String value;

private Password(String pw) {
this.value = pw;
public Password(String pw) {
validatePasswordPattern(pw);
this.value = passwordEncoder.encode(pw);
}

//암호화
public static Password encrypt(String pw, PasswordEncoder encoder) {
validatePasswordPattern(pw);
return new Password(encoder.encode(pw));
public void confirmPassword(String password) {
if (!passwordEncoder.matches(password, value)) {
throw new WishHairException(ErrorCode.USER_WRONG_PASSWORD);
}
}

private static void validatePasswordPattern(String pw) {
private void validatePasswordPattern(String pw) {
if (isNotValidPattern(pw)) {
throw new WishHairException(ErrorCode.USER_INVALID_PASSWORD);
}
}

private static boolean isNotValidPattern(String pw) {
private boolean isNotValidPattern(String pw) {
return !PASSWORD_MATCHER.matcher(pw).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@ public class User {
private FaceShape faceShape;

private User(final Email email,
final Password password,
final String password,
final String name,
final Nickname nickname,
final Sex sex
) {
this.email = email;
this.password = password;
this.password = new Password(password);
this.name = name;
this.nickname = nickname;
this.sex = sex;
this.faceShape = null;
}

//=Factory method==//
public static User createUser(
//==Factory method==//
public static User of(
final String email,
final Password password,
final String password,
final String name,
final String nickname,
final Sex sex
Expand Down Expand Up @@ -105,16 +105,16 @@ public boolean existFaceShape() {
return faceShape != null;
}

public void updateFaceShape(FaceShape faceShape) {
this.faceShape = faceShape;
public void updateFaceShape(Tag tag) {
this.faceShape = new FaceShape(tag);
}

public void updatePassword(Password password) {
this.password = password;
public void updatePassword(String password) {
this.password = new Password(password);
}

public void updateNickname(Nickname nickname) {
this.nickname = nickname;
public void updateNickname(String nickname) {
this.nickname = new Nickname(nickname);
}

public void updateSex(Sex sex) {
Expand All @@ -128,4 +128,8 @@ public String getPasswordValue() {
public String getNicknameValue() {
return nickname.getValue();
}

public void confirmPassword(String password) {
this.password.confirmPassword(password);
}
}
Loading

0 comments on commit c437673

Please sign in to comment.