-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from woowa-techcamp-2024/feature/4_kimhyun5u_구…
…매자_회원가입 구매자 회원가입
- Loading branch information
Showing
22 changed files
with
910 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
27 changes: 27 additions & 0 deletions
27
src/main/java/camp/woowak/lab/customer/domain/Customer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,45 @@ | ||
package camp.woowak.lab.customer.domain; | ||
|
||
import camp.woowak.lab.customer.exception.InvalidCreationException; | ||
import camp.woowak.lab.payaccount.domain.PayAccount; | ||
import camp.woowak.lab.web.authentication.PasswordEncoder; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.OneToOne; | ||
import lombok.Getter; | ||
|
||
@Entity | ||
@Getter | ||
public class Customer { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
@Column(nullable = false, length = 50) | ||
private String name; | ||
@Column(unique = true, nullable = false, length = 100) | ||
private String email; | ||
@Column(nullable = false, length = 30) | ||
private String password; | ||
@Column(nullable = false, length = 30) | ||
private String phone; | ||
@OneToOne(fetch = FetchType.LAZY) | ||
private PayAccount payAccount; | ||
|
||
public Customer() { | ||
} | ||
|
||
public Customer(String name, String email, String password, String phone, PayAccount payAccount, | ||
PasswordEncoder passwordEncoder) throws | ||
InvalidCreationException { | ||
CustomerValidator.validateCreation(name, email, password, phone, payAccount); | ||
this.name = name; | ||
this.email = email; | ||
this.password = passwordEncoder.encode(password); | ||
this.phone = phone; | ||
this.payAccount = payAccount; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package camp.woowak.lab.customer.domain; | ||
|
||
import camp.woowak.lab.customer.exception.CustomerErrorCode; | ||
import camp.woowak.lab.customer.exception.InvalidCreationException; | ||
import camp.woowak.lab.payaccount.domain.PayAccount; | ||
|
||
public class CustomerValidator { | ||
private static final int MAX_NAME_LENGTH = 50; | ||
private static final int MAX_EMAIL_LENGTH = 100; | ||
private static final int MIN_PASSWORD_LENGTH = 8; | ||
private static final int MAX_PASSWORD_LENGTH = 30; | ||
private static final int MAX_PHONE_LENGTH = 30; | ||
|
||
private CustomerValidator() { | ||
} | ||
|
||
public static void validateCreation(String name, String email, String password, String phone, | ||
PayAccount payAccount) throws InvalidCreationException { | ||
validateName(name); | ||
validateEmail(email); | ||
validatePassword(password); | ||
validatePhone(phone); | ||
validatePayAccount(payAccount); | ||
} | ||
|
||
public static void validateName(String name) throws InvalidCreationException { | ||
if (name == null || name.isBlank()) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer name cannot be blank"); | ||
} | ||
if (name.length() > MAX_NAME_LENGTH) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, | ||
"Customer name cannot be longer than 50 characters"); | ||
} | ||
} | ||
|
||
public static void validateEmail(String email) throws InvalidCreationException { | ||
if (email == null || email.isBlank()) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer email cannot be blank"); | ||
} | ||
if (email.trim().length() > MAX_EMAIL_LENGTH) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, | ||
"Customer email cannot be longer than 100 characters"); | ||
} | ||
} | ||
|
||
public static void validatePassword(String password) throws InvalidCreationException { | ||
if (password == null || password.isBlank()) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer password cannot be blank"); | ||
} | ||
if (password.trim().length() < MIN_PASSWORD_LENGTH) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, | ||
"Customer password cannot be shorter than 8 characters"); | ||
} | ||
if (password.trim().length() > MAX_PASSWORD_LENGTH) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, | ||
"Customer password cannot be longer than 30 characters"); | ||
} | ||
} | ||
|
||
public static void validatePhone(String phone) throws InvalidCreationException { | ||
if (phone == null || phone.isBlank()) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer phone cannot be blank"); | ||
} | ||
if (phone.trim().length() > MAX_PHONE_LENGTH) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, | ||
"Customer phone cannot be longer than 30 characters"); | ||
} | ||
} | ||
|
||
public static void validatePayAccount(PayAccount payAccount) throws InvalidCreationException { | ||
if (payAccount == null) { | ||
throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, | ||
"Customer payAccount cannot be null"); | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package camp.woowak.lab.customer.exception; | ||
|
||
import camp.woowak.lab.common.exception.ErrorCode; | ||
|
||
public enum CustomerErrorCode implements ErrorCode { | ||
INVALID_CREATION(400, "C1", "잘못된 요청입니다."), | ||
DUPLICATE_EMAIL(400, "C2", "이미 존재하는 이메일입니다."); | ||
|
||
private final int status; | ||
private final String errorCode; | ||
private final String message; | ||
|
||
CustomerErrorCode(int status, String errorCode, String message) { | ||
this.status = status; | ||
this.errorCode = errorCode; | ||
this.message = message; | ||
} | ||
|
||
@Override | ||
public int getStatus() { | ||
return status; | ||
} | ||
|
||
@Override | ||
public String getErrorCode() { | ||
return errorCode; | ||
} | ||
|
||
@Override | ||
public String getMessage() { | ||
return message; | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package camp.woowak.lab.customer.exception; | ||
|
||
import camp.woowak.lab.common.exception.BadRequestException; | ||
|
||
public class DuplicateEmailException extends BadRequestException { | ||
public DuplicateEmailException() { | ||
super(CustomerErrorCode.DUPLICATE_EMAIL); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package camp.woowak.lab.customer.exception; | ||
|
||
import camp.woowak.lab.common.exception.BadRequestException; | ||
import camp.woowak.lab.common.exception.ErrorCode; | ||
|
||
public class InvalidCreationException extends BadRequestException { | ||
public InvalidCreationException(ErrorCode errorCode, String message) { | ||
super(errorCode, message); | ||
} | ||
} |
Empty file.
8 changes: 8 additions & 0 deletions
8
src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package camp.woowak.lab.customer.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import camp.woowak.lab.customer.domain.Customer; | ||
|
||
public interface CustomerRepository extends JpaRepository<Customer, Long> { | ||
} |
Empty file.
49 changes: 49 additions & 0 deletions
49
src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package camp.woowak.lab.customer.service; | ||
|
||
import org.springframework.dao.DataIntegrityViolationException; | ||
import org.springframework.stereotype.Service; | ||
|
||
import camp.woowak.lab.customer.domain.Customer; | ||
import camp.woowak.lab.customer.exception.DuplicateEmailException; | ||
import camp.woowak.lab.customer.exception.InvalidCreationException; | ||
import camp.woowak.lab.customer.repository.CustomerRepository; | ||
import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; | ||
import camp.woowak.lab.payaccount.domain.PayAccount; | ||
import camp.woowak.lab.payaccount.repository.PayAccountRepository; | ||
import camp.woowak.lab.web.authentication.PasswordEncoder; | ||
import jakarta.transaction.Transactional; | ||
|
||
@Service | ||
public class SignUpCustomerService { | ||
private final CustomerRepository customerRepository; | ||
private final PayAccountRepository payAccountRepository; | ||
private final PasswordEncoder passwordEncoder; | ||
|
||
public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRepository payAccountRepository, | ||
PasswordEncoder passwordEncoder) { | ||
this.customerRepository = customerRepository; | ||
this.payAccountRepository = payAccountRepository; | ||
this.passwordEncoder = passwordEncoder; | ||
} | ||
|
||
/** | ||
* | ||
* @throws InvalidCreationException 구매자 생성에 오류가 나는 경우 | ||
* @throws DuplicateEmailException 이메일이 중복되는 경우 | ||
*/ | ||
@Transactional | ||
public Long signUp(SignUpCustomerCommand cmd) { | ||
PayAccount payAccount = new PayAccount(); | ||
payAccountRepository.save(payAccount); | ||
|
||
Customer newCustomer = new Customer(cmd.name(), cmd.email(), cmd.password(), cmd.phone(), payAccount, | ||
passwordEncoder); | ||
|
||
try { | ||
customerRepository.save(newCustomer); | ||
} catch (DataIntegrityViolationException e) { | ||
throw new DuplicateEmailException(); | ||
} | ||
return newCustomer.getId(); | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
src/main/java/camp/woowak/lab/customer/service/command/SignUpCustomerCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package camp.woowak.lab.customer.service.command; | ||
|
||
public record SignUpCustomerCommand(String name, String email, String password, String phone) { | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/camp/woowak/lab/web/api/customer/CustomerApiController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package camp.woowak.lab.web.api.customer; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import camp.woowak.lab.customer.service.SignUpCustomerService; | ||
import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; | ||
import camp.woowak.lab.web.api.utils.APIResponse; | ||
import camp.woowak.lab.web.api.utils.APIUtils; | ||
import camp.woowak.lab.web.dto.request.customer.SignUpCustomerRequest; | ||
import camp.woowak.lab.web.dto.response.customer.SignUpCustomerResponse; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import jakarta.validation.Valid; | ||
|
||
@RestController | ||
public class CustomerApiController { | ||
private final SignUpCustomerService signUpCustomerService; | ||
|
||
public CustomerApiController(SignUpCustomerService signUpCustomerService) { | ||
this.signUpCustomerService = signUpCustomerService; | ||
} | ||
|
||
@PostMapping("/customers") | ||
public ResponseEntity<APIResponse<SignUpCustomerResponse>> signUp(@Valid @RequestBody SignUpCustomerRequest request, | ||
HttpServletResponse response) { | ||
SignUpCustomerCommand command = | ||
new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone()); | ||
|
||
Long registeredId = signUpCustomerService.signUp(command); | ||
|
||
response.setHeader("Location", "/customers/" + registeredId); | ||
|
||
return APIUtils.of(HttpStatus.CREATED, new SignUpCustomerResponse(registeredId)); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/camp/woowak/lab/web/api/customer/CustomerExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package camp.woowak.lab.web.api.customer; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ProblemDetail; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; | ||
|
||
import camp.woowak.lab.common.advice.DomainExceptionHandler; | ||
import camp.woowak.lab.common.exception.BadRequestException; | ||
import camp.woowak.lab.customer.exception.DuplicateEmailException; | ||
import camp.woowak.lab.customer.exception.InvalidCreationException; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
@DomainExceptionHandler | ||
public class CustomerExceptionHandler extends ResponseEntityExceptionHandler { | ||
/** | ||
* | ||
* BadRequestException.class 와 MethodArgumentNotValidException.class 를 처리한다. | ||
*/ | ||
@ExceptionHandler({InvalidCreationException.class}) | ||
@ResponseStatus(HttpStatus.BAD_REQUEST) | ||
public ProblemDetail handleBadRequestException(BadRequestException e) { | ||
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, | ||
e.errorCode().getErrorCode()); | ||
problemDetail.setProperty("errorCode", e.errorCode().getErrorCode()); | ||
return problemDetail; | ||
} | ||
|
||
/** | ||
* | ||
* DuplicateEmailException.class 를 처리한다. | ||
*/ | ||
@ExceptionHandler({DuplicateEmailException.class}) | ||
@ResponseStatus(HttpStatus.CONFLICT) | ||
public ProblemDetail handleDuplicateEmailException(DuplicateEmailException e) { | ||
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT, | ||
e.errorCode().getMessage()); | ||
problemDetail.setProperty("errorCode", e.errorCode().getErrorCode()); | ||
return problemDetail; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package camp.woowak.lab.web.dto.request; | ||
|
||
import org.hibernate.validator.constraints.Length; | ||
|
||
import camp.woowak.lab.web.validation.annotation.Phone; | ||
import jakarta.validation.constraints.Email; | ||
|
||
public record SignUpVendorRequest( | ||
@Length(min = 1, max = 50) | ||
String name, | ||
String email, | ||
@Length(min = 1, max = 30) | ||
String password, | ||
@Phone | ||
String phone | ||
) { | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package camp.woowak.lab.web.dto.request.customer; | ||
|
||
import org.hibernate.validator.constraints.Length; | ||
|
||
import camp.woowak.lab.web.validation.annotation.Phone; | ||
import jakarta.validation.constraints.Email; | ||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record SignUpCustomerRequest( | ||
@Length(min = 1, max = 50, message = "이름은 1자 이상 50자 이하여야 합니다.") | ||
String name, | ||
@NotBlank(message = "이메일은 필수 입력값입니다.") | ||
@Email(message = "이메일 형식이 올바르지 않습니다.") | ||
String email, | ||
@Length(min = 8, max = 20, message = "비밀번호는 8자 이상 20자 이하여야 합니다.") | ||
String password, | ||
@Phone(message = "전화번호 형식이 올바르지 않습니다.") | ||
String phone | ||
) { | ||
} |
4 changes: 4 additions & 0 deletions
4
src/main/java/camp/woowak/lab/web/dto/response/customer/SignUpCustomerResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package camp.woowak.lab.web.dto.response.customer; | ||
|
||
public record SignUpCustomerResponse(Long id) { | ||
} |
Oops, something went wrong.