diff --git a/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/domain/Notice.kt b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/domain/Notice.kt index 5e83a5a..ac887a6 100644 --- a/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/domain/Notice.kt +++ b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/domain/Notice.kt @@ -5,16 +5,16 @@ data class Notice( val content: String, ) { data class Summary( - val id: String, + val id: String? = null, val title: String, - val createdAt: String, + val createdAt: String? = null, ) data class Detail( - val id: String, + val id: String? = null, val title: String, val content: String, - val createdAt: String, + val createdAt: String? = null, ) fun detail(): Detail { diff --git a/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/input/RegisterNoticeCommand.kt b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/input/RegisterNoticeCommand.kt new file mode 100644 index 0000000..4d3c977 --- /dev/null +++ b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/input/RegisterNoticeCommand.kt @@ -0,0 +1,6 @@ +package me.jiniworld.demohx.application.notice.port.input + +data class RegisterNoticeCommand( + val title: String, + val content: String, +) \ No newline at end of file diff --git a/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/input/RegisterNoticeUseCase.kt b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/input/RegisterNoticeUseCase.kt new file mode 100644 index 0000000..aeed918 --- /dev/null +++ b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/input/RegisterNoticeUseCase.kt @@ -0,0 +1,5 @@ +package me.jiniworld.demohx.application.notice.port.input + +interface RegisterNoticeUseCase { + suspend fun registerNotice(command: RegisterNoticeCommand) +} \ No newline at end of file diff --git a/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/output/SaveNoticePort.kt b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/output/SaveNoticePort.kt new file mode 100644 index 0000000..b9566a5 --- /dev/null +++ b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/port/output/SaveNoticePort.kt @@ -0,0 +1,7 @@ +package me.jiniworld.demohx.application.notice.port.output + +import me.jiniworld.demohx.application.notice.domain.Notice + +interface SaveNoticePort { + suspend fun saveNotice(notice: Notice) +} \ No newline at end of file diff --git a/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/service/RegisterNoticeService.kt b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/service/RegisterNoticeService.kt new file mode 100644 index 0000000..ee3b5ca --- /dev/null +++ b/core/demo-reactive-core/src/main/kotlin/me/jiniworld/demohx/application/notice/service/RegisterNoticeService.kt @@ -0,0 +1,20 @@ +package me.jiniworld.demohx.application.notice.service + +import me.jiniworld.demohx.annotation.UseCase +import me.jiniworld.demohx.application.notice.domain.Notice +import me.jiniworld.demohx.application.notice.port.input.RegisterNoticeCommand +import me.jiniworld.demohx.application.notice.port.input.RegisterNoticeUseCase +import me.jiniworld.demohx.application.notice.port.output.SaveNoticePort +import org.springframework.transaction.annotation.Transactional + +@Transactional(readOnly = true) +@UseCase +internal class RegisterNoticeService( + private val saveNoticePort: SaveNoticePort, +): RegisterNoticeUseCase { + + override suspend fun registerNotice(command: RegisterNoticeCommand) { + saveNoticePort.saveNotice(Notice(Notice.Summary(title = command.title), content = command.content)) + } + +} \ No newline at end of file diff --git a/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticeMapper.kt b/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticeMapper.kt index bb3de0f..9ddde84 100644 --- a/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticeMapper.kt +++ b/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticeMapper.kt @@ -9,4 +9,7 @@ internal object NoticeMapper { Notice(summary = Notice.Summary(id = doc.id, title = doc.title, createdAt = DateTimeUtils.toString(doc.createdAt)), content = doc.content) + fun mapToDocument(notice: Notice) = + NoticeDocument(title = notice.summary.title, content = notice.content) + } \ No newline at end of file diff --git a/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticePersistenceAdapter.kt b/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticePersistenceAdapter.kt index 5b8644d..2e4614d 100644 --- a/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticePersistenceAdapter.kt +++ b/infrastructure/datastore-mongodb-reactive/src/main/kotlin/me/jiniworld/demohx/persistence/notice/NoticePersistenceAdapter.kt @@ -5,12 +5,13 @@ import kotlinx.coroutines.flow.map import me.jiniworld.demohx.annotation.PersistenceAdapter import me.jiniworld.demohx.application.notice.domain.Notice import me.jiniworld.demohx.application.notice.port.output.LoadNoticePort +import me.jiniworld.demohx.application.notice.port.output.SaveNoticePort import org.springframework.data.domain.Pageable @PersistenceAdapter internal class NoticePersistenceAdapter( private val noticeRepository: NoticeRepository, -) : LoadNoticePort { +) : LoadNoticePort, SaveNoticePort { override fun loadNotices(pageable: Pageable): Flow { return noticeRepository.findAllBy(pageable).map { NoticeMapper.mapToNotice(it) } } @@ -18,4 +19,8 @@ internal class NoticePersistenceAdapter( override suspend fun loadNotice(id: String): Notice? { return noticeRepository.findById(id)?.let { NoticeMapper.mapToNotice(it) } } + + override suspend fun saveNotice(notice: Notice) { + noticeRepository.save(NoticeMapper.mapToDocument(notice)) + } } \ No newline at end of file diff --git a/server/demo-reactive-app/src/main/kotlin/me/jiniworld/demohx/web/notice/RegisterNoticeController.kt b/server/demo-reactive-app/src/main/kotlin/me/jiniworld/demohx/web/notice/RegisterNoticeController.kt new file mode 100644 index 0000000..f244015 --- /dev/null +++ b/server/demo-reactive-app/src/main/kotlin/me/jiniworld/demohx/web/notice/RegisterNoticeController.kt @@ -0,0 +1,27 @@ +package me.jiniworld.demohx.web.notice + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import me.jiniworld.demohx.annotation.WebAdapter +import me.jiniworld.demohx.application.notice.port.input.RegisterNoticeCommand +import me.jiniworld.demohx.application.notice.port.input.RegisterNoticeUseCase +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@WebAdapter +@Tag(name = "setting-system", description = "설정-시스템(공지사항, FAQ, 이용약관, 메타정보 등)") +@RestController +@RequestMapping("/v1/notices") +internal class RegisterNoticeController( + private val registerNoticeUseCase: RegisterNoticeUseCase, +) { + + @Operation(summary = "공지사항 등록") + @PostMapping("") + suspend fun getNotices( + @RequestBody command: RegisterNoticeCommand, + ) = registerNoticeUseCase.registerNotice(command) + +} \ No newline at end of file