Feat: 워크스페이스 CRUD 기능 구현 - S11P21S002-36
This commit is contained in:
parent
2ecca31dd7
commit
f0e6f2da93
@ -1,15 +1,19 @@
|
||||
package com.worlabel.domain.workspace.controller;
|
||||
|
||||
import com.worlabel.domain.workspace.entity.Workspace;
|
||||
import com.worlabel.domain.workspace.entity.dto.WorkspaceRequest;
|
||||
import com.worlabel.domain.workspace.entity.dto.WorkspaceResponse;
|
||||
import com.worlabel.domain.workspace.entity.dto.WorkspaceResponses;
|
||||
import com.worlabel.domain.workspace.service.WorkspaceService;
|
||||
import com.worlabel.global.annotation.CurrentUser;
|
||||
import com.worlabel.global.config.swagger.SwaggerApiError;
|
||||
import com.worlabel.global.config.swagger.SwaggerApiSuccess;
|
||||
import com.worlabel.global.exception.ErrorCode;
|
||||
import com.worlabel.global.response.BaseResponse;
|
||||
import com.worlabel.global.response.SuccessResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -26,46 +30,50 @@ public class WorkspaceController {
|
||||
@SwaggerApiSuccess(description = "워크스페이스를 성공적으로 생성합니다.")
|
||||
@SwaggerApiError({ErrorCode.EMPTY_REQUEST_PARAMETER, ErrorCode.SERVER_ERROR})
|
||||
@PostMapping
|
||||
public ResponseEntity<Workspace> createWorkspace(final Integer memberId, @RequestBody final WorkspaceRequest workspaceRequest) {
|
||||
Workspace createdWorkspace = workspaceService.createWorkspace(memberId, workspaceRequest);
|
||||
return ResponseEntity.ok(createdWorkspace);
|
||||
public BaseResponse<WorkspaceResponse> createWorkspace(@CurrentUser final Integer memberId, @RequestBody final WorkspaceRequest workspaceRequest) {
|
||||
WorkspaceResponse workspace = workspaceService.createWorkspace(memberId, workspaceRequest);
|
||||
return SuccessResponse.of(workspace);
|
||||
}
|
||||
|
||||
@Operation(summary = "특정 워크스페이스 조회", description = "특정 워크스페이스를 조회합니다.")
|
||||
@SwaggerApiSuccess(description = "특정 워크스페이스를 성공적으로 조회합니다.")
|
||||
@SwaggerApiError({ErrorCode.BAD_REQUEST, ErrorCode.NOT_AUTHOR, ErrorCode.SERVER_ERROR})
|
||||
@GetMapping("/{workspace_id}")
|
||||
public ResponseEntity<Workspace> getWorkspace(@PathVariable("workspace_id") Integer workspaceId) {
|
||||
Workspace workspace = workspaceService.getWorkspaceById(workspaceId);
|
||||
return ResponseEntity.ok(workspace);
|
||||
public BaseResponse<WorkspaceResponse> getWorkspace(@CurrentUser final Integer memberId, @PathVariable("workspace_id") final Integer workspaceId) {
|
||||
WorkspaceResponse workspace = workspaceService.getWorkspaceById(memberId, workspaceId);
|
||||
return SuccessResponse.of(workspace);
|
||||
}
|
||||
|
||||
@Operation(summary = "전체 워크스페이스 조회", description = "모든 워크스페이스를 조회합니다.")
|
||||
@SwaggerApiSuccess(description = "전체 워크스페이스를 성공적으로 조회합니다.")
|
||||
@SwaggerApiError({ErrorCode.SERVER_ERROR})
|
||||
@GetMapping
|
||||
public ResponseEntity<List<Workspace>> getAllWorkspaces() {
|
||||
List<Workspace> workspaces = workspaceService.getAllWorkspaces();
|
||||
return ResponseEntity.ok(workspaces);
|
||||
public BaseResponse<WorkspaceResponses> getAllWorkspaces(
|
||||
@CurrentUser final Integer memberId,
|
||||
@Parameter(name = "마지막 워크스페이스 id", description = "마지막 워크스페이스 id를 넣으면 그 아래 부터 가져옴, 넣지않으면 가장 최신", example = "1") @RequestParam(required = false) Integer lastWorkspaceId,
|
||||
@Parameter(name = "가져올 워크스페이스 수", description = "가져올 워크스페이스 수 default = 10", example = "20") @RequestParam(defaultValue = "10") Integer limitPage) {
|
||||
List<WorkspaceResponse> workspaces = workspaceService.getAllWorkspaces(memberId, lastWorkspaceId, limitPage);
|
||||
return SuccessResponse.of(WorkspaceResponses.from(workspaces));
|
||||
}
|
||||
|
||||
@Operation(summary = "워크스페이스 수정", description = "특정 워크스페이스를 수정합니다.")
|
||||
@SwaggerApiSuccess(description = "특정 워크스페이스를 성공적으로 수정합니다.")
|
||||
@SwaggerApiError({ErrorCode.BAD_REQUEST, ErrorCode.NOT_AUTHOR, ErrorCode.SERVER_ERROR})
|
||||
@PutMapping("/{workspace_id}")
|
||||
public ResponseEntity<Workspace> updateWorkspace(
|
||||
@PathVariable("workspace_id") Integer workspaceId,
|
||||
@RequestBody Workspace updatedWorkspace) {
|
||||
Workspace workspace = workspaceService.updateWorkspace(workspaceId, updatedWorkspace);
|
||||
return ResponseEntity.ok(workspace);
|
||||
public BaseResponse<WorkspaceResponse> updateWorkspace(
|
||||
@CurrentUser final Integer memberId,
|
||||
@PathVariable("workspace_id") final Integer workspaceId,
|
||||
@RequestBody final WorkspaceRequest updatedWorkspace) {
|
||||
WorkspaceResponse workspace = workspaceService.updateWorkspace(memberId, workspaceId, updatedWorkspace);
|
||||
return SuccessResponse.of(workspace);
|
||||
}
|
||||
|
||||
@Operation(summary = "워크스페이스 삭제", description = "특정 워크스페이스를 삭제합니다.")
|
||||
@SwaggerApiSuccess(description = "특정 워크스페이스를 성공적으로 삭제합니다.")
|
||||
@SwaggerApiError({ErrorCode.BAD_REQUEST, ErrorCode.NOT_AUTHOR, ErrorCode.SERVER_ERROR})
|
||||
@DeleteMapping("/{workspace_id}")
|
||||
public ResponseEntity<Void> deleteWorkspace(@PathVariable("workspace_id") Integer workspaceId) {
|
||||
workspaceService.deleteWorkspace(workspaceId);
|
||||
return ResponseEntity.noContent().build();
|
||||
public BaseResponse<Void> deleteWorkspace(@CurrentUser final Integer memberId, @PathVariable("workspace_id") final Integer workspaceId) {
|
||||
workspaceService.deleteWorkspace(memberId, workspaceId);
|
||||
return SuccessResponse.empty();
|
||||
}
|
||||
}
|
||||
|
@ -57,4 +57,10 @@ public class Workspace extends BaseEntity {
|
||||
public static Workspace of(final Member member, final String title, final String description) {
|
||||
return new Workspace(member, title, description);
|
||||
}
|
||||
|
||||
public void updateWorkspace(final String title, final String description) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Schema(name = "워크스페이스 request dto", description = "워크스페이스 작성시 필요한 정보")
|
||||
@Schema(name = "워크스페이스 요청 dto", description = "워크스페이스 작성시 필요한 정보")
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.worlabel.domain.workspace.entity.dto;
|
||||
|
||||
import com.worlabel.domain.workspace.entity.Workspace;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(name = "워크스페이스 응답 dto", description = "워크스페이스 응답 DTO")
|
||||
@Getter
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class WorkspaceResponse {
|
||||
|
||||
@Schema(description = "워크스페이스 ID", example = "1")
|
||||
private Integer id;
|
||||
|
||||
@Schema(description = "회원 ID", example = "member123")
|
||||
private String memberId;
|
||||
|
||||
@Schema(description = "제목", example = "workspace1")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "내용", example = "갤럭시 s24 불량 검증")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "생성일시", example = "2024-07-25 17:51:02")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Schema(description = "수정일시", example = "2024-07-28 17:51:02")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public static WorkspaceResponse from(final Workspace workspace) {
|
||||
return new WorkspaceResponse(
|
||||
workspace.getId(),
|
||||
workspace.getMember().getNickname(),
|
||||
workspace.getTitle(),
|
||||
workspace.getDescription(),
|
||||
workspace.getCreatedAt(),
|
||||
workspace.getUpdatedAt());
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.worlabel.domain.workspace.entity.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(name = "워크스페이스 목록 응답 dto", description = "워크스페이스 목록 응답 DTO")
|
||||
@Getter
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class WorkspaceResponses {
|
||||
|
||||
@Schema(description = "워크스페이스 목록", example = "")
|
||||
private List<WorkspaceResponse> workspaceResponses;
|
||||
|
||||
public static WorkspaceResponses from(final List<WorkspaceResponse> workspaceResponses) {
|
||||
return new WorkspaceResponses(workspaceResponses);
|
||||
}
|
||||
}
|
@ -2,8 +2,22 @@ package com.worlabel.domain.workspace.repository;
|
||||
|
||||
import com.worlabel.domain.workspace.entity.Workspace;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface WorkspaceRepository extends JpaRepository<Workspace, Integer> {
|
||||
}
|
||||
|
||||
Optional<Workspace> findByMemberIdAndId(Integer memberId, Integer workspaceId);
|
||||
|
||||
@Query(value = "SELECT * FROM workspace w WHERE w.member_id = :memberId " +
|
||||
"AND (:lastWorkspaceId IS NULL OR w.workspace_id < :lastWorkspaceId) " +
|
||||
"ORDER BY w.workspace_id DESC " +
|
||||
"LIMIT :pageSize",
|
||||
nativeQuery = true)
|
||||
List<Workspace> findWorkspacesByMemberIdAndLastWorkspaceId(@Param("memberId") Integer memberId, @Param("lastWorkspaceId") Integer lastWorkspaceId, @Param("pageSize") Integer pageSize);
|
||||
}
|
||||
|
@ -1,59 +1,85 @@
|
||||
package com.worlabel.domain.workspace.service;
|
||||
|
||||
import com.worlabel.domain.member.entity.Member;
|
||||
import com.worlabel.domain.member.repository.MemberRepository;
|
||||
import com.worlabel.domain.workspace.entity.Workspace;
|
||||
import com.worlabel.domain.workspace.entity.dto.WorkspaceRequest;
|
||||
import com.worlabel.domain.workspace.entity.dto.WorkspaceResponse;
|
||||
import com.worlabel.domain.workspace.repository.WorkspaceRepository;
|
||||
import com.worlabel.global.annotation.CurrentUser;
|
||||
import com.worlabel.global.exception.CustomException;
|
||||
import com.worlabel.global.exception.ErrorCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
public class WorkspaceService {
|
||||
|
||||
private final WorkspaceRepository workspaceRepository;
|
||||
private final MemberRepository memberRepository;
|
||||
|
||||
/**
|
||||
* 새로운 워크스페이스 생성
|
||||
*/
|
||||
public Workspace createWorkspace(Integer memberId, WorkspaceRequest workspace) {
|
||||
public WorkspaceResponse createWorkspace(final Integer memberId, final WorkspaceRequest workspaceRequest) {
|
||||
Member member = getMember(memberId);
|
||||
Workspace workspace = Workspace.of(member, workspaceRequest.getTitle(), workspaceRequest.getContent());
|
||||
workspaceRepository.save(workspace);
|
||||
|
||||
// return workspaceRepository.save();
|
||||
return WorkspaceResponse.from(workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 워크스페이스 조회
|
||||
*/
|
||||
public Workspace getWorkspaceById(Integer id) {
|
||||
return workspaceRepository.findById(id)
|
||||
.orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND, "Workspace not found"));
|
||||
public WorkspaceResponse getWorkspaceById(final Integer memberId, final Integer workspaceId) {
|
||||
Workspace workspace = getWorkspace(memberId, workspaceId);
|
||||
return WorkspaceResponse.from(workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* 전체 워크스페이스 조회
|
||||
*/
|
||||
public List<Workspace> getAllWorkspaces() {
|
||||
return workspaceRepository.findAll();
|
||||
public List<WorkspaceResponse> getAllWorkspaces(final Integer memberId, final Integer lastWorkspaceId, final Integer pageSize) {
|
||||
return workspaceRepository.findWorkspacesByMemberIdAndLastWorkspaceId(memberId, lastWorkspaceId, pageSize).stream()
|
||||
.map(WorkspaceResponse::from)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 워크스페이스 수정
|
||||
*/
|
||||
public Workspace updateWorkspace(Integer id, Workspace updatedWorkspace) {
|
||||
Workspace workspace = getWorkspaceById(id);
|
||||
// workspace.setTitle(updatedWorkspace.getTitle());
|
||||
// workspace.setDescription(updatedWorkspace.getDescription());
|
||||
return workspaceRepository.save(workspace);
|
||||
public WorkspaceResponse updateWorkspace(final Integer memberId, final Integer workspaceId, final WorkspaceRequest updatedWorkspace) {
|
||||
Workspace workspace = getWorkspace(memberId, workspaceId);
|
||||
workspace.updateWorkspace(updatedWorkspace.getTitle(), updatedWorkspace.getContent());
|
||||
|
||||
return WorkspaceResponse.from(workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* 워크스페이스 삭제
|
||||
*/
|
||||
public void deleteWorkspace(Integer id) {
|
||||
Workspace workspace = getWorkspaceById(id);
|
||||
public void deleteWorkspace(final Integer memberId, final Integer workspaceId) {
|
||||
Workspace workspace = getWorkspace(memberId, workspaceId);
|
||||
workspaceRepository.delete(workspace);
|
||||
}
|
||||
|
||||
private Member getMember(final Integer memberId) {
|
||||
return memberRepository.findById(memberId)
|
||||
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
|
||||
}
|
||||
|
||||
/**
|
||||
* 작성자와 같은 워크스페이스만 가져옴
|
||||
* 기존 방식은 DB 2번 접근 -> 쿼리로 한번에 접근하도록 바꿈
|
||||
*/
|
||||
private Workspace getWorkspace(final Integer memberId, final Integer workspaceId) {
|
||||
return workspaceRepository.findByMemberIdAndId(memberId, workspaceId)
|
||||
.orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND, "Workspace not found"));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user