feat(user): 찜 목록 카드 확장(매장별 필터·평점·할인율)과 매장별 그룹 조회 - #214
Conversation
찜 화면 시안(상품 찜 목록·매장별 보기) 기준. 상품 카드에 지역 뱃지·상품 평점(리뷰 수)·할인율을 표시하고, '매장별 보기'는 찜 상품을 매장 단위로 묶어 프로필·찜 상품 수를 보여준다. 스펙 문서가 없어 정책은 사용자 문답으로 확정했다. 정책 결정(시안 외, 사용자 확정): - 특정 매장의 찜 상품 화면은 별도 쿼리 대신 MyWishlistInput.storeId 옵션 필터로 처리. - 매장 그룹 정렬은 찜 상품 수 desc, 동점 시 최근 찜 순. - 상품 평점은 리뷰 없으면 0.0/0건, 소수 첫째 자리 반올림(매장 평점 표기와 동일). - 할인율은 서버 제공(discountRate 0~100) — PopularCake 등 기존 카드 컨벤션과 통일. - 가시성(비활성·삭제 상품/매장 제외)은 기존 visibleWishlistWhere를 그룹핑에도 공유해 상품 찜 목록 totalCount와 그룹 카운트 합이 일치한다. 변경점: - SDL: WishlistItemSummary에 storeId·discountRate·regionLabel·ratingAverage·reviewCount 추가, MyWishlistInput에 storeId 추가, myWishlistStoreGroups 쿼리·타입 신설 - UserRepository: visibleWishlistWhere에 storeId 필터, findWishlistItems select 확장, findVisibleWishlistItemsForGrouping 신설 (WishlistItem에 store_id가 없어 groupBy 불가 → 최소 필드 조회 후 service 그룹핑, 찜은 사용자당 소규모 전제) - UserWishlistService: 카드 매핑 확장(aggregateProductReviewStats·calcDiscountRate· buildRegionLabel 재사용), myWishlistStoreGroups 구현 - product 배럴에 calcDiscountRate 공개(기존 aggregateProductReviewStats는 그대로 재사용) 회귀 테스트 11건: - service 8: 카드 필드 매핑 / 평점 0건 / storeId 필터 / 그룹 집계·정렬 / 동점 최근 찜 순 / 가시성 일치(그룹 합 == 목록 totalCount) / 그룹 페이지네이션 / 빈 목록 - resolver 통합 1: myWishlistStoreGroups 전체 경로 - input spec 2: storeId 검증 + 상속 페이지네이션 Claude-Session: https://claude.ai/code/session_01KfiGgWooJdsa4iPQPmqvBj
PR #213 Codex 리뷰(매장 찜 동일 이슈 2건)를 상품 찜에도 반영. - soft-delete 복원 시 created_at이 최초 찜 시점으로 남아 '찜 최신순' 정렬과 addedAt 표기가 재찜을 반영하지 못하는 문제 수정. - 단, active 찜에 대한 중복 요청(더블 탭·재시도)은 created_at을 건드리지 않도록 복원(updateMany, deleted_at != null)과 신규 생성(create + P2002 멱등 처리)을 분리. 회귀 테스트 2건: 재찜 상품 최상단 정렬 / 중복 추가 시 created_at 불변. Claude-Session: https://claude.ai/code/session_01KfiGgWooJdsa4iPQPmqvBj
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🧹 knip — dead-code 리포트전체 리포트
|
🩺 NestJS Doctor — 89/100 (Good)진단 283건 (error 0).
architecture / security 상위 항목
|
Coverage report
Test suite run success1635 tests passing in 190 suites. Report generated by 🧪jest coverage report action from aaf5d9a |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
feat(user): 찜 목록 카드 확장(매장별 필터·평점·할인율)과 매장별 그룹 조회
배경
찜 화면 시안 중 상품 찜 목록·매장별 보기·매장별 찜 상품 화면의 백엔드 API입니다.
기존
myWishlist카드에는 지역·평점·할인율·매장 ID가 없었고, 찜 상품을 매장 단위로 묶어 보는 API도 없었습니다.PR #213(매장 찜 목록 +
Store.profile_image_url)에 이어지는 작업으로, 매장별 보기 행의 프로필 이미지는 그 컬럼을 사용합니다.스펙 문서가 없는 화면이라 정책은 사전에 사용자 문답으로 전부 확정했습니다.
주요 결정 사항
MyWishlistInput.storeId옵션 필터로 처리.카드 구성이 상품 찜 목록과 완전히 동일해 응답 타입과 매핑을 재사용합니다.
myWishlistStoreGroups)은 찜 상품 수 desc, 동점 시 최근 찜 순.WishlistItem에는store_id가 없어(product 경유) Prisma groupBy로 매장 단위 집계가 불가능합니다.최소 필드만 조회해 service에서 그룹핑했습니다(찜은 사용자당 소규모 전제, 근거는 코드 주석에 남겼습니다).
visibleWishlistWhere를 그룹핑에도 공유.상품 찜 목록 totalCount와 그룹 카운트 합이 항상 일치합니다(회귀 테스트로 고정).
aggregateProductReviewStats(product),calcDiscountRate(product 배럴에 공개),buildRegionLabel(store 배럴).리뷰 없으면 0.0/0건, 소수 첫째 자리 반올림 — 매장 카드 표기와 동일 정책입니다.
soft-delete 복원 시에만 created_at을 재찜 시점으로 갱신하고, active 찜 중복 요청(더블 탭·재시도)은 건드리지 않습니다.
검증
yarn validate통과 (190 suites / 1,635 tests).