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

Feature/#170 관리자 관련 api 구현 #185

Merged
merged 18 commits into from
Sep 11, 2024

Conversation

llddang
Copy link
Contributor

@llddang llddang commented Sep 7, 2024

관련 이슈

작업 요약

[BACKEND]

  • 이메일과 이름 입력을 통한 관리자 단일 등록 api 구현
  • 이메일과 이름이 담긴 엑셀파일을 이용한 관리자 다중 등록 api 구현
  • 슈퍼관리자만 가능한 관리자 삭제 api 구현

리뷰 요구 사항

  • 리뷰 예상 시간: 20분
  • 궁금하신 점이 있다면 언제나 물어봐주세요!
  • 코드 스타일 잘못 된 것이 있다면 알려주세용!

@llddang llddang added ✨ 기능 개발 새로운 기능을 구현하는 데 필요한 작업 또는 변경 사항 🌑 백엔드 백엔드 개발 labels Sep 7, 2024
@llddang llddang requested a review from tkschkim September 7, 2024 06:27
@llddang llddang self-assigned this Sep 7, 2024
@llddang llddang requested a review from amaran-th September 7, 2024 06:29
@Value("${password.admin}")
private String password;

@Transactional
Copy link
Contributor

Choose a reason for hiding this comment

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

@Transactional은 Class 단에 붙여주면 하위 메서드에 모두 적용이 됩니다!
그리고 QueryService는 조회만 하는 서비스 클래스이고 CommandService는 수정을 하기 위한 서비스 클래스이니 계정 등록 로직은 CommandService로 분리해서 작성해주시면 좋을 것 같아용

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Transactional을 Class 단에 붙여주지 않은 이유는 사용하지 않는 함수도 있어서 입니다.

file을 이용한 관리자 다중등록일 경우,
일부 실패에 대해 모든 사용자가 등록되지 않는 것보단 성공한 사용자는 등록이 되고 등록되지 않은 사용자의 line number를 알려주는 편이 UX적으로 편리할 것 같습니다.

클래스 명은 바꿨습니다!

public Long registerFaculty(RegisterFacultyRequest request) {
final String encodedPassword = Password.encode(password);

Member member = memberRepository.findByEmail(request.email()).orElse(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

null 객체를 사용하기보단 Optional 객체를 활용하는 편이 더 좋을 것 같습니다!
그리고 개인 취향이긴 한데 전 else if, else를 쓰는 것보다 메서드 분리를 통해 로직을 단순화 시키는 편을 선호합니당 이건 재량껏 반영해주세요!

    final Optional<Member> member = memberRepository.findByEmail(request.email());
    validateDuplicate(member);
    if(member.isPresent()){
        return saveExistFaculty(request.email(), request.name(), member, encodedPassword);
    }
    ...
}

private void validateDuplicate(Optional<Member> member){
    if (member != null && !member.isDeleted()) {
            throw new AdminAuthException(AdminAuthExceptionType.MEMBER_EMAIL_DUPLICATE);
    }
}

@@ -10,6 +10,8 @@
import sw_css.auth.domain.repository.EmailAuthRedisRepository;
import sw_css.auth.exception.AuthException;
import sw_css.auth.exception.AuthExceptionType;
import sw_css.member.domain.Member;
import sw_css.member.domain.repository.MemberRepository;
import sw_css.utils.MailUtil;

@Service
Copy link
Contributor

Choose a reason for hiding this comment

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

레파지토리에 접근하는 모든 서비스에는 @Transactional을 붙여주는 것이 좋습니다!

}
throw new AuthException(AuthExceptionType.MEMBER_EMAIL_DUPLICATE);
Copy link
Contributor

Choose a reason for hiding this comment

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

JPA에는 엔티티 조회 시 특정 조건에 해당되는 엔티티만 조회되도록 필터링하도록 설정할 수 있는 기능이 있습니다!
관련 글
이렇게 일일이 isDeleted()를 검증해주지 않아도 됩니당

Copy link
Contributor

Choose a reason for hiding this comment

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

그리고 그렇게 고친다면 아래처럼 로직을 수정하면 좋을 것 같아용

if(member!= null){
    throw new AuthException(AuthExceptionType.MEMBER_EMAIL_DUPLICATE);
}

String accessToken = jwtTokenProvider.createToken(member.getId(), role);

return SignInResponse.of(member, facultyMember.getId(), role, true, accessToken);
}

throw new AuthException(AuthExceptionType.MEMBER_EMAIL_NOT_FOUND);
throw new AuthException(AuthExceptionType.MEMBER_NOT_REGISTER);
Copy link
Contributor

Choose a reason for hiding this comment

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

가능한 예외 처리 구문은 앞에 두는 것이 로직 흐름을 읽기 편해서 권장되는 컨벤션입니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

네 예외 구문이 바로 앞에 있을 경우 로직 흐름을 읽기 쉬워질 것 입니다.

if (memberDetail instanceof StudentMember studentMember) {
    // something...

} else if (memberDetail instanceof FacultyMember facultyMember) {
    // something...
}

이 위쪽 코드를 보면 위와 같이 경우에 따른 서로 다른 행동을 보이고 있습니다.
그리고 이에 해당하지 않는 구문이 else로 예외를 던지고 있는 형상입니다.

이럴 때 if (!memberDetail instanceof FacultyMember || !memberDetail instanceof StudentMember) 를 하고 밑에 똑같은 과정을 적는것보다 위의 방식이 좀더 효율적이라고 생각됩니다.

또한 예외구문을 던지는 것이 함수의 제일 마지막에 있기 때문에 모든 과정이 이루어지지 않았을 때 예외를 던지도록 되어있구나라고 판단할 수 있을 것이라 생각됩니다.
그리고 if 문 안의 내용일 길다면 예외를 위로 올리는 것이 좋을 것 같으나. 현재 if, else-if, 예외 구문이 14줄로 한 화면에 다 보여서 읽는데 무리가 없어보입니다.

}

@Test
@DisplayName("[성공] 관리자 단중 등록을 할 수 있다.")
Copy link
Contributor

Choose a reason for hiding this comment

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

오타가 있는 것 같습니다!

}

@Test
@DisplayName("[성공] 관리자 단중 등록을 할 수 있다.")
Copy link
Contributor

Choose a reason for hiding this comment

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

관리자를 제거한다고 수정하는 게 좋을 것 같습니다!

@@ -35,6 +36,7 @@ public class Member extends BaseEntity {
@Column(nullable = false)
private String phoneNumber;

@Setter(AccessLevel.PUBLIC)
Copy link
Contributor

Choose a reason for hiding this comment

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

혹시 이 부분 왜 이렇게 설정하셨는지 알 수 있을까요?? 엔티티 id는 엔티티의 고유성을 결정하는 식별자라 함부로 수정하지 않는 것이 일반적이라서요~!(id가 다르면 다른 엔티티로 취급하기 때문에)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

isDeleted 쪽에 코멘트를 달았던데요. id를 말하는 거겠죠?

AdminAuthQueryServicesaveFaculty 부분에서 사용했습니다.

Member member = new Member(email, name, password, "01000000000", false);

final long memberId = memberRepository.save(member).getId();
member.setId(memberId);

위 경우 새롭게 member를 만드는 것보다 id를 입력해주는 것이 낫겠다고 판단했습니다.

- soft delete 에 해당하는 SQLRestriction 사용하기
- 조회를 뜻하는 queryService에서 commandService로 서비스명 수정
#170
@llddang llddang merged commit 27e3700 into develop Sep 11, 2024
2 checks passed
@llddang llddang deleted the Feature/#170-관리자_관련_API_구현 branch September 11, 2024 08:31
llddang added a commit that referenced this pull request Sep 12, 2024
* Feature/#173 깃 액션 빌드조건 변경 (#174)

* feat: 백엔드 조건 변경

#173

* feat: 프론트 조건 변경

#173

* Feature/#175 test 및 application 수정 (#176)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* Feature/#175 test 및 application 수정 (#178)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* feat: application test 주석처리

#175

* Feature/#182 출시이후 기능 안보이도록 수정 (#183)

* RELEASE (#177)

* Feature/#173 깃 액션 빌드조건 변경 (#174)

* feat: 백엔드 조건 변경

#173

* feat: 프론트 조건 변경

#173

* Feature/#175 test 및 application 수정 (#176)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* release (#179)

* Feature/#173 깃 액션 빌드조건 변경 (#174)

* feat: 백엔드 조건 변경

#173

* feat: 프론트 조건 변경

#173

* Feature/#175 test 및 application 수정 (#176)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* Feature/#175 test 및 application 수정 (#178)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* feat: application test 주석처리

#175

* Develop (#180)

* Feature/#173 깃 액션 빌드조건 변경 (#174)

* feat: 백엔드 조건 변경

#173

* feat: 프론트 조건 변경

#173

* Feature/#175 test 및 application 수정 (#176)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* Feature/#175 test 및 application 수정 (#178)

* feat: config 폴더 업데이트

#175

* feat: application 수정

#175

* feat: test 주석 처리

#175

* feat: config submodule 업데이트

#175

* feat: application 수정

#175

* feat: application test 주석처리

#175

* fix: mixed-content 에러 해결

* feat: 메인 페이지의 마일스톤 api 연결 및 mock 데이터 삭제

#182

* refactor: 서버 api 구조 변경

#182

* feat: test-data.sql의 데이터 수정

#182

* feat: config submodule 폴더 최신화

#182

* feat: 메인페이지의 외부 링크 변경

#182

* feat: 해커톤 개발중인 기능이라고 표시

#182

* feat: 팀 빌딩 구현 중인 기능으로 표시

#182

* feat: title 의 제목 글씨 크기 28px 로 축소

#182

* feat: 관리자 페이지로 이동할 수 있는 버튼 생성

#182

* feat: 메인 페이지의 외부 링크 명 변경

#182

* Feature/#170 관리자 관련 api 구현 (#185)

* feat: 관리자 계정들의 id 자동 생성되도록 수정

#170

* feat: super admin 어노테이션 구현

#170

* feat: 관리자 계정의 어노테이션 구현

#170

* feat: 관리자 단일 등록 api 구현

#170

* feat: Admin & SuperAdmin annotation 등록

#170

* feat: config 폴더 최신화

#170

* feat: 파일을 이용한 교직원 등록 api 구현

#170

* feat: 교직원 탈퇴 api 구현

#170

* feat: 로그인 할 때 deleted 된 사용자인지 검증하는 로직 추가

#179

* feat: 이메일 및 전화번호 중복확인 api 삭제

#170

* feat: 회원가입 및 이메일 인증시 탈퇴한 회원인지 확인하는 로직 추가

#170

* feat: 로그인 관련 회원을 찾지 못할 때의 문구 수정

#170

* feat: 교직원 단일/다중 등록 시 deleted 된 회원인지 검증하는 로직 추가

#170

* refactor: 관리자 등록 및 삭제 api의 컨트롤러 명 수정

#170

* refactor: 관리자 권한 관련 컨트롤러 명 수정

#170

* feat: 관리자 등록/삭제 관련 api test 코드 작성 및 rest docs 작성

#170

* refactor: 코드리뷰 반영

- soft delete 에 해당하는 SQLRestriction 사용하기
- 조회를 뜻하는 queryService에서 commandService로 서비스명 수정
#170

* refactor: 코드리뷰 반영

- setter 삭제
#170

* Feature/#186 마일스톤 권한 설정 (#187)

* refactor: jwt argument Resolver 명 변경

#186

* refactor: jwt annotation 명 수정

#186

* refactor: jwt annotation 명 수정

#186

* feat: student argument resolver 추가

#186

* feat: 마일스톤 등록 시, 해당 회원 권환 확인

#186

* feat: 학생만 마일스톤 삭제할 수 있도록 권한 설정

#186

* feat: 마일스톤 조회 권한 설정

#186

* feat: 마일스톤 점수 조회 api 불러오는 것 권한 설정

#186

* feat: 관리자의 마일스톤 권한 설정

#186

* feat: 프론트 오류 수정 및 api 에 authentication 추가

#186

* feat: api 호출 시 Authorization 붙여서 보내도록 수정

#186

* fix: page 폴더 바깥에서 next/header 사용할 수 없어서 직접 token 넣어주도록 변경

#186
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.

[BACK] 관리자 관련 API 구현
2 participants