Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
22574c6
feat: BaseEntity 엔티티 구현 (#1)
sangyunpark99 Mar 31, 2025
af21ba6
feat: User 엔티티 구현 (#1)
sangyunpark99 Mar 31, 2025
0998526
refactor: 사용하지 않는 클래스 삭제 (#1)
sangyunpark99 Mar 31, 2025
c4828de
refactor: User 엔티티 필드명 userId → id로 변경(#1)
sangyunpark99 Mar 31, 2025
2f83a01
refactor: providerId 자료형 String으로 변경(#1)
sangyunpark99 Apr 2, 2025
86cbc52
feat: UserAddress 엔티티 구현 (#1)
sangyunpark99 Apr 2, 2025
9416a2c
chore: .gitignore에 application.yml 파일 추가 (#1)
sangyunpark99 Apr 2, 2025
4a78fb4
refactor: User 엔티티와 UserAddress 엔티티 간의 외래키 제거 (#1)
sangyunpark99 Apr 2, 2025
ea1ac42
feat : 사용자 회원가입 api 엔드포인트 생성 (#1)
sangyunpark99 Apr 2, 2025
abd1120
chore : validation 의존성 추가 (#1)
sangyunpark99 Apr 2, 2025
ed9c25b
feat : 주소 요청 DTO 생성 및 유효성 검증 추가 (#1)
sangyunpark99 Apr 2, 2025
804d08f
feat : 회원 가입 요청 DTO 생성 및 유효성 검증 추가 (#1)
sangyunpark99 Apr 2, 2025
16ec2c2
feat : 회원 가입 요청 DTO 생성 및 유효성 검증 테스트 추가 (#1)
sangyunpark99 Apr 2, 2025
220520b
feat : 주소 요청 DTO 생성 및 유효성 검증 테스트 추가 (#1)
sangyunpark99 Apr 2, 2025
1b03b82
refactor : 유효성 검증 메시지 상수 클래스로 분리 (#1)
sangyunpark99 Apr 2, 2025
b0ae2d2
style : 불필요한 import문 제거 (#1)
sangyunpark99 Apr 2, 2025
7e41f10
chore : 비밀번호 암호화에 필요한 crypto 의존성 추가 (#1)
sangyunpark99 Apr 2, 2025
9c42aaa
feat : User 엔티티에 password 필드 추가 (#1)
sangyunpark99 Apr 2, 2025
c9ba0fd
feat : UserAddress 엔티티에 phoneNumber 필드 삭제 (#1)
sangyunpark99 Apr 2, 2025
50b98e6
feat : UserAddressRequestDto → UserAddress 엔티티 변환 Mapper 구현 (#1)
sangyunpark99 Apr 2, 2025
7802513
feat : UserSignupRequestDto → User 엔티티 변환 Mapper 구현 (#1)
sangyunpark99 Apr 2, 2025
0a919de
test : UserMapper 테스트 (#1)
sangyunpark99 Apr 2, 2025
789331d
test : UserAddressMapper 테스트 (#1)
sangyunpark99 Apr 2, 2025
eac7c9a
feat : 사용자 주소 정보를 담는 UserAddressRequestDto 구현 (#1)
sangyunpark99 Apr 2, 2025
43ba1bb
test : 사용자 주소 정보를 담는 UserAddressRequestDto 테스트 (#1)
sangyunpark99 Apr 2, 2025
f3a9018
feat : 회원 가입시 필요한 UserSignupRequestDto 구현 (#1)
sangyunpark99 Apr 2, 2025
a3347d8
test : 회원 가입시 필요한 UserSignupRequestDto 테스트 (#1)
sangyunpark99 Apr 2, 2025
978f13c
feat : 회원가입 응답용 UserSignupResponseDto 구현 (#1)
sangyunpark99 Apr 2, 2025
d76d899
feat : 회원가입 응답 메시지를 ResponseMessages enum으로 분리 (#1)
sangyunpark99 Apr 2, 2025
8529873
feat : UserController 구현 (#1)
sangyunpark99 Apr 2, 2025
56a96e3
test : UserController 테스트 (#1)
sangyunpark99 Apr 2, 2025
a195785
test : 회원가입 통합 테스트 (#1)
sangyunpark99 Apr 2, 2025
155e062
feat : User 엔티티에 대한 CrudRepository 생성 (#1)
sangyunpark99 Apr 2, 2025
9915ec0
feat : UserService에 회원가입 로직 구현 (#1)
sangyunpark99 Apr 2, 2025
15d61fc
test : UserService에 회원가입 로직 테스트 (#1)
sangyunpark99 Apr 2, 2025
ca16721
feat : 유효성 검증 메시지 상수화 클래스 ValidationMessages 추가 (#1)
sangyunpark99 Apr 2, 2025
75337f9
feat: 중복 회원 예외 메시지 Enum에 추가 (#1)
sangyunpark99 Apr 3, 2025
8e06340
feat: GlobalExceptionHandler에 중복 회원 예외 처리 추가 (#1)
sangyunpark99 Apr 3, 2025
54fbbae
test: UserController에 중복 이메일 및 유효성 검사 테스트 케이스 추가 (#1)
sangyunpark99 Apr 3, 2025
c44d480
feat: UserDuplicateException 예외 클래스 추가 (#1)
sangyunpark99 Apr 3, 2025
7fe1008
test: User 통합 테스트에 회원가입 중복 이메일 실패 케이스 추가 (#1)
sangyunpark99 Apr 3, 2025
b3e6726
feat: UserJpaRepository에 이메일 기반 조회 메서드 추가 (#1)
sangyunpark99 Apr 3, 2025
386c329
feat: 회원가입 시 중복 이메일 검사 로직 추가 (#1)
sangyunpark99 Apr 3, 2025
06b6961
test: UserService 중복 이메일 예외 테스트 추가 (#1)
sangyunpark99 Apr 3, 2025
0eaa0f1
test: UserIntegrationTest에 중복 이메일 실패 케이스 추가 (#1)
sangyunpark99 Apr 3, 2025
a0f2565
refactor: enum 타입 constants 폴더의 enums 폴더로 분류 (#1)
sangyunpark99 Apr 3, 2025
3eaf910
refactor: BaseEntity 클래스 삭제 (#1)
sangyunpark99 Apr 4, 2025
bb9ca16
feat: 비즈니스 로직 예외처리를 위한 BusinessException 구현 (#1)
sangyunpark99 Apr 4, 2025
d4f540c
feat: ErrorCode enum 정의 및 기본 오류 코드 추가 (#1)
sangyunpark99 Apr 4, 2025
ed2b053
feat: 에러 응답시 사용되는 ErrorResponse 구현 (#1)
sangyunpark99 Apr 4, 2025
5ce6acf
chore: 불필요한 클래스 제거 (#1)
sangyunpark99 Apr 4, 2025
ff8762a
refactor: 전역 예외 처리 방식 통합 및 BusinessException 기반 구조로 개선 (#1)
sangyunpark99 Apr 4, 2025
114339e
refactor: BaseEntity 삭제 후, 필드에 createdAt, updatedAt 변수 추가 (#1)
sangyunpark99 Apr 4, 2025
3ab3f83
refactor: User 객체에 대한 LazyLoading 처리 (#1)
sangyunpark99 Apr 4, 2025
119f343
refactor: UserAddressMapper 유틸성 클래스로 변경 및 @Component 제거, 파라미터 변수에 fin…
sangyunpark99 Apr 4, 2025
01f37ab
feat: validation 메시지 삭제 (#1)
sangyunpark99 Apr 4, 2025
62e487e
refactor: ResponseEntity 삭제 (#1)
sangyunpark99 Apr 4, 2025
7177d52
test: 테스트 메시지 검증 삭제 (#1)
sangyunpark99 Apr 4, 2025
3b4de32
test: 테스트 메시지 검증 삭제 (#1)
sangyunpark99 Apr 4, 2025
29f3e5b
refactor: final 키워드 추가 (#1)
sangyunpark99 Apr 4, 2025
ff79ca6
refactor: 회원가입 로직 함수형 스타일로 리팩터링 및 예외 처리 일관화 (#1)
sangyunpark99 Apr 4, 2025
517c1ca
refactor: validation 메시지 제거 (#1)
sangyunpark99 Apr 4, 2025
0d5dc4a
test: 테스트 검증시 메시지 검증 제거 (#1)
sangyunpark99 Apr 4, 2025
1060d9a
test: UserServiceTest에서 UserMapper 제거 및 메서드 호출 방식 리팩터링 (#1)
sangyunpark99 Apr 4, 2025
5698b5b
feat: UserSignupResponseDto message 필드 삭제 (#1)
sangyunpark99 Apr 4, 2025
841bed8
refactor: 파라미터에 final 키워드 추가 (#1)
sangyunpark99 Apr 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .idea/dataSources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions user/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ out/

### VS Code ###
.vscode/

### applicaiton.yml ###
/src/main/resources/application.yml
3 changes: 3 additions & 0 deletions user/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.security:spring-security-crypto:6.4.4'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
package com.sangyunpark.user.application;

import com.sangyunpark.user.constant.code.ErrorCode;
import com.sangyunpark.user.domain.dto.request.UserSignupRequestDto;
import com.sangyunpark.user.domain.entity.User;
import com.sangyunpark.user.exception.BusinessException;
import com.sangyunpark.user.infrastructure.repository.UserJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.sangyunpark.user.application.mapper.UserMapper.toEntity;

@Service
@RequiredArgsConstructor
public class UserService {

private final UserJpaRepository userJpaRepository;

@Transactional
public Long signup(final UserSignupRequestDto userSignupRequestDto) {

return (Long) userJpaRepository.findUserByEmail(userSignupRequestDto.email())
.map(user -> {
throw new BusinessException(ErrorCode.USER_DUPLICATE);
})
.orElseGet(() -> {
User savedUser = userJpaRepository.save(toEntity(userSignupRequestDto));
return savedUser.getId();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sangyunpark.user.application.mapper;

import com.sangyunpark.user.domain.dto.request.UserAddressRequestDto;
import com.sangyunpark.user.domain.entity.UserAddress;

public class UserAddressMapper {

public static UserAddress toEntity(final UserAddressRequestDto dto) {
return UserAddress.builder()
.address(dto.address())
.defaultAddress(dto.defaultAddress())
.receiverName(dto.receiverName())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sangyunpark.user.application.mapper;

import com.sangyunpark.user.constant.enums.UserStatus;
import com.sangyunpark.user.domain.dto.request.UserSignupRequestDto;
import com.sangyunpark.user.domain.entity.User;
import com.sangyunpark.user.domain.entity.UserAddress;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

public class UserMapper {

private static final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

public static User toEntity(final UserSignupRequestDto dto) {

final UserAddress userAddress = UserAddressMapper.toEntity(dto.shippingInfo());

final User user = User.builder()
.email(dto.email())
.username(dto.username())
.password(passwordEncoder.encode(dto.password()))
.registerType(dto.registerType())
.phoneNumber(dto.phoneNumber())
.userType(dto.userType())
.userStatus(UserStatus.ACTIVE)
.build();

user.addUserAddress(userAddress);

return user;
}
}

This file was deleted.

9 changes: 9 additions & 0 deletions user/src/main/java/com/sangyunpark/user/config/JpaConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sangyunpark.user.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@Configuration
@EnableJpaAuditing
public class JpaConfig {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.sangyunpark.user.constant.code;

import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
public enum ErrorCode {

USER_DUPLICATE("user_duplicate",HttpStatus.CONFLICT),
USER_NOT_FOUND("user_not_found", HttpStatus.NOT_FOUND),
INVALID_REQUEST("invalid_request", HttpStatus.BAD_REQUEST),

INTERNAL_SERVER_ERROR("internal_server_error", HttpStatus.INTERNAL_SERVER_ERROR);

private final String code;
private final HttpStatus status;

ErrorCode(String code, HttpStatus status) {
this.code = code;
this.status = status;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sangyunpark.user.constant.enums;

public enum RegisterType {
EMAIL, OAUTH
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sangyunpark.user.constant.enums;

public enum UserStatus {
ACTIVE, INACTIVE, DELETED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sangyunpark.user.constant.enums;

public enum UserType {
NORMAL, ADMIN
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sangyunpark.user.domain.dto.request;


import jakarta.validation.constraints.NotBlank;

public record UserAddressRequestDto(
@NotBlank
String receiverName,

@NotBlank
String address,

boolean defaultAddress
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.sangyunpark.user.domain.dto.request;

import com.sangyunpark.user.constant.enums.RegisterType;
import com.sangyunpark.user.constant.enums.UserType;
import jakarta.validation.constraints.*;

public record UserSignupRequestDto(

@Email
@NotBlank
String email,

@NotBlank
@Size(min = 2, max = 10)
String username,

@NotBlank
@Size(min = 8, max = 20)
String password,

@NotBlank
@Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$")
String phoneNumber,

@NotNull
RegisterType registerType,

@NotNull
UserType userType,

@NotNull
UserAddressRequestDto shippingInfo
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sangyunpark.user.domain.dto.response;

public record ErrorResponse(String code) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sangyunpark.user.domain.dto.response;

public record UserSignupResponseDto(
Long userId
) {
}
71 changes: 71 additions & 0 deletions user/src/main/java/com/sangyunpark/user/domain/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,75 @@
package com.sangyunpark.user.domain.entity;

import com.sangyunpark.user.constant.enums.RegisterType;
import com.sangyunpark.user.constant.enums.UserStatus;
import com.sangyunpark.user.constant.enums.UserType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "users")
@Getter
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {

@Id @GeneratedValue
@Column(name = "user_id")
private Long id;

@Column(unique = true, nullable = false)
private String email;

@Column(nullable = false)
private String username;

@Column(nullable = false)
private String password;

@Column(nullable = false)
@Enumerated(value = EnumType.STRING)
private UserType userType;

@Column(nullable = false)
@Enumerated(value = EnumType.STRING)
private UserStatus userStatus;

@Column
private String providerId;

@Column(nullable = false)
@Enumerated(value = EnumType.STRING)
private RegisterType registerType;

@Column(nullable = false)
private String phoneNumber;

@Builder.Default
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserAddress> userAddress = new ArrayList<>();

@CreatedDate
@Column(updatable = false, nullable = false)
private LocalDateTime createdAt;

@LastModifiedDate
@Column(nullable = false)
private LocalDateTime updatedAt;

public void addUserAddress(UserAddress address) {
this.userAddress.add(address);
address.setUser(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sangyunpark.user.domain.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "user_address")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserAddress {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_address_id")
private Long id;

@Column(nullable = false)
private String receiverName;

@Setter
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), nullable = false)
private User user;

@Column(nullable = false)
private String address;

@Column(nullable = false)
private Boolean defaultAddress;

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.sangyunpark.user.exception;

import com.sangyunpark.user.constant.code.ErrorCode;
import lombok.Getter;

@Getter
public class BusinessException extends RuntimeException {

private final ErrorCode errorCode;

public BusinessException(ErrorCode errorCode) {
this.errorCode = errorCode;
}
}

This file was deleted.

Loading
Loading