-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] Store 에 district 컬럼 추가 #154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Caution Review failedFailed to post review comments. Configuration used: .coderabbit.yaml 📒 Files selected for processing (6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (2)
Walkthrough가게 도메인에 ‘구(District)’ 개념을 도입했다. District enum 추가, Store/StoreSearchResult에 District 필드 확장, Kakao 지도 검색 결과에서 지번주소를 파싱해 구를 추론하도록 MapClientStoreSearchResult에 로직을 추가했다. 초기 스키마와 시드 데이터에 district 컬럼을 반영했고, 관련 테스트와 픽스처를 전반적으로 수정했다. Changes
Sequence Diagram(s)sequenceDiagram
participant KakaoAPI as Kakao Map API
participant MapClient as MapClientStoreSearchResult
participant Domain as StoreSearchResult
participant Store as Store
KakaoAPI-->>MapClient: 가게 검색 응답(지번주소 포함)
MapClient->>MapClient: getDistrict()로 지번주소 토큰화/구 추론(기본 ETC)
MapClient->>Domain: toDomain(..., district)
Domain->>Store: toStore()/builder에 district 전달하여 엔티티 생성
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Out-of-scope changes
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
|
📌 최신 ERD가 자동 생성되었습니다. 👉 ERD 보러가기 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
src/main/java/eatda/domain/store/StoreSearchResult.java (1)
16-28: toStore 메서드에 district null-safety 방어 코드 추가
Store엔티티의district컬럼은@Column(nullable = false)로 설정돼 있어,district값이null일 경우 JPA 저장 시 예외가 발생합니다.district가null일 때District.ETC로 폴백하도록 수정해주세요.대상:
- 파일:
src/main/java/eatda/domain/store/StoreSearchResult.java- 메서드:
toStore()제안 diff:
@@ src/main/java/eatda/domain/store/StoreSearchResult.java - .district(district) + .district(district != null ? district : District.ETC)
🧹 Nitpick comments (6)
src/main/resources/db/seed/dev/V2__dev_init_data.sql (1)
10-25: district 컬럼 추가 반영 확인 및 시드 데이터 다양성 제안
- 컬럼 순서(road_address, lot_number_address, district, latitude, longitude)와 값 개수는 일치합니다. 빈 문자열 road_address(예: Line 18, 24)도 NOT NULL 제약엔 저촉되지 않습니다. OK.
- 다만 모든 row에
'GANGNAM'을 사용하면 데이터 다양성이 떨어집니다. 이후 “구별 검색/통계” 기능 검증을 위해 여러 구를 혼합해 넣는 것을 권장합니다.- 일부 좌표가 주소(예: 강남구)와 지리적으로 상이해 보입니다. dev 환경이라도 가능하면 주소–좌표–district가 서로 일관되도록 해두면 문제 추적에 유리합니다.
필요 시 district 다양화 예:
-- 예시: (일부 row) ..., '서울시 서초구 ...', '서울시 서초구 ...', 'SEOCHO', 37.48..., 127.03...), ..., '서울시 성북구 ...', '서울시 성북구 ...', 'SEONGBUK', 37.60..., 127.02...),src/main/java/eatda/domain/store/District.java (1)
39-48: fromName 성능/견고성 개선: trim 처리 + 사전(Map) 기반 조회현재는 호출 때마다
values()순회로 비교합니다. 입력 공백/탭 등도 그대로 비교되어 매치가 실패할 수 있습니다. 아래처럼 정규화와 Map 캐싱을 적용하면 성능과 견고성이 함께 개선됩니다.package eatda.domain.store; import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; import lombok.Getter; @Getter public enum District { @@ private final String name; + private static final Map<String, District> BY_DISPLAY_NAME = + Collections.unmodifiableMap( + Arrays.stream(values()) + .collect(Collectors.toMap(District::getName, Function.identity())) + ); + District(String name) { this.name = name; } public static District fromName(String name) { - return Arrays.stream(District.values()) - .filter(district -> district.name.equals(name)) - .findFirst() - .orElse(ETC); + if (name == null) return ETC; + String key = name.trim(); + if (key.isEmpty()) return ETC; + return BY_DISPLAY_NAME.getOrDefault(key, ETC); } }src/test/java/eatda/client/map/MapClientStoreSearchResultTest.java (1)
77-95: 엣지 케이스 보강 + District import로 가독성 향상 제안
- 현재 비정형 주소/공백 케이스에 대한 ETC 반환을 잘 커버하고 있습니다. 여기에 “시명 생략” 등 현실적인 변형 주소도 포함해 주세요.
- 또한
eatda.domain.store.District.ETC와 같은 FQN 대신import eatda.domain.store.District;를 추가하고District.ETC로 단순화하면 가독성이 좋아집니다.추가적으로, 주소 파싱 구현이 “두 번째 토큰”에만 의존한다면,
"중구 ..." (시명 없음)케이스에서 오동작할 수 있습니다. 구현을 “토큰 중 처음으로 '구'로 끝나는 문자열”을 찾는 방식으로 개선하는 것을 권장합니다.src/test/java/eatda/service/cheer/CheerServiceTest.java (1)
47-47: 중복 생성 로직 정리 + district 영속 여부 검증 추가 제안
- 동일한
StoreSearchResult(...)생성 구문이 여러 테스트에 반복됩니다. 테스트 유틸/팩토리 메서드로 추출해 중복을 줄이세요.- “가게 신규 저장” 시나리오에서 실제로 저장된 Store의 district가 기대값(
GANGNAM)인지도 함께 검증하면 회귀 방지에 좋습니다.예시:
private StoreSearchResult gangnamResult() { return new StoreSearchResult( "123", StoreCategory.KOREAN, "02-755-5232", "농민백암순대 본점", "http://place.map.kakao.com/123", "서울시 강남구 역삼동 123-45", "서울시 강남구 역삼동 123-45", District.GANGNAM, 37.5665, 126.9780 ); }그리고 검증 추가:
Store foundStore = storeRepository.findByKakaoId("123").orElseThrow(); assertThat(foundStore.getDistrict()).isEqualTo(District.GANGNAM); // 또는 노출 레이어 문자열 검증 시 assertThat(foundStore.getAddressDistrict()).isEqualTo("강남구");Also applies to: 65-65, 81-81, 102-102, 123-123
src/main/resources/db/seed/local/V2__local_init_data.sql (1)
10-25: district 컬럼 추가가 올바르게 반영되었습니다.모든 가게가 강남구 역삼동 주소를 가지고 있어 'GANGNAM' district 값이 정확합니다.
다만, 향후 테스트 데이터의 다양성을 위해 다른 구의 가게들도 추가하는 것을 고려해보시면 좋을 것 같습니다.
src/main/java/eatda/domain/store/Store.java (1)
65-65: 필드 할당 순서 일관성 개선 제안필드 선언 순서와 동일하게
lotNumberAddress할당 후district를 할당하는 것이 코드 가독성에 도움이 됩니다.this.roadAddress = roadAddress; - this.district = district; this.lotNumberAddress = lotNumberAddress; + this.district = district; this.coordinates = new Coordinates(latitude, longitude);Also applies to: 74-75
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
src/main/java/eatda/client/map/MapClientStoreSearchResult.java(4 hunks)src/main/java/eatda/domain/store/District.java(1 hunks)src/main/java/eatda/domain/store/Store.java(3 hunks)src/main/java/eatda/domain/store/StoreSearchResult.java(2 hunks)src/main/resources/db/migration/V1__init.sql(1 hunks)src/main/resources/db/seed/dev/V2__dev_init_data.sql(1 hunks)src/main/resources/db/seed/local/V2__local_init_data.sql(1 hunks)src/test/java/eatda/client/map/MapClientStoreSearchResultTest.java(2 hunks)src/test/java/eatda/controller/cheer/CheerControllerTest.java(2 hunks)src/test/java/eatda/document/store/StoreDocumentTest.java(2 hunks)src/test/java/eatda/domain/cheer/CheerTest.java(2 hunks)src/test/java/eatda/domain/store/DistrictTest.java(1 hunks)src/test/java/eatda/domain/store/StoreTest.java(1 hunks)src/test/java/eatda/fixture/StoreGenerator.java(4 hunks)src/test/java/eatda/service/cheer/CheerServiceTest.java(6 hunks)src/test/java/eatda/service/story/StoryServiceTest.java(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/test/java/eatda/fixture/StoreGenerator.java (1)
src/test/java/eatda/util/DomainUtils.java (1)
DomainUtils(7-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (16)
src/test/java/eatda/domain/cheer/CheerTest.java (1)
30-30: LGTM — 테스트 픽스처에 district 지정이 적절합니다
성북구주소와District.SEONGBUK가 일치하고, 새 NOT NULL 제약에도 부합합니다.src/test/java/eatda/client/map/MapClientStoreSearchResultTest.java (1)
59-75: 정상 케이스 테스트 추가는 적절합니다
"서울 중구 ..."에서District.JUNG도출을 검증한 것은 유의미합니다.실서비스 주소 포맷은
"서울시 ...","서울특별시 ...", 또는 시명 생략 등 다양합니다. 본 테스트 클래스에 추가 케이스(예:"서울시 성북구 ...","서울특별시 송파구 ...","중구 ...")를 보강해두면 회귀 방지에 도움이 됩니다.src/main/java/eatda/domain/store/StoreSearchResult.java (1)
11-11: district 필드 추가 방향성 적절검색 결과 DTO에
District를 포함시키는 설계가 명확하고, 도메인 매핑 경로도 일관됩니다.src/test/java/eatda/controller/cheer/CheerControllerTest.java (1)
67-69: LGTM — 시나리오에 District 주입이 적절하며 응답 검증도 일치합니다
NOWON/SEONGBUK을 구분하여 최신 응원 목록의storeDistrict를 검증하는 흐름이 타당합니다.src/test/java/eatda/service/story/StoryServiceTest.java (1)
15-15: 변경사항이 적절합니다!District enum import와 StoreSearchResult 생성자에 District.GANGNAM 추가가 PR 목적에 부합합니다.
Also applies to: 40-42
src/test/java/eatda/domain/store/DistrictTest.java (1)
1-35: District enum 테스트가 잘 작성되었습니다!서울의 모든 25개 구와 예외 케이스들을 포함한 포괄적인 테스트 커버리지입니다. ParameterizedTest를 활용한 구조도 깔끔합니다.
src/test/java/eatda/document/store/StoreDocumentTest.java (1)
23-23: API 문서 테스트 업데이트가 적절합니다!StoreSearchResult 생성자에 District enum 추가가 올바르게 반영되었습니다.
Also applies to: 244-249
src/test/java/eatda/domain/store/StoreTest.java (1)
18-18: Store 테스트가 District enum 사용에 맞게 잘 수정되었습니다!테스트 메서드명과 구현이 enum 기반 구 정보 처리 방식을 정확히 반영합니다.
Also applies to: 26-29
src/main/java/eatda/domain/store/Store.java (2)
50-52: District 필드 추가가 적절합니다!EnumType.STRING 사용과 nullable = false 설정이 데이터 무결성 보장에 좋습니다.
79-81: getAddressDistrict() 구현 개선!District enum을 직접 사용하여 문자열 파싱 로직을 제거한 것이 훨씬 깔끔합니다.
src/test/java/eatda/fixture/StoreGenerator.java (3)
3-3: 테스트 기본값 설정이 적절합니다!테스트용 DEFAULT_DISTRICT로 GANGNAM을 사용한 것이 합리적입니다.
Also applies to: 19-19
30-50: generate 메소드들의 District 지원이 잘 구현되었습니다!기존 메소드들의 하위 호환성을 유지하면서 District 파라미터를 받는 새로운 오버로드를 추가한 설계가 좋습니다.
52-52: create 메소드 업데이트가 적절합니다!District 파라미터 추가와 빌더 설정이 올바르게 구현되었습니다.
Also applies to: 61-61
src/main/java/eatda/client/map/MapClientStoreSearchResult.java (3)
5-5: District 임포트와 기본값 설정이 적절합니다!알 수 없는 구역에 대해 District.ETC를 기본값으로 사용하는 것이 합리적입니다.
Also applies to: 32-32
78-78: toDomain() 메소드의 District 통합이 깔끔합니다!getDistrict() 메소드를 활용하여 StoreSearchResult에 district를 전달하는 구현이 적절합니다.
58-67: 코드 승인 및 API 주소 형식 검증 요청
getDistrict()의 null/blank 체크와 배열 경계 검사는 적절하며,District.fromName()이 알 수 없는 구 이름을ETC로 처리하는 것도 테스트로 확인되었습니다. 남은 검증 사항은 다음과 같습니다.
- 카카오 API의
lotNumberAddress응답이 항상"서울 XX구 …"형식을 따르는지 확인해주세요. 혹시 다른 패턴(예:"경기도 성남시 분당구 …")이 올 경우 로직이 올바르게 동작하는지 검토가 필요합니다.
| `place_url` VARCHAR(255) NOT NULL, | ||
| `road_address` VARCHAR(255) NOT NULL, | ||
| `lot_number_address` VARCHAR(255) NOT NULL, | ||
| `district` VARCHAR(31) NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미 배포된 초기 마이그레이션(V1)을 수정하지 마세요 — 신규 마이그레이션으로 분리 필요
운영/공용 DB에 V1이 적용된 상태에서 V1__init.sql을 수정하면 마이그레이션 불일치가 발생합니다. store.district 추가는 신규 마이그레이션(예: V2__add_store_district.sql)으로 처리하세요.
권장 절차:
- 새 마이그레이션 추가:
- (안전) NULL 허용으로 추가 → 데이터 백필 → NOT NULL로 변경
- 지역 검색 대비 인덱스 추가
예시(DDL):
-- V2__add_store_district.sql
ALTER TABLE `store` ADD COLUMN `district` VARCHAR(31) NULL AFTER `lot_number_address`;
-- 필요 시: 모든 기존 row를 ETC로 백필
UPDATE `store` SET `district` = 'ETC' WHERE `district` IS NULL;
-- NOT NULL 강제
ALTER TABLE `store` MODIFY COLUMN `district` VARCHAR(31) NOT NULL;
-- 향후 지역별 조회 최적화용 인덱스
CREATE INDEX `idx_store_district` ON `store`(`district`);또한, 현재 PR에서 dev/local seed는 district 컬럼을 전제로 작성되어 있으므로, 새 마이그레이션 추가 후 적용 순서가 보장되도록 스크립트/파이프라인을 점검해주세요.
🤖 Prompt for AI Agents
In src/main/resources/db/migration/V1__init.sql around line 23: do not modify
the already-deployed V1 migration to add the `district` column; instead create a
new migration file (e.g., V2__add_store_district.sql) that (1) ALTER TABLE store
ADD COLUMN district VARCHAR(31) NULL AFTER lot_number_address, (2) run a
backfill UPDATE to set a default like 'ETC' for existing NULLs, (3) ALTER TABLE
to MODIFY COLUMN district VARCHAR(31) NOT NULL, and (4) CREATE INDEX
idx_store_district ON store(district); also update dev/local seed scripts and
CI/deployment pipeline to run the new migration before any seed/logic that
assumes the district column exists.
|
📌 최신 ERD가 자동 생성되었습니다. 👉 ERD 보러가기 |
7580093 to
2567bc6
Compare
|
📌 최신 ERD가 자동 생성되었습니다. 👉 ERD 보러가기 |
|



✨ 개요
XX구)🧾 관련 이슈
closed #151
🔍 참고 사항 (선택)
Summary by CodeRabbit