diff --git a/src/main/java/com/tiki/server/auth/controller/docs/AuthControllerDocs.java b/src/main/java/com/tiki/server/auth/controller/docs/AuthControllerDocs.java index d535b518..1f66bd93 100644 --- a/src/main/java/com/tiki/server/auth/controller/docs/AuthControllerDocs.java +++ b/src/main/java/com/tiki/server/auth/controller/docs/AuthControllerDocs.java @@ -10,11 +10,13 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; +@Tag(name = "auth", description = "인증 API") public interface AuthControllerDocs { @Operation( diff --git a/src/main/java/com/tiki/server/document/controller/docs/DocumentControllerDocs.java b/src/main/java/com/tiki/server/document/controller/docs/DocumentControllerDocs.java index b9f6a5f8..acd37a33 100644 --- a/src/main/java/com/tiki/server/document/controller/docs/DocumentControllerDocs.java +++ b/src/main/java/com/tiki/server/document/controller/docs/DocumentControllerDocs.java @@ -22,7 +22,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "documents", description = "문서 API") +@Tag(name = "documents", description = "파일 API") public interface DocumentControllerDocs { @Operation( @@ -119,7 +119,7 @@ ResponseEntity> getDocuments( ) @PathVariable long teamId, @Parameter( name = "folderId", - description = "조회할 폴더 id", + description = "조회할 폴더 id (최상단은 비워두기)", in = ParameterIn.QUERY, example = "1" ) @RequestParam Long folderId diff --git a/src/main/java/com/tiki/server/document/dto/response/DocumentsGetResponse.java b/src/main/java/com/tiki/server/document/dto/response/DocumentsGetResponse.java index 6ae8be32..4e3503fd 100644 --- a/src/main/java/com/tiki/server/document/dto/response/DocumentsGetResponse.java +++ b/src/main/java/com/tiki/server/document/dto/response/DocumentsGetResponse.java @@ -12,17 +12,17 @@ @Builder(access = PRIVATE) public record DocumentsGetResponse( - List documents + List documents ) { public static DocumentsGetResponse from(final List documents) { return DocumentsGetResponse.builder() - .documents(documents.stream().map(DocumentGetResponse::from).toList()) + .documents(documents.stream().map(DocumentInfoGetResponse::from).toList()) .build(); } @Builder(access = PRIVATE) - private record DocumentGetResponse( + private record DocumentInfoGetResponse( long documentId, @NonNull String name, @NonNull String url, @@ -30,8 +30,8 @@ private record DocumentGetResponse( @NonNull LocalDateTime createdTime ) { - public static DocumentGetResponse from(final Document document) { - return DocumentGetResponse.builder() + public static DocumentInfoGetResponse from(final Document document) { + return DocumentInfoGetResponse.builder() .documentId(document.getId()) .name(document.getFileName()) .url(document.getFileUrl()) diff --git a/src/main/java/com/tiki/server/drive/controller/DriveController.java b/src/main/java/com/tiki/server/drive/controller/DriveController.java new file mode 100644 index 00000000..f594dc6e --- /dev/null +++ b/src/main/java/com/tiki/server/drive/controller/DriveController.java @@ -0,0 +1,41 @@ +package com.tiki.server.drive.controller; + +import static com.tiki.server.common.dto.SuccessResponse.success; +import static com.tiki.server.drive.message.SuccessMessage.SUCCESS_GET_DRIVE; + +import java.security.Principal; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.tiki.server.common.dto.SuccessResponse; +import com.tiki.server.drive.controller.docs.DriveControllerDocs; +import com.tiki.server.drive.dto.DriveGetResponse; +import com.tiki.server.drive.service.DriveService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/v1") +public class DriveController implements DriveControllerDocs { + + private final DriveService driveService; + + @ResponseStatus(HttpStatus.OK) + @GetMapping("/teams/{teamId}/drive") + public SuccessResponse getDrive( + final Principal principal, + @PathVariable final long teamId, + @RequestParam(required = false) final Long folderId + ) { + long memberId = Long.parseLong(principal.getName()); + DriveGetResponse response = driveService.getDrive(memberId, teamId, folderId); + return success(SUCCESS_GET_DRIVE.getMessage(), response); + } +} diff --git a/src/main/java/com/tiki/server/drive/controller/docs/DriveControllerDocs.java b/src/main/java/com/tiki/server/drive/controller/docs/DriveControllerDocs.java new file mode 100644 index 00000000..5ca280d5 --- /dev/null +++ b/src/main/java/com/tiki/server/drive/controller/docs/DriveControllerDocs.java @@ -0,0 +1,53 @@ +package com.tiki.server.drive.controller.docs; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; + +import com.tiki.server.common.dto.ErrorResponse; +import com.tiki.server.common.dto.SuccessResponse; +import com.tiki.server.drive.dto.DriveGetResponse; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "drive", description = "드라이브 API") +public interface DriveControllerDocs { + + @Operation( + summary = "드라이브 조회", + description = "드라이브 뷰를 조회한다.", + responses = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse getDrive( + @Parameter(hidden = true) Principal principal, + @Parameter( + name = "teamId", + description = "팀 id", + in = ParameterIn.PATH, + required = true, + example = "1" + ) @PathVariable long teamId, + @Parameter( + name = "folderId", + description = "조회할 폴더 id (최상단은 비워두기)", + in = ParameterIn.QUERY, + example = "1" + ) @RequestParam Long folderId + ); +} diff --git a/src/main/java/com/tiki/server/drive/dto/DriveGetResponse.java b/src/main/java/com/tiki/server/drive/dto/DriveGetResponse.java new file mode 100644 index 00000000..e8ce22c6 --- /dev/null +++ b/src/main/java/com/tiki/server/drive/dto/DriveGetResponse.java @@ -0,0 +1,68 @@ +package com.tiki.server.drive.dto; + +import static lombok.AccessLevel.PRIVATE; + +import java.time.LocalDateTime; +import java.util.List; + +import com.tiki.server.document.entity.Document; +import com.tiki.server.folder.entity.Folder; + +import lombok.Builder; +import lombok.NonNull; + +@Builder(access = PRIVATE) +public record DriveGetResponse( + List documents, + List folders +) { + + public static DriveGetResponse of(final List documents, final List folders) { + return DriveGetResponse.builder() + .documents(documents.stream().map(DocumentGetResponse::from).toList()) + .folders(folders.stream().map(FolderGetResponse::from).toList()) + .build(); + } + + @Builder(access = PRIVATE) + private record DocumentGetResponse( + long documentId, + @NonNull String name, + @NonNull String url, + double capacity, + @NonNull LocalDateTime createdTime, + @NonNull String type + ) { + + public static DocumentGetResponse from(final Document document) { + return DocumentGetResponse.builder() + .documentId(document.getId()) + .name(document.getFileName()) + .url(document.getFileUrl()) + .capacity(document.getCapacity()) + .createdTime(document.getCreatedAt()) + .type("document") + .build(); + } + } + + @Builder(access = PRIVATE) + private record FolderGetResponse( + long folderId, + @NonNull String name, + @NonNull LocalDateTime createdTime, + @NonNull String path, + @NonNull String type + ) { + + private static FolderGetResponse from(Folder folder) { + return FolderGetResponse.builder() + .folderId(folder.getId()) + .name(folder.getName()) + .createdTime(folder.getCreatedAt()) + .path(folder.getPath()) + .type("folder") + .build(); + } + } +} diff --git a/src/main/java/com/tiki/server/drive/message/SuccessMessage.java b/src/main/java/com/tiki/server/drive/message/SuccessMessage.java new file mode 100644 index 00000000..1d5a50fe --- /dev/null +++ b/src/main/java/com/tiki/server/drive/message/SuccessMessage.java @@ -0,0 +1,13 @@ +package com.tiki.server.drive.message; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum SuccessMessage { + + SUCCESS_GET_DRIVE("드라이브 조회 성공"); + + private final String message; +} diff --git a/src/main/java/com/tiki/server/drive/service/DriveService.java b/src/main/java/com/tiki/server/drive/service/DriveService.java new file mode 100644 index 00000000..c195375b --- /dev/null +++ b/src/main/java/com/tiki/server/drive/service/DriveService.java @@ -0,0 +1,52 @@ +package com.tiki.server.drive.service; + +import static com.tiki.server.folder.constant.Constant.ROOT_PATH; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.tiki.server.document.adapter.DocumentFinder; +import com.tiki.server.document.entity.Document; +import com.tiki.server.drive.dto.DriveGetResponse; +import com.tiki.server.folder.adapter.FolderFinder; +import com.tiki.server.folder.entity.Folder; +import com.tiki.server.memberteammanager.adapter.MemberTeamManagerFinder; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class DriveService { + + private final MemberTeamManagerFinder memberTeamManagerFinder; + private final DocumentFinder documentFinder; + private final FolderFinder folderFinder; + + public DriveGetResponse getDrive(final long memberId, final long teamId, final Long folderId) { + memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + List documents = documentFinder.findByTeamIdAndFolderId(teamId, folderId); + Folder folder = getFolder(teamId, folderId); + String path = getChildFolderPath(folder); + List folders = folderFinder.findByTeamIdAndPath(teamId, path); + return DriveGetResponse.of(documents, folders); + } + + private Folder getFolder(final long teamId, final Long folderId) { + if (folderId == null) { + return null; + } + Folder folder = folderFinder.findById(folderId); + folder.validateTeamId(teamId); + return folder; + } + + private String getChildFolderPath(final Folder folder) { + if (folder == null) { + return ROOT_PATH; + } + return folder.getChildPath(); + } +} diff --git a/src/main/java/com/tiki/server/folder/controller/docs/FolderControllerDocs.java b/src/main/java/com/tiki/server/folder/controller/docs/FolderControllerDocs.java index 20c62c3c..e919c543 100644 --- a/src/main/java/com/tiki/server/folder/controller/docs/FolderControllerDocs.java +++ b/src/main/java/com/tiki/server/folder/controller/docs/FolderControllerDocs.java @@ -10,7 +10,6 @@ import com.tiki.server.common.dto.ErrorResponse; import com.tiki.server.common.dto.SuccessResponse; -import com.tiki.server.document.dto.response.DeletedDocumentsGetResponse; import com.tiki.server.folder.dto.request.FolderCreateRequest; import com.tiki.server.folder.dto.request.FolderNameUpdateRequest; import com.tiki.server.folder.dto.response.FolderCreateResponse; @@ -22,7 +21,9 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +@Tag(name = "folders", description = "폴더 API") public interface FolderControllerDocs { @Operation( @@ -45,11 +46,12 @@ ResponseEntity> getFolders( name = "teamId", description = "팀 id", in = ParameterIn.PATH, + required = true, example = "1" ) @PathVariable long teamId, @Parameter( name = "folderId", - description = "조회할 폴더 id", + description = "조회할 폴더 id (최상단은 비워두기)", in = ParameterIn.QUERY, example = "1" ) @RequestParam Long folderId @@ -75,11 +77,12 @@ ResponseEntity> createFolder( name = "teamId", description = "팀 id", in = ParameterIn.PATH, + required = true, example = "1" ) @PathVariable long teamId, @Parameter( name = "folderId", - description = "생성할 폴더가 속할 폴더 id", + description = "생성할 폴더가 속할 폴더 id (최상단은 비워두기)", in = ParameterIn.QUERY, example = "1" ) @RequestParam Long folderId, @@ -106,6 +109,7 @@ ResponseEntity> updateFolderName( name = "teamId", description = "팀 id", in = ParameterIn.PATH, + required = true, example = "1" ) @PathVariable long teamId, @Parameter( @@ -137,6 +141,7 @@ ResponseEntity delete( name = "teamId", description = "팀 id", in = ParameterIn.PATH, + required = true, example = "1" ) @PathVariable long teamId, @Parameter( diff --git a/src/main/java/com/tiki/server/folder/dto/response/FoldersGetResponse.java b/src/main/java/com/tiki/server/folder/dto/response/FoldersGetResponse.java index 75b7c9bd..8109f699 100644 --- a/src/main/java/com/tiki/server/folder/dto/response/FoldersGetResponse.java +++ b/src/main/java/com/tiki/server/folder/dto/response/FoldersGetResponse.java @@ -12,25 +12,25 @@ @Builder(access = PRIVATE) public record FoldersGetResponse( - List folders + List folders ) { public static FoldersGetResponse from(List folders) { return FoldersGetResponse.builder() - .folders(folders.stream().map(FolderGetResponse::from).toList()) + .folders(folders.stream().map(FolderInfoGetResponse::from).toList()) .build(); } @Builder(access = PRIVATE) - private record FolderGetResponse( + private record FolderInfoGetResponse( long id, @NonNull String name, @NonNull LocalDateTime createdTime, @NonNull String path ) { - private static FolderGetResponse from(Folder folder) { - return FolderGetResponse.builder() + private static FolderInfoGetResponse from(Folder folder) { + return FolderInfoGetResponse.builder() .id(folder.getId()) .name(folder.getName()) .createdTime(folder.getCreatedAt()) diff --git a/src/main/java/com/tiki/server/member/controller/docs/MemberControllerDocs.java b/src/main/java/com/tiki/server/member/controller/docs/MemberControllerDocs.java index 3729f511..2edee43a 100644 --- a/src/main/java/com/tiki/server/member/controller/docs/MemberControllerDocs.java +++ b/src/main/java/com/tiki/server/member/controller/docs/MemberControllerDocs.java @@ -12,12 +12,14 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import java.security.Principal; +@Tag(name = "members", description = "멤버 API") public interface MemberControllerDocs { @Operation( diff --git a/src/main/java/com/tiki/server/timeblock/dto/response/TimeBlockDetailGetResponse.java b/src/main/java/com/tiki/server/timeblock/dto/response/TimeBlockDetailGetResponse.java index acd356dd..eee4d272 100644 --- a/src/main/java/com/tiki/server/timeblock/dto/response/TimeBlockDetailGetResponse.java +++ b/src/main/java/com/tiki/server/timeblock/dto/response/TimeBlockDetailGetResponse.java @@ -12,27 +12,27 @@ @Builder(access = PRIVATE) public record TimeBlockDetailGetResponse( - List documents, + List documents, List notes ) { public static TimeBlockDetailGetResponse from(List documents, List notes) { return TimeBlockDetailGetResponse.builder() - .documents(documents.stream().map(DocumentGetResponse::from).toList()) + .documents(documents.stream().map(DocumentDetailGetResponse::from).toList()) .notes(notes.stream().map(NoteNameGetResponse::from).toList()) .build(); } @Builder(access = PRIVATE) - private record DocumentGetResponse( + private record DocumentDetailGetResponse( long documentId, @NonNull String fileName, @NonNull String fileUrl, long tagId ) { - private static DocumentGetResponse from(DocumentTagInfo document) { - return DocumentGetResponse.builder() + private static DocumentDetailGetResponse from(DocumentTagInfo document) { + return DocumentDetailGetResponse.builder() .documentId(document.documentId()) .fileName(document.fileName()) .fileUrl(document.fileUrl()) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 6dbe84dc..3dc067d9 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -54,6 +54,3 @@ aws-property: bucket: ${AWS_PROPERTY.BUCKET} aws-region: ap-northeast-2 s3-url: ${AWS_PROPERTY.S3_URL} - -springdoc: - use-fqn: true