몬그로이

팀프로젝트 3~5일차 본문

Dev입성기/Dev 입성기 _전기

팀프로젝트 3~5일차

Mon Groy 2024. 6. 25. 07:58

오전: Entity, package 구성 설정, Entity 필드값과 연관관계 설정

오후: Git push test

log 와 주석 사용에 규칙 정하기

 

정적 팩터리 메서드와 빌더 패턴

 

@Builder

Entity 에서는 자제

,responseDto 생성자 대신 빌더패턴 이용


매장 등록 메서드 구현

매장 정보 수정 메서드 구현 및 수정 - 확실히 시간이 덜 걸렸다

 

repository에 접근하는 메서드 명명법 정의

메서드 명이란 단순히 "알아보기 편한" 것이라고 생각했는데

팀끼리 규칙을 정해 find 와 query 로 나눠서 그에 맞춰 짓기도 한다는 사실을 알았다


DDD 구조로 Admin만 사용할 수 있는 기능들을 추가하려니 난관에 봉착했다

각 기능들의 controller 를 각각 만들 것인지, 아니면 한 군데에 묶어서 만들 것인지

 

https://blog.naver.com/626ksb/223267256184

 

생성자와 Builder 패턴

생성자를 통해서만 인스턴스를 생성하면 어떤 문제가 있을까? 만약 Person 에 address 라는 필드가 추가됐...

blog.naver.com

 

repository 에서 찾은 User를 @Builder를 적용해서 ResponseDto 객체를 채워 List로 반환하려고 했더니

.map() 에서는 생성자로 적용해야 한다고 한다

.findAll().stream()
        .map(AdminUserResponseDto::new)

를 적용하기 위해서 .map 이 수용할 수 있는 방식의 생성자

즉, builder 방식이 아닌 생성자가 필요하다

 

그런데 Dto에 @AllArgsConstructor 를 달아줬는데더 불구하고 작동하지 않았다

그래서 IntelliJ 를 Run 했고, 원인이 나왔다

 

error: incompatible types: invalid constructor reference .map(AdminUserResponseDto::new).toList();
                                                                                                    ^ constructor AdminUserResponseDto in class AdminUserResponseDto cannot be applied to given types
required: Long,String,String,String,String,String,UserStatus,UserRole
found: User reason: actual and formal argument lists differ in length

 

User 를 넣어 만드는 생성자가 없다는 것이다

userRepository 에서 모든 객체를 찾아올 때는 기본적으로 user 로 나오기 때문에 User를 받아서 Dto 에 넣어야 하는 것


Admin 기능 중 회원 전체 조회를 구현하였다

후에 paging 기능 적용 후 PR 하였고

 

" Page 는 상속을 받고 있으므로 가지고 있는 정보가 많으므로 그 정보들 중에서 필요한 것만 추려서 가지고 있는 page 객체를 만들고, Dto 에 딱 그 정보만 담아서 보내줄 것"

라는 feedback 을 받았다

 

거의 3시간정도 걸려서 완성했다

Run 은 정상이기에 postman으로 테스트해보고자 했는데

회원가입시 에러가 발생했다

 

비밀번호 pattern 설정의 간단한 에러여서 고쳤는데

500에러가 떠버렸다.. 팀장님과 얘기한 결과 내일 마저 하기로 결정되었다

 

다음날 dev 업그레이드와 머지를 하고, 정신을 차리고 나니

팀원 중 한 분이 페이징 처리를 해 놓은 것을 발견할 수 있었다

이해를 하고 나니

아직 응용력이 부족하다는 사실을 잘 알 수 있었다


현재 우리 팀 프로젝트에서 OrderList 를 불러올 수 있는 방법은 세 가지가 있다

첫 번째, userId 사용

두 번째, storeId 사용

세 번째, maganerId 사용

그 중에서 나는 storeId 를 선택했다

 

user 는 USER, MANAGER, ADMIN 으로 분류 된다

첫 번째 이유로 store 는 managerId 가 FK 로 들어가 있기 때문이고

두 번째 이유는 storeId 는 store 만 사용하기 때문이다

세 번째 이유는 모든 유저 중에서 찾기보다

전체 유저 중 일부인 manager만 storeId 를 갖기 때문에 탐색에 시간이 덜 걸린다

 

더보기

-> 고군분투 하던 와중 나중에 필요에 의해 팀원분이 연관관계를 수정하여

다 만들어 둔지 얼마 안 된 것의 코드를 수정해야만 했다

아쉽지만 팀프로젝트니까 떠나보내 주었다

아직까지는 많이 작성해본 코드가 적기에 지우는 순간이 오자 아쉬움이 크게 느껴졌다

힘들게 짜낸 부분이기에 그런지도 모르겠다


코드 작성이 어느정도 끝나고 마무리 준비를 위해서 Admin 권한도 추가하고

로직에도 Admin 검증 설정을 추가했다

그러다가

@PreAuthorize("hasRole('ADMIN')")

이라고 하는 어노테이션을 알게 되었는데

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + userRole.getUserRoleName()));
}

라고 설정해 두면 알아서 확인진행이 되는 기능을 가지고 있다고 한다

팀에 이야기 하니, 팀장님은 알고 계셨고, 팀원들과 함께 이야기하여 사용하기로 결정하였다


    public List<ReviewPerStoreResponseDto> getReviewListPerStore(
            AuthenticationUser authenticationUser, Long storeId, Integer pageNum, String sortBy, Boolean isDesc) {

        //(ADMIN 권한의) 유저 Status 가 ENABLE 인지 확인
        adminUserStatusCheck(authenticationUser);

        //storeId 로 order 찾기
        Pageable pageable = PageUtil.createPageable(pageNum, PageUtil.PAGE_SIZE_FIVE, sortBy, isDesc);

        //storeId 와 OrderStatus.DELIVERY_COMPLETED 로 orderList 가져오기
        List<Order> deliveredOrderList = orderAdaptor.queryOrderListByStoreIdAndOrderStatus(storeId, OrderStatus.DELIVERY_COMPLETED);

        //orderId를 for 문 돌려서 하나씩 userReviews 찾아 responseDto 에 담기 -> List 화 (orderId : userReview = 1:1)
        List<ReviewPerStoreResponseDto> reviewDtoList = new ArrayList<>();

        //userReview 는 배송완료된 주문 건의 id 로 찾아본 결과 나오는 것만 가지고 오기 때문에
        // userReview 객체가 비어있을 수가 없음 (userReview 가 생성된 순간 id 와 내용물이 생성되기에)
        // 따라서 userReview 는 null 따질 필요 없음
        // userReview 와 managerReview 모두 null 인 경우 수행하지 않고 다음으로 넘어간다.
        // -> 만약 유저리뷰나 그것에 달린 판매자댓글이 삭제되더라도 status 만 변경하기 때문에 id 는 살아있고, 삭제여부 파악가능함
        for (Order deliveredOrder : deliveredOrderList) {
            UserReviews userReview = deliveredOrder.getUserReviews();

            if (userReview.getManagerReviews().getId() == null) {
                continue; // 이러면 안 되는데?? 판매자 댓글이 없으면 다시 올라간다는 말은 Dto 를 만들지 않겠다는 것
                // 따라서 Dto 를 두 가지 버전으로 만들어야 함!!
            }

            ReviewPerStoreResponseDto ReviewResponseDto = ReviewPerStoreResponseDto.of(storeId, userReview);
            reviewDtoList.add(ReviewResponseDto);
        }

        return reviewDtoList;

null에 대한 이해가 부족했는데 이번 경험을 통해  알게 되었다

null인 경우 화면에 띄우지 않아도 될텐데 왜 적는 걸까 하고 항상의문이었는데,

굳이 'null' 이라고 사용 하는 이유는 백엔드가 예외를 띄워서 프로그램을 멈추도록 하는 것 말고

처리할 수 있는 또 다른 한 가지 방법이기 때문이고

화면에 띄우고 말고는 UI 로 결정되는 부분이기 때문인 것이다

'Dev입성기 > Dev 입성기 _전기' 카테고리의 다른 글

KPT 회고  (0) 2024.06.25
미리 작성하는 프로젝트 소감  (0) 2024.06.25
현재 상태  (0) 2024.06.18
벽이 반쯤 허물어진  (1) 2024.06.07
AFTER 숙련주차 개인과제  (0) 2024.05.31