-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/12 layerd to hexagonal screen #18
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이 변경 사항은 "screen" 이미지 관리 기능을 위한 전체적인 백엔드 레이어를 도입합니다. 컨트롤러, 서비스, 포트, 어댑터, 매퍼, JPA 엔터티, 예외, 도메인 모델, DTO, 리포지토리 등 관련 컴포넌트가 모두 추가되어, 화면 이미지의 생성, 수정, 조회를 REST API로 제공합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ScreenWebAdapter
participant CreateScreenService
participant SaveScreenPort
participant AdminUtils
participant FileUtil
Client->>ScreenWebAdapter: POST /screen (image)
ScreenWebAdapter->>CreateScreenService: execute(image)
CreateScreenService->>AdminUtils: getCurrentAdminId()
CreateScreenService->>FileUtil: uploadFile(image, path)
CreateScreenService->>SaveScreenPort: saveScreen(Screen)
CreateScreenService-->>ScreenWebAdapter: ScreenResponse
ScreenWebAdapter-->>Client: 201 Created + ScreenResponse
sequenceDiagram
participant Client
participant ScreenWebAdapter
participant UpdateScreenService
participant FindScreenPort
participant FileUtil
participant SaveScreenPort
Client->>ScreenWebAdapter: PATCH /screen/{id} (image)
ScreenWebAdapter->>UpdateScreenService: execute(id, image)
UpdateScreenService->>FindScreenPort: findByIdOrNull(id)
alt 존재하지 않음
UpdateScreenService-->>ScreenWebAdapter: ScreenNotFoundException
else 존재함
UpdateScreenService->>FileUtil: uploadFile(image, path)
UpdateScreenService->>FileUtil: deleteFile(oldImage, path)
UpdateScreenService->>SaveScreenPort: saveScreen(Screen)
UpdateScreenService-->>ScreenWebAdapter: ScreenResponse
end
ScreenWebAdapter-->>Client: ScreenResponse
sequenceDiagram
participant Client
participant ScreenWebAdapter
participant QueryScreenService
participant FindScreenPort
participant FileUtil
Client->>ScreenWebAdapter: GET /screen
ScreenWebAdapter->>QueryScreenService: execute()
QueryScreenService->>FindScreenPort: findAll()
QueryScreenService->>FileUtil: generateObjectUrl(image)
QueryScreenService-->>ScreenWebAdapter: List<QueryScreenResponse>
ScreenWebAdapter-->>Client: List<QueryScreenResponse>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20분 Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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 (
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
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: 9
🧹 Nitpick comments (7)
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt (1)
18-19: 속성명 명명 규칙 개선 제안
createAt과modifyAt대신createdAt과modifiedAt또는createdDate와modifiedDate사용을 고려해보세요. 이는 일반적인 Kotlin/Java 명명 규칙에 더 부합합니다.- val createAt: LocalDateTime, - val modifyAt: LocalDateTime, + val createdAt: LocalDateTime, + val modifiedAt: LocalDateTime,casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/CreateScreenService.kt (1)
16-18: 문서화 오류 수정 필요Property 문서에서
userUtils로 표기되어 있지만 실제로는adminUtils입니다.- * @property userUtils 사용자 인증 유틸리티 + * @property adminUtils 관리자 인증 유틸리티casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt (1)
18-18: 이미지 속성의 가변성을 재고해보세요.
image속성이var로 선언되어 있어 의도하지 않은 수정이 발생할 수 있습니다. JPA 엔터티에서는 불변성을 유지하는 것이 좋습니다.다음과 같이 불변으로 만드는 것을 고려해보세요:
- var image: String, + val image: String,그리고 이미지 업데이트가 필요한 경우 새로운 엔터티 인스턴스를 생성하도록 비즈니스 로직을 조정하세요.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt (1)
19-20: 기본값으로 현재 시간 사용에 대한 개선을 고려하세요.
LocalDateTime.now()를 기본값으로 사용하면 테스트가 어려워질 수 있습니다. 시간 제공자를 주입받거나 팩토리 메서드를 사용하는 것을 고려해보세요.예를 들어:
data class Screen( val id: UUID? = null, val image: String, val adminId: UUID, val createdAt: LocalDateTime, val modifiedAt: LocalDateTime, ) { companion object { fun create(image: String, adminId: UUID): Screen = Screen( image = image, adminId = adminId, createdAt = LocalDateTime.now(), modifiedAt = LocalDateTime.now() ) } }casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt (1)
23-25: 저장 메서드의 반환값 고려가 필요합니다.
saveScreen메서드가 저장된 엔터티를 반환하지 않습니다. 생성된 ID나 업데이트된 엔터티 정보가 필요한 경우를 고려해보세요.- override fun saveScreen(screen: Screen) { - screenRepository.save(screenMapper.toEntity(screen)) - } + override fun saveScreen(screen: Screen): Screen { + val savedEntity = screenRepository.save(screenMapper.toEntity(screen)) + return screenMapper.toModel(savedEntity) + }casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt (2)
54-58: 파일 업로드 검증 로직 추가를 고려해보세요.업로드되는 이미지 파일에 대한 검증(파일 크기, 형식, 내용 등)이 컨트롤러 레벨에서 필요할 수 있습니다.
@PatchMapping("/{screen-id}") fun updateScreen( @PathVariable(name = "screen-id") id: UUID, - @RequestPart(name = "image") image: MultipartFile, + @RequestPart(name = "image") @Valid image: MultipartFile, ): ScreenResponse = updateScreenUseCase.execute(id, image)또는 커스텀 밸리데이션 어노테이션을 고려해보세요:
@RequestPart(name = "image") @ImageFile image: MultipartFile,
26-26: KDoc 주석의 오타를 수정해주세요.KDoc에서
@property screenService로 언급되어 있지만 실제로는 세 개의 유스케이스를 사용합니다.- * @property screenService 화면 정보 비즈니스 로직을 처리하는 서비스 + * @property createScreenUseCase 화면 생성 유스케이스 + * @property updateScreenUseCase 화면 수정 유스케이스 + * @property queryScreenUseCase 화면 조회 유스케이스
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
📒 Files selected for processing (17)
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/ScreenResponse.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/mapper/screen/ScreenMapper.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/repository/ScreenRepository.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/CreateScreenUseCase.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/QueryScreenUseCase.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/UpdateScreenUseCase.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/FindScreenPort.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/SaveScreenPort.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/CreateScreenService.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/QueryScreenService.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/UpdateScreenService.kt(1 hunks)casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt(1 hunks)
🔇 Additional comments (17)
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt (1)
15-20: 잘 구현된 응답 DTOdata class 사용과 포괄적인 한국어 문서화가 잘 되어 있습니다. UUID 사용과 LocalDateTime 타입 선택도 적절합니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/ScreenResponse.kt (1)
9-11: 간결하고 적절한 응답 DTO단순한 구조로 목적에 맞게 잘 구현되었습니다. 한국어 문서화도 명확하게 작성되어 있습니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/SaveScreenPort.kt (1)
9-16: 헥사고날 아키텍처 아웃바운드 포트 적절한 구현화면 저장을 위한 포트 인터페이스가 헥사고날 아키텍처 원칙에 맞게 잘 구현되었습니다. 도메인 객체를 매개변수로 받아 영속성 계층의 세부사항을 추상화하고 있습니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/FindScreenPort.kt (1)
10-25: 조회 포트 인터페이스 우수한 구현두 가지 조회 메서드가 명확하게 정의되어 있고,
findByIdOrNull네이밍은 Kotlin 관례를 잘 따르고 있습니다. 헥사고날 아키텍처의 아웃바운드 포트 역할을 적절히 수행하고 있습니다.casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/QueryScreenUseCase.kt (1)
9-16: 유스케이스 인터페이스 구조는 적절함의존성 문제를 제외하면, 인바운드 포트로서의 구조와 한국어 문서화는 잘 되어 있습니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/repository/ScreenRepository.kt (1)
1-11: 헥사고날 아키텍처에 적합한 깔끔한 Repository 구현Spring Data JPA를 활용한 표준적인 repository 인터페이스 구현이 잘 되어 있습니다. UUID를 기본키로 사용하는 것도 적절하며, 한국어 문서화도 명확합니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt (1)
12-14: 예외 싱글톤 패턴 일관성 확인 및 승인ScreenNotFoundException을 Kotlin의
object키워드로 구현하여 메모리 효율성과 일관적인 에러 처리 구조를 지킨 점이 적절합니다. 아래 예외 클래스들도 동일한object싱글톤 패턴을 사용하고 있음을 확인했습니다:
- casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt
- casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/notice/exception/AttachFileNotFoundException.kt
- casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/notice/exception/NoticeNotFoundException.kt
위 변경사항을 승인합니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/CreateScreenUseCase.kt (1)
10-13: 헥사고날 아키텍처의 입력 포트 인터페이스가 잘 정의됨suspend 함수를 사용한 비동기 처리와 명확한 입출력 타입 정의가 적절합니다. 유스케이스 인터페이스가 비즈니스 로직을 잘 추상화하고 있습니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/UpdateScreenService.kt (1)
20-25: 헥사고날 아키텍처 구현이 잘 되어 있습니다.
UpdateScreenUseCase인터페이스를 구현하여 포트 패턴을 올바르게 적용했고, 의존성 주입을 통해 외부 어댑터와의 결합도를 낮췄습니다.@Transactional어노테이션도 적절히 적용되어 있습니다.casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/mapper/screen/ScreenMapper.kt (1)
11-28: MapStruct 매퍼 구현이 완벽합니다.도메인 모델과 JPA 엔터티 간의 변환을 위한 MapStruct 매퍼가 올바르게 구현되어 있습니다. Spring 컴포넌트 모델 설정과 양방향 변환 메서드가 적절히 정의되어 있고, 헥사고날 아키텍처의 어댑터 패턴을 잘 따르고 있습니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/QueryScreenService.kt (1)
16-21: 헥사고날 아키텍처 구현이 우수합니다.
QueryScreenUseCase인터페이스를 구현하여 포트 패턴을 올바르게 적용했고, 비즈니스 로직과 외부 의존성이 잘 분리되어 있습니다.casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt (1)
15-21: JPA 엔터티 구현이 적절합니다.테이블 매핑, BaseEntity 상속, UUID의 BINARY(16) 저장 방식이 모두 올바르게 구현되어 있습니다. 헥사고날 아키텍처의 어댑터 레이어에 적합한 구조입니다.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt (2)
15-21: 도메인 모델 설계가 우수합니다.불변 데이터 클래스로 구현되어 있고, 헥사고날 아키텍처의 도메인 레이어에 적합한 순수한 비즈니스 로직을 담고 있습니다. 외부 의존성이 없어 테스트하기 용이합니다.
28-28: 구문 오류를 수정하세요.등호 다음에 공백이 누락되었습니다.
- fun updateImage(newImage: String): Screen =copy(image = newImage) + fun updateImage(newImage: String): Screen = copy(image = newImage)Likely an incorrect or invalid review comment.
casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt (2)
18-22: 헥사고날 아키텍처 구현이 적절합니다.
@Component어노테이션과 포트 인터페이스들을 구현하여 헥사고날 아키텍처의 아웃바운드 어댑터 패턴을 잘 구현했습니다. 도메인과 인프라스트럭처 계층 간의 적절한 분리를 보여줍니다.
31-35: 널 안전성 처리가 적절합니다.
findByIdOrNull메서드에서 엘비스 연산자와let을 사용한 널 처리가 코틀린다운 방식으로 잘 구현되었습니다.casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt (1)
28-34: 헥사고날 아키텍처의 인바운드 어댑터 구현이 우수합니다.REST 컨트롤러가 유스케이스 포트들을 의존성으로 주입받아 헥사고날 아키텍처를 잘 구현했습니다. 비즈니스 로직과 웹 계층이 적절히 분리되었습니다.
Summary by CodeRabbit
신규 기능
버그 수정