-
Notifications
You must be signed in to change notification settings - Fork 0
[YS-310] feat: 실험 공고 수정 시, 입력 자동완성 지원을 위한 조회 API 구현 #97
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
|
""" Walkthrough이번 변경사항은 실험글 수정 시 필요한 상세 정보를 조회하는 기능을 추가합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant C as Client
participant Con as ExperimentPostController
participant Map as ExperimentPostMapper
participant Ser as ExperimentPostService
participant UC as GetExperimentPostDetailForUpdateUseCase
participant GW as ExperimentPostGateway
C->>Con: GET /{postId}/edit 요청
Con->>Map: toGetExperimentPostDetailForUpdateUseCaseInput(postId)
Map-->>Con: UseCaseInput 생성
Con->>Ser: getExperimentPostDetailForUpdate(input)
Ser->>UC: execute(input) 호출
UC->>GW: 실험글 조회 요청 (memberId, experimentPostId)
GW-->>UC: 실험글 정보 반환
UC-->>Ser: 상세 정보 Output 반환
Ser-->>Con: Output 반환
Con->>Map: toGetExperimentPostDetailForUpdateResponse(Output)
Map-->>Con: ExperimentPostDetailResponse 생성
Con-->>C: 응답 반환
Possibly related PRs
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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
🧹 Nitpick comments (2)
src/main/kotlin/com/dobby/backend/application/usecase/experiment/GetExperimentPostDetailForUpdateUseCase.kt (1)
81-98: Extension 함수들이 책임을 잘 분할하여 매핑을 수행하고 있습니다.
toExperimentPostDetailForUpdate,toSummaryForUpdate,toTargetGroupForUpdate,toAddressForUpdate등으로 변환 로직이 명확히 구분되어 있어, 코드 가독성과 유지보수성이 뛰어납니다.ExperimentPost,TargetGroup등 도메인 객체에서 사용자 정의 DTO로 변환 시, 필수/옵셔널 데이터를 명확히 구분해두면 추가 개발시 혼동을 줄일 수 있습니다.만약 항목이 많아지는 경우, 변환 로직을 별도 매퍼(Mapping) 객체로 분리하는 것도 고려해 볼 수 있습니다.
Also applies to: 100-110, 112-119, 121-128
src/main/kotlin/com/dobby/backend/presentation/api/mapper/ExperimentPostMapper.kt (1)
157-211: 코드 중복 제거를 위한 리팩토링 제안
toGetExperimentPostDetailForUpdateUseCase와toGetExperimentPostDetailResponse메소드 간에 중복된 매핑 로직이 존재합니다. 공통 매핑 로직을 추출하여 재사용성을 높이는 것이 좋겠습니다.다음과 같은 리팩토링을 제안합니다:
private fun mapToExperimentPostDetailResponse( experimentPostId: String, title: String, uploadDate: LocalDateTime, uploaderName: String, views: Int, recruitStatus: RecruitStatus, summary: Any, targetGroup: Any, address: Any, content: String, imageList: List<String>, isAuthor: Boolean, isUploaderActive: Boolean, alarmAgree: Boolean ): ExperimentPostDetailResponse { return ExperimentPostDetailResponse( experimentPostId = experimentPostId, title = title, uploadDate = uploadDate, uploaderName = uploaderName, views = views, recruitStatus = recruitStatus, summary = when(summary) { is GetExperimentPostDetailForUpdateUseCase.ExperimentPostDetailForUpdate.Summary -> summary.toResponse() is GetExperimentPostDetailUseCase.ExperimentPostDetail.Summary -> summary.toResponse() else -> throw IllegalArgumentException("Unsupported summary type") }, targetGroup = when(targetGroup) { is GetExperimentPostDetailForUpdateUseCase.ExperimentPostDetailForUpdate.TargetGroup -> targetGroup.toResponse() is GetExperimentPostDetailUseCase.ExperimentPostDetail.TargetGroup -> targetGroup.toResponse() else -> throw IllegalArgumentException("Unsupported target group type") }, address = when(address) { is GetExperimentPostDetailForUpdateUseCase.ExperimentPostDetailForUpdate.Address -> address.toResponse() is GetExperimentPostDetailUseCase.ExperimentPostDetail.Address -> address.toResponse() else -> throw IllegalArgumentException("Unsupported address type") }, content = content, imageList = imageList, isAuthor = isAuthor, isUploaderActive = isUploaderActive, alarmAgree = alarmAgree ) }이 공통 메소드를 사용하여 기존 메소드들을 다음과 같이 수정할 수 있습니다:
fun toGetExperimentPostDetailForUpdateUseCase(response: GetExperimentPostDetailForUpdateUseCase.Output): ExperimentPostDetailResponse { return mapToExperimentPostDetailResponse( experimentPostId = response.experimentPostDetail.experimentPostId, title = response.experimentPostDetail.title, uploadDate = response.experimentPostDetail.uploadDate, uploaderName = response.experimentPostDetail.uploaderName, views = response.experimentPostDetail.views, recruitStatus = response.experimentPostDetail.recruitStatus, summary = response.experimentPostDetail.summary, targetGroup = response.experimentPostDetail.targetGroup, address = response.experimentPostDetail.address, content = response.experimentPostDetail.content, imageList = response.experimentPostDetail.imageList, isAuthor = response.experimentPostDetail.isAuthor, isUploaderActive = response.experimentPostDetail.isUploaderActive, alarmAgree = response.experimentPostDetail.alarmAgree ) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/main/kotlin/com/dobby/backend/application/service/ExperimentPostService.kt(2 hunks)src/main/kotlin/com/dobby/backend/application/usecase/experiment/GetExperimentPostDetailForUpdateUseCase.kt(1 hunks)src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt(1 hunks)src/main/kotlin/com/dobby/backend/presentation/api/mapper/ExperimentPostMapper.kt(1 hunks)src/test/kotlin/com/dobby/backend/application/usecase/experiment/GetExperimentPostDetailForUpdateUseCaseTest.kt(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (9)
src/main/kotlin/com/dobby/backend/application/usecase/experiment/GetExperimentPostDetailForUpdateUseCase.kt (3)
15-23: 클래스 선언과 Input 데이터 클래스 구조가 적절해 보입니다.
클래스와Input데이터 클래스가 각각의 책임을 명확히 분리하여 유스케이스를 호출할 때 필요한 파라미터를 깔끔하게 전달하고 있습니다. 대체로 좋은 구조로 보이며 추가적인 파라미터가 필요할 때도 변경 범위가 명확해져 유지보수에 유리합니다.
24-27: Output 데이터 클래스와 execute 메서드의 예외 처리 흐름이 적절합니다.
Output데이터 클래스를 통해 반환 데이터의 구조를 명확히 정의한 점이 가독성과 유지보수성에 좋습니다.execute메서드 호출 시, Gateway의findExperimentPostByMemberIdAndPostId(...)가null인 경우 예외(ExperimentPostNotFoundException)를 던지는 것은 비정상 상황 처리를 명확히 해줍니다.- 필요하다면 예외 케이스에 대한 구체적인 로깅도 고려하실 수 있습니다.
Also applies to: 69-78
28-67: 중첩된 데이터 클래스들의 역할 분리와 구조가 명확합니다.
ExperimentPostDetailForUpdate내의Summary,TargetGroup,Address등 세부 정보를 별도의 데이터 클래스로 분리하여 가독성이 좋습니다.- 필요한 정보가 체계적으로 배열되어 있어서, 후속 기능 확장(예: 다른 필드 추가)에도 유연하게 대응할 수 있을 것으로 보입니다.
src/test/kotlin/com/dobby/backend/application/usecase/experiment/GetExperimentPostDetailForUpdateUseCaseTest.kt (3)
21-29: mockk 라이브러리를 이용한 멤버 객체(Mock) 설정이 적절합니다.
member객체의id,name,deletedAt등을 명확히 정의하여 테스트 환경을 잘 구성했습니다.- 이후 다른 테스트 케이스에도 재사용 가능하므로, 불필요한 중복 mock 생성을 줄이는 면에서도 유리합니다.
70-85: 작성자 본인에게 정상적으로 데이터를 반환하는 시나리오 테스트가 명확합니다.
given-when-then구조로 흐름이 분리되어 있어 가독성이 좋습니다.isAuthor필드가true로 반환되는지 확인하는 부분이 핵심 로직 검증에 포함되어 잘 처리되었습니다.
87-118: 실패 케이스(작성자가 아니거나 잘못된 ID) 테스트가 체계적으로 분리되어 있습니다.
- 작성자가 아닌 경우와 존재하지 않는 게시글 ID를 각각
ExperimentPostNotFoundException이 발생하는지 확인하는 로직이 분명합니다.- 이 부분은 예외 처리가 의도한 대로 동작하는지 검증하는 핵심 코드로 보이며, 유지보수 시에도 쉽게 참조 가능합니다.
src/main/kotlin/com/dobby/backend/application/service/ExperimentPostService.kt (2)
31-31: 신규 UseCase 주입 방식이 분리되어 있어 의존성 구조가 명확합니다.
private val getExperimentPostForUpdateUseCase를 주입받아 변경에 쉽게 대응할 수 있습니다.- 새로운 유스케이스가 추가되더라도 차후 확장 용이성이 높아 보입니다.
51-54: getExperimentPostDetailForUpdate 메서드의 역할이 분명합니다.
- 트랜잭션 범주 내에서 단순히 UseCase의
execute를 호출만 담당하므로, 서비스 레이어 역할을 명확히 구분한 점이 우수합니다.- 필요하다면 향후 로깅, 권한 체크 등 부가 로직을 추가하기도 용이합니다.
src/main/kotlin/com/dobby/backend/presentation/api/mapper/ExperimentPostMapper.kt (1)
183-211: 구현이 깔끔하고 잘 되어있습니다!각 확장 함수가 명확한 책임을 가지고 있으며, 코드가 잘 구조화되어 있습니다.
src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt
Show resolved
Hide resolved
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: 0
🧹 Nitpick comments (2)
src/main/kotlin/com/dobby/backend/presentation/api/mapper/ExperimentPostMapper.kt (2)
164-181: 코드 중복을 제거하여 유지보수성을 향상시킬 수 있습니다.
toGetExperimentPostDetailForUpdateResponse와toGetExperimentPostDetailResponse함수가 매우 유사한 로직을 가지고 있습니다. 공통 로직을 추출하여 재사용 가능한 private 함수로 만드는 것을 고려해보세요.예시:
+ private fun toExperimentPostDetailResponse( + experimentPostId: String, + title: String, + uploadDate: LocalDateTime, + uploaderName: String, + views: Int, + recruitStatus: RecruitStatus, + summary: ExperimentPostDetailResponse.SummaryResponse, + targetGroup: ExperimentPostDetailResponse.TargetGroupResponse, + address: ExperimentPostDetailResponse.AddressResponse, + content: String, + imageList: List<String>, + isAuthor: Boolean, + isUploaderActive: Boolean, + alarmAgree: Boolean + ): ExperimentPostDetailResponse { + return ExperimentPostDetailResponse( + experimentPostId = experimentPostId, + title = title, + uploadDate = uploadDate, + uploaderName = uploaderName, + views = views, + recruitStatus = recruitStatus, + summary = summary, + targetGroup = targetGroup, + address = address, + content = content, + imageList = imageList, + isAuthor = isAuthor, + isUploaderActive = isUploaderActive, + alarmAgree = alarmAgree + ) + }
183-211: 확장 함수의 활용이 좋습니다!
Summary,TargetGroup,Address에 대한 확장 함수를 사용하여 코드의 가독성을 높였습니다. 다만, 이 확장 함수들도 기존 코드와 중복되어 있으므로, 공통 인터페이스를 도입하여 코드 중복을 제거하는 것을 고려해보세요.예시:
interface ExperimentPostDetail { interface Summary { val startDate: LocalDateTime val endDate: LocalDateTime val leadResearcher: String val matchType: MatchType val reward: Int val count: Int val timeRequired: Int } // TargetGroup, Address 인터페이스도 유사하게 정의 }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt(1 hunks)src/main/kotlin/com/dobby/backend/presentation/api/mapper/ExperimentPostMapper.kt(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (1)
src/main/kotlin/com/dobby/backend/presentation/api/mapper/ExperimentPostMapper.kt (1)
157-162: 함수 구현이 깔끔합니다!현재 멤버 ID와 실험 게시물 ID를 사용하여 UseCase 입력을 생성하는 로직이 명확하게 구현되어 있습니다.
chock-cho
left a comment
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.
LGTM👍👍 수고하셨어요!
* feat: add GetExperimentPostDetailForUpdateUseCase logic * test: add GetExperimentPostDetailForUpdateUseCase test code * refactor: rename mapper class for consistency
* feat: add GetExperimentPostDetailForUpdateUseCase logic * test: add GetExperimentPostDetailForUpdateUseCase test code * refactor: rename mapper class for consistency
* feat: add GetExperimentPostDetailForUpdateUseCase logic * test: add GetExperimentPostDetailForUpdateUseCase test code * refactor: rename mapper class for consistency
💡 작업 내용
✅ 셀프 체크리스트
🙋🏻 확인해주세요
🔗 Jira 티켓
https://yappsocks.atlassian.net/browse/YS-310
Summary by CodeRabbit
새로운 기능
테스트