feat(search): 가격 분포 facets(searchProductFacets) - #254
Conversation
검색 결과 가격대 필터 시트(figma search 03)의 분포 히스토그램·최저/최고가 대응 (검색 화면 API 4/4). 정책은 문답으로 확정. - searchProductFacets(keyword, eventCategoryIds, styleCategoryIds, regionIds): 가격 조건을 뺀 나머지 검색 조건으로 표시가(sale ?? regular)를 모아 5,000원 고정 폭 버킷(0~70,000) + '70,000원 이상' 버킷으로 센다. 빈 구간도 count 0으로 반환해 FE 막대 자리를 고정. min/max 표시가 동반(없으면 null). - 버킷 폭 5,000원·상한 70,000원은 시안 슬라이더 눈금(2만~7만 이상) 기반 자체 판단(상수). - 'N개 상품보기' 카운트는 searchProducts.totalCount 재사용(별도 API 없음 — 사용자 확정). - 검색 where 빌더를 그대로 재사용해 목록·분포 조건 불일치를 차단. 메모리 집계는 상품 수 소규모 전제(규모 증가 시 SQL FLOOR 그룹핑 전환 여지 주석). 테스트 7건: 버킷 경계(5,000 정확히 상위 버킷·상한 이상), 빈 구간 0, 폭/상한 파라미터, 분포·min/max·건수, 카테고리·지역 반영, 빈 결과, 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 |
🩺 NestJS Doctor — 90/100 (Excellent)진단 288건 (error 0).
architecture / security 상위 항목
|
🧹 knip — dead-code 리포트전체 리포트
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85021e69bd
ℹ️ 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".
| minPrice: prices.length > 0 ? Math.min(...prices) : null, | ||
| maxPrice: prices.length > 0 ? Math.max(...prices) : null, |
There was a problem hiding this comment.
Avoid spreading every matched price into Math.min/max
When a broad facet query matches roughly 125,000 or more products under the deployed Node 24 runtime, Math.min(...prices) and Math.max(...prices) exceed V8's function-argument limit and throw RangeError: Maximum call stack size exceeded, turning this public query into a 500 response. Compute both extrema during the existing iteration/reduction, or aggregate them in the repository, so result cardinality does not determine whether the query succeeds.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
반영: Math.min/max spread를 순회 집계로 교체(V8 인자 한도 방어).
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Coverage report
Test suite run success1772 tests passing in 207 suites. Report generated by 🧪jest coverage report action from 9df3c95 |
Math.min/max(...prices)는 V8 인자 한도(약 12만+)에서 RangeError — 순회 집계로 방어.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9df3c95336
ℹ️ 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".
| } | ||
| return counts.map((count, i) => ({ | ||
| minPrice: i === bucketCount ? max : i * size, | ||
| maxPrice: i === bucketCount ? null : Math.min((i + 1) * size, max), |
There was a problem hiding this comment.
Make bucket bounds match inclusive search filters
When a client uses a bucket's returned maxPrice in SearchProductsInput, the histogram and result count disagree at every boundary: this code defines the bucket as [minPrice, maxPrice) and assigns a 10,000원 product to the 10,000–15,000 bucket, while buildProductSearchWhere applies the search maximum with lte, so the same product is also returned for the 5,000–10,000 selection. Return bounds compatible with the inclusive filter (or change the filter/API contract consistently) so bucket counts match the products shown.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
미반영: 버킷은 가격 슬라이더 배경의 분포 시각화용이지 클릭 필터 계약이 아님(figma 03 — 슬라이더가 임의 min/max를 보내고, 필터바 프리셋 경계는 FE 정의). half-open [min, max)는 히스토그램 표준 규약이고 SDL 주석에 명시됨. 경계 1건의 시각적 오차는 수용, 버킷을 필터 프리셋으로 쓰는 요구가 생기면 그때 계약을 맞춘다.
배경
검색 결과 가격대 필터 시트(figma
search/03)의 가격 분포 히스토그램 + 최저/최고가 대응(검색 화면 API 4/4, 마지막). #253 후속.변경
searchProductFacets(input: { keyword!, eventCategoryIds, styleCategoryIds, regionIds }): 가격 조건을 제외한 검색 조건으로 표시가(sale ?? regular)를 모아 5,000원 고정 폭 버킷(0~70,000) + '70,000원 이상' 버킷으로 카운트. 빈 구간도 0으로 반환(FE 막대 자리 고정).minPrice/maxPrice(결과 없으면 null)·totalCount동반.buildProductSearchWhere) 재사용으로 목록·분포 조건 단일 소스.searchProducts.totalCount재사용(별도 쿼리 없음 — 확정 정책).자체 판단(시안 외)
버킷 폭 5,000원·상한 70,000원(시안 슬라이더 눈금 기반, 상수로 분리). 메모리 집계(소규모 전제, 주석에 전환 여지 명시).
테스트
7건 추가.
yarn validate통과(207 suites).