Skip to content

feat: 매장 선택 결과에 선택 지역 지도 범위 추가 - #542

Merged
chanwoo7 merged 1 commit into
developfrom
feat/pickup-stores-region-bounds
Oct 22, 2026
Merged

chanwoo7 merged 1 commit into
developfrom
feat/pickup-stores-region-bounds

Conversation

@chanwoo7

Copy link
Copy Markdown
Member

개요

매장 선택(메인 검색 결과) 화면이 검색한 지역으로 지도를 옮길 수 있도록 pickupStores 응답에 선택 지역의 지도 범위(regionBounds)를 싣습니다.

  • FE 화면은 URL의 regionIds만 가지고 있고, ID로 지역을 조회하는 쿼리가 없습니다. 그래서 Region 타입에 좌표를 여는 대신 이미 호출하는 응답에 담았습니다.
  • 지역 하나, 같은 1차 안의 여러 지역, 1차 '전체'(하위 2차 ID 전부)가 모두 "2차 ID 묶음"이라 계산 하나로 처리됩니다. 1차 지역 좌표는 만들지 않았습니다.

변경 사항

  • SDL: PickupStoreConnection.regionBounds: MapBounds(south·west·north·east)를 추가했습니다. 필드 추가라 FE 파괴적 변경은 없습니다.
    • 선택한 2차 지역 중심 좌표들의 외곽이며, 지역이 하나면 한 점입니다.
    • 전국(regionIds 비움)이거나 좌표가 있는 2차 지역이 없으면 null입니다.
    • 매장이 0건이거나 예약 가능 기간 상한을 넘는 날짜여도 내려갑니다.
  • repository: StoreRepository.findRegionCenters를 추가했습니다.
    • 2차 지역만 읽고, 활성 여부는 매장 후보 조건(region_id IN …)과 같게 보지 않습니다.
    • Region·Store는 같은 catalog 서비스라 read-boundary 허용 목록은 늘지 않았습니다.
  • 좌표 데이터: 2차 83곳의 중심 좌표를 카카오 주소 검색의 시군구 대표점으로 채웠습니다.
    • scripts/fill-region-centers.ts가 좌표가 없는 항목만 채우고, 받은 좌표를 coord2regioncode로 되돌려 같은 시군구인지 역검증합니다. 하나라도 어긋나면 파일을 쓰지 않습니다.
    • 시드 JSON과 시드 upsert에 반영했고, 생성기(generate-region-seed.ts)는 다시 만들 때 좌표를 slug로 이어받습니다.
  • 데이터 마이그레이션 region_center_coordinates: 시드를 돌리지 않는 운영 DB를 채웁니다.
    • 좌표가 빈 2차 행만 slug로 채우므로 관리자가 넣은 값은 보존됩니다.
    • 빈 DB에서는 아무 행도 바꾸지 않고, 비활성인 옛 인천 3개 구는 null로 남습니다.

검증

  • 테스트
    • service 6건: 한 점, 여러 지역, 좌표 누락, 전국, 1차·삭제·비활성 지역, 매장 0건·상한 초과
    • resolver 1건: 전체 경로에서 regionBounds가 실리는지
    • 마이그레이션 4건: 시드와 83건 일치, 반증(값 하나를 바꾼 SQL은 그 지역만 어긋남), 기존 값 보존, 빈 DB
  • 반증: 서비스·repository에 결함 3개(상한 초과 경로의 범위 누락, 1차 지역 필터 제거, 서쪽 끝 계산 오류)를 넣으면 겨냥한 테스트 3건만 실패하는 것을 확인했습니다.
  • 스크립트: 대상 83건, 역검증 83/83 통과를 확인했습니다. 틀린 시군구 코드나 없는 지역명을 넣으면 그 항목만 실패하고 파일을 쓰지 않습니다.
  • 로컬 실행: 로컬 DB에 마이그레이션을 적용하고(활성 2차 83곳 채움) 로컬 BE에서 pickupStores를 호출했습니다.
    • 종로구: 한 점(매장 0건)
    • 종로구+노원구: 두 구를 담는 범위
    • 서울 북부 전체(14곳): 용산구부터 도봉구까지 담는 범위
    • 전국: null

참고

  • 옹진군의 카카오 대표점은 백령도(경도 124.67)입니다. 옹진군 안이라 역검증은 통과하지만, '인천 전체'를 고르면 범위가 서해 쪽으로 넓어집니다.
    • 플랜대로 카카오 대표점을 그대로 썼습니다. 마이그레이션이 빈 값만 채우므로 관리자 화면에서 좌표를 고칠 수 있습니다.

플랜 대조

플랜 항목 상태
SDL: PickupStoreConnection.regionBounds: MapBounds 추가 한 것
SDL: MapBounds를 store-pickup-stores.graphql에 정의 한 것
스크립트: 좌표 없는 2차 항목만 카카오 주소 검색으로 채움(시도 전체명 + 일반시 구 띄움) 한 것
스크립트: REGION 1건이 아니면 실패 한 것
스크립트: coord2regioncode 역검증, 어긋나면 실패 한 것
스크립트: 소수 7자리 문자열 저장, OIDC_KAKAO_CLIENT_ID 사용 한 것
스크립트: 마이그레이션 SQL을 JSON에서 생성 한 것
생성기: 재생성 때 좌표를 slug로 이어받음 한 것
시드: 2차 create·update에 좌표 반영, 좌표 없는 항목은 건드리지 않음 한 것
마이그레이션: slug 기준, 좌표가 빈 행만 채움, 빈 DB 변경 없음, 옛 인천 3개 구 null 한 것
repository: findRegionCenters(2차만, 활성 여부 안 봄, 허용 목록 변경 없음) 한 것
helper: 위도·경도 최소·최대로 범위 계산, 비면 null 한 것(서비스 파일 내 함수 toRegionBounds)
service: regionIds가 있을 때 범위 계산, 상한 초과 조기 반환에도 포함, 검증 실패는 먼저 한 것
타입: PickupStoreConnection에 regionBounds 추가 한 것
팩토리: createRegion에 center_lat·center_lng override 한 것
codegen 한 것
service spec 7개 경우 한 것(0건·상한 초과는 한 케이스, 비활성 포함 추가)
resolver spec 1케이스 한 것
마이그레이션 spec(채움·보존·빈 DB·83건 일치·반증) 한 것
일회성 검증(83건·역검증·틀린 코드 반증·로컬 DB·로컬 BE 4개 경우) 한 것

매장 선택 화면이 고른 지역으로 지도를 옮길 수 있게 pickupStores 응답에 regionBounds를 싣는다.
화면은 URL의 regionIds만 갖고 ID로 지역을 조회하는 쿼리가 없어 Region 타입 노출 대신 응답에 담음.

- SDL: PickupStoreConnection.regionBounds: MapBounds(south·west·north·east). 선택한 2차 지역 중심 좌표의 외곽, 한 곳이면 한 점, 전국·좌표 없음이면 null. 매장 0건·예약 기간 상한 초과에도 옴
- repository: findRegionCenters. 2차 지역만, 활성 여부는 매장 후보 조건과 같게 보지 않음
- 데이터: 2차 83곳 중심 좌표를 카카오 주소 검색의 시군구 대표점으로 채움(scripts/fill-region-centers.ts, coord2regioncode 역검증). 시드 JSON·시드 upsert 반영, 생성기는 재생성 때 좌표를 slug로 이어받음
- 마이그레이션 region_center_coordinates: 좌표가 빈 2차 행만 slug로 채움(관리자 입력 보존, 빈 DB는 변경 없음)
- 테스트: service 6건(한 점·다중·좌표 누락·전국·1차/삭제/비활성·0건/상한 초과), resolver 1건, 마이그레이션 4건(83건 일치·반증·보존·빈 DB)
@coderabbitai

coderabbitai Bot commented Oct 22, 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

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 22, 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-22T13:12:16.003493Z 9d5b552 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

🩺 NestJS Doctor — 90/100 (Excellent)

진단 493건 (error 13).

Category error warning info
architecture 1 1 44
correctness 0 269 0
performance 0 41 28
schema 0 0 76
security 12 21 0
architecture / security 상위 항목
  • error security/security/no-hardcoded-secrets: Variable 'SEED_PASSWORD' appears to contain a hardcoded secret.
  • 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.

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

@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

Coverage report

St.❔
Category Percentage Covered / Total
🟢 Statements
98.02% (+0% 🔼)
10805/11023
🟢 Branches
92.96% (+0.01% 🔼)
4120/4432
🟢 Functions
97.56% (+0.01% 🔼)
2155/2209
🟢 Lines
98.6% (+0% 🔼)
9828/9968

Test suite run success

4314 tests passing in 388 suites.

Report generated by 🧪jest coverage report action from 9d5b552

@chanwoo7
chanwoo7 merged commit 9d64ae1 into develop Oct 22, 2026
17 checks passed
@chanwoo7
chanwoo7 deleted the feat/pickup-stores-region-bounds branch October 22, 2026 13:16
@codecov

codecov Bot commented Oct 22, 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