From ca600ca787f06a12d381e3721c1576528265dffd Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:44:40 +0900 Subject: [PATCH 01/17] feat ( #12 ) : QueryScreenResponse --- .../dto/response/QueryScreenResponse.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt new file mode 100644 index 0000000..c1714ba --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/QueryScreenResponse.kt @@ -0,0 +1,20 @@ +package hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response + +import java.time.LocalDateTime +import java.util.UUID + +/** + * 화면 정보 조회 응답을 위한 데이터 클래스입니다. + * 화면의 상세 정보와 메타데이터를 클라이언트에 반환할 때 사용됩니다. + * + * @property id 화면 정보의 고유 식별자 (UUID) + * @property image 화면에 표시될 이미지의 URL 또는 경로 + * @property createAt 화면 정보가 생성된 일시 + * @property modifyAt 화면 정보가 마지막으로 수정된 일시 + */ +data class QueryScreenResponse( + val id: UUID, + val image: String, + val createAt: LocalDateTime, + val modifyAt: LocalDateTime, +) From aa9ce656b11689d6591d6dd67d88a54d131bfdc4 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:44:47 +0900 Subject: [PATCH 02/17] feat ( #12 ) : ScreenResponse --- .../adapter/in/screen/dto/response/ScreenResponse.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/ScreenResponse.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/ScreenResponse.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/ScreenResponse.kt new file mode 100644 index 0000000..9675153 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/dto/response/ScreenResponse.kt @@ -0,0 +1,11 @@ +package hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response + +/** + * 화면 정보 응답을 위한 데이터 클래스입니다. + * 클라이언트에게 반환되는 화면 관련 정보를 담고 있습니다. + * + * @property image 화면에 표시될 이미지의 URL 또는 경로 + */ +data class ScreenResponse( + val image: String, +) From a5cea7170977724be302edcf34b6c7407210c072 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:44:57 +0900 Subject: [PATCH 03/17] feat ( #12 ) : ScreenWebAdapter --- .../adapter/in/screen/ScreenWebAdapter.kt | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt new file mode 100644 index 0000000..fd4af41 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/in/screen/ScreenWebAdapter.kt @@ -0,0 +1,67 @@ +package hs.kr.entrydsm.feed.adapter.`in`.screen + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.QueryScreenResponse +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.ScreenResponse +import hs.kr.entrydsm.feed.application.screen.port.`in`.CreateScreenUseCase +import hs.kr.entrydsm.feed.application.screen.port.`in`.QueryScreenUseCase +import hs.kr.entrydsm.feed.application.screen.port.`in`.UpdateScreenUseCase +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PatchMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestPart +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController +import org.springframework.web.multipart.MultipartFile +import java.util.UUID + +/** + * 화면 정보 관련 HTTP 요청을 처리하는 웹 어댑터 클래스입니다. + * + * 이 클래스는 화면 정보와 관련된 모든 HTTP 엔드포인트를 제공하며, + * 클라이언트의 요청을 적절한 서비스 메서드로 라우팅합니다. + * + * @property screenService 화면 정보 비즈니스 로직을 처리하는 서비스 + */ +@RestController +@RequestMapping("/screen") +class ScreenWebAdapter( + private val createScreenUseCase: CreateScreenUseCase, + private val updateScreenUseCase: UpdateScreenUseCase, + private val queryScreenUseCase: QueryScreenUseCase, +) { + /** + * 새로운 화면 이미지를 업로드하고 저장합니다. + * + * @param image 업로드할 화면 이미지 파일 + * @return 업로드된 화면 이미지 정보가 포함된 응답 객체 + */ + @ResponseStatus(value = HttpStatus.CREATED) + @PostMapping + suspend fun createScreen( + @RequestPart(name = "image") image: MultipartFile, + ): ScreenResponse = createScreenUseCase.execute(image) + + /** + * 기존 화면 이미지를 새로운 이미지로 업데이트합니다. + * + * @param id 업데이트할 화면의 고유 식별자 + * @param image 새로운 화면 이미지 파일 + * @return 업데이트된 화면 이미지 정보가 포함된 응답 객체 + */ + @PatchMapping("/{screen-id}") + fun updateScreen( + @PathVariable(name = "screen-id") id: UUID, + @RequestPart(name = "image") image: MultipartFile, + ): ScreenResponse = updateScreenUseCase.execute(id, image) + + /** + * 모든 화면 이미지 목록을 조회합니다. + * + * @return 화면 이미지 목록이 포함된 응답 객체 리스트 + */ + @GetMapping + fun queryScreen(): List = queryScreenUseCase.execute() +} From f19040b59801cbb07a5c596fa984bba8f4d62efe Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:45:06 +0900 Subject: [PATCH 04/17] feat ( #12 ) : ScreenJpaEntity --- .../out/entity/screen/ScreenJpaEntity.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt new file mode 100644 index 0000000..fdbb5e8 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/entity/screen/ScreenJpaEntity.kt @@ -0,0 +1,21 @@ +package hs.kr.entrydsm.feed.adapter.out.entity.screen + +import hs.kr.entrydsm.feed.global.entity.BaseEntity +import jakarta.persistence.Column +import jakarta.persistence.Entity +import java.util.UUID + +/** + * 화면 정보를 데이터베이스에 저장하기 위한 JPA 엔티티 클래스입니다. + * + * @property image 화면에 표시될 이미지의 경로 또는 URL + * @property adminId 화면을 등록한 관리자 ID (UUID) + * @param id 엔티티의 고유 식별자 (생성 시 자동 생성됨) + */ +@Entity(name = "tbl_screen") +class ScreenJpaEntity( + id: UUID? = null, + var image: String, + @Column(columnDefinition = "BINARY(16)") + val adminId: UUID, +) : BaseEntity(id) From 6fefbbe907fc9d5169219259d9f454e6bf80d154 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:45:15 +0900 Subject: [PATCH 05/17] feat ( #12 ) : ScreenMapper --- .../adapter/out/mapper/screen/ScreenMapper.kt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/mapper/screen/ScreenMapper.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/mapper/screen/ScreenMapper.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/mapper/screen/ScreenMapper.kt new file mode 100644 index 0000000..037c49d --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/mapper/screen/ScreenMapper.kt @@ -0,0 +1,28 @@ +package hs.kr.entrydsm.feed.adapter.out.mapper.screen + +import hs.kr.entrydsm.feed.adapter.out.entity.screen.ScreenJpaEntity +import hs.kr.entrydsm.feed.model.screen.Screen +import org.mapstruct.Mapper + +/** + * 화면(Screen) 도메인 모델과 JPA 엔티티 간의 변환을 담당하는 매퍼 인터페이스입니다. + * MapStruct를 사용하여 구현체가 자동으로 생성됩니다. + */ +@Mapper(componentModel = "spring") +interface ScreenMapper { + /** + * Screen 도메인 모델을 JPA 엔티티로 변환합니다. + * + * @param model 변환할 Screen 도메인 모델 + * @return 변환된 ScreenJpaEntity 인스턴스 + */ + fun toEntity(model: Screen): ScreenJpaEntity + + /** + * JPA 엔티티를 Screen 도메인 모델로 변환합니다. + * + * @param entity 변환할 ScreenJpaEntity 인스턴스 + * @return 변환된 Screen 도메인 모델 + */ + fun toModel(entity: ScreenJpaEntity): Screen +} From 233340e61c0193177cce3faae20b7c422b73e1c9 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:45:25 +0900 Subject: [PATCH 06/17] feat ( #12 ) : ScreenRepository --- .../persistence/screen/repository/ScreenRepository.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/repository/ScreenRepository.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/repository/ScreenRepository.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/repository/ScreenRepository.kt new file mode 100644 index 0000000..e6ebb8f --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/repository/ScreenRepository.kt @@ -0,0 +1,11 @@ +package hs.kr.entrydsm.feed.adapter.out.persistence.screen.repository + +import hs.kr.entrydsm.feed.adapter.out.entity.screen.ScreenJpaEntity +import org.springframework.data.jpa.repository.JpaRepository +import java.util.UUID + +/** + * 화면(Screen) 데이터에 접근하기 위한 JPA Repository 인터페이스입니다. + * 화면 엔티티의 CRUD 작업을 위한 기본 메서드를 상속받아 사용합니다. + */ +interface ScreenRepository : JpaRepository From 520cfde32b3c8d7e80355e66bdf49bb753188499 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:45:39 +0900 Subject: [PATCH 07/17] feat ( #12 ) : ScreenPersistenceAdapter --- .../screen/ScreenPersistenceAdapter.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt new file mode 100644 index 0000000..b3755e1 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/adapter/out/persistence/screen/ScreenPersistenceAdapter.kt @@ -0,0 +1,35 @@ +package hs.kr.entrydsm.feed.adapter.out.persistence.screen + +import hs.kr.entrydsm.feed.adapter.out.mapper.screen.ScreenMapper +import hs.kr.entrydsm.feed.adapter.out.persistence.screen.repository.ScreenRepository +import hs.kr.entrydsm.feed.application.screen.port.out.FindScreenPort +import hs.kr.entrydsm.feed.application.screen.port.out.SaveScreenPort +import hs.kr.entrydsm.feed.model.screen.Screen +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Component +import java.util.UUID + +/** + * 화면 정보 도메인과 데이터베이스 간의 상호작용을 담당하는 어댑터 클래스입니다. + * + * @property screenRepository 화면 정보 엔티티를 데이터베이스에서 조작하기 위한 리포지토리 + * @property screenMapper 화면 정보 도메인 객체와 엔티티 간의 변환을 담당하는 매퍼 + */ +@Component +class ScreenPersistenceAdapter( + private val screenRepository: ScreenRepository, + private val screenMapper: ScreenMapper, +) : SaveScreenPort, FindScreenPort { + override fun saveScreen(screen: Screen) { + screenRepository.save(screenMapper.toEntity(screen)) + } + + override fun findAll(): List { + return screenRepository.findAll().map { screenMapper.toModel(it) } + } + + override fun findByIdOrNull(screenId: UUID): Screen? = + screenRepository.findByIdOrNull(screenId)?.let { + screenMapper.toModel(it) + } +} From ad6500889a190db8e4adcffbfafc53a8469d0046 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:45:48 +0900 Subject: [PATCH 08/17] feat ( #12 ) : ScreenNotFoundException --- .../screen/exception/ScreenNotFoundException.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt new file mode 100644 index 0000000..8d81767 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/exception/ScreenNotFoundException.kt @@ -0,0 +1,14 @@ +package hs.kr.entrydsm.feed.application.screen.exception + +import hs.kr.entrydsm.feed.global.error.exception.CasperException +import hs.kr.entrydsm.feed.global.error.exception.ErrorCode + +/** + * 화면 정보를 찾을 수 없을 때 발생하는 예외 클래스입니다. + * + * @property status HTTP 상태 코드 (404) + * @property message 에러 메시지 + */ +object ScreenNotFoundException : CasperException( + ErrorCode.SCREEN_NOT_FOUND, +) From 27fa04b1f5a225b3795bcdd1720de7c2d637f1bf Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:45:57 +0900 Subject: [PATCH 09/17] feat ( #12 ) : Q --- .../screen/port/in/CreateScreenUseCase.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/CreateScreenUseCase.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/CreateScreenUseCase.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/CreateScreenUseCase.kt new file mode 100644 index 0000000..e8ab8d2 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/CreateScreenUseCase.kt @@ -0,0 +1,13 @@ +package hs.kr.entrydsm.feed.application.screen.port.`in` + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.ScreenResponse +import org.springframework.web.multipart.MultipartFile + +/** + * 화면 생성을 위한 유스케이스 인터페이스입니다. + * 화면 도메인에서 새로운 화면 이미지를 업로드하고 생성하는 역할을 담당합니다. + */ +interface CreateScreenUseCase { + + suspend fun execute(file: MultipartFile): ScreenResponse +} From afe985a684da4131da415a1e77127c25c4c42a42 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:46:06 +0900 Subject: [PATCH 10/17] feat ( #12 ) : QueryScreenUseCase --- .../screen/port/in/QueryScreenUseCase.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/QueryScreenUseCase.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/QueryScreenUseCase.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/QueryScreenUseCase.kt new file mode 100644 index 0000000..1fc77cb --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/QueryScreenUseCase.kt @@ -0,0 +1,16 @@ +package hs.kr.entrydsm.feed.application.screen.port.`in` + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.QueryScreenResponse + +/** + * 화면 목록 조회를 위한 유스케이스 인터페이스입니다. + * 화면 도메인에서 모든 화면 목록을 조회하는 역할을 담당합니다. + */ +interface QueryScreenUseCase { + /** + * 모든 화면 목록을 조회합니다. + * + * @return 화면 목록 응답 + */ + fun execute(): List +} From 97f28023c1945542f9b62f82f152654688fd30e4 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:46:15 +0900 Subject: [PATCH 11/17] feat ( #12 ) : UpdateScreenUseCase --- .../screen/port/in/UpdateScreenUseCase.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/UpdateScreenUseCase.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/UpdateScreenUseCase.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/UpdateScreenUseCase.kt new file mode 100644 index 0000000..4c949a2 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/in/UpdateScreenUseCase.kt @@ -0,0 +1,23 @@ +package hs.kr.entrydsm.feed.application.screen.port.`in` + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.ScreenResponse +import org.springframework.web.multipart.MultipartFile +import java.util.UUID + +/** + * 화면 업데이트를 위한 유스케이스 인터페이스입니다. + * 화면 도메인에서 기존 화면 이미지를 새로운 이미지로 업데이트하는 역할을 담당합니다. + */ +interface UpdateScreenUseCase { + /** + * 특정 화면 이미지를 업데이트합니다. + * + * @param screenId 업데이트할 화면의 고유 식별자 + * @param file 새로운 화면 이미지 파일 + * @return 화면 업데이트 응답 + */ + fun execute( + screenId: UUID, + file: MultipartFile, + ): ScreenResponse +} From e763e73dfae7e5851e382e25df053767b1391932 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:46:23 +0900 Subject: [PATCH 12/17] feat ( #12 ) : FindScreenPort --- .../screen/port/out/FindScreenPort.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/FindScreenPort.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/FindScreenPort.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/FindScreenPort.kt new file mode 100644 index 0000000..6664542 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/FindScreenPort.kt @@ -0,0 +1,25 @@ +package hs.kr.entrydsm.feed.application.screen.port.out + +import hs.kr.entrydsm.feed.model.screen.Screen +import java.util.UUID + +/** + * 화면 조회를 위한 포트 인터페이스입니다. + * 화면 도메인 객체를 다양한 방식으로 조회하는 메서드를 정의합니다. + */ +interface FindScreenPort { + /** + * 모든 화면을 조회합니다. + * + * @return 모든 화면 목록 (없을 경우 빈 목록) + */ + fun findAll(): List + + /** + * 화면 ID로 화면을 조회합니다. + * + * @param screenId 조회할 화면의 고유 식별자 + * @return 조회된 화면 객체, 없을 경우 null + */ + fun findByIdOrNull(screenId: UUID): Screen? +} From 0be9eed733ad7f4c04693f4dafd3583201206b76 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:46:31 +0900 Subject: [PATCH 13/17] feat ( #12 ) : SaveScreenPort --- .../screen/port/out/SaveScreenPort.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/SaveScreenPort.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/SaveScreenPort.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/SaveScreenPort.kt new file mode 100644 index 0000000..da38d55 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/port/out/SaveScreenPort.kt @@ -0,0 +1,16 @@ +package hs.kr.entrydsm.feed.application.screen.port.out + +import hs.kr.entrydsm.feed.model.screen.Screen + +/** + * 화면 저장을 위한 포트 인터페이스입니다. + * 화면 도메인 객체를 저장하거나 업데이트하는 메서드를 정의합니다. + */ +interface SaveScreenPort { + /** + * 화면을 저장하거나 업데이트합니다. + * + * @param screen 저장하거나 업데이트할 화면 도메인 객체 + */ + fun saveScreen(screen: Screen) +} From f6231d6eedf1fa80b82a5d764c484207bd3dad3f Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:46:38 +0900 Subject: [PATCH 14/17] feat ( #12 ) : CreateScreenService --- .../screen/service/CreateScreenService.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/CreateScreenService.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/CreateScreenService.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/CreateScreenService.kt new file mode 100644 index 0000000..3f887c1 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/CreateScreenService.kt @@ -0,0 +1,39 @@ +package hs.kr.entrydsm.feed.application.screen.service + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.ScreenResponse +import hs.kr.entrydsm.feed.application.screen.port.`in`.CreateScreenUseCase +import hs.kr.entrydsm.feed.application.screen.port.out.SaveScreenPort +import hs.kr.entrydsm.feed.global.utils.admin.AdminUtils +import hs.kr.entrydsm.feed.infrastructure.s3.PathList +import hs.kr.entrydsm.feed.infrastructure.s3.util.FileUtil +import hs.kr.entrydsm.feed.model.screen.Screen +import org.springframework.stereotype.Service +import org.springframework.web.multipart.MultipartFile + +/** + * 화면 이미지 생성을 처리하는 서비스 클래스입니다. + * + * @property saveScreenPort 화면 저장을 위한 포트 + * @property userUtils 사용자 인증 유틸리티 + * @property fileUtil 파일 업로드 유틸리티 + */ +@Service +class CreateScreenService( + private val saveScreenPort: SaveScreenPort, + private val adminUtils: AdminUtils, + private val fileUtil: FileUtil, +) : CreateScreenUseCase { + + override suspend fun execute(file: MultipartFile): ScreenResponse { + val adminId = adminUtils.getCurrentAdmin().id + + val fileName = fileUtil.upload(file, PathList.SCREEN) + saveScreenPort.saveScreen( + Screen( + image = fileName, + adminId = adminId, + ), + ) + return ScreenResponse(fileName) + } +} From d890d28be44622c88d8a4a02507a2363c138e55f Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:46:48 +0900 Subject: [PATCH 15/17] feat ( #12 ) : QueryScreenService --- .../screen/service/QueryScreenService.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/QueryScreenService.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/QueryScreenService.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/QueryScreenService.kt new file mode 100644 index 0000000..4b8a402 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/QueryScreenService.kt @@ -0,0 +1,37 @@ +package hs.kr.entrydsm.feed.application.screen.service + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.QueryScreenResponse +import hs.kr.entrydsm.feed.application.screen.port.`in`.QueryScreenUseCase +import hs.kr.entrydsm.feed.application.screen.port.out.FindScreenPort +import hs.kr.entrydsm.feed.infrastructure.s3.PathList +import hs.kr.entrydsm.feed.infrastructure.s3.util.FileUtil +import org.springframework.stereotype.Service + +/** + * 화면 이미지 목록 조회를 처리하는 서비스 클래스입니다. + * + * @property findScreenPort 화면 조회를 위한 포트 + * @property fileUtil 파일 URL 생성을 위한 유틸리티 + */ +@Service +class QueryScreenService( + private val findScreenPort: FindScreenPort, + private val fileUtil: FileUtil, +) : QueryScreenUseCase { + /** + * 모든 화면 이미지 목록을 조회합니다. + * + * @return 화면 이미지 목록 (각 항목은 ID, URL, 생성일시, 수정일시 포함) + */ + override fun execute(): List { + return findScreenPort.findAll() + .map { it -> + QueryScreenResponse( + it.id!!, + fileUtil.generateObjectUrl(it.image, PathList.SCREEN), + it.createdAt, + it.modifiedAt, + ) + } + } +} From 69dd4e088926ed8cc9428fb6fe1ebd06932c025a Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:47:00 +0900 Subject: [PATCH 16/17] feat ( #12 ) : UpdateScreenService --- .../screen/service/UpdateScreenService.kt | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/UpdateScreenService.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/UpdateScreenService.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/UpdateScreenService.kt new file mode 100644 index 0000000..8840e4b --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/application/screen/service/UpdateScreenService.kt @@ -0,0 +1,48 @@ +package hs.kr.entrydsm.feed.application.screen.service + +import hs.kr.entrydsm.feed.adapter.`in`.screen.dto.response.ScreenResponse +import hs.kr.entrydsm.feed.application.screen.exception.ScreenNotFoundException +import hs.kr.entrydsm.feed.application.screen.port.`in`.UpdateScreenUseCase +import hs.kr.entrydsm.feed.application.screen.port.out.FindScreenPort +import hs.kr.entrydsm.feed.infrastructure.s3.PathList +import hs.kr.entrydsm.feed.infrastructure.s3.util.FileUtil +import jakarta.transaction.Transactional +import org.springframework.stereotype.Service +import org.springframework.web.multipart.MultipartFile +import java.util.UUID + +/** + * 화면 이미지 업데이트를 처리하는 서비스 클래스입니다. + * + * @property fileUtil 파일 업로드 및 삭제를 위한 유틸리티 + * @property findScreenPort 화면 조회를 위한 포트 + */ +@Transactional +@Service +class UpdateScreenService( + private val fileUtil: FileUtil, + private val findScreenPort: FindScreenPort, +) : UpdateScreenUseCase { + /** + * 지정된 ID의 화면 이미지를 새로운 이미지로 업데이트합니다. + * 기존 이미지는 삭제됩니다. + * + * @param screenId 업데이트할 화면의 고유 식별자 + * @param file 새로운 이미지 파일 + * @return 업데이트된 화면 이미지의 URL이 포함된 응답 + * @throws hs.kr.entrydsm.feed.application.screen.exception.ScreenNotFoundException 지정된 ID의 화면을 찾을 수 없는 경우 + */ + override fun execute( + screenId: UUID, + file: MultipartFile, + ): ScreenResponse { + val screen = + findScreenPort.findByIdOrNull(screenId) + ?: throw ScreenNotFoundException + val fileName = fileUtil.upload(file, PathList.SCREEN) + fileUtil.delete(screen.image, PathList.SCREEN) + screen.updateImage(fileName) + + return ScreenResponse(fileUtil.generateObjectUrl(fileName, PathList.SCREEN)) + } +} From 8bb1e993cbac84c011861f6e7921fc95863eed86 Mon Sep 17 00:00:00 2001 From: coehgns Date: Fri, 1 Aug 2025 17:47:08 +0900 Subject: [PATCH 17/17] feat ( #12 ) : Screen model --- .../kr/entrydsm/feed/model/screen/Screen.kt | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt diff --git a/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt new file mode 100644 index 0000000..7b9dc28 --- /dev/null +++ b/casper-feed/src/main/kotlin/hs/kr/entrydsm/feed/model/screen/Screen.kt @@ -0,0 +1,29 @@ +package hs.kr.entrydsm.feed.model.screen + +import java.time.LocalDateTime +import java.util.UUID + +/** + * 화면 정보를 나타내는 도메인 모델 클래스입니다. + * + * @property id 화면의 고유 식별자 (생성 시 자동 할당) + * @property image 화면 이미지 파일명 또는 경로 + * @property adminId 화면을 등록한 관리자 ID + * @property createdAt 화면 정보 생성 일시 (기본값: 현재 시간) + * @property modifiedAt 화면 정보 수정 일시 (기본값: 현재 시간) + */ +data class Screen( + val id: UUID? = null, + val image: String, + val adminId: UUID, + val createdAt: LocalDateTime = LocalDateTime.now(), + val modifiedAt: LocalDateTime = LocalDateTime.now(), +) { + /** + * 화면 이미지를 새로운 이미지로 업데이트합니다. + * + * @param newImage 새로운 화면 이미지 파일명 또는 경로 + * @return 이미지가 업데이트된 Screen 객체 + */ + fun updateImage(newImage: String): Screen =copy(image = newImage) +}