diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/AdminController.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/AdminController.kt new file mode 100644 index 000000000..924f7dd2f --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/AdminController.kt @@ -0,0 +1,106 @@ +package com.few.api.web.controller.admin + +import com.few.api.domain.admin.document.dto.* +import com.few.api.domain.admin.document.usecase.AddArticleUseCase +import com.few.api.domain.admin.document.usecase.AddWorkbookUseCase +import com.few.api.domain.admin.document.usecase.ConvertContentUseCase +import com.few.api.domain.admin.document.usecase.MapArticleUseCase +import com.few.api.web.controller.admin.request.AddArticleRequest +import com.few.api.web.controller.admin.request.AddWorkbookRequest +import com.few.api.web.controller.admin.request.ConvertContentRequest +import com.few.api.web.controller.admin.request.MapArticleRequest +import com.few.api.web.controller.admin.response.AddArticleResponse +import com.few.api.web.controller.admin.response.AddWorkbookResponse +import com.few.api.web.controller.admin.response.ConvertContentResponse +import com.few.api.web.support.ApiResponse +import com.few.api.web.support.ApiResponseGenerator +import com.few.api.web.support.MessageCode +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.validation.annotation.Validated +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 + +@Validated +@RestController +@RequestMapping(value = ["/api/v1/admin"]) +class AdminController( + private val addArticleUseCase: AddArticleUseCase, + private val addWorkbookUseCase: AddWorkbookUseCase, + private val mapArticleUseCase: MapArticleUseCase, + private val convertContentUseCase: ConvertContentUseCase +) { + @PostMapping("/workbooks") + fun addWorkbook(@RequestBody request: AddWorkbookRequest): ApiResponse> { + val useCaseOut = AddWorkbookUseCaseIn( + title = request.title, + mainImageUrl = request.mainImageUrl, + category = request.category, + description = request.description + ).let { + addWorkbookUseCase.execute(it) + } + + return AddWorkbookResponse(useCaseOut.workbookId).let { + ApiResponseGenerator.success(it, HttpStatus.OK) + } + } + + @PostMapping("/articles") + fun addArticle( + @RequestBody request: AddArticleRequest + ): ApiResponse> { + val useCaseOut = AddArticleUseCaseIn( + writerEmail = request.writerEmail, + articleImageUrl = request.articleImageUrl, + title = request.title, + category = request.category, + contentSource = request.contentSource, + problemData = ProblemDetail( + title = request.problemData.title, + contents = request.problemData.contents.map { + ProblemContentDetail( + number = it.number, + content = it.content + ) + }, + answer = request.problemData.answer, + explanation = request.problemData.explanation + ) + ).let { useCaseIn -> + addArticleUseCase.execute(useCaseIn) + } + + return AddArticleResponse(useCaseOut).let { + ApiResponseGenerator.success(it, HttpStatus.OK) + } + } + + @PostMapping("/relations/articles") + fun mapArticle(@RequestBody request: MapArticleRequest): ApiResponse { + MapArticleUseCaseIn( + workbookId = request.workbookId, + articleId = request.articleId, + dayCol = request.dayCol + ).let { + mapArticleUseCase.execute(it) + } + + return ApiResponseGenerator.success(HttpStatus.OK, MessageCode.RESOURCE_CREATED) + } + + @PostMapping("/utilities/conversion/content", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) + fun convertContent( + request: ConvertContentRequest + ): ApiResponse> { + val useCaseOut = ConvertContentUseCaseIn(request.content).let { + convertContentUseCase.execute(it) + } + + ConvertContentResponse(useCaseOut.content, useCaseOut.originDownLoadUrl).let { + return ApiResponseGenerator.success(it, HttpStatus.OK) + } + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/request/AddArticleRequest.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/request/AddArticleRequest.kt new file mode 100644 index 000000000..17070e5b2 --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/request/AddArticleRequest.kt @@ -0,0 +1,34 @@ +package com.few.api.web.controller.admin.request + +import jakarta.validation.constraints.NotBlank +import java.net.URL + +data class AddArticleRequest( + /** Article MST */ + @field:NotBlank(message = "{email.notblank}") + val writerEmail: String, + @field:NotBlank(message = "{image.url.notblank}") + val articleImageUrl: URL, + @field:NotBlank(message = "{title.notblank}") + val title: String, + @field:NotBlank(message = "{category.notblank}") + val category: String, + /** Article IFO */ + @field:NotBlank(message = "{content.source.notblank}") + val contentSource: String, + val problemData: ProblemDto +) + +data class ProblemDto( + @field:NotBlank(message = "{problem.title.notblank}") + val title: String, + val contents: List, + @field:NotBlank(message = "{problem.answer.notblank}") + val answer: String, + @field:NotBlank(message = "{problem.explanation.notblank}") + val explanation: String +) +data class ProblemContentDto( + val number: Long, + val content: String +) \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/request/AddWorkbookRequest.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/request/AddWorkbookRequest.kt new file mode 100644 index 000000000..e0cf84f54 --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/request/AddWorkbookRequest.kt @@ -0,0 +1,15 @@ +package com.few.api.web.controller.admin.request + +import jakarta.validation.constraints.NotBlank +import java.net.URL + +data class AddWorkbookRequest( + @field:NotBlank(message = "{workbook.title.notblank}") + val title: String, + @field:NotBlank(message = "{image.url.notblank}") + val mainImageUrl: URL, + @field:NotBlank(message = "{category.notblank}") + val category: String, + @field:NotBlank(message = "{workbook.description.notblank}") + val description: String +) \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/request/ConvertContentRequest.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/request/ConvertContentRequest.kt new file mode 100644 index 000000000..aaa443cba --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/request/ConvertContentRequest.kt @@ -0,0 +1,7 @@ +package com.few.api.web.controller.admin.request + +import org.springframework.web.multipart.MultipartFile + +data class ConvertContentRequest( + val content: MultipartFile +) \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/request/MapArticleRequest.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/request/MapArticleRequest.kt new file mode 100644 index 000000000..aec6cbac1 --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/request/MapArticleRequest.kt @@ -0,0 +1,15 @@ +package com.few.api.web.controller.admin.request + +import jakarta.validation.constraints.Max +import jakarta.validation.constraints.Min +import jakarta.validation.constraints.NotBlank + +data class MapArticleRequest( + @field:NotBlank(message = "{min.id}") + val workbookId: Long, + @field:NotBlank(message = "{min.id}") + val articleId: Long, + @field:Min(value = 1, message = "{min.id}") + @field:Max(value = 7, message = "{max.day}") + val dayCol: Int +) \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/response/AddArticleResponse.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/response/AddArticleResponse.kt new file mode 100644 index 000000000..ede7b5750 --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/response/AddArticleResponse.kt @@ -0,0 +1,11 @@ +package com.few.api.web.controller.admin.response + +import com.few.api.domain.admin.document.dto.AddArticleUseCaseOut + +data class AddArticleResponse( + val articleId: Long +) { + constructor(useCaseOut: AddArticleUseCaseOut) : this( + articleId = useCaseOut.articleId + ) +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/response/AddWorkbookResponse.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/response/AddWorkbookResponse.kt new file mode 100644 index 000000000..2497e54b9 --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/response/AddWorkbookResponse.kt @@ -0,0 +1,5 @@ +package com.few.api.web.controller.admin.response + +data class AddWorkbookResponse( + val workbookId: Long +) \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/web/controller/admin/response/ConvertContentResponse.kt b/api/src/main/kotlin/com/few/api/web/controller/admin/response/ConvertContentResponse.kt new file mode 100644 index 000000000..0668bc02c --- /dev/null +++ b/api/src/main/kotlin/com/few/api/web/controller/admin/response/ConvertContentResponse.kt @@ -0,0 +1,8 @@ +package com.few.api.web.controller.admin.response + +import java.net.URL + +data class ConvertContentResponse( + val content: String, + val originDownLoadUrl: URL +) \ No newline at end of file