Skip to content

feat: 매장 선택(메인 검색 결과) pickupStores 쿼리 추가 - #532

Merged
chanwoo7 merged 1 commit into
developfrom
feat/pickup-stores
Oct 15, 2026
Merged

chanwoo7 merged 1 commit into
developfrom
feat/pickup-stores

Conversation

@chanwoo7

Copy link
Copy Markdown
Member

요약

  • 홈 메인 검색(지역·픽업 날짜·시간 → "검색하기")의 결과인 "매장 선택" 화면에 맞는 API가 없었습니다.
    • FE는 todayPickupStores로 임시 연결해 두어서, 오늘 외 날짜는 안내 문구만 띄우고 시간은 클라이언트에서 거르며 지도 마커와 정렬은 비어 있었습니다.
  • pickupStores(input: PickupStoresInput!): PickupStoreConnection!을 추가합니다(비로그인 가능).
    • 입력: date(필수, "YYYY-MM-DD" KST), time(선택, "HH:mm"), regionIds, sort(#531의 StoreSort, 기본 인기순), offset/limit(≤50)
    • 항목: StoreCard + latitude/longitude(지도 마커, 미설정 null). 시안 카드에 없는 슬롯 배열은 싣지 않습니다.
  • 판정 규칙
    • 시간을 주면 그 슬롯이 정확히 예약 가능한 매장만 남깁니다(영업시간·리드타임·capacity·휴무 반영). 생략·null이면 그날 슬롯이 하나라도 있는 매장입니다.
    • 형식 오류는 INVALID_DATE/INVALID_TIME_VALUE, 오늘보다 앞선 날짜는 신규 PICKUP_DATE_PAST(400)입니다.
    • 정책 상한(MAX_DAYS_AHEAD 365일)을 넘는 날짜는 조회 없이 빈 결과입니다. 매장별 max_days_ahead를 넘으면 그 매장만 빠집니다.
  • 중복 제거
    • todayPickupStores에 있던 "후보 × 하루 → 예약 가능 매장" 판정(벌크 조회 4회 + evaluatePickupDay)을 StorePickupAvailabilityService.openSlotsOn으로 분리했습니다.
    • todayPickupStores도 이것을 오늘 날짜로 호출합니다. 동작은 그대로이고 기존 spec이 수정 없이 통과합니다(provider 추가만).
    • 좌표 변환은 store-detail 매퍼의 toCoordinate를 export해 재사용합니다.

테스트

  • store-pickup-stores.service.spec 20건
    • 날짜 판정: 요일 휴무·영업시간 미설정·다른 요일·특별휴무·capacity 소진·max_days_ahead·리드타임·오늘 날짜·365일 초과
    • 시간 필터: 정확 일치, 슬롯 간격이 다른 매장, 격자 밖 시각(16:15), 리드타임으로 마감된 슬롯, 생략·null
    • 입력 검증 표 9건(날짜 형식 3·지난 날짜 1·시간 형식 5)
    • 정렬(지정·기본 인기순), 지역·offset/limit·totalCount·hasMore, 좌표 null
  • store-pickup-stores-query.resolver.spec 2건: 찜 여부, 비로그인
  • 반증: 시간 필터 제거·available 무시·과거 검사 제거·날짜 무시·좌표 제거·sort 무시 6가지가 모두 실패로 잡힙니다.
  • pre-push 전체 jest 386 suites / 4293 tests 통과

플랜 대조

플랜 PR 2 불릿 상태
pickupStores 쿼리·PickupStoresInput(date 필수·time 선택·regionIds·sort·offset/limit) 한 것
PickupStoreConnection·PickupStoreItem { store, latitude, longitude } 한 것
오늘 픽업 판정을 날짜 인자 공용 메서드로 분리, todayPickupStores가 재사용(동작 불변) 한 것: StorePickupAvailabilityService.openSlotsOn
흐름(검증 → 후보 → 그날 판정 → 시간 필터 → 정렬 → 페이지 → 카드+좌표) 한 것
날짜 상하한 한 것: 연도 범위 상수 대신 정책 상한(MAX_DAYS_AHEAD) 초과 시 빈 결과로 처리했습니다. 그 이상의 날짜는 어느 매장도 열릴 수 없어 같은 결과이고, 극단 연도의 DB 경계 문제도 함께 피합니다.
좌표 조회 한 것: 후보 select에 포함(별도 쿼리 없음)
PICKUP_DATE_PAST(400) 추가 한 것
service spec(날짜·시간·검증·정렬·페이지·좌표), resolver spec, todayPickupStores 회귀 한 것

홈 메인 검색(지역·픽업 날짜·시간 → 검색하기) 결과인 매장 선택 화면에 맞는 API가 없어 FE가 todayPickupStores로 임시 연결 중이었음(오늘 외 날짜 미지원, 시간은 클라이언트 필터, 지도 마커 없음, 정렬 미전달).

- SDL: pickupStores(input: PickupStoresInput!): PickupStoreConnection!(비로그인 가능)
  - date 필수("YYYY-MM-DD" KST), time 선택("HH:mm"), regionIds, sort(StoreSort, 기본 인기순), offset/limit(≤50)
  - 항목은 StoreCard + latitude/longitude(지도 마커, 미설정 null). 슬롯은 싣지 않음(시안 카드에 없음)
- 시간 필터: 그 슬롯이 정확히 예약 가능한 매장만(영업시간·리드타임·capacity·휴무 반영). 생략·null이면 그날 슬롯이 하나라도 있는 매장
- 검증: 형식 오류 INVALID_DATE / INVALID_TIME_VALUE, 오늘보다 앞선 날짜는 신규 PICKUP_DATE_PAST(400). 정책 상한(MAX_DAYS_AHEAD 365일)을 넘으면 조회 없이 빈 결과
- StorePickupAvailabilityService.openSlotsOn: todayPickupStores에 있던 "후보 × 하루 → 예약 가능 매장" 판정(벌크 조회 4회 + evaluatePickupDay)을 날짜 인자로 분리. todayPickupStores도 이것을 오늘로 호출(동작 불변)
- 후보 select에 좌표 추가, toCoordinate를 store-detail 매퍼에서 export해 재사용

테스트
- store-pickup-stores.service.spec 20건: 날짜 판정(요일 휴무·미설정·다른 요일·특별휴무·capacity·max_days_ahead·리드타임·오늘), 시간 필터(정확 일치·격자 밖·리드타임 마감·생략/null), 입력 검증 표 9건, 정렬·지역·페이지·좌표
- store-pickup-stores-query.resolver.spec 2건(찜 여부·비로그인)
- 오늘 픽업 service·resolver spec은 provider만 추가하고 그대로 통과
- 반증: 시간 필터 제거·available 무시·과거 검사 제거·날짜 무시·좌표 제거·sort 무시 6가지 모두 실패로 잡힘
@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: CaQuick/caquick-be/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 656d554d-25da-4486-9626-909ccf7866fe

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-15T09:09:18.126196Z fb09834 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown

🧹 knip — dead-code 리포트

Unused exported types (1)
전체 리포트
Unused exported types (1)
RateLimitPolicy  type  src/global/rate-limit/index.ts:4:8

청소 후보(오탐 가능) · 기준 docs/guide/architecture-conventions.md

@github-actions

Copy link
Copy Markdown

🩺 NestJS Doctor — 90/100 (Excellent)

진단 486건 (error 12).

Category error warning info
architecture 1 1 44
correctness 0 268 0
performance 0 36 28
schema 0 0 76
security 11 21 0
architecture / security 상위 항목
  • error architecture/architecture/no-manual-instantiation: Manual instantiation of 'OutboxRepository' detected. Use dependency injection instead.
  • info architecture/architecture/no-barrel-export-internals: Barrel file re-exports internal type 'IAuditLogRepository'.
  • warning security/security/no-exposed-env-vars: Direct 'process.env.NODE_ENV' access in 'AuthController'. Use ConfigService instead.
  • warning security/security/require-guards-on-endpoints: Endpoint 'start' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'callback' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'refresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'logout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerLogin' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerRefresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerLogout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'devIssueToken' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminLogin' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminRefresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminLogout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'getJwks' has no @UseGuards() at class or method level.

오탐 포함 가능 · 기준 docs/guide/architecture-conventions.md

@github-actions

Copy link
Copy Markdown

Coverage report

St.❔
Category Percentage Covered / Total
🟢 Statements
98.02% (+0.01% 🔼)
10791/11009
🟢 Branches
92.95% (+0.04% 🔼)
4112/4424
🟢 Functions
97.55% (+0.01% 🔼)
2150/2204
🟢 Lines
98.59% (+0.01% 🔼)
9818/9958
Show new covered files 🐣
St.❔
File Statements Branches Functions Lines
🟢
... / store-pickup-stores-query.resolver.ts
100% 100% 100% 100%
🟢
... / pickup-stores.input.ts
100% 100% 100% 100%
🟢
... / store-pickup-stores.service.ts
100% 100% 100% 100%
🟢
... / store-pickup-availability.service.ts
100% 100% 100% 100%

Test suite run success

4292 tests passing in 386 suites.

Report generated by 🧪jest coverage report action from fb09834

@chanwoo7
chanwoo7 merged commit a10f5a2 into develop Oct 15, 2026
17 checks passed
@chanwoo7
chanwoo7 deleted the feat/pickup-stores branch October 15, 2026 09:11
@codecov

codecov Bot commented Oct 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant