Conversation
WalkthroughRegion 엔티티를 상세 주소 구조로 재설계하고 지역 식별 방식을 이름→ID로 전환했다. 회원가입/구글가입/유저정보수정 DTO와 서비스 로직이 regionId 기반으로 변경되었고, 지역 검색 API·페이지 응답 DTO·보안 설정·Flyway 초기 마이그레이션이 추가되었다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant RC as RegionController
participant S as RegionQueryService
participant R as RegionRepository
rect rgb(245,248,255)
note over C,RC: 지역 검색 요청 (GET /api/regions?searchKeyword=...&page=...)
C->>RC: searchRegion(keyword, page)
RC->>S: searchRegion(keyword, page)
S->>S: trim keyword, PageRequest(size=10)
S->>R: searchByKeywordIgnoreCase(keyword, pageable)
R-->>S: Page<Region>
S->>S: map -> List<SearchRegionDto>
S-->>RC: PageResponseDto<SearchRegionDto>
RC-->>C: 200 OK (PageResponseDto)
end
sequenceDiagram
autonumber
participant C as Client
participant AS as AuthService
participant RS as RegionQueryService
note over C,AS: 회원가입/구글가입/정보수정 흐름 (region name → regionId)
C->>AS: signUp / googleSignUp / updateUserInfo (regionId)
AS->>RS: findRegionById(regionId)
RS-->>AS: Region
AS-->>C: 처리 완료 (회원 생성/업데이트)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
🧰 Additional context used🧬 Code graph analysis (1)src/main/java/com/example/dgu/returnwork/domain/auth/dto/request/GoogleSignUpRequestDto.java (3)
🔇 Additional comments (2)
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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (10)
src/main/resources/application-local.yml (1)
23-26: YAML 포맷 수정 권장.Flyway 설정이 올바르게 추가되었습니다.
baseline-on-migrate: true설정은 기존 데이터베이스에 마이그레이션을 적용할 때 유용합니다.다만, YAMLlint에서 콜론 앞 공백이 과도하다는 경고가 있습니다. 일관성을 위해 다음과 같이 수정하는 것을 권장합니다:
flyway: - enabled : true + enabled: true baseline-on-migrate: true - locations : classpath:db/migration + locations: classpath:db/migrationsrc/main/resources/db/migration/V1__create_tables.sql (2)
3-11: 검색 성능을 위한 인덱스 추가 권장.
regions테이블의search_keywords필드를 기반으로 검색이 이루어질 것으로 보이는데, 검색 성능 향상을 위해 인덱스 추가를 고려하시기 바랍니다.다음과 같은 인덱스를 추가할 수 있습니다:
CREATE INDEX idx_regions_search_keywords ON regions(search_keywords);또는 FULLTEXT 인덱스가 더 적합할 수 있습니다:
CREATE FULLTEXT INDEX idx_regions_fulltext ON regions(search_keywords);
138-138: 파일 끝에 개행 추가 권장.SQL 파일 끝에 개행 문자가 없습니다. 일부 도구와의 호환성 및 Git diff의 가독성을 위해 파일 끝에 개행을 추가하는 것이 좋습니다.
CONSTRAINT FK7t0qlyrlnhn8xjj1atdwtevad FOREIGN KEY (region_id) REFERENCES regions (id) - ); + ); +src/main/java/com/example/dgu/returnwork/domain/auth/dto/request/SignUpRequestDto.java (1)
36-37: regionId에 유효성 검증 추가를 고려하세요.regionId 필드가 필수값인 경우
@NotNull검증을 추가하는 것이 좋습니다. 다른 필수 필드들은@NotBlank를 사용하고 있지만, regionId는 검증 어노테이션이 없어 null 값이 허용됩니다.다음 diff를 적용하여 검증을 추가할 수 있습니다:
+ @NotNull(message = "지역은 필수입니다") @Schema(example = "1") Long regionId,src/main/java/com/example/dgu/returnwork/domain/auth/dto/request/GoogleSignUpRequestDto.java (1)
25-26: regionId에 유효성 검증 추가를 고려하세요.SignUpRequestDto와 동일하게, regionId가 필수값인 경우
@NotNull검증을 추가하는 것이 좋습니다.다음 diff를 적용하여 검증을 추가할 수 있습니다:
+ @NotNull(message = "지역은 필수입니다") @Schema(example = "1") Long regionId,src/main/java/com/example/dgu/returnwork/domain/region/service/RegionQueryService.java (2)
26-34: trim 후 빈 문자열 검증을 고려하세요.Line 28에서 keyword를 trim하지만, trim 후 빈 문자열인지 확인하지 않습니다. 공백만 입력된 경우 데이터베이스에 불필요한 쿼리가 실행될 수 있습니다.
다음과 같이 검증을 추가할 수 있습니다:
public PageResponseDto<SearchRegionDto> searchRegion(String keyword, Integer page){ String trimKeyword = keyword.trim(); + + if (trimKeyword.isEmpty()) { + return PageResponseDto.from(Page.empty()); + } Pageable pageable = PageRequest.of(page, 10);
30-30: 페이지 크기를 설정 가능하도록 고려하세요.페이지 크기가 10으로 고정되어 있습니다. 향후 확장성을 위해 상수로 추출하거나 설정 파일에서 관리하는 것을 고려해보세요.
예시:
+ private static final int DEFAULT_PAGE_SIZE = 10; + public PageResponseDto<SearchRegionDto> searchRegion(String keyword, Integer page){ String trimKeyword = keyword.trim(); - Pageable pageable = PageRequest.of(page, 10); + Pageable pageable = PageRequest.of(page, DEFAULT_PAGE_SIZE);src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionApi.java (1)
83-91: searchKeyword 파라미터에 유효성 검증 추가를 고려하세요.searchKeyword 파라미터가 빈 문자열이나 공백만으로 구성되는 것을 방지하기 위해
@NotBlank검증을 추가하는 것이 좋습니다.다음 diff를 적용할 수 있습니다:
PageResponseDto<SearchRegionDto> searchRegion( @Parameter( description = "검색할 지역 키워드 (시/도, 시/군/구, 동/리 등)", example = "서울" ) + @NotBlank(message = "검색 키워드는 필수입니다") @RequestParam String searchKeyword, @RequestParam(defaultValue = "0") Integer page );src/main/java/com/example/dgu/returnwork/domain/region/Region.java (2)
8-37: 인스턴스 생성을 위한 빌더 또는 팩토리 메서드 추가 권장현재 엔티티에
protectedno-args 생성자만 존재하여 JPA 요구사항은 충족하지만, 테스트나 데이터 초기화 시 인스턴스를 생성할 명확한 방법이 없습니다. Lombok의@Builder나 정적 팩토리 메서드를 추가하는 것을 권장합니다.방법 1: Lombok @builder 추가 (권장)
@Entity @Table(name = "regions") @Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Region {방법 2: 정적 팩토리 메서드 추가
@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Region { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // ... 필드들 ... + + public static Region of(String fullAddress, String sido, String sigungu, + String dongLi, String sidoNormalized, String searchKeywords) { + Region region = new Region(); + region.fullAddress = fullAddress; + region.sido = sido; + region.sigungu = sigungu; + region.dongLi = dongLi; + region.sidoNormalized = sidoNormalized; + region.searchKeywords = searchKeywords; + return region; + } }
18-34: Bean Validation 애노테이션 추가 고려 (선택사항)현재 필드 검증이 JPA
@Column제약에만 의존하고 있습니다. Bean Validation 애노테이션(@NotNull,@Size등)을 추가하면 애플리케이션 레벨에서 더 일찍 검증할 수 있으며, 더 명확한 에러 메시지를 제공할 수 있습니다.+import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + @Entity @Table(name = "regions") @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Region { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @NotNull + @Size(max = 200) @Column(nullable = false, length = 200) private String fullAddress; + @Size(max = 50) @Column(length = 50) private String sido; // 나머지 필드들에도 유사하게 적용...
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
build.gradle(1 hunks)src/main/java/com/example/dgu/returnwork/domain/auth/dto/request/GoogleSignUpRequestDto.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/auth/dto/request/SignUpRequestDto.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/auth/service/AuthService.java(2 hunks)src/main/java/com/example/dgu/returnwork/domain/region/Region.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionApi.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionController.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/region/dto/response/SearchRegionDto.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/region/repository/RegionRepository.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/region/service/RegionQueryService.java(2 hunks)src/main/java/com/example/dgu/returnwork/domain/user/dto/request/UpdateUserInfoRequestDto.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/user/dto/response/GetUserInfoResponseDto.java(1 hunks)src/main/java/com/example/dgu/returnwork/domain/user/service/UserCommandService.java(1 hunks)src/main/java/com/example/dgu/returnwork/global/config/SecurityConfig.java(1 hunks)src/main/java/com/example/dgu/returnwork/global/dto/PageResponseDto.java(1 hunks)src/main/resources/application-local.yml(2 hunks)src/main/resources/db/migration/V1__create_tables.sql(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
src/main/resources/application-local.yml
[warning] 24-24: too many spaces before colon
(colons)
[warning] 26-26: too many spaces before colon
(colons)
🔇 Additional comments (16)
build.gradle (1)
65-67: LGTM!Flyway 의존성이 올바르게 추가되었습니다. Spring Boot의 dependency management가 버전을 관리하므로 별도의 버전 명시가 필요하지 않습니다.
src/main/resources/application-local.yml (1)
10-10: 로컬 환경에서validate모드 사용 확인 필요.
ddl-auto를update에서validate로 변경하셨습니다. 이는 Flyway로 스키마를 관리하는 프로덕션 환경에 적합하지만, 로컬 개발 환경에서는 엔티티 변경 시 수동으로 마이그레이션 스크립트를 작성해야 하는 번거로움이 있을 수 있습니다.로컬 개발 시 빠른 프로토타이핑이 필요한 경우
update모드 유지를 고려하거나, 팀 내에서 로컬 환경의 마이그레이션 관리 방침을 명확히 하시기 바랍니다.src/main/java/com/example/dgu/returnwork/global/config/SecurityConfig.java (1)
65-66: LGTM!지역 검색 API(
/api/regions)를 공개 엔드포인트로 추가한 것이 적절합니다. 회원가입 시 사용자가 인증 없이 지역을 조회할 수 있어야 하므로permitAll에 포함되는 것이 맞습니다.src/main/resources/db/migration/V1__create_tables.sql (1)
18-18:region_id NOT NULL제약 조건 검토 필요.
user테이블의region_id가NOT NULL로 정의되어 있습니다. 회원가입 시 반드시 지역을 선택해야 한다는 의미인데, 이것이 비즈니스 요구사항과 일치하는지 확인하시기 바랍니다.만약 선택적으로 지역을 입력받을 가능성이 있다면,
NULL을 허용하도록 수정해야 합니다.src/main/java/com/example/dgu/returnwork/domain/user/dto/response/GetUserInfoResponseDto.java (1)
39-39: LGTM!Region 엔티티의 확장된 주소 구조에 맞춰
getFullAddress()를 사용하도록 올바르게 변경되었습니다. 사용자에게 더 상세한 주소 정보를 제공할 수 있습니다.src/main/java/com/example/dgu/returnwork/domain/user/service/UserCommandService.java (1)
52-52: LGTM!
UpdateUserInfoRequestDto의 변경사항에 맞춰findRegionById를 사용하도록 올바르게 수정되었습니다. ID 기반 조회로 전환하여 더 명확하고 효율적인 지역 검색이 가능합니다.src/main/java/com/example/dgu/returnwork/domain/auth/service/AuthService.java (2)
57-57: LGTM!회원가입 시 지역 조회 로직이 ID 기반으로 올바르게 변경되었습니다.
SignUpRequestDto의 변경사항과 일치합니다.
117-117: LGTM!구글 회원가입 완료 시 지역 조회 로직이 ID 기반으로 올바르게 변경되었습니다.
GoogleSignUpRequestDto의 변경사항과 일치합니다.src/main/java/com/example/dgu/returnwork/domain/region/repository/RegionRepository.java (1)
13-14: LGTM!JPQL 쿼리가 올바르게 작성되었으며, LOWER 함수를 사용한 대소문자 구분 없는 검색과 LIKE를 통한 부분 검색이 적절하게 구현되었습니다.
src/main/java/com/example/dgu/returnwork/domain/region/dto/response/SearchRegionDto.java (1)
5-12: LGTM!간결하고 명확한 DTO 구현입니다. 정적 팩토리 메서드를 사용한 매핑도 적절합니다.
src/main/java/com/example/dgu/returnwork/domain/region/service/RegionQueryService.java (1)
21-24: LGTM!메서드 이름 변경과 ID 기반 조회 로직이 올바르게 구현되었습니다.
src/main/java/com/example/dgu/returnwork/global/dto/PageResponseDto.java (1)
7-26: LGTM!표준 페이지네이션 패턴을 따르는 깔끔한 구현입니다. Spring의 Page 객체를 올바르게 매핑하고 있으며, 필요한 모든 페이징 정보를 포함하고 있습니다.
src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionApi.java (1)
20-82: LGTM!OpenAPI 문서화가 상세하고 명확하게 작성되었습니다. 성공/실패 케이스의 예제 응답이 모두 포함되어 있어 API 사용자에게 유용합니다.
src/main/java/com/example/dgu/returnwork/domain/region/Region.java (3)
21-28: 주소 필드 nullable 허용 여부 수동 검증 필요
sido,sigungu,dongLi필드가 모두 nullable로 설정되어 있습니다. 실제 DB 마이그레이션 파일과 도메인 로직에서 해당 컬럼의 null 허용 여부를 확인하고, 비즈니스 요구사항에 따라 최소sido필드가 필수인지 검증해주세요.
30-34: searchKeywords에 일반 B-tree 인덱스는 LIKE '%…%' 패턴에 적용되지 않습니다
현 쿼리(LOWER(r.searchKeywords) LIKE LOWER(CONCAT('%', :keyword, '%')))는 선행 와일드카드 사용으로 인해 B-tree 인덱스를 활용하지 못합니다. MySQL FULLTEXT 인덱스나 PostgreSQL GIN/pg_trgm 기반 full-text 검색 도입 혹은 와일드카드 위치 조정(예:%keyword→keyword%), 쿼리 패턴 변경을 검토하세요.Likely an incorrect or invalid review comment.
18-19:fullAddress필드 길이 검증 필요
fullAddress최대 길이 200자가 실제 생성되는 전체 주소(시도, 시군구, 동/리, 상세주소 포함)를 모두 담기에 충분한지, Region 생성 로직(엔티티 빌더 또는 서비스)에서 확인해주세요.
src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionController.java
Outdated
Show resolved
Hide resolved
src/main/java/com/example/dgu/returnwork/domain/user/dto/request/UpdateUserInfoRequestDto.java
Show resolved
Hide resolved
Docstrings generation was requested by @oOccasio. * #64 (comment) The following files were modified: * `src/main/java/com/example/dgu/returnwork/domain/auth/service/AuthService.java` * `src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionApi.java` * `src/main/java/com/example/dgu/returnwork/domain/region/controller/RegionController.java` * `src/main/java/com/example/dgu/returnwork/domain/region/dto/response/SearchRegionDto.java` * `src/main/java/com/example/dgu/returnwork/domain/region/repository/RegionRepository.java` * `src/main/java/com/example/dgu/returnwork/domain/region/service/RegionQueryService.java` * `src/main/java/com/example/dgu/returnwork/domain/user/dto/response/GetUserInfoResponseDto.java` * `src/main/java/com/example/dgu/returnwork/domain/user/service/UserCommandService.java` * `src/main/java/com/example/dgu/returnwork/global/config/SecurityConfig.java` * `src/main/java/com/example/dgu/returnwork/global/dto/PageResponseDto.java`
|
Note Generated docstrings for this pull request at #65 |
📝 요약
♻️ [refactor] - 상세 주소를 위해 Region 엔티티를 리팩토링한다
🔍 변경 사항
queryservice 개선
String 입력이 아닌 지역 id 입력으로 변경
📋 체크리스트
🔗 관련 이슈
Closes #61
Summary by CodeRabbit