Skip to content

Conversation

@ggamnunq
Copy link
Contributor

@ggamnunq ggamnunq commented Aug 29, 2025

좋아요 API 구현

  • 명소 좋아요 API
  • 축제 좋아요 API

Tour 정보 수정

  • 명소 문자열 정보에 포함된 태그 제거
  • 명소 저장 시 이용객 분포 정보 같이 저장하도록 변경

Summary by CodeRabbit

  • 신기능
    • 장소/축제 좋아요 토글 API 추가: PATCH /api/places/like/{placeId}, PATCH /api/festivals/like/{festivalId} (성공 여부와 메시지 반환)
    • 장소 상세에 방문자 분포 정보 자동 제공
    • 축제 소개 텍스트에서 HTML 태그 제거로 더 깔끔한 표시
  • API 변경
    • placeId·festivalId 누락 시 명확한 오류 코드/메시지 반환
  • 안정성
    • 데이터 수집/저장 과정의 트랜잭션 처리 개선으로 부분 성공 및 내결함성 향상

  - 문자열 정보에 포함된 태그 제거 후 저장
  - 명소 저장 시 분포 정보 저장하도록 변경
@ggamnunq ggamnunq self-assigned this Aug 29, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 29, 2025

Walkthrough

페스티벌/장소 좋아요 토글 기능이 추가되어 컨트롤러, 서비스, 리포지토리, DTO가 확장되었고, 좋아요 엔티티는 복합키(EmbeddedId)로 전환되었습니다. 투어 수집 로직은 항목별 트랜잭션 저장과 문자열 태그 제거가 도입되었으며, Place의 연관관계와 에러 상태 값이 보강되었습니다.

Changes

Cohort / File(s) Summary
Controller: like 엔드포인트 추가
src/main/kotlin/.../festival/controller/FestivalController.kt, src/main/kotlin/.../place/controller/PlaceController.kt
두 컨트롤러에 PATCH /like/{id} 엔드포인트 추가 및 CommandService 의존성 주입. 응답 DTO 매핑 추가.
Service: Command 토글 로직 추가
src/main/kotlin/.../festival/service/FestivalCommandService.kt, src/main/kotlin/.../place/service/PlaceCommandService.kt
현재 사용자 기준 좋아요 토글 처리, 존재 시 삭제, 미존재 시 생성. DataIntegrityViolationException 처리로 동시성 대응. 트랜잭션 적용.
Repository: (Entity, User) 단건 질의/삭제로 변경
src/main/kotlin/.../festival/repository/FestivalLikesRepository.kt, src/main/kotlin/.../place/repository/PlaceLikeRepository.kt
place/festival 단독 조회 제거. (festival/place, user) 기반 단건 조회/삭제 메서드 추가.
Domain: Like 엔티티 복합키 전환
src/main/kotlin/.../festival/domain/FestivalLike.kt, src/main/kotlin/.../festival/domain/FestivalLikeId.kt, src/main/kotlin/.../place/domain/PlaceLike.kt, src/main/kotlin/.../place/domain/PlaceLikeId.kt
@EmbeddedId 기반 복합키 도입, @mapsid로 User/대상 엔티티 키 매핑. Like 클래스 open으로 변경. PlaceLike는 BaseEntity 상속.
DTO: 좋아요 응답 추가 및 포맷 유지
src/main/kotlin/.../festival/dto/FestivalLikeResponseDTO.kt, src/main/kotlin/.../place/dto/PlaceResponseDTO.kt, src/main/kotlin/.../festival/dto/FestivalListResponseDTO.kt
좋아요 응답 DTO 추가(snake_case). PlaceResponseDTO에 LikeDto 추가. FestivalListResponseDTO는 공백만 변경.
Domain: Place 연관관계 보강
src/main/kotlin/.../place/domain/Place.kt
visitorDistribution를 비널(nullable)→널 아님으로 변경, @OnetoOne에 PERSIST/MERGE 캐스케이드 추가.
Tour: 정제 및 저장 전략 변경
src/main/kotlin/.../tourApi/service/TourCommandService.kt, src/main/kotlin/.../tourApi/util/TourFestivalConverter.kt, src/main/kotlin/.../tourApi/util/TourPlaceUtil.kt
HTML 태그 제거 유틸 적용, VisitorDistribution 랜덤 생성, 일괄 저장→항목별 REQUIRES_NEW 저장으로 변경, pageNo 구성 상수화.
Global: 에러 상태 추가
src/main/kotlin/.../global/apiPayload/code/status/ErrorStatus.kt
PLACE_ID_REQUIRED, FESTIVAL_ID_REQUIRED 상수 추가.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant C as Controller (/like/{id})
  participant S as CommandService
  participant AR as AuthService
  participant R as Repository (Entity,Like)
  participant DB as DB

  U->>C: PATCH /like/{entityId}
  C->>S: like(entityId)
  S->>S: entityId null 검사
  S->>AR: getCurrentUser()
  AR-->>S: User
  S->>R: find Entity by id
  R-->>S: Entity or null
  alt Entity 없음
    S-->>C: throw FESTIVAL/PLACE_NOT_FOUND
  else Entity 있음
    S->>R: findBy(Entity, User)
    R-->>S: Like or null
    alt Like 존재
      S->>R: deleteBy(Entity, User)
      R-->>S: 삭제됨
      S-->>C: {success:true, message:"좋아요 취소 성공"}
    else Like 없음
      S->>DB: save(Like with EmbeddedId)
      alt 저장 충돌(DataIntegrityViolation)
        S->>R: deleteBy(Entity, User)
        R-->>S: 삭제됨
        S-->>C: {success:true, message:"좋아요 취소 성공"}
      else 저장 성공
        S-->>C: {success:true, message:"좋아요 성공"}
      end
    end
  end
  C-->>U: ApiResponse(Like DTO)
Loading
sequenceDiagram
  autonumber
  participant T as TourCommandService
  participant U as External API Data
  participant C as Converter
  participant PR as PlaceRepository
  participant TX as Transaction(REQUIRES_NEW)

  U-->>T: place item list
  T->>C: 문자열 필드 removeTag()
  C-->>T: 정제된 Place 목록(+VisitorDistribution 랜덤 생성)
  loop 각 Place
    T->>TX: saveOne(place)
    TX->>PR: save(place)
    PR-->>TX: persisted
    TX-->>T: 완료(개별 트랜잭션)
    note over T: 아이템 실패는 캐치 후 이어감
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

당근 깃털 들고 톡톡, 패치 패치!
좋아요는 토글로 딱딱, 키는 둘이 착착.
태그는 쓱쓱 지우고, 저장은 한 알씩 콩콩.
분산 손님도 채워넣고, 에러 코드는 쾅쾅!
오늘도 깡총—코드는 단단, 릴리즈는 가벼웡 🥕🐇

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Free

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dfc7500 and 0f12187.

📒 Files selected for processing (18)
  • src/main/kotlin/busanVibe/busan/domain/festival/controller/FestivalController.kt (3 hunks)
  • src/main/kotlin/busanVibe/busan/domain/festival/domain/FestivalLike.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/festival/domain/FestivalLikeId.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/festival/dto/FestivalLikeResponseDTO.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/festival/dto/FestivalListResponseDTO.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/festival/repository/FestivalLikesRepository.kt (2 hunks)
  • src/main/kotlin/busanVibe/busan/domain/festival/service/FestivalCommandService.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/controller/PlaceController.kt (4 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/domain/Place.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/domain/PlaceLike.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/domain/PlaceLikeId.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/dto/PlaceResponseDTO.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/repository/PlaceLikeRepository.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/place/service/PlaceCommandService.kt (1 hunks)
  • src/main/kotlin/busanVibe/busan/domain/tourApi/service/TourCommandService.kt (6 hunks)
  • src/main/kotlin/busanVibe/busan/domain/tourApi/util/TourFestivalConverter.kt (2 hunks)
  • src/main/kotlin/busanVibe/busan/domain/tourApi/util/TourPlaceUtil.kt (2 hunks)
  • src/main/kotlin/busanVibe/busan/global/apiPayload/code/status/ErrorStatus.kt (1 hunks)

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Join our Discord community for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ggamnunq ggamnunq merged commit d5cf613 into main Aug 29, 2025
2 checks passed
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.

2 participants