Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PDS-36] 아카이빙 자료 삭제 API hard delete 구현 및 스웨거 설정 #7

Merged
merged 3 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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