Skip to content

Commit

Permalink
Merge pull request #7 from PLADI-ALM/feat/PDS-36-delete-material
Browse files Browse the repository at this point in the history
[PDS-36] 아카이빙 자료 삭제 API hard delete 구현 및 스웨거 설정
  • Loading branch information
leeseunghakhello authored Oct 19, 2023
2 parents 60a05f3 + 9c8c182 commit 1c17177
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,26 @@
import com.example.PLADIALMArchiving.archiving.dto.request.UploadMaterialReq;
import com.example.PLADIALMArchiving.archiving.dto.response.SearchMaterialRes;
import com.example.PLADIALMArchiving.archiving.service.ArchivingService;
import com.example.PLADIALMArchiving.global.exception.BaseException;
import com.example.PLADIALMArchiving.global.exception.BaseResponseCode;
import com.example.PLADIALMArchiving.global.resolver.Account;
import com.example.PLADIALMArchiving.global.response.ResponseCustom;
import com.example.PLADIALMArchiving.user.entity.User;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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.responses.ApiResponses;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Api(tags = "아카이빙 API")
@RestController
@RequiredArgsConstructor
Expand All @@ -25,33 +36,59 @@ public class ArchivingController {
/**
* 프로젝트를 추가한다.
*/
@Operation(summary = "프로젝트 추가 (김민기)", description = "자료 아카이빙을 위한 프로젝트를 추가한다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "(S0001)요청에 성공했습니다."),
@ApiResponse(responseCode = "409", description = "(P0001)이미 등록된 프로젝트입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "400", description = "(P0006)올바르지 않은 프로젝트 이름입니다. 다시 입력해주세요. (공백, 특수문자 제외 20자 이내)", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
})
@PostMapping("/projects/register")
public ResponseCustom<?> registerProject(@RequestBody RegisterProjectReq registerProjectReq) {
public ResponseCustom<?> registerProject(@RequestBody @Valid RegisterProjectReq registerProjectReq)
{
archivingService.registerProject(registerProjectReq);
return ResponseCustom.OK();
}

/**
* 자료를 업로드한다.
*/
@Operation(summary = "자료 업로드 (김민기)", description = "아카이빙할 자료를 업로드한다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "(S0001)요청에 성공했습니다."),
@ApiResponse(responseCode = "400", description = "(G0001)잘못된 요청입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "403", description = "(G0002)접근권한이 없습니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "404", description = "(P0002)존재하지 않는 프로젝트입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
})
@PostMapping("/projects/{projectId}/upload")
public ResponseCustom<?> uploadMaterial(
@RequestBody UploadMaterialReq uploadMaterialReq,
@PathVariable Long projectId,
public ResponseCustom<?> uploadMaterial
(
@RequestBody @Valid UploadMaterialReq uploadMaterialReq,
@Parameter(description = "(Long) 프로젝트 Id", example = "1") @PathVariable(name = "projectId") Long projectId,
@Account User user
)
{
if(!StringUtils.hasText(uploadMaterialReq.getFileKey()) || !StringUtils.hasText(uploadMaterialReq.getName()) ||
!StringUtils.hasText(uploadMaterialReq.getExtension()) || uploadMaterialReq.getSize() == null)
throw new BaseException(BaseResponseCode.INVALID_UPLOAD_MATERIAL_REQUEST);

archivingService.uploadMaterial(uploadMaterialReq, projectId, user);
return ResponseCustom.OK();
}

/**
* 자료목록을 조회 및 검색한다.
*/
@Operation(summary = "자료목록 조회 및 검색 (김민기)", description = "아카이빙 자료목록을 조회 및 검색한다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "(S0001)요청에 성공했습니다."),
@ApiResponse(responseCode = "404", description = "(P0002)존재하지 않는 프로젝트입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "404", description = "(P0003)존재하지 않는 카테고리입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
})
@PostMapping("/projects/{projectId}")
public ResponseCustom<Page<SearchMaterialRes>> searchMaterial(
@PathVariable Long projectId,
@RequestBody SearchMaterialReq searchMaterialReq,
public ResponseCustom<Page<SearchMaterialRes>> searchMaterial
(
@Parameter(description = "(Long) 프로젝트 Id", example = "1") @PathVariable(name = "projectId") Long projectId,
@RequestBody @Valid SearchMaterialReq searchMaterialReq,
Pageable pageable
)
{
Expand All @@ -60,9 +97,17 @@ public ResponseCustom<Page<SearchMaterialRes>> searchMaterial(
/**
* 자료를 삭제한다.
*/
@Operation(summary = "자료 삭제 (김민기)", description = "아카이빙 자료를 삭제한다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "(S0001)요청에 성공했습니다."),
@ApiResponse(responseCode = "400", description = "(G0001)잘못된 요청입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "403", description = "(G0002)접근권한이 없습니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "404", description = "(P0004)존재하지 않는 자료입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "401", description = "(P0005)관리자 계정 또는 자료를 업로드한 유저가 아니므로 자료를 삭제할 수 없습니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
})
@DeleteMapping("/materials/{materialId}")
public ResponseCustom<?> deleteMaterial(
@PathVariable Long materialId,
@Parameter(description = "(Long) 자원 Id", example = "15") @PathVariable(name = "materialId") Long materialId,
@Account User user
)
{
Expand All @@ -73,10 +118,16 @@ public ResponseCustom<?> deleteMaterial(
/**
* 자료를 다운로드한다.
*/
@GetMapping("/materials/{materialsId}")
@Operation(summary = "자료 다운로드 (김민기)", description = "아카이빙 자료를 다운로드한다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "(S0001)요청에 성공했습니다."),
@ApiResponse(responseCode = "400", description = "(G0001)잘못된 요청입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
@ApiResponse(responseCode = "404", description = "(P0004)존재하지 않는 자료입니다.", content = @Content(schema = @Schema(implementation = ResponseCustom.class))),
})
@GetMapping("/materials/{materialId}")
public ResponseCustom<?> downloadMaterial(
@PathVariable Long materialsId
@Parameter(description = "(Long) 자원 Id", example = "15") @PathVariable(name = "materialId") Long materialId
) {
return ResponseCustom.OK(archivingService.downloadMaterial(materialsId));
return ResponseCustom.OK(archivingService.downloadMaterial(materialId));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package com.example.PLADIALMArchiving.archiving.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.validation.constraints.Size;

@Getter
@NoArgsConstructor
public class RegisterProjectReq {

@Schema(type = "String", description = "프로젝트 이름 (공백, 특수문자 제외)", minLength = 1, maxLength = 20)
@Size(max = 20, message = "P0006")
private String name;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package com.example.PLADIALMArchiving.archiving.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

import javax.validation.constraints.Size;

@Getter
public class SearchMaterialReq {

private String cond;

@Schema(type = "String", description = "검색 카테고리 (전체, 이미지, 비디오, 문서)", maxLength = 10)
@Size(max = 10, message = "P0003")
private String category;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
package com.example.PLADIALMArchiving.archiving.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Getter
public class UploadMaterialReq {

@Schema(type = "String", description = "aws s3 file key")
@NotNull(message = "P0007")
private String fileKey;

@Schema(type = "String", description = "자료 이름 (공백, 특수문자 제외)", minLength = 1, maxLength = 20)
@Size(max = 20, message = "P0007")
private String name;

@Schema(type = "String", description = "자료 사이즈")
@NotNull(message = "P0007")
private Long size;

@Schema(type = "String", description = "확장자 ex) png, jpeg, mp4 ...")
@NotNull(message = "P0007")
private String extension;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,4 @@ public static Material toEntity(UploadMaterialReq uploadMaterialReq, Project pro
.user(user)
.build();
}

public void delete() {
this.setIsEnable(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

Expand All @@ -36,11 +37,16 @@ public class ArchivingService {

@Transactional
public void registerProject(RegisterProjectReq registerProjectReq) {
if(!validatePrjNameInput(registerProjectReq.getName())) throw new BaseException(BaseResponseCode.INVALID_NAME);
boolean present = projectRepository.findByName(registerProjectReq.getName()).isPresent();
if(present) throw new BaseException(BaseResponseCode.ALREADY_REGISTERED_PROJECT);
projectRepository.save(Project.toEntity(registerProjectReq.getName()));
}

private boolean validatePrjNameInput(String name) {
return name.matches("^[a-zA-Z0-9가-핳]{1,20}$");
}

@Transactional
public void uploadMaterial(UploadMaterialReq uploadMaterialReq, Long projectId, User user) {
Project project = projectRepository.findById(projectId).orElseThrow(() -> new BaseException(BaseResponseCode.PROJECT_NOT_FOUND));
Expand All @@ -55,7 +61,7 @@ public void deleteMaterial(Long materialId, User user) {
if(user.getRole() != Role.ADMIN || !user.getUserId().equals(material.getUser().getUserId()))
throw new BaseException(BaseResponseCode.UNAUTHORIZED_USER);

material.delete();
materialRepository.delete(material);
}

public Page<SearchMaterialRes> searchMaterial(Long projectId, SearchMaterialReq searchMaterialReq, Pageable pageable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

@Configuration
public class SwaggerConfig {
private static final String API_NAME = "PLADI_SERVER_API";
private static final String API_NAME = "PLADI_ARCHIVING_API";
private static final String API_VERSION = "0.0.1";
private static final String API_DESCRIPTION = "PLADI_SERVER_API_명세서";
private static final String API_DESCRIPTION = "PLADI_ARCHIVING_명세서";


@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ public enum BaseResponseCode {
BLACKLIST_TOKEN("T0007", HttpStatus.FORBIDDEN, "로그아웃 혹은 회원 탈퇴된 토큰입니다."),

// Archiving
ALREADY_REGISTERED_PROJECT("P0001", HttpStatus.BAD_REQUEST, "이미 등록된 프로젝트입니다."),
ALREADY_REGISTERED_PROJECT("P0001", HttpStatus.CONFLICT, "이미 등록된 프로젝트입니다."),
PROJECT_NOT_FOUND("P0002", HttpStatus.NOT_FOUND, "존재하지 않는 프로젝트입니다."),
CATEGORY_NOT_FOUND("P0003", HttpStatus.NOT_FOUND, "존재하지 않는 카테고리입니다."),
MATERIAL_NOT_FOUND("P0004", HttpStatus.NOT_FOUND, "존재하지 않는 자료입니다."),
UNAUTHORIZED_USER("P0005", HttpStatus.UNAUTHORIZED, "관리자 계정 또는 자료를 업로드한 유저가 아니므로 자료를 삭제할 수 없습니다."),
INVALID_NAME("P0006", HttpStatus.BAD_REQUEST, "올바르지 않은 이름 형식입니다. 다시 입력해주세요. (공백, 특수문자 제외 20자 이내)"),
INVALID_UPLOAD_MATERIAL_REQUEST("P0007", HttpStatus.BAD_REQUEST, "부적절한 자료 업로드 요청입니다. 공백을 제외하고 다시 입력해주세요."),
;

public final String code;
Expand Down

0 comments on commit 1c17177

Please sign in to comment.