feat(search): 실시간 판매 Best와 검색 진입 배너 - #252
Conversation
검색 진입 화면(figma search 05) '실시간 판매 Best' 리스트와 인기 검색어 아래 배너 슬롯 대응
(검색 화면 API 2/4). 정책은 문답으로 확정.
- realtimeBestCakes(limit=10, 최대 20): 최근 24시간 유효 주문(RANKING_VALID_ORDER_STATUSES —
인기 점수와 동일, SUBMITTED 제외는 프로덕션 관행 근거로 사용자 확정) OrderItem.quantity 합
desc. 판매 0건 제외(데이터 적으면 빈 목록), 동률은 인기 점수 → 리뷰수 → id desc(자체 판단).
실시간 집계, rankedAt=호출 시각. 카드는 PopularCake 타입 재사용.
- 랭킹·카드 규칙은 product feature(ProductBestSellerService)에 두고 search feature가
배럴로 소비. ProductRepository.aggregateProductSoldQuantities 추가(판매순 정렬도 공유 예정).
- searchBanner: BannerPlacement.SEARCH 추가(마이그레이션) + placement=SEARCH 배너 1건,
없으면 null(홈 배너와 동일, fallback 없음). findHomeBanner의 활성·기간·링크 대상 활성
조건을 findFirstBanner로 공용화.
- 셀러 배너 SDL/DTO/출력 타입에 SEARCH 지면 추가(등록 가능하도록).
- 시드: SEARCH 배너 1건([SEED] 제목 prefix로 resetSeedScope 정리).
테스트 11건: 수량 합 정렬·rank, 판매 0 제외, 24h/취소·접수/삭제 주문 제외, 비활성 상품·매장
제외, 동률 인기 점수, limit 상한, 카드 필드, 배너 정렬·기간·비활성·링크 대상 제외, resolver 통합.
|
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 — 90/100 (Excellent)진단 281건 (error 0).
architecture / security 상위 항목
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7a649ad186
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| 'HOME_SUB', | ||
| 'CATEGORY', | ||
| 'STORE', | ||
| 'SEARCH', |
There was a problem hiding this comment.
Accept SEARCH in the placement converter
When a seller creates a banner with the newly exposed SEARCH placement, DTO validation succeeds but SellerBannerService.toBannerPlacement() handles only the four older values and throws INVALID_BANNER_PLACEMENT; updates to SEARCH fail through the same path. As a result, production users cannot configure the new search banner through the seller API, so the converter must map SEARCH to BannerPlacement.SEARCH.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
반영: toBannerPlacement에 SEARCH 매핑 추가 + 생성 테스트(placement=SEARCH) 1건.
Coverage report
Test suite run success1729 tests passing in 200 suites. Report generated by 🧪jest coverage report action from 0a6f12f |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a6f12f270
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (raw === 'HOME_SUB') return BannerPlacement.HOME_SUB; | ||
| if (raw === 'CATEGORY') return BannerPlacement.CATEGORY; | ||
| if (raw === 'STORE') return BannerPlacement.STORE; | ||
| if (raw === 'SEARCH') return BannerPlacement.SEARCH; |
There was a problem hiding this comment.
Associate linkless SEARCH banners with their creating store
When a seller creates the newly supported SEARCH banner with the default linkType: NONE (the added creation test exercises exactly this input), both link_store_id and link_product_id remain null. SellerRepository.listBannersByStore() and findBannerByIdForStore() only recognize banners through one of those links, so the banner immediately disappears from the seller's list and all subsequent update/delete calls return not found, while findSearchBanner() continues exposing it globally. Persist an explicit owner/store association or require an ownership-bearing link before accepting this placement.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
미반영(기존 설계): 셀러 배너 소유권을 link_store_id/link_product_id로 판정하는 구조는 이 PR 이전부터이며, HOME_MAIN + linkType NONE/URL/CATEGORY 배너도 동일하게 셀러 목록에서 보이지 않음. SEARCH 지면은 CATEGORY/HOME_MAIN과 같은 운영 등록 전제(링크 없는 지면 배너는 운영이 등록). 배너 owner 컬럼 분리는 지면 배너 전반의 별도 과제로 기록.
배경
검색 진입 화면(figma
search/05) '실시간 판매 Best' 리스트 + 인기 검색어 아래 배너 슬롯 대응(검색 화면 API 2/4). #251 후속.변경
realtimeBestCakes(input: { limit = 10, 최대 20 }): 최근 24시간 유효 주문(RANKING_VALID_ORDER_STATUSES, 인기 점수와 동일 상태 집합)OrderItem.quantity합 desc. 판매 0건 제외, 동률은 인기 점수 → 리뷰수 → id desc. 실시간 집계,rankedAt= 호출 시각. 카드는PopularCake재사용.ProductBestSellerService)에 두고 search feature가 배럴로 소비.aggregateProductSoldQuantities는 후속 판매순 정렬도 공유.searchBanner:BannerPlacement.SEARCH추가(마이그레이션) + placement=SEARCH 배너 1건, 없으면 null.findHomeBanner의 활성·기간·링크 대상 활성 조건을findFirstBanner로 공용화.자체 판단(시안 외)
판매 0건 제외, 동률 인기 점수 해소.
테스트
11건 추가.
yarn validate통과(200 suites).