Skip to content

Conversation

@1winhyun
Copy link
Member

@1winhyun 1winhyun commented Jan 12, 2026

🔀 변경 내용

  • 키워드 기반 장소 검색 기능 구현했으며 및 일부 오류를 수정했습니다.

✅ 작업 항목

  • 키워드 기반 장소 검색 기능을 구현했습니다.

추가 작업(수정)

  • 학생회 게시글 상세 조회(학생회 전용) 시 Place 객체가 전부 반환되도록 수정

추가 작업(오류 해결)

  • 게시글 수정 기능 이미지 삭제 시 중복 삭제 시도 및 삭제 실패 시 트랜잭션 롤백 문제 해결
  • 게시글 삭제 기능 이미지 삭제 시 중복 삭제 시도 및 삭제 실패 시 트랜잭션 롤백 문제 해결
  • PostCategory endDateTime 정규화 과정 중 LocalTime.MAX 사용시 반올림이 일어나는 오류 명시적 표현을 통해 해결

📸 스크린샷 (선택)

키워드 기반 장소 검색 기능 구현

image

상세 조회 시 Place 객체가 전부 반환

  • 게시글 수정 시 기존 항목들을 유지하기 위함.
image

📎 참고 이슈

관련 이슈 번호 #59

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 게시물 상세 조회에 이미지와 장소 정보 추가
    • 장소 검색에 키워드만으로 검색하는 새로운 옵션 추가
  • Bug Fixes

    • 파트너십 게시물의 종료 시간 정확성 개선
  • Refactor

    • 검색 로직 최적화 및 통합

✏️ Tip: You can customize this high-level summary in your review settings.

@1winhyun 1winhyun self-assigned this Jan 12, 2026
@1winhyun 1winhyun added ♻️Refactor 리팩토링 ✨Feat 새로운 기능 개발 labels Jan 12, 2026
@1winhyun 1winhyun linked an issue Jan 12, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

Walkthrough

상세 게시물 조회 기능을 추가하여 새로운 GetPostDetailResponse DTO와 매퍼 메서드를 도입하고, 장소 이미지 데이터를 처리하며, 장소 검색 기능을 위치 기반 및 키워드 기반으로 분리하였습니다.

Changes

Cohort / File(s) Summary
Post Detail Response 정의
src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostDetailResponse.java
상세 게시물 조회용 새로운 레코드 타입 도입. 게시물 ID, 작성자 정보, 카테고리, 내용, 장소, 날짜/시간, 썸네일, 이미지 목록 필드 포함
Post Mapper 로직 확장
src/main/java/com/campus/campus/domain/councilpost/application/mapper/StudentCouncilPostMapper.java
GetPostDetailResponse 생성 매퍼 메서드 추가. SavedPlaceInfo로의 Place 변환 헬퍼 메서드 추가. 조건부 날짜 처리 (이벤트/일반) 로직 포함
Post Service 개선
src/main/java/com/campus/campus/domain/councilpost/application/service/StudentCouncilPostService.java
findById 메서드 반환 타입을 GetPostDetailResponse로 변경. PlaceImagesRepository 의존성 추가 및 장소 이미지 URL 조회 로직 구현. 이미지 삭제 시 List\<String\>에서 Set\<String\>으로 변경. 예외 처리 범위 확대
Post Category 검증
src/main/java/com/campus/campus/domain/councilpost/domain/entity/PostCategory.java
PARTNERSHIP 카테고리의 종료 시간 정규화를 LocalTime.MAX에서 23:59:59로 변경
Post Controller 업데이트
src/main/java/com/campus/campus/domain/councilpost/presentation/StudentCouncilPostController.java
getPost 메서드의 응답 타입을 GetPostDetailResponse로 변경. GetPostDetailResponse 임포트 추가
Place Service 검색 리팩터링
src/main/java/com/campus/campus/domain/place/application/service/PlaceService.java
search 메서드를 searchByLocationAndKeyword로 이름 변경. 새로운 searchByKeyword 공개 메서드 추가. 검색 결과 처리 로직을 processSearchResults 헬퍼 메서드로 추출 및 통합
Place Controller 끝점 확장
src/main/java/com/campus/campus/domain/place/presentation/PlaceController.java
getPlaceInfo를 getPlaceInfoWithLocationAndKeyword로 이름 변경. 응답을 CommonResponse로 감싸기. 키워드 전용 검색용 새로운 GET /places/search/keyword 끝점 추가

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Controller as StudentCouncilPostController
    participant Service as StudentCouncilPostService
    participant Mapper as StudentCouncilPostMapper
    participant PlaceImageRepo as PlaceImagesRepository
    participant DB as Database

    Client->>Controller: GET /posts/{postId}
    Controller->>Service: findById(postId, councilId)
    
    Service->>DB: findPost(postId)
    DB-->>Service: StudentCouncilPost
    
    Service->>DB: findPlaceImages(place)
    DB-->>Service: List<PlaceImages>
    
    Service->>Mapper: toGetPostDetailResponse(post, images, placeImageUrls, councilId)
    
    Mapper->>Mapper: toSavedPlaceInfo(place, placeImageUrls)
    Mapper-->>Mapper: SavedPlaceInfo
    
    Mapper-->>Service: GetPostDetailResponse
    Service-->>Controller: GetPostDetailResponse
    
    Controller-->>Client: CommonResponse<GetPostDetailResponse>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Refactor/#57 행사 게시글 생성 시 장소 상세정보 입력하도록 수정 #58: GetPostDetailResponse 추가 및 detailedLocation 필드 도입으로 동일한 DTO 및 매퍼 변경 사항과 중복됨
  • 26: SavedPlaceInfo, PlaceImages/PlaceImagesRepository, PlaceService 등 이 PR에서 사용하는 장소 관련 타입 및 리포지토리 확장과 연관됨
  • 24: StudentCouncilPostMapper와 서비스/컨트롤러 매핑을 수정하여 상세 응답 타입 변경 시 동일한 매핑 및 응답 흐름 변경

Suggested reviewers

  • 1224kang
  • jjaeroong

Poem

🐰 상세한 게시물 보기, 장소 이미지도 함께!
검색은 키워드로, 위치로도 찾아봐~
서비스와 매퍼가 춤을 춘다네,
Place 정보도 쏘옥 담겨있고,
우리 캠퍼스는 더욱 풍성해졌어! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 사항의 핵심을 명확하게 요약하고 있습니다. 키워드 기반 장소 검색 기능 구현과 오류 수정이라는 두 가지 주요 변경 사항을 간결하게 표현하고 있습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/com/campus/campus/domain/place/presentation/PlaceController.java (1)

63-69: 키워드 파라미터에 유효성 검증이 없습니다.

빈 문자열이나 공백만 있는 키워드로 검색이 가능합니다. @NotBlank 또는 @Size(min=1) 어노테이션 추가를 고려해주세요.

♻️ 권장 수정안
+import jakarta.validation.constraints.NotBlank;
+
 @GetMapping("/search/keyword")
 @Operation(summary = "키워드 기반 장소 검색")
-public CommonResponse<List<SavedPlaceInfo>> getPlaceInfoWithKeyword(@RequestParam String keyword) {
+public CommonResponse<List<SavedPlaceInfo>> getPlaceInfoWithKeyword(@RequestParam @NotBlank String keyword) {
     List<SavedPlaceInfo> searchResponse = placeService.searchByKeyword(keyword);

     return CommonResponse.success(PlaceResponseCode.PLACE_SEARCH_SUCCESS, searchResponse);
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a89c014 and e42d5be.

📒 Files selected for processing (7)
  • src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostDetailResponse.java
  • src/main/java/com/campus/campus/domain/councilpost/application/mapper/StudentCouncilPostMapper.java
  • src/main/java/com/campus/campus/domain/councilpost/application/service/StudentCouncilPostService.java
  • src/main/java/com/campus/campus/domain/councilpost/domain/entity/PostCategory.java
  • src/main/java/com/campus/campus/domain/councilpost/presentation/StudentCouncilPostController.java
  • src/main/java/com/campus/campus/domain/place/application/service/PlaceService.java
  • src/main/java/com/campus/campus/domain/place/presentation/PlaceController.java
🧰 Additional context used
🧬 Code graph analysis (5)
src/main/java/com/campus/campus/domain/councilpost/domain/entity/PostCategory.java (1)
src/main/java/com/campus/campus/domain/councilpost/application/dto/response/NormalizedDateTime.java (1)
  • NormalizedDateTime (5-9)
src/main/java/com/campus/campus/domain/councilpost/application/mapper/StudentCouncilPostMapper.java (1)
src/main/java/com/campus/campus/domain/councilpost/domain/entity/StudentCouncilPost.java (1)
  • Entity (26-101)
src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostDetailResponse.java (3)
src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostListForCouncilResponse.java (1)
  • GetPostListForCouncilResponse (10-32)
src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostResponse.java (1)
  • Builder (13-35)
src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostForUserResponse.java (1)
  • Builder (13-36)
src/main/java/com/campus/campus/domain/place/presentation/PlaceController.java (3)
src/main/java/com/campus/campus/domain/place/application/service/PartnershipPlaceService.java (1)
  • Slf4j (38-194)
src/main/java/com/campus/campus/domain/school/presentation/SchoolController.java (1)
  • RestController (20-55)
src/main/java/com/campus/campus/domain/place/domain/repository/PlaceRepository.java (1)
  • PlaceRepository (10-15)
src/main/java/com/campus/campus/domain/councilpost/application/service/StudentCouncilPostService.java (3)
src/main/java/com/campus/campus/domain/councilpost/domain/repository/PostImageRepository.java (1)
  • PostImageRepository (12-29)
src/main/java/com/campus/campus/domain/councilpost/domain/entity/StudentCouncilPost.java (1)
  • update (61-83)
src/main/java/com/campus/campus/domain/place/domain/entity/PlaceImages.java (1)
  • Entity (18-40)
⏰ 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: build
🔇 Additional comments (12)
src/main/java/com/campus/campus/domain/place/application/service/PlaceService.java (2)

63-90: 검색 메서드 분리 및 코드 중복 제거가 잘 되었습니다.

searchByLocationAndKeywordsearchByKeyword로 검색 기능을 분리하고, 공통 로직을 processSearchResults로 추출하여 DRY 원칙을 잘 적용했습니다.


154-185: 공통 처리 로직이 잘 추출되었습니다.

processSearchResults 메서드가 후보 생성, 이미지 조회, 비동기 처리를 깔끔하게 캡슐화했습니다. completeOnTimeoutexceptionally를 통한 타임아웃 및 예외 처리도 적절합니다.

src/main/java/com/campus/campus/domain/place/presentation/PlaceController.java (1)

41-61: CommonResponse 래핑이 잘 적용되었습니다.

기존 raw list 반환에서 CommonResponse.success()로 변경하여 일관된 API 응답 형식을 유지합니다. 단, 기존 /search 엔드포인트의 keyword 파라미터에도 동일한 유효성 검증 추가를 고려해주세요.

src/main/java/com/campus/campus/domain/councilpost/domain/entity/PostCategory.java (1)

32-36: LocalTime.MAX 반올림 문제 수정이 적절합니다.

LocalTime.MAX(23:59:59.999999999)는 나노초 정밀도로 인해 데이터베이스 저장 시 다음 날로 반올림될 수 있습니다. LocalTime.of(23, 59, 59)로 명시적으로 지정하여 안전하게 처리됩니다.

src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostDetailResponse.java (1)

14-36: 새로운 상세 조회 응답 DTO가 잘 설계되었습니다.

기존 GetPostResponseplaceName (String) 대신 SavedPlaceInfo 객체를 사용하여 장소 정보를 풍부하게 제공합니다. @JsonInclude(NON_NULL)@Builder 패턴이 기존 DTO들과 일관성 있게 적용되었습니다.

src/main/java/com/campus/campus/domain/councilpost/presentation/StudentCouncilPostController.java (1)

171-177: 상세 조회 응답 타입 변경이 적절합니다.

GetPostResponse에서 GetPostDetailResponse로 변경하여 장소의 전체 정보(SavedPlaceInfo)를 반환하도록 업데이트되었습니다. PR 목표에 부합하는 변경입니다.

src/main/java/com/campus/campus/domain/councilpost/application/mapper/StudentCouncilPostMapper.java (2)

107-132: LGTM!

toGetPostDetailResponse 메서드가 기존 toGetPostResponse와 일관된 패턴으로 잘 구현되었습니다. SavedPlaceInfo를 통해 Place 객체 전체 정보를 반환하는 구조가 적절하며, null 처리도 올바르게 되어 있습니다.


221-236: LGTM!

toSavedPlaceInfo 헬퍼 메서드가 적절하게 구현되었습니다. place에 대한 null 체크와 imageUrls에 대한 빈 리스트 폴백 처리가 올바릅니다.

src/main/java/com/campus/campus/domain/councilpost/application/service/StudentCouncilPostService.java (4)

104-118: LGTM!

findById 메서드가 GetPostDetailResponse를 반환하도록 업데이트되었고, Place 이미지 URL을 포함하는 로직이 올바르게 추가되었습니다.


175-194: 이미지 중복 삭제 방지 및 트랜잭션 롤백 문제 수정 확인

Set<String>을 사용하여 중복 이미지 URL 삭제 시도를 방지하고, 일반 Exception을 catch하여 OCI 삭제 실패 시 트랜잭션이 롤백되지 않도록 수정되었습니다. PR 목표에 맞게 잘 구현되었습니다.


259-267: LGTM!

getPlaceImageUrls 헬퍼 메서드가 적절하게 구현되었습니다. placeplaceKey에 대한 null 체크가 방어적으로 잘 처리되어 있습니다.


270-298: cleanupUnusedImages에서 동일한 수정 적용 확인

delete 메서드와 동일하게 Set<String>으로 중복 삭제 방지 및 일반 Exception catch로 트랜잭션 롤백 문제가 수정되었습니다. 두 메서드 간 일관성이 유지되어 좋습니다.

@1winhyun 1winhyun merged commit 5859b74 into dev Jan 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨Feat 새로운 기능 개발 ♻️Refactor 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 키워드 기반 장소 검색 기능 구현

2 participants