diff --git a/src/main/java/com/tiki/server/document/adapter/DocumentDeleter.java b/src/main/java/com/tiki/server/document/adapter/DocumentDeleter.java index 2c343a3c..1a4c113c 100644 --- a/src/main/java/com/tiki/server/document/adapter/DocumentDeleter.java +++ b/src/main/java/com/tiki/server/document/adapter/DocumentDeleter.java @@ -5,7 +5,6 @@ import com.tiki.server.common.support.RepositoryAdapter; import com.tiki.server.document.entity.Document; import com.tiki.server.document.repository.DocumentRepository; -import com.tiki.server.document.vo.DocumentVO; import lombok.RequiredArgsConstructor; @@ -15,15 +14,7 @@ public class DocumentDeleter { private final DocumentRepository documentRepository; - public void delete(Document document) { - documentRepository.delete(document); - } - public void deleteAll(List documents) { documentRepository.deleteAll(documents); } - - public void deleteAllByTimeBlockId(long timeBlockId) { - documentRepository.deleteAllByTimeBlockId(timeBlockId); - } } diff --git a/src/main/java/com/tiki/server/document/adapter/DocumentFinder.java b/src/main/java/com/tiki/server/document/adapter/DocumentFinder.java index fdcc7546..772db6d3 100644 --- a/src/main/java/com/tiki/server/document/adapter/DocumentFinder.java +++ b/src/main/java/com/tiki/server/document/adapter/DocumentFinder.java @@ -3,14 +3,11 @@ import static com.tiki.server.document.message.ErrorCode.INVALID_DOCUMENT; import java.util.List; -import java.util.Objects; -import com.tiki.server.common.entity.Position; import com.tiki.server.common.support.RepositoryAdapter; import com.tiki.server.document.entity.Document; import com.tiki.server.document.exception.DocumentException; import com.tiki.server.document.repository.DocumentRepository; -import com.tiki.server.document.vo.DocumentVO; import lombok.RequiredArgsConstructor; @@ -26,24 +23,9 @@ public List findAllByIdAndTeamId(final List documentIds, final l .toList(); } - public Document findByIdOrElseThrow(final long documentId) { - return documentRepository.findById(documentId).orElseThrow(() -> new DocumentException(INVALID_DOCUMENT)); - } - - public Document findByIdWithTimeBlock(long documentId) { - Document document = documentRepository.findByIdWithTimeBlock(documentId); - if (Objects.isNull(document)) { - throw new DocumentException(INVALID_DOCUMENT); - } - return document; - } - - public List findAllByTimeBlockId(long timeBlockId) { - return documentRepository.findAllByTimeBlockId(timeBlockId).stream().map(DocumentVO::from).toList(); - } - - public List findAllByTeamIdAndAccessiblePosition(long teamId, Position accessiblePosition) { - return documentRepository.findAllByTeamIdAndAccessiblePosition(teamId, accessiblePosition); + public Document findById(final long documentId) { + return documentRepository.findById(documentId) + .orElseThrow(() -> new DocumentException(INVALID_DOCUMENT)); } public List findAllByTeamId(long teamId) { diff --git a/src/main/java/com/tiki/server/document/adapter/DocumentSaver.java b/src/main/java/com/tiki/server/document/adapter/DocumentSaver.java index 8648cb85..d86f99b7 100644 --- a/src/main/java/com/tiki/server/document/adapter/DocumentSaver.java +++ b/src/main/java/com/tiki/server/document/adapter/DocumentSaver.java @@ -24,11 +24,6 @@ public void restore(final List deletedDocuments) { } private Document create(final DeletedDocument deletedDocument) { - return Document.restore( - deletedDocument.getFileName(), - deletedDocument.getFileUrl(), - deletedDocument.getCapacity(), - deletedDocument.getTeamId() - ); + return Document.restore(deletedDocument); } } diff --git a/src/main/java/com/tiki/server/document/controller/DocumentController.java b/src/main/java/com/tiki/server/document/controller/DocumentController.java index 671c2ed4..6fbf95d7 100644 --- a/src/main/java/com/tiki/server/document/controller/DocumentController.java +++ b/src/main/java/com/tiki/server/document/controller/DocumentController.java @@ -46,18 +46,6 @@ public ResponseEntity> getAllDocuments( return ResponseEntity.ok(SuccessResponse.success(SUCCESS_GET_DOCUMENTS.getMessage(), response)); } - @Override - @DeleteMapping("/documents/team/{teamId}/document/{documentId}") - public ResponseEntity deleteDocument( - final Principal principal, - @PathVariable final long teamId, - @PathVariable final long documentId - ) { - long memberId = Long.parseLong(principal.getName()); - documentService.deleteDocument(memberId, teamId, documentId); - return ResponseEntity.noContent().build(); - } - @PostMapping("/teams/{teamId}/documents") public ResponseEntity> createDocuments( final Principal principal, 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 dd8f2e17..b9f6a5f8 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 @@ -64,44 +64,6 @@ ResponseEntity> getAllDocuments( ) @RequestParam String type ); - @Operation( - summary = "문서 삭제", - description = "문서를 삭제한다.", - responses = { - @ApiResponse(responseCode = "204", description = "성공"), - @ApiResponse( - responseCode = "403", - description = "접근 권한 없음", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse( - responseCode = "404", - description = "팀에 존재하지 않는 회원, 유효하지 않은 문서", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse( - responseCode = "4xx", - description = "클라이언트(요청) 오류", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse( - responseCode = "500", - description = "서버 내부 오류", - content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} - ) - ResponseEntity deleteDocument( - @Parameter(hidden = true) Principal principal, - @Parameter( - name = "teamId", - description = "팀 id", - in = ParameterIn.PATH, - example = "1" - ) @PathVariable long teamId, - @Parameter( - name = "documentId", - description = "문서 id", - in = ParameterIn.PATH, - example = "1" - ) @PathVariable long documentId - ); - @Operation( summary = "문서 생성", description = "문서를 여러 개 생성한다.", @@ -119,13 +81,13 @@ ResponseEntity deleteDocument( ResponseEntity> createDocuments( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "폴더 id", + name = "folderId", description = "생성할 파일이 속할 폴더 id", in = ParameterIn.QUERY, example = "1" @@ -150,13 +112,13 @@ ResponseEntity> createDocuments( ResponseEntity> getDocuments( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "폴더 id", + name = "folderId", description = "조회할 폴더 id", in = ParameterIn.QUERY, example = "1" @@ -180,13 +142,13 @@ ResponseEntity> getDocuments( ResponseEntity delete( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "파일 id", + name = "documentId", description = "삭제할 파일 id 리스트", in = ParameterIn.QUERY, required = true, @@ -211,13 +173,13 @@ ResponseEntity delete( ResponseEntity deleteTrash( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "파일 id", + name = "documentId", description = "삭제할 파일 id 리스트", in = ParameterIn.QUERY, required = true, @@ -242,13 +204,13 @@ ResponseEntity deleteTrash( ResponseEntity restore( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "파일 id", + name = "documentId", description = "복구할 파일 id 리스트", in = ParameterIn.QUERY, required = true, @@ -273,7 +235,7 @@ ResponseEntity restore( ResponseEntity> getTrash( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" diff --git a/src/main/java/com/tiki/server/document/dto/request/DocumentCreateRequest.java b/src/main/java/com/tiki/server/document/dto/request/DocumentCreateRequest.java index f53dff20..9c4da95f 100644 --- a/src/main/java/com/tiki/server/document/dto/request/DocumentCreateRequest.java +++ b/src/main/java/com/tiki/server/document/dto/request/DocumentCreateRequest.java @@ -8,6 +8,8 @@ public record DocumentCreateRequest( @NonNull String fileName, @Schema(description = "파일 url", example = "https://.../tiki.jpg") @NonNull String fileUrl, + @Schema(description = "파일 key", example = "....jpg") + @NonNull String fileKey, @Schema(description = "파일 용량", example = "1.23") double capacity ) { diff --git a/src/main/java/com/tiki/server/document/entity/DeletedDocument.java b/src/main/java/com/tiki/server/document/entity/DeletedDocument.java index 5f1b352f..0007a031 100644 --- a/src/main/java/com/tiki/server/document/entity/DeletedDocument.java +++ b/src/main/java/com/tiki/server/document/entity/DeletedDocument.java @@ -31,6 +31,8 @@ public class DeletedDocument extends BaseTime { private String fileUrl; + private String fileKey; + private long teamId; private double capacity; diff --git a/src/main/java/com/tiki/server/document/entity/Document.java b/src/main/java/com/tiki/server/document/entity/Document.java index 429f21b5..7fc463af 100644 --- a/src/main/java/com/tiki/server/document/entity/Document.java +++ b/src/main/java/com/tiki/server/document/entity/Document.java @@ -36,47 +36,33 @@ public class Document extends BaseTime { private String fileUrl; + private String fileKey; + private double capacity; private long teamId; private Long folderId; - @ManyToOne(fetch = LAZY) - @JoinColumn(name = "block_id") - private TimeBlock timeBlock; - - public static Document of(final String fileName, final String fileUrl, final TimeBlock timeBlock) { - return Document.builder() - .fileName(fileName) - .fileUrl(fileUrl) - .capacity(0) // TODO : 타임 블록 생성 api 수정 후 제거 예정 - .teamId(1) // TODO : 타임 블록 생성 api 수정 후 제거 예정 - .folderId(null) // TODO : 타임 블록 생성 api 수정 후 제거 예정 - .timeBlock(timeBlock) - .build(); - } - public static Document of(final DocumentCreateRequest request, final long teamId, final Long folderId) { return Document.builder() .fileName(request.fileName()) .fileUrl(request.fileUrl()) .capacity(request.capacity()) + .fileKey(request.fileKey()) .teamId(teamId) .folderId(folderId) - .timeBlock(null) // TODO : 타임 블록 생성 api 수정 후 제거 예정 .build(); } - public static Document restore(final String fileName, final String fileUrl, - final double capacity, final long teamId) { + public static Document restore(final DeletedDocument deletedDocument) { return Document.builder() - .fileName(fileName) - .fileUrl(fileUrl) - .capacity(capacity) - .teamId(teamId) + .fileName(deletedDocument.getFileName()) + .fileUrl(deletedDocument.getFileUrl()) + .capacity(deletedDocument.getCapacity()) + .fileKey(deletedDocument.getFileKey()) + .teamId(deletedDocument.getTeamId()) .folderId(null) - .timeBlock(null) .build(); } } diff --git a/src/main/java/com/tiki/server/document/repository/DocumentRepository.java b/src/main/java/com/tiki/server/document/repository/DocumentRepository.java index 63c4dfc2..8013da3c 100644 --- a/src/main/java/com/tiki/server/document/repository/DocumentRepository.java +++ b/src/main/java/com/tiki/server/document/repository/DocumentRepository.java @@ -10,23 +10,10 @@ import com.tiki.server.document.entity.Document; public interface DocumentRepository extends JpaRepository { - - List findAllByTimeBlockId(long timeBlockId); - List findAllByFolderId(long folderId); - @Query("select d from Document d join fetch d.timeBlock t " - + "where t.team.id = :teamId and t.accessiblePosition = :position order by d.createdAt asc") - List findAllByTeamIdAndAccessiblePosition(long teamId, Position position); - - @Query("select d from Document d join d.timeBlock t where t.team.id = :teamId") List findAllByTeamId(long teamId); - @Query("select d from Document d join fetch d.timeBlock where d.id = :documentId") - Document findByIdWithTimeBlock(long documentId); - - void deleteAllByTimeBlockId(long timeBlockId); - List findAllByTeamIdAndFolderIdOrderByCreatedAtDesc(long teamId, Long folderId); Optional findByIdAndTeamId(long id, long teamId); diff --git a/src/main/java/com/tiki/server/document/service/DocumentService.java b/src/main/java/com/tiki/server/document/service/DocumentService.java index 3c863fa2..9c1020e4 100644 --- a/src/main/java/com/tiki/server/document/service/DocumentService.java +++ b/src/main/java/com/tiki/server/document/service/DocumentService.java @@ -19,6 +19,7 @@ import com.tiki.server.document.entity.DeletedDocument; import com.tiki.server.document.entity.Document; import com.tiki.server.document.exception.DocumentException; +import com.tiki.server.documenttimeblockmanager.adapter.DTBAdapter; import com.tiki.server.external.util.S3Handler; import com.tiki.server.folder.adapter.FolderFinder; import com.tiki.server.folder.entity.Folder; @@ -41,21 +42,15 @@ public class DocumentService { private final MemberTeamManagerFinder memberTeamManagerFinder; private final DeletedDocumentAdapter deletedDocumentAdapter; private final TeamFinder teamFinder; + private final DTBAdapter dtbAdapter; private final S3Handler s3Handler; public DocumentsGetResponse getAllDocuments(final long memberId, final long teamId, final String type) { MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); Position accessiblePosition = Position.getAccessiblePosition(type); memberTeamManager.checkMemberAccessible(accessiblePosition); - return getAllDocumentsByType(teamId, accessiblePosition); - } - - @Transactional - public void deleteDocument(final long memberId, final long teamId, final long documentId) { - MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); - Document document = documentFinder.findByIdWithTimeBlock(documentId); - memberTeamManager.checkMemberAccessible(document.getTimeBlock().getAccessiblePosition()); - documentDeleter.delete(document); + List documents = documentFinder.findAllByTeamId(teamId); + return DocumentsGetResponse.from(documents); } @Transactional @@ -77,6 +72,7 @@ public DocumentsGetResponse get(final long memberId, final long teamId, final Lo public void delete(final long memberId, final long teamId, final List documentIds) { memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); List documents = documentFinder.findAllByIdAndTeamId(documentIds, teamId); + dtbAdapter.deleteAllByDocuments(documentIds); deletedDocumentAdapter.save(documents); documentDeleter.deleteAll(documents); } @@ -86,7 +82,7 @@ public void deleteTrash(final long memberId, final long teamId, final List memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); List deletedDocuments = deletedDocumentAdapter.get(documentIds, teamId); restoreTeamUsage(teamId, deletedDocuments); - deletedDocuments.forEach(deletedDocument -> s3Handler.deleteFile(deletedDocument.getFileName())); + deletedDocuments.forEach(deletedDocument -> s3Handler.deleteFile(deletedDocument.getFileKey())); deletedDocumentAdapter.deleteAll(deletedDocuments); } @@ -104,11 +100,6 @@ public DeletedDocumentsGetResponse getTrash(final long memberId, final long team return DeletedDocumentsGetResponse.from(deletedDocuments); } - private DocumentsGetResponse getAllDocumentsByType(final long teamId, final Position accessiblePosition) { - List documents = documentFinder.findAllByTeamIdAndAccessiblePosition(teamId, accessiblePosition); - return DocumentsGetResponse.from(documents); - } - private void validateFolder(final Long folderId, final long teamId) { if (folderId == null) { return; diff --git a/src/main/java/com/tiki/server/documenttimeblockmanager/adapter/DTBAdapter.java b/src/main/java/com/tiki/server/documenttimeblockmanager/adapter/DTBAdapter.java new file mode 100644 index 00000000..0866f7f7 --- /dev/null +++ b/src/main/java/com/tiki/server/documenttimeblockmanager/adapter/DTBAdapter.java @@ -0,0 +1,41 @@ +package com.tiki.server.documenttimeblockmanager.adapter; + +import java.util.List; + +import com.tiki.server.common.support.RepositoryAdapter; +import com.tiki.server.documenttimeblockmanager.entity.DTBManager; +import com.tiki.server.documenttimeblockmanager.repository.DTBRepository; +import com.tiki.server.timeblock.entity.TimeBlock; + +import lombok.RequiredArgsConstructor; + +@RepositoryAdapter +@RequiredArgsConstructor +public class DTBAdapter { + + private final DTBRepository dtbRepository; + + public void saveAll(final TimeBlock timeBlock, final List documentIds) { + documentIds.forEach(documentId -> dtbRepository.save(DTBManager.of(timeBlock, documentId))); + } + + public List getAllByTimeBlock(final TimeBlock timeBlock) { + return dtbRepository.findAllByTimeBlockId(timeBlock.getId()); + } + + public List getAllByIds(final List ids) { + return dtbRepository.findAllByIdIn(ids); + } + + public void deleteAll(final List dtbManagers) { + dtbRepository.deleteAll(dtbManagers); + } + + public void deleteAllByTimeBlock(final TimeBlock timeBlock) { + dtbRepository.deleteAllByTimeBlockId(timeBlock.getId()); + } + + public void deleteAllByDocuments(final List documentIds) { + dtbRepository.deleteAllByDocumentIdIn(documentIds); + } +} diff --git a/src/main/java/com/tiki/server/documenttimeblockmanager/entity/DTBManager.java b/src/main/java/com/tiki/server/documenttimeblockmanager/entity/DTBManager.java new file mode 100644 index 00000000..d7195198 --- /dev/null +++ b/src/main/java/com/tiki/server/documenttimeblockmanager/entity/DTBManager.java @@ -0,0 +1,49 @@ +package com.tiki.server.documenttimeblockmanager.entity; + +import static com.tiki.server.timeblock.message.ErrorCode.INVALID_DOCUMENT_TAG; +import static jakarta.persistence.GenerationType.IDENTITY; +import static lombok.AccessLevel.PRIVATE; +import static lombok.AccessLevel.PROTECTED; + +import com.tiki.server.common.entity.BaseTime; +import com.tiki.server.timeblock.entity.TimeBlock; +import com.tiki.server.timeblock.exception.TimeBlockException; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder(access = PRIVATE) +@AllArgsConstructor(access = PRIVATE) +@NoArgsConstructor(access = PROTECTED) +@Table(name = "document_time_block_manager") +public class DTBManager extends BaseTime { + + @Id + @GeneratedValue(strategy = IDENTITY) + private Long id; + + private long documentId; + + private long timeBlockId; + + public static DTBManager of(final TimeBlock timeBlock, final long documentId) { + return DTBManager.builder() + .documentId(documentId) + .timeBlockId(timeBlock.getId()) + .build(); + } + + public void validateTimeBlock(final TimeBlock timeBlock) { + if (this.timeBlockId != timeBlock.getId()) { + throw new TimeBlockException(INVALID_DOCUMENT_TAG); + } + } +} diff --git a/src/main/java/com/tiki/server/documenttimeblockmanager/repository/DTBRepository.java b/src/main/java/com/tiki/server/documenttimeblockmanager/repository/DTBRepository.java new file mode 100644 index 00000000..3dec3420 --- /dev/null +++ b/src/main/java/com/tiki/server/documenttimeblockmanager/repository/DTBRepository.java @@ -0,0 +1,17 @@ +package com.tiki.server.documenttimeblockmanager.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.tiki.server.documenttimeblockmanager.entity.DTBManager; + +public interface DTBRepository extends JpaRepository { + List findAllByTimeBlockId(long timeBlockId); + + List findAllByIdIn(List ids); + + void deleteAllByTimeBlockId(long timeBlockId); + + void deleteAllByDocumentIdIn(List documentIds); +} diff --git a/src/main/java/com/tiki/server/external/dto/request/S3DeleteRequest.java b/src/main/java/com/tiki/server/external/dto/request/S3DeleteRequest.java index ea68a69c..7904f7cb 100644 --- a/src/main/java/com/tiki/server/external/dto/request/S3DeleteRequest.java +++ b/src/main/java/com/tiki/server/external/dto/request/S3DeleteRequest.java @@ -3,6 +3,6 @@ import lombok.NonNull; public record S3DeleteRequest( - @NonNull String fileName + @NonNull String fileKey ) { } diff --git a/src/main/java/com/tiki/server/external/service/S3Service.java b/src/main/java/com/tiki/server/external/service/S3Service.java index 4cded7b7..444c3feb 100644 --- a/src/main/java/com/tiki/server/external/service/S3Service.java +++ b/src/main/java/com/tiki/server/external/service/S3Service.java @@ -17,6 +17,6 @@ public PreSignedUrlResponse getUploadPreSignedUrl(final String fileFormat) { } public void deleteFile(final S3DeleteRequest request) { - s3Handler.deleteFile(request.fileName()); + s3Handler.deleteFile(request.fileKey()); } } 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 57086748..20c62c3c 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 @@ -42,13 +42,13 @@ public interface FolderControllerDocs { ResponseEntity> getFolders( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "폴더 id", + name = "folderId", description = "조회할 폴더 id", in = ParameterIn.QUERY, example = "1" @@ -72,13 +72,13 @@ ResponseEntity> getFolders( ResponseEntity> createFolder( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "폴더 id", + name = "folderId", description = "생성할 폴더가 속할 폴더 id", in = ParameterIn.QUERY, example = "1" @@ -103,13 +103,13 @@ ResponseEntity> createFolder( ResponseEntity> updateFolderName( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "폴더 id", + name = "folderId", description = "수정할 폴더 id", in = ParameterIn.PATH, example = "1" @@ -134,13 +134,13 @@ ResponseEntity> updateFolderName( ResponseEntity delete( @Parameter(hidden = true) Principal principal, @Parameter( - name = "팀 id", + name = "teamId", description = "팀 id", in = ParameterIn.PATH, example = "1" ) @PathVariable long teamId, @Parameter( - name = "폴더 id", + name = "folderId", description = "삭제할 폴더 id 리스트", in = ParameterIn.QUERY, required = true, diff --git a/src/main/java/com/tiki/server/note/service/NoteService.java b/src/main/java/com/tiki/server/note/service/NoteService.java index a9be7efc..0835a74e 100644 --- a/src/main/java/com/tiki/server/note/service/NoteService.java +++ b/src/main/java/com/tiki/server/note/service/NoteService.java @@ -201,7 +201,7 @@ private List getTimeBlocksMappedByNote(final long noteId) { .map(NoteTimeBlockManager::getTimeBlockId) .toList(); return timblockIdList.stream() - .map(timeBlockFinder::findByIdOrElseThrow) + .map(timeBlockFinder::findById) .toList(); } @@ -210,7 +210,7 @@ private List getDocumentListMappedByNote(final long noteId) { .map(NoteDocumentManager::getDocumentId) .toList(); return documentIdList.stream() - .map(documentFinder::findByIdOrElseThrow) + .map(documentFinder::findById) .toList(); } diff --git a/src/main/java/com/tiki/server/timeblock/adapter/TimeBlockFinder.java b/src/main/java/com/tiki/server/timeblock/adapter/TimeBlockFinder.java index a87d2e76..9777a9a0 100644 --- a/src/main/java/com/tiki/server/timeblock/adapter/TimeBlockFinder.java +++ b/src/main/java/com/tiki/server/timeblock/adapter/TimeBlockFinder.java @@ -15,23 +15,28 @@ @RequiredArgsConstructor public class TimeBlockFinder { - private final TimeBlockRepository timeBlockRepository; - - public TimeBlock findByIdOrElseThrow(long id) { - return timeBlockRepository.findById(id) - .orElseThrow(() -> new TimeBlockException(INVALID_TIME_BLOCK)); - } - - public List findByTeamAndAccessiblePositionAndDate( - long teamId, - String accessiblePosition, - String date - ) { - return timeBlockRepository. - findByTeamAndAccessiblePositionAndDate(teamId, accessiblePosition, date).stream().toList(); - } - - public boolean existsById(Long timeBlockId) { - return timeBlockRepository.existsById(timeBlockId); - } + private final TimeBlockRepository timeBlockRepository; + + public TimeBlock findById(final long id) { + return timeBlockRepository.findById(id) + .orElseThrow(() -> new TimeBlockException(INVALID_TIME_BLOCK)); + } + + public TimeBlock findByIdAndTeamId(final long id, final long teamId) { + return timeBlockRepository.findByIdAndTeamId(id, teamId) + .orElseThrow(() -> new TimeBlockException(INVALID_TIME_BLOCK)); + } + + public List findByTeamAndAccessiblePositionAndDate( + final long teamId, + final String accessiblePosition, + final String date + ) { + return timeBlockRepository.findByTeamAndAccessiblePositionAndDate(teamId, accessiblePosition, date).stream() + .toList(); + } + + public boolean existsById(Long timeBlockId) { + return timeBlockRepository.existsById(timeBlockId); + } } diff --git a/src/main/java/com/tiki/server/timeblock/controller/TimeBlockController.java b/src/main/java/com/tiki/server/timeblock/controller/TimeBlockController.java index 50ed73bd..981f9bbe 100644 --- a/src/main/java/com/tiki/server/timeblock/controller/TimeBlockController.java +++ b/src/main/java/com/tiki/server/timeblock/controller/TimeBlockController.java @@ -1,12 +1,15 @@ package com.tiki.server.timeblock.controller; import static com.tiki.server.common.dto.SuccessResponse.*; +import static com.tiki.server.timeblock.message.SuccessMessage.SUCCESS_CREATE_DOCUMENT_TAG; import static com.tiki.server.timeblock.message.SuccessMessage.SUCCESS_CREATE_TIME_BLOCK; import static com.tiki.server.timeblock.message.SuccessMessage.SUCCESS_GET_TIMELINE; import static com.tiki.server.timeblock.message.SuccessMessage.SUCCESS_GET_TIME_BLOCK_DETAIL; import java.security.Principal; +import java.util.List; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -15,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestBody; 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; @@ -30,18 +34,18 @@ @RestController @RequiredArgsConstructor -@RequestMapping("api/v1/time-blocks") +@RequestMapping("api/v1") public class TimeBlockController implements TimeBlockControllerDocs { private final TimeBlockService timeBlockService; @Override - @PostMapping("/team/{teamId}/time-block") + @PostMapping("/teams/{teamId}/time-block") public ResponseEntity> createTimeBlock( - Principal principal, - @PathVariable long teamId, - @RequestParam String type, - @RequestBody TimeBlockCreateRequest request + final Principal principal, + @PathVariable final long teamId, + @RequestParam final String type, + @RequestBody final TimeBlockCreateRequest request ) { long memberId = Long.parseLong(principal.getName()); TimeBlockCreateResponse response = timeBlockService.createTimeBlock(memberId, teamId, type, request); @@ -51,12 +55,12 @@ public ResponseEntity> createTimeBlock( } @Override - @GetMapping("/team/{teamId}/timeline") + @GetMapping("/teams/{teamId}/timeline") public ResponseEntity> getTimeline( - Principal principal, - @PathVariable long teamId, - @RequestParam String type, - @RequestParam String date + final Principal principal, + @PathVariable final long teamId, + @RequestParam final String type, + @RequestParam final String date ) { long memberId = Long.parseLong(principal.getName()); TimelineGetResponse response = timeBlockService.getTimeline(memberId, teamId, type, date); @@ -64,11 +68,11 @@ public ResponseEntity> getTimeline( } @Override - @GetMapping("/team/{teamId}/time-block/{timeBlockId}") + @GetMapping("/teams/{teamId}/time-block/{timeBlockId}") public ResponseEntity> getTimeBlockDetail( - Principal principal, - @PathVariable long teamId, - @PathVariable long timeBlockId + final Principal principal, + @PathVariable final long teamId, + @PathVariable final long timeBlockId ) { long memberId = Long.parseLong(principal.getName()); TimeBlockDetailGetResponse response = timeBlockService.getTimeBlockDetail(memberId, teamId, timeBlockId); @@ -76,14 +80,40 @@ public ResponseEntity> getTimeBlockD } @Override - @DeleteMapping("/team/{teamId}/time-block/{timeBlockId}") + @DeleteMapping("/teams/{teamId}/time-block/{timeBlockId}") public ResponseEntity deleteTimeBlock( - Principal principal, - @PathVariable long teamId, - @PathVariable long timeBlockId + final Principal principal, + @PathVariable final long teamId, + @PathVariable final long timeBlockId ) { long memberId = Long.parseLong(principal.getName()); timeBlockService.deleteTimeBlock(memberId, teamId, timeBlockId); return ResponseEntity.noContent().build(); } + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping("/teams/{teamId}/time-block/{timeBlockId}") + public SuccessResponse createDocumentTag( + final Principal principal, + @PathVariable final long teamId, + @PathVariable final long timeBlockId, + @RequestParam("documentId") final List documentIds + ) { + long memberId = Long.parseLong(principal.getName()); + timeBlockService.createDocumentTag(memberId, teamId, timeBlockId, documentIds); + return SuccessResponse.success(SUCCESS_CREATE_DOCUMENT_TAG.getMessage()); + } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping("/teams/{teamId}/time-block/{timeBlockId}/tags") + public SuccessResponse deleteDocumentTag( + final Principal principal, + @PathVariable final long teamId, + @PathVariable final long timeBlockId, + @RequestParam("tagId") final List tagIds + ) { + long memberId = Long.parseLong(principal.getName()); + timeBlockService.deleteDocumentTag(memberId, teamId, timeBlockId, tagIds); + return SuccessResponse.success(SUCCESS_CREATE_DOCUMENT_TAG.getMessage()); + } } diff --git a/src/main/java/com/tiki/server/timeblock/controller/docs/TimeBlockControllerDocs.java b/src/main/java/com/tiki/server/timeblock/controller/docs/TimeBlockControllerDocs.java index 13023a62..6cff82ec 100644 --- a/src/main/java/com/tiki/server/timeblock/controller/docs/TimeBlockControllerDocs.java +++ b/src/main/java/com/tiki/server/timeblock/controller/docs/TimeBlockControllerDocs.java @@ -1,6 +1,7 @@ package com.tiki.server.timeblock.controller.docs; import java.security.Principal; +import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; @@ -200,4 +201,80 @@ ResponseEntity deleteTimeBlock( ) @PathVariable long timeBlockId ); + + @Operation( + summary = "타임 블록 파일 태그 추가", + description = "타임 블록에 파일 태그를 추가한다.", + responses = { + @ApiResponse(responseCode = "201", description = "성공"), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse createDocumentTag( + @Parameter(hidden = true) Principal principal, + @Parameter( + name = "teamId", + description = "팀 id", + in = ParameterIn.PATH, + example = "1" + ) @PathVariable long teamId, + @Parameter( + name = "timeBlockId", + description = "타임 블록 id", + in = ParameterIn.PATH, + example = "1" + ) @PathVariable long timeBlockId, + @Parameter( + name = "documentId", + description = "추가할 파일 id 리스트", + in = ParameterIn.QUERY, + required = true, + example = "[1, 2]" + ) @RequestParam("documentId") List documentIds + ); + + @Operation( + summary = "타임 블록 파일 태그 삭제", + description = "타임 블록의 파일 태그를 삭제한다.", + responses = { + @ApiResponse(responseCode = "204", description = "성공"), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse deleteDocumentTag( + @Parameter(hidden = true) Principal principal, + @Parameter( + name = "teamId", + description = "팀 id", + in = ParameterIn.PATH, + example = "1" + ) + @PathVariable long teamId, + @Parameter( + name = "timeBlockId", + description = "타임 블록 id", + in = ParameterIn.PATH, + example = "1" + ) + @PathVariable long timeBlockId, + @Parameter( + name = "tagId", + description = "삭제할 파일 태그 id 리스트", + in = ParameterIn.QUERY, + required = true, + example = "[1, 2]" + ) @RequestParam("tagId") List tagIds + ); } diff --git a/src/main/java/com/tiki/server/timeblock/dto/request/TimeBlockCreateRequest.java b/src/main/java/com/tiki/server/timeblock/dto/request/TimeBlockCreateRequest.java index 3a619105..c25e9c6c 100644 --- a/src/main/java/com/tiki/server/timeblock/dto/request/TimeBlockCreateRequest.java +++ b/src/main/java/com/tiki/server/timeblock/dto/request/TimeBlockCreateRequest.java @@ -1,7 +1,7 @@ package com.tiki.server.timeblock.dto.request; import java.time.LocalDate; -import java.util.Map; +import java.util.List; import com.tiki.server.timeblock.entity.BlockType; @@ -13,6 +13,6 @@ public record TimeBlockCreateRequest( @NonNull LocalDate startDate, @NonNull LocalDate endDate, @NonNull BlockType blockType, - Map files + List documentIds ) { } 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 4b186524..acd356dd 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 @@ -4,52 +4,54 @@ import java.util.List; -import com.tiki.server.document.vo.DocumentVO; - import com.tiki.server.note.entity.Note; +import com.tiki.server.timeblock.service.dto.DocumentTagInfo; + import lombok.Builder; import lombok.NonNull; @Builder(access = PRIVATE) public record TimeBlockDetailGetResponse( - List documents, - List notes + List documents, + List notes ) { - public static TimeBlockDetailGetResponse from(List documents, List notes) { - return TimeBlockDetailGetResponse.builder() - .documents(documents.stream().map(DocumentGetResponse::from).toList()) - .notes(notes.stream().map(NoteNameGetResponse::from).toList()) - .build(); - } - - @Builder(access = PRIVATE) - public record DocumentGetResponse( - long documentId, - @NonNull String fileName, - @NonNull String fileUrl - ) { - - public static DocumentGetResponse from(DocumentVO document) { - return DocumentGetResponse.builder() - .documentId(document.documentId()) - .fileName(document.fileName()) - .fileUrl(document.fileUrl()) - .build(); - } - } - - @Builder(access = PRIVATE) - public record NoteNameGetResponse( - long noteId, - @NonNull String noteName - ) { - - public static NoteNameGetResponse from(final Note note) { - return NoteNameGetResponse.builder() - .noteId(note.getId()) - .noteName(note.getTitle()) - .build(); - } - } + public static TimeBlockDetailGetResponse from(List documents, List notes) { + return TimeBlockDetailGetResponse.builder() + .documents(documents.stream().map(DocumentGetResponse::from).toList()) + .notes(notes.stream().map(NoteNameGetResponse::from).toList()) + .build(); + } + + @Builder(access = PRIVATE) + private record DocumentGetResponse( + long documentId, + @NonNull String fileName, + @NonNull String fileUrl, + long tagId + ) { + + private static DocumentGetResponse from(DocumentTagInfo document) { + return DocumentGetResponse.builder() + .documentId(document.documentId()) + .fileName(document.fileName()) + .fileUrl(document.fileUrl()) + .tagId(document.tagId()) + .build(); + } + } + + @Builder(access = PRIVATE) + private record NoteNameGetResponse( + long noteId, + @NonNull String noteName + ) { + + private static NoteNameGetResponse from(final Note note) { + return NoteNameGetResponse.builder() + .noteId(note.getId()) + .noteName(note.getTitle()) + .build(); + } + } } diff --git a/src/main/java/com/tiki/server/timeblock/message/ErrorCode.java b/src/main/java/com/tiki/server/timeblock/message/ErrorCode.java index 98509f12..cafa8d6d 100644 --- a/src/main/java/com/tiki/server/timeblock/message/ErrorCode.java +++ b/src/main/java/com/tiki/server/timeblock/message/ErrorCode.java @@ -15,6 +15,7 @@ public enum ErrorCode { /* 400 BAD_REQUEST : 잘못된 요청 */ INVALID_TYPE(BAD_REQUEST, "유효한 타입이 아닙니다."), + INVALID_DOCUMENT_TAG(BAD_REQUEST, "유효한 파일이 아닙니다"), /* 404 NOT_FOUND : 자원을 찾을 수 없음 */ INVALID_TIME_BLOCK(NOT_FOUND, "유효하지 않은 타임 블록입니다."); diff --git a/src/main/java/com/tiki/server/timeblock/message/SuccessMessage.java b/src/main/java/com/tiki/server/timeblock/message/SuccessMessage.java index f1ce45ef..3e3dd441 100644 --- a/src/main/java/com/tiki/server/timeblock/message/SuccessMessage.java +++ b/src/main/java/com/tiki/server/timeblock/message/SuccessMessage.java @@ -9,7 +9,8 @@ public enum SuccessMessage { SUCCESS_CREATE_TIME_BLOCK("타임 블록 생성 성공"), SUCCESS_GET_TIMELINE("타임라인 조회 성공"), - SUCCESS_GET_TIME_BLOCK_DETAIL("타임 블록 상세 정보 조회 성공"); + SUCCESS_GET_TIME_BLOCK_DETAIL("타임 블록 상세 정보 조회 성공"), + SUCCESS_CREATE_DOCUMENT_TAG("파일 태그 성공"); private final String message; } diff --git a/src/main/java/com/tiki/server/timeblock/repository/TimeBlockRepository.java b/src/main/java/com/tiki/server/timeblock/repository/TimeBlockRepository.java index c3d0e6f4..6b2ff15a 100644 --- a/src/main/java/com/tiki/server/timeblock/repository/TimeBlockRepository.java +++ b/src/main/java/com/tiki/server/timeblock/repository/TimeBlockRepository.java @@ -1,6 +1,7 @@ package com.tiki.server.timeblock.repository; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -9,6 +10,7 @@ import com.tiki.server.timeblock.entity.TimeBlock; public interface TimeBlockRepository extends JpaRepository { + Optional findByIdAndTeamId(long id, long teamId); void deleteAllByTeamId(long teamId); diff --git a/src/main/java/com/tiki/server/timeblock/service/TimeBlockService.java b/src/main/java/com/tiki/server/timeblock/service/TimeBlockService.java index 66169dd6..26a66ba8 100644 --- a/src/main/java/com/tiki/server/timeblock/service/TimeBlockService.java +++ b/src/main/java/com/tiki/server/timeblock/service/TimeBlockService.java @@ -1,21 +1,20 @@ package com.tiki.server.timeblock.service; import java.util.List; -import java.util.Map; +import com.tiki.server.document.entity.Document; +import com.tiki.server.documenttimeblockmanager.adapter.DTBAdapter; +import com.tiki.server.documenttimeblockmanager.entity.DTBManager; import com.tiki.server.note.adapter.NoteFinder; import com.tiki.server.note.entity.Note; import com.tiki.server.notetimeblockmanager.adapter.NoteTimeBlockManagerFinder; import com.tiki.server.notetimeblockmanager.entity.NoteTimeBlockManager; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.tiki.server.common.entity.Position; -import com.tiki.server.document.adapter.DocumentDeleter; import com.tiki.server.document.adapter.DocumentFinder; -import com.tiki.server.document.adapter.DocumentSaver; -import com.tiki.server.document.entity.Document; -import com.tiki.server.document.vo.DocumentVO; import com.tiki.server.memberteammanager.adapter.MemberTeamManagerFinder; import com.tiki.server.memberteammanager.entity.MemberTeamManager; import com.tiki.server.team.adapter.TeamFinder; @@ -28,6 +27,8 @@ import com.tiki.server.timeblock.dto.response.TimeBlockDetailGetResponse; import com.tiki.server.timeblock.dto.response.TimelineGetResponse; import com.tiki.server.timeblock.entity.TimeBlock; +import com.tiki.server.timeblock.service.dto.DocumentTagInfo; + import lombok.RequiredArgsConstructor; @Service @@ -35,73 +36,128 @@ @Transactional(readOnly = true) public class TimeBlockService { - private final TeamFinder teamFinder; - private final MemberTeamManagerFinder memberTeamManagerFinder; - private final TimeBlockSaver timeBlockSaver; - private final TimeBlockFinder timeBlockFinder; - private final TimeBlockDeleter timeBlockDeleter; - private final DocumentSaver documentSaver; - private final DocumentFinder documentFinder; - private final DocumentDeleter documentDeleter; - private final NoteTimeBlockManagerFinder noteTimeBlockManagerFinder; - private final NoteFinder noteFinder; - - @Transactional - public TimeBlockCreateResponse createTimeBlock( - long memberId, - long teamId, - String type, - TimeBlockCreateRequest request - ) { - Team team = teamFinder.findById(teamId); - MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); - Position accessiblePosition = Position.getAccessiblePosition(type); - memberTeamManager.checkMemberAccessible(accessiblePosition); - TimeBlock timeBlock = saveTimeBlock(team, accessiblePosition, request); - saveDocuments(request.files(), timeBlock); - return TimeBlockCreateResponse.of(timeBlock.getId()); - } - - public TimelineGetResponse getTimeline(long memberId, long teamId, String type, String date) { - Team team = teamFinder.findById(teamId); - MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); - Position accessiblePosition = Position.getAccessiblePosition(type); - memberTeamManager.checkMemberAccessible(accessiblePosition); - List timeBlocks = timeBlockFinder.findByTeamAndAccessiblePositionAndDate( - team.getId(), accessiblePosition.name(), date); - return TimelineGetResponse.from(timeBlocks); - } - - public TimeBlockDetailGetResponse getTimeBlockDetail(long memberId, long teamId, long timeBlockId) { - MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); - TimeBlock timeBlock = timeBlockFinder.findByIdOrElseThrow(timeBlockId); - memberTeamManager.checkMemberAccessible(timeBlock.getAccessiblePosition()); - List documents = documentFinder.findAllByTimeBlockId(timeBlockId); - List notes = getNotes(timeBlock.getId()); - return TimeBlockDetailGetResponse.from(documents, notes); - } - - @Transactional - public void deleteTimeBlock(long memberId, long teamId, long timeBlockId) { - MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); - TimeBlock timeBlock = timeBlockFinder.findByIdOrElseThrow(timeBlockId); - memberTeamManager.checkMemberAccessible(timeBlock.getAccessiblePosition()); - documentDeleter.deleteAllByTimeBlockId(timeBlock.getId()); - timeBlockDeleter.deleteById(timeBlock.getId()); - } - - private TimeBlock saveTimeBlock(Team team, Position accessiblePosition, TimeBlockCreateRequest request) { - return timeBlockSaver.save(TimeBlock.of(team, accessiblePosition, request)); - } - - private void saveDocuments(Map files, TimeBlock timeBlock) { - files.forEach((fileName, fileUrl) -> documentSaver.save(Document.of(fileName, fileUrl, timeBlock))); - } - - private List getNotes(final long timeBlockId) { - List noteTimeBlockManagers = noteTimeBlockManagerFinder.findAllByTimeBlockId(timeBlockId); - return noteTimeBlockManagers.stream() - .map(noteTimeBlockManager -> noteFinder.findById(noteTimeBlockManager.getNoteId())) - .toList(); - } + private final TeamFinder teamFinder; + private final MemberTeamManagerFinder memberTeamManagerFinder; + private final TimeBlockSaver timeBlockSaver; + private final TimeBlockFinder timeBlockFinder; + private final TimeBlockDeleter timeBlockDeleter; + private final DocumentFinder documentFinder; + private final DTBAdapter dtbAdapter; + private final NoteTimeBlockManagerFinder noteTimeBlockManagerFinder; + private final NoteFinder noteFinder; + + @Transactional + public TimeBlockCreateResponse createTimeBlock( + final long memberId, + final long teamId, + final String type, + final TimeBlockCreateRequest request + ) { + Team team = teamFinder.findById(teamId); + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + Position accessiblePosition = Position.getAccessiblePosition(type); + memberTeamManager.checkMemberAccessible(accessiblePosition); + validateDocuments(team, request.documentIds()); + TimeBlock timeBlock = saveTimeBlock(team, accessiblePosition, request); + dtbAdapter.saveAll(timeBlock, request.documentIds()); + return TimeBlockCreateResponse.of(timeBlock.getId()); + } + + public TimelineGetResponse getTimeline( + final long memberId, + final long teamId, + final String type, + final String date + ) { + Team team = teamFinder.findById(teamId); + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + Position accessiblePosition = Position.getAccessiblePosition(type); + memberTeamManager.checkMemberAccessible(accessiblePosition); + List timeBlocks = timeBlockFinder.findByTeamAndAccessiblePositionAndDate( + team.getId(), accessiblePosition.name(), date); + return TimelineGetResponse.from(timeBlocks); + } + + public TimeBlockDetailGetResponse getTimeBlockDetail( + final long memberId, + final long teamId, + final long timeBlockId + ) { + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + TimeBlock timeBlock = timeBlockFinder.findByIdAndTeamId(timeBlockId, teamId); + memberTeamManager.checkMemberAccessible(timeBlock.getAccessiblePosition()); + List documents = getDocumentsInfo(timeBlock); + List notes = getNotes(timeBlock.getId()); + return TimeBlockDetailGetResponse.from(documents, notes); + } + + @Transactional + public void deleteTimeBlock(final long memberId, final long teamId, final long timeBlockId) { + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + TimeBlock timeBlock = timeBlockFinder.findByIdAndTeamId(timeBlockId, teamId); + memberTeamManager.checkMemberAccessible(timeBlock.getAccessiblePosition()); + dtbAdapter.deleteAllByTimeBlock(timeBlock); + timeBlockDeleter.deleteById(timeBlock.getId()); + } + + @Transactional + public void createDocumentTag( + final long memberId, + final long teamId, + final long timeBlockId, + final List documentIds + ) { + Team team = teamFinder.findById(teamId); + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + TimeBlock timeBlock = timeBlockFinder.findByIdAndTeamId(timeBlockId, teamId); + memberTeamManager.checkMemberAccessible(timeBlock.getAccessiblePosition()); + validateDocuments(team, documentIds); + dtbAdapter.saveAll(timeBlock, documentIds); + } + + @Transactional + public void deleteDocumentTag( + final long memberId, + final long teamId, + final long timeBlockId, + final List tagIds + ) { + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + TimeBlock timeBlock = timeBlockFinder.findByIdAndTeamId(timeBlockId, teamId); + memberTeamManager.checkMemberAccessible(timeBlock.getAccessiblePosition()); + List dtbManagers = dtbAdapter.getAllByIds(tagIds); + dtbManagers.forEach(dtbManager -> dtbManager.validateTimeBlock(timeBlock)); + dtbAdapter.deleteAll(dtbManagers); + } + + private void validateDocuments(final Team team, final List documentIds) { + documentFinder.findAllByIdAndTeamId(documentIds, team.getId()); + } + + private TimeBlock saveTimeBlock( + final Team team, + final Position accessiblePosition, + final TimeBlockCreateRequest request + ) { + return timeBlockSaver.save(TimeBlock.of(team, accessiblePosition, request)); + } + + private List getDocumentsInfo(final TimeBlock timeBlock) { + List dtbManagers = dtbAdapter.getAllByTimeBlock(timeBlock); + return dtbManagers.stream() + .map(this::getDocumentTagInfo) + .toList(); + } + + private DocumentTagInfo getDocumentTagInfo(final DTBManager dtbManager) { + Document document = documentFinder.findById(dtbManager.getDocumentId()); + return DocumentTagInfo.of(document, dtbManager); + } + + private List getNotes(final long timeBlockId) { + List noteTimeBlockManagers = noteTimeBlockManagerFinder.findAllByTimeBlockId(timeBlockId); + return noteTimeBlockManagers.stream() + .map(noteTimeBlockManager -> noteFinder.findById(noteTimeBlockManager.getNoteId())) + .toList(); + } } diff --git a/src/main/java/com/tiki/server/document/vo/DocumentVO.java b/src/main/java/com/tiki/server/timeblock/service/dto/DocumentTagInfo.java similarity index 50% rename from src/main/java/com/tiki/server/document/vo/DocumentVO.java rename to src/main/java/com/tiki/server/timeblock/service/dto/DocumentTagInfo.java index 1fa87eb0..553c3ede 100644 --- a/src/main/java/com/tiki/server/document/vo/DocumentVO.java +++ b/src/main/java/com/tiki/server/timeblock/service/dto/DocumentTagInfo.java @@ -1,24 +1,27 @@ -package com.tiki.server.document.vo; +package com.tiki.server.timeblock.service.dto; import static lombok.AccessLevel.PRIVATE; import com.tiki.server.document.entity.Document; +import com.tiki.server.documenttimeblockmanager.entity.DTBManager; import lombok.Builder; import lombok.NonNull; @Builder(access = PRIVATE) -public record DocumentVO( +public record DocumentTagInfo( long documentId, @NonNull String fileName, - @NonNull String fileUrl + @NonNull String fileUrl, + long tagId ) { - public static DocumentVO from(Document document) { - return DocumentVO.builder() + public static DocumentTagInfo of(final Document document, final DTBManager dtbManager) { + return DocumentTagInfo.builder() .documentId(document.getId()) .fileName(document.getFileName()) .fileUrl(document.getFileUrl()) + .tagId(dtbManager.getId()) .build(); } }