diff --git a/src/main/java/com/wooteco/wiki/document/controller/DocumentController.java b/src/main/java/com/wooteco/wiki/document/controller/DocumentController.java new file mode 100644 index 0000000..ee56d24 --- /dev/null +++ b/src/main/java/com/wooteco/wiki/document/controller/DocumentController.java @@ -0,0 +1,136 @@ +package com.wooteco.wiki.document.controller; + +import com.wooteco.wiki.document.domain.Document; +import com.wooteco.wiki.document.domain.dto.*; +import com.wooteco.wiki.document.service.DocumentSearchService; +import com.wooteco.wiki.document.service.DocumentService; +import com.wooteco.wiki.document.service.DocumentServiceJava; +import com.wooteco.wiki.global.common.ApiResponse; +import com.wooteco.wiki.global.common.ApiResponse.SuccessBody; +import com.wooteco.wiki.global.common.ApiResponseGenerator; +import com.wooteco.wiki.global.common.PageRequestDto; +import com.wooteco.wiki.global.common.ResponseDto; +import com.wooteco.wiki.history.domain.dto.HistoryDetailResponse; +import com.wooteco.wiki.history.domain.dto.HistoryResponse; +import com.wooteco.wiki.history.service.HistoryService; +import com.wooteco.wiki.organizationdocument.dto.OrganizationDocumentSearchResponse; +import io.swagger.v3.oas.annotations.Operation; +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/document") +@RequiredArgsConstructor +public class DocumentController { + + private final DocumentService documentService; + private final HistoryService historyService; + private final DocumentSearchService documentSearchService; + private final DocumentServiceJava documentServiceJava; + + @Operation(summary = "위키 글 작성", description = "위키 글을 작성합니다.") + @PostMapping + public ApiResponse> post(@RequestBody CrewDocumentCreateRequest crewDocumentCreateRequest) { + DocumentResponse response = documentService.postCrewDocument(crewDocumentCreateRequest); + return ApiResponseGenerator.success(response); + } + + @Operation(summary = "랜덤 위키 글 조회", description = "랜덤으로 위키 글을 조회합니다.") + @GetMapping("/random") + public ApiResponse> getRandom() { + DocumentResponse response = documentService.getRandom(); + return ApiResponseGenerator.success(response); + } + + @Operation(summary = "위키 글 전체 조회", description = "페이지네이션을 통해 모든 위키 글을 조회합니다.") + @GetMapping("") + public ApiResponse>>> findAll(@ModelAttribute PageRequestDto pageRequestDto) { + Page pageResponses = documentService.findAll(pageRequestDto); + return ApiResponseGenerator.success(convertToResponse(pageResponses)); + } + + @Operation(summary = "제목으로 위키 글 조회", description = "제목을 통해 위키 글을 조회합니다.") + @GetMapping("title/{title}") + public ApiResponse> get(@PathVariable String title) { + Object response = documentService.get(title); + return ApiResponseGenerator.success(response); + } + + @Operation(summary = "제목으로 UUID 조회", description = "제목을 통해 위키 글의 UUID를 조회합니다.") + @GetMapping("title/{title}/uuid") + public ApiResponse> getUuidByTitle(@PathVariable String title) { + Object response = documentService.getUuidByTitle(title); + return ApiResponseGenerator.success(response); + } + + @Operation(summary = "UUID로 위키 글 조회", description = "UUID를 통해 위키 글을 조회합니다.") + @GetMapping("uuid/{uuidText}") + public ApiResponse> getByUuid(@PathVariable String uuidText) { + UUID uuid = UUID.fromString(uuidText); + Object response = documentService.getByUuid(uuid); + return ApiResponseGenerator.success(response); + } + + @Operation(summary = "문서 로그 목록 조회", description = "문서 UUID로 해당 문서의 로그 목록을 페이지네이션을 통해 조회합니다.") + @GetMapping("uuid/{uuidText}/log") + public ApiResponse>>> getLogs( + @PathVariable String uuidText, + @ModelAttribute PageRequestDto pageRequestDto + ) { + UUID uuid = UUID.fromString(uuidText); + Page pageResponses = historyService.findAllByDocumentUuid(uuid, pageRequestDto); + return ApiResponseGenerator.success(convertToResponse(pageResponses)); + } + + @Operation(summary = "로그 상세 조회", description = "로그 ID로 로그 상세 정보를 조회합니다.") + @GetMapping("/log/{logId}") + public ApiResponse> getDocumentLogs(@PathVariable Long logId) { + HistoryDetailResponse logDetail = historyService.getLogDetail(logId); + return ApiResponseGenerator.success(logDetail); + } + + @Operation(summary = "위키 글 수정", description = "위키 글을 수정합니다.") + @PutMapping + public ApiResponse> put( + @RequestBody DocumentUpdateRequest documentUpdateRequest + ) { + DocumentResponse response = documentService.put(documentUpdateRequest.uuid(), documentUpdateRequest); + return ApiResponseGenerator.success(response); + } + + @Operation(summary = "키워드로 위키 글 검색", description = "키워드로 위키 글을 검색합니다.") + @GetMapping("/search") + public ApiResponse>> search(@RequestParam String keyWord) { + return ApiResponseGenerator.success(documentSearchService.search(keyWord)); + } + + @Operation(summary = "누적 조회수 수신 API", description = "프론트에서 누적된 조회수를 전달받아 DB에 반영합니다.") + @PostMapping("/views/flush") + public ApiResponse> flushViews( + @RequestBody ViewFlushRequest request + ) { + documentService.flushViews(request.views()); + return ApiResponseGenerator.success("조회수 누적 완료"); + } + + @Operation(summary = "특정 문서에 대한 조직 문서 조회 API", description = "특정 문서에 대한 조직 문서들을 조회합니다.") + @GetMapping("/{uuidText}/organization-documents") + public ApiResponse>> readOrganizationDocument( + @PathVariable String uuidText + ) { + UUID uuid = UUID.fromString(uuidText); + return ApiResponseGenerator.success(documentServiceJava.searchOrganizationDocument(uuid)); + } + + private ResponseDto> convertToResponse(Page pageResponses) { + return ResponseDto.of( + pageResponses.getNumber(), + pageResponses.getTotalPages(), + pageResponses.getContent() + ); + } +} + diff --git a/src/main/java/com/wooteco/wiki/document/controller/DocumentController.kt b/src/main/java/com/wooteco/wiki/document/controller/DocumentController.kt deleted file mode 100644 index b153d33..0000000 --- a/src/main/java/com/wooteco/wiki/document/controller/DocumentController.kt +++ /dev/null @@ -1,132 +0,0 @@ -package com.wooteco.wiki.document.controller - -import com.wooteco.wiki.document.domain.Document -import com.wooteco.wiki.document.domain.dto.* -import com.wooteco.wiki.document.service.DocumentSearchService -import com.wooteco.wiki.document.service.DocumentService -import com.wooteco.wiki.document.service.DocumentServiceJava -import com.wooteco.wiki.global.common.ApiResponse -import com.wooteco.wiki.global.common.ApiResponse.SuccessBody -import com.wooteco.wiki.global.common.ApiResponseGenerator -import com.wooteco.wiki.global.common.PageRequestDto -import com.wooteco.wiki.global.common.ResponseDto -import com.wooteco.wiki.history.domain.dto.HistoryDetailResponse -import com.wooteco.wiki.history.domain.dto.HistoryResponse -import com.wooteco.wiki.history.service.HistoryService -import com.wooteco.wiki.organizationdocument.dto.OrganizationDocumentSearchResponse -import io.swagger.v3.oas.annotations.Operation -import org.springframework.data.domain.Page -import org.springframework.web.bind.annotation.* -import java.util.* - -@RestController -@RequestMapping("/document") -class DocumentController( - private val documentService: DocumentService, - private val historyService: HistoryService, - private val documentSearchService: DocumentSearchService, - private val documentServiceJava: DocumentServiceJava -) { - - @Operation(summary = "위키 글 작성", description = "위키 글을 작성합니다.") - @PostMapping - fun post(@RequestBody crewDocumentCreateRequest: CrewDocumentCreateRequest): ApiResponse> { - val response = documentService.postCrewDocument(crewDocumentCreateRequest) - return ApiResponseGenerator.success(response) - } - - @Operation(summary = "랜덤 위키 글 조회", description = "랜덤으로 위키 글을 조회합니다.") - @GetMapping("/random") - fun getRandom(): ApiResponse> { - val response = documentService.getRandom() - return ApiResponseGenerator.success(response) - } - - @Operation(summary = "위키 글 전체 조회", description = "페이지네이션을 통해 모든 위키 글을 조회합니다.") - @GetMapping("") - fun findAll(@ModelAttribute pageRequestDto: PageRequestDto): ApiResponse>>> { - val pageResponses = documentService.findAll(pageRequestDto) - return ApiResponseGenerator.success(convertToResponse(pageResponses)) - } - - @Operation(summary = "제목으로 위키 글 조회", description = "제목을 통해 위키 글을 조회합니다.") - @GetMapping("title/{title}") - fun get(@PathVariable title: String): ApiResponse> { - val response = documentService.get(title) - return ApiResponseGenerator.success(response) - } - - @Operation(summary = "제목으로 UUID 조회", description = "제목을 통해 위키 글의 UUID를 조회합니다.") - @GetMapping("title/{title}/uuid") - fun getUuidByTitle(@PathVariable title: String): ApiResponse> { - val response = documentService.getUuidByTitle(title) - return ApiResponseGenerator.success(response) - } - - @Operation(summary = "UUID로 위키 글 조회", description = "UUID를 통해 위키 글을 조회합니다.") - @GetMapping("uuid/{uuidText}") - fun getByUuid(@PathVariable uuidText: String): ApiResponse> { - val uuid = UUID.fromString(uuidText) - val response = documentService.getByUuid(uuid) - return ApiResponseGenerator.success(response) - } - - @Operation(summary = "문서 로그 목록 조회", description = "문서 UUID로 해당 문서의 로그 목록을 페이지네이션을 통해 조회합니다.") - @GetMapping("uuid/{uuidText}/log") - fun getLogs( - @PathVariable uuidText: String, - @ModelAttribute pageRequestDto: PageRequestDto - ): ApiResponse>>> { - val uuid = UUID.fromString(uuidText) - val pageResponses = historyService.findAllByDocumentUuid(uuid, pageRequestDto) - return ApiResponseGenerator.success(convertToResponse(pageResponses)) - } - - @Operation(summary = "로그 상세 조회", description = "로그 ID로 로그 상세 정보를 조회합니다.") - @GetMapping("/log/{logId}") - fun getDocumentLogs(@PathVariable logId: Long): ApiResponse> { - val logDetail = historyService.getLogDetail(logId) - return ApiResponseGenerator.success(logDetail) - } - - @Operation(summary = "위키 글 수정", description = "위키 글을 수정합니다.") - @PutMapping - fun put( - @RequestBody documentUpdateRequest: DocumentUpdateRequest - ): ApiResponse> { - val response = documentService.put(documentUpdateRequest.uuid, documentUpdateRequest) - return ApiResponseGenerator.success(response) - } - - @Operation(summary = "키워드로 위키 글 검색", description = "키워드로 위키 글을 검색합니다.") - @GetMapping("/search") - fun search(@RequestParam keyWord: String): ApiResponse>> { - return ApiResponseGenerator.success(documentSearchService.search(keyWord)) - } - - @Operation(summary = "누적 조회수 수신 API", description = "프론트에서 누적된 조회수를 전달받아 DB에 반영합니다.") - @PostMapping("/views/flush") - fun flushViews( - @RequestBody request: ViewFlushRequest - ): ApiResponse> { - documentService.flushViews(request.views) - return ApiResponseGenerator.success("조회수 누적 완료") - } - - @Operation(summary = "특정 문서에 대한 조직 문서 조회 API", description = "특정 문서에 대한 조직 문서들을 조회합니다.") - @GetMapping("/{uuidText}/organization-documents") - fun readOrganizationDocument( - @PathVariable uuidText: String - ): ApiResponse>> { - val uuid = UUID.fromString(uuidText) - return ApiResponseGenerator.success(documentServiceJava.searchOrganizationDocument(uuid)) - } - - private fun convertToResponse(pageResponses: Page): ResponseDto> { - return ResponseDto.of( - pageResponses.number, - pageResponses.totalPages, - pageResponses.content - ) - } -} diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentResponse.java b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentResponse.java new file mode 100644 index 0000000..78b1469 --- /dev/null +++ b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentResponse.java @@ -0,0 +1,20 @@ +package com.wooteco.wiki.document.domain.dto; + +import com.wooteco.wiki.organizationdocument.dto.response.OrganizationDocumentResponse; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +public record DocumentResponse( + Long documentId, + UUID documentUUID, + String title, + String contents, + String writer, + LocalDateTime generateTime, + Integer viewCount, + Long latestVersion, + List organizationDocumentResponses +) { +} + diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentResponse.kt b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentResponse.kt deleted file mode 100644 index cdc2db8..0000000 --- a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentResponse.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.wooteco.wiki.document.domain.dto - -import com.wooteco.wiki.organizationdocument.dto.response.OrganizationDocumentResponse -import java.time.LocalDateTime -import java.util.* - -data class DocumentResponse( - val documentId: Long, - var documentUUID: UUID, - val title: String, - val contents: String, - val writer: String, - val generateTime: LocalDateTime, - val viewCount: Int, - val latestVersion: Long, - val organizationDocumentResponses : List -) diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentSearchResponse.java b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentSearchResponse.java new file mode 100644 index 0000000..ae114a8 --- /dev/null +++ b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentSearchResponse.java @@ -0,0 +1,12 @@ +package com.wooteco.wiki.document.domain.dto; + +import com.wooteco.wiki.document.domain.DocumentType; +import java.util.UUID; + +public record DocumentSearchResponse( + String title, + UUID uuid, + DocumentType documentType +) { +} + diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentSearchResponse.kt b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentSearchResponse.kt deleted file mode 100644 index 79f6165..0000000 --- a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentSearchResponse.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.wooteco.wiki.document.domain.dto - -import com.wooteco.wiki.document.domain.DocumentType -import java.util.* - -data class DocumentSearchResponse( - val title: String, - val uuid: UUID, - val documentType: DocumentType -) diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentUpdateRequest.java b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentUpdateRequest.java new file mode 100644 index 0000000..cbc7209 --- /dev/null +++ b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentUpdateRequest.java @@ -0,0 +1,13 @@ +package com.wooteco.wiki.document.domain.dto; + +import java.util.UUID; + +public record DocumentUpdateRequest( + String title, + String contents, + String writer, + Long documentBytes, + UUID uuid +) { +} + diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentUpdateRequest.kt b/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentUpdateRequest.kt deleted file mode 100644 index 2c0a6bb..0000000 --- a/src/main/java/com/wooteco/wiki/document/domain/dto/DocumentUpdateRequest.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.wooteco.wiki.document.domain.dto - -import java.util.* - -data class DocumentUpdateRequest( - val title: String, - val contents: String, - val writer: String, - val documentBytes: Long, - val uuid: UUID -) - diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/ViewFlushRequest.java b/src/main/java/com/wooteco/wiki/document/domain/dto/ViewFlushRequest.java new file mode 100644 index 0000000..0e9d6fe --- /dev/null +++ b/src/main/java/com/wooteco/wiki/document/domain/dto/ViewFlushRequest.java @@ -0,0 +1,10 @@ +package com.wooteco.wiki.document.domain.dto; + +import java.util.Map; +import java.util.UUID; + +public record ViewFlushRequest( + Map views +) { +} + diff --git a/src/main/java/com/wooteco/wiki/document/domain/dto/ViewFlushRequest.kt b/src/main/java/com/wooteco/wiki/document/domain/dto/ViewFlushRequest.kt deleted file mode 100644 index 793ddee..0000000 --- a/src/main/java/com/wooteco/wiki/document/domain/dto/ViewFlushRequest.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.wooteco.wiki.document.domain.dto - -import java.util.UUID - -data class ViewFlushRequest( - val views: Map -) diff --git a/src/main/java/com/wooteco/wiki/document/service/DocumentService.java b/src/main/java/com/wooteco/wiki/document/service/DocumentService.java index 7344526..cc9dd7c 100644 --- a/src/main/java/com/wooteco/wiki/document/service/DocumentService.java +++ b/src/main/java/com/wooteco/wiki/document/service/DocumentService.java @@ -17,8 +17,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.UUID; -import kotlin.random.Random; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -93,10 +93,10 @@ public DocumentResponse getByUuid(UUID uuid) { } public DocumentResponse put(UUID uuid, DocumentUpdateRequest request) { - String title = request.getTitle(); - String contents = request.getContents(); - String writer = request.getWriter(); - Long documentBytes = request.getDocumentBytes(); + String title = request.title(); + String contents = request.contents(); + String writer = request.writer(); + Long documentBytes = request.documentBytes(); Document document = documentRepository.findByUuid(uuid) .orElseThrow(() -> new WikiException(ErrorCode.DOCUMENT_NOT_FOUND)); diff --git a/src/main/java/com/wooteco/wiki/global/config/RandomConfig.java b/src/main/java/com/wooteco/wiki/global/config/RandomConfig.java new file mode 100644 index 0000000..29e0b33 --- /dev/null +++ b/src/main/java/com/wooteco/wiki/global/config/RandomConfig.java @@ -0,0 +1,15 @@ +package com.wooteco.wiki.global.config; + +import java.util.Random; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RandomConfig { + + @Bean + public Random random() { + return new Random(); + } +} + diff --git a/src/main/java/com/wooteco/wiki/global/config/RandomConfig.kt b/src/main/java/com/wooteco/wiki/global/config/RandomConfig.kt deleted file mode 100644 index 7bdc80c..0000000 --- a/src/main/java/com/wooteco/wiki/global/config/RandomConfig.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.wooteco.wiki.global.config - -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import kotlin.random.Random - -@Configuration -class RandomConfig { - - @Bean - fun random(): Random = Random.Default -} diff --git a/src/test/java/com/wooteco/wiki/document/service/DocumentSearchServiceTest.java b/src/test/java/com/wooteco/wiki/document/service/DocumentSearchServiceTest.java index 33c5f00..aaa0e60 100644 --- a/src/test/java/com/wooteco/wiki/document/service/DocumentSearchServiceTest.java +++ b/src/test/java/com/wooteco/wiki/document/service/DocumentSearchServiceTest.java @@ -75,8 +75,8 @@ void search_success_has_valid_type() { // then assertSoftly(softly -> { softly.assertThat(result).hasSize(2); - softly.assertThat(result.get(0).getDocumentType()).isEqualTo(DocumentType.CREW); - softly.assertThat(result.get(1).getDocumentType()).isEqualTo(DocumentType.ORGANIZATION); + softly.assertThat(result.get(0).documentType()).isEqualTo(DocumentType.CREW); + softly.assertThat(result.get(1).documentType()).isEqualTo(DocumentType.ORGANIZATION); }); } } diff --git a/src/test/java/com/wooteco/wiki/document/service/DocumentServiceTest.java b/src/test/java/com/wooteco/wiki/document/service/DocumentServiceTest.java index 87cfd7c..de4f079 100644 --- a/src/test/java/com/wooteco/wiki/document/service/DocumentServiceTest.java +++ b/src/test/java/com/wooteco/wiki/document/service/DocumentServiceTest.java @@ -61,14 +61,14 @@ void getDocumentLatestVersion_success_byExistsDocument() { historyRepository.save(history); // when - DocumentUpdateRequest documentUpdateRequest = new DocumentUpdateRequest("test", "test", "test", 150, + DocumentUpdateRequest documentUpdateRequest = new DocumentUpdateRequest("test", "test", "test", 150L, savedCrewDocument.getUuid()); documentService.put(savedCrewDocument.getUuid(), documentUpdateRequest); DocumentResponse documentResponse = documentService.getByUuid(savedCrewDocument.getUuid()); // then - assertThat(documentResponse.getLatestVersion()).isEqualTo(21L); + assertThat(documentResponse.latestVersion()).isEqualTo(21L); } } @@ -84,10 +84,10 @@ void getUuidByTitle_success_byExistsDocumentTitle() { DocumentFixture.createDocumentCreateRequestDefault()); // when - DocumentUuidResponse documentUuidResponse = documentService.getUuidByTitle(documentResponse.getTitle()); + DocumentUuidResponse documentUuidResponse = documentService.getUuidByTitle(documentResponse.title()); // then - assertThat(documentUuidResponse.uuid()).isEqualTo(documentResponse.getDocumentUUID()); + assertThat(documentUuidResponse.uuid()).isEqualTo(documentResponse.documentUUID()); } @DisplayName("존재하지 않는 문서 제목으로 조회할 경우 예외를 반환한다 : WikiException.DOCUMENT_NOT_FOUND") @@ -262,7 +262,7 @@ void deleteById_success_byExistsId() { assertThat(historyRepository.findAll()).hasSize(1); // when - documentService.deleteByUuid(documentResponse.getDocumentUUID()); + documentService.deleteByUuid(documentResponse.documentUUID()); // after then assertThat(documentRepository.findAll()).hasSize(0);