Skip to content
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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ AWS_ACCESS_KEY_ID=<aws-access-key-id>
AWS_SECRET_ACCESS_KEY=<aws-secret-access-key>

# S3 bucket
CLOUD_AWS_S3_BUCKET=<cloud-aws-s3-bucket>
CLOUD_AWS_S3_BUCKET=<cloud-aws-s3-bucket>
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ dependencies {
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testAnnotationProcessor 'org.projectlombok:lombok'

// AWS
implementation platform('software.amazon.awssdk:bom:2.25.60')
implementation 'software.amazon.awssdk:s3'
// AWS
implementation platform('software.amazon.awssdk:bom:2.27.21')
implementation 'software.amazon.awssdk:s3'
}

tasks.named('test') {
Expand All @@ -50,4 +50,4 @@ tasks.named('test') {

tasks.named('bootJar') {
archiveFileName = 'slatto.jar'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.slatto.domain.project.controller;

import com.slatto.domain.project.dto.ProjectFileDownloadResponse;
import com.slatto.domain.project.dto.ProjectFileListResponse;
import com.slatto.domain.project.dto.ProjectFileResponse;
import com.slatto.domain.project.dto.ProjectFileUpdateRequest;
import com.slatto.domain.project.dto.ProjectFileUploadRequest;
import com.slatto.domain.project.service.ProjectFileService;
import com.slatto.global.response.ApiResponse;
import com.slatto.global.response.code.CommonSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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.RequestPart;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.nio.charset.StandardCharsets;

@Tag(name = "Project File", description = "프로젝트 파일 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/projects/{projectId}/files")
public class ProjectFileController {

private final ProjectFileService projectFileService;

@Operation(summary = "프로젝트 파일 목록 조회")
@GetMapping
public ApiResponse<ProjectFileListResponse> getProjectFiles(
@AuthenticationPrincipal Long currentUserId,
@PathVariable Long projectId,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) Long cursor,
@RequestParam(defaultValue = "20") int size
) {
ProjectFileListResponse response = projectFileService.getProjectFiles(
projectId,
currentUserId,
keyword,
cursor,
size
);

return ApiResponse.success(CommonSuccessCode.OK, response);
}

@Operation(summary = "프로젝트 파일 업로드")
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public ApiResponse<ProjectFileResponse> uploadProjectFile(
@AuthenticationPrincipal Long currentUserId,
@PathVariable Long projectId,
@Valid @RequestPart("request") ProjectFileUploadRequest request,
@RequestPart("file") MultipartFile file
) {
ProjectFileResponse response = projectFileService.uploadProjectFile(
projectId,
currentUserId,
request,
file
);

return ApiResponse.success(CommonSuccessCode.CREATED, response);
}

@Operation(summary = "프로젝트 파일 수정")
@PatchMapping("/{fileId}")
public ApiResponse<ProjectFileResponse> updateProjectFile(
@AuthenticationPrincipal Long currentUserId,
@PathVariable Long projectId,
@PathVariable Long fileId,
@Valid @RequestBody ProjectFileUpdateRequest request
) {
ProjectFileResponse response = projectFileService.updateProjectFile(
projectId,
fileId,
currentUserId,
request
);

return ApiResponse.success(CommonSuccessCode.OK, response);
}

@Operation(summary = "프로젝트 파일 삭제")
@DeleteMapping("/{fileId}")
public ApiResponse<Void> deleteProjectFile(
@AuthenticationPrincipal Long currentUserId,
@PathVariable Long projectId,
@PathVariable Long fileId
) {
projectFileService.deleteProjectFile(projectId, fileId, currentUserId);

return ApiResponse.success(CommonSuccessCode.OK, null);
}

@Operation(summary = "프로젝트 파일 다운로드")
@GetMapping("/{fileId}/download")
public ResponseEntity<InputStreamResource> downloadProjectFile(
@AuthenticationPrincipal Long currentUserId,
@PathVariable Long projectId,
@PathVariable Long fileId
) {
ProjectFileDownloadResponse response = projectFileService.downloadProjectFile(
projectId,
fileId,
currentUserId
);

return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(response.getContentType()))
.contentLength(response.getFileSize())
.headers(headers -> headers.setContentDisposition(
ContentDisposition.attachment()
.filename(response.getFileName(), StandardCharsets.UTF_8)
.build()
))
.body(new InputStreamResource(response.getInputStream()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public Project toProject(Users ownerUser, ProjectCreateRequest request) {
ownerUser,
request.getTitle(),
request.getType(),
request.getCustomTypeName(),
request.getLengthType(),
request.getDescription(),
request.getEndDate(),
Expand Down Expand Up @@ -84,7 +83,7 @@ public ProjectListResponse.ProjectSummary toSummary(
public ProjectDetailResponse toDetailResponse(
Project project,
ProjectMember currentMember,
List<RoleName> myRoles,
List<RoleName> roleNames,
Long memberCount
) {
boolean admin = currentMember.isAdmin();
Expand All @@ -102,7 +101,7 @@ public ProjectDetailResponse toDetailResponse(
.kind(project.getKind())
.owner(toOwnerSummary(project.getOwnerUser()))
.myPermission(currentMember.getPermission())
.myRoles(myRoles)
.roleNames(roleNames)
.memberCount(memberCount)
.canEdit(admin)
.canDelete(admin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ public class ProjectCreateRequest {
@NotNull(message = "프로젝트 유형은 필수입니다.")
private CategoryName type;

@Size(max = 100, message = "커스텀 유형명은 최대 100자까지 입력할 수 있습니다.")
private String customTypeName;

@NotNull(message = "영상 길이는 필수입니다.")
private LengthType lengthType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class ProjectDetailResponse {

private Permission myPermission;

private List<RoleName> myRoles;
private List<RoleName> roleNames;

private Long memberCount;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.slatto.domain.project.dto;

import lombok.Builder;
import lombok.Getter;

import java.io.InputStream;

@Getter
@Builder
public class ProjectFileDownloadResponse {

private String fileName;

private String contentType;

private Long fileSize;

private InputStream inputStream;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.slatto.domain.project.dto;

import lombok.Builder;
import lombok.Getter;

import java.util.List;

@Getter
@Builder
public class ProjectFileListResponse {

private List<ProjectFileResponse> items;

private Long nextCursor;

private Boolean hasNext;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.slatto.domain.project.dto;

import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
@Builder
public class ProjectFileResponse {

private Long id;

private String fileName;

private String description;

private String contentType;

private Long fileSize;

private Boolean isPinned;

private Boolean isFinal;

private UploaderSummary uploader;

private LocalDateTime createdAt;

private LocalDateTime updatedAt;

@Getter
@Builder
public static class UploaderSummary {

private Long id;

private String nickname;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.slatto.domain.project.dto;

import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ProjectFileUpdateRequest {

@Size(max = 255, message = "파일명은 최대 255자까지 입력할 수 있습니다.")
private String fileName;

private String description;

private Boolean isPinned;

private Boolean isFinal;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.slatto.domain.project.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ProjectFileUploadRequest {

@NotBlank(message = "파일명은 필수입니다.")
@Size(max = 255, message = "파일명은 최대 255자까지 입력할 수 있습니다.")
private String fileName;

private String description;

private Boolean isPinned;

private Boolean isFinal;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ public class ProjectUpdateRequest {
@NotNull(message = "프로젝트 유형은 필수입니다.")
private CategoryName type;

@Size(max = 100, message = "커스텀 유형명은 최대 100자까지 입력할 수 있습니다.")
private String customTypeName;

@NotNull(message = "영상 길이는 필수입니다.")
private LengthType lengthType;

Expand Down
9 changes: 0 additions & 9 deletions src/main/java/com/slatto/domain/project/entity/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ public class Project extends BaseEntity {
@Column(name = "type", nullable = false)
private CategoryName type;

@Column(name = "custom_type_name", nullable = true, length = 100)
private String customTypeName;

@Enumerated(EnumType.STRING)
@Column(name = "length_type", nullable = true)
private LengthType lengthType;
Expand Down Expand Up @@ -74,7 +71,6 @@ private Project(
Users ownerUser,
String title,
CategoryName type,
String customTypeName,
LengthType lengthType,
String description,
LocalDate endDate,
Expand All @@ -87,7 +83,6 @@ private Project(
this.ownerUser = ownerUser;
this.title = title;
this.type = type;
this.customTypeName = customTypeName;
this.lengthType = lengthType;
this.description = description;
this.startDate = startDate;
Expand All @@ -101,7 +96,6 @@ public static Project create(
Users ownerUser,
String title,
CategoryName type,
String customTypeName,
LengthType lengthType,
String description,
LocalDate endDate,
Expand All @@ -112,7 +106,6 @@ public static Project create(
ownerUser,
title,
type,
customTypeName,
lengthType,
description,
endDate,
Expand All @@ -124,7 +117,6 @@ public static Project create(
public void updateInfo(
String title,
CategoryName type,
String customTypeName,
LengthType lengthType,
String description,
LocalDate endDate,
Expand All @@ -135,7 +127,6 @@ public void updateInfo(

this.title = title;
this.type = type;
this.customTypeName = customTypeName;
this.lengthType = lengthType;
this.description = description;
this.endDate = endDate;
Expand Down
Loading
Loading