Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

구매자 회원가입 #16

Merged
merged 76 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
17a4cc8
[chore] .gitkeep 삭제
kimhyun5u Aug 10, 2024
38c81a2
[feat] PasswordEncoder 추가
kimhyun5u Aug 10, 2024
deb1f8b
[feat] Vendor CustomException 추가
kimhyun5u Aug 10, 2024
030a8c0
[feat] PayAccountRepository 구현
kimhyun5u Aug 10, 2024
bffe230
[test] SignUpCustomerServiceTest
kimhyun5u Aug 10, 2024
0313777
[feat] Customer 회원가입 조건에 맞도록 수정
kimhyun5u Aug 10, 2024
d7482dc
[feat] CustomerRepository 구현
kimhyun5u Aug 10, 2024
8a94701
[feat] SignUpCustomerCommand 구현
kimhyun5u Aug 10, 2024
04f61a0
[feat] SignUpCustomerService 구현
kimhyun5u Aug 10, 2024
2900681
[feat] Vendor 회원가입 전송 계층 구현
Dr-KoKo Aug 10, 2024
4d6a20c
[feat] SignUpCustomerRequest 구현
kimhyun5u Aug 10, 2024
f93f83d
[feat] AuthController.signUpCustomer 구현
kimhyun5u Aug 10, 2024
c1bd5dc
[refactor] AuthController -> CustomerController
kimhyun5u Aug 11, 2024
07cd051
[test] Customer 테스트
kimhyun5u Aug 11, 2024
17fb832
[feat] Phone 검증 기능
Dr-KoKo Aug 10, 2024
bbafb20
[feat] jpa 설정
Dr-KoKo Aug 10, 2024
a9201d7
[test] CustomerController 테스트
kimhyun5u Aug 11, 2024
2d54d49
[feat] SignUpCustomerRequest 제약 조건 추가
kimhyun5u Aug 11, 2024
98f450b
[feat] CustomerController.signUp 파라미터 Valid 추가
kimhyun5u Aug 11, 2024
6d718e5
[refactor] SignUpCustomerServiceTest 수정
kimhyun5u Aug 11, 2024
5197be3
[feat] CustomerFixture 추가
kimhyun5u Aug 11, 2024
476489c
[chore] CustomerControllerTest 주석 추가
kimhyun5u Aug 11, 2024
4adf5de
[fix] CustomerControllerTest 로직 오류 수정
kimhyun5u Aug 11, 2024
5f51c1e
[test] SignUpCustomerServiceIntegrationTest 추가
kimhyun5u Aug 11, 2024
1ceeb0d
[feat] SignUpCustomerService.signUp 수정
kimhyun5u Aug 11, 2024
8dcc908
[feat] DuplicateException, InvalidCreationException 수정
kimhyun5u Aug 11, 2024
f0aa992
[fix] SignUpCustomerRequest
kimhyun5u Aug 11, 2024
a06d1c6
[feat] TestPayAccount 추가
kimhyun5u Aug 11, 2024
2750dbc
[chore] 오류 메세지 수정
kimhyun5u Aug 11, 2024
196b911
[build] 깃헙 템플릿 수정
Dr-KoKo Aug 10, 2024
9ae90e9
[build] 깃헙 템플릿 수정
Dr-KoKo Aug 10, 2024
56ec6f2
[build] 깃헙 액션 추가
Dr-KoKo Aug 10, 2024
8e86910
[feat] APIResponse 구현
Hyeon-Uk Aug 12, 2024
0797084
[feat] APIUtils 구현
Hyeon-Uk Aug 12, 2024
b9a7e0b
[test] APIUtils 테스트 코드 작성
Hyeon-Uk Aug 12, 2024
8c9a222
[docs] APIResponse에 사용시 주의사항 주석 추가
Hyeon-Uk Aug 12, 2024
e43860c
[feat] HttpStatusException 구현
kimhyun5u Aug 12, 2024
587c0d5
[feat] HttpStatusException 를 구현하는 Exception 구현
kimhyun5u Aug 12, 2024
3d2bc74
[feat] ErrorCode interface 구현
kimhyun5u Aug 12, 2024
11994fb
[feat] CustomRestControllerAdvice 구현
kimhyun5u Aug 12, 2024
99df6fd
[chore] 사용하지 않는 import 제거
kimhyun5u Aug 12, 2024
7d57737
[refactor] CustomRestControllerAdvice 이름 변경
kimhyun5u Aug 12, 2024
0677fb4
[fix] open-in-view 기본 설정으로 복구
kimhyun5u Aug 12, 2024
eb702f8
[chore] .gitkeep 제거
kimhyun5u Aug 12, 2024
b76a98f
[chore] .gitkeep 제거
kimhyun5u Aug 12, 2024
6ec34a9
[feat] CustomerErrorCode 생성
kimhyun5u Aug 12, 2024
ed6a9b8
[refactor] 도메인 Validation 주체 분리
kimhyun5u Aug 12, 2024
70f0f14
[refactor] CustomerException 수정
kimhyun5u Aug 12, 2024
a542d7c
[fix] 올바른 Exception 으로 변경
kimhyun5u Aug 12, 2024
956fb2b
[chore] 사용하지 않는 코드 삭제
kimhyun5u Aug 12, 2024
f3b8142
[chore] Exception 관련 Service 주석 추가
kimhyun5u Aug 12, 2024
ca68049
[feat] CustomerController 를 전담하는 DomainExceptionHandler 구현
kimhyun5u Aug 12, 2024
e81511d
[refactor] CustomerController 의 에러 처리 주체 변경
kimhyun5u Aug 13, 2024
140dbcc
[test] CustomerControllerTest 수정
kimhyun5u Aug 13, 2024
e2bd830
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
kimhyun5u Aug 13, 2024
9f90cf1
[chore] .gitkeep 제거
kimhyun5u Aug 13, 2024
ca72425
[chore] 사용하지 않는 코드 제거
kimhyun5u Aug 13, 2024
c38cbdb
[chore] 사용하지 않는 코드 제거
kimhyun5u Aug 13, 2024
ba7ef95
[refactor] 패키지 구조 변경
kimhyun5u Aug 13, 2024
3b07854
[test] 에러 코드 정책 변경으로 인한 수정
kimhyun5u Aug 13, 2024
d3d1cfc
[chore] @Repository 제거
kimhyun5u Aug 13, 2024
6be87cd
[chore] CustomerController 이름 변경
kimhyun5u Aug 13, 2024
e6b0b0c
[refactor] SignUpCustomerRequest 패키지 구조 변경
kimhyun5u Aug 13, 2024
f6d3346
[feat] BadRequestException 생성자 추가
kimhyun5u Aug 13, 2024
16ff26c
[feat] 에러코드 정책 변경에 따른 수정
kimhyun5u Aug 13, 2024
f932cae
[feat] 에러코드 정책 변경에 따른 수정
kimhyun5u Aug 13, 2024
54840c1
[feat] InvalidCreationException 수정
kimhyun5u Aug 13, 2024
c8784cd
[feat] SignUpCustomerResponse 추가
kimhyun5u Aug 13, 2024
6f125c9
[feat] CustomerValidator private 생성자 추가
kimhyun5u Aug 13, 2024
0b1eb38
Merge remote-tracking branch 'origin/main' into feature/4_kimhyun5u_구…
kimhyun5u Aug 13, 2024
ae0385d
[style] 코드 스타일 수정 적용
kimhyun5u Aug 13, 2024
98d77d1
Merge remote-tracking branch 'origin/main' into feature/4_kimhyun5u_구…
kimhyun5u Aug 13, 2024
7a44fac
[feat] SignUpCustomerRequest annotation param 수정
kimhyun5u Aug 13, 2024
b28cc5d
[refactor] Validation 상수 값 추출
kimhyun5u Aug 13, 2024
7a1e3fb
[feat] SignUpCustomerRequest annotation param 수정
kimhyun5u Aug 13, 2024
b68368a
[chore] 불필요한 throws 제거
kimhyun5u Aug 13, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ public class BadRequestException extends HttpStatusException {
public BadRequestException(ErrorCode errorCode) {
super(errorCode);
}

public BadRequestException(ErrorCode errorCode, String message) {
super(errorCode, message);
}
}
Empty file.
27 changes: 27 additions & 0 deletions src/main/java/camp/woowak/lab/customer/domain/Customer.java
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;
}
}
kimhyun5u marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
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 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() > 50) {
kimhyun5u marked this conversation as resolved.
Show resolved Hide resolved
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() > 100) {
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() > 30) {
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() > 30) {
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");
}
}
}
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;
}
}
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);
}
}
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.
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.
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;
}

kimhyun5u marked this conversation as resolved.
Show resolved Hide resolved
/**
*
* @throws InvalidCreationException 구매자 생성에 오류가 나는 경우
* @throws DuplicateEmailException 이메일이 중복되는 경우
*/
@Transactional
public Long signUp(SignUpCustomerCommand cmd) throws InvalidCreationException, DuplicateEmailException {
PayAccount payAccount = new PayAccount();
payAccountRepository.save(payAccount);

Customer newCustomer = new Customer(cmd.name(), cmd.email(), cmd.password(), cmd.phone(), payAccount,
passwordEncoder);

try {
kimhyun5u marked this conversation as resolved.
Show resolved Hide resolved
customerRepository.save(newCustomer);
} catch (DataIntegrityViolationException e) {
throw new DuplicateEmailException();
}
return newCustomer.getId();
}
}
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) {
}
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));
}
}
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;
}
}
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)
kimhyun5u marked this conversation as resolved.
Show resolved Hide resolved
String name,
@Email
String email,
@Length(min = 1, max = 30)
String password,
@Phone
String phone
) {
}
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)
String name,
@NotBlank
@Email
String email,
@Length(min = 8, max = 20)
String password,
@Phone
String phone
) {
}
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) {
}
Loading