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

Bp 25 implement user registration #6

Merged
merged 13 commits into from
Jul 20, 2024

Conversation

ekgns33
Copy link
Collaborator

@ekgns33 ekgns33 commented Jul 17, 2024

작업 목표

  • 회원 가입을 위한 기능 개발

  • 테스트 코드 작성

제한사항

  • 이미 존재하는 유저가 회원가입을 시도할 시 실패하고 에러를 반환한다.

  • 새로운 유저가 회원가입을 시도할 시 유저 정보를 저장한다.

  • 회원 가입 시 유저의 비밀번호는 암호화하여 저장한다.

목표가 아닌것

프로필 이미지 저장은 현재 Task에서 구현하지 않는다.

  • 기능 개발
  • 테스트코드 작성

@ekgns33 ekgns33 requested a review from goldentrash July 17, 2024 16:05
@ekgns33 ekgns33 self-assigned this Jul 17, 2024
Copy link

sonarcloud bot commented Jul 17, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarCloud

Copy link
Member

@zbqmgldjfh zbqmgldjfh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지나가다 리뷰 남겨봅니다~~ 화이팅!!

import lombok.Getter;

@Getter
@Builder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builder를 여기다 선언하면 다음과 같은 코드도 생성될것 같습니다.

Member.builder()
		.memberId(request.getMemberId())
		.build();

또한 인자로 null도 전달 가능한 상황입니다. 방어적인 생성이 필요하다 봅니다.

private final PasswordEncoder passwordEncoder;
private final MemberRepository memberRepository;

private boolean checkMemberAlreadyExist(String memberId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private 메서드는 public 메서드 보다 아래쪽에 나와야 합니다!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private를 아래로 내리겠습니다!

}

@Transactional
public SuccessResponse register(MemberRegisterRequest registerRequest) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

register 메서드는 SuccessResponse에 의존적이게 되었군요, 향후 다른 응답이 필요하면 해당 부분을 변경해야 할것 같은데요?
Controller의 역할을 조금더 생각해보시면 좋을것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서비스단에서는 객체만 반환을 하고 프레젠테이션 레이어에서 응답객체를 만들어 반환하도록 하는것을 말씀하시나용?


private final MemberService memberService;

@PostMapping("")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

("") 이부분 없어도 됩니다!

@PostMapping("")
public ResponseEntity<SuccessResponse> signup(@RequestBody MemberRegisterRequest registerRequest) {
memberService.register(registerRequest);
return ResponseEntity.status(201).body(SuccessResponse.messageOnly());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

201같은 상수를 직접 사용하기 보다는, HttpStatus 에 정의된 상수값을 사용하길 권장합니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

매직넘버를 제거하고 HttpStatus.Created이런 정의된 상수를 사용하는 것을 말씀하시는걸까요?

@@ -14,6 +15,12 @@
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(UserAlreadyExistException.class)
protected ResponseEntity<ErrorResponse> handleUserAlreadyExistException(final UserAlreadyExistException e) {
log.error("UserAlreadyExistException Caught! [{}]", e.getLogMessage());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.error("UserAlreadyExistException Caught! [{}]", e.getLogMessage(), e); 끝에 e도 인자로 추가하면 stack trace도 모두 출력됩니다. 추가적인 e를 위한 {}는 지정하지 않아도 되구요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그런 방법이 있군요! 적용해보겠습니다🤗

@@ -10,7 +10,9 @@ public enum ErrorCode {
INTERNAL_SERVER_ERROR("서버 오류입니다. 잠시후 재시도 해주세요", "[ERROR] : 예상치못한 에러 발생", 500),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이부분도 직접 500을 사용하기 보다는 HttpStatus 사용 권장

Copy link
Contributor

@goldentrash goldentrash Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrorCode.statusCode는 HTTP Status가 아닌, front-end에서의 error handling을 위한 additional code입니다.

다만, 현재 ErrorCode.logMessage가 해당 역할을 홀로 완벽히 수행하고 있는 것으로 보이는데, ErrorCode.StatusCod property 삭제에 대해서는 어떻게 생각하시나요? @ekgns33

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다. 응답객체를 만들어주는 부분에서 http 응답코드를 정하면 enum에 정의할 필요가 없다고 생각해요. 어떻게 생각하시나요

@Test
@DisplayName("새로운 멤버 회원가입 성공")
@Transactional
void should_success_when_newMember_register() {
Copy link
Member

@zbqmgldjfh zbqmgldjfh Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 class의 이름은 MemberServiceTest 인데,

  1. Transactional을 통해 데이터를 롤백한다는 것 -> Repository까지 확인하는 테스트 인것 같은데,
  2. 상단에 보면 Mock을 선언 -> Repository 는 가짜로 지정한 행동만 반환한다? Service Layer만 테스트 하고 싶은건가?
    인데, 둘중 뭘 의도한 테스트 인지 모르겠습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로컬에서 테스트할때 레포지토리를 살려놓은상태에서도 진행했는데 모킹하고나서도 그대로 놓은것 같습니다! 이 테스트에서는 서비스 레이어만 테스트하고자하여 삭제하겠습니다 😀


MockMvc mockMvc;

@MockBean
Copy link
Member

@zbqmgldjfh zbqmgldjfh Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mock과 MockBean의 차이점을 알고있으실까요?? 확인해보시면 좋을것 같아요~!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MockBean은 스프링애플리케이션 컨텍스트의 동일 유형의 빈을 대체하는 것으로 알고있습니다. 통합테스트나 외부의존성을 처리할때 사용한적이 있는데 이 테스트에서는 WebMvc를 사용하여 테스트를했기에 목빈을 사용했어요:)


@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(readOnly = true)의 장점은 무엇일까요?

Copy link
Collaborator Author

@ekgns33 ekgns33 Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

읽기 전용으로 트랜잭션을 설정하여 어느정도 성능의 이점을 가져갈 수 있습니다. 대표적으로 데이터 변경이 일어나지 않는것을 보장하므로 스냅샷을 저장하지 않죠(변경감지가 필요없어요).
다만 엔티티에 대해서 낙관적락을 사용하는 경우 쿼리한 데이터들의 수정을 리드온리에서 하는경우 일관성이 깨질 수 있습니다. 현재 우리 엔티티에는 낙관적 락을 적용하지 않았기 때문에 서비스 클래스에 넓은 범위로 적용했습니다. 위에서 언급한 내용은 데이터 수정과 관련된 메소드를 명세와 코드리뷰로 해결할 수 있다고 생각해요.

Copy link
Contributor

@goldentrash goldentrash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/application dir의 의미가 무엇일까요?

controllerdomain은 top-level에 위치하고, serviceapplication 아래에 위치시킨 이유가 궁금합니다. 일반적으로 controllerdomain에 비해 service의 규모가 비대해지는 경향이 있나요?

@ekgns33
Copy link
Collaborator Author

ekgns33 commented Jul 18, 2024

음 우선 레이어별로 디렉토리를 분리했어요! 그리고 말씀해주신 내용 관련해서는 서비스클래스 자체가 커질 수 있다고 생각해요. 그래서 애플리케이션레이어에서 조립의 역할을 하는 (일종의 파사드)와 서비스 레이어(실질적구현)을 나누고 싶었어요. 지금은 서비스가 하나뿐이라 크게 나뉘진 않네요

Copy link
Contributor

@goldentrash goldentrash Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserAlreadyExistException의 필요를 잘 모르겠습니다.

사용되는 형태를 살펴보니 UserAlreadyExistException.of(ErrorCode.USER_ALREADY_EXIST)의 형태입니다.
우리는 이미 ErrorCode Enum을 통해 Error의 유형을 구별하고 logMessage를 통한 메시지를 결정했습니다. 또한, ErrorCode/global/excpetions에 위치해서 codebase의 top-level에서 일괄 관리되고 있습니다. ErrorCode에 의존적이라면, application/member아래에서 domain 단위로 나눠 다시 관리할 필요가 있을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 에러코드에 의존하게된다는 말씀이군요. 하지만 에러코드의 경우 프로젝트 전역에서 공통으로 사용하는 값으로 로직이 존재하지않는 순수한 값만을 담고있는 클래스입니다. 의존이 생겨 에러코드를 사용하는 코드단에서 수정할일이 있을까요? 에러코드가 변해서 수정이 일어나야한다면 에러코드 자체를 바꾸는 경우만 생각나는데 이것은 로직의 변경으로 바라봐야하지 않을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예외클래스가 존재할 필요성에 대해서는 저는 이렇게 생각해요

    1. 에러코드와 무관하게 에러추적할때 어떤 비즈니스로직에서 발생했는지 파악하기 용이하다.
    1. 비즈니스 에러들을 하나로 묶어서 처리하면 에러코드 필드값으로 에러를 분류해야하는데 오히려 이게 복잡도를 높이지 않을까요? 에러코드는 같은데 예외의 이유가 다를 수 있을 것 같아요. 예외클래스 자체가 의미를 담고있다는 점에서 저는 만들었습니다

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BusinessException.of(ErrorCode.User_ALREADY_EXIST)의 형태로 사용해도 충분하지 않을까 싶었습니다.

아래는 /global/controller/GlobalExceptionHandler의 코드 일부분입니다.

@ExceptionHandler(UserAlreadyExistException.class)
protected ResponseEntity<ErrorResponse> handleUserAlreadyExistException(final UserAlreadyExistException e) {
	log.error("UserAlreadyExistException Caught! [{}]", e.getLogMessage());
	final ErrorResponse response = ErrorResponse.of(e.getMessage(), e.getLogMessage());
	return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(BusinessException.class)
protected ResponseEntity<ErrorResponse> handleBusinessException(final BusinessException e) {
	log.error("BusinessException Caught! [{}]", e.getLogMessage());
	final ErrorResponse response = ErrorResponse.of(e.getMessage(), e.getLogMessage());
	return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}

BusinexxException은 정의 및 사용 scope가 확실히 Global입니다. 그런데 UserAlreadyExisitException의 경우 정의는 Domain scope에서 이뤄지지만 사용은 Global scope까지 확장되고 있습니다. 앞으로 Domain이 계속 늘어날 것이고, Domain마다 각각의 Exception을 관리하게 될 것인데 이 모든 것들을 Global scope가 control해야 하는 구조는 관리에 어려움이 따를것같습니다.

그래서 떠오른 방법에 대한 @ekgns33의 의견이 궁금합니다!

  1. MemberErrorCodeapplication/member아래에 새로 정의합니다.
  2. UserAlreadyExistException exception에 대한 controllerAddvice를 /controller/member로 옮깁니다.
  3. MemberControllerAdvice에서 BuisnessException을 다시 throw합니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1번으로 가는게 어떨까요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인터넷 오류였을까요...? 분명 전 하나의 답글을 보고 2번째 comment를 작성했는데 이제보니 2개네요???

말씀하신것처럼 ErrorCode만 사용하는것보다는 Class를 분기하는게 더 로직을 단순하게 만든다고 생각합니다. 제가 BusinessException.of(ErrorCode.User_ALREADY_EXIST)를 언급했던 이유는 ControllerAdvice에서 BusinessExceptionUserAlreadyExistException의 처리에 약간의 log message를 제외한 나머지가 동일했기 때문입니다.

2번째 comment에서 작성한 떠오른 방법은 1, 2, 3 중에서 하나를 선택하자가 아닌 순서대로 전부라는 의미였는데, 지금 다시 읽어보니 뭔가뭔가인 느낌이 있네요. 해당 사항은 저도 조금 더 고민해 보겠습니다. 1번을 말씀하셨는데, 떠오른 좋은 구조가 있다면 편하신대로 re-factoring을 진행해주시면 감사합니다. 그런데 만약 저 3중에 하나를 골라야 한다고 생각하셨다면 전혀 아니니, 더 나은 구조가 없다면 현상 유지도 좋다고 생각합니다!

Copy link

sonarcloud bot commented Jul 20, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)
7.8% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

@ekgns33 ekgns33 merged commit 437488f into BP-24-implement-User-CRUD Jul 20, 2024
1 of 2 checks passed
@ekgns33 ekgns33 deleted the BP-25-implement-User-Registration branch July 20, 2024 13:22
@ekgns33 ekgns33 mentioned this pull request Jul 22, 2024
ekgns33 added a commit that referenced this pull request Jul 22, 2024
* Bp 25 implement user registration (#6)

* feat : 회원가입 api 권한 수정, 엔드포인트 prefix 메소드 추가

* feat : 에러코드, 커스텀 에러 추가, 전역 핸들러에 로직구현

* feat : 회원가입 DTO추가, 멤버 컨트롤러 추가

* feat : 멤버 서비스 추가, 회원가입 기능 추가

* test : 컨트롤러 테스트, 유닛테스트 작성

* feat : 유저 비밀번호 암호화 추가

* rename : 파일 위치 수정

* test : 암호화 로직 추가

* rename : DTO 컨트롤러 패키지로 이동

* refactor : 매직넘버 삭제, HttpStatus사용

* refactor : 기존 ErrorCode를 인터페이스화, 도메인마다 에러코드 정의

* refactor : 에러코드 구조 변경에 따른 코드 수정

* chore : spring-validation 추가

* Bp 26 implement user withdraw (#8)

* feat : 객체 생성 시 필드 체크를 위한 Validator생성

* feat : 멤버 엔티티객체 필드 기본값 수정, 탈퇴로직 구현

* feat : 회원 탈퇴 로직 구현

* feat : 시큐리티 회원가입, 로그인 csrf해제

* feat : 시큐리티 유틸성 클래스 추가

* feat : 멤버 서비스 예외 추가와 에러코드 추가

* style : 코드 포맷 수정

* test: 테스트코드 수정, 삭제 테스트코드 작성

* feat : Spring Validation에서 발생하는 에러 핸들링

* test : mock user 어노테이션추가

* refactor : 코드리뷰 적용

* fix ; csrf 비활성화

* feat : 식별자 전략 명시 IDENTITY
goldentrash pushed a commit that referenced this pull request Aug 27, 2024
* Bp 25 implement user registration (#6)

* feat : 회원가입 api 권한 수정, 엔드포인트 prefix 메소드 추가

* feat : 에러코드, 커스텀 에러 추가, 전역 핸들러에 로직구현

* feat : 회원가입 DTO추가, 멤버 컨트롤러 추가

* feat : 멤버 서비스 추가, 회원가입 기능 추가

* test : 컨트롤러 테스트, 유닛테스트 작성

* feat : 유저 비밀번호 암호화 추가

* rename : 파일 위치 수정

* test : 암호화 로직 추가

* rename : DTO 컨트롤러 패키지로 이동

* refactor : 매직넘버 삭제, HttpStatus사용

* refactor : 기존 ErrorCode를 인터페이스화, 도메인마다 에러코드 정의

* refactor : 에러코드 구조 변경에 따른 코드 수정

* chore : spring-validation 추가

* Bp 26 implement user withdraw (#8)

* feat : 객체 생성 시 필드 체크를 위한 Validator생성

* feat : 멤버 엔티티객체 필드 기본값 수정, 탈퇴로직 구현

* feat : 회원 탈퇴 로직 구현

* feat : 시큐리티 회원가입, 로그인 csrf해제

* feat : 시큐리티 유틸성 클래스 추가

* feat : 멤버 서비스 예외 추가와 에러코드 추가

* style : 코드 포맷 수정

* test: 테스트코드 수정, 삭제 테스트코드 작성

* feat : Spring Validation에서 발생하는 에러 핸들링

* test : mock user 어노테이션추가

* refactor : 코드리뷰 적용

* fix ; csrf 비활성화

* feat : 식별자 전략 명시 IDENTITY
goldentrash added a commit that referenced this pull request Aug 27, 2024
* Test/test ci (#2)

* Gitactions Test (#1)

* feat : 소나큐브 플러그인 의존성추가

* fix: 그래들 파일 수정

* feat: CI용 워크플로우생성

* feat : 테스트용 커밋

* fix: 잘못된 디렉토리명 수정

* feat : CI실패 시 디스코드 알림 추가

* test : CI 테스트를 위한 커밋

* feat: 그래들 캐시 추가, 불필요한 스크립트 제거

* Bp 3 spring project  (#3)

* chore : h2, p6spy의존성 추가

* feat : 응답을 위한 클래스 생성

* feat : 에러코드 공통 관리를 위한 Enum생성

* feat : 전역 에러 핸들러 추가

* remove : 불필요한 파일 삭제

* feat : 워크플로우 수정

* feat : 생성자 파라매터 수정, Of 메소드 수정

* Bp 4 swagger configuration (#4)

* chore : RestDocs, Swagger 의존성추가

* feat : 테스트용 컨트롤러 작성

* feat : RestDocsTest 어노테이션 생성

* test : 스웨거 컨트롤러를 위한 테스트 코드 작성

* Bp 12 implement user login (#5)

* chore : 스프링 시큐리티, 테스트 모듈 추가

* Feat : 스프링 시큐리티를 위한 UserDetail기능 재작성, 핸들러 작성

* feat : 전역 에러 핸들러에 비즈니스 에러 핸들러 추가

* feat : 비즈니스 로직에서 발생하는 예외를 정의하는 클래스 정의

* feat : 사용자 인증관련 에러코드 추가, 응답클래스에 메소드 추가

* refactor : 사용하지 않는 클래스 의존 삭제

* test : 로그인 기능 테스트 코드 작성

* remove : 필요없는 파일 삭제

* feat : 유저 권한 Enum클래스와 로그인 시 권한을 부여하는 기능 추가

* feat : 멤버 엔티티, 레포지토리 생성

* test : 로그인 통합 테스트 작성

* hotfix : 불필요한 파라매터설정 제거

* fix : 코드리뷰 적용 csrf 적용 및 스프링시큐리티로 세션저장 활성화

* refactor : 불필요한 상태값 제거에 따른 타입 변경

* Bp 24 implement user crud (#9)

* Bp 25 implement user registration (#6)

* feat : 회원가입 api 권한 수정, 엔드포인트 prefix 메소드 추가

* feat : 에러코드, 커스텀 에러 추가, 전역 핸들러에 로직구현

* feat : 회원가입 DTO추가, 멤버 컨트롤러 추가

* feat : 멤버 서비스 추가, 회원가입 기능 추가

* test : 컨트롤러 테스트, 유닛테스트 작성

* feat : 유저 비밀번호 암호화 추가

* rename : 파일 위치 수정

* test : 암호화 로직 추가

* rename : DTO 컨트롤러 패키지로 이동

* refactor : 매직넘버 삭제, HttpStatus사용

* refactor : 기존 ErrorCode를 인터페이스화, 도메인마다 에러코드 정의

* refactor : 에러코드 구조 변경에 따른 코드 수정

* chore : spring-validation 추가

* Bp 26 implement user withdraw (#8)

* feat : 객체 생성 시 필드 체크를 위한 Validator생성

* feat : 멤버 엔티티객체 필드 기본값 수정, 탈퇴로직 구현

* feat : 회원 탈퇴 로직 구현

* feat : 시큐리티 회원가입, 로그인 csrf해제

* feat : 시큐리티 유틸성 클래스 추가

* feat : 멤버 서비스 예외 추가와 에러코드 추가

* style : 코드 포맷 수정

* test: 테스트코드 수정, 삭제 테스트코드 작성

* feat : Spring Validation에서 발생하는 에러 핸들링

* test : mock user 어노테이션추가

* refactor : 코드리뷰 적용

* fix ; csrf 비활성화

* feat : 식별자 전략 명시 IDENTITY

* Bp 14  attendance api (#7)

* feat: Event 엔티티 생성

* feat: 특정 달의 이벤트 목록 조회

* feat: Participants 엔티티

* feat: 출석 기능 (Google Oauth 부분은 뼈대만)

* feat: Event Controller 작성 및 테스트, 문서 생성

* chore: validator와 Oauth Client 추가

* feat: Google OIDC를 이용한 사용자 출석 (draft)

* feat: 이벤트 출석 등록 -> 출석 URL (for QR Code) 생성

* comment: TODO, 출석 만료 기능 필요

* fix: 출석 API를 GET으로 변경, security matcher 수정 및 request 유지

* feat: security config conflict 정리

* feat: validation 책임을 Entity가 아닌 Factory로 전가

* feat: dto를 service layer가 아닌 presentational layer에서 정의

* feat: Event 도메인의 Custom ErrorCode와 Exception 정의

* style: `@RequiredArgsConstructor` 활용

* style: gwt 다듬기

* chore: 실 credential 반영

* fix: presentational layer test에 `@SpringbootTest`를 사용하도록 일괄 변경

* fix: HTTP METHOD 정정 (post -> get)

* feat: QR Login 구현

* chore: build 실패시 artifact로 report 보관

* fix: spring build directory 정정

* fix: CI, application.yml profile 맞춤

* fix: CI, yml 문법

* chore: jacoco 추가

* fix: jacocoTestReport

* Bp 35 implement email sending (#10)

* chore : Spring-mail 의존성 추가

* feat : 이메일, 수신자 엔티티, 레포지토리 생성

* feat : Email전송 컨트롤러 작성

* feat : 이메일서비스 작성

* feat : 이메일 전송 클라이언트 설정, 전송 로직작성

* test : 컨트롤러 테스트 작성

* format : reformat codes indentation 2space로 수정

* feat : 클래스 이름 수정, 연관관계 매핑

* feat : toEntity생성, 적용

* rename : 네이밍 수정

* refactor : 컨벤션에 맞게 의존성 변경

* feat : 기본 트랜잭션 설정 read only로 명시

* refactor : 불필요한 import 제거

* feat : 에러 처리 분기 수정

* test : 이메일 기능 테스트코드 작성

* Bp 27  출석현황조회 api (#11)

* feat: 학과 필드 추가

* feat: `AttendanceInfo` DTO, query 구현

* feat: 출석 현황 조회 Controller & Test

* feat: 출석 현황 조회 Service

* feat: `AttendanceInfo`에 participantId field 추가

* fix: 출석 현황 조회에 멤버 외의 인원이 출석한 경우 error가 발생하지 않도록 수정

* feat: 멤버 출석 현황 수정 기능

* feat: 멤버 출석 현황 수정 controller 작성 및 test

* fix: DTO 전환 과정에서 immutable list로 초기화되어 이후 수정이 불가능했던 문제 해결

* fix: 유효하지 않은 `participantId`의 출석 수정 요청 exception handling

* fix: Event에 이미 출석이 존재할 경우, 중복 생성을 막음

* chore: gradle task `openapi3`, type casting

* style: `MemberToParticipantMapper`에서 `ParticipantMapper`로 이름 변경

* feat: 출석 현황 수정 request payload 형식 변경

* refactor: `Member` To` Participant` Mapping 과정에서 `Member`에 존재하지 않던 `attendance` field를 기본으로 false로 설정

* Bp 36 implement email cancellation (#14)

* feature : EmailTask로 네이밍 변경, VO 생성

* remove : 엔티티이름 변경에 따른 클래스 삭제

* feat : 이메일작업 레포지토리생성

* feature : 이메일 작업등록 관련 에러, 에러코드 추가

* feature : 이메일 작업 수정, 조회, 삭제 로직 추가

* feature : DTO와 Mapper 작성

* test : 컨트롤러 테스트 작성

* feat : 이메일 서비스 작성, 헬퍼 클래스 추가

* test : 이메일 서비스 코드 추가

* refactor : 팀 컨벤션 적용

* refactor : 생성자 접근 범위 조정

* refactor : 엔티티 이름 변경에 따른 수정

* test : 테스트코드 수정

* rename : 이메일 클라이언트에서 발생하는 에러코드로 이름 수정

* test : EmailTask 테스트코드 작성

* Bp 38 retrospect crud api implementation (#12)

* feat: 이벤트 및 회고 등록 기능

* feat: 이벤트 등록 controller 작성 및 테스트

* feat: 이벤트 회고 조회 기능

* feat: 이벤트 회고 조회 controller & 테스트

* feat: 이벤트 회고 수정 기능

* feat: 이벤트 회고 수정 controller 및 test

* refactor: `Retrospect`를 `Event`의 Embedding으로 변경

* fix: `@Valid`를 통한 dto 검증 추가

* Bp 39 implement email scheduler (#15)

* feat : 미전송 작업 조회, 작업완료 메소드 추가

* feat : 미전송 작업 쿼리 추가

* feat : 스케줄러 설정파일 작성

* feat : 작업 정보 메모리 저장소 작성

* feat : 작업 조회 관련 에러 및 코드 추가

* feat : 작업 스케줄러 추가

* feat : DTO에서 entity로 파라매터 수정

* feat : 스케줄 관련 업데이트 적용

* feat : 이메일 전송 로그 추가

* test : 이메일 스케줄 서비스 테스트코드 작성

* refactor : unused import 삭제

* test : 이메일 스케줄링 통합테스트 작성

* feat : 작업 스케줄 서비스 추가

* test : 로직 수정 테스트코드에 반영

* style : 카멜케이스 적용

* feat : 에러코드 정의 변경

* feat : cancel중 다른 스레드 접근 불가능하게 락 적용

* refactor : 함수 네이밍 변경

* refactor : remove save() method

* rename : EmailScheduleServiceTest 이름 수정

* feat : 디스코드 알림 웹 훅을 위한 클라이언트 작성

* feat : RestTemplate 설정파일 작성

* feat : 디스코드 문자열 상수 정의

* feat : 이메일 전송 에러처리 추가

* rename : 위치 수정

* test : 이메일 전송 실패시 디스코드 알림 테스트 추가

* refactor : 에러를 받아서 디스코드 메세지를 만드는 로직을 디스코드 메세지에서 작성

* test : 디스코드 메세지 테스트 작성

* refactor : 반드시 발생하는 상황 finally로 실행부분 변경

* fix : 이메일 저장후 바로 조회 시 조회가 안되는 이슈 수정 (#16)

* fix : 이메일 저장후 바로 조회 시 조회가 안되는 이슈 수정

* fix : 사용하는 메소드 수정에 따른 test코드 모킹 변경

* Bp 37 event crud api implementation (#13)

* chore: aws-s3 모듈 추가

* feat: s3 presigned url 기능

* feat: 당장 불필요한 Member Profile Image 주석처리

* change: 이달의 출석 조회를 `EventController`에서 `AttendanceController`로 이동

* feat: S3 Storage Client

* feat: `EventImages`

* feat: 불필요한 파일 삭제 (`ImageController/Service`)

* feat: `Event` CRUD 기능

* feat: `Event` CRUD Controller

* fix: 일대다 Mapping에서 변경이 전파되도록 수정

* fix: 이미지 URL을 반환하도록 변경

* fix: 이벤트 상세 조회에 Image key를 반환하도록 수정

* fix: 사진 추가를 Optional하게 변경

* fix: 잘못된 에러 메시지 수정 + object key에 확장자 포함

* fix: Spring Security Matcher가 정상 동작하도록 변경 (출석 Entry 수정)

* fix: Spring Security Matcher가 정상 동작하도록 변경 (출석 Entry 수정)

* test: 회원 출석 url 변경 반영

* test: 누락되었던 인증 정보 추가

* test: 이벤트 CRU 테스트

* style: redundant 삭제

* refactor: 혼동을 줄이기 위해 `equals` override

* refactor: 혼동을 줄이기 위해 `equals`를 `isKeyEqual`로 변경

* feat: S3 object URL에 object key가 포함되어 있음!!

* refactor: DTO에 생성 위임

* style: rename(`S3Config` -> `S3Properties`)

* refactor: String format으로 + 연산 줄이기

* fix: S3 property를 제대로 읽어오도록 수정

* fix: 모든 Event 조회에 N+1 문제 해결

* Fix redefine email receivers (#17)

* fix : 이메일 개수가 증가할 시 제한에 걸리는 이슈로 컬렉션 테이블 분리

* feat : 트랜잭션 템플릿으로 새로운 트랜잭션 생성 및 롤백

* fix : Resttemplate Post요청시 URI타입 캐스팅

* Fix: 로그인 성공 후 스태틱 페이지가 없어 발생하는 에러 수정 (#18)

* fix: 로그인 성공 후 스태틱 페이지가 없어 발생하는 에러 수정

* fix: test가 3xx가 아닌 200을 기다리도록 수정

* fix: test가 redirection url을 기대하지 않음

* Fix: error response (#21)

* fix: `BusinessException`을 response 할 때, name 대신 `logMessage`를 반환하던 문제 해결

* fix: 4xx 대신 5xx를 반환하던 문제 해결

* fix: fallback handler의 인자를 `RuntimeException`에서 `Exception`으로 변경

* Fix jpa element collection type (#20)

* fix : List에서 Set으로 자료구조 변경

* feat : EmailReceviers 자료구조 변경 적용

* feat : Set 삭제, 추가 메소드

* feat : 변경전 수신자들과 비교하는 함수 추가

* feat : 시그니처 변경 및 타입수정

* feat : 업데이트된 수신자와 기존 값 비교후 병합메소드 추가

* refactor : optimize imports

* test: 이메일 작업 전송대상 업데이트 필터링 테스트

* Fix: `not found` and `login failure` response (#22)

* fix: 404 응답이 500으로 가던 문제 해결

* fix: 로그인 Content-Type이 `x-www-urlencoded`가 아니어서 회원 정보가 제대로 전달되지 않는 경우의 에러 코드 변경

* fix: 로그인 실패 테스트 입력이 의도와 달랐던 문제 해결

* fix: [dev] CORS 비활성화 (#23)

* feat: 사용자가 로그인 된 상태인지 확인하는 API (#24)

* fix: API에 인증받지 않은 사용자가 요청 시 302 대신 401로 반환하도록 수정 (#25)

* fix: 이벤트 이미지가 없을 경우 이벤트를 조회할 수 없던 문제 해결 (#26)

* fix: 이벤트에 누락된 속성(`장소`) 추가 (#27)

* Refactor attendance api (#28)

* Change: include retrospect into event detail (#29)

* change: 이벤트 조회에 이벤트 회고가 함께 조회되도록 변경

* style: DTO 파일 위치 컨벤션 통일

* feat: Event 삭제 API (#30)

* Fix: cors without nginx (#32)

* feat: cors custom filter

* feat: cors custom filter 적용

* fix: cors allowed origin을 `localhost:*`에서 `localhost:5173`으로 변경 (#33)

* fix: preflight시에 security filter chain을 거치기 전에 성공하도록 수정 (#34)

* Change: attendance registration response (#35)

* style: image upload/delete method 분리

* change: 출석 및 출석 URL 생성 응답에 body 추가

* change: 출석 QR 만료 요청에 QR UUID가 불필요하게끔 수정

* test: 수정 사항 반영

* fix: 출석 URI이 제대로 생성되도록 수정

* Feat: include receiver name into mail registration (#31)

* fix: 확률적으로 실패하던 Test Case 보완

* feat: `EmailReceiver`에 이름 정보가 누락되어 있던 문제 해결

* feat: `{이름}`을 통해 대상 이름을 이메일 양식에 포함할 수 있도록 기능 추가

* test: 수정 사항 반영 (이메일 수신자에 이름 속성 추가)

* refactor: 이름 토큰(`{이름}`)을 상수로 정의, 메서드 분리

* test: 이름 토큰(`{이름}`) 치환 동작 확인 테스트 작성

* Feat: request attendance state (#37)

* feat: Attendance Status 조회 API

* test: Attendance Status 조회 API Test

* fix: CORS 재수정 (`List.of` 대신 `Arrays.asList` 사용) + origin에 개발/배포 서버 추가 (#36)

* change: EmailTask 전체 조회시, 응답 양식을 EmailTaskDetail 양식처럼 `ReceiverInfos`를 묶음으로 표시 (#39)

* Test: use fixture (#38)

* test: Fixture 작성 (`Member`, `Event`)

* change: 멤버 등록 필요 속성 수정

* change: `WithCustomUser` Annotation을 사용하도록 통일, 관리자 권한이 필요한 API일 경우 해당 권한 테스트에 미리 반영

* test: `MemberFixture` 적용

* test: GWT 다듬기

* style: `EmailDetails`가 Entity가 아닐 경우 단일 Data인 점을 반영하여 `EmailDetail`로 이름 변경

* test: Email Fixture 작성

* test: Email Fixture 적용

* style: `given`절의 메서드가 when보다는 given을 사용하도록 변경

* test: `Attendance` Fixture 작성

* test: `Attendance` Fixture 적용

* test: `Event` Fixture 작성

* test: `Event` Fixture 적용

* test: `Controller` Test를 단위 테스트로 전환

* test: EmailFixture 적용

* fix: 이미 인증된 사용자를 통해 로그인 테스트를 하던 문제 해결

* change: 멤버 출석 성공 시 보여주는 정보 축소

* change: 멤버 출석 등록 시 `Role`을 받도록 수정

* feat: feedback 반영, Test Fixture를 좀 더 Verbose 하게

* test: 변경한 Fixture 반영

* chore: test build에 lombok 사용

* Docs: readme (#19)

* docs: readme 초본

* docs: Readme에 다이어그램 추가

* [Draft] Release: `v0.0.0` (#40)

* chore: Dockerfile이 app version에 의존적이지 않도록 수정

* chore: spring actuator 추가

* style: `build.gradle` re-format

* chore: 기본 타임존을 한국으로 설정

* chore: API 접속 권한 조정

* fix: OAuth redirect URL scheme을 https로 변경

* fix: 로그인 요청은 로그아웃 상태에서도 허용하도록 변경

* fix: csrf 비활성화 (Client Side 추가 설정 필요)

* chore: CI를 위해, github action이 h2를 사용하도록

---------

Co-authored-by: ekgns33 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants