fix: 이벤트 디테일 조회 시 이미지 정렬 제거, feat: 이벤트 페이지 버튼 관련 기능#151
Conversation
|
Note
|
| Cohort / File(s) | Summary |
|---|---|
DB 스키마 변경 sql/init.sql |
events 및 events_detail 테이블에 button_visible BOOLEAN NOT NULL 및 button_text VARCHAR(63) NULL 컬럼 추가 |
엔티티: Events 및 EventsDetail src/main/java/.../events/persistence/entity/Events.java, src/main/java/.../events/detail/persistence/entity/EventsDetail.java |
엔티티에 buttonVisible(Boolean, not null) 및 buttonText(String, length=63) 필드 추가, 빌더/생성자 인자 확장, updateButtonVisible, updateButtonText 뮤테이터 추가 |
레포지토리(쿼리 변경) src/main/java/.../events/detail/persistence/repository/querydsl/EventsDetailRepositoryCustomImpl.java |
findAllWithImgs 쿼리에서 기존의 order by ed.id asc 절 제거 (select/leftJoin/fetchJoin는 동일) |
매퍼 변경 src/main/java/.../events/detail/common/mapper/EventsDetailMapper.java, src/main/java/.../events/events/common/mapper/EventsMapper.java |
엔티티 ↔ DTO 매핑에 buttonVisible, buttonText 포함(양방향) |
서비스 로직 수정 src/main/java/.../events/detail/domain/service/EventsDetailService.java, src/main/java/.../events/events/domain/service/EventsService.java |
업데이트 로직에 buttonVisible 및 buttonText 조건부 적용 분기 추가 (요청값이 non-null일 때만 엔티티 업데이트 호출) |
프레젠테이션 DTOs(요청/응답) src/main/java/.../events/events/presentation/dto/request/EventsCreateRequest.java, .../EventsUpdateRequest.java, .../detail/presentation/dto/request/EventsDetailCreateRequest.java, .../detail/presentation/dto/request/EventsDetailUpdateRequest.java, .../detail/presentation/dto/response/EventsDetailResponse.java, .../events/presentation/dto/response/EventsResponse.java |
Create/Update 요청 및 응답 레코드에 buttonVisible 및 buttonText 필드 추가(유효성·Swagger 어노테이션 포함), 일부 메시지/어노테이션 조정 |
테스트 변경 src/test/java/.../events/detail/domain/usecase/EventsDetailUseCaseTest.java, src/test/java/.../events/events/domain/usecase/EventsUseCaseTest.java |
테스트 데이터/빌더에 buttonVisible 및 buttonText 추가 또는 null 처리로 테스트 시나리오 반영 |
Sequence Diagram(s)
sequenceDiagram
participant Client
participant Controller
participant Service
participant Repository
participant Database
Client->>Controller: POST /events (body: buttonVisible, buttonText, ...)
Controller->>Service: createEvents(request)
Service->>Repository: save(Events entity with buttonVisible, buttonText)
Repository->>Database: INSERT events (button_visible, button_text, ...)
Database-->>Repository: OK
Repository-->>Service: persisted Events
Service-->>Controller: EventsResponse (buttonVisible, buttonText 포함)
Controller-->>Client: 201 Created (응답)
sequenceDiagram
participant Client
participant Controller
participant Service
participant Repository
participant Database
Client->>Controller: PATCH /events/{id} (body may include buttonVisible/buttonText)
Controller->>Service: updateEvents(id, request)
Service->>Repository: findById(id)
Repository->>Database: SELECT events
Database-->>Repository: Events entity
Repository-->>Service: Events
alt request.buttonVisible != null
Service->>Events: updateButtonVisible(value)
end
alt request.buttonText != null
Service->>Events: updateButtonText(value)
end
Service->>Repository: save(updated Events)
Repository->>Database: UPDATE events (...)
Database-->>Repository: OK
Repository-->>Service: updated Events
Service-->>Controller: EventsResponse
Controller-->>Client: 200 OK
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
- Main <- Develop #144 — 이전에
order by id ASC를 같은 메서드에 추가했던 PR; 정렬 관련 직접적인 상충 가능성. - 소셜 이벤트 기능 구현 #142 — 동일 커스텀 레포지토리 메서드(
findAllWithImgs)를 변경한 PR으로 직접적인 연관성 존재.
Suggested labels
✨ Feature
Suggested reviewers
- Junad-Park
- kang20
- jungbk0808
Poem
🐰
들판에 달린 작은 버튼 하나,
보일까 말까 토끼는 깡충 뛰네.
데이터에 새겨진 글자빛,
쿼리는 가벼워져 춤추고 —
축하의 당첨 소식도 함께! 🎉
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% 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 | PR 설명이 제공된 템플릿 구조를 따르고 있으나, 두 작업내용을 하나의 섹션에 포함하고 있으며 세부 설명이 최소한으로 제시되어 있습니다. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/event
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 @coderabbitai help to get the list of available commands and usage tips.
📝 Jacoco Test Coverage
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In
@src/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailCreateRequest.java:
- Around line 25-27: Fix the typo in the @Schema example for the buttonText
field in EventsDetailCreateRequest: change the example string from "당청 확인하기" to
"당첨 확인하기" so the Schema annotation for String buttonText shows the correct text.
In
@src/main/java/im/toduck/domain/events/events/presentation/dto/request/EventsCreateRequest.java:
- Around line 45-47: Fix the typo in the Schema example for the button text:
change the Korean word "당청" to "당첨" in the Schema example for the buttonText
field in EventsCreateRequest (field name: buttonText) and make the identical
correction in EventsDetailCreateRequest where the same Schema example string
appears; ensure both Schema annotations' example values read "당첨 확인하기".
In
@src/main/java/im/toduck/domain/events/events/presentation/dto/response/EventsResponse.java:
- Around line 39-43: EventsResponse currently declares isButtonVisible as
primitive boolean while the Events entity uses Boolean, risking NPE during
unboxing; update the DTO to use Boolean isButtonVisible to match Events (or
conversely change the Events entity and EventsCreateRequest to primitive boolean
and add explicit null checks in the mapper). Locate the EventsResponse class and
change the field signature for isButtonVisible to Boolean (and update its
getter/setter if present) and verify the mapping code (mapper method that maps
Events -> EventsResponse, referenced where isButtonVisible is accessed) handles
nulls appropriately; alternatively, if you choose the primitive path, update the
Events entity and EventsCreateRequest types and add null-safe logic in the
mapper to provide a default before assigning to the primitive field.
🧹 Nitpick comments (3)
src/main/java/im/toduck/domain/events/events/persistence/entity/Events.java (1)
45-46:buttonVisible기본값 누락 가능성
buttonVisible필드가@Column(nullable = false)로 선언되어 있지만, 빌더에서 이 값을 설정하지 않으면null이 할당됩니다. 엔티티 생성 시buttonVisible을 설정하지 않으면 DB 저장 시 constraint violation이 발생할 수 있습니다.빌더에서 기본값을 설정하거나,
@Builder.Default어노테이션을 사용하는 것을 권장합니다.💡 기본값 설정 예시
- @Column(nullable = false) - private Boolean buttonVisible; + @Column(nullable = false) + private Boolean buttonVisible = false;또는 Lombok
@Builder.Default사용:@Builder.Default @Column(nullable = false) private Boolean buttonVisible = false;Also applies to: 56-58, 64-64
sql/init.sql (1)
369-370: 기존 데이터 마이그레이션 고려 필요
button_visible이NOT NULL로 정의되어 있으나DEFAULT값이 없습니다. 기존 데이터가 있는 환경에서 이 스키마를 적용하려면 마이그레이션 스크립트가 필요합니다.프로덕션 환경에 기존 데이터가 있다면:
ALTER TABLE로 컬럼 추가 시DEFAULT false지정- 또는 별도 마이그레이션 스크립트 작성
-- 예시 마이그레이션 ALTER TABLE events ADD COLUMN button_visible BOOLEAN NOT NULL DEFAULT false; ALTER TABLE events ADD COLUMN button_text VARCHAR(63) NULL;Also applies to: 381-382
src/main/java/im/toduck/domain/events/detail/persistence/entity/EventsDetail.java (1)
44-48:Boolean대신boolean원시 타입 사용 고려
buttonVisible필드가nullable = false로 정의되어 있으므로, wrapper 타입Boolean대신 원시 타입boolean을 사용하는 것이 더 적절합니다. 이렇게 하면 null 값이 할당될 가능성을 컴파일 타임에 방지할 수 있습니다.♻️ 제안된 수정
@Column(nullable = false) - private Boolean buttonVisible; + private boolean buttonVisible;
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
sql/init.sqlsrc/main/java/im/toduck/domain/events/detail/common/mapper/EventsDetailMapper.javasrc/main/java/im/toduck/domain/events/detail/domain/service/EventsDetailService.javasrc/main/java/im/toduck/domain/events/detail/persistence/entity/EventsDetail.javasrc/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailCreateRequest.javasrc/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailUpdateRequest.javasrc/main/java/im/toduck/domain/events/detail/presentation/dto/response/EventsDetailResponse.javasrc/main/java/im/toduck/domain/events/events/common/mapper/EventsMapper.javasrc/main/java/im/toduck/domain/events/events/domain/service/EventsService.javasrc/main/java/im/toduck/domain/events/events/persistence/entity/Events.javasrc/main/java/im/toduck/domain/events/events/presentation/dto/request/EventsCreateRequest.javasrc/main/java/im/toduck/domain/events/events/presentation/dto/request/EventsUpdateRequest.javasrc/main/java/im/toduck/domain/events/events/presentation/dto/response/EventsResponse.java
⏰ 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: CI
🔇 Additional comments (10)
src/main/java/im/toduck/domain/events/events/domain/service/EventsService.java (1)
59-64: LGTM!기존 필드 업데이트 패턴과 일관되게 null 체크 후 업데이트하는 방식으로 구현되어 있습니다.
src/main/java/im/toduck/domain/events/detail/domain/service/EventsDetailService.java (1)
88-94: LGTM!
routingUrl업데이트 로직과 동일한 패턴으로buttonVisible과buttonText업데이트가 추가되었습니다.src/main/java/im/toduck/domain/events/detail/presentation/dto/response/EventsDetailResponse.java (1)
20-24: LGTM!
EventsDetailResponse에서Booleanwrapper 타입을 사용하여 엔티티와 타입 일관성이 유지됩니다.src/main/java/im/toduck/domain/events/detail/common/mapper/EventsDetailMapper.java (2)
27-37: LGTM!
fromEventsDetail메서드에서 새로운 필드들이 올바르게 응답 객체에 매핑되고 있습니다.
22-23: 검증 결과: 이미 검증이 적절하게 구현되어 있습니다.
EventsDetailCreateRequest에서buttonVisible필드는@NotNull어노테이션으로 필수 값으로 지정되어 있으며, 엔티티의buttonVisible컬럼도nullable = false로 설정되어 있습니다. 요청에서 값이 누락될 경우 자동으로 검증되어 DB 저장 전에 오류가 발생하므로 추가 조치가 필요하지 않습니다.src/main/java/im/toduck/domain/events/events/common/mapper/EventsMapper.java (1)
18-41: LGTM!새로운
buttonVisible과buttonText필드에 대한 매핑 로직이 올바르게 구현되었습니다. Entity에서 Response로, Request에서 Entity로의 변환이 일관성 있게 처리됩니다.src/main/java/im/toduck/domain/events/events/presentation/dto/request/EventsUpdateRequest.java (1)
35-40: LGTM!Update 요청 DTO에서
buttonVisible과buttonText필드가 optional로 적절하게 추가되었습니다. Partial update 패턴에 맞게@NotNull없이 구현되어 있어 기존 값을 유지하면서 선택적 업데이트가 가능합니다.src/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailUpdateRequest.java (1)
18-23: LGTM!Update 요청 DTO에서 새 필드들이 partial update 패턴에 맞게 optional로 적절히 추가되었습니다.
@Size제약 조건도 다른 DTO와 일관성 있게 적용되어 있습니다.src/main/java/im/toduck/domain/events/detail/persistence/entity/EventsDetail.java (2)
53-62: LGTM!생성자가 새로운 필드들을 올바르게 초기화하고 있습니다. 위에서 제안한 대로
buttonVisible을 원시 타입으로 변경할 경우, 생성자 파라미터도boolean으로 변경하면 됩니다.
71-78: LGTM!
updateButtonVisible메서드가 원시 타입boolean을 파라미터로 받아 null 값 전달을 방지하는 좋은 패턴입니다.updateButtonText메서드도 기존 update 메서드들과 일관된 패턴을 따르고 있습니다.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/test/java/im/toduck/domain/events/events/domain/usecase/EventsUseCaseTest.java (1)
152-154: 업데이트 테스트에buttonVisible과buttonText검증이 누락되었습니다.
null로 설정된 필드들이 기존 값을 유지하는지 검증하는 assertion이 필요합니다.🔧 제안된 수정
assertSoftly(softly -> { softly.assertThat(updatedEvent.getEventName()).isEqualTo(eventsUpdateRequest.eventName()); softly.assertThat(updatedEvent.getStartAt()).isEqualTo(events.getStartAt()); softly.assertThat(updatedEvent.getEndAt()).isEqualTo(events.getEndAt()); softly.assertThat(updatedEvent.getThumbUrl()).isEqualTo(events.getThumbUrl()); softly.assertThat(updatedEvent.getAppVersion()).isEqualTo(events.getAppVersion()); + softly.assertThat(updatedEvent.getButtonVisible()).isEqualTo(events.getButtonVisible()); + softly.assertThat(updatedEvent.getButtonText()).isEqualTo(events.getButtonText()); });src/test/java/im/toduck/domain/events/detail/domain/usecase/EventsDetailUseCaseTest.java (3)
119-126: 사용되지 않는 변수eventsDetailCreateRequest2이 변수는 생성만 되고 테스트에서 사용되지 않습니다. 삭제하거나 테스트에 활용하세요.
🧹 제안된 수정
- EventsDetailCreateRequest eventsDetailCreateRequest2 = - EventsDetailCreateRequest.builder() - .eventsId(savedEvent.getId()) - .routingUrl("toduck://anotherPost") - .buttonVisible(true) - .buttonText("당첨 확인하기") - .eventsDetailImgs(Arrays.asList("xyz", "123")) - .build(); -
204-211: 사용되지 않는 변수eventsDetailUpdateRequest2이 변수도 생성만 되고 사용되지 않습니다. 삭제하세요.
🧹 제안된 수정
- EventsDetailUpdateRequest eventsDetailUpdateRequest2 = - EventsDetailUpdateRequest.builder() - .eventsId(null) - .routingUrl("asas") - .buttonVisible(true) - .buttonText("당첨 확인하기") - .eventsDetailImgs(Arrays.asList()) - .build(); -
100-104:buttonVisible과buttonText검증 assertion 추가를 고려하세요.생성 테스트에서 새로 추가된 버튼 관련 필드가 올바르게 저장되었는지 검증이 누락되었습니다.
🔧 제안된 수정
assertSoftly(softly -> { softly.assertThat(eventsDetail2.getEvents().getId()) .isEqualTo(eventsDetailCreateRequest.eventsId()); softly.assertThat(eventsDetail2.getRoutingUrl()).isEqualTo(eventsDetailCreateRequest.routingUrl()); + softly.assertThat(eventsDetail2.getButtonVisible()).isEqualTo(eventsDetailCreateRequest.buttonVisible()); + softly.assertThat(eventsDetail2.getButtonText()).isEqualTo(eventsDetailCreateRequest.buttonText()); });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailCreateRequest.javasrc/main/java/im/toduck/domain/events/events/presentation/dto/request/EventsCreateRequest.javasrc/main/java/im/toduck/domain/events/events/presentation/dto/response/EventsResponse.javasrc/test/java/im/toduck/domain/events/detail/domain/usecase/EventsDetailUseCaseTest.javasrc/test/java/im/toduck/domain/events/events/domain/usecase/EventsUseCaseTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/im/toduck/domain/events/events/presentation/dto/response/EventsResponse.java
⏰ 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: CI
🔇 Additional comments (4)
src/test/java/im/toduck/domain/events/events/domain/usecase/EventsUseCaseTest.java (1)
54-56: LGTM!새로운
buttonVisible과buttonText필드가 생성 요청에 적절히 추가되었습니다.src/main/java/im/toduck/domain/events/events/presentation/dto/request/EventsCreateRequest.java (1)
41-47:buttonVisible이true일 때buttonText필수 검증 여부를 확인하세요.현재
buttonVisible은 필수이지만buttonText는 선택입니다.buttonVisible이true일 때buttonText가null이면 텍스트 없는 버튼이 표시될 수 있습니다.비즈니스 요구사항에 따라 조건부 검증이 필요할 수 있습니다.
src/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailCreateRequest.java (1)
21-27:EventsCreateRequest와 동일한 검증 패턴입니다.
buttonVisible이true일 때buttonText가 필수인지 확인이 필요합니다. 두 DTO 간 검증 로직의 일관성은 유지되고 있습니다.src/test/java/im/toduck/domain/events/detail/domain/usecase/EventsDetailUseCaseTest.java (1)
75-77: LGTM!Events 엔티티 빌더에 새로운 버튼 필드가 적절히 추가되었습니다.
✨ 작업 내용
1️⃣ 작업내용1
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.