From b83a15867e1e4127832cbd9e370e6923b6f1dfa3 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 24 Dec 2024 16:48:47 +0900 Subject: [PATCH 001/181] =?UTF-8?q?Fix=20:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit card와 cardList의 order를 sequence로 변경 --- .../java/com/example/trello/card/Card.java | 18 ++++++++++++++++-- .../com/example/trello/cardlist/CardList.java | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index 0a9acde..af88321 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -3,13 +3,18 @@ import com.example.trello.cardlist.CardList; import com.example.trello.comment.Comment; import jakarta.persistence.*; +import jakarta.validation.constraints.Pattern; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; import java.time.LocalDateTime; import java.util.List; @Entity @Getter +@RequiredArgsConstructor public class Card { @Id @@ -22,16 +27,18 @@ public class Card { @Column(name = "description") private String description; - @Column(name = "order") - private Integer order; + @Column(name = "sequence") + private Integer sequence; @Column(name = "image") private String image; @Column(name = "start_at") + @CreatedDate private LocalDateTime startAt; @Column(name = "end_at") + @LastModifiedDate private LocalDateTime endAt; @ManyToOne(fetch = FetchType.LAZY) @@ -40,5 +47,12 @@ public class Card { @OneToMany(mappedBy = "card",cascade = CascadeType.ALL,orphanRemoval = true) private List comments; + public Card(String title, String description, CardList cardList) { + this.title = title; + this.description = description; + this.cardList = cardList; + } + + } diff --git a/src/main/java/com/example/trello/cardlist/CardList.java b/src/main/java/com/example/trello/cardlist/CardList.java index 452bcad..1e49dec 100644 --- a/src/main/java/com/example/trello/cardlist/CardList.java +++ b/src/main/java/com/example/trello/cardlist/CardList.java @@ -18,8 +18,8 @@ public class CardList { @Column(name = "title") private String title; - @Column(name = "order") - private Integer order; + @Column(name = "sequence") + private Integer sequence; @ManyToOne(fetch = FetchType.LAZY) private Board board; From 9848556499fd5fd7fc91f7518d1d66fc0f75c8b6 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Tue, 24 Dec 2024 18:47:30 +0900 Subject: [PATCH 002/181] =?UTF-8?q?fix=20:=20WorkspaceUser=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 역할 관리를 위한 Role 컬럼 추가 --- .../trello/workspace_user/WorkspaceUser.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java index 4aa39ef..2cd7a40 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java @@ -1,7 +1,9 @@ package com.example.trello.workspace_user; import com.example.trello.user.User; +import com.example.trello.workspace.Workspace; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; @Entity @@ -12,11 +14,22 @@ public class WorkspaceUser { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(name = "role") + private WorkspaceUserRole role; + @ManyToOne(fetch = FetchType.LAZY) private User user; @ManyToOne(fetch = FetchType.LAZY) - private WorkspaceUser workspaceUser; + private Workspace workspace; + public WorkspaceUser() { + } + @Builder + public WorkspaceUser(WorkspaceUserRole role, User user, Workspace workspace) { + this.role = role; + this.user = user; + this.workspace = workspace; + } } From fa10d6f454b2ad3dc887e6f73e1252cd5d83e7f8 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Tue, 24 Dec 2024 18:59:42 +0900 Subject: [PATCH 003/181] =?UTF-8?q?feat=20:=20Workspace,=20WorkspaceUser?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 각각의 Controller, Service 추가 --- .../example/trello/user/UserRepository.java | 8 ++++++- .../trello/workspace/WorkspaceController.java | 9 ++++++++ .../trello/workspace/WorkspaceService.java | 9 ++++++++ .../WorkspaceUserController.java | 17 ++++++++++++++ .../workspace_user/WorkspaceUserRole.java | 7 ++++++ .../workspace_user/WorkspaceUserService.java | 22 +++++++++++++++++++ 6 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/trello/workspace/WorkspaceController.java create mode 100644 src/main/java/com/example/trello/workspace/WorkspaceService.java create mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java create mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java create mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java diff --git a/src/main/java/com/example/trello/user/UserRepository.java b/src/main/java/com/example/trello/user/UserRepository.java index b82e59a..5a65635 100644 --- a/src/main/java/com/example/trello/user/UserRepository.java +++ b/src/main/java/com/example/trello/user/UserRepository.java @@ -4,10 +4,16 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface UserRepository extends JpaRepository { + Optional findByEmail(String email); default User findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + return findById(id).orElseThrow(() -> new RuntimeException()); + } + default User findByEmailOrElseThrow(String email){ + return findByEmail(email).orElseThrow(() -> new RuntimeException()); } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java new file mode 100644 index 0000000..73f9c6f --- /dev/null +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -0,0 +1,9 @@ +package com.example.trello.workspace; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class WorkspaceController { +} diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java new file mode 100644 index 0000000..47eb43e --- /dev/null +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -0,0 +1,9 @@ +package com.example.trello.workspace; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class WorkspaceService { +} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java new file mode 100644 index 0000000..779e87b --- /dev/null +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java @@ -0,0 +1,17 @@ +package com.example.trello.workspace_user; + +import com.example.trello.workspace_user.dto.WorkspaceUserRequestDto; +import com.example.trello.workspace_user.dto.WorkspaceUserResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/workspaces/{workspace_id}") +public class WorkspaceUserController { + + private final WorkspaceUserService workspaceUserService; + +} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java new file mode 100644 index 0000000..3a0d7ae --- /dev/null +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java @@ -0,0 +1,7 @@ +package com.example.trello.workspace_user; + +public enum WorkspaceUserRole { + WORKSPACE, + BOARD, + READ_ONLY +} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java new file mode 100644 index 0000000..0bb31c9 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java @@ -0,0 +1,22 @@ +package com.example.trello.workspace_user; + +import com.example.trello.user.User; +import com.example.trello.user.UserRepository; +import com.example.trello.workspace.WorkSpaceRepository; +import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_user.dto.WorkspaceUserResponseDto; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import static com.example.trello.workspace_user.WorkspaceUserRole.READ_ONLY; + +@Service +@RequiredArgsConstructor +public class WorkspaceUserService { + + private final WorkspaceUserRepository workspaceUserRepository; + private final WorkSpaceRepository workSpaceRepository; + private final UserRepository userRepository; + +} From e6f79cc47454f7850b992b53d0959bc174af4125 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Tue, 24 Dec 2024 19:03:44 +0900 Subject: [PATCH 004/181] =?UTF-8?q?feat=20:=20Workspace=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=EC=B4=88=EB=8C=80=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WorkspaceUserController.java | 8 +++++++ .../workspace_user/WorkspaceUserService.java | 15 +++++++++++++ .../dto/UpdateWorkspaceUserRoleDto.java | 17 ++++++++++++++ .../dto/WorkspaceUserRequestDto.java | 12 ++++++++++ .../dto/WorkspaceUserResponseDto.java | 22 +++++++++++++++++++ 5 files changed, 74 insertions(+) create mode 100644 src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java create mode 100644 src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java create mode 100644 src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java index 779e87b..a2c1435 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java @@ -14,4 +14,12 @@ public class WorkspaceUserController { private final WorkspaceUserService workspaceUserService; + @PostMapping("/member-invite") + public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceUserRequestDto dto) { + WorkspaceUserResponseDto workspaceUserResponseDto = workspaceUserService.inviteWorkspaceUser(workspaceId, dto.getEmail()); + return new ResponseEntity<>(workspaceUserResponseDto, HttpStatus.CREATED); + } + +// @PatchMapping("/member-role") +// public ResponseEntity<> } diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java index 0bb31c9..3d5743a 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java @@ -19,4 +19,19 @@ public class WorkspaceUserService { private final WorkSpaceRepository workSpaceRepository; private final UserRepository userRepository; + @Transactional + public WorkspaceUserResponseDto inviteWorkspaceUser(Long workspaceId, String email) { + User findUser = userRepository.findByEmailOrElseThrow(email); + Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + + WorkspaceUser workspaceUser = WorkspaceUser.builder() + .user(findUser) + .workspace(findWorkspace) + .role(READ_ONLY) + .build(); + + workspaceUserRepository.save(workspaceUser); + + return WorkspaceUserResponseDto.toDto(workspaceUser); + } } diff --git a/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java b/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java new file mode 100644 index 0000000..1fdb26c --- /dev/null +++ b/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java @@ -0,0 +1,17 @@ +package com.example.trello.workspace_user.dto; + +import com.example.trello.workspace_user.WorkspaceUserRole; +import lombok.Getter; + +@Getter +public class UpdateWorkspaceUserRoleDto { + private Long userId; + private Long workspaceId; + private WorkspaceUserRole role; + + public UpdateWorkspaceUserRoleDto(Long userId, Long workspaceId, WorkspaceUserRole role) { + this.userId = userId; + this.workspaceId = workspaceId; + this.role = role; + } +} diff --git a/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java b/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java new file mode 100644 index 0000000..4e68df3 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java @@ -0,0 +1,12 @@ +package com.example.trello.workspace_user.dto; + +import lombok.Getter; + +@Getter +public class WorkspaceUserRequestDto { + private String email; + + public WorkspaceUserRequestDto(String email) { + this.email = email; + } +} diff --git a/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java b/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java new file mode 100644 index 0000000..6bf05f7 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java @@ -0,0 +1,22 @@ +package com.example.trello.workspace_user.dto; + +import com.example.trello.workspace_user.WorkspaceUser; +import com.example.trello.workspace_user.WorkspaceUserRole; +import lombok.Getter; + +@Getter +public class WorkspaceUserResponseDto { + private Long userId; + private Long workspaceId; + private WorkspaceUserRole role; + + public WorkspaceUserResponseDto(Long workspaceId, Long userId, WorkspaceUserRole role) { + this.workspaceId = workspaceId; + this.userId = userId; + this.role = role; + } + + public static WorkspaceUserResponseDto toDto(WorkspaceUser workspaceUser) { + return new WorkspaceUserResponseDto(workspaceUser.getUser().getId(), workspaceUser.getWorkspace().getId(), workspaceUser.getRole()); + } +} From 52da70d4a1f8c02299b7e6bbb98ab181b7cd8fcd Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Tue, 24 Dec 2024 19:04:15 +0900 Subject: [PATCH 005/181] =?UTF-8?q?feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20CR(=EB=8B=A8=EA=B1=B4=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C)UD=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/cardlist/CardList.java | 20 +++++++++ .../trello/cardlist/CardListController.java | 44 +++++++++++++++++++ .../trello/cardlist/CardListRepository.java | 4 +- .../trello/cardlist/CardListService.java | 44 +++++++++++++++++++ .../cardlist/dto/CardListRequestDto.java | 13 ++++++ .../dto/CreateCardListRequestDto.java | 24 ++++++++++ .../dto/CreateCardListResponseDto.java | 13 ++++++ 7 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/trello/cardlist/CardListController.java create mode 100644 src/main/java/com/example/trello/cardlist/CardListService.java create mode 100644 src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java create mode 100644 src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java create mode 100644 src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java diff --git a/src/main/java/com/example/trello/cardlist/CardList.java b/src/main/java/com/example/trello/cardlist/CardList.java index 1e49dec..12c9914 100644 --- a/src/main/java/com/example/trello/cardlist/CardList.java +++ b/src/main/java/com/example/trello/cardlist/CardList.java @@ -2,13 +2,21 @@ import com.example.trello.board.Board; import com.example.trello.card.Card; +import com.example.trello.cardlist.dto.CardListRequestDto; +import com.example.trello.cardlist.dto.CreateCardListResponseDto; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import java.util.List; @Getter @Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor public class CardList { @Id @@ -26,4 +34,16 @@ public class CardList { @OneToMany(mappedBy = "cardList", cascade = CascadeType.ALL, orphanRemoval = true) private List cards; + + public static CreateCardListResponseDto toDto(CardList cardList) { + return CreateCardListResponseDto.builder() + .id(cardList.getId()) + .sequence(cardList.sequence) + .build(); + } + + public void update(CardListRequestDto requestDto) { + this.title = requestDto.getTitle(); + this.sequence = requestDto.getSequence(); + } } diff --git a/src/main/java/com/example/trello/cardlist/CardListController.java b/src/main/java/com/example/trello/cardlist/CardListController.java new file mode 100644 index 0000000..2aa8b41 --- /dev/null +++ b/src/main/java/com/example/trello/cardlist/CardListController.java @@ -0,0 +1,44 @@ +package com.example.trello.cardlist; + +import com.example.trello.cardlist.dto.CardListRequestDto; +import com.example.trello.cardlist.dto.CreateCardListRequestDto; +import com.example.trello.cardlist.dto.CreateCardListResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/lists") +public class CardListController { + + private final CardListService cardListService; + + @PostMapping + public ResponseEntity createCardList(@RequestBody CreateCardListRequestDto requestDto) { + CreateCardListResponseDto createCardListResponseDto = cardListService.create(requestDto); + return new ResponseEntity<>(createCardListResponseDto, HttpStatus.CREATED); + } + + @GetMapping("/{id}") + public ResponseEntity findCardList(@PathVariable Long id) { + CreateCardListResponseDto cardListResponseDto = cardListService.findCardList(id); + return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); + } + + @PatchMapping("/{id}") + public ResponseEntity updateCardList(@PathVariable Long id, @RequestBody CardListRequestDto requestDto) { + CreateCardListResponseDto createCardListResponseDto = cardListService.update(id, requestDto); + return new ResponseEntity<>(createCardListResponseDto, HttpStatus.OK); + + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteCardList(@PathVariable Long id) { + cardListService.delete(id); + return new ResponseEntity<>(HttpStatus.OK); + } + + +} diff --git a/src/main/java/com/example/trello/cardlist/CardListRepository.java b/src/main/java/com/example/trello/cardlist/CardListRepository.java index 79df0c9..2dc56d5 100644 --- a/src/main/java/com/example/trello/cardlist/CardListRepository.java +++ b/src/main/java/com/example/trello/cardlist/CardListRepository.java @@ -6,8 +6,8 @@ @Repository public interface CardListRepository extends JpaRepository { - default CardList findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + default CardList findByIdOrElseThrow(Long id) { + return findById(id).orElseThrow(() -> new RuntimeException()); } } diff --git a/src/main/java/com/example/trello/cardlist/CardListService.java b/src/main/java/com/example/trello/cardlist/CardListService.java new file mode 100644 index 0000000..a540a01 --- /dev/null +++ b/src/main/java/com/example/trello/cardlist/CardListService.java @@ -0,0 +1,44 @@ +package com.example.trello.cardlist; + +import com.example.trello.board.Board; +import com.example.trello.board.BoardRepository; +import com.example.trello.cardlist.dto.CardListRequestDto; +import com.example.trello.cardlist.dto.CreateCardListRequestDto; +import com.example.trello.cardlist.dto.CreateCardListResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CardListService { + + private final CardListRepository cardListRepository; + private final BoardRepository boardRepository; + + public CreateCardListResponseDto create(CreateCardListRequestDto requestDto) { + Board board = boardRepository.findByIdOrElseThrow(requestDto.getBoardId()); + CardList cardList = requestDto.toEntity(requestDto, board); + CardList savedCardList = cardListRepository.save(cardList); + return CardList.toDto(savedCardList); + } + + + public CreateCardListResponseDto findCardList(Long id) { + CardList cardList = cardListRepository.findByIdOrElseThrow(id); + return CardList.toDto(cardList); + } + + @Transactional + public CreateCardListResponseDto update(Long id, CardListRequestDto requestDto) { + CardList cardList = cardListRepository.findByIdOrElseThrow(id); + cardList.update(requestDto); + return CardList.toDto(cardList); + } + + @Transactional + public void delete(Long id) { + CardList cardList = cardListRepository.findByIdOrElseThrow(id); + cardListRepository.delete(cardList); + } +} diff --git a/src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java b/src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java new file mode 100644 index 0000000..f83c789 --- /dev/null +++ b/src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java @@ -0,0 +1,13 @@ +package com.example.trello.cardlist.dto; + +import lombok.Getter; + +@Getter +public class CardListRequestDto { + + private String title; + + private Integer sequence; + + +} diff --git a/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java b/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java new file mode 100644 index 0000000..36e00b0 --- /dev/null +++ b/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java @@ -0,0 +1,24 @@ +package com.example.trello.cardlist.dto; + +import com.example.trello.board.Board; +import com.example.trello.cardlist.CardList; +import lombok.Getter; + +@Getter +public class CreateCardListRequestDto { + + private String title; + + private Integer sequence; + + private Long boardId; + + public CardList toEntity(CreateCardListRequestDto requestDto, Board board) { + return CardList.builder() + .title(requestDto.title) + .sequence(requestDto.sequence) + .board(board) + .build(); + } + +} diff --git a/src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java b/src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java new file mode 100644 index 0000000..e192a88 --- /dev/null +++ b/src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java @@ -0,0 +1,13 @@ +package com.example.trello.cardlist.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class CreateCardListResponseDto { + + private Long id; + + private Integer sequence; +} From 30390016a4ce133ca14a00c5056104e0d400dad8 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Tue, 24 Dec 2024 19:50:39 +0900 Subject: [PATCH 006/181] =?UTF-8?q?feat=20:=20Workspace=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=EC=97=AD=ED=95=A0=20=EB=B3=80=EA=B2=BD=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/workspace_user/WorkspaceUser.java | 5 +++++ .../trello/workspace_user/WorkspaceUserController.java | 9 ++++++--- .../trello/workspace_user/WorkspaceUserRepository.java | 5 ++++- .../trello/workspace_user/WorkspaceUserService.java | 9 +++++++++ .../workspace_user/dto/UpdateWorkspaceUserRoleDto.java | 8 +++----- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java index 2cd7a40..941a6e8 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java @@ -15,6 +15,7 @@ public class WorkspaceUser { private Long id; @Column(name = "role") + @Enumerated(EnumType.STRING) private WorkspaceUserRole role; @ManyToOne(fetch = FetchType.LAZY) @@ -32,4 +33,8 @@ public WorkspaceUser(WorkspaceUserRole role, User user, Workspace workspace) { this.user = user; this.workspace = workspace; } + + public void updateRole(WorkspaceUserRole role) { + this.role = role; + } } diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java index a2c1435..86b61c9 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java @@ -1,5 +1,6 @@ package com.example.trello.workspace_user; +import com.example.trello.workspace_user.dto.UpdateWorkspaceUserRoleDto; import com.example.trello.workspace_user.dto.WorkspaceUserRequestDto; import com.example.trello.workspace_user.dto.WorkspaceUserResponseDto; import lombok.RequiredArgsConstructor; @@ -9,7 +10,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/workspaces/{workspace_id}") +@RequestMapping("/workspaces/{workspaceId}") public class WorkspaceUserController { private final WorkspaceUserService workspaceUserService; @@ -20,6 +21,8 @@ public ResponseEntity inviteWorkspaceUser(@PathVariabl return new ResponseEntity<>(workspaceUserResponseDto, HttpStatus.CREATED); } -// @PatchMapping("/member-role") -// public ResponseEntity<> + @PatchMapping("/member-role") + public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceUserRoleDto dto) { + return workspaceUserService.updateWorkspaceUserRole(workspaceId, dto.getWorkspaceUserId(), dto.getRole()); + } } diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java index 89adcd2..08e4908 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java @@ -4,10 +4,13 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface WorkspaceUserRepository extends JpaRepository { default WorkspaceUser findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + return findById(id).orElseThrow(() -> new RuntimeException()); } + } diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java index 3d5743a..fa41983 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java +++ b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java @@ -34,4 +34,13 @@ public WorkspaceUserResponseDto inviteWorkspaceUser(Long workspaceId, String ema return WorkspaceUserResponseDto.toDto(workspaceUser); } + + @Transactional + public String updateWorkspaceUserRole(Long workspaceId, Long workspaceUserId , WorkspaceUserRole role) { + WorkspaceUser findWorkspaceUser = workspaceUserRepository.findByIdOrElseThrow(workspaceUserId); + + findWorkspaceUser.updateRole(role); + + return "권한이 " + role + "로 변경되었습니다."; + } } diff --git a/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java b/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java index 1fdb26c..817669f 100644 --- a/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java +++ b/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java @@ -5,13 +5,11 @@ @Getter public class UpdateWorkspaceUserRoleDto { - private Long userId; - private Long workspaceId; + private Long workspaceUserId; private WorkspaceUserRole role; - public UpdateWorkspaceUserRoleDto(Long userId, Long workspaceId, WorkspaceUserRole role) { - this.userId = userId; - this.workspaceId = workspaceId; + public UpdateWorkspaceUserRoleDto(Long workspaceUserId, WorkspaceUserRole role) { + this.workspaceUserId = workspaceUserId; this.role = role; } } From 866ab71ac7ae8e7a183df49c13721819873f13c3 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Tue, 24 Dec 2024 20:37:28 +0900 Subject: [PATCH 007/181] =?UTF-8?q?refactor=20:=20WorkspaceUser=EC=97=90?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=EB=90=9C=20=EC=A0=84=EB=B6=80=20Workspace?= =?UTF-8?q?Member=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WorkspaceMember.java} | 12 ++--- .../WorkspaceMemberController.java | 28 +++++++++++ .../WorkspaceMemberRepository.java | 13 ++++++ .../workspace_member/WorkspaceMemberRole.java | 7 +++ .../WorkspaceMemberService.java | 46 +++++++++++++++++++ .../dto/UpdateWorkspaceMemberRoleDto.java | 15 ++++++ .../dto/WorkspaceMemberRequestDto.java | 12 +++++ .../dto/WorkspaceMemberResponseDto.java | 22 +++++++++ .../WorkspaceUserController.java | 28 ----------- .../WorkspaceUserRepository.java | 16 ------- .../workspace_user/WorkspaceUserRole.java | 7 --- .../workspace_user/WorkspaceUserService.java | 46 ------------------- .../dto/UpdateWorkspaceUserRoleDto.java | 15 ------ .../dto/WorkspaceUserRequestDto.java | 12 ----- .../dto/WorkspaceUserResponseDto.java | 22 --------- 15 files changed, 149 insertions(+), 152 deletions(-) rename src/main/java/com/example/trello/{workspace_user/WorkspaceUser.java => workspace_member/WorkspaceMember.java} (68%) create mode 100644 src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java create mode 100644 src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java create mode 100644 src/main/java/com/example/trello/workspace_member/WorkspaceMemberRole.java create mode 100644 src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java create mode 100644 src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java create mode 100644 src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java create mode 100644 src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java delete mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java delete mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java delete mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java delete mode 100644 src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java delete mode 100644 src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java delete mode 100644 src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java delete mode 100644 src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMember.java similarity index 68% rename from src/main/java/com/example/trello/workspace_user/WorkspaceUser.java rename to src/main/java/com/example/trello/workspace_member/WorkspaceMember.java index 941a6e8..c699941 100644 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUser.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMember.java @@ -1,4 +1,4 @@ -package com.example.trello.workspace_user; +package com.example.trello.workspace_member; import com.example.trello.user.User; import com.example.trello.workspace.Workspace; @@ -8,7 +8,7 @@ @Entity @Getter -public class WorkspaceUser { +public class WorkspaceMember { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -16,7 +16,7 @@ public class WorkspaceUser { @Column(name = "role") @Enumerated(EnumType.STRING) - private WorkspaceUserRole role; + private WorkspaceMemberRole role; @ManyToOne(fetch = FetchType.LAZY) private User user; @@ -24,17 +24,17 @@ public class WorkspaceUser { @ManyToOne(fetch = FetchType.LAZY) private Workspace workspace; - public WorkspaceUser() { + public WorkspaceMember() { } @Builder - public WorkspaceUser(WorkspaceUserRole role, User user, Workspace workspace) { + public WorkspaceMember(WorkspaceMemberRole role, User user, Workspace workspace) { this.role = role; this.user = user; this.workspace = workspace; } - public void updateRole(WorkspaceUserRole role) { + public void updateRole(WorkspaceMemberRole role) { this.role = role; } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java new file mode 100644 index 0000000..b2bbc90 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java @@ -0,0 +1,28 @@ +package com.example.trello.workspace_member; + +import com.example.trello.workspace_member.dto.UpdateWorkspaceMemberRoleDto; +import com.example.trello.workspace_member.dto.WorkspaceMemberRequestDto; +import com.example.trello.workspace_member.dto.WorkspaceMemberResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/workspaces/{workspaceId}") +public class WorkspaceMemberController { + + private final WorkspaceMemberService workspaceMemberService; + + @PostMapping("/member-invite") + public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto) { + WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto.getEmail()); + return new ResponseEntity<>(workspaceMemberResponseDto, HttpStatus.CREATED); + } + + @PatchMapping("/member-role") + public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto) { + return workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto.getWorkspaceMemberId(), dto.getRole()); + } +} diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java new file mode 100644 index 0000000..ec531e8 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -0,0 +1,13 @@ +package com.example.trello.workspace_member; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface WorkspaceMemberRepository extends JpaRepository { + + default WorkspaceMember findByIdOrElseThrow(Long id){ + return findById(id).orElseThrow(() -> new RuntimeException()); + } + +} diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRole.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRole.java new file mode 100644 index 0000000..f9722cc --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRole.java @@ -0,0 +1,7 @@ +package com.example.trello.workspace_member; + +public enum WorkspaceMemberRole { + WORKSPACE, + BOARD, + READ_ONLY +} diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java new file mode 100644 index 0000000..0ebc534 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -0,0 +1,46 @@ +package com.example.trello.workspace_member; + +import com.example.trello.user.User; +import com.example.trello.user.UserRepository; +import com.example.trello.workspace.WorkSpaceRepository; +import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_member.dto.WorkspaceMemberResponseDto; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; + +@Service +@RequiredArgsConstructor +public class WorkspaceMemberService { + + private final WorkspaceMemberRepository workspaceMemberRepository; + private final WorkSpaceRepository workSpaceRepository; + private final UserRepository userRepository; + + @Transactional + public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String email) { + User findUser = userRepository.findByEmailOrElseThrow(email); + Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + + WorkspaceMember workspaceMember = com.example.trello.workspace_member.WorkspaceMember.builder() + .user(findUser) + .workspace(findWorkspace) + .role(READ_ONLY) + .build(); + + workspaceMemberRepository.save(workspaceMember); + + return WorkspaceMemberResponseDto.toDto(workspaceMember); + } + + @Transactional + public String updateWorkspaceMemberRole(Long workspaceId, Long workspaceMemberId , WorkspaceMemberRole role) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(workspaceMemberId); + + findWorkspaceMember.updateRole(role); + + return "권한이 " + role + "로 변경되었습니다."; + } +} diff --git a/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java b/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java new file mode 100644 index 0000000..0eda279 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java @@ -0,0 +1,15 @@ +package com.example.trello.workspace_member.dto; + +import com.example.trello.workspace_member.WorkspaceMemberRole; +import lombok.Getter; + +@Getter +public class UpdateWorkspaceMemberRoleDto { + private Long workspaceMemberId; + private WorkspaceMemberRole role; + + public UpdateWorkspaceMemberRoleDto(Long workspaceMemberId, WorkspaceMemberRole role) { + this.workspaceMemberId = workspaceMemberId; + this.role = role; + } +} diff --git a/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java new file mode 100644 index 0000000..8acaac4 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java @@ -0,0 +1,12 @@ +package com.example.trello.workspace_member.dto; + +import lombok.Getter; + +@Getter +public class WorkspaceMemberRequestDto { + private String email; + + public WorkspaceMemberRequestDto(String email) { + this.email = email; + } +} diff --git a/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java new file mode 100644 index 0000000..90149a7 --- /dev/null +++ b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java @@ -0,0 +1,22 @@ +package com.example.trello.workspace_member.dto; + +import com.example.trello.workspace_member.WorkspaceMember; +import com.example.trello.workspace_member.WorkspaceMemberRole; +import lombok.Getter; + +@Getter +public class WorkspaceMemberResponseDto { + private Long userId; + private Long workspaceId; + private WorkspaceMemberRole role; + + public WorkspaceMemberResponseDto(Long workspaceId, Long userId, WorkspaceMemberRole role) { + this.workspaceId = workspaceId; + this.userId = userId; + this.role = role; + } + + public static WorkspaceMemberResponseDto toDto(WorkspaceMember workspaceMember) { + return new WorkspaceMemberResponseDto(workspaceMember.getUser().getId(), workspaceMember.getWorkspace().getId(), workspaceMember.getRole()); + } +} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java deleted file mode 100644 index 86b61c9..0000000 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserController.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.trello.workspace_user; - -import com.example.trello.workspace_user.dto.UpdateWorkspaceUserRoleDto; -import com.example.trello.workspace_user.dto.WorkspaceUserRequestDto; -import com.example.trello.workspace_user.dto.WorkspaceUserResponseDto; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/workspaces/{workspaceId}") -public class WorkspaceUserController { - - private final WorkspaceUserService workspaceUserService; - - @PostMapping("/member-invite") - public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceUserRequestDto dto) { - WorkspaceUserResponseDto workspaceUserResponseDto = workspaceUserService.inviteWorkspaceUser(workspaceId, dto.getEmail()); - return new ResponseEntity<>(workspaceUserResponseDto, HttpStatus.CREATED); - } - - @PatchMapping("/member-role") - public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceUserRoleDto dto) { - return workspaceUserService.updateWorkspaceUserRole(workspaceId, dto.getWorkspaceUserId(), dto.getRole()); - } -} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java deleted file mode 100644 index 08e4908..0000000 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.trello.workspace_user; - -import com.example.trello.workspace.Workspace; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -@Repository -public interface WorkspaceUserRepository extends JpaRepository { - - default WorkspaceUser findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(() -> new RuntimeException()); - } - -} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java deleted file mode 100644 index 3a0d7ae..0000000 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserRole.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.trello.workspace_user; - -public enum WorkspaceUserRole { - WORKSPACE, - BOARD, - READ_ONLY -} diff --git a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java b/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java deleted file mode 100644 index fa41983..0000000 --- a/src/main/java/com/example/trello/workspace_user/WorkspaceUserService.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.example.trello.workspace_user; - -import com.example.trello.user.User; -import com.example.trello.user.UserRepository; -import com.example.trello.workspace.WorkSpaceRepository; -import com.example.trello.workspace.Workspace; -import com.example.trello.workspace_user.dto.WorkspaceUserResponseDto; -import jakarta.transaction.Transactional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import static com.example.trello.workspace_user.WorkspaceUserRole.READ_ONLY; - -@Service -@RequiredArgsConstructor -public class WorkspaceUserService { - - private final WorkspaceUserRepository workspaceUserRepository; - private final WorkSpaceRepository workSpaceRepository; - private final UserRepository userRepository; - - @Transactional - public WorkspaceUserResponseDto inviteWorkspaceUser(Long workspaceId, String email) { - User findUser = userRepository.findByEmailOrElseThrow(email); - Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); - - WorkspaceUser workspaceUser = WorkspaceUser.builder() - .user(findUser) - .workspace(findWorkspace) - .role(READ_ONLY) - .build(); - - workspaceUserRepository.save(workspaceUser); - - return WorkspaceUserResponseDto.toDto(workspaceUser); - } - - @Transactional - public String updateWorkspaceUserRole(Long workspaceId, Long workspaceUserId , WorkspaceUserRole role) { - WorkspaceUser findWorkspaceUser = workspaceUserRepository.findByIdOrElseThrow(workspaceUserId); - - findWorkspaceUser.updateRole(role); - - return "권한이 " + role + "로 변경되었습니다."; - } -} diff --git a/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java b/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java deleted file mode 100644 index 817669f..0000000 --- a/src/main/java/com/example/trello/workspace_user/dto/UpdateWorkspaceUserRoleDto.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.trello.workspace_user.dto; - -import com.example.trello.workspace_user.WorkspaceUserRole; -import lombok.Getter; - -@Getter -public class UpdateWorkspaceUserRoleDto { - private Long workspaceUserId; - private WorkspaceUserRole role; - - public UpdateWorkspaceUserRoleDto(Long workspaceUserId, WorkspaceUserRole role) { - this.workspaceUserId = workspaceUserId; - this.role = role; - } -} diff --git a/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java b/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java deleted file mode 100644 index 4e68df3..0000000 --- a/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserRequestDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.trello.workspace_user.dto; - -import lombok.Getter; - -@Getter -public class WorkspaceUserRequestDto { - private String email; - - public WorkspaceUserRequestDto(String email) { - this.email = email; - } -} diff --git a/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java b/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java deleted file mode 100644 index 6bf05f7..0000000 --- a/src/main/java/com/example/trello/workspace_user/dto/WorkspaceUserResponseDto.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.example.trello.workspace_user.dto; - -import com.example.trello.workspace_user.WorkspaceUser; -import com.example.trello.workspace_user.WorkspaceUserRole; -import lombok.Getter; - -@Getter -public class WorkspaceUserResponseDto { - private Long userId; - private Long workspaceId; - private WorkspaceUserRole role; - - public WorkspaceUserResponseDto(Long workspaceId, Long userId, WorkspaceUserRole role) { - this.workspaceId = workspaceId; - this.userId = userId; - this.role = role; - } - - public static WorkspaceUserResponseDto toDto(WorkspaceUser workspaceUser) { - return new WorkspaceUserResponseDto(workspaceUser.getUser().getId(), workspaceUser.getWorkspace().getId(), workspaceUser.getRole()); - } -} From 45e7e0a3ca3e5260993070370e56b9bd5ed4226c Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Tue, 24 Dec 2024 23:33:21 +0900 Subject: [PATCH 008/181] =?UTF-8?q?fix=20:=20Update,=20Delete=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [update] 각 1,2,3,4 있을 때 2,3을 변경하면 1,2(이전 값:3),3(이전 값:2),4 로 되도록 수정 [delete] 각 1,2,3,4 있을 때 2를 삭제하면 1,2(이전 값:3),3(이전 값:4 )로 되도록 수정 --- .../com/example/trello/cardlist/CardList.java | 13 ++++++++-- .../trello/cardlist/CardListRepository.java | 11 +++++++++ .../trello/cardlist/CardListService.java | 24 +++++++++++++++++-- .../dto/CreateCardListRequestDto.java | 4 ++-- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/trello/cardlist/CardList.java b/src/main/java/com/example/trello/cardlist/CardList.java index 12c9914..32ad722 100644 --- a/src/main/java/com/example/trello/cardlist/CardList.java +++ b/src/main/java/com/example/trello/cardlist/CardList.java @@ -42,8 +42,17 @@ public static CreateCardListResponseDto toDto(CardList cardList) { .build(); } - public void update(CardListRequestDto requestDto) { + public void update(CardListRequestDto requestDto,Integer sequence ) { this.title = requestDto.getTitle(); - this.sequence = requestDto.getSequence(); + this.sequence = sequence; + + } + + public void sortSequence(Integer sequence) { + this.sequence=sequence-1; + } + + public void updateSequence(Integer sequence) { + this.sequence=sequence; } } diff --git a/src/main/java/com/example/trello/cardlist/CardListRepository.java b/src/main/java/com/example/trello/cardlist/CardListRepository.java index 2dc56d5..4069c25 100644 --- a/src/main/java/com/example/trello/cardlist/CardListRepository.java +++ b/src/main/java/com/example/trello/cardlist/CardListRepository.java @@ -1,13 +1,24 @@ package com.example.trello.cardlist; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface CardListRepository extends JpaRepository { default CardList findByIdOrElseThrow(Long id) { return findById(id).orElseThrow(() -> new RuntimeException()); } + @Query(value = "select MAX(sequence)from card_list ",nativeQuery = true) + Optional findByMax(); + + Optional findBySequence(Integer sequence); + + default CardList findBySequenceOrElseThrow(Integer sequence){ + return findBySequence(sequence).orElseThrow(()->new RuntimeException()); + } } diff --git a/src/main/java/com/example/trello/cardlist/CardListService.java b/src/main/java/com/example/trello/cardlist/CardListService.java index a540a01..fad5bed 100644 --- a/src/main/java/com/example/trello/cardlist/CardListService.java +++ b/src/main/java/com/example/trello/cardlist/CardListService.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + @Service @RequiredArgsConstructor public class CardListService { @@ -16,10 +18,15 @@ public class CardListService { private final CardListRepository cardListRepository; private final BoardRepository boardRepository; + private static Integer MAX_SEQUENCE; + + @Transactional public CreateCardListResponseDto create(CreateCardListRequestDto requestDto) { Board board = boardRepository.findByIdOrElseThrow(requestDto.getBoardId()); - CardList cardList = requestDto.toEntity(requestDto, board); + MAX_SEQUENCE = cardListRepository.findByMax().orElse(0); + CardList cardList = requestDto.toEntity(requestDto, board, ++MAX_SEQUENCE); CardList savedCardList = cardListRepository.save(cardList); + return CardList.toDto(savedCardList); } @@ -32,13 +39,26 @@ public CreateCardListResponseDto findCardList(Long id) { @Transactional public CreateCardListResponseDto update(Long id, CardListRequestDto requestDto) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); - cardList.update(requestDto); + CardList exchangeCardList = cardListRepository.findBySequenceOrElseThrow(requestDto.getSequence()); + Integer temp = cardList.getSequence(); + cardList.update(requestDto, exchangeCardList.getSequence()); + exchangeCardList.updateSequence(temp); + return CardList.toDto(cardList); } @Transactional public void delete(Long id) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); + Integer deleteSequence = cardList.getSequence(); cardListRepository.delete(cardList); + List cardLists = cardListRepository.findAll(); + for (CardList list : cardLists) { + if (list.getSequence() > deleteSequence) { + list.sortSequence(list.getSequence()); + } + } } + + } diff --git a/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java b/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java index 36e00b0..e42e304 100644 --- a/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java +++ b/src/main/java/com/example/trello/cardlist/dto/CreateCardListRequestDto.java @@ -13,10 +13,10 @@ public class CreateCardListRequestDto { private Long boardId; - public CardList toEntity(CreateCardListRequestDto requestDto, Board board) { + public CardList toEntity(CreateCardListRequestDto requestDto, Board board ,Integer sequence) { return CardList.builder() .title(requestDto.title) - .sequence(requestDto.sequence) + .sequence(sequence) .board(board) .build(); } From 784b6b2dde5c446e6a3b852ad9b2284151e47a17 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 10:33:35 +0900 Subject: [PATCH 009/181] =?UTF-8?q?feat=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=83=9D=EC=84=B1=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/workspace/Workspace.java | 10 +++++++ .../trello/workspace/WorkspaceController.java | 17 ++++++++++- .../trello/workspace/WorkspaceService.java | 30 +++++++++++++++++++ .../workspace/dto/WorkspaceRequestDto.java | 14 +++++++++ .../workspace/dto/WorkspaceResponseDto.java | 21 +++++++++++++ .../WorkspaceMemberRepository.java | 8 +++++ .../WorkspaceMemberService.java | 2 +- 7 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java create mode 100644 src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index cf983e9..0a96bb8 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -3,6 +3,7 @@ import com.example.trello.board.Board; import com.example.trello.user.User; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import java.util.List; @@ -25,4 +26,13 @@ public class Workspace { @ManyToOne(fetch = FetchType.LAZY) private User user; + + public Workspace() { + } + + @Builder + public Workspace(String title, String description) { + this.title = title; + this.description = description; + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 73f9c6f..a3727c0 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -1,9 +1,24 @@ package com.example.trello.workspace; +import com.example.trello.workspace.dto.WorkspaceRequestDto; +import com.example.trello.workspace.dto.WorkspaceResponseDto; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @RequiredArgsConstructor +@RequestMapping("/workspaces") public class WorkspaceController { + private final WorkspaceService workspaceService; + + @PostMapping + public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto) { + WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto.getTitle(), dto.getDescription()); + + return new ResponseEntity<>(createdWorkspaceResponseDto, HttpStatus.CREATED); + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 47eb43e..88ac6c7 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -1,9 +1,39 @@ package com.example.trello.workspace; +import com.example.trello.user.User; +import com.example.trello.user.UserRepository; +import com.example.trello.workspace.dto.WorkspaceRequestDto; +import com.example.trello.workspace.dto.WorkspaceResponseDto; + + +import com.example.trello.workspace_member.WorkspaceMember; +import com.example.trello.workspace_member.WorkspaceMemberRepository; +import lombok.Builder; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +import java.util.ArrayList; +import java.util.List; @Service @RequiredArgsConstructor public class WorkspaceService { + private final UserRepository userRepository; + private final WorkSpaceRepository workSpaceRepository; + private final WorkspaceMemberRepository workspaceMemberRepository; + + // todo : Admin 권한을 가진 유저만 생성가능하게 + @Transactional + public WorkspaceResponseDto createWorkspace(String title, String description) { + Workspace workspace = Workspace.builder() + .title(title) + .description(description) + .build(); + + workSpaceRepository.save(workspace); + + return WorkspaceResponseDto.toDto(workspace); + } } diff --git a/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java b/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java new file mode 100644 index 0000000..74c2676 --- /dev/null +++ b/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java @@ -0,0 +1,14 @@ +package com.example.trello.workspace.dto; + +import lombok.Getter; + +@Getter +public class WorkspaceRequestDto { + private String title; + private String description; + + public WorkspaceRequestDto(String title, String description) { + this.title = title; + this.description = description; + } +} diff --git a/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java b/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java new file mode 100644 index 0000000..a0f373b --- /dev/null +++ b/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java @@ -0,0 +1,21 @@ +package com.example.trello.workspace.dto; + +import com.example.trello.workspace.Workspace; +import lombok.Getter; + +@Getter +public class WorkspaceResponseDto { + private Long workspaceId; + private String title; + private String description; + + public WorkspaceResponseDto(Long workspaceId, String title, String description) { + this.workspaceId = workspaceId; + this.title = title; + this.description = description; + } + + public static WorkspaceResponseDto toDto(Workspace workspace) { + return new WorkspaceResponseDto(workspace.getId(), workspace.getTitle(), workspace.getDescription()); + } +} diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index ec531e8..1932655 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -1,13 +1,21 @@ package com.example.trello.workspace_member; +import com.example.trello.user.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + @Repository public interface WorkspaceMemberRepository extends JpaRepository { + List findByUser(User user); default WorkspaceMember findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(() -> new RuntimeException()); } +// default WorkspaceMember findByUserOrElseThrow(User user) { +// return findByUser(user).orElseThrow(() -> new RuntimeException()); +// } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 0ebc534..381d2b7 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -24,7 +24,7 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String User findUser = userRepository.findByEmailOrElseThrow(email); Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); - WorkspaceMember workspaceMember = com.example.trello.workspace_member.WorkspaceMember.builder() + WorkspaceMember workspaceMember = WorkspaceMember.builder() .user(findUser) .workspace(findWorkspace) .role(READ_ONLY) From 2ad32da214b3e058c2b3e8ce3ee58d023c14e554 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 10:34:37 +0900 Subject: [PATCH 010/181] =?UTF-8?q?feat=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/workspace/WorkspaceController.java | 6 ++++++ .../trello/workspace/WorkspaceService.java | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index a3727c0..3811391 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -21,4 +21,10 @@ public ResponseEntity createWorkspace(@RequestBody Workspa return new ResponseEntity<>(createdWorkspaceResponseDto, HttpStatus.CREATED); } + + @GetMapping + public ResponseEntity> viewAllWorkspace() { + List workspaceResponseDtoList = workspaceService.viewAllWorkspace(); + return new ResponseEntity<>(workspaceResponseDtoList, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 88ac6c7..faad094 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -36,4 +36,20 @@ public WorkspaceResponseDto createWorkspace(String title, String description) { return WorkspaceResponseDto.toDto(workspace); } + + @Transactional(readOnly = true) + public List viewAllWorkspace() { + User findUser = userRepository.findByIdOrElseThrow(1L); + List WorkspaceMemberListByUser = workspaceMemberRepository.findByUser(findUser); + + List workspaceList = new ArrayList<>(); + for (WorkspaceMember workspaceMember : WorkspaceMemberListByUser) { + workspaceList.add(workspaceMember.getWorkspace()); + } + + return workspaceList + .stream() + .map(WorkspaceResponseDto::toDto) + .toList(); + } } From 7c14e69fd27bbcf521c75b16cb7b4a74b8985741 Mon Sep 17 00:00:00 2001 From: jut Date: Thu, 26 Dec 2024 10:35:05 +0900 Subject: [PATCH 011/181] =?UTF-8?q?feat=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=B0=8F=20=EC=9C=A0=EC=A0=80=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/config/SecurityConfig.java | 30 ++++++++ .../java/com/example/trello/user/User.java | 35 +++++++-- .../example/trello/user/UserController.java | 71 +++++++++++++++++++ .../example/trello/user/UserRepository.java | 12 +++- .../trello/user/dto/LoginRequestDto.java | 24 +++++++ .../trello/user/dto/SignupRequestDto.java | 35 +++++++++ .../trello/user/enums/AccountStatus.java | 5 ++ .../com/example/trello/user/enums/Role.java | 13 ++++ 8 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/example/trello/user/UserController.java create mode 100644 src/main/java/com/example/trello/user/dto/LoginRequestDto.java create mode 100644 src/main/java/com/example/trello/user/dto/SignupRequestDto.java create mode 100644 src/main/java/com/example/trello/user/enums/AccountStatus.java create mode 100644 src/main/java/com/example/trello/user/enums/Role.java diff --git a/src/main/java/com/example/trello/config/SecurityConfig.java b/src/main/java/com/example/trello/config/SecurityConfig.java index 070d57d..28e08cf 100644 --- a/src/main/java/com/example/trello/config/SecurityConfig.java +++ b/src/main/java/com/example/trello/config/SecurityConfig.java @@ -1,4 +1,34 @@ package com.example.trello.config; +import com.example.trello.user.enums.Role; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@EnableWebSecurity public class SecurityConfig { + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { + + httpSecurity + .cors(AbstractHttpConfigurer::disable) + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests((author) -> author + .requestMatchers("/users/**").permitAll() + .anyRequest().authenticated()); + + return httpSecurity.build(); + } } diff --git a/src/main/java/com/example/trello/user/User.java b/src/main/java/com/example/trello/user/User.java index b64461c..64647ae 100644 --- a/src/main/java/com/example/trello/user/User.java +++ b/src/main/java/com/example/trello/user/User.java @@ -1,24 +1,49 @@ package com.example.trello.user; +import com.example.trello.user.enums.AccountStatus; +import com.example.trello.user.enums.Role; import jakarta.persistence.*; -import lombok.Getter; +import lombok.*; @Getter @Entity +@Table(name = "users") +@NoArgsConstructor +@AllArgsConstructor public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "email") + @Column(name = "email", unique = true, nullable = false) private String email; - @Column(name = "password") + @Column(name = "password", nullable = false) private String password; - @Column(name = "nickname") + @Column(name = "nickname", nullable = false) private String nickname; - + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private Role role; + + @Setter + @Column + @Enumerated(EnumType.STRING) + private AccountStatus status; + + @Builder + public User(String email, String password, String nickname, Role role, AccountStatus status) { + this.email = email; + this.password = password; + this.nickname = nickname; + this.role = role; + this.status = status; + } + + public void deletedAccount(AccountStatus status) { + this.status = status; + } } diff --git a/src/main/java/com/example/trello/user/UserController.java b/src/main/java/com/example/trello/user/UserController.java new file mode 100644 index 0000000..25cfcb2 --- /dev/null +++ b/src/main/java/com/example/trello/user/UserController.java @@ -0,0 +1,71 @@ +package com.example.trello.user; + +import com.example.trello.user.dto.LoginRequestDto; +import com.example.trello.user.dto.SignupRequestDto; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("/users") +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + + @PostMapping("/sign-up") + public ResponseEntity signupUser(@Valid @RequestBody SignupRequestDto requestDto) { + userService.signupUser(requestDto); + + return ResponseEntity.status(HttpStatus.CREATED).body("회원가입이 완료되었습니다."); + } + + @PostMapping("/login") + public ResponseEntity login( + @RequestBody LoginRequestDto requestDto, + HttpServletRequest httpServletRequest + ) { + User loginUser = userService.login(requestDto); + + HttpSession session = httpServletRequest.getSession(); + + if (session.getAttribute("id") != null) { + throw new RuntimeException(); + } + + session.setAttribute("id", loginUser); + return ResponseEntity.ok().body("정상적으로 로그인 되었습니다."); + } + + @PostMapping("/logout") + public ResponseEntity logout(HttpServletRequest httpServletRequest) { + HttpSession session = httpServletRequest.getSession(); + + if (session != null) { + session.invalidate(); + } + + return ResponseEntity.ok().body("로그아웃 되었습니다."); + } + + @DeleteMapping("/leave") + public ResponseEntity leave( + @SessionAttribute("id") User user, + HttpServletRequest httpServletRequest + ) { + userService.leave(user.getId()); + + HttpSession session = httpServletRequest.getSession(); + if (session != null) { + session.invalidate(); + } + + return ResponseEntity.ok().body("회원 탈퇴가 정상적으로 처리되었습니다."); + } +} diff --git a/src/main/java/com/example/trello/user/UserRepository.java b/src/main/java/com/example/trello/user/UserRepository.java index b82e59a..5e0c096 100644 --- a/src/main/java/com/example/trello/user/UserRepository.java +++ b/src/main/java/com/example/trello/user/UserRepository.java @@ -4,10 +4,18 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface UserRepository extends JpaRepository { + default User findByIdOrElseThrow(Long userId){ + return findById(userId).orElseThrow(()-> new RuntimeException()); + } - default User findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + Optional findByEmail(String email); + + default User findByEmailOrElseThrow(String email) { + return findByEmail(email).orElseThrow(()-> new RuntimeException()); } } + diff --git a/src/main/java/com/example/trello/user/dto/LoginRequestDto.java b/src/main/java/com/example/trello/user/dto/LoginRequestDto.java new file mode 100644 index 0000000..0839a0b --- /dev/null +++ b/src/main/java/com/example/trello/user/dto/LoginRequestDto.java @@ -0,0 +1,24 @@ +package com.example.trello.user.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class LoginRequestDto { + + @NotBlank(message = "이메일은 필수값 입니다.") + @Pattern(regexp = "^[A-Za-z0-9.!@#$+]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", message = "이메일 형식이 올바르지 않습니다. 다시 입력해주세요") + private final String email; + + @NotBlank(message = "비밀번호는 필수값 입니다.") + @Pattern(regexp = "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$._+]).{8,16}$" , message = "비밀번호는 대문자 + 소문자 + 숫자 + 특수문자를 최소 1글자씩 입려해주세요") + private final String password; + + @Builder + public LoginRequestDto(String email, String password) { + this.email = email; + this.password = password; + } +} diff --git a/src/main/java/com/example/trello/user/dto/SignupRequestDto.java b/src/main/java/com/example/trello/user/dto/SignupRequestDto.java new file mode 100644 index 0000000..3bd6ebb --- /dev/null +++ b/src/main/java/com/example/trello/user/dto/SignupRequestDto.java @@ -0,0 +1,35 @@ +package com.example.trello.user.dto; + +import com.example.trello.user.enums.Role; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class SignupRequestDto { + + @NotBlank(message = "이메일은 필수값 입니다.") + @Pattern(regexp = "^[A-Za-z0-9.!@#$+]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", message = "이메일 형식이 올바르지 않습니다. 다시 입력해주세요") + private final String email; + + @NotBlank(message = "비밀번호는 필수값 입니다.") + @Pattern(regexp = "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$._+]).{8,16}$" , message = "비밀번호는 대문자 + 소문자 + 숫자 + 특수문자를 최소 1글자씩 입려해주세요") + private final String password; + + @NotBlank(message = "닉네임은 필수값 입니다.") + private final String nickname; + + @NotNull(message = "유저 역할은 필수값 입니다.") + private final Role role; + + + @Builder + public SignupRequestDto(String email, String password, String nickname, Role role) { + this.email = email; + this.password = password; + this.nickname = nickname; + this.role = role; + } +} diff --git a/src/main/java/com/example/trello/user/enums/AccountStatus.java b/src/main/java/com/example/trello/user/enums/AccountStatus.java new file mode 100644 index 0000000..cb96adc --- /dev/null +++ b/src/main/java/com/example/trello/user/enums/AccountStatus.java @@ -0,0 +1,5 @@ +package com.example.trello.user.enums; + +public enum AccountStatus { + ACTIVE, DELETED +} diff --git a/src/main/java/com/example/trello/user/enums/Role.java b/src/main/java/com/example/trello/user/enums/Role.java new file mode 100644 index 0000000..b4f405f --- /dev/null +++ b/src/main/java/com/example/trello/user/enums/Role.java @@ -0,0 +1,13 @@ +package com.example.trello.user.enums; + +public enum Role { + USER("user"), + ADMIN("admin") + + ; + private final String name; + + Role(String name) { + this.name = name; + } +} From 7d7c5d3a58757fc52c0942a7693e4215a7e5bfdf Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 10:35:08 +0900 Subject: [PATCH 012/181] =?UTF-8?q?feat=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=8B=A8=EC=9D=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/workspace/WorkspaceController.java | 6 ++++++ .../com/example/trello/workspace/WorkspaceService.java | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 3811391..a17368d 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -27,4 +27,10 @@ public ResponseEntity> viewAllWorkspace() { List workspaceResponseDtoList = workspaceService.viewAllWorkspace(); return new ResponseEntity<>(workspaceResponseDtoList, HttpStatus.OK); } + + @GetMapping("/{workspaceId}") + public ResponseEntity viewWorkspace(@PathVariable Long workspaceId) { + WorkspaceResponseDto findWorkspaceResponseDto = workspaceService.viewWorkspace(workspaceId); + return new ResponseEntity<>(findWorkspaceResponseDto, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index faad094..f59dcb6 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -52,4 +52,11 @@ public List viewAllWorkspace() { .map(WorkspaceResponseDto::toDto) .toList(); } + + @Transactional(readOnly = true) + public WorkspaceResponseDto viewWorkspace(Long workspaceId) { + Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + + return WorkspaceResponseDto.toDto(findWorkspace); + } } From 7368c5264ef76de7948650fa09f7562c19f0630d Mon Sep 17 00:00:00 2001 From: jut Date: Thu, 26 Dec 2024 10:36:53 +0900 Subject: [PATCH 013/181] =?UTF-8?q?feat=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=B0=8F=20=EC=9C=A0=EC=A0=80=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/user/UserService.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/java/com/example/trello/user/UserService.java diff --git a/src/main/java/com/example/trello/user/UserService.java b/src/main/java/com/example/trello/user/UserService.java new file mode 100644 index 0000000..32e8b4d --- /dev/null +++ b/src/main/java/com/example/trello/user/UserService.java @@ -0,0 +1,67 @@ +package com.example.trello.user; + +import com.example.trello.user.dto.LoginRequestDto; +import com.example.trello.user.dto.SignupRequestDto; +import com.example.trello.user.enums.AccountStatus; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + private final BCryptPasswordEncoder bCryptPasswordEncoder; + + public void signupUser(SignupRequestDto requestDto) { + Optional findUser = userRepository.findByEmail(requestDto.getEmail()); + + if (findUser.isPresent()) { + + if (AccountStatus.DELETED.equals(findUser.get().getStatus())) { + throw new RuntimeException(); + } + throw new RuntimeException(); + } + + String encodedPassword = bCryptPasswordEncoder.encode(requestDto.getPassword()); + + User user = User.builder(). + email(requestDto.getEmail()) + .password(encodedPassword) + .nickname(requestDto.getNickname()) + .role(requestDto.getRole()) + .status(AccountStatus.ACTIVE).build(); + + userRepository.save(user); + } + + + public User login(LoginRequestDto requestDto) { + User findUser = userRepository.findByEmailOrElseThrow(requestDto.getEmail()); + + if (findUser.getStatus().equals(AccountStatus.DELETED)) { + throw new RuntimeException(); + } + + String encodedPassword = bCryptPasswordEncoder.encode(requestDto.getPassword()); + + if (bCryptPasswordEncoder.matches(findUser.getPassword(), encodedPassword)) { + throw new RuntimeException(); + } + + return findUser; + } + + @Transactional + public void leave(Long userId) { + User findUser = userRepository.findByIdOrElseThrow(userId); + findUser.deletedAccount(AccountStatus.DELETED); + } +} From 86b3d538b7e4fc809d65a9c4b2e09d7ef46113f1 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:38:14 +0900 Subject: [PATCH 014/181] =?UTF-8?q?Feat=20:=20CardRequestDto=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CardRequestDto 생성 --- .../card/requestDto/CardRequestDto.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/com/example/trello/card/requestDto/CardRequestDto.java diff --git a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java new file mode 100644 index 0000000..7a67f18 --- /dev/null +++ b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java @@ -0,0 +1,19 @@ +package com.example.trello.card.requestDto; + +import jakarta.persistence.Column; +import lombok.Getter; + +@Getter +public class CardRequestDto { + + @Column(nullable = false) + Long CardListId; + + @Column(nullable = false) + String title; + + @Column(nullable = false) + String description; + + +} From ae7ccab761b8da396dd2777f578e794653a9be27 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:38:26 +0900 Subject: [PATCH 015/181] =?UTF-8?q?Feat=20:=20CardResponseDto=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CardResponseDto 생성 --- .../card/responsedto/CardResponseDto.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/com/example/trello/card/responsedto/CardResponseDto.java diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java new file mode 100644 index 0000000..0c61db2 --- /dev/null +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -0,0 +1,27 @@ +package com.example.trello.card.responsedto; + +import jakarta.persistence.Column; +import lombok.Getter; + + +@Getter +public class CardResponseDto { + + @Column(updatable = false) + + Long cardListId; + + Long cardId; + + String title; + + String description; + + + public CardResponseDto(Long cardListId, Long cardId, String title, String description) { + this.cardListId = cardListId; + this.cardId = cardId; + this.title = title; + this.description = description; + } +} From 8b227ee7838249c4c8c4c57ea022694f07c5a32e Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:38:54 +0900 Subject: [PATCH 016/181] =?UTF-8?q?Feat=20:=20QueryDslConfig=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 동적인 queryDsl을 위한 설정 --- .../com/example/trello/config/QueryDslConfig.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/example/trello/config/QueryDslConfig.java b/src/main/java/com/example/trello/config/QueryDslConfig.java index a1cc8f7..727471f 100644 --- a/src/main/java/com/example/trello/config/QueryDslConfig.java +++ b/src/main/java/com/example/trello/config/QueryDslConfig.java @@ -1,4 +1,18 @@ package com.example.trello.config; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration public class QueryDslConfig { + @PersistenceContext + private EntityManager entityManager; + + @Bean + public JPAQueryFactory jpaQueryFactory() { + return new JPAQueryFactory(entityManager); + } } From 6793c0960270a42a104c50a5c0785ef143dc466c Mon Sep 17 00:00:00 2001 From: jut Date: Thu, 26 Dec 2024 10:39:07 +0900 Subject: [PATCH 017/181] =?UTF-8?q?feat=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=B0=8F=20=EC=9A=B0=EC=A0=80=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EA=B8=B0=EB=8B=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ src/main/resources/application.properties | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c2065bc..d9eaf9e 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ out/ ### VS Code ### .vscode/ + +### properties ### +/src/main/resources/* \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index af41afb..b3b55ba 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,10 +4,9 @@ spring.datasource.url=jdbc:mysql://localhost:3306/${DB_NAME} spring.datasource.username=${DB_USERNAME} spring.datasource.password=${DB_PASSWORD} spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.jpa.hibernate.ddl-auto=none +spring.jpa.hibernate.ddl-auto=create spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect From fb9a5f7c3dbd3e4b59c44c4bc70df0c94b75e7c7 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:39:09 +0900 Subject: [PATCH 018/181] =?UTF-8?q?Feat=20:=20UpdateCardRequestDto=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UpdateCardRequestDto 생성 --- .../card/requestDto/UpdateCardRequestDto.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java diff --git a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java new file mode 100644 index 0000000..249532e --- /dev/null +++ b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java @@ -0,0 +1,20 @@ +package com.example.trello.card.requestDto; + +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +public class UpdateCardRequestDto { + + Long CardListId; + + String title; + + String description; + + LocalDateTime startAt; + + LocalDateTime endAt; + +} From c4dea2e7478693506e070bc97f2714c7cf0b993a Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:41:01 +0900 Subject: [PATCH 019/181] =?UTF-8?q?Feat=20:=20CardRepositoryCustom,=20Card?= =?UTF-8?q?RepositoryCustomImpl=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 카드 검색시 사용하는 쿼리 dsl 생성 BooleanExpression으로 조건을 받을 수 있게 했다 --- .../cardrepository/CardRepositoryCustom.java | 9 ++++ .../CardRepositoryCustomImpl.java | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java create mode 100644 src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java new file mode 100644 index 0000000..06e4425 --- /dev/null +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.example.trello.card.cardrepository; + +import com.example.trello.card.Card; + +import java.util.List; + +public interface CardRepositoryCustom { + List searchCard(Long cardListId, String title, String description); +} diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java new file mode 100644 index 0000000..7fbb190 --- /dev/null +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java @@ -0,0 +1,44 @@ +package com.example.trello.card.cardrepository; + +import com.example.trello.card.Card; +import com.example.trello.card.QCard; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class CardRepositoryCustomImpl implements CardRepositoryCustom{ + + private final JPAQueryFactory queryFactory; + + @Override + public List searchCard(Long cardListId, String title, String description) { + QCard card = QCard.card; + + return queryFactory + .selectFrom(card) + .where( + eqCardListId(cardListId), + eqTitle(title), + eqDescription(description) + ) + .fetch(); + } + + private BooleanExpression eqCardListId(Long cardListId) { + return cardListId != null ? QCard.card.cardList.id.eq(cardListId) : null; + } + + private BooleanExpression eqTitle(String title) { + return title != null ? QCard.card.title.eq(title) : null; + } + + private BooleanExpression eqDescription(String description) { + return description != null ? QCard.card.description.eq(description) : null; + } +} From 5e233f12f9337f1085229ae0511aa7b02820c723 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:42:21 +0900 Subject: [PATCH 020/181] =?UTF-8?q?Feat=20:=20CardRepository=EC=9D=98=20?= =?UTF-8?q?=EC=83=81=EC=86=8D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CardRepositoryCustom를 추가 상속 --- .../trello/card/{ => cardrepository}/CardRepository.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/main/java/com/example/trello/card/{ => cardrepository}/CardRepository.java (73%) diff --git a/src/main/java/com/example/trello/card/CardRepository.java b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java similarity index 73% rename from src/main/java/com/example/trello/card/CardRepository.java rename to src/main/java/com/example/trello/card/cardrepository/CardRepository.java index 1e6c533..faa740a 100644 --- a/src/main/java/com/example/trello/card/CardRepository.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java @@ -1,11 +1,11 @@ -package com.example.trello.card; +package com.example.trello.card.cardrepository; -import com.example.trello.board.Board; +import com.example.trello.card.Card; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface CardRepository extends JpaRepository { +public interface CardRepository extends JpaRepository, CardRepositoryCustom { default Card findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(()->new RuntimeException()); From 1ccfd30244706138faac087b557c00843aa2753f Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 10:53:19 +0900 Subject: [PATCH 021/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=EC=83=9D?= =?UTF-8?q?=EC=84=B1,=20=EC=82=AD=EC=A0=9C(=ED=95=98=EB=93=9C=20=EB=94=9C?= =?UTF-8?q?=EB=A6=AC=ED=8A=B8)=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기본적인 카드 생성,삭제 구현 아직 테스트 안해봄 카드 업데이트 및 조회 기능은 현제 구현중 --- .../java/com/example/trello/card/Card.java | 17 +++--- .../example/trello/card/CardController.java | 50 ++++++++++++++++ .../com/example/trello/card/CardService.java | 59 +++++++++++++++++++ .../card/requestDto/CardFindRequestDto.java | 13 ++++ 4 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/example/trello/card/CardController.java create mode 100644 src/main/java/com/example/trello/card/CardService.java create mode 100644 src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index af88321..c41b568 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -1,19 +1,20 @@ package com.example.trello.card; +import com.example.trello.card.requestDto.UpdateCardRequestDto; import com.example.trello.cardlist.CardList; import com.example.trello.comment.Comment; import jakarta.persistence.*; import jakarta.validation.constraints.Pattern; import lombok.Getter; import lombok.RequiredArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; +import org.hibernate.annotations.DynamicInsert; import java.time.LocalDateTime; import java.util.List; @Entity @Getter +@DynamicInsert @RequiredArgsConstructor public class Card { @@ -27,18 +28,15 @@ public class Card { @Column(name = "description") private String description; - @Column(name = "sequence") - private Integer sequence; - @Column(name = "image") private String image; @Column(name = "start_at") - @CreatedDate + @Pattern(regexp = "yyyy-mm-dd") private LocalDateTime startAt; @Column(name = "end_at") - @LastModifiedDate + @Pattern(regexp = "yyyy-mm-dd") private LocalDateTime endAt; @ManyToOne(fetch = FetchType.LAZY) @@ -53,6 +51,7 @@ public Card(String title, String description, CardList cardList) { this.cardList = cardList; } - - +// public void updateCard(UpdateCardRequestDto requestDto) { +// this.cardList.getId() = requestDto.getCardListId(); +// } } diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java new file mode 100644 index 0000000..27ef303 --- /dev/null +++ b/src/main/java/com/example/trello/card/CardController.java @@ -0,0 +1,50 @@ +package com.example.trello.card; + +import com.example.trello.card.requestDto.CardRequestDto; +import com.example.trello.card.responsedto.CardResponseDto; +import com.example.trello.card.requestDto.UpdateCardRequestDto; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.hibernate.query.Page; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.awt.print.Pageable; +import java.util.List; + +import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.title; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/cards") +public class CardController { + + private final CardService cardService; + + public ResponseEntity createdCard(CardRequestDto requestDto, HttpServletRequest servletRequest) { + CardResponseDto responseDto = cardService.createdCardService(requestDto, servletRequest); + return new ResponseEntity<>(responseDto, HttpStatus.CREATED); + } + + @PostMapping("/{cardsId}") + public ResponseEntity updateCard(@PathVariable Long cardsId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { + CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, servletRequest); + return new ResponseEntity<>(responseDto, HttpStatus.OK); + } + + @PostMapping("/{cardsId}") + public ResponseEntity deleteCard(@PathVariable Long cardsId) { + cardService.deleteCardService(cardsId); + return ResponseEntity.ok().body("삭제 완료되었습니다"); + } + +// @PostMapping("/getCards") +// public ResponseEntity> getCards(@PageableDefault(page = 1)Pageable pageable, +// @RequestParam String title, +// @RequestParam) { +// +// } + +} diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java new file mode 100644 index 0000000..5749923 --- /dev/null +++ b/src/main/java/com/example/trello/card/CardService.java @@ -0,0 +1,59 @@ +package com.example.trello.card; + +import com.example.trello.board.Board; +import com.example.trello.card.cardrepository.CardRepository; +import com.example.trello.card.requestDto.CardRequestDto; +import com.example.trello.card.responsedto.CardResponseDto; +import com.example.trello.card.requestDto.UpdateCardRequestDto; +import com.example.trello.cardlist.CardList; +import com.example.trello.cardlist.CardListRepository; +import com.example.trello.workspace.Workspace; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CardService { + + private final CardRepository cardRepository; + private final CardListRepository cardListRepository; + + // 카드 생성 + public CardResponseDto createdCardService(CardRequestDto requestDto, HttpServletRequest servletRequest) { + + CardList cardList = findCardListByCardListId(requestDto.getCardListId()); + + Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), cardList); + cardRepository.save(card); + + return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription()); + } + +// //카드 업데이트 +// public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { +// Card card = cardRepository.findByIdOrElseThrow(cardId); +// card.updateCard(requestDto); +// cardRepository.save(card); +// +// CardList cardList = findCardListByCardListId(requestDto.getCardListId()); +// +// return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription()); +// } + + // 카드 삭제(일단 hard delete 추후의 수정가능) + public void deleteCardService(Long cardId) { + Card card = cardRepository.findByIdOrElseThrow(cardId); + cardRepository.delete(card); + } + + + // 카드 리스트id로 카드 리스트 찾는 메소드 + public CardList findCardListByCardListId(Long id) { + return cardListRepository.findByIdOrElseThrow(id); + } + +} diff --git a/src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java new file mode 100644 index 0000000..fed42c4 --- /dev/null +++ b/src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java @@ -0,0 +1,13 @@ +package com.example.trello.card.requestDto; + +import lombok.Getter; + +@Getter +public class CardFindRequestDto { + + Long BoardId; + + String criteria; + + +} From 5c3855171911e5d120fc86e2c04f667a453e154e Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 12:24:35 +0900 Subject: [PATCH 022/181] =?UTF-8?q?comment=20:=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 업데이트 메서드의 주석처리 --- .../java/com/example/trello/card/CardController.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 27ef303..aa5d408 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -14,7 +14,7 @@ import java.awt.print.Pageable; import java.util.List; -import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.title; +//import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.title; @RequiredArgsConstructor @RestController @@ -28,11 +28,11 @@ public ResponseEntity createdCard(CardRequestDto requestDto, Ht return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } - @PostMapping("/{cardsId}") - public ResponseEntity updateCard(@PathVariable Long cardsId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { - CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, servletRequest); - return new ResponseEntity<>(responseDto, HttpStatus.OK); - } +// @PostMapping("/{cardsId}") +// public ResponseEntity updateCard(@PathVariable Long cardsId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { +// CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, servletRequest); +// return new ResponseEntity<>(responseDto, HttpStatus.OK); +// } @PostMapping("/{cardsId}") public ResponseEntity deleteCard(@PathVariable Long cardsId) { From 128eb8644f8e98254b89cac692263b846f5098ea Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 13:49:55 +0900 Subject: [PATCH 023/181] =?UTF-8?q?Feat=20:=20CardRequestDto=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit startAt과 endAt을 추가 --- .../com/example/trello/card/requestDto/CardRequestDto.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java index 7a67f18..a0aa82c 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java @@ -3,6 +3,8 @@ import jakarta.persistence.Column; import lombok.Getter; +import java.time.LocalDateTime; + @Getter public class CardRequestDto { @@ -15,5 +17,8 @@ public class CardRequestDto { @Column(nullable = false) String description; + LocalDateTime startAt; + + LocalDateTime endAt; } From c5370459e64ececd84d6e8508ad67e7f408f26d7 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 13:50:49 +0900 Subject: [PATCH 024/181] =?UTF-8?q?Feat=20:=20UpdateCardResponseDto=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 업데이트를 할 때 사용할 UpdateCardResponseDto를 생성 --- .../responsedto/UpdateCardResponseDto.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java diff --git a/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java new file mode 100644 index 0000000..8c94efa --- /dev/null +++ b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java @@ -0,0 +1,26 @@ +package com.example.trello.card.responsedto; + +import com.example.trello.cardlist.CardList; + +import java.time.LocalDateTime; + +public class UpdateCardResponseDto { + + CardList cardList; + + String title; + + String description; + + LocalDateTime startAt; + + LocalDateTime endAt; + + public UpdateCardResponseDto(CardList cardList, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + this.cardList = cardList; + this.title = title; + this.description = description; + this.startAt = startAt; + this.endAt = endAt; + } +} From 90a3a5f47ffeebf0492fb300a992dcb4f68fbd53 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 13:51:51 +0900 Subject: [PATCH 025/181] =?UTF-8?q?Feat=20:=20CardResponseDto=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit startAt과 endAt 추가 --- .../trello/card/responsedto/CardResponseDto.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index 0c61db2..361f5d3 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -3,12 +3,12 @@ import jakarta.persistence.Column; import lombok.Getter; +import java.time.LocalDateTime; + @Getter public class CardResponseDto { - @Column(updatable = false) - Long cardListId; Long cardId; @@ -17,11 +17,17 @@ public class CardResponseDto { String description; + LocalDateTime startAt; + + LocalDateTime endAt; + - public CardResponseDto(Long cardListId, Long cardId, String title, String description) { + public CardResponseDto(Long cardListId, Long cardId, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { this.cardListId = cardListId; this.cardId = cardId; this.title = title; this.description = description; + this.startAt = startAt; + this.endAt =endAt; } } From 6a29660cb1113e226ca5cf65dc3b15598475fda3 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 13:52:34 +0900 Subject: [PATCH 026/181] =?UTF-8?q?Comment=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 아직 미구현임으로 주석처리 --- src/main/java/com/example/trello/card/Card.java | 10 ++++++++-- .../java/com/example/trello/card/CardService.java | 11 ++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index c41b568..b6e1685 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -1,6 +1,8 @@ package com.example.trello.card; import com.example.trello.card.requestDto.UpdateCardRequestDto; +import com.example.trello.card.responsedto.CardResponseDto; +import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.comment.Comment; import jakarta.persistence.*; @@ -51,7 +53,11 @@ public Card(String title, String description, CardList cardList) { this.cardList = cardList; } -// public void updateCard(UpdateCardRequestDto requestDto) { -// this.cardList.getId() = requestDto.getCardListId(); +// public void updateCard(UpdateCardResponseDto updateCardResponseDto) { +// cardList = up +// title = requestDto.getTitle(); +// description = requestDto.getDescription(); +// startAt = requestDto.getStartAt(); +// endAt = requestDto.getEndAt(); // } } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 5749923..d83684a 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -5,6 +5,7 @@ import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; +import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; import com.example.trello.workspace.Workspace; @@ -30,17 +31,21 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, HttpServlet Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), cardList); cardRepository.save(card); - return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription()); + return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); } // //카드 업데이트 // public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { // Card card = cardRepository.findByIdOrElseThrow(cardId); +// +// CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); +// +// UpdateCardResponseDto updateCardResponseDto = new UpdateCardResponseDto(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); +// +// // card.updateCard(requestDto); // cardRepository.save(card); // -// CardList cardList = findCardListByCardListId(requestDto.getCardListId()); -// // return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription()); // } From 1fe3b85a446dbe5a336d583ed5df8bcca1172ce0 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 15:24:09 +0900 Subject: [PATCH 027/181] =?UTF-8?q?feat=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=88=98=EC=A0=95=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/workspace/Workspace.java | 5 +++++ .../trello/workspace/WorkspaceController.java | 8 ++++++-- .../example/trello/workspace/WorkspaceService.java | 9 +++++++++ .../workspace/dto/UpdateWorkspaceRequestDto.java | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index 0a96bb8..4c27544 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -35,4 +35,9 @@ public Workspace(String title, String description) { this.title = title; this.description = description; } + + public void updateWorkspace(String title, String description) { + this.title = title; + this.description = description; + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 0e97642..d58f7e1 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -1,5 +1,6 @@ package com.example.trello.workspace; +import com.example.trello.workspace.dto.UpdateWorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceResponseDto; import lombok.RequiredArgsConstructor; @@ -34,6 +35,9 @@ public ResponseEntity viewWorkspace(@PathVariable Long wor return new ResponseEntity<>(findWorkspaceResponseDto, HttpStatus.OK); } -// @PatchMapping("/{workspaceId}") -// public ResponseEntity<> + @PatchMapping("/{workspaceId}") + public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto) { + WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto.getTitle(), dto.getDescription()); + return new ResponseEntity<>(updatedWorkspaceResponseDto, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index f59dcb6..0404e7a 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -59,4 +59,13 @@ public WorkspaceResponseDto viewWorkspace(Long workspaceId) { return WorkspaceResponseDto.toDto(findWorkspace); } + + @Transactional + public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, String description) { + Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + + findWorkspace.updateWorkspace(title, description); + + return WorkspaceResponseDto.toDto(findWorkspace); + } } diff --git a/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java b/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java new file mode 100644 index 0000000..27d08f2 --- /dev/null +++ b/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java @@ -0,0 +1,14 @@ +package com.example.trello.workspace.dto; + +import lombok.Getter; + +@Getter +public class UpdateWorkspaceRequestDto { + private String title; + private String description; + + public UpdateWorkspaceRequestDto(String title, String description) { + this.title = title; + this.description = description; + } +} From b9a0def977e11e68c00c9bab34a911853435eedd Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 15:31:27 +0900 Subject: [PATCH 028/181] =?UTF-8?q?feat=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/workspace/Workspace.java | 4 ++++ .../com/example/trello/workspace/WorkspaceController.java | 6 ++++++ .../java/com/example/trello/workspace/WorkspaceService.java | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index 4c27544..dada86c 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -2,6 +2,7 @@ import com.example.trello.board.Board; import com.example.trello.user.User; +import com.example.trello.workspace_member.WorkspaceMember; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; @@ -24,6 +25,9 @@ public class Workspace { @OneToMany(mappedBy = "workspace", cascade = CascadeType.ALL, orphanRemoval = true) private List boards; + @OneToMany(mappedBy = "workspace", cascade = CascadeType.ALL, orphanRemoval = true) + private List workspaceMembers; + @ManyToOne(fetch = FetchType.LAZY) private User user; diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index d58f7e1..5f728f6 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -40,4 +40,10 @@ public ResponseEntity updateWorkspace(@PathVariable Long w WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto.getTitle(), dto.getDescription()); return new ResponseEntity<>(updatedWorkspaceResponseDto, HttpStatus.OK); } + + @DeleteMapping("/{workspaceId}") + public ResponseEntity deleteWorkspace(@PathVariable Long workspaceId) { + workspaceService.deleteWorkspace(workspaceId); + return new ResponseEntity<>(HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 0404e7a..a48faa0 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -68,4 +68,10 @@ public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, Stri return WorkspaceResponseDto.toDto(findWorkspace); } + + @Transactional + public void deleteWorkspace(Long workspaceId) { + Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + workSpaceRepository.delete(findWorkspace); + } } From 54ee2367df8fe92595f165aba23a607f994e6a38 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 15:55:22 +0900 Subject: [PATCH 029/181] =?UTF-8?q?refactor=20:=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=EC=9D=98=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EC=9D=98=20=EA=B6=8C=ED=95=9C=EC=9D=B4=20ADM?= =?UTF-8?q?IN=20=EC=9D=BC=EB=95=8C=EB=A7=8C=20=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/workspace/Workspace.java | 3 ++- .../trello/workspace/WorkspaceController.java | 4 ++-- .../trello/workspace/WorkspaceService.java | 21 +++++++++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index dada86c..6708792 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -35,9 +35,10 @@ public Workspace() { } @Builder - public Workspace(String title, String description) { + public Workspace(String title, String description, User user) { this.title = title; this.description = description; + this.user = user; } public void updateWorkspace(String title, String description) { diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 5f728f6..49d17b5 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -17,8 +17,8 @@ public class WorkspaceController { private final WorkspaceService workspaceService; @PostMapping - public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto) { - WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto.getTitle(), dto.getDescription()); + public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto, @SessionAttribute("id") Long loginUserId) { + WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto.getTitle(), dto.getDescription(), loginUserId); return new ResponseEntity<>(createdWorkspaceResponseDto, HttpStatus.CREATED); } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index a48faa0..780ceba 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -17,6 +17,10 @@ import java.util.ArrayList; import java.util.List; +import static com.example.trello.user.enums.Role.ADMIN; +import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; +import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; + @Service @RequiredArgsConstructor public class WorkspaceService { @@ -24,15 +28,28 @@ public class WorkspaceService { private final WorkSpaceRepository workSpaceRepository; private final WorkspaceMemberRepository workspaceMemberRepository; - // todo : Admin 권한을 가진 유저만 생성가능하게 @Transactional - public WorkspaceResponseDto createWorkspace(String title, String description) { + public WorkspaceResponseDto createWorkspace(String title, String description, Long loginUserId) { + User loginUser = userRepository.findByIdOrElseThrow(loginUserId); + + if (loginUser.getRole() != ADMIN) { + throw new RuntimeException("권한이 ADMIN 인 유저만 워크스페이스 생성이 가능합니다."); + } + Workspace workspace = Workspace.builder() .title(title) .description(description) + .user(loginUser) + .build(); + + WorkspaceMember workspaceMember = WorkspaceMember.builder() + .user(loginUser) + .workspace(workspace) + .role(WORKSPACE) .build(); workSpaceRepository.save(workspace); + workspaceMemberRepository.save(workspaceMember); return WorkspaceResponseDto.toDto(workspace); } From 908689852228e1258d09d54baecc05f8c2e5d89b Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 16:07:45 +0900 Subject: [PATCH 030/181] =?UTF-8?q?refactor=20:=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=EC=9D=98=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EB=A5=BC=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EA=B0=80=20=EA=B8=B0=EC=A4=80=EC=9D=B4=20?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 워크스페이스 전체 조회 → 로그인한 유저가 멤버로 있는 모든 워크스페이스 조회 워크스페이스 단건 조회 → 로그인한 유저가 멤버로 있는 워크스페이스만 조회가능 (멤버가 아닌 워크스페이스 조회 시도시 예외발생) --- .../example/trello/workspace/WorkspaceController.java | 8 ++++---- .../com/example/trello/workspace/WorkspaceService.java | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 49d17b5..9a444f0 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -24,14 +24,14 @@ public ResponseEntity createWorkspace(@RequestBody Workspa } @GetMapping - public ResponseEntity> viewAllWorkspace() { - List workspaceResponseDtoList = workspaceService.viewAllWorkspace(); + public ResponseEntity> viewAllWorkspace(@SessionAttribute("id") Long loginUserId) { + List workspaceResponseDtoList = workspaceService.viewAllWorkspace(loginUserId); return new ResponseEntity<>(workspaceResponseDtoList, HttpStatus.OK); } @GetMapping("/{workspaceId}") - public ResponseEntity viewWorkspace(@PathVariable Long workspaceId) { - WorkspaceResponseDto findWorkspaceResponseDto = workspaceService.viewWorkspace(workspaceId); + public ResponseEntity viewWorkspace(@PathVariable Long workspaceId, @SessionAttribute("id") Long loginUserId) { + WorkspaceResponseDto findWorkspaceResponseDto = workspaceService.viewWorkspace(workspaceId, loginUserId); return new ResponseEntity<>(findWorkspaceResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 780ceba..f4beebe 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -55,8 +55,8 @@ public WorkspaceResponseDto createWorkspace(String title, String description, Lo } @Transactional(readOnly = true) - public List viewAllWorkspace() { - User findUser = userRepository.findByIdOrElseThrow(1L); + public List viewAllWorkspace(Long loginUserId) { + User findUser = userRepository.findByIdOrElseThrow(loginUserId); List WorkspaceMemberListByUser = workspaceMemberRepository.findByUser(findUser); List workspaceList = new ArrayList<>(); @@ -71,9 +71,13 @@ public List viewAllWorkspace() { } @Transactional(readOnly = true) - public WorkspaceResponseDto viewWorkspace(Long workspaceId) { + public WorkspaceResponseDto viewWorkspace(Long workspaceId, Long loginUserId) { Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + if (!loginUserId.equals(findWorkspace.getUser().getId())) { + throw new RuntimeException("조회할 권한이 없는 워크스페이스입니다."); + } + return WorkspaceResponseDto.toDto(findWorkspace); } From e435fb1407bef1b265c8779a9ddb7ea093820a4d Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 16:17:28 +0900 Subject: [PATCH 031/181] =?UTF-8?q?Fix=20:=20CardFindRequestDto,=20UpdateC?= =?UTF-8?q?ardResponseDto=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 쓸 필요가 없다고 판단하여 삭제 --- .../card/requestDto/CardFindRequestDto.java | 13 ---------- .../responsedto/UpdateCardResponseDto.java | 26 ------------------- 2 files changed, 39 deletions(-) delete mode 100644 src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java delete mode 100644 src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java diff --git a/src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java deleted file mode 100644 index fed42c4..0000000 --- a/src/main/java/com/example/trello/card/requestDto/CardFindRequestDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.trello.card.requestDto; - -import lombok.Getter; - -@Getter -public class CardFindRequestDto { - - Long BoardId; - - String criteria; - - -} diff --git a/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java deleted file mode 100644 index 8c94efa..0000000 --- a/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.trello.card.responsedto; - -import com.example.trello.cardlist.CardList; - -import java.time.LocalDateTime; - -public class UpdateCardResponseDto { - - CardList cardList; - - String title; - - String description; - - LocalDateTime startAt; - - LocalDateTime endAt; - - public UpdateCardResponseDto(CardList cardList, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { - this.cardList = cardList; - this.title = title; - this.description = description; - this.startAt = startAt; - this.endAt = endAt; - } -} From 171a20539cf7bbe755d4e3efa1f972e9a1b28f79 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 16:19:51 +0900 Subject: [PATCH 032/181] =?UTF-8?q?Feat=20:=20LocalDateTime=EC=9D=98=20@Js?= =?UTF-8?q?onFormat=EC=B6=94=EA=B0=80=20=EB=B0=8F=20CardRequestDto?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LocalDateTime에 @JsonFormat을 추가하여 String 값으로 보관 가능하게 변경, CardRequestDto에 생성자 생성 --- .../card/requestDto/CardRequestDto.java | 23 ++++++++++++------- .../card/responsedto/CardResponseDto.java | 11 +++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java index a0aa82c..6d9c169 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java @@ -1,5 +1,6 @@ package com.example.trello.card.requestDto; +import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.persistence.Column; import lombok.Getter; @@ -8,17 +9,23 @@ @Getter public class CardRequestDto { - @Column(nullable = false) - Long CardListId; + private Long cardListId; - @Column(nullable = false) - String title; + private String title; - @Column(nullable = false) - String description; + private String description; - LocalDateTime startAt; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime startAt; - LocalDateTime endAt; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime endAt; + public CardRequestDto(Long cardListId, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + this.cardListId = cardListId; + this.title = title; + this.description = description; + this.startAt = startAt; + this.endAt = endAt; + } } diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index 361f5d3..1f86424 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -1,5 +1,6 @@ package com.example.trello.card.responsedto; +import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.persistence.Column; import lombok.Getter; @@ -9,16 +10,18 @@ @Getter public class CardResponseDto { - Long cardListId; + private Long cardListId; - Long cardId; + private Long cardId; - String title; + private String title; - String description; + private String description; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") LocalDateTime startAt; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") LocalDateTime endAt; From d135d22440c403abe20ef7ffef4f1900561536e8 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 16:20:45 +0900 Subject: [PATCH 033/181] =?UTF-8?q?Feat=20:=20LocalDateTime=EC=9D=98=20@Js?= =?UTF-8?q?onFormat=EC=B6=94=EA=B0=80=20=EB=B0=8FUpdateCardRequestDto?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LocalDateTime에 @JsonFormat을 추가하여 String 값으로 보관 가능하게 변경, UpdateCardRequestDto에 생성자 생성 --- .../com/example/trello/card/CardService.java | 44 +++++++++++-------- .../card/requestDto/UpdateCardRequestDto.java | 20 ++++++--- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index d83684a..1d9da8a 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -5,13 +5,13 @@ import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; -import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; import com.example.trello.workspace.Workspace; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PostMapping; import java.util.ArrayList; import java.util.List; @@ -24,37 +24,43 @@ public class CardService { private final CardListRepository cardListRepository; // 카드 생성 - public CardResponseDto createdCardService(CardRequestDto requestDto, HttpServletRequest servletRequest) { + public CardResponseDto createdCardService(CardRequestDto requestDto) { CardList cardList = findCardListByCardListId(requestDto.getCardListId()); - Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), cardList); + Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), cardList, requestDto.getStartAt(), requestDto.getEndAt()); cardRepository.save(card); return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); } -// //카드 업데이트 -// public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { -// Card card = cardRepository.findByIdOrElseThrow(cardId); -// -// CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); -// -// UpdateCardResponseDto updateCardResponseDto = new UpdateCardResponseDto(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); -// -// -// card.updateCard(requestDto); -// cardRepository.save(card); -// -// return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription()); -// } - - // 카드 삭제(일단 hard delete 추후의 수정가능) + //카드 업데이트 + public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto) { + Card card = cardRepository.findByIdOrElseThrow(cardId); + + CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); + + card.updateCard(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + + cardRepository.save(card); + + return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + } + + // 카드 삭제 + @PostMapping("/{cardsId}") public void deleteCardService(Long cardId) { Card card = cardRepository.findByIdOrElseThrow(cardId); cardRepository.delete(card); } + // 카드 단건 조회 + public CardResponseDto findCardById(Long cardsId) { + Card card = cardRepository.findByIdOrElseThrow(cardsId); + return new CardResponseDto(card.getCardList().getId(), card.getId(), card.getTitle(), card.getDescription(), card.getStartAt(),card.getEndAt()); + } + + // 카드 리스트id로 카드 리스트 찾는 메소드 public CardList findCardListByCardListId(Long id) { diff --git a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java index 249532e..4727a13 100644 --- a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java @@ -1,5 +1,6 @@ package com.example.trello.card.requestDto; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Getter; import java.time.LocalDateTime; @@ -7,14 +8,23 @@ @Getter public class UpdateCardRequestDto { - Long CardListId; + private Long CardListId; - String title; + private String title; - String description; + private String description; - LocalDateTime startAt; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime startAt; - LocalDateTime endAt; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm") + private LocalDateTime endAt; + public UpdateCardRequestDto(String title, Long cardListId, String description, LocalDateTime startAt, LocalDateTime endAt) { + this.title = title; + this.CardListId = cardListId; + this.description = description; + this.startAt = startAt; + this.endAt = endAt; + } } From 4fbd6fe270871b8b7bea1669e75e0ec64d94faca Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 16:22:08 +0900 Subject: [PATCH 034/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8,=EB=8B=A8=EA=B1=B4?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84,?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=ED=95=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/card/Card.java | 21 ++++++----- .../example/trello/card/CardController.java | 35 ++++++++++++------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index b6e1685..f84422d 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -2,7 +2,6 @@ import com.example.trello.card.requestDto.UpdateCardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; -import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.comment.Comment; import jakarta.persistence.*; @@ -34,11 +33,9 @@ public class Card { private String image; @Column(name = "start_at") - @Pattern(regexp = "yyyy-mm-dd") private LocalDateTime startAt; @Column(name = "end_at") - @Pattern(regexp = "yyyy-mm-dd") private LocalDateTime endAt; @ManyToOne(fetch = FetchType.LAZY) @@ -47,17 +44,19 @@ public class Card { @OneToMany(mappedBy = "card",cascade = CascadeType.ALL,orphanRemoval = true) private List comments; - public Card(String title, String description, CardList cardList) { + public Card(String title, String description, CardList cardList, LocalDateTime startAt, LocalDateTime endAt) { this.title = title; this.description = description; this.cardList = cardList; + this.startAt = startAt; + this.endAt = endAt; } -// public void updateCard(UpdateCardResponseDto updateCardResponseDto) { -// cardList = up -// title = requestDto.getTitle(); -// description = requestDto.getDescription(); -// startAt = requestDto.getStartAt(); -// endAt = requestDto.getEndAt(); -// } + public void updateCard(CardList cardList, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + this.cardList = cardList; + this.title = title; + this.description = description; + this.startAt = startAt; + this.endAt = endAt; + } } diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index aa5d408..492bdfc 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.*; import java.awt.print.Pageable; +import java.time.LocalDateTime; import java.util.List; //import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.title; @@ -23,28 +24,36 @@ public class CardController { private final CardService cardService; - public ResponseEntity createdCard(CardRequestDto requestDto, HttpServletRequest servletRequest) { - CardResponseDto responseDto = cardService.createdCardService(requestDto, servletRequest); + @PostMapping + public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto) { + CardResponseDto responseDto = cardService.createdCardService(requestDto); return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } -// @PostMapping("/{cardsId}") -// public ResponseEntity updateCard(@PathVariable Long cardsId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { -// CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, servletRequest); -// return new ResponseEntity<>(responseDto, HttpStatus.OK); -// } + @PatchMapping("/{cardsId}/updateCards") + public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto) { + CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto); + return new ResponseEntity<>(responseDto, HttpStatus.OK); + } - @PostMapping("/{cardsId}") + @DeleteMapping("/{cardsId}") public ResponseEntity deleteCard(@PathVariable Long cardsId) { cardService.deleteCardService(cardsId); - return ResponseEntity.ok().body("삭제 완료되었습니다"); + return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); + } + + @GetMapping("/{cardsId}") + public ResponseEntity findCard(@PathVariable Long cardsId) { + CardResponseDto responseDto = cardService.findCardById(cardsId); + return new ResponseEntity<>(responseDto, HttpStatus.OK); } // @PostMapping("/getCards") -// public ResponseEntity> getCards(@PageableDefault(page = 1)Pageable pageable, -// @RequestParam String title, -// @RequestParam) { -// +// public List getCards(@PageableDefault(page = 1)Pageable pageable, +// @RequestParam(required = false) String title, +// @RequestParam(required = false) LocalDateTime startAt, +// @RequestParam(required = false) LocalDateTime endAt) { +// return cardService.searchCards(title, startAt, endAt); // } } From 6ebc3b1d80d8bdf880a797f9d1497a8cc556c9e0 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 16:24:31 +0900 Subject: [PATCH 035/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EB=8B=A4=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/CardController.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 492bdfc..7d352b7 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -48,12 +48,12 @@ public ResponseEntity findCard(@PathVariable Long cardsId) { return new ResponseEntity<>(responseDto, HttpStatus.OK); } -// @PostMapping("/getCards") -// public List getCards(@PageableDefault(page = 1)Pageable pageable, -// @RequestParam(required = false) String title, -// @RequestParam(required = false) LocalDateTime startAt, -// @RequestParam(required = false) LocalDateTime endAt) { -// return cardService.searchCards(title, startAt, endAt); -// } + @PostMapping("/getCards") + public List getCards(@PageableDefault(page = 1)Pageable pageable, + @RequestParam(required = false) String title, + @RequestParam(required = false) LocalDateTime startAt, + @RequestParam(required = false) LocalDateTime endAt) { + return cardService.searchCards(title, startAt, endAt); + } } From a1ba8084ddcdbeb8ad0323ca38db1711883aaf95 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 16:44:06 +0900 Subject: [PATCH 036/181] =?UTF-8?q?refactor=20:=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=EC=9D=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=82=AD=EC=A0=9C=EB=A5=BC=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=ED=95=9C=20=EC=9C=A0=EC=A0=80=EA=B0=80=20WOR?= =?UTF-8?q?KSPACE=20=EC=97=AD=ED=95=A0=EC=9D=84=20=EA=B0=80=EC=A7=80?= =?UTF-8?q?=EA=B3=A0=20=EC=9E=88=EC=9D=84=EB=95=8C=EB=A7=8C=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 워크스페이스 수정 및 삭제 → 로그인한 유저가 해당 워크스페이스의 WORKSPACE 롤을 가지고 있을때만 수정 및 삭제가능 (아닐시 예외발생) --- .../trello/workspace/WorkspaceController.java | 10 +++---- .../trello/workspace/WorkspaceService.java | 27 ++++++++++++++----- .../WorkspaceMemberRepository.java | 7 ++--- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 9a444f0..bee1685 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -36,14 +36,14 @@ public ResponseEntity viewWorkspace(@PathVariable Long wor } @PatchMapping("/{workspaceId}") - public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto) { - WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto.getTitle(), dto.getDescription()); + public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto, @SessionAttribute("id") Long loginUserId) { + WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto.getTitle(), dto.getDescription(), loginUserId); return new ResponseEntity<>(updatedWorkspaceResponseDto, HttpStatus.OK); } @DeleteMapping("/{workspaceId}") - public ResponseEntity deleteWorkspace(@PathVariable Long workspaceId) { - workspaceService.deleteWorkspace(workspaceId); - return new ResponseEntity<>(HttpStatus.OK); + public String deleteWorkspace(@PathVariable Long workspaceId, @SessionAttribute("id") Long loginUserId) { + workspaceService.deleteWorkspace(workspaceId, loginUserId); + return "워크스페이스가 정상적으로 삭제되었습니다."; } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index f4beebe..d2cc4af 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -82,17 +82,30 @@ public WorkspaceResponseDto viewWorkspace(Long workspaceId, Long loginUserId) { } @Transactional - public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, String description) { - Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, String description, Long loginUserId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); - findWorkspace.updateWorkspace(title, description); + if (findWorkspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("워크스페이스를 수정할 권한이 없습니다."); + } - return WorkspaceResponseDto.toDto(findWorkspace); + Workspace workspace = findWorkspaceMember.getWorkspace(); + + workspace.updateWorkspace(title, description); + + return WorkspaceResponseDto.toDto(workspace); } @Transactional - public void deleteWorkspace(Long workspaceId) { - Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); - workSpaceRepository.delete(findWorkspace); + public void deleteWorkspace(Long workspaceId, Long loginUserId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + + if (findWorkspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("워크스페이스를 삭제할 권한이 없습니다."); + } + + Workspace workspace = findWorkspaceMember.getWorkspace(); + + workSpaceRepository.delete(workspace); } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index 1932655..1780201 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -10,12 +10,13 @@ @Repository public interface WorkspaceMemberRepository extends JpaRepository { List findByUser(User user); + Optional findByUserIdAndWorkspaceId(Long userId, Long workspaceId); default WorkspaceMember findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(() -> new RuntimeException()); } -// default WorkspaceMember findByUserOrElseThrow(User user) { -// return findByUser(user).orElseThrow(() -> new RuntimeException()); -// } + default WorkspaceMember findByUserIdOrElseThrow(Long userId, Long workspaceId) { + return findByUserIdAndWorkspaceId(userId, workspaceId).orElseThrow(() -> new RuntimeException()); + } } From 7be0fd0f483b84dd4c7528fb091767afb2780396 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 16:49:31 +0900 Subject: [PATCH 037/181] =?UTF-8?q?fix=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=8B=A8=EA=B1=B4=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=8B=9C=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EA=B0=80=20=EC=95=88=EB=90=98=EB=8D=98=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 워크스페이스 단건 조회시 로그인한유저가 해당 워크스페이스의 멤버일때 조회가 가능해야 하는데, 워크스페이스의 제작자일때만 조회가 가능하던 부분 수정 --- .../com/example/trello/workspace/WorkspaceService.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index d2cc4af..e4ed1fe 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -72,13 +72,11 @@ public List viewAllWorkspace(Long loginUserId) { @Transactional(readOnly = true) public WorkspaceResponseDto viewWorkspace(Long workspaceId, Long loginUserId) { - Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); - if (!loginUserId.equals(findWorkspace.getUser().getId())) { - throw new RuntimeException("조회할 권한이 없는 워크스페이스입니다."); - } + Workspace workspace = findWorkspaceMember.getWorkspace(); - return WorkspaceResponseDto.toDto(findWorkspace); + return WorkspaceResponseDto.toDto(workspace); } @Transactional From d8f910c4cd6b086f9445da76379f5387b997fd88 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 17:16:02 +0900 Subject: [PATCH 038/181] =?UTF-8?q?refactor=20:=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EC=B4=88=EB=8C=80=20=EB=B0=8F=20=EB=A9=A4=EB=B2=84=20=EC=97=AD?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=EC=A0=95=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 워크스페이스 멤버 초대는 WORKSPACE 롤을 가진 유저만 가능하도록 리팩토링 워크스페이스 멤버 역할 수정 중 WORKSPACE 롤은 ADMIN 만 부여 가능하도록 설정, 나머지 롤은 WORKSPACE 롤을 가진 유저만 변경하도록 리팩토링 --- .../WorkspaceMemberController.java | 9 ++--- .../WorkspaceMemberService.java | 33 +++++++++++++++---- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java index b2bbc90..390574f 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java @@ -16,13 +16,14 @@ public class WorkspaceMemberController { private final WorkspaceMemberService workspaceMemberService; @PostMapping("/member-invite") - public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto) { - WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto.getEmail()); + public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto, @SessionAttribute("id") Long loginUserId) { + WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto.getEmail(), loginUserId); return new ResponseEntity<>(workspaceMemberResponseDto, HttpStatus.CREATED); } @PatchMapping("/member-role") - public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto) { - return workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto.getWorkspaceMemberId(), dto.getRole()); + public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto, @SessionAttribute("id") Long loginUserId) { + workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto.getWorkspaceMemberId(), dto.getRole(), loginUserId); + return "권한이 " + dto.getRole() + "로 변경되었습니다."; } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 381d2b7..118a87c 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -7,10 +7,14 @@ import com.example.trello.workspace_member.dto.WorkspaceMemberResponseDto; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import static com.example.trello.user.enums.Role.ADMIN; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; +import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; +@Slf4j @Service @RequiredArgsConstructor public class WorkspaceMemberService { @@ -20,13 +24,19 @@ public class WorkspaceMemberService { private final UserRepository userRepository; @Transactional - public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String email) { + public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String email, Long loginUserId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + + if (findWorkspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("멤버를 초대할 권한이 없습니다."); + } + User findUser = userRepository.findByEmailOrElseThrow(email); - Workspace findWorkspace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + Workspace workspace = findWorkspaceMember.getWorkspace(); WorkspaceMember workspaceMember = WorkspaceMember.builder() .user(findUser) - .workspace(findWorkspace) + .workspace(workspace) .role(READ_ONLY) .build(); @@ -36,11 +46,20 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String } @Transactional - public String updateWorkspaceMemberRole(Long workspaceId, Long workspaceMemberId , WorkspaceMemberRole role) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(workspaceMemberId); + public void updateWorkspaceMemberRole(Long workspaceId, Long workspaceMemberId , WorkspaceMemberRole role, Long loginUserId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + + if (role == WORKSPACE && findWorkspaceMember.getUser().getRole() != ADMIN) { + throw new RuntimeException("WORKSPACE 역할은 ADMIN 만 부여할 수 있습니다."); + } + + if (findWorkspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("멤버 역할을 수정할 권한이 없습니다."); + } - findWorkspaceMember.updateRole(role); + WorkspaceMember roleUpdatedWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(workspaceMemberId); - return "권한이 " + role + "로 변경되었습니다."; + roleUpdatedWorkspaceMember.updateRole(role); + log.info("{}의 역할이 {}로 변경되었습니다.", roleUpdatedWorkspaceMember.getUser().getNickname(), role); } } From a3b28bb91b038056fd35911e44505fb1927b8c93 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 17:49:07 +0900 Subject: [PATCH 039/181] =?UTF-8?q?Fix=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EB=8B=A4=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 카드 다건 조회시 조건을 cardListId,startAt,endAt,boardId로 변경 --- .../cardrepository/CardRepositoryCustom.java | 4 +++- .../CardRepositoryCustomImpl.java | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java index 06e4425..8cfe3b0 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java @@ -2,8 +2,10 @@ import com.example.trello.card.Card; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; public interface CardRepositoryCustom { - List searchCard(Long cardListId, String title, String description); + List searchCard(Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); } diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java index 7fbb190..c0ff75d 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java @@ -8,6 +8,8 @@ import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.RequestParam; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; @Repository @@ -17,15 +19,16 @@ public class CardRepositoryCustomImpl implements CardRepositoryCustom{ private final JPAQueryFactory queryFactory; @Override - public List searchCard(Long cardListId, String title, String description) { + public List searchCard(Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { QCard card = QCard.card; return queryFactory .selectFrom(card) .where( eqCardListId(cardListId), - eqTitle(title), - eqDescription(description) + eqStartAt(startAt), + eqEndAt(endAt), + eqBoard(boardId) ) .fetch(); } @@ -34,11 +37,15 @@ private BooleanExpression eqCardListId(Long cardListId) { return cardListId != null ? QCard.card.cardList.id.eq(cardListId) : null; } - private BooleanExpression eqTitle(String title) { - return title != null ? QCard.card.title.eq(title) : null; + private BooleanExpression eqStartAt(LocalDate startAt) { + return startAt != null ? QCard.card.startAt.eq(startAt) : null; } - private BooleanExpression eqDescription(String description) { - return description != null ? QCard.card.description.eq(description) : null; + private BooleanExpression eqEndAt(LocalDate endAt) { + return endAt != null ? QCard.card.endAt.eq(endAt) : null; + } + + private BooleanExpression eqBoard(Long boardId) { + return boardId != null ? QCard.card.cardList.board.id.eq(boardId) : null; } } From 6a8af4a38a50ac63913d537fb0fe8d8120cf4942 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 17:50:36 +0900 Subject: [PATCH 040/181] =?UTF-8?q?Fix=20:=20=EC=8B=9C=EC=9E=91=EC=9D=BC,?= =?UTF-8?q?=EB=A7=88=EA=B0=90=EC=9D=BC=EC=9D=98=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 시작일,마감일의 타입을 LocalDateTime에서 LocalDate로 변경 --- src/main/java/com/example/trello/card/Card.java | 9 +++++---- .../trello/card/requestDto/CardRequestDto.java | 11 ++++++----- .../trello/card/requestDto/UpdateCardRequestDto.java | 11 ++++++----- .../trello/card/responsedto/CardResponseDto.java | 11 ++++++----- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index f84422d..b5b86c8 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -10,6 +10,7 @@ import lombok.RequiredArgsConstructor; import org.hibernate.annotations.DynamicInsert; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -33,10 +34,10 @@ public class Card { private String image; @Column(name = "start_at") - private LocalDateTime startAt; + private LocalDate startAt; @Column(name = "end_at") - private LocalDateTime endAt; + private LocalDate endAt; @ManyToOne(fetch = FetchType.LAZY) private CardList cardList; @@ -44,7 +45,7 @@ public class Card { @OneToMany(mappedBy = "card",cascade = CascadeType.ALL,orphanRemoval = true) private List comments; - public Card(String title, String description, CardList cardList, LocalDateTime startAt, LocalDateTime endAt) { + public Card(String title, String description, CardList cardList, LocalDate startAt, LocalDate endAt) { this.title = title; this.description = description; this.cardList = cardList; @@ -52,7 +53,7 @@ public Card(String title, String description, CardList cardList, LocalDateTime s this.endAt = endAt; } - public void updateCard(CardList cardList, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + public void updateCard(CardList cardList, String title, String description, LocalDate startAt, LocalDate endAt) { this.cardList = cardList; this.title = title; this.description = description; diff --git a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java index 6d9c169..c5698de 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java @@ -4,6 +4,7 @@ import jakarta.persistence.Column; import lombok.Getter; +import java.time.LocalDate; import java.time.LocalDateTime; @Getter @@ -15,13 +16,13 @@ public class CardRequestDto { private String description; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm") - private LocalDateTime startAt; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate startAt; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm") - private LocalDateTime endAt; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endAt; - public CardRequestDto(Long cardListId, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + public CardRequestDto(Long cardListId, String title, String description, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.title = title; this.description = description; diff --git a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java index 4727a13..d342d45 100644 --- a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Getter; +import java.time.LocalDate; import java.time.LocalDateTime; @Getter @@ -14,13 +15,13 @@ public class UpdateCardRequestDto { private String description; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm") - private LocalDateTime startAt; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate startAt; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm") - private LocalDateTime endAt; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endAt; - public UpdateCardRequestDto(String title, Long cardListId, String description, LocalDateTime startAt, LocalDateTime endAt) { + public UpdateCardRequestDto(String title, Long cardListId, String description, LocalDate startAt, LocalDate endAt) { this.title = title; this.CardListId = cardListId; this.description = description; diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index 1f86424..776ba34 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -4,6 +4,7 @@ import jakarta.persistence.Column; import lombok.Getter; +import java.time.LocalDate; import java.time.LocalDateTime; @@ -18,14 +19,14 @@ public class CardResponseDto { private String description; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm") - LocalDateTime startAt; + @JsonFormat(pattern = "yyyy-MM-dd") + LocalDate startAt; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm") - LocalDateTime endAt; + @JsonFormat(pattern = "yyyy-MM-dd") + LocalDate endAt; - public CardResponseDto(Long cardListId, Long cardId, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + public CardResponseDto(Long cardListId, Long cardId, String title, String description, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.cardId = cardId; this.title = title; From 2263c52702cc6e6a2fcde8b09b6d858825a3b3d3 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 17:51:38 +0900 Subject: [PATCH 041/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EB=8B=A4=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 페이징을 제외한 카드 다건 조회 기능 구현 --- .../example/trello/card/CardController.java | 16 ++++++------ .../com/example/trello/card/CardService.java | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 7d352b7..6fd2746 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -7,11 +7,13 @@ import lombok.RequiredArgsConstructor; import org.hibernate.query.Page; import org.springframework.data.web.PageableDefault; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.awt.print.Pageable; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -48,12 +50,12 @@ public ResponseEntity findCard(@PathVariable Long cardsId) { return new ResponseEntity<>(responseDto, HttpStatus.OK); } - @PostMapping("/getCards") - public List getCards(@PageableDefault(page = 1)Pageable pageable, - @RequestParam(required = false) String title, - @RequestParam(required = false) LocalDateTime startAt, - @RequestParam(required = false) LocalDateTime endAt) { - return cardService.searchCards(title, startAt, endAt); + @GetMapping("/getCards") + public List getCards( + @RequestParam(required = false) Long cardListId, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startAt, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endAt, + @RequestParam(required = false) Long boardId) { + return cardService.searchCards(cardListId, startAt, endAt, boardId); } - } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 1d9da8a..92a2bfc 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -2,6 +2,7 @@ import com.example.trello.board.Board; import com.example.trello.card.cardrepository.CardRepository; +import com.example.trello.card.cardrepository.CardRepositoryCustomImpl; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; @@ -13,6 +14,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -22,6 +25,7 @@ public class CardService { private final CardRepository cardRepository; private final CardListRepository cardListRepository; + private final CardRepositoryCustomImpl cardRepositoryCustomImpl; // 카드 생성 public CardResponseDto createdCardService(CardRequestDto requestDto) { @@ -60,6 +64,27 @@ public CardResponseDto findCardById(Long cardsId) { return new CardResponseDto(card.getCardList().getId(), card.getId(), card.getTitle(), card.getDescription(), card.getStartAt(),card.getEndAt()); } + // 카드 다건 조회(조건 O) + public List searchCards(Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + + List cards = cardRepository.searchCard(cardListId, startAt, endAt, boardId); + + return convertToDto(cards); + } + + private List convertToDto(List cards) { + return cards.stream() + .map(card -> new CardResponseDto( + card.getCardList().getId(), + card.getId(), + card.getTitle(), + card.getDescription(), + card.getStartAt(), + card.getEndAt() + )) + .toList(); + } + // 카드 리스트id로 카드 리스트 찾는 메소드 From 3712d094d4418db5e805a3093f9ea72f57522343 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 19:33:37 +0900 Subject: [PATCH 042/181] =?UTF-8?q?refactor=20:=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=A9=A4=EB=B2=84=20Rep?= =?UTF-8?q?ository=20=EC=9D=98=20findByUserIdOrElseThrow=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit findByUserIdAndWorkspaceIdOrElseThrow 로 변경 --- .../com/example/trello/workspace/WorkspaceService.java | 9 +++------ .../workspace_member/WorkspaceMemberRepository.java | 2 +- .../trello/workspace_member/WorkspaceMemberService.java | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index e4ed1fe..7987d37 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -2,13 +2,11 @@ import com.example.trello.user.User; import com.example.trello.user.UserRepository; -import com.example.trello.workspace.dto.WorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceResponseDto; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; -import lombok.Builder; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,7 +16,6 @@ import java.util.List; import static com.example.trello.user.enums.Role.ADMIN; -import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @@ -72,7 +69,7 @@ public List viewAllWorkspace(Long loginUserId) { @Transactional(readOnly = true) public WorkspaceResponseDto viewWorkspace(Long workspaceId, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); Workspace workspace = findWorkspaceMember.getWorkspace(); @@ -81,7 +78,7 @@ public WorkspaceResponseDto viewWorkspace(Long workspaceId, Long loginUserId) { @Transactional public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, String description, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("워크스페이스를 수정할 권한이 없습니다."); @@ -96,7 +93,7 @@ public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, Stri @Transactional public void deleteWorkspace(Long workspaceId, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("워크스페이스를 삭제할 권한이 없습니다."); diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index 1780201..48a1fa9 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -16,7 +16,7 @@ default WorkspaceMember findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(() -> new RuntimeException()); } - default WorkspaceMember findByUserIdOrElseThrow(Long userId, Long workspaceId) { + default WorkspaceMember findByUserIdAndWorkspaceIdOrElseThrow(Long userId, Long workspaceId) { return findByUserIdAndWorkspaceId(userId, workspaceId).orElseThrow(() -> new RuntimeException()); } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 118a87c..3537582 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -25,7 +25,7 @@ public class WorkspaceMemberService { @Transactional public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String email, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("멤버를 초대할 권한이 없습니다."); @@ -47,7 +47,7 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String @Transactional public void updateWorkspaceMemberRole(Long workspaceId, Long workspaceMemberId , WorkspaceMemberRole role, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdOrElseThrow(loginUserId, workspaceId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (role == WORKSPACE && findWorkspaceMember.getUser().getRole() != ADMIN) { throw new RuntimeException("WORKSPACE 역할은 ADMIN 만 부여할 수 있습니다."); From 5444b997b53fbe8679f2c2446cd299c4cba3f484 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 19:46:09 +0900 Subject: [PATCH 043/181] =?UTF-8?q?feat=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/board/Board.java | 13 +++++- .../example/trello/board/BoardController.java | 23 ++++++++++ .../example/trello/board/BoardService.java | 43 +++++++++++++++++++ .../trello/board/dto/BoardRequestDto.java | 18 ++++++++ .../trello/board/dto/BoardResponseDto.java | 23 ++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/trello/board/BoardController.java create mode 100644 src/main/java/com/example/trello/board/BoardService.java create mode 100644 src/main/java/com/example/trello/board/dto/BoardRequestDto.java create mode 100644 src/main/java/com/example/trello/board/dto/BoardResponseDto.java diff --git a/src/main/java/com/example/trello/board/Board.java b/src/main/java/com/example/trello/board/Board.java index 3813008..83a40a6 100644 --- a/src/main/java/com/example/trello/board/Board.java +++ b/src/main/java/com/example/trello/board/Board.java @@ -3,6 +3,7 @@ import com.example.trello.cardlist.CardList; import com.example.trello.workspace.Workspace; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import java.util.List; @@ -15,7 +16,7 @@ public class Board { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "title") + @Column(name = "title", nullable = false) private String title; @Column(name = "color") @@ -30,4 +31,14 @@ public class Board { @OneToMany(mappedBy = "board", cascade = CascadeType.ALL, orphanRemoval = true) private List cardLists; + public Board() { + } + + @Builder + public Board(String title, String color, String image, Workspace workspace) { + this.title = title; + this.color = color; + this.image = image; + this.workspace = workspace; + } } diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java new file mode 100644 index 0000000..59866cf --- /dev/null +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -0,0 +1,23 @@ +package com.example.trello.board; + +import com.example.trello.board.dto.BoardRequestDto; +import com.example.trello.board.dto.BoardResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/boards") +public class BoardController { + private final BoardService boardService; + + @PostMapping + public ResponseEntity createBoard(@RequestBody BoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { + BoardResponseDto boardResponseDto = boardService.createBoard(dto.getWorkspaceId(), dto.getTitle(), dto.getColor(), dto.getImage(), loginUserId); + return new ResponseEntity<>(boardResponseDto, HttpStatus.CREATED); + } +} diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java new file mode 100644 index 0000000..e5fc2e5 --- /dev/null +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -0,0 +1,43 @@ +package com.example.trello.board; + +import com.example.trello.board.dto.BoardResponseDto; +import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_member.WorkspaceMember; +import com.example.trello.workspace_member.WorkspaceMemberRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; + +@Service +@RequiredArgsConstructor +public class BoardService { + private final BoardRepository boardRepository; + private final WorkspaceMemberRepository workspaceMemberRepository; + + @Transactional + public BoardResponseDto createBoard(Long workspaceId, String title, String color, String image, Long loginUserId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); + + if (findWorkspaceMember.getRole() == READ_ONLY) { + throw new RuntimeException("읽기 전용 역할은 보드를 생성할 수 없습니다."); + } + + Workspace workspace = findWorkspaceMember.getWorkspace(); + + Board board = Board.builder() + .title(title) + .color(color) + .image(image) + .workspace(workspace) + .build(); + + boardRepository.save(board); + + return BoardResponseDto.toDto(board); + } + +} diff --git a/src/main/java/com/example/trello/board/dto/BoardRequestDto.java b/src/main/java/com/example/trello/board/dto/BoardRequestDto.java new file mode 100644 index 0000000..b9af364 --- /dev/null +++ b/src/main/java/com/example/trello/board/dto/BoardRequestDto.java @@ -0,0 +1,18 @@ +package com.example.trello.board.dto; + +import lombok.Getter; + +@Getter +public class BoardRequestDto { + private String title; + private String color; + private String image; + private Long workspaceId; + + public BoardRequestDto(String title, String color, String image, Long workspaceId) { + this.title = title; + this.color = color; + this.image = image; + this.workspaceId = workspaceId; + } +} diff --git a/src/main/java/com/example/trello/board/dto/BoardResponseDto.java b/src/main/java/com/example/trello/board/dto/BoardResponseDto.java new file mode 100644 index 0000000..22a83cb --- /dev/null +++ b/src/main/java/com/example/trello/board/dto/BoardResponseDto.java @@ -0,0 +1,23 @@ +package com.example.trello.board.dto; + +import com.example.trello.board.Board; +import lombok.Getter; + +@Getter +public class BoardResponseDto { + private Long id; + private String title; + private String color; + private String image; + + public BoardResponseDto(Long id, String title, String color, String image) { + this.id = id; + this.title = title; + this.color = color; + this.image = image; + } + + public static BoardResponseDto toDto(Board board) { + return new BoardResponseDto(board.getId(), board.getTitle(), board.getColor(), board.getImage()); + } +} From b52ffb1a138be4c4876b927516c96cf8fe14da98 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Thu, 26 Dec 2024 20:31:55 +0900 Subject: [PATCH 044/181] =?UTF-8?q?feat=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 특정 워크스페이스의 보드 전체 조회 기능 구현 --- .../com/example/trello/board/BoardController.java | 7 +++++++ .../com/example/trello/board/BoardRepository.java | 3 +++ .../java/com/example/trello/board/BoardService.java | 13 +++++++++++++ .../trello/board/dto/viewAllBoardRequestDto.java | 12 ++++++++++++ .../workspace_member/WorkspaceMemberRepository.java | 1 + 5 files changed, 36 insertions(+) create mode 100644 src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 59866cf..7632307 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -2,6 +2,7 @@ import com.example.trello.board.dto.BoardRequestDto; import com.example.trello.board.dto.BoardResponseDto; +import com.example.trello.board.dto.viewAllBoardRequestDto; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,4 +21,10 @@ public ResponseEntity createBoard(@RequestBody BoardRequestDto BoardResponseDto boardResponseDto = boardService.createBoard(dto.getWorkspaceId(), dto.getTitle(), dto.getColor(), dto.getImage(), loginUserId); return new ResponseEntity<>(boardResponseDto, HttpStatus.CREATED); } + + @GetMapping + public ResponseEntity> viewAllBoard(@RequestBody viewAllBoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { + List boardResponseDtoList = boardService.viewAllBoard(dto.getWorkspaceId(), loginUserId); + return new ResponseEntity<>(boardResponseDtoList, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/board/BoardRepository.java b/src/main/java/com/example/trello/board/BoardRepository.java index cf06247..9f9f1ff 100644 --- a/src/main/java/com/example/trello/board/BoardRepository.java +++ b/src/main/java/com/example/trello/board/BoardRepository.java @@ -3,8 +3,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface BoardRepository extends JpaRepository { + List findAllByWorkspaceId(Long workspaceId); default Board findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(()->new RuntimeException()); diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index e5fc2e5..cd3d45f 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -40,4 +40,17 @@ public BoardResponseDto createBoard(Long workspaceId, String title, String color return BoardResponseDto.toDto(board); } + @Transactional(readOnly = true) + public List viewAllBoard(Long workspaceId, Long loginUserId) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(loginUserId, workspaceId)) { + throw new RuntimeException("해당 워크스페이스의 멤버가 아닙니다."); + } + + List findBoardList = boardRepository.findAllByWorkspaceId(workspaceId); + + return findBoardList + .stream() + .map(BoardResponseDto::toDto) + .toList(); + } } diff --git a/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java b/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java new file mode 100644 index 0000000..ecbee31 --- /dev/null +++ b/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java @@ -0,0 +1,12 @@ +package com.example.trello.board.dto; + +import lombok.Getter; + +@Getter +public class viewAllBoardRequestDto { + private Long workspaceId; + + public viewAllBoardRequestDto(Long workspaceId) { + this.workspaceId = workspaceId; + } +} diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index 48a1fa9..56ff64d 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -11,6 +11,7 @@ public interface WorkspaceMemberRepository extends JpaRepository { List findByUser(User user); Optional findByUserIdAndWorkspaceId(Long userId, Long workspaceId); + Boolean existsByUserIdAndWorkspaceId(Long userId, Long workspaceId); default WorkspaceMember findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(() -> new RuntimeException()); From e50578a570860dc7d6eaf56ac5a11acb70ffa398 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Thu, 26 Dec 2024 20:43:23 +0900 Subject: [PATCH 045/181] =?UTF-8?q?Fix=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1,=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=9D=B4=EB=A6=84=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 카드 생성시 현재 접속한 유저의 이름을 session에서 가져와 저장 카드 조회시 카드를 생성한 유저의 이름도 조회되도록 변경 --- src/main/java/com/example/trello/card/Card.java | 8 ++++++-- .../com/example/trello/card/CardController.java | 4 ++-- .../com/example/trello/card/CardService.java | 16 +++++++++++----- .../trello/card/responsedto/CardResponseDto.java | 5 ++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index b5b86c8..c8f5d3d 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -33,6 +33,9 @@ public class Card { @Column(name = "image") private String image; + @Column(name = "userName") + private String nikeName; + @Column(name = "start_at") private LocalDate startAt; @@ -45,12 +48,13 @@ public class Card { @OneToMany(mappedBy = "card",cascade = CascadeType.ALL,orphanRemoval = true) private List comments; - public Card(String title, String description, CardList cardList, LocalDate startAt, LocalDate endAt) { + public Card(String title, String description, String nikeName, LocalDate startAt, LocalDate endAt,CardList cardList) { this.title = title; this.description = description; - this.cardList = cardList; + this.nikeName = nikeName; this.startAt = startAt; this.endAt = endAt; + this.cardList = cardList; } public void updateCard(CardList cardList, String title, String description, LocalDate startAt, LocalDate endAt) { diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 6fd2746..83e9f96 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -27,8 +27,8 @@ public class CardController { private final CardService cardService; @PostMapping - public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto) { - CardResponseDto responseDto = cardService.createdCardService(requestDto); + public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto, HttpServletRequest servletRequest) { + CardResponseDto responseDto = cardService.createdCardService(requestDto, servletRequest); return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 92a2bfc..3a89884 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -8,6 +8,8 @@ import com.example.trello.card.requestDto.UpdateCardRequestDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; +import com.example.trello.user.User; +import com.example.trello.user.UserRepository; import com.example.trello.workspace.Workspace; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -26,16 +28,19 @@ public class CardService { private final CardRepository cardRepository; private final CardListRepository cardListRepository; private final CardRepositoryCustomImpl cardRepositoryCustomImpl; + private final UserRepository userRepository; // 카드 생성 - public CardResponseDto createdCardService(CardRequestDto requestDto) { + public CardResponseDto createdCardService(CardRequestDto requestDto, HttpServletRequest servletRequest) { + + User user = (User) servletRequest.getSession().getAttribute("id"); CardList cardList = findCardListByCardListId(requestDto.getCardListId()); - Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), cardList, requestDto.getStartAt(), requestDto.getEndAt()); + Card card = new Card(requestDto.getTitle(), requestDto.getDescription(),user.getNickname(), requestDto.getStartAt(), requestDto.getEndAt(), cardList); cardRepository.save(card); - return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(),user.getNickname(), requestDto.getStartAt(), requestDto.getEndAt()); } //카드 업데이트 @@ -48,7 +53,7 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque cardRepository.save(card); - return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), card.getNikeName(),requestDto.getStartAt(), requestDto.getEndAt()); } // 카드 삭제 @@ -61,7 +66,7 @@ public void deleteCardService(Long cardId) { // 카드 단건 조회 public CardResponseDto findCardById(Long cardsId) { Card card = cardRepository.findByIdOrElseThrow(cardsId); - return new CardResponseDto(card.getCardList().getId(), card.getId(), card.getTitle(), card.getDescription(), card.getStartAt(),card.getEndAt()); + return new CardResponseDto(card.getCardList().getId(), card.getId(), card.getTitle(), card.getDescription(), card.getNikeName(), card.getStartAt(),card.getEndAt()); } // 카드 다건 조회(조건 O) @@ -79,6 +84,7 @@ private List convertToDto(List cards) { card.getId(), card.getTitle(), card.getDescription(), + card.getNikeName(), card.getStartAt(), card.getEndAt() )) diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index 776ba34..da1f8e5 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -19,6 +19,8 @@ public class CardResponseDto { private String description; + private String nikeName; + @JsonFormat(pattern = "yyyy-MM-dd") LocalDate startAt; @@ -26,11 +28,12 @@ public class CardResponseDto { LocalDate endAt; - public CardResponseDto(Long cardListId, Long cardId, String title, String description, LocalDate startAt, LocalDate endAt) { + public CardResponseDto(Long cardListId, Long cardId, String title, String description, String nikeName, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.cardId = cardId; this.title = title; this.description = description; + this.nikeName = nikeName; this.startAt = startAt; this.endAt =endAt; } From 826f304354d72b5bc12444bbf3aa5037427c9b0c Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Thu, 26 Dec 2024 21:04:45 +0900 Subject: [PATCH 046/181] =?UTF-8?q?fix=20:=20=EA=B0=81=20=EC=9A=94?= =?UTF-8?q?=EA=B5=AC=20=EC=82=AC=ED=95=AD=EC=97=90=20=EB=A7=9E=EB=8A=94=20?= =?UTF-8?q?Update,=20Delete=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/cardlist/CardList.java | 25 ++++----- .../trello/cardlist/CardListController.java | 26 +++++---- .../trello/cardlist/CardListRepository.java | 14 +++-- .../trello/cardlist/CardListService.java | 54 +++++++++++++++---- ...ponseDto.java => CardListResponseDto.java} | 2 +- ...Dto.java => UpdateCardListRequestDto.java} | 2 +- 6 files changed, 83 insertions(+), 40 deletions(-) rename src/main/java/com/example/trello/cardlist/dto/{CreateCardListResponseDto.java => CardListResponseDto.java} (79%) rename src/main/java/com/example/trello/cardlist/dto/{CardListRequestDto.java => UpdateCardListRequestDto.java} (77%) diff --git a/src/main/java/com/example/trello/cardlist/CardList.java b/src/main/java/com/example/trello/cardlist/CardList.java index 32ad722..80befed 100644 --- a/src/main/java/com/example/trello/cardlist/CardList.java +++ b/src/main/java/com/example/trello/cardlist/CardList.java @@ -2,13 +2,10 @@ import com.example.trello.board.Board; import com.example.trello.card.Card; -import com.example.trello.cardlist.dto.CardListRequestDto; -import com.example.trello.cardlist.dto.CreateCardListResponseDto; +import com.example.trello.cardlist.dto.UpdateCardListRequestDto; +import com.example.trello.cardlist.dto.CardListResponseDto; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import java.util.List; @@ -25,7 +22,7 @@ public class CardList { @Column(name = "title") private String title; - + @Setter @Column(name = "sequence") private Integer sequence; @@ -35,21 +32,25 @@ public class CardList { @OneToMany(mappedBy = "cardList", cascade = CascadeType.ALL, orphanRemoval = true) private List cards; - public static CreateCardListResponseDto toDto(CardList cardList) { - return CreateCardListResponseDto.builder() + public static CardListResponseDto toDto(CardList cardList) { + return CardListResponseDto.builder() .id(cardList.getId()) .sequence(cardList.sequence) .build(); } - public void update(CardListRequestDto requestDto,Integer sequence ) { + public void update(UpdateCardListRequestDto requestDto, Integer sequence ) { this.title = requestDto.getTitle(); this.sequence = sequence; } - public void sortSequence(Integer sequence) { - this.sequence=sequence-1; + public void downSequence() { + this.sequence--; + } + + public void upSequence() { + this.sequence++; } public void updateSequence(Integer sequence) { diff --git a/src/main/java/com/example/trello/cardlist/CardListController.java b/src/main/java/com/example/trello/cardlist/CardListController.java index 2aa8b41..14cd9f1 100644 --- a/src/main/java/com/example/trello/cardlist/CardListController.java +++ b/src/main/java/com/example/trello/cardlist/CardListController.java @@ -1,8 +1,8 @@ package com.example.trello.cardlist; -import com.example.trello.cardlist.dto.CardListRequestDto; +import com.example.trello.cardlist.dto.UpdateCardListRequestDto; import com.example.trello.cardlist.dto.CreateCardListRequestDto; -import com.example.trello.cardlist.dto.CreateCardListResponseDto; +import com.example.trello.cardlist.dto.CardListResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,21 +16,27 @@ public class CardListController { private final CardListService cardListService; @PostMapping - public ResponseEntity createCardList(@RequestBody CreateCardListRequestDto requestDto) { - CreateCardListResponseDto createCardListResponseDto = cardListService.create(requestDto); - return new ResponseEntity<>(createCardListResponseDto, HttpStatus.CREATED); + public ResponseEntity createCardList(@RequestBody CreateCardListRequestDto requestDto) { + CardListResponseDto cardListResponseDto = cardListService.create(requestDto); + return new ResponseEntity<>(cardListResponseDto, HttpStatus.CREATED); } @GetMapping("/{id}") - public ResponseEntity findCardList(@PathVariable Long id) { - CreateCardListResponseDto cardListResponseDto = cardListService.findCardList(id); + public ResponseEntity findCardList(@PathVariable Long id) { + CardListResponseDto cardListResponseDto = cardListService.findCardList(id); return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); } @PatchMapping("/{id}") - public ResponseEntity updateCardList(@PathVariable Long id, @RequestBody CardListRequestDto requestDto) { - CreateCardListResponseDto createCardListResponseDto = cardListService.update(id, requestDto); - return new ResponseEntity<>(createCardListResponseDto, HttpStatus.OK); + public ResponseEntity updateCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto) { + CardListResponseDto cardListResponseDto = cardListService.moveSequence(id, requestDto); + return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); + + } + @PatchMapping("/{id}/exchange") + public ResponseEntity swapCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto) { + CardListResponseDto cardListResponseDto = cardListService.swapSequence(id, requestDto); + return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/cardlist/CardListRepository.java b/src/main/java/com/example/trello/cardlist/CardListRepository.java index 4069c25..07ccd36 100644 --- a/src/main/java/com/example/trello/cardlist/CardListRepository.java +++ b/src/main/java/com/example/trello/cardlist/CardListRepository.java @@ -2,8 +2,10 @@ 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 @@ -12,13 +14,15 @@ public interface CardListRepository extends JpaRepository { default CardList findByIdOrElseThrow(Long id) { return findById(id).orElseThrow(() -> new RuntimeException()); } - @Query(value = "select MAX(sequence)from card_list ",nativeQuery = true) - Optional findByMax(); + @Query(value = "select max(cardlist.sequence)from CardList cardlist where cardlist.board.id = :board_id" ) + Optional findByMax(@Param("board_id") Long board_id); - Optional findBySequence(Integer sequence); + Optional findBySequenceAndBoardId(Integer sequence,Long boardId); - default CardList findBySequenceOrElseThrow(Integer sequence){ - return findBySequence(sequence).orElseThrow(()->new RuntimeException()); + default CardList findBySequenceAndBoardIdOrElseThrow(Integer sequence,Long boardId){ + return findBySequenceAndBoardId(sequence,boardId).orElseThrow(()->new RuntimeException()); } + List findAllByBoardId(Long boardId); + } diff --git a/src/main/java/com/example/trello/cardlist/CardListService.java b/src/main/java/com/example/trello/cardlist/CardListService.java index fad5bed..d25c3b4 100644 --- a/src/main/java/com/example/trello/cardlist/CardListService.java +++ b/src/main/java/com/example/trello/cardlist/CardListService.java @@ -2,9 +2,9 @@ import com.example.trello.board.Board; import com.example.trello.board.BoardRepository; -import com.example.trello.cardlist.dto.CardListRequestDto; +import com.example.trello.cardlist.dto.UpdateCardListRequestDto; import com.example.trello.cardlist.dto.CreateCardListRequestDto; -import com.example.trello.cardlist.dto.CreateCardListResponseDto; +import com.example.trello.cardlist.dto.CardListResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,28 +18,57 @@ public class CardListService { private final CardListRepository cardListRepository; private final BoardRepository boardRepository; - private static Integer MAX_SEQUENCE; + private Integer maxSequence; // 보드에서 가장 큰 순서 @Transactional - public CreateCardListResponseDto create(CreateCardListRequestDto requestDto) { + public CardListResponseDto create(CreateCardListRequestDto requestDto) { Board board = boardRepository.findByIdOrElseThrow(requestDto.getBoardId()); - MAX_SEQUENCE = cardListRepository.findByMax().orElse(0); - CardList cardList = requestDto.toEntity(requestDto, board, ++MAX_SEQUENCE); + maxSequence = cardListRepository.findByMax(board.getId()).orElse(0); + CardList cardList = requestDto.toEntity(requestDto, board, ++maxSequence); CardList savedCardList = cardListRepository.save(cardList); return CardList.toDto(savedCardList); } - public CreateCardListResponseDto findCardList(Long id) { + public CardListResponseDto findCardList(Long id) { //todo dto 이름 바꾸기 CardList cardList = cardListRepository.findByIdOrElseThrow(id); return CardList.toDto(cardList); } @Transactional - public CreateCardListResponseDto update(Long id, CardListRequestDto requestDto) { + public CardListResponseDto moveSequence(Long id, UpdateCardListRequestDto requestDto) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); - CardList exchangeCardList = cardListRepository.findBySequenceOrElseThrow(requestDto.getSequence()); + Integer currentSequence=cardList.getSequence(); + + List cardLists = cardListRepository.findAllByBoardId(cardList.getBoard().getId()); + + if(currentSequence!=requestDto.getSequence()) { + if(currentSequencee.getSequence()>currentSequence) + .filter(e->e.getSequence()<=requestDto.getSequence()) + .forEach(e->e.downSequence()); + }else { + cardLists.stream() + .filter(e->e.getSequence()e.getSequence()>=requestDto.getSequence()) + .forEach(e->e.upSequence()); + } + } + + if (requestDto.getSequence()>cardLists.size()){ + + throw new RuntimeException(); + } + + return CardList.toDto(cardList); + } + + @Transactional + public CardListResponseDto swapSequence(Long id, UpdateCardListRequestDto requestDto) { + CardList cardList = cardListRepository.findByIdOrElseThrow(id); + CardList exchangeCardList = cardListRepository.findBySequenceAndBoardIdOrElseThrow(requestDto.getSequence(),cardList.getBoard().getId()); Integer temp = cardList.getSequence(); cardList.update(requestDto, exchangeCardList.getSequence()); exchangeCardList.updateSequence(temp); @@ -47,15 +76,18 @@ public CreateCardListResponseDto update(Long id, CardListRequestDto requestDto) return CardList.toDto(cardList); } + @Transactional public void delete(Long id) { + CardList cardList = cardListRepository.findByIdOrElseThrow(id); + Board board = boardRepository.findByIdOrElseThrow(cardList.getBoard().getId()); Integer deleteSequence = cardList.getSequence(); cardListRepository.delete(cardList); - List cardLists = cardListRepository.findAll(); + List cardLists = cardListRepository.findAllByBoardId(board.getId()); for (CardList list : cardLists) { if (list.getSequence() > deleteSequence) { - list.sortSequence(list.getSequence()); + list.downSequence(); } } } diff --git a/src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java b/src/main/java/com/example/trello/cardlist/dto/CardListResponseDto.java similarity index 79% rename from src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java rename to src/main/java/com/example/trello/cardlist/dto/CardListResponseDto.java index e192a88..b9d0ae5 100644 --- a/src/main/java/com/example/trello/cardlist/dto/CreateCardListResponseDto.java +++ b/src/main/java/com/example/trello/cardlist/dto/CardListResponseDto.java @@ -5,7 +5,7 @@ @Getter @Builder -public class CreateCardListResponseDto { +public class CardListResponseDto { private Long id; diff --git a/src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java b/src/main/java/com/example/trello/cardlist/dto/UpdateCardListRequestDto.java similarity index 77% rename from src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java rename to src/main/java/com/example/trello/cardlist/dto/UpdateCardListRequestDto.java index f83c789..19c95ae 100644 --- a/src/main/java/com/example/trello/cardlist/dto/CardListRequestDto.java +++ b/src/main/java/com/example/trello/cardlist/dto/UpdateCardListRequestDto.java @@ -3,7 +3,7 @@ import lombok.Getter; @Getter -public class CardListRequestDto { +public class UpdateCardListRequestDto { private String title; From 093a0018333166002c8ea9660660369961593df2 Mon Sep 17 00:00:00 2001 From: jut Date: Fri, 27 Dec 2024 09:25:45 +0900 Subject: [PATCH 047/181] =?UTF-8?q?fix=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20DTO=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/user/dto/LoginRequestDto.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/user/dto/LoginRequestDto.java b/src/main/java/com/example/trello/user/dto/LoginRequestDto.java index 0839a0b..d89de7e 100644 --- a/src/main/java/com/example/trello/user/dto/LoginRequestDto.java +++ b/src/main/java/com/example/trello/user/dto/LoginRequestDto.java @@ -13,7 +13,7 @@ public class LoginRequestDto { private final String email; @NotBlank(message = "비밀번호는 필수값 입니다.") - @Pattern(regexp = "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$._+]).{8,16}$" , message = "비밀번호는 대문자 + 소문자 + 숫자 + 특수문자를 최소 1글자씩 입려해주세요") + @Pattern(regexp = "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$._+]).{8,16}$" , message = "비밀번호는 대문자 + 소문자 + 숫자 + 특수문자를 최소 1글자씩 입력해주세요") private final String password; @Builder From 3c5525597b85f8042081d8eeaff8d264f1fecb47 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 10:31:52 +0900 Subject: [PATCH 048/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EB=8B=A4=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=95=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 카드 다건 조회시 10개씩 페이징되어 출력되도록 적용 --- .../example/trello/card/CardController.java | 7 ++-- .../com/example/trello/card/CardService.java | 38 +++++++++++-------- .../cardrepository/CardRepositoryCustom.java | 7 +++- .../CardRepositoryCustomImpl.java | 29 ++++++++++++-- .../trello/card/requestDto/CardListDto.java | 21 ++++++++++ .../card/responsedto/CardResponseDto.java | 12 ++++++ 6 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/example/trello/card/requestDto/CardListDto.java diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 83e9f96..b970a05 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -1,5 +1,6 @@ package com.example.trello.card; +import com.example.trello.card.requestDto.CardListDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; @@ -17,7 +18,6 @@ import java.time.LocalDateTime; import java.util.List; -//import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.title; @RequiredArgsConstructor @RestController @@ -51,11 +51,12 @@ public ResponseEntity findCard(@PathVariable Long cardsId) { } @GetMapping("/getCards") - public List getCards( + public ResponseEntity getCards(@RequestParam(defaultValue = "0") int page, @RequestParam(required = false) Long cardListId, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startAt, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endAt, @RequestParam(required = false) Long boardId) { - return cardService.searchCards(cardListId, startAt, endAt, boardId); + CardListDto cards = cardService.searchCards(page, cardListId, startAt, endAt, boardId); + return new ResponseEntity<>(cards, HttpStatus.OK); } } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 3a89884..c0a338c 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -3,6 +3,7 @@ import com.example.trello.board.Board; import com.example.trello.card.cardrepository.CardRepository; import com.example.trello.card.cardrepository.CardRepositoryCustomImpl; +import com.example.trello.card.requestDto.CardListDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; @@ -13,12 +14,16 @@ import com.example.trello.workspace.Workspace; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; +import java.awt.print.Pageable; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.Dictionary; import java.util.List; @Service @@ -70,26 +75,27 @@ public CardResponseDto findCardById(Long cardsId) { } // 카드 다건 조회(조건 O) - public List searchCards(Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + public CardListDto searchCards(int page ,Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); - List cards = cardRepository.searchCard(cardListId, startAt, endAt, boardId); + CardListDto cards = cardRepository.searchCard(pageRequest, cardListId, startAt, endAt, boardId); - return convertToDto(cards); + return cards; } - private List convertToDto(List cards) { - return cards.stream() - .map(card -> new CardResponseDto( - card.getCardList().getId(), - card.getId(), - card.getTitle(), - card.getDescription(), - card.getNikeName(), - card.getStartAt(), - card.getEndAt() - )) - .toList(); - } +// private CardListDto convertToDto(List cards) { +// return cards.stream() +// .map(card -> new CardResponseDto( +// card.getCardList().getId(), +// card.getId(), +// card.getTitle(), +// card.getDescription(), +// card.getNikeName(), +// card.getStartAt(), +// card.getEndAt() +// )) +// .toList(); +// } diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java index 8cfe3b0..7dbea6c 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java @@ -1,11 +1,16 @@ package com.example.trello.card.cardrepository; import com.example.trello.card.Card; +import com.example.trello.card.requestDto.CardListDto; +import com.example.trello.card.responsedto.CardResponseDto; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import java.awt.print.Pageable; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; public interface CardRepositoryCustom { - List searchCard(Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); + CardListDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); } diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java index c0ff75d..5fa3e1e 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java @@ -2,12 +2,18 @@ import com.example.trello.card.Card; import com.example.trello.card.QCard; +import com.example.trello.card.requestDto.CardListDto; +import com.example.trello.card.responsedto.CardResponseDto; import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.RequestParam; +import java.awt.print.Pageable; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -19,18 +25,32 @@ public class CardRepositoryCustomImpl implements CardRepositoryCustom{ private final JPAQueryFactory queryFactory; @Override - public List searchCard(Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + public CardListDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { QCard card = QCard.card; - return queryFactory + + List cardList = queryFactory .selectFrom(card) .where( eqCardListId(cardListId), eqStartAt(startAt), eqEndAt(endAt), - eqBoard(boardId) - ) + eqBoard(boardId)) + .offset(pageRequest.getOffset()) + .limit(pageRequest.getPageSize()) .fetch(); + + Long count = queryFactory + .select(card.count()) + .from(card) + .where( + eqCardListId(cardListId), + eqStartAt(startAt), + eqEndAt(endAt), + eqBoard(boardId)) + .fetchOne(); + return new CardListDto(cardList,count); + } private BooleanExpression eqCardListId(Long cardListId) { @@ -48,4 +68,5 @@ private BooleanExpression eqEndAt(LocalDate endAt) { private BooleanExpression eqBoard(Long boardId) { return boardId != null ? QCard.card.cardList.board.id.eq(boardId) : null; } + } diff --git a/src/main/java/com/example/trello/card/requestDto/CardListDto.java b/src/main/java/com/example/trello/card/requestDto/CardListDto.java new file mode 100644 index 0000000..cc52cef --- /dev/null +++ b/src/main/java/com/example/trello/card/requestDto/CardListDto.java @@ -0,0 +1,21 @@ +package com.example.trello.card.requestDto; + +import com.example.trello.card.Card; +import com.example.trello.card.responsedto.CardResponseDto; +import lombok.Getter; + +import java.util.List; + +@Getter +public class CardListDto { + + private List cardList; + private Long count; + + public CardListDto(List cardList, Long count) { + this.cardList = cardList.stream() + .map(card -> new CardResponseDto(card)) + .toList(); + this.count = count; + } +} diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index da1f8e5..efaafb8 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -1,5 +1,6 @@ package com.example.trello.card.responsedto; +import com.example.trello.card.Card; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.persistence.Column; import lombok.Getter; @@ -11,6 +12,7 @@ @Getter public class CardResponseDto { + private Long cardListId; private Long cardId; @@ -37,4 +39,14 @@ public CardResponseDto(Long cardListId, Long cardId, String title, String descri this.startAt = startAt; this.endAt =endAt; } + + public CardResponseDto(Card card) { + this.cardListId = card.getCardList().getId(); + this.cardId = card.getId(); + this.title = card.getTitle(); + this.description = card.getDescription(); + this.nikeName = card.getNikeName(); + this.startAt = card.getStartAt(); + this.endAt =card.getEndAt(); + } } From d81d8ae8cc137e4d97081b7da4554c7c095557cb Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 11:21:25 +0900 Subject: [PATCH 049/181] =?UTF-8?q?feat=20:=20=EB=8B=A8=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=B4=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 단일 보드 조회시 보드에 속해있는 카드리스트, 카드를 전부 조회가능 --- .../example/trello/board/BoardController.java | 7 +++++ .../example/trello/board/BoardService.java | 31 +++++++++++++++++++ .../board/dto/BoardDetailResponseDto.java | 29 +++++++++++++++++ .../example/trello/card/CardRepository.java | 4 +++ .../trello/card/dto/GetCardResponseDto.java | 30 ++++++++++++++++++ .../trello/cardlist/CardListRepository.java | 3 ++ .../cardlist/dto/GetCardListResponseDto.java | 27 ++++++++++++++++ 7 files changed, 131 insertions(+) create mode 100644 src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java create mode 100644 src/main/java/com/example/trello/card/dto/GetCardResponseDto.java create mode 100644 src/main/java/com/example/trello/cardlist/dto/GetCardListResponseDto.java diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 7632307..1e3c0fa 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -1,5 +1,6 @@ package com.example.trello.board; +import com.example.trello.board.dto.BoardDetailResponseDto; import com.example.trello.board.dto.BoardRequestDto; import com.example.trello.board.dto.BoardResponseDto; import com.example.trello.board.dto.viewAllBoardRequestDto; @@ -27,4 +28,10 @@ public ResponseEntity> viewAllBoard(@RequestBody viewAllB List boardResponseDtoList = boardService.viewAllBoard(dto.getWorkspaceId(), loginUserId); return new ResponseEntity<>(boardResponseDtoList, HttpStatus.OK); } + + @GetMapping("/{boardId}") + public ResponseEntity viewBoard(@PathVariable Long boardId, @SessionAttribute("id") Long loginUserId) { + BoardDetailResponseDto boardDetailResponseDto = boardService.viewBoard(boardId, loginUserId); + return new ResponseEntity<>(boardDetailResponseDto, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index cd3d45f..9860ad0 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -1,6 +1,13 @@ package com.example.trello.board; +import com.example.trello.board.dto.BoardDetailResponseDto; import com.example.trello.board.dto.BoardResponseDto; +import com.example.trello.card.Card; +import com.example.trello.card.CardRepository; +import com.example.trello.card.dto.GetCardResponseDto; +import com.example.trello.cardlist.CardList; +import com.example.trello.cardlist.CardListRepository; +import com.example.trello.cardlist.dto.GetCardListResponseDto; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; @@ -8,6 +15,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; @@ -17,6 +25,8 @@ public class BoardService { private final BoardRepository boardRepository; private final WorkspaceMemberRepository workspaceMemberRepository; + private final CardListRepository cardListRepository; + private final CardRepository cardRepository; @Transactional public BoardResponseDto createBoard(Long workspaceId, String title, String color, String image, Long loginUserId) { @@ -53,4 +63,25 @@ public List viewAllBoard(Long workspaceId, Long loginUserId) { .map(BoardResponseDto::toDto) .toList(); } + + @Transactional(readOnly = true) + public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { + Board findBoard = boardRepository.findByIdOrElseThrow(boardId); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(loginUserId, findBoard.getWorkspace().getId())) { + throw new RuntimeException("해당 워크스페이스의 멤버가 아닙니다."); + } + + List findCardLists = cardListRepository.findByBoard(findBoard); + List getCardListResponseDtoList = new ArrayList<>(); + + for (CardList cardList : findCardLists) { + List findCards = cardRepository.findByCardList(cardList); + List getCardResponseDtoList = findCards.stream().map(GetCardResponseDto::toDto).toList(); + GetCardListResponseDto getCardListResponseDto = GetCardListResponseDto.toDto(cardList, getCardResponseDtoList); + getCardListResponseDtoList.add(getCardListResponseDto); + } + + return BoardDetailResponseDto.toDto(findBoard, getCardListResponseDtoList); + } } diff --git a/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java b/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java new file mode 100644 index 0000000..d6af99c --- /dev/null +++ b/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java @@ -0,0 +1,29 @@ +package com.example.trello.board.dto; + +import com.example.trello.board.Board; +import com.example.trello.cardlist.CardList; +import com.example.trello.cardlist.dto.GetCardListResponseDto; +import lombok.Getter; + +import java.util.List; + +@Getter +public class BoardDetailResponseDto { + private Long id; + private String title; + private String color; + private String image; + private List cardList; + + public BoardDetailResponseDto(Long id, String title, String color, String image, List cardList) { + this.id = id; + this.title = title; + this.color = color; + this.image = image; + this.cardList = cardList; + } + + public static BoardDetailResponseDto toDto(Board board, List cardList) { + return new BoardDetailResponseDto(board.getId(), board.getTitle(), board.getImage(), board.getColor(), cardList); + } +} diff --git a/src/main/java/com/example/trello/card/CardRepository.java b/src/main/java/com/example/trello/card/CardRepository.java index 1e6c533..0aaee3e 100644 --- a/src/main/java/com/example/trello/card/CardRepository.java +++ b/src/main/java/com/example/trello/card/CardRepository.java @@ -1,11 +1,15 @@ package com.example.trello.card; import com.example.trello.board.Board; +import com.example.trello.cardlist.CardList; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface CardRepository extends JpaRepository { + List findByCardList(CardList cardList); default Card findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(()->new RuntimeException()); diff --git a/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java b/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java new file mode 100644 index 0000000..76edb41 --- /dev/null +++ b/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java @@ -0,0 +1,30 @@ +package com.example.trello.card.dto; + +import com.example.trello.card.Card; +import com.example.trello.cardlist.CardList; +import com.example.trello.cardlist.dto.GetCardListResponseDto; +import lombok.Getter; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +public class GetCardResponseDto { + private Long id; + private String title; + private String description; + private LocalDateTime startAt; + private LocalDateTime endAt; + + public GetCardResponseDto(Long id, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + this.id = id; + this.title = title; + this.description = description; + this.startAt = startAt; + this.endAt = endAt; + } + + public static GetCardResponseDto toDto(Card card) { + return new GetCardResponseDto(card.getId(), card.getTitle(), card.getDescription(), card.getStartAt(), card.getEndAt()); + } +} diff --git a/src/main/java/com/example/trello/cardlist/CardListRepository.java b/src/main/java/com/example/trello/cardlist/CardListRepository.java index 4069c25..ab84587 100644 --- a/src/main/java/com/example/trello/cardlist/CardListRepository.java +++ b/src/main/java/com/example/trello/cardlist/CardListRepository.java @@ -1,13 +1,16 @@ package com.example.trello.cardlist; +import com.example.trello.board.Board; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository public interface CardListRepository extends JpaRepository { + List findByBoard(Board board); default CardList findByIdOrElseThrow(Long id) { return findById(id).orElseThrow(() -> new RuntimeException()); diff --git a/src/main/java/com/example/trello/cardlist/dto/GetCardListResponseDto.java b/src/main/java/com/example/trello/cardlist/dto/GetCardListResponseDto.java new file mode 100644 index 0000000..372072f --- /dev/null +++ b/src/main/java/com/example/trello/cardlist/dto/GetCardListResponseDto.java @@ -0,0 +1,27 @@ +package com.example.trello.cardlist.dto; + +import com.example.trello.card.Card; +import com.example.trello.card.dto.GetCardResponseDto; +import com.example.trello.cardlist.CardList; +import lombok.Getter; + +import java.util.List; + +@Getter +public class GetCardListResponseDto { + private Long id; + private String title; + private Integer sequence; + private List card; + + public GetCardListResponseDto(Long id, String title, Integer sequence, List card) { + this.id = id; + this.title = title; + this.sequence = sequence; + this.card = card; + } + + public static GetCardListResponseDto toDto(CardList cardList, List card) { + return new GetCardListResponseDto(cardList.getId(), cardList.getTitle(), cardList.getSequence(), card); + } +} From 79c5d8086e7faaf63744ed2e631fa3c1e0ca97d5 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 11:51:20 +0900 Subject: [PATCH 050/181] =?UTF-8?q?Feat=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=97=90=20=EC=82=AC=EC=9A=A9=ED=95=A0=20Dto?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 댓글 생성시 사용하는 Request, Response Dto 생성 --- .../dto/request/CommentRequestDto.java | 19 +++++++++++++ .../dto/response/CommentResponseDto.java | 27 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java create mode 100644 src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java diff --git a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java new file mode 100644 index 0000000..1a01b88 --- /dev/null +++ b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java @@ -0,0 +1,19 @@ +package com.example.trello.comment.dto.request; + +import lombok.Getter; + +@Getter +public class CommentRequestDto { + + private String content; + + private Long cardId; + + private Long userId; + + public CommentRequestDto(String content, Long cardId, Long userId) { + this.content = content; + this.cardId = cardId; + this.userId = userId; + } +} diff --git a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java new file mode 100644 index 0000000..e599a0c --- /dev/null +++ b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java @@ -0,0 +1,27 @@ +package com.example.trello.comment.dto.response; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class CommentResponseDto { + + private Long commentId; + + private String content; + + private String nikeName; + + private Long cardId; + + private Long userId; + + public CommentResponseDto(Long commentId, String content, String nikeName, Long cardId, Long userId) { + this.commentId = commentId; + this.content = content; + this.nikeName = nikeName; + this.cardId = cardId; + this.userId = userId; + } +} From 8463cbeafc69a480070b1294f23830809704824a Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 11:53:19 +0900 Subject: [PATCH 051/181] =?UTF-8?q?Feat=20:=20=ED=95=84=EB=93=9C,=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90,=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 닉네임 필드와 생성자 추가, @DynamicInsert, @RequiredArgsConstructor 어노테이션 추가 --- .../java/com/example/trello/comment/Comment.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/example/trello/comment/Comment.java b/src/main/java/com/example/trello/comment/Comment.java index 2c00cb2..aad41a2 100644 --- a/src/main/java/com/example/trello/comment/Comment.java +++ b/src/main/java/com/example/trello/comment/Comment.java @@ -4,9 +4,13 @@ import com.example.trello.user.User; import jakarta.persistence.*; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.hibernate.annotations.DynamicInsert; @Entity @Getter +@DynamicInsert +@RequiredArgsConstructor public class Comment { @Id @@ -16,10 +20,20 @@ public class Comment { @Column(name = "content") private String content; + @Column(name = "nikeName") + private String nikeName; + @ManyToOne(fetch = FetchType.LAZY) private Card card; @ManyToOne(fetch = FetchType.LAZY) private User user; + public Comment(String content, String nikeName, Card card, User user) { + this.content = content; + this.nikeName = nikeName; + this.card = card; + this.user = user; + } + } From f3bd2ae2a5b8cd9698333ecda893dff5c7813701 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 11:53:21 +0900 Subject: [PATCH 052/181] =?UTF-8?q?feat=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/board/Board.java | 6 ++++++ .../example/trello/board/BoardController.java | 11 +++++++---- .../com/example/trello/board/BoardService.java | 14 ++++++++++++++ .../trello/board/dto/BoardDetailResponseDto.java | 2 +- .../trello/board/dto/UpdateBoardRequestDto.java | 16 ++++++++++++++++ .../WorkspaceMemberRepository.java | 2 +- .../dto/WorkspaceMemberResponseDto.java | 4 ++-- 7 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java diff --git a/src/main/java/com/example/trello/board/Board.java b/src/main/java/com/example/trello/board/Board.java index 83a40a6..27349ff 100644 --- a/src/main/java/com/example/trello/board/Board.java +++ b/src/main/java/com/example/trello/board/Board.java @@ -41,4 +41,10 @@ public Board(String title, String color, String image, Workspace workspace) { this.image = image; this.workspace = workspace; } + + public void updateBoard(String title, String color, String image) { + this.title = title; + this.color = color; + this.image = image; + } } diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 1e3c0fa..f3cd618 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -1,9 +1,6 @@ package com.example.trello.board; -import com.example.trello.board.dto.BoardDetailResponseDto; -import com.example.trello.board.dto.BoardRequestDto; -import com.example.trello.board.dto.BoardResponseDto; -import com.example.trello.board.dto.viewAllBoardRequestDto; +import com.example.trello.board.dto.*; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -34,4 +31,10 @@ public ResponseEntity viewBoard(@PathVariable Long board BoardDetailResponseDto boardDetailResponseDto = boardService.viewBoard(boardId, loginUserId); return new ResponseEntity<>(boardDetailResponseDto, HttpStatus.OK); } + + @PatchMapping("/{boardId}") + public ResponseEntity updateBoard(@PathVariable Long boardId, @RequestBody UpdateBoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { + BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto.getTitle(), dto.getColor(), dto.getImage(), loginUserId); + return new ResponseEntity<>(updatedBoardResponseDto, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 9860ad0..ebf15ba 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -84,4 +84,18 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { return BoardDetailResponseDto.toDto(findBoard, getCardListResponseDtoList); } + + @Transactional + public BoardResponseDto updateBoard(Long boardId, String title, String color, String image, Long loginUserId) { + Board findBoard = boardRepository.findByIdOrElseThrow(boardId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); + + if (findWorkspaceMember.getRole() == READ_ONLY) { + throw new RuntimeException("읽기 전용 역할은 보드를 수정할 수 없습니다."); + } + + findBoard.updateBoard(title, color, image); + + return BoardResponseDto.toDto(findBoard); + } } diff --git a/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java b/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java index d6af99c..fa1383e 100644 --- a/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java @@ -24,6 +24,6 @@ public BoardDetailResponseDto(Long id, String title, String color, String image, } public static BoardDetailResponseDto toDto(Board board, List cardList) { - return new BoardDetailResponseDto(board.getId(), board.getTitle(), board.getImage(), board.getColor(), cardList); + return new BoardDetailResponseDto(board.getId(), board.getTitle(), board.getColor(), board.getImage(), cardList); } } diff --git a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java new file mode 100644 index 0000000..25e62c4 --- /dev/null +++ b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java @@ -0,0 +1,16 @@ +package com.example.trello.board.dto; + +import lombok.Getter; + +@Getter +public class UpdateBoardRequestDto { + private String title; + private String color; + private String image; + + public UpdateBoardRequestDto(String title, String color, String image) { + this.title = title; + this.color = color; + this.image = image; + } +} diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index 56ff64d..125f7d0 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -18,6 +18,6 @@ default WorkspaceMember findByIdOrElseThrow(Long id){ } default WorkspaceMember findByUserIdAndWorkspaceIdOrElseThrow(Long userId, Long workspaceId) { - return findByUserIdAndWorkspaceId(userId, workspaceId).orElseThrow(() -> new RuntimeException()); + return findByUserIdAndWorkspaceId(userId, workspaceId).orElseThrow(() -> new RuntimeException("해당 워크스페이스의 멤버가 아닙니다.")); } } diff --git a/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java index 90149a7..5419efd 100644 --- a/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java +++ b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberResponseDto.java @@ -10,9 +10,9 @@ public class WorkspaceMemberResponseDto { private Long workspaceId; private WorkspaceMemberRole role; - public WorkspaceMemberResponseDto(Long workspaceId, Long userId, WorkspaceMemberRole role) { - this.workspaceId = workspaceId; + public WorkspaceMemberResponseDto(Long userId, Long workspaceId, WorkspaceMemberRole role) { this.userId = userId; + this.workspaceId = workspaceId; this.role = role; } From e6c7924b439bda3734852892f496f8c7403b34c9 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 11:53:54 +0900 Subject: [PATCH 053/181] =?UTF-8?q?Feat=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 댓글 생성 기능 구현 --- .../trello/comment/CommentController.java | 27 +++++++++++++++ .../trello/comment/CommentService.java | 34 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/main/java/com/example/trello/comment/CommentController.java create mode 100644 src/main/java/com/example/trello/comment/CommentService.java diff --git a/src/main/java/com/example/trello/comment/CommentController.java b/src/main/java/com/example/trello/comment/CommentController.java new file mode 100644 index 0000000..3aa0569 --- /dev/null +++ b/src/main/java/com/example/trello/comment/CommentController.java @@ -0,0 +1,27 @@ +package com.example.trello.comment; + +import com.example.trello.comment.dto.request.CommentRequestDto; +import com.example.trello.comment.dto.response.CommentResponseDto; +import jakarta.servlet.http.HttpServletRequest; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/comments") +public class CommentController { + + private final CommentService commentService; + + @PostMapping + public ResponseEntity createComment(@RequestBody CommentRequestDto requestDto, HttpServletRequest servletRequest) { + CommentResponseDto responseDto = commentService.createComment(requestDto, servletRequest); + return new ResponseEntity<>(responseDto, HttpStatus.OK); + } +} diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java new file mode 100644 index 0000000..c587e48 --- /dev/null +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -0,0 +1,34 @@ +package com.example.trello.comment; + +import com.example.trello.card.Card; +import com.example.trello.card.cardrepository.CardRepository; +import com.example.trello.comment.dto.request.CommentRequestDto; +import com.example.trello.comment.dto.response.CommentResponseDto; +import com.example.trello.user.User; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PostMapping; + +@Service +@RequiredArgsConstructor +public class CommentService { + private final CardRepository cardRepository; + private final CommentRepository commentRepository; + + + public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServletRequest servletRequest) { + + User user = (User) servletRequest.getSession().getAttribute("id"); + + Card card = cardRepository.findByIdOrElseThrow(requestDto.getCardId()); + + Comment comment = new Comment(requestDto.getContent(), user.getNickname(), card, user); + + card.getComments().add(comment); + + commentRepository.save(comment); + + return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getNikeName(), comment.getCard().getId(), comment.getUser().getId()); + } +} From dca56578108005ec3d7f2ff9503e9f39d8657ad0 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 12:00:53 +0900 Subject: [PATCH 054/181] =?UTF-8?q?feat=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/board/BoardController.java | 6 ++++++ .../java/com/example/trello/board/BoardService.java | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index f3cd618..28cc13a 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -37,4 +37,10 @@ public ResponseEntity updateBoard(@PathVariable Long boardId, BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto.getTitle(), dto.getColor(), dto.getImage(), loginUserId); return new ResponseEntity<>(updatedBoardResponseDto, HttpStatus.OK); } + + @DeleteMapping("/{boardId}") + public String deleteBoard(@PathVariable Long boardId, @SessionAttribute("id") Long loginUserId) { + boardService.deleteBoard(boardId, loginUserId); + return "보드가 정상적으로 삭제되었습니다."; + } } diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index ebf15ba..6d91155 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -98,4 +98,16 @@ public BoardResponseDto updateBoard(Long boardId, String title, String color, St return BoardResponseDto.toDto(findBoard); } + + @Transactional + public void deleteBoard(Long boardId, Long loginUserId) { + Board findBoard = boardRepository.findByIdOrElseThrow(boardId); + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); + + if (findWorkspaceMember.getRole() == READ_ONLY) { + throw new RuntimeException("읽기 전용 역할은 보드를 삭제할 수 없습니다."); + } + + boardRepository.delete(findBoard); + } } From 7ef259eb35a60c63197e859abd7262fb98b46222 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 12:27:34 +0900 Subject: [PATCH 055/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8,=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EC=8B=9C=20=EC=A1=B0=EA=B1=B4=EB=AC=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit servletRequest를 받아서 유저 id를 조회하여 작성자의 id와 현제 접속중이 유저의 id가 다르면 오류가 출력되도록 변경 --- .../com/example/trello/card/CardController.java | 8 ++++---- .../com/example/trello/card/CardService.java | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index b970a05..9f3966e 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -33,14 +33,14 @@ public ResponseEntity createdCard(@RequestBody CardRequestDto r } @PatchMapping("/{cardsId}/updateCards") - public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto) { - CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto); + public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { + CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, servletRequest); return new ResponseEntity<>(responseDto, HttpStatus.OK); } @DeleteMapping("/{cardsId}") - public ResponseEntity deleteCard(@PathVariable Long cardsId) { - cardService.deleteCardService(cardsId); + public ResponseEntity deleteCard(@PathVariable Long cardsId, HttpServletRequest servletRequest) { + cardService.deleteCardService(cardsId, servletRequest); return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index c0a338c..d55b8d2 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -49,11 +49,17 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, HttpServlet } //카드 업데이트 - public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto) { + public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { Card card = cardRepository.findByIdOrElseThrow(cardId); CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); + User user = (User) servletRequest.getSession().getAttribute("id"); + + if (!user.getId().equals(cardId)) { + throw new RuntimeException(); + } + card.updateCard(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); cardRepository.save(card); @@ -63,8 +69,14 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque // 카드 삭제 @PostMapping("/{cardsId}") - public void deleteCardService(Long cardId) { + public void deleteCardService(Long cardId, HttpServletRequest servletRequest) { Card card = cardRepository.findByIdOrElseThrow(cardId); + + User user = (User) servletRequest.getSession().getAttribute("id"); + + if (!user.getId().equals(cardId)) { + throw new RuntimeException(); + } cardRepository.delete(card); } From 080a22d42696b9aa6856d2f45cfe3f14d3851c80 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 12:47:42 +0900 Subject: [PATCH 056/181] =?UTF-8?q?Feat=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=EC=97=90=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=A0=20Dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 댓글 업데이트에 사용할 Dto 생성 --- .../dto/request/UpdateCommentRequestDto.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/com/example/trello/comment/dto/request/UpdateCommentRequestDto.java diff --git a/src/main/java/com/example/trello/comment/dto/request/UpdateCommentRequestDto.java b/src/main/java/com/example/trello/comment/dto/request/UpdateCommentRequestDto.java new file mode 100644 index 0000000..214fff6 --- /dev/null +++ b/src/main/java/com/example/trello/comment/dto/request/UpdateCommentRequestDto.java @@ -0,0 +1,13 @@ +package com.example.trello.comment.dto.request; + +import lombok.Getter; + +@Getter +public class UpdateCommentRequestDto { + + private String content; + + public UpdateCommentRequestDto (String content) { + this.content = content; + } +} From 8ef60ce41eeb487b1229a10f7771f889bf7a89c0 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 12:48:14 +0900 Subject: [PATCH 057/181] =?UTF-8?q?Feat=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 댓글 업데이트 기능 구현 --- .../com/example/trello/comment/Comment.java | 4 ++++ .../trello/comment/CommentController.java | 12 ++++++++---- .../trello/comment/CommentService.java | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/trello/comment/Comment.java b/src/main/java/com/example/trello/comment/Comment.java index aad41a2..0e1953c 100644 --- a/src/main/java/com/example/trello/comment/Comment.java +++ b/src/main/java/com/example/trello/comment/Comment.java @@ -36,4 +36,8 @@ public Comment(String content, String nikeName, Card card, User user) { this.user = user; } + public void updateComment(String content) { + this.content = content; + } + } diff --git a/src/main/java/com/example/trello/comment/CommentController.java b/src/main/java/com/example/trello/comment/CommentController.java index 3aa0569..c9322f5 100644 --- a/src/main/java/com/example/trello/comment/CommentController.java +++ b/src/main/java/com/example/trello/comment/CommentController.java @@ -1,16 +1,14 @@ package com.example.trello.comment; import com.example.trello.comment.dto.request.CommentRequestDto; +import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; import jakarta.servlet.http.HttpServletRequest; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -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.RestController; +import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @RestController @@ -24,4 +22,10 @@ public ResponseEntity createComment(@RequestBody CommentRequ CommentResponseDto responseDto = commentService.createComment(requestDto, servletRequest); return new ResponseEntity<>(responseDto, HttpStatus.OK); } + + @PatchMapping("/{commentId}") + public ResponseEntity updateComment(@PathVariable Long commentId, @RequestBody UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { + CommentResponseDto responseDto = commentService.updateComment(commentId, requestDto, servletRequest); + return new ResponseEntity<>(responseDto, HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index c587e48..17461e4 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -3,6 +3,7 @@ import com.example.trello.card.Card; import com.example.trello.card.cardrepository.CardRepository; import com.example.trello.comment.dto.request.CommentRequestDto; +import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; import com.example.trello.user.User; import jakarta.servlet.http.HttpServletRequest; @@ -31,4 +32,22 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServle return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getNikeName(), comment.getCard().getId(), comment.getUser().getId()); } + + public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { + + User user = (User) servletRequest.getSession().getAttribute("id"); + + Comment comment = commentRepository.findByIdOrElseThrow(commentId); + + if (!comment.getUser().getId().equals(user.getId())) { + throw new RuntimeException(); + } + + comment.updateComment(requestDto.getContent()); + + commentRepository.save(comment); + + return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getNikeName(), comment.getCard().getId(), comment.getUser().getId()); + + } } From 26f938da53b645e6ac63569d186071dc4240562f Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 12:59:12 +0900 Subject: [PATCH 058/181] =?UTF-8?q?Feat=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 댓글 삭제 기능 구현 --- .../example/trello/comment/CommentController.java | 6 ++++++ .../com/example/trello/comment/CommentService.java | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/com/example/trello/comment/CommentController.java b/src/main/java/com/example/trello/comment/CommentController.java index c9322f5..5087a74 100644 --- a/src/main/java/com/example/trello/comment/CommentController.java +++ b/src/main/java/com/example/trello/comment/CommentController.java @@ -28,4 +28,10 @@ public ResponseEntity updateComment(@PathVariable Long comme CommentResponseDto responseDto = commentService.updateComment(commentId, requestDto, servletRequest); return new ResponseEntity<>(responseDto, HttpStatus.OK); } + + @DeleteMapping("/{commentId}") + public ResponseEntity deleteComment(@PathVariable Long commentId, HttpServletRequest servletRequest) { + commentService.deleteComment(commentId, servletRequest); + return new ResponseEntity<>("삭제되었습니다" , HttpStatus.OK); + } } diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 17461e4..22eef35 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -50,4 +50,17 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getNikeName(), comment.getCard().getId(), comment.getUser().getId()); } + + public void deleteComment(Long commentId, HttpServletRequest servletRequest) { + + User user = (User) servletRequest.getSession().getAttribute("id"); + + Comment comment = commentRepository.findByIdOrElseThrow(commentId); + + if (!comment.getUser().getId().equals(user.getId())) { + throw new RuntimeException(); + } + + commentRepository.delete(comment); + } } From 17345685141ec0e263527940eb819bf47a1f7c4d Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Fri, 27 Dec 2024 13:52:57 +0900 Subject: [PATCH 059/181] =?UTF-8?q?feat=20:=20=EC=8A=AC=EB=9E=99=EC=95=8C?= =?UTF-8?q?=EB=9E=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++ .../trello/notification/Notification.java | 11 ++++- .../notification/NotificationService.java | 45 +++++++++++++++++++ .../trello/notification/NotificationType.java | 19 ++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/trello/notification/NotificationService.java create mode 100644 src/main/java/com/example/trello/notification/NotificationType.java diff --git a/build.gradle b/build.gradle index 638f295..6e2230d 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,9 @@ dependencies { annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" + + //Slack + implementation 'com.slack.api:slack-api-client:1.27.2' } tasks.named('test') { diff --git a/src/main/java/com/example/trello/notification/Notification.java b/src/main/java/com/example/trello/notification/Notification.java index c23583b..ffaa2c3 100644 --- a/src/main/java/com/example/trello/notification/Notification.java +++ b/src/main/java/com/example/trello/notification/Notification.java @@ -2,14 +2,19 @@ import com.example.trello.workspace.Workspace; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.Fetch; import java.time.LocalDateTime; @Entity @Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class Notification { @Id @@ -26,4 +31,8 @@ public class Notification { @ManyToOne(fetch = FetchType.LAZY) private Workspace workspace; + @Enumerated(EnumType.STRING) + private NotificationType notificationType; + + } diff --git a/src/main/java/com/example/trello/notification/NotificationService.java b/src/main/java/com/example/trello/notification/NotificationService.java new file mode 100644 index 0000000..ccf0a4d --- /dev/null +++ b/src/main/java/com/example/trello/notification/NotificationService.java @@ -0,0 +1,45 @@ +package com.example.trello.notification; + +import com.example.trello.workspace.Workspace; +import com.slack.api.Slack; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; + +@Service +@RequiredArgsConstructor +public class NotificationService { + + private final NotificationRepository notificationRepository; + + @Value("${SLACK_URL}") + private String slackUrl; + + @Transactional + public void sendSlack(NotificationType notificationType ,Workspace workspace) { + Slack slack =Slack.getInstance(); + String message = NotificationType.createMessage(notificationType); + try { + slack.send(slackUrl,message); + Notification notification = Notification.builder() + .content(notificationType.getMessage()) + .notificationType(notificationType) + .workspace(workspace) + .build(); + notificationRepository.save(notification); + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + + + + + + +} diff --git a/src/main/java/com/example/trello/notification/NotificationType.java b/src/main/java/com/example/trello/notification/NotificationType.java new file mode 100644 index 0000000..ac486e2 --- /dev/null +++ b/src/main/java/com/example/trello/notification/NotificationType.java @@ -0,0 +1,19 @@ +package com.example.trello.notification; + +import lombok.Getter; + +@Getter +public enum NotificationType { + + ADD_MEMBER("맴버가 추가되었습니다"),UPDATE_CARD("카드가 변경되었습니다"),CREATE_COMMENT("새로운 댓글이 생성되었습니다"); + + private String message; + + NotificationType(String message) { + this.message = message; + } + + public static String createMessage(NotificationType notificationType) { + return "{\"text\" : " + " \""+notificationType.getMessage()+"\" }"; + } +} From 5bca60e45dd89e164232d92b4a7298899638a721 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:37:52 +0900 Subject: [PATCH 060/181] =?UTF-8?q?Fix=20:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CardListDto에서 CardPageDto로 변환 --- .../cardrepository/CardRepositoryCustomImpl.java | 13 +++---------- .../{CardListDto.java => CardPageDto.java} | 6 +++--- 2 files changed, 6 insertions(+), 13 deletions(-) rename src/main/java/com/example/trello/card/requestDto/{CardListDto.java => CardPageDto.java} (72%) diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java index 5fa3e1e..a719133 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java @@ -2,20 +2,14 @@ import com.example.trello.card.Card; import com.example.trello.card.QCard; -import com.example.trello.card.requestDto.CardListDto; -import com.example.trello.card.responsedto.CardResponseDto; +import com.example.trello.card.requestDto.CardPageDto; import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Repository; -import org.springframework.web.bind.annotation.RequestParam; -import java.awt.print.Pageable; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.List; @Repository @@ -25,10 +19,9 @@ public class CardRepositoryCustomImpl implements CardRepositoryCustom{ private final JPAQueryFactory queryFactory; @Override - public CardListDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + public CardPageDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { QCard card = QCard.card; - List cardList = queryFactory .selectFrom(card) .where( @@ -49,7 +42,7 @@ public CardListDto searchCard(PageRequest pageRequest, Long cardListId, LocalDat eqEndAt(endAt), eqBoard(boardId)) .fetchOne(); - return new CardListDto(cardList,count); + return new CardPageDto(cardList,count); } diff --git a/src/main/java/com/example/trello/card/requestDto/CardListDto.java b/src/main/java/com/example/trello/card/requestDto/CardPageDto.java similarity index 72% rename from src/main/java/com/example/trello/card/requestDto/CardListDto.java rename to src/main/java/com/example/trello/card/requestDto/CardPageDto.java index cc52cef..3fac6c0 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardListDto.java +++ b/src/main/java/com/example/trello/card/requestDto/CardPageDto.java @@ -7,14 +7,14 @@ import java.util.List; @Getter -public class CardListDto { +public class CardPageDto { private List cardList; private Long count; - public CardListDto(List cardList, Long count) { + public CardPageDto(List cardList, Long count) { this.cardList = cardList.stream() - .map(card -> new CardResponseDto(card)) + .map(CardResponseDto::toDto) .toList(); this.count = count; } From 53bf88f896d7eb8270d8a2582beacba6f7253036 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:41:20 +0900 Subject: [PATCH 061/181] =?UTF-8?q?Fix=20:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20=EB=B0=91=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=EB=A9=A4=EB=B2=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/card/Card.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index c8f5d3d..5542066 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -4,9 +4,12 @@ import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.comment.Comment; +import com.example.trello.workspace_member.WorkspaceMember; import jakarta.persistence.*; import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import org.hibernate.annotations.DynamicInsert; @@ -17,7 +20,8 @@ @Entity @Getter @DynamicInsert -@RequiredArgsConstructor +@AllArgsConstructor +@NoArgsConstructor public class Card { @Id @@ -33,9 +37,6 @@ public class Card { @Column(name = "image") private String image; - @Column(name = "userName") - private String nikeName; - @Column(name = "start_at") private LocalDate startAt; @@ -45,18 +46,24 @@ public class Card { @ManyToOne(fetch = FetchType.LAZY) private CardList cardList; + @ManyToOne(fetch = FetchType.LAZY) + private WorkspaceMember workspaceMember; + @OneToMany(mappedBy = "card",cascade = CascadeType.ALL,orphanRemoval = true) private List comments; - public Card(String title, String description, String nikeName, LocalDate startAt, LocalDate endAt,CardList cardList) { + + + public Card(String title, String description, WorkspaceMember workspaceMember, LocalDate startAt, LocalDate endAt,CardList cardList) { this.title = title; this.description = description; - this.nikeName = nikeName; + this.workspaceMember = workspaceMember; this.startAt = startAt; this.endAt = endAt; this.cardList = cardList; } + public void updateCard(CardList cardList, String title, String description, LocalDate startAt, LocalDate endAt) { this.cardList = cardList; this.title = title; From d62275c6610f72a5cd8e4a79cdfe70b134963131 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:43:09 +0900 Subject: [PATCH 062/181] =?UTF-8?q?Fix=20:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20=EB=B0=91=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=A9=A4=EB=B2=84=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EB=94=94=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../card/requestDto/CardRequestDto.java | 9 +++++++- .../card/responsedto/CardResponseDto.java | 23 ++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java index c5698de..aa7b2ea 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java @@ -1,5 +1,8 @@ package com.example.trello.card.requestDto; +import com.example.trello.card.Card; +import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_member.WorkspaceMember; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.persistence.Column; import lombok.Getter; @@ -16,17 +19,21 @@ public class CardRequestDto { private String description; + private Long workSpaceMemberId; + @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate startAt; @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate endAt; - public CardRequestDto(Long cardListId, String title, String description, LocalDate startAt, LocalDate endAt) { + public CardRequestDto(Long cardListId, String title, String description, Long workspaceMemberId, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.title = title; this.description = description; + this.workSpaceMemberId = workspaceMemberId; this.startAt = startAt; this.endAt = endAt; } + } diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index efaafb8..1d0e0bf 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -21,7 +21,7 @@ public class CardResponseDto { private String description; - private String nikeName; + private Long workSpaceMemberId; @JsonFormat(pattern = "yyyy-MM-dd") LocalDate startAt; @@ -30,23 +30,24 @@ public class CardResponseDto { LocalDate endAt; - public CardResponseDto(Long cardListId, Long cardId, String title, String description, String nikeName, LocalDate startAt, LocalDate endAt) { + public CardResponseDto(Long cardListId, Long cardId, String title, String description, Long workSpaceMemberId, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.cardId = cardId; this.title = title; this.description = description; - this.nikeName = nikeName; + this.workSpaceMemberId = workSpaceMemberId; this.startAt = startAt; this.endAt =endAt; } - public CardResponseDto(Card card) { - this.cardListId = card.getCardList().getId(); - this.cardId = card.getId(); - this.title = card.getTitle(); - this.description = card.getDescription(); - this.nikeName = card.getNikeName(); - this.startAt = card.getStartAt(); - this.endAt =card.getEndAt(); + + public static CardResponseDto toDto(Card card) { + return new CardResponseDto(card.getCardList().getId(), + card.getId(), + card.getTitle(), + card.getDescription(), + card.getWorkspaceMember().getId(), + card.getStartAt(), + card.getEndAt()); } } From 8e72f242c600974d69476db554c28c902fca6574 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:43:22 +0900 Subject: [PATCH 063/181] =?UTF-8?q?Fix=20:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20=EB=B0=91=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=A9=A4=EB=B2=84=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EB=94=94=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/card/requestDto/UpdateCardRequestDto.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java index d342d45..0c06299 100644 --- a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java @@ -15,16 +15,19 @@ public class UpdateCardRequestDto { private String description; + private Long workSpaceMemberId; + @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate startAt; @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate endAt; - public UpdateCardRequestDto(String title, Long cardListId, String description, LocalDate startAt, LocalDate endAt) { + public UpdateCardRequestDto(String title, Long cardListId, String description, Long workSpaceMemberId, LocalDate startAt, LocalDate endAt) { this.title = title; this.CardListId = cardListId; this.description = description; + this.workSpaceMemberId = workSpaceMemberId; this.startAt = startAt; this.endAt = endAt; } From 36595935e94cd9377e9ae5e5ef02fa824b2e5e35 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:45:06 +0900 Subject: [PATCH 064/181] =?UTF-8?q?Fix=20:=20mapping=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EB=B3=80=EA=B2=BD,=20@SessionAtt?= =?UTF-8?q?ribute=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/card/CardController.java | 33 +++++----- .../com/example/trello/card/CardService.java | 60 +++++++++---------- 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 9f3966e..a22d512 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -1,22 +1,17 @@ package com.example.trello.card; -import com.example.trello.card.requestDto.CardListDto; +import com.example.trello.card.requestDto.CardPageDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; -import org.hibernate.query.Page; -import org.springframework.data.web.PageableDefault; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.awt.print.Pageable; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; @RequiredArgsConstructor @@ -27,20 +22,20 @@ public class CardController { private final CardService cardService; @PostMapping - public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto, HttpServletRequest servletRequest) { - CardResponseDto responseDto = cardService.createdCardService(requestDto, servletRequest); + public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto, @SessionAttribute("id") Long userid) { + CardResponseDto responseDto = cardService.createdCardService(requestDto, userid); return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } @PatchMapping("/{cardsId}/updateCards") - public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { - CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, servletRequest); + public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto, @SessionAttribute("id") Long userid) { + CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, userid); return new ResponseEntity<>(responseDto, HttpStatus.OK); } @DeleteMapping("/{cardsId}") - public ResponseEntity deleteCard(@PathVariable Long cardsId, HttpServletRequest servletRequest) { - cardService.deleteCardService(cardsId, servletRequest); + public ResponseEntity deleteCard(@PathVariable Long cardsId, @SessionAttribute("id") Long userid) { + cardService.deleteCardService(cardsId, userid); return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); } @@ -50,13 +45,13 @@ public ResponseEntity findCard(@PathVariable Long cardsId) { return new ResponseEntity<>(responseDto, HttpStatus.OK); } - @GetMapping("/getCards") - public ResponseEntity getCards(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false) Long cardListId, - @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startAt, - @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endAt, - @RequestParam(required = false) Long boardId) { - CardListDto cards = cardService.searchCards(page, cardListId, startAt, endAt, boardId); + @GetMapping + public ResponseEntity getCards(@RequestParam(defaultValue = "0") int page, + @RequestParam(required = false) Long cardListId, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startAt, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endAt, + @RequestParam(required = false) Long boardId) { + CardPageDto cards = cardService.searchCards(page, cardListId, startAt, endAt, boardId); return new ResponseEntity<>(cards, HttpStatus.OK); } } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index d55b8d2..9514f17 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -1,9 +1,8 @@ package com.example.trello.card; -import com.example.trello.board.Board; import com.example.trello.card.cardrepository.CardRepository; import com.example.trello.card.cardrepository.CardRepositoryCustomImpl; -import com.example.trello.card.requestDto.CardListDto; +import com.example.trello.card.requestDto.CardPageDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; @@ -11,20 +10,20 @@ import com.example.trello.cardlist.CardListRepository; import com.example.trello.user.User; import com.example.trello.user.UserRepository; -import com.example.trello.workspace.Workspace; +import com.example.trello.workspace.WorkSpaceRepository; +import com.example.trello.workspace_member.WorkspaceMember; +import com.example.trello.workspace_member.WorkspaceMemberRepository; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.DeleteMapping; -import java.awt.print.Pageable; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.List; + +import static com.example.trello.card.QCard.card; +import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; @Service @RequiredArgsConstructor @@ -34,27 +33,35 @@ public class CardService { private final CardListRepository cardListRepository; private final CardRepositoryCustomImpl cardRepositoryCustomImpl; private final UserRepository userRepository; + private final WorkSpaceRepository workSpaceRepository; + private final WorkspaceMemberRepository workspaceMemberRepository; // 카드 생성 - public CardResponseDto createdCardService(CardRequestDto requestDto, HttpServletRequest servletRequest) { + public CardResponseDto createdCardService(CardRequestDto requestDto, Long userId) { + + User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); - User user = (User) servletRequest.getSession().getAttribute("id"); + CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); - CardList cardList = findCardListByCardListId(requestDto.getCardListId()); + WorkspaceMember workspaceMember = workspaceMemberRepository.findByIdOrElseThrow(requestDto.getWorkSpaceMemberId()); + + if (workspaceMember.getRole().equals(READ_ONLY)) { + throw new RuntimeException(); + } - Card card = new Card(requestDto.getTitle(), requestDto.getDescription(),user.getNickname(), requestDto.getStartAt(), requestDto.getEndAt(), cardList); + Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), workspaceMember, requestDto.getStartAt(), requestDto.getEndAt(), cardList); cardRepository.save(card); - return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(),user.getNickname(), requestDto.getStartAt(), requestDto.getEndAt()); + return CardResponseDto.toDto(card); } //카드 업데이트 - public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, HttpServletRequest servletRequest) { + public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, Long userId) { Card card = cardRepository.findByIdOrElseThrow(cardId); CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); - User user = (User) servletRequest.getSession().getAttribute("id"); + User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); if (!user.getId().equals(cardId)) { throw new RuntimeException(); @@ -64,15 +71,15 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque cardRepository.save(card); - return new CardResponseDto(cardList.getId(), card.getId(), requestDto.getTitle(), requestDto.getDescription(), card.getNikeName(),requestDto.getStartAt(), requestDto.getEndAt()); + return CardResponseDto.toDto(card); } // 카드 삭제 - @PostMapping("/{cardsId}") - public void deleteCardService(Long cardId, HttpServletRequest servletRequest) { + @DeleteMapping("/{cardsId}") + public void deleteCardService(Long cardId, Long userId) { Card card = cardRepository.findByIdOrElseThrow(cardId); - User user = (User) servletRequest.getSession().getAttribute("id"); + User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); if (!user.getId().equals(cardId)) { throw new RuntimeException(); @@ -83,14 +90,14 @@ public void deleteCardService(Long cardId, HttpServletRequest servletRequest) { // 카드 단건 조회 public CardResponseDto findCardById(Long cardsId) { Card card = cardRepository.findByIdOrElseThrow(cardsId); - return new CardResponseDto(card.getCardList().getId(), card.getId(), card.getTitle(), card.getDescription(), card.getNikeName(), card.getStartAt(),card.getEndAt()); + return CardResponseDto.toDto(card); } // 카드 다건 조회(조건 O) - public CardListDto searchCards(int page ,Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + public CardPageDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); - CardListDto cards = cardRepository.searchCard(pageRequest, cardListId, startAt, endAt, boardId); + CardPageDto cards = cardRepository.searchCard(pageRequest, cardListId, startAt, endAt, boardId); return cards; } @@ -109,11 +116,4 @@ public CardListDto searchCards(int page ,Long cardListId, LocalDate startAt, Loc // .toList(); // } - - - // 카드 리스트id로 카드 리스트 찾는 메소드 - public CardList findCardListByCardListId(Long id) { - return cardListRepository.findByIdOrElseThrow(id); - } - } From 5413a2e8dce8684d7298fb078a4efbbd33ba85e0 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:45:24 +0900 Subject: [PATCH 065/181] =?UTF-8?q?Fix=20:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../card/cardrepository/CardRepositoryCustom.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java index 7dbea6c..55e4172 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java @@ -1,16 +1,10 @@ package com.example.trello.card.cardrepository; -import com.example.trello.card.Card; -import com.example.trello.card.requestDto.CardListDto; -import com.example.trello.card.responsedto.CardResponseDto; -import org.springframework.data.domain.Page; +import com.example.trello.card.requestDto.CardPageDto; import org.springframework.data.domain.PageRequest; -import java.awt.print.Pageable; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; public interface CardRepositoryCustom { - CardListDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); + CardPageDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); } From e102775407ae43634510a7c0aaf6a5a73ad13ed4 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:52:01 +0900 Subject: [PATCH 066/181] =?UTF-8?q?Fix=20:=20Builder=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/Card.java | 6 ++---- src/main/java/com/example/trello/card/CardService.java | 9 ++++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index 5542066..1dbce44 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -7,10 +7,7 @@ import com.example.trello.workspace_member.WorkspaceMember; import jakarta.persistence.*; import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; +import lombok.*; import org.hibernate.annotations.DynamicInsert; import java.time.LocalDate; @@ -54,6 +51,7 @@ public class Card { + @Builder public Card(String title, String description, WorkspaceMember workspaceMember, LocalDate startAt, LocalDate endAt,CardList cardList) { this.title = title; this.description = description; diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 9514f17..b8c4808 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -49,7 +49,14 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, Long userId throw new RuntimeException(); } - Card card = new Card(requestDto.getTitle(), requestDto.getDescription(), workspaceMember, requestDto.getStartAt(), requestDto.getEndAt(), cardList); + Card card = Card.builder() + .title(requestDto.getTitle()) + .description(requestDto.getDescription()) + .workspaceMember(workspaceMember) + .startAt(requestDto.getStartAt()) + .endAt(requestDto.getEndAt()) + .cardList(cardList) + .build(); cardRepository.save(card); return CardResponseDto.toDto(card); From 6f06da3cbf5cde9d401d7636b7ae229b8c66b4a7 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:56:01 +0900 Subject: [PATCH 067/181] =?UTF-8?q?Fix=20:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0,=20toDto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/dto/response/CommentResponseDto.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java index e599a0c..d0a92b1 100644 --- a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java +++ b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java @@ -1,5 +1,6 @@ package com.example.trello.comment.dto.response; +import com.example.trello.comment.Comment; import lombok.Getter; import java.util.List; @@ -11,17 +12,22 @@ public class CommentResponseDto { private String content; - private String nikeName; - private Long cardId; private Long userId; - public CommentResponseDto(Long commentId, String content, String nikeName, Long cardId, Long userId) { + public CommentResponseDto(Long commentId, String content, Long cardId, Long userId) { this.commentId = commentId; this.content = content; - this.nikeName = nikeName; this.cardId = cardId; this.userId = userId; } + + public static CommentResponseDto toDto(Comment comment) { + return new CommentResponseDto( + comment.getId(), + comment.getContent(), + comment.getCard().getId(), + comment.getUser().getId()); + } } From b2cc8d6f010ea1c17c8c90b3d9183d9624cb8946 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:56:29 +0900 Subject: [PATCH 068/181] =?UTF-8?q?Fix=20:=20userId=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/comment/dto/request/CommentRequestDto.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java index 1a01b88..60a5150 100644 --- a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java +++ b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java @@ -9,11 +9,8 @@ public class CommentRequestDto { private Long cardId; - private Long userId; - - public CommentRequestDto(String content, Long cardId, Long userId) { + public CommentRequestDto(String content, Long cardId) { this.content = content; this.cardId = cardId; - this.userId = userId; } } From ef4431111137128fd29737fb889c1fbdad7f05c5 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:56:58 +0900 Subject: [PATCH 069/181] =?UTF-8?q?Fix=20:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/comment/CommentService.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 22eef35..93a62e1 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -24,13 +24,11 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServle Card card = cardRepository.findByIdOrElseThrow(requestDto.getCardId()); - Comment comment = new Comment(requestDto.getContent(), user.getNickname(), card, user); - - card.getComments().add(comment); + Comment comment = new Comment(requestDto.getContent(), card, user); commentRepository.save(comment); - return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getNikeName(), comment.getCard().getId(), comment.getUser().getId()); + return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getCard().getId(), comment.getUser().getId()); } public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { @@ -47,7 +45,7 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto commentRepository.save(comment); - return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getNikeName(), comment.getCard().getId(), comment.getUser().getId()); + return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getCard().getId(), comment.getUser().getId()); } From 7020f4439d8612785d3983b35e076249837df3b1 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 14:57:38 +0900 Subject: [PATCH 070/181] =?UTF-8?q?Fix=20:=20workspaceMember=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=A0=9C=EA=B1=B0,?= =?UTF-8?q?=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/comment/Comment.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/comment/Comment.java b/src/main/java/com/example/trello/comment/Comment.java index 0e1953c..e029c77 100644 --- a/src/main/java/com/example/trello/comment/Comment.java +++ b/src/main/java/com/example/trello/comment/Comment.java @@ -2,15 +2,18 @@ import com.example.trello.card.Card; import com.example.trello.user.User; +import com.example.trello.workspace_member.WorkspaceMember; import jakarta.persistence.*; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import org.hibernate.annotations.DynamicInsert; @Entity @Getter -@DynamicInsert -@RequiredArgsConstructor +@AllArgsConstructor +@NoArgsConstructor public class Comment { @Id @@ -20,18 +23,17 @@ public class Comment { @Column(name = "content") private String content; - @Column(name = "nikeName") - private String nikeName; - @ManyToOne(fetch = FetchType.LAZY) private Card card; @ManyToOne(fetch = FetchType.LAZY) private User user; - public Comment(String content, String nikeName, Card card, User user) { + @ManyToOne(fetch = FetchType.LAZY) + private WorkspaceMember workspaceMember; + + public Comment(String content, Card card, User user) { this.content = content; - this.nikeName = nikeName; this.card = card; this.user = user; } From 0c1460646d3716f4ec93c5742ae4b2ea7751a0e9 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 15:02:38 +0900 Subject: [PATCH 071/181] =?UTF-8?q?Fix=20:=20CommentResponseDto.toDto?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/comment/CommentService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 93a62e1..0fe384d 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -28,7 +28,7 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServle commentRepository.save(comment); - return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getCard().getId(), comment.getUser().getId()); + return CommentResponseDto.toDto(comment); } public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { @@ -45,7 +45,7 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto commentRepository.save(comment); - return new CommentResponseDto(comment.getId(), comment.getContent(), comment.getCard().getId(), comment.getUser().getId()); + return CommentResponseDto.toDto(comment); } From 5f582c7cb90ae0efd358ed3c652eac69e7809c38 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 15:08:09 +0900 Subject: [PATCH 072/181] =?UTF-8?q?Fix=20:=20workSpaceMember=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=91=20Builder=ED=8C=A8=ED=84=B4=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/comment/Comment.java | 9 ++++----- .../com/example/trello/comment/CommentService.java | 13 ++++++++++++- .../comment/dto/request/CommentRequestDto.java | 5 ++++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/comment/Comment.java b/src/main/java/com/example/trello/comment/Comment.java index e029c77..b7b3258 100644 --- a/src/main/java/com/example/trello/comment/Comment.java +++ b/src/main/java/com/example/trello/comment/Comment.java @@ -4,10 +4,7 @@ import com.example.trello.user.User; import com.example.trello.workspace_member.WorkspaceMember; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; +import lombok.*; import org.hibernate.annotations.DynamicInsert; @Entity @@ -32,10 +29,12 @@ public class Comment { @ManyToOne(fetch = FetchType.LAZY) private WorkspaceMember workspaceMember; - public Comment(String content, Card card, User user) { + @Builder + public Comment(String content, Card card, User user, WorkspaceMember workspaceMember) { this.content = content; this.card = card; this.user = user; + this.workspaceMember = workspaceMember; } public void updateComment(String content) { diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 0fe384d..9ab64c3 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -6,6 +6,9 @@ import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; import com.example.trello.user.User; +import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_member.WorkspaceMember; +import com.example.trello.workspace_member.WorkspaceMemberRepository; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -16,6 +19,7 @@ public class CommentService { private final CardRepository cardRepository; private final CommentRepository commentRepository; + private final WorkspaceMemberRepository workspaceMemberRepository; public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServletRequest servletRequest) { @@ -24,7 +28,14 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServle Card card = cardRepository.findByIdOrElseThrow(requestDto.getCardId()); - Comment comment = new Comment(requestDto.getContent(), card, user); + WorkspaceMember workspaceMember = workspaceMemberRepository.findByIdOrElseThrow(requestDto.getWorkSpaceMemberId()); + + Comment comment = Comment.builder() + .content(requestDto.getContent()) + .card(card) + .user(user) + .workspaceMember(workspaceMember) + .build(); commentRepository.save(comment); diff --git a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java index 60a5150..d255aed 100644 --- a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java +++ b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java @@ -9,8 +9,11 @@ public class CommentRequestDto { private Long cardId; - public CommentRequestDto(String content, Long cardId) { + private Long workSpaceMemberId; + + public CommentRequestDto(String content, Long cardId, Long workSpaceMemberId) { this.content = content; this.cardId = cardId; + this.workSpaceMemberId = workSpaceMemberId; } } From 6e746f14e3c8fc7209240ae1d4b90f217b7ce43a Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 15:12:27 +0900 Subject: [PATCH 073/181] =?UTF-8?q?Fix=20:=20workSpaceMemberId=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/comment/dto/response/CommentResponseDto.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java index d0a92b1..51552b8 100644 --- a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java +++ b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java @@ -16,11 +16,14 @@ public class CommentResponseDto { private Long userId; - public CommentResponseDto(Long commentId, String content, Long cardId, Long userId) { + private Long workSpaceMemberId; + + public CommentResponseDto(Long commentId, String content, Long cardId, Long userId, Long workSpaceMemberId) { this.commentId = commentId; this.content = content; this.cardId = cardId; this.userId = userId; + this.workSpaceMemberId = workSpaceMemberId; } public static CommentResponseDto toDto(Comment comment) { @@ -28,6 +31,7 @@ public static CommentResponseDto toDto(Comment comment) { comment.getId(), comment.getContent(), comment.getCard().getId(), - comment.getUser().getId()); + comment.getUser().getId(), + comment.getWorkspaceMember().getId()); } } From 3ca91544e7c9aa5a76306016b746640b2f1a12d7 Mon Sep 17 00:00:00 2001 From: jut Date: Fri, 27 Dec 2024 15:40:31 +0900 Subject: [PATCH 074/181] =?UTF-8?q?fix=20:=20enum=20Role=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/user/enums/Role.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/user/enums/Role.java b/src/main/java/com/example/trello/user/enums/Role.java index b4f405f..634ec9d 100644 --- a/src/main/java/com/example/trello/user/enums/Role.java +++ b/src/main/java/com/example/trello/user/enums/Role.java @@ -1,5 +1,11 @@ package com.example.trello.user.enums; +import lombok.Getter; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.util.List; + +@Getter public enum Role { USER("user"), ADMIN("admin") @@ -10,4 +16,18 @@ public enum Role { Role(String name) { this.name = name; } -} + + public static Role of(String roleName) throws IllegalArgumentException { + for (Role role : values()) { + if (role.getName().equals(roleName.toLowerCase())) { + return role; + } + } + + throw new RuntimeException(); + } + + public List getAuthorities() { + return List.of(new SimpleGrantedAuthority("ROLE_" + this.name)); + } + } From fd8436d64bc08753aa924782a8a8430b6007d20c Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 16:03:22 +0900 Subject: [PATCH 075/181] =?UTF-8?q?Fix=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8,=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=AC=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EB=8B=A8=EA=B1=B4,=20=EB=8B=A4=EA=B1=B4=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20Mapping=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/CardService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index b8c4808..425a774 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -14,11 +14,13 @@ import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import jakarta.servlet.http.HttpServletRequest; +import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import java.time.LocalDate; @@ -70,7 +72,7 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); - if (!user.getId().equals(cardId)) { + if (!user.getId().equals(card.getWorkspaceMember().getUser().getId())) { throw new RuntimeException(); } @@ -88,19 +90,21 @@ public void deleteCardService(Long cardId, Long userId) { User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); - if (!user.getId().equals(cardId)) { + if (!user.getId().equals(card.getWorkspaceMember().getUser().getId())) { throw new RuntimeException(); } cardRepository.delete(card); } // 카드 단건 조회 + @GetMapping("/{cardId}") public CardResponseDto findCardById(Long cardsId) { Card card = cardRepository.findByIdOrElseThrow(cardsId); return CardResponseDto.toDto(card); } // 카드 다건 조회(조건 O) + @GetMapping public CardPageDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); From 07bb4e1ace5774913287276e3b46899e74d499fd Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 16:15:16 +0900 Subject: [PATCH 076/181] =?UTF-8?q?Fix=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=AC=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/comment/CommentService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 9ab64c3..cdaf667 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -48,7 +48,7 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto Comment comment = commentRepository.findByIdOrElseThrow(commentId); - if (!comment.getUser().getId().equals(user.getId())) { + if (!user.getId().equals(comment.getWorkspaceMember().getUser().getId())) { throw new RuntimeException(); } @@ -66,7 +66,7 @@ public void deleteComment(Long commentId, HttpServletRequest servletRequest) { Comment comment = commentRepository.findByIdOrElseThrow(commentId); - if (!comment.getUser().getId().equals(user.getId())) { + if (!user.getId().equals(comment.getWorkspaceMember().getUser().getId())) { throw new RuntimeException(); } From 4860d51ba6556d800ca093c31ce92ed318ebec20 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 17:01:05 +0900 Subject: [PATCH 077/181] =?UTF-8?q?feat=20:=20=EC=95=84=EB=A7=88=EC=A1=B4?= =?UTF-8?q?=20s3=20=ED=8C=8C=EC=9D=BC=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../trello/board/FileUploadController.java | 42 +++++++++++++++++++ .../com/example/trello/config/S3config.java | 29 +++++++++++++ .../example/trello/workspace/Workspace.java | 2 + 4 files changed, 74 insertions(+) create mode 100644 src/main/java/com/example/trello/board/FileUploadController.java create mode 100644 src/main/java/com/example/trello/config/S3config.java diff --git a/build.gradle b/build.gradle index 6e2230d..7cf0c29 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/java/com/example/trello/board/FileUploadController.java b/src/main/java/com/example/trello/board/FileUploadController.java new file mode 100644 index 0000000..635c12b --- /dev/null +++ b/src/main/java/com/example/trello/board/FileUploadController.java @@ -0,0 +1,42 @@ +package com.example.trello.board; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.ObjectMetadata; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +@RestController +@RequestMapping("/upload") +@RequiredArgsConstructor +public class FileUploadController { + private final AmazonS3Client amazonS3Client; + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + @PostMapping + public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) { + try { + String fileName = file.getOriginalFilename(); + String fileUrl = "https://" + bucket + "/test" + fileName; + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(file.getContentType()); + metadata.setContentLength(file.getSize()); + amazonS3Client.putObject(bucket, fileName, file.getInputStream(), metadata); + return ResponseEntity.ok(fileUrl); + } catch (IOException e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } +} + diff --git a/src/main/java/com/example/trello/config/S3config.java b/src/main/java/com/example/trello/config/S3config.java new file mode 100644 index 0000000..bef6f62 --- /dev/null +++ b/src/main/java/com/example/trello/config/S3config.java @@ -0,0 +1,29 @@ +package com.example.trello.config; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class S3config { + @Value("${cloud.aws.credentials.access-key}") + private String accessKey; + @Value("${cloud.aws.credentials.secret-key}") + private String secretKey; + @Value("${cloud.aws.region.static}") + private String region; + + @Bean + public AmazonS3Client amazonS3Client() { + BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); + return (AmazonS3Client) AmazonS3ClientBuilder.standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) + .build(); + } +} + diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index 6708792..c0eb224 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -6,11 +6,13 @@ import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; +import org.hibernate.annotations.DynamicUpdate; import java.util.List; @Entity @Getter +@DynamicUpdate public class Workspace { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From ea21fa6b8fbe8875e4e3c97ad1501e22d2cb612b Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 17:26:58 +0900 Subject: [PATCH 078/181] =?UTF-8?q?feat=20:=20application.yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 --- src/main/resources/application.yml | 9 +++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/application.yml diff --git a/.gitignore b/.gitignore index d9eaf9e..c2065bc 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,3 @@ out/ ### VS Code ### .vscode/ - -### properties ### -/src/main/resources/* \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..0e44c6f --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,9 @@ +cloud: + aws: + s3: + bucket: ${BUCKET_NAME} + stack.auto: false + region.static: ap-northeast-2 + credentials: + accessKey: ${BUCKET_ACCESSKEY} + secretKey: ${BUCKET_SECRETKEY} \ No newline at end of file From 7536a8414f9ffdf235454c05d60360de11d67e50 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 17:32:03 +0900 Subject: [PATCH 079/181] =?UTF-8?q?Fix=20:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20Mapping=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/CardService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 425a774..5b35857 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -84,7 +84,6 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque } // 카드 삭제 - @DeleteMapping("/{cardsId}") public void deleteCardService(Long cardId, Long userId) { Card card = cardRepository.findByIdOrElseThrow(cardId); @@ -97,14 +96,12 @@ public void deleteCardService(Long cardId, Long userId) { } // 카드 단건 조회 - @GetMapping("/{cardId}") public CardResponseDto findCardById(Long cardsId) { Card card = cardRepository.findByIdOrElseThrow(cardsId); return CardResponseDto.toDto(card); } // 카드 다건 조회(조건 O) - @GetMapping public CardPageDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); From 912e892941383a90f8b169f7540b79944ed988de Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 17:33:51 +0900 Subject: [PATCH 080/181] =?UTF-8?q?Fix=20:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/CardController.java | 15 +++++++-------- .../java/com/example/trello/card/CardService.java | 11 +++-------- .../card/cardrepository/CardRepositoryCustom.java | 4 ++-- .../cardrepository/CardRepositoryCustomImpl.java | 6 +++--- .../CardPageResponseDto.java} | 7 +++---- 5 files changed, 18 insertions(+), 25 deletions(-) rename src/main/java/com/example/trello/card/{requestDto/CardPageDto.java => responsedto/CardPageResponseDto.java} (62%) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index a22d512..44b90ad 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -1,10 +1,9 @@ package com.example.trello.card; -import com.example.trello.card.requestDto.CardPageDto; +import com.example.trello.card.responsedto.CardPageResponseDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; -import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; @@ -46,12 +45,12 @@ public ResponseEntity findCard(@PathVariable Long cardsId) { } @GetMapping - public ResponseEntity getCards(@RequestParam(defaultValue = "0") int page, - @RequestParam(required = false) Long cardListId, - @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startAt, - @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endAt, - @RequestParam(required = false) Long boardId) { - CardPageDto cards = cardService.searchCards(page, cardListId, startAt, endAt, boardId); + public ResponseEntity getCards(@RequestParam(defaultValue = "0") int page, + @RequestParam(required = false) Long cardListId, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startAt, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endAt, + @RequestParam(required = false) Long boardId) { + CardPageResponseDto cards = cardService.searchCards(page, cardListId, startAt, endAt, boardId); return new ResponseEntity<>(cards, HttpStatus.OK); } } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 5b35857..77923a3 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -2,7 +2,7 @@ import com.example.trello.card.cardrepository.CardRepository; import com.example.trello.card.cardrepository.CardRepositoryCustomImpl; -import com.example.trello.card.requestDto.CardPageDto; +import com.example.trello.card.responsedto.CardPageResponseDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; @@ -13,18 +13,13 @@ import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; -import jakarta.servlet.http.HttpServletRequest; -import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; import java.time.LocalDate; -import static com.example.trello.card.QCard.card; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; @Service @@ -102,10 +97,10 @@ public CardResponseDto findCardById(Long cardsId) { } // 카드 다건 조회(조건 O) - public CardPageDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + public CardPageResponseDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); - CardPageDto cards = cardRepository.searchCard(pageRequest, cardListId, startAt, endAt, boardId); + CardPageResponseDto cards = cardRepository.searchCard(pageRequest, cardListId, startAt, endAt, boardId); return cards; } diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java index 55e4172..6d4bbc9 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustom.java @@ -1,10 +1,10 @@ package com.example.trello.card.cardrepository; -import com.example.trello.card.requestDto.CardPageDto; +import com.example.trello.card.responsedto.CardPageResponseDto; import org.springframework.data.domain.PageRequest; import java.time.LocalDate; public interface CardRepositoryCustom { - CardPageDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); + CardPageResponseDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId); } diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java index a719133..bbac456 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepositoryCustomImpl.java @@ -2,7 +2,7 @@ import com.example.trello.card.Card; import com.example.trello.card.QCard; -import com.example.trello.card.requestDto.CardPageDto; +import com.example.trello.card.responsedto.CardPageResponseDto; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -19,7 +19,7 @@ public class CardRepositoryCustomImpl implements CardRepositoryCustom{ private final JPAQueryFactory queryFactory; @Override - public CardPageDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + public CardPageResponseDto searchCard(PageRequest pageRequest, Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { QCard card = QCard.card; List cardList = queryFactory @@ -42,7 +42,7 @@ public CardPageDto searchCard(PageRequest pageRequest, Long cardListId, LocalDat eqEndAt(endAt), eqBoard(boardId)) .fetchOne(); - return new CardPageDto(cardList,count); + return new CardPageResponseDto(cardList,count); } diff --git a/src/main/java/com/example/trello/card/requestDto/CardPageDto.java b/src/main/java/com/example/trello/card/responsedto/CardPageResponseDto.java similarity index 62% rename from src/main/java/com/example/trello/card/requestDto/CardPageDto.java rename to src/main/java/com/example/trello/card/responsedto/CardPageResponseDto.java index 3fac6c0..d96f737 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardPageDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardPageResponseDto.java @@ -1,18 +1,17 @@ -package com.example.trello.card.requestDto; +package com.example.trello.card.responsedto; import com.example.trello.card.Card; -import com.example.trello.card.responsedto.CardResponseDto; import lombok.Getter; import java.util.List; @Getter -public class CardPageDto { +public class CardPageResponseDto { private List cardList; private Long count; - public CardPageDto(List cardList, Long count) { + public CardPageResponseDto(List cardList, Long count) { this.cardList = cardList.stream() .map(CardResponseDto::toDto) .toList(); From 5ceb741cc40806bcbafd62f0544c27ddfcae00d0 Mon Sep 17 00:00:00 2001 From: jut Date: Fri, 27 Dec 2024 17:39:37 +0900 Subject: [PATCH 081/181] =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=20=EB=B0=8F=20securrityFilter=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 + .../example/trello/config/SecurityConfig.java | 58 ++++-- .../com/example/trello/config/WebConfig.java | 100 +++++++++++ .../auth/DelegateAccessDeniedHandler.java | 31 ++++ .../DelegatedAuthenticationEntryPoint.java | 29 +++ .../trello/config/auth/UserDetailsImpl.java | 55 ++++++ .../config/auth/UserDetailsServiceImpl.java | 26 +++ .../trello/config/filter/JwtAuthFilter.java | 109 +++++++++++ .../java/com/example/trello/user/User.java | 4 + .../example/trello/user/UserController.java | 71 -------- .../com/example/trello/user/UserService.java | 40 ++++- .../user/controller/UserController.java | 72 ++++++++ .../trello/user/dto/JwtAuthResponse.java | 28 +++ .../trello/util/AuthenticationScheme.java | 22 +++ .../com/example/trello/util/JwtProvider.java | 170 ++++++++++++++++++ src/main/resources/application.properties | 5 +- 16 files changed, 731 insertions(+), 94 deletions(-) create mode 100644 src/main/java/com/example/trello/config/WebConfig.java create mode 100644 src/main/java/com/example/trello/config/auth/DelegateAccessDeniedHandler.java create mode 100644 src/main/java/com/example/trello/config/auth/DelegatedAuthenticationEntryPoint.java create mode 100644 src/main/java/com/example/trello/config/auth/UserDetailsImpl.java create mode 100644 src/main/java/com/example/trello/config/auth/UserDetailsServiceImpl.java create mode 100644 src/main/java/com/example/trello/config/filter/JwtAuthFilter.java delete mode 100644 src/main/java/com/example/trello/user/UserController.java create mode 100644 src/main/java/com/example/trello/user/controller/UserController.java create mode 100644 src/main/java/com/example/trello/user/dto/JwtAuthResponse.java create mode 100644 src/main/java/com/example/trello/util/AuthenticationScheme.java create mode 100644 src/main/java/com/example/trello/util/JwtProvider.java diff --git a/build.gradle b/build.gradle index 638f295..1246db4 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,11 @@ dependencies { testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + // JWT + compileOnly 'io.jsonwebtoken:jjwt-api:0.12.3' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3' + // QueryDSL implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" diff --git a/src/main/java/com/example/trello/config/SecurityConfig.java b/src/main/java/com/example/trello/config/SecurityConfig.java index 28e08cf..abb3bda 100644 --- a/src/main/java/com/example/trello/config/SecurityConfig.java +++ b/src/main/java/com/example/trello/config/SecurityConfig.java @@ -1,34 +1,62 @@ package com.example.trello.config; -import com.example.trello.user.enums.Role; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; @Configuration -@EnableWebSecurity +@RequiredArgsConstructor +@Slf4j(topic = "Security::SecurityConfig") public class SecurityConfig { + private final UserDetailsService userDetailsService; + +// private static final String[] WHITE_LIST = {"/users/login", "/users/sign-up"}; + + @Bean - public BCryptPasswordEncoder bCryptPasswordEncoder() { + BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } + /** + * AuthenticationManager(인증 관리자). + * + * @param config {@link AuthenticationConfiguration} + * @return 설정이 추가된 AuthenticationManager + */ @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) + throws Exception { + log.info("AuthenticationManager에 위임."); + return config.getAuthenticationManager(); + } + + /** + * AuthenticationProvider(인증 공급자). + * + * @return {@link AuthenticationProvider} + */ + @Bean + AuthenticationProvider authenticationProvider() { + DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); + log.info("AuthenticationProvider 설정. 구현체: {}", authProvider.getClass().getSimpleName()); + + log.info("UserDetailsService에 사용자 관리 위임. 구현체: {}", + this.userDetailsService.getClass().getSimpleName()); + authProvider.setUserDetailsService(this.userDetailsService); - httpSecurity - .cors(AbstractHttpConfigurer::disable) - .csrf(AbstractHttpConfigurer::disable) - .authorizeHttpRequests((author) -> author - .requestMatchers("/users/**").permitAll() - .anyRequest().authenticated()); + log.info("PasswordEncoder에 암호 검증 위임. 구현체: {}", + this.passwordEncoder().getClass().getSimpleName()); + authProvider.setPasswordEncoder(passwordEncoder()); - return httpSecurity.build(); + return authProvider; } } diff --git a/src/main/java/com/example/trello/config/WebConfig.java b/src/main/java/com/example/trello/config/WebConfig.java new file mode 100644 index 0000000..18b6960 --- /dev/null +++ b/src/main/java/com/example/trello/config/WebConfig.java @@ -0,0 +1,100 @@ +package com.example.trello.config; + +import jakarta.servlet.DispatcherType; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.hierarchicalroles.RoleHierarchy; +import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity // SecurityFilterChain 빈 설정을 위해 필요. +@RequiredArgsConstructor +public class WebConfig { + + private final AuthenticationProvider authenticationProvider; + + /** + * AuthenticationEntryPoint. + */ + private final AuthenticationEntryPoint authEntryPoint; + + /** + * AccessDeniedHandler. + */ + private final AccessDeniedHandler accessDeniedHandler; + + /** + * 화이트 리스트. + */ + private static final String[] WHITE_LIST = {"/users/login","/users/sign-up"}; + + /** + * security 필터. + * + * @param http {@link HttpSecurity} + * @return {@link SecurityFilterChain} 필터 체인 + */ + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http.cors(AbstractHttpConfigurer::disable) + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(auth -> + auth.requestMatchers(WHITE_LIST).permitAll() + .requestMatchers("/admins/**").hasRole("ADMIN") + .requestMatchers("/users/**").hasRole("USER") + // 나머지는 인증이 필요 + .anyRequest().authenticated() + ) + // Spring Security 예외에 대한 처리를 핸들러에 위임. + .exceptionHandling(handler -> handler + .authenticationEntryPoint(authEntryPoint) + .accessDeniedHandler(accessDeniedHandler)) + // JWT 기반 테스트를 위해 SecurityContext를 가져올 때 HttpSession을 사용하지 않도록 설정. + .sessionManagement( + session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authenticationProvider(authenticationProvider); + + return http.build(); + } + + /** + * 사용자 권한의 계층을 설정. + * + * @return {@link RoleHierarchy} + */ + @Bean + public RoleHierarchy roleHierarchy() { + return RoleHierarchyImpl.fromHierarchy( + // "ROLE_ADMIN > ROLE_STAFF\nROLE_ADMIN > ROLE_USER" + """ + ROLE_ADMIN > ROLE_STAFF + ROLE_ADMIN > ROLE_USER + """); + } + + /** + * h2-console 접속은 Spring Security를 거치지 않도록 설정. + * + * @return {@link WebSecurityCustomizer} + * @see spring-security에서-h2-console-사용하기 + */ + @Bean + @ConditionalOnProperty(name = "spring.h2.console.enabled", havingValue = "true") + public WebSecurityCustomizer configureH2ConsoleEnable() { + return web -> web.ignoring().requestMatchers(PathRequest.toH2Console()); + } +} diff --git a/src/main/java/com/example/trello/config/auth/DelegateAccessDeniedHandler.java b/src/main/java/com/example/trello/config/auth/DelegateAccessDeniedHandler.java new file mode 100644 index 0000000..61e0a3e --- /dev/null +++ b/src/main/java/com/example/trello/config/auth/DelegateAccessDeniedHandler.java @@ -0,0 +1,31 @@ +package com.example.trello.config.auth; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerExceptionResolver; + +import java.io.IOException; + +@Component +public class DelegateAccessDeniedHandler implements AccessDeniedHandler { + + + private final HandlerExceptionResolver resolver; + + public DelegateAccessDeniedHandler( + @Qualifier("handlerExceptionResolver") HandlerExceptionResolver resolver) { + this.resolver = resolver; + } + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) + throws IOException, ServletException { + resolver.resolveException(request, response, null, accessDeniedException); + + } +} diff --git a/src/main/java/com/example/trello/config/auth/DelegatedAuthenticationEntryPoint.java b/src/main/java/com/example/trello/config/auth/DelegatedAuthenticationEntryPoint.java new file mode 100644 index 0000000..9e3808a --- /dev/null +++ b/src/main/java/com/example/trello/config/auth/DelegatedAuthenticationEntryPoint.java @@ -0,0 +1,29 @@ +package com.example.trello.config.auth; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerExceptionResolver; + +import java.io.IOException; + +@Component +public class DelegatedAuthenticationEntryPoint implements AuthenticationEntryPoint { + + private final HandlerExceptionResolver resolver; + + public DelegatedAuthenticationEntryPoint( + @Qualifier("handlerExceptionResolver") HandlerExceptionResolver resolver) { + this.resolver = resolver; + } + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) + throws IOException, ServletException { + resolver.resolveException(request, response, null, authException); + } +} diff --git a/src/main/java/com/example/trello/config/auth/UserDetailsImpl.java b/src/main/java/com/example/trello/config/auth/UserDetailsImpl.java new file mode 100644 index 0000000..d9c6b2f --- /dev/null +++ b/src/main/java/com/example/trello/config/auth/UserDetailsImpl.java @@ -0,0 +1,55 @@ +package com.example.trello.config.auth; + +import com.example.trello.user.User; +import com.example.trello.user.enums.Role; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.ArrayList; +import java.util.Collection; + +@Getter +@RequiredArgsConstructor +@Slf4j(topic = "Security::UserDetailsImpl") +public class UserDetailsImpl implements UserDetails { + + private final User user; + + + @Override + public Collection getAuthorities() { + Role role = this.user.getRole(); + log.info("사용자 권한: {}", role.getAuthorities()); + return new ArrayList<>(role.getAuthorities()); + } + + @Override + public String getPassword() { + return this.user.getPassword(); + } + + @Override + public String getUsername() { + return this.user.getEmail(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; } + + @Override + public boolean isCredentialsNonExpired() { + return true; } + + @Override + public boolean isEnabled() { + return true; } +} diff --git a/src/main/java/com/example/trello/config/auth/UserDetailsServiceImpl.java b/src/main/java/com/example/trello/config/auth/UserDetailsServiceImpl.java new file mode 100644 index 0000000..d0d1f2b --- /dev/null +++ b/src/main/java/com/example/trello/config/auth/UserDetailsServiceImpl.java @@ -0,0 +1,26 @@ +package com.example.trello.config.auth; + +import com.example.trello.user.User; +import com.example.trello.user.UserRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j(topic = "Security::UserDetailsServiceImpl") +public class UserDetailsServiceImpl implements UserDetailsService { + + private final UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = this.userRepository.findByEmailOrElseThrow(username); + + log.info("찾는 사용자 : {}", username); + return new UserDetailsImpl(user); + } +} diff --git a/src/main/java/com/example/trello/config/filter/JwtAuthFilter.java b/src/main/java/com/example/trello/config/filter/JwtAuthFilter.java new file mode 100644 index 0000000..3645f5c --- /dev/null +++ b/src/main/java/com/example/trello/config/filter/JwtAuthFilter.java @@ -0,0 +1,109 @@ +package com.example.trello.config.filter; + +import com.example.trello.util.AuthenticationScheme; +import com.example.trello.util.JwtProvider; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +@RequiredArgsConstructor +@Slf4j(topic = "Security::JwtAuthFilter") +public class JwtAuthFilter extends OncePerRequestFilter { + + /** + * JWT 토큰 제공자. + */ + private final JwtProvider jwtProvider; + + /** + * UserDetailsService. + */ + private final UserDetailsService userDetailsService; + + /** + * {@inheritDoc} + */ + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + log.info("URI: {}", request.getRequestURI()); + this.authenticate(request); + filterChain.doFilter(request, response); + } + + /** + * request를 이용해 인증을 처리한다. + * + * @param request {@link HttpServletRequest} + */ + private void authenticate(HttpServletRequest request) { + log.info("인증 처리."); + + // 토큰 검증. + String token = this.getTokenFromRequest(request); + if (!jwtProvider.validToken(token)) { + return; + } + + // 토큰으로부텨 username을 추출. + String username = this.jwtProvider.getUsername(token); + + // username에 해당되는 사용자를 찾는다. + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + + // SecurityContext에 인증 객체 저장. + this.setAuthentication(request, userDetails); + } + + /** + * request의 Authorization 헤더에서 토큰 값을 추출. + * + * @param request {@link HttpServletRequest} + * @return 토큰 값 (찾지 못한 경우 {@code null}) + */ + private String getTokenFromRequest(HttpServletRequest request) { + final String bearerToken = request.getHeader(HttpHeaders.AUTHORIZATION); + final String headerPrefix = AuthenticationScheme.generateType(AuthenticationScheme.BEARER); + + boolean tokenFound = + StringUtils.hasText(bearerToken) && bearerToken.startsWith(headerPrefix); + if (tokenFound) { + return bearerToken.substring(headerPrefix.length()); + } + + return null; + } + + /** + * {@code SecurityContext}에 인증 객체를 저장한다. + * + * @param request {@link HttpServletRequest} + * @param userDetails 찾아온 사용자 정보 + */ + private void setAuthentication(HttpServletRequest request, UserDetails userDetails) { + log.info("SecurityContext에 Authentication 저장."); + + // 찾아온 사용자 정보로 인증 객체를 생성. + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + userDetails, userDetails.getPassword(), userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + + // SecurityContext에 인증 객체 저장. + SecurityContextHolder.getContext().setAuthentication(authentication); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/trello/user/User.java b/src/main/java/com/example/trello/user/User.java index 64647ae..3decebb 100644 --- a/src/main/java/com/example/trello/user/User.java +++ b/src/main/java/com/example/trello/user/User.java @@ -46,4 +46,8 @@ public User(String email, String password, String nickname, Role role, AccountSt public void deletedAccount(AccountStatus status) { this.status = status; } + + public boolean isDeletedAccount(User user) { + return user.getStatus().equals(AccountStatus.DELETED); + } } diff --git a/src/main/java/com/example/trello/user/UserController.java b/src/main/java/com/example/trello/user/UserController.java deleted file mode 100644 index 25cfcb2..0000000 --- a/src/main/java/com/example/trello/user/UserController.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.example.trello.user; - -import com.example.trello.user.dto.LoginRequestDto; -import com.example.trello.user.dto.SignupRequestDto; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpSession; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.server.ResponseStatusException; - -@RestController -@RequestMapping("/users") -@RequiredArgsConstructor -public class UserController { - - private final UserService userService; - - @PostMapping("/sign-up") - public ResponseEntity signupUser(@Valid @RequestBody SignupRequestDto requestDto) { - userService.signupUser(requestDto); - - return ResponseEntity.status(HttpStatus.CREATED).body("회원가입이 완료되었습니다."); - } - - @PostMapping("/login") - public ResponseEntity login( - @RequestBody LoginRequestDto requestDto, - HttpServletRequest httpServletRequest - ) { - User loginUser = userService.login(requestDto); - - HttpSession session = httpServletRequest.getSession(); - - if (session.getAttribute("id") != null) { - throw new RuntimeException(); - } - - session.setAttribute("id", loginUser); - return ResponseEntity.ok().body("정상적으로 로그인 되었습니다."); - } - - @PostMapping("/logout") - public ResponseEntity logout(HttpServletRequest httpServletRequest) { - HttpSession session = httpServletRequest.getSession(); - - if (session != null) { - session.invalidate(); - } - - return ResponseEntity.ok().body("로그아웃 되었습니다."); - } - - @DeleteMapping("/leave") - public ResponseEntity leave( - @SessionAttribute("id") User user, - HttpServletRequest httpServletRequest - ) { - userService.leave(user.getId()); - - HttpSession session = httpServletRequest.getSession(); - if (session != null) { - session.invalidate(); - } - - return ResponseEntity.ok().body("회원 탈퇴가 정상적으로 처리되었습니다."); - } -} diff --git a/src/main/java/com/example/trello/user/UserService.java b/src/main/java/com/example/trello/user/UserService.java index 32e8b4d..969ec45 100644 --- a/src/main/java/com/example/trello/user/UserService.java +++ b/src/main/java/com/example/trello/user/UserService.java @@ -1,10 +1,18 @@ package com.example.trello.user; +import com.example.trello.user.dto.JwtAuthResponse; import com.example.trello.user.dto.LoginRequestDto; import com.example.trello.user.dto.SignupRequestDto; import com.example.trello.user.enums.AccountStatus; +import com.example.trello.util.AuthenticationScheme; +import com.example.trello.util.JwtProvider; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,10 +22,13 @@ @Service @RequiredArgsConstructor +@Slf4j public class UserService { private final UserRepository userRepository; + private final AuthenticationManager authenticationManager; private final BCryptPasswordEncoder bCryptPasswordEncoder; + private final JwtProvider jwtProvider; public void signupUser(SignupRequestDto requestDto) { Optional findUser = userRepository.findByEmail(requestDto.getEmail()); @@ -43,20 +54,27 @@ public void signupUser(SignupRequestDto requestDto) { } - public User login(LoginRequestDto requestDto) { + public JwtAuthResponse login(LoginRequestDto requestDto) { User findUser = userRepository.findByEmailOrElseThrow(requestDto.getEmail()); - if (findUser.getStatus().equals(AccountStatus.DELETED)) { + if (findUser.isDeletedAccount(findUser)) { throw new RuntimeException(); } - String encodedPassword = bCryptPasswordEncoder.encode(requestDto.getPassword()); + this.validatePassword(requestDto.getPassword(), findUser.getPassword()); - if (bCryptPasswordEncoder.matches(findUser.getPassword(), encodedPassword)) { - throw new RuntimeException(); - } + Authentication authentication = this.authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + requestDto.getEmail(), + requestDto.getPassword()) + ); + log.info("SecurituContext에 Authentication 저장"); + SecurityContextHolder.getContext().setAuthentication(authentication); + + String accessToken = jwtProvider.generateToken(authentication); + log.info("토큰 생성: {}",accessToken); - return findUser; + return new JwtAuthResponse(AuthenticationScheme.BEARER.getName(), accessToken); } @Transactional @@ -64,4 +82,12 @@ public void leave(Long userId) { User findUser = userRepository.findByIdOrElseThrow(userId); findUser.deletedAccount(AccountStatus.DELETED); } + + private void validatePassword(String rawPassword, String encodedPassword) + throws RuntimeException { + boolean notValid = !bCryptPasswordEncoder.matches(rawPassword, encodedPassword); + if (notValid) { + throw new RuntimeException(); + } + } } diff --git a/src/main/java/com/example/trello/user/controller/UserController.java b/src/main/java/com/example/trello/user/controller/UserController.java new file mode 100644 index 0000000..be78ec3 --- /dev/null +++ b/src/main/java/com/example/trello/user/controller/UserController.java @@ -0,0 +1,72 @@ +package com.example.trello.user.controller; + +import com.example.trello.user.User; +import com.example.trello.user.UserService; +import com.example.trello.user.dto.JwtAuthResponse; +import com.example.trello.user.dto.LoginRequestDto; +import com.example.trello.user.dto.SignupRequestDto; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("/users") +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + + @PostMapping("/sign-up") + public ResponseEntity signupUser(@Valid @RequestBody SignupRequestDto requestDto) { + userService.signupUser(requestDto); + + return ResponseEntity.status(HttpStatus.CREATED).body("회원가입이 완료되었습니다."); + } + + @PostMapping("/login") + public ResponseEntity login( + @Valid @RequestBody LoginRequestDto requestDto + ) { + JwtAuthResponse authResponse = this.userService.login(requestDto); + + return ResponseEntity.ok().body(authResponse); + } + + @PostMapping("/logout") + public ResponseEntity logout( + HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse, + Authentication authentication + ) throws RuntimeException { + if (authentication != null && authentication.isAuthenticated()) { + new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, null); + + return ResponseEntity.ok().body("로그아웃 되었습니다."); + } + throw new RuntimeException(); + } + + @DeleteMapping("/{userId}") + public ResponseEntity leave( + @PathVariable Long userId, + HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse, + Authentication authentication + ) throws RuntimeException { + userService.leave(userId); + + if (authentication != null && authentication.isAuthenticated()) { + new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, null); + } + + return ResponseEntity.ok().body("회원 탈퇴가 정상적으로 처리되었습니다."); + } +} diff --git a/src/main/java/com/example/trello/user/dto/JwtAuthResponse.java b/src/main/java/com/example/trello/user/dto/JwtAuthResponse.java new file mode 100644 index 0000000..cc2af04 --- /dev/null +++ b/src/main/java/com/example/trello/user/dto/JwtAuthResponse.java @@ -0,0 +1,28 @@ +package com.example.trello.user.dto; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PACKAGE) +public class JwtAuthResponse { + + /** + * access token 인증 방식. + */ + private String tokenAuthScheme; + + /** + * access token. + */ + private String accessToken; + + /** + * 생성자. + */ + public JwtAuthResponse(String tokenAuthScheme, String accessToken) { + this.tokenAuthScheme = tokenAuthScheme; + this.accessToken = accessToken; + } +} diff --git a/src/main/java/com/example/trello/util/AuthenticationScheme.java b/src/main/java/com/example/trello/util/AuthenticationScheme.java new file mode 100644 index 0000000..844dd91 --- /dev/null +++ b/src/main/java/com/example/trello/util/AuthenticationScheme.java @@ -0,0 +1,22 @@ +package com.example.trello.util; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum AuthenticationScheme { + BEARER("Bearer"); + + private final String name; + + /** + * Authorization 헤더의 값으로 사용될 prefix를 생성. + * + * @param authenticationScheme {@link AuthenticationScheme} + * @return 생성된 prefix + */ + public static String generateType(AuthenticationScheme authenticationScheme) { + return authenticationScheme.getName() + " "; + } +} diff --git a/src/main/java/com/example/trello/util/JwtProvider.java b/src/main/java/com/example/trello/util/JwtProvider.java new file mode 100644 index 0000000..9b689f0 --- /dev/null +++ b/src/main/java/com/example/trello/util/JwtProvider.java @@ -0,0 +1,170 @@ +package com.example.trello.util; + +import com.example.trello.user.User; +import com.example.trello.user.UserRepository; +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import jakarta.persistence.EntityNotFoundException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.function.Function; + +@Component +@RequiredArgsConstructor +@Slf4j +public class JwtProvider { + + /** + * JWT 시크릿 키. + */ + @Value("${jwt.secret}") + private String secret; + + /** + * 토큰 만료시간(밀리초). + */ + @Getter + @Value("${jwt.expiry-millis}") + private Long expiryMillis; + + /** + * Member repository. + */ + private final UserRepository userRepository; + + /** + *

토큰 생성 후 리턴.

+ * 입력받은 {@link Authentication}에서 추출한 {@code username}으로 {@link #generateTokenBy(String)} 이용한다. + * + * @param authentication 인증 완료된 후 세부 정보 + * @return 생성된 토큰 + * @throws EntityNotFoundException 입력받은 이메일에 해당하는 사용자를 찾지 못했을 경우 + */ + public String generateToken(Authentication authentication) throws EntityNotFoundException { + String username = authentication.getName(); + return this.generateTokenBy(username); + } + + /** + * 입력받은 토큰에서 {@link Authentication}의 {@code username}을 리턴. + * + * @param token 토큰 + * @return username + */ + public String getUsername(String token) { + Claims claims = this.getClaims(token); + return claims.getSubject(); + } + + /** + * 토큰이 유효한지 확인. + * + * @param token 토큰 + * @return 유효 여부. + *
    + *
  • {@code true} - 유효함.
  • + *
  • {@code false} - 유효하지 않음.
  • + *
+ */ + public boolean validToken(String token) throws JwtException { + try { + return !this.tokenExpired(token); + } catch (MalformedJwtException e) { + log.error("Invalid JWT token: {}", e.getMessage()); + } catch (ExpiredJwtException e) { + log.error("JWT token is expired: {}", e.getMessage()); + } catch (UnsupportedJwtException e) { + log.error("JWT token is unsupported: {}", e.getMessage()); + } + + return false; + } + + /** + *

이메일 주소를 이용해 토큰을 생성한 후 리턴.

+ *

토큰 생성에는 HS256 알고리즘을 이용.

+ * + * @param email 이메일 + * @return 생성된 토큰 + * @throws EntityNotFoundException 입력받은 이메일에 해당하는 사용자를 찾지 못했을 경우 + */ + private String generateTokenBy(String email) throws EntityNotFoundException { + User user = this.userRepository.findByEmail(email) + .orElseThrow(() -> new EntityNotFoundException("해당 email에 맞는 값이 존재하지 않습니다.")); + Date currentDate = new Date(); + Date expireDate = new Date(currentDate.getTime() + this.expiryMillis); + + return Jwts.builder() + .subject(email) + .issuedAt(currentDate) + .expiration(expireDate) + .claim("role", user.getRole()) + .signWith(Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)), Jwts.SIG.HS256) + .compact(); + } + + /** + * JWT의 claim 부분을 추출. + * + * @param token 토큰 + * @return {@link Claims} + * @see JSON 웹 토큰 + */ + private Claims getClaims(String token) { + if (!StringUtils.hasText(token)) { + throw new MalformedJwtException("토큰이 비어 있습니다."); + } + + return Jwts.parser() + .verifyWith(Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8))) + .build() + .parseSignedClaims(token) + .getPayload(); + } + + /** + * 입력받은 토큰의 만료 여부. + * + * @param token 토큰 + * @return 만료 여부 + *
    + *
  • {@code true} - 만료됨.
  • + *
  • {@code false} - 만료되지 않음.
  • + *
+ */ + private boolean tokenExpired(String token) { + final Date expiration = this.getExpirationDateFromToken(token); + return expiration.before(new Date()); + } + + /** + * 입력 받은 토큰의 만료일을 리턴. + * + * @param token 토큰 + * @return 만료일 + */ + private Date getExpirationDateFromToken(String token) { + return this.resolveClaims(token, Claims::getExpiration); + } + + /** + * 토큰에 입력 받은 로직을 적용하고 그 결과를 리턴. + * + * @param token 토큰 + * @param claimsResolver 토큰에 적용할 로직. + * @param {@code claimsResolver}의 리턴 타입. + * @return {@code T} + */ + private T resolveClaims(String token, Function claimsResolver) { + final Claims claims = this.getClaims(token); + return claimsResolver.apply(claims); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index af41afb..569448a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,10 +4,13 @@ spring.datasource.url=jdbc:mysql://localhost:3306/${DB_NAME} spring.datasource.username=${DB_USERNAME} spring.datasource.password=${DB_PASSWORD} spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.jpa.hibernate.ddl-auto=none +spring.jpa.hibernate.ddl-auto=create spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect + +jwt.secret=${jwt.secret} +jwt.expiry-millis=${jwt.expiry-millis:3600000} \ No newline at end of file From 50d712c8961bf69a971627f91b7a30e7d13f254e Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 18:15:09 +0900 Subject: [PATCH 082/181] =?UTF-8?q?refactor=20:=20BoardController=20?= =?UTF-8?q?=EA=B3=BC=20BoardService=20=EC=97=90=EC=84=9C=20Dto=20=EB=A5=BC?= =?UTF-8?q?=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=EB=A1=9C=20=EB=B0=9B?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/board/BoardController.java | 6 ++--- .../example/trello/board/BoardService.java | 23 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 28cc13a..8a255fe 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -16,13 +16,13 @@ public class BoardController { @PostMapping public ResponseEntity createBoard(@RequestBody BoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { - BoardResponseDto boardResponseDto = boardService.createBoard(dto.getWorkspaceId(), dto.getTitle(), dto.getColor(), dto.getImage(), loginUserId); + BoardResponseDto boardResponseDto = boardService.createBoard(dto, loginUserId); return new ResponseEntity<>(boardResponseDto, HttpStatus.CREATED); } @GetMapping public ResponseEntity> viewAllBoard(@RequestBody viewAllBoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { - List boardResponseDtoList = boardService.viewAllBoard(dto.getWorkspaceId(), loginUserId); + List boardResponseDtoList = boardService.viewAllBoard(dto, loginUserId); return new ResponseEntity<>(boardResponseDtoList, HttpStatus.OK); } @@ -34,7 +34,7 @@ public ResponseEntity viewBoard(@PathVariable Long board @PatchMapping("/{boardId}") public ResponseEntity updateBoard(@PathVariable Long boardId, @RequestBody UpdateBoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { - BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto.getTitle(), dto.getColor(), dto.getImage(), loginUserId); + BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto, loginUserId); return new ResponseEntity<>(updatedBoardResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 6d91155..435e854 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -1,7 +1,6 @@ package com.example.trello.board; -import com.example.trello.board.dto.BoardDetailResponseDto; -import com.example.trello.board.dto.BoardResponseDto; +import com.example.trello.board.dto.*; import com.example.trello.card.Card; import com.example.trello.card.CardRepository; import com.example.trello.card.dto.GetCardResponseDto; @@ -29,8 +28,8 @@ public class BoardService { private final CardRepository cardRepository; @Transactional - public BoardResponseDto createBoard(Long workspaceId, String title, String color, String image, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); + public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, dto.getWorkspaceId()); if (findWorkspaceMember.getRole() == READ_ONLY) { throw new RuntimeException("읽기 전용 역할은 보드를 생성할 수 없습니다."); @@ -39,9 +38,9 @@ public BoardResponseDto createBoard(Long workspaceId, String title, String color Workspace workspace = findWorkspaceMember.getWorkspace(); Board board = Board.builder() - .title(title) - .color(color) - .image(image) + .title(dto.getTitle()) + .color(dto.getColor()) + .image(dto.getImage()) .workspace(workspace) .build(); @@ -51,12 +50,12 @@ public BoardResponseDto createBoard(Long workspaceId, String title, String color } @Transactional(readOnly = true) - public List viewAllBoard(Long workspaceId, Long loginUserId) { - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(loginUserId, workspaceId)) { + public List viewAllBoard(viewAllBoardRequestDto dto, Long loginUserId) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(loginUserId, dto.getWorkspaceId())) { throw new RuntimeException("해당 워크스페이스의 멤버가 아닙니다."); } - List findBoardList = boardRepository.findAllByWorkspaceId(workspaceId); + List findBoardList = boardRepository.findAllByWorkspaceId(dto.getWorkspaceId()); return findBoardList .stream() @@ -86,7 +85,7 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { } @Transactional - public BoardResponseDto updateBoard(Long boardId, String title, String color, String image, Long loginUserId) { + public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); @@ -94,7 +93,7 @@ public BoardResponseDto updateBoard(Long boardId, String title, String color, St throw new RuntimeException("읽기 전용 역할은 보드를 수정할 수 없습니다."); } - findBoard.updateBoard(title, color, image); + findBoard.updateBoard(dto.getTitle(), dto.getColor(), dto.getImage()); return BoardResponseDto.toDto(findBoard); } From 03bcb8869eefcaae33827a569ad8cb84ea42cb1c Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 18:20:07 +0900 Subject: [PATCH 083/181] =?UTF-8?q?refactor=20:=20Workspace=20=EB=B0=8F=20?= =?UTF-8?q?WorkspaceMember=20=EA=B4=80=EB=A0=A8=20Controller,=20Service=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=A5=BC=20dto=20=EB=A1=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/workspace/WorkspaceController.java | 4 ++-- .../trello/workspace/WorkspaceService.java | 12 +++++++----- .../WorkspaceMemberController.java | 4 ++-- .../workspace_member/WorkspaceMemberService.java | 16 +++++++++------- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index bee1685..231a3e6 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -18,7 +18,7 @@ public class WorkspaceController { @PostMapping public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto, @SessionAttribute("id") Long loginUserId) { - WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto.getTitle(), dto.getDescription(), loginUserId); + WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto, loginUserId); return new ResponseEntity<>(createdWorkspaceResponseDto, HttpStatus.CREATED); } @@ -37,7 +37,7 @@ public ResponseEntity viewWorkspace(@PathVariable Long wor @PatchMapping("/{workspaceId}") public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto, @SessionAttribute("id") Long loginUserId) { - WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto.getTitle(), dto.getDescription(), loginUserId); + WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto, loginUserId); return new ResponseEntity<>(updatedWorkspaceResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 7987d37..b402ea4 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -2,6 +2,8 @@ import com.example.trello.user.User; import com.example.trello.user.UserRepository; +import com.example.trello.workspace.dto.UpdateWorkspaceRequestDto; +import com.example.trello.workspace.dto.WorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceResponseDto; @@ -26,7 +28,7 @@ public class WorkspaceService { private final WorkspaceMemberRepository workspaceMemberRepository; @Transactional - public WorkspaceResponseDto createWorkspace(String title, String description, Long loginUserId) { + public WorkspaceResponseDto createWorkspace(WorkspaceRequestDto dto, Long loginUserId) { User loginUser = userRepository.findByIdOrElseThrow(loginUserId); if (loginUser.getRole() != ADMIN) { @@ -34,8 +36,8 @@ public WorkspaceResponseDto createWorkspace(String title, String description, Lo } Workspace workspace = Workspace.builder() - .title(title) - .description(description) + .title(dto.getTitle()) + .description(dto.getDescription()) .user(loginUser) .build(); @@ -77,7 +79,7 @@ public WorkspaceResponseDto viewWorkspace(Long workspaceId, Long loginUserId) { } @Transactional - public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, String description, Long loginUserId) { + public WorkspaceResponseDto updateWorkspace(Long workspaceId, UpdateWorkspaceRequestDto dto, Long loginUserId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { @@ -86,7 +88,7 @@ public WorkspaceResponseDto updateWorkspace(Long workspaceId, String title, Stri Workspace workspace = findWorkspaceMember.getWorkspace(); - workspace.updateWorkspace(title, description); + workspace.updateWorkspace(dto.getTitle(), dto.getDescription()); return WorkspaceResponseDto.toDto(workspace); } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java index 390574f..ea63b92 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java @@ -17,13 +17,13 @@ public class WorkspaceMemberController { @PostMapping("/member-invite") public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto, @SessionAttribute("id") Long loginUserId) { - WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto.getEmail(), loginUserId); + WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto, loginUserId); return new ResponseEntity<>(workspaceMemberResponseDto, HttpStatus.CREATED); } @PatchMapping("/member-role") public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto, @SessionAttribute("id") Long loginUserId) { - workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto.getWorkspaceMemberId(), dto.getRole(), loginUserId); + workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto, loginUserId); return "권한이 " + dto.getRole() + "로 변경되었습니다."; } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 3537582..d33383b 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -4,6 +4,8 @@ import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_member.dto.UpdateWorkspaceMemberRoleDto; +import com.example.trello.workspace_member.dto.WorkspaceMemberRequestDto; import com.example.trello.workspace_member.dto.WorkspaceMemberResponseDto; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; @@ -24,14 +26,14 @@ public class WorkspaceMemberService { private final UserRepository userRepository; @Transactional - public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String email, Long loginUserId) { + public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, WorkspaceMemberRequestDto dto, Long loginUserId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("멤버를 초대할 권한이 없습니다."); } - User findUser = userRepository.findByEmailOrElseThrow(email); + User findUser = userRepository.findByEmailOrElseThrow(dto.getEmail()); Workspace workspace = findWorkspaceMember.getWorkspace(); WorkspaceMember workspaceMember = WorkspaceMember.builder() @@ -46,10 +48,10 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, String } @Transactional - public void updateWorkspaceMemberRole(Long workspaceId, Long workspaceMemberId , WorkspaceMemberRole role, Long loginUserId) { + public void updateWorkspaceMemberRole(Long workspaceId, UpdateWorkspaceMemberRoleDto dto, Long loginUserId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); - if (role == WORKSPACE && findWorkspaceMember.getUser().getRole() != ADMIN) { + if (dto.getRole() == WORKSPACE && findWorkspaceMember.getUser().getRole() != ADMIN) { throw new RuntimeException("WORKSPACE 역할은 ADMIN 만 부여할 수 있습니다."); } @@ -57,9 +59,9 @@ public void updateWorkspaceMemberRole(Long workspaceId, Long workspaceMemberId , throw new RuntimeException("멤버 역할을 수정할 권한이 없습니다."); } - WorkspaceMember roleUpdatedWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(workspaceMemberId); + WorkspaceMember roleUpdatedWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(dto.getWorkspaceMemberId()); - roleUpdatedWorkspaceMember.updateRole(role); - log.info("{}의 역할이 {}로 변경되었습니다.", roleUpdatedWorkspaceMember.getUser().getNickname(), role); + roleUpdatedWorkspaceMember.updateRole(dto.getRole()); + log.info("{}의 역할이 {}로 변경되었습니다.", roleUpdatedWorkspaceMember.getUser().getNickname(), dto.getRole()); } } From 1643974ada9c7342e1bc2db8edb18a9823dadb25 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 18:28:12 +0900 Subject: [PATCH 084/181] =?UTF-8?q?refactor=20:=20Workspace=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=EC=A1=B0=ED=9A=8C=EC=97=90=EC=84=9C=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=98=EA=B2=8C=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=EC=97=90=202=EB=B2=88=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=ED=95=98=EB=8D=98=EA=B2=83=EC=9D=84=201?= =?UTF-8?q?=EB=B2=88=20=EC=A0=91=EA=B7=BC=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인한 유저Id로 UserRepository에서 User 찾고, 찾은 User로 Member 검색하던 로직 → 로그인한 유저아이디로 WorkspaceMemberRepository 에 UserId로 바로 검색하도록 수정 --- .../java/com/example/trello/workspace/WorkspaceService.java | 3 +-- .../trello/workspace_member/WorkspaceMemberRepository.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index b402ea4..3003ddf 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -55,8 +55,7 @@ public WorkspaceResponseDto createWorkspace(WorkspaceRequestDto dto, Long loginU @Transactional(readOnly = true) public List viewAllWorkspace(Long loginUserId) { - User findUser = userRepository.findByIdOrElseThrow(loginUserId); - List WorkspaceMemberListByUser = workspaceMemberRepository.findByUser(findUser); + List WorkspaceMemberListByUser = workspaceMemberRepository.findByUserId(loginUserId); List workspaceList = new ArrayList<>(); for (WorkspaceMember workspaceMember : WorkspaceMemberListByUser) { diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index 125f7d0..6148a65 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -9,7 +9,7 @@ @Repository public interface WorkspaceMemberRepository extends JpaRepository { - List findByUser(User user); + List findByUserId(Long userId); Optional findByUserIdAndWorkspaceId(Long userId, Long workspaceId); Boolean existsByUserIdAndWorkspaceId(Long userId, Long workspaceId); From afc74e7eb4170fdac552c0c684472e7a9c41ba7b Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 19:00:13 +0900 Subject: [PATCH 085/181] =?UTF-8?q?Fix=20:=20=EB=88=84=EB=9D=BD=EB=90=9C?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 2 +- .../example/trello/card/cardrepository/CardRepository.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 6d91155..f84adc3 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -3,7 +3,7 @@ import com.example.trello.board.dto.BoardDetailResponseDto; import com.example.trello.board.dto.BoardResponseDto; import com.example.trello.card.Card; -import com.example.trello.card.CardRepository; +import com.example.trello.card.cardrepository.CardRepository; import com.example.trello.card.dto.GetCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepository.java b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java index faa740a..9ef8a1e 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepository.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java @@ -1,12 +1,17 @@ package com.example.trello.card.cardrepository; import com.example.trello.card.Card; +import com.example.trello.cardlist.CardList; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface CardRepository extends JpaRepository, CardRepositoryCustom { + List findByCardList(CardList cardList); + default Card findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(()->new RuntimeException()); } From 5c29080ab3ec0b7a52544e15018e5c2d2b245120 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 19:00:35 +0900 Subject: [PATCH 086/181] =?UTF-8?q?Fix=20:=20startAt,=20endAt=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/dto/GetCardResponseDto.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java b/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java index 76edb41..0ccdd49 100644 --- a/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java +++ b/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java @@ -5,6 +5,7 @@ import com.example.trello.cardlist.dto.GetCardListResponseDto; import lombok.Getter; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -13,10 +14,10 @@ public class GetCardResponseDto { private Long id; private String title; private String description; - private LocalDateTime startAt; - private LocalDateTime endAt; + private LocalDate startAt; + private LocalDate endAt; - public GetCardResponseDto(Long id, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + public GetCardResponseDto(Long id, String title, String description, LocalDate startAt, LocalDate endAt) { this.id = id; this.title = title; this.description = description; From fbe66d627dcc38ab7f6556fec3e3e82c80206eca Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Fri, 27 Dec 2024 19:02:48 +0900 Subject: [PATCH 087/181] =?UTF-8?q?feat=20:=20=EA=B3=B5=ED=86=B5=EB=90=9C?= =?UTF-8?q?=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/CardListErrorCode.java | 14 +++++++++ .../common/exception/CardListException.java | 10 +++++++ .../common/exception/ErrorResponse.java | 12 ++++++++ .../exception/GlobalExceptionHandler.java | 30 +++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 src/main/java/com/example/trello/common/exception/CardListErrorCode.java create mode 100644 src/main/java/com/example/trello/common/exception/CardListException.java create mode 100644 src/main/java/com/example/trello/common/exception/ErrorResponse.java create mode 100644 src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java diff --git a/src/main/java/com/example/trello/common/exception/CardListErrorCode.java b/src/main/java/com/example/trello/common/exception/CardListErrorCode.java new file mode 100644 index 0000000..4c830d7 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/CardListErrorCode.java @@ -0,0 +1,14 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +@Getter +public enum CardListErrorCode { + CARD_LIST_NOT_FOUND("리스트를 찾을 수 없습니다.", HttpStatus.NOT_FOUND); + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/CardListException.java b/src/main/java/com/example/trello/common/exception/CardListException.java new file mode 100644 index 0000000..ff97bab --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/CardListException.java @@ -0,0 +1,10 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class CardListException extends RuntimeException { + private CardListErrorCode cardListErrorCode; +} diff --git a/src/main/java/com/example/trello/common/exception/ErrorResponse.java b/src/main/java/com/example/trello/common/exception/ErrorResponse.java new file mode 100644 index 0000000..6007082 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/ErrorResponse.java @@ -0,0 +1,12 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +@Getter +@AllArgsConstructor +@Builder +public class ErrorResponse { + private String errorCode; + private String message; +} diff --git a/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java b/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..563e089 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java @@ -0,0 +1,30 @@ +package com.example.trello.common.exception; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(CardListException.class) + public ResponseEntity handleCardListException(CardListException e) { + ErrorResponse message = ErrorResponse.builder() + .errorCode(e.getCardListErrorCode().name()) + .message(e.getCardListErrorCode().getMessage()) + .build(); + return new ResponseEntity<>(message, e.getCardListErrorCode().getHttpStatus()); + + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidException(MethodArgumentNotValidException e) { + ErrorResponse message = ErrorResponse.builder() + .errorCode(e.getStatusCode().toString()) + .message(e.getBindingResult().getFieldError().getDefaultMessage()) + .build(); + return new ResponseEntity<>(message, e.getStatusCode()); + + } +} From 425ed11a1a36f160efd4a0459e7657f9bf9a9bbe Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 19:20:44 +0900 Subject: [PATCH 088/181] =?UTF-8?q?Fix=20:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EA=B5=90=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/CardController.java | 6 +++--- src/main/java/com/example/trello/card/CardService.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 44b90ad..cbd5a9a 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -38,9 +38,9 @@ public ResponseEntity deleteCard(@PathVariable Long cardsId, @SessionAtt return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); } - @GetMapping("/{cardsId}") - public ResponseEntity findCard(@PathVariable Long cardsId) { - CardResponseDto responseDto = cardService.findCardById(cardsId); + @GetMapping("/{cardId}") + public ResponseEntity findCard(@PathVariable Long cardId) { + CardResponseDto responseDto = cardService.findCardById(cardId); return new ResponseEntity<>(responseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 77923a3..e5a207c 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -91,8 +91,8 @@ public void deleteCardService(Long cardId, Long userId) { } // 카드 단건 조회 - public CardResponseDto findCardById(Long cardsId) { - Card card = cardRepository.findByIdOrElseThrow(cardsId); + public CardResponseDto findCardById(Long cardId) { + Card card = cardRepository.findByIdOrElseThrow(cardId); return CardResponseDto.toDto(card); } From 17cae2d404e68947a6a9ac4bc810ee04b0248004 Mon Sep 17 00:00:00 2001 From: jut Date: Fri, 27 Dec 2024 19:25:56 +0900 Subject: [PATCH 089/181] =?UTF-8?q?fix=20:=20properties=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20config=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/config/WebConfig.java | 17 ++++++++--------- src/main/resources/application.properties | 4 ++-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/example/trello/config/WebConfig.java b/src/main/java/com/example/trello/config/WebConfig.java index 18b6960..147007c 100644 --- a/src/main/java/com/example/trello/config/WebConfig.java +++ b/src/main/java/com/example/trello/config/WebConfig.java @@ -1,6 +1,6 @@ package com.example.trello.config; -import jakarta.servlet.DispatcherType; +import com.example.trello.config.auth.UserDetailsServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.servlet.PathRequest; @@ -17,25 +17,25 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.AccessDeniedHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity // SecurityFilterChain 빈 설정을 위해 필요. @RequiredArgsConstructor public class WebConfig { - private final AuthenticationProvider authenticationProvider; + private final UserDetailsServiceImpl userDetailsServiceImpl; + + + private final AuthenticationProvider authenticationProvider; /** * AuthenticationEntryPoint. */ private final AuthenticationEntryPoint authEntryPoint; - /** * AccessDeniedHandler. */ private final AccessDeniedHandler accessDeniedHandler; - /** * 화이트 리스트. */ @@ -53,10 +53,9 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth.requestMatchers(WHITE_LIST).permitAll() - .requestMatchers("/admins/**").hasRole("ADMIN") - .requestMatchers("/users/**").hasRole("USER") - // 나머지는 인증이 필요 - .anyRequest().authenticated() +// .requestMatchers("/admins/**").hasRole("ADMIN") +// .requestMatchers("/users/**").hasRole("user") + .anyRequest().permitAll() ) // Spring Security 예외에 대한 처리를 핸들러에 위임. .exceptionHandling(handler -> handler diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 569448a..b419c31 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -12,5 +12,5 @@ spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect -jwt.secret=${jwt.secret} -jwt.expiry-millis=${jwt.expiry-millis:3600000} \ No newline at end of file +jwt.secret="036c4fe3ec667532545b9e8fa7e2a98a22f439dff102623c097715060e2da68c" +jwt.expiry-millis=3600000 \ No newline at end of file From 128c0a2b2bce558317eb705ea8a4779895f92743 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 19:41:27 +0900 Subject: [PATCH 090/181] =?UTF-8?q?Fix=20:=20@Transactional=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/CardService.java | 6 ++++++ .../java/com/example/trello/comment/CommentService.java | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index e5a207c..067355e 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -13,6 +13,7 @@ import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -34,6 +35,7 @@ public class CardService { private final WorkspaceMemberRepository workspaceMemberRepository; // 카드 생성 + @Transactional public CardResponseDto createdCardService(CardRequestDto requestDto, Long userId) { User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); @@ -60,6 +62,7 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, Long userId } //카드 업데이트 + @Transactional public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, Long userId) { Card card = cardRepository.findByIdOrElseThrow(cardId); @@ -79,6 +82,7 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque } // 카드 삭제 + @Transactional public void deleteCardService(Long cardId, Long userId) { Card card = cardRepository.findByIdOrElseThrow(cardId); @@ -91,12 +95,14 @@ public void deleteCardService(Long cardId, Long userId) { } // 카드 단건 조회 + @Transactional public CardResponseDto findCardById(Long cardId) { Card card = cardRepository.findByIdOrElseThrow(cardId); return CardResponseDto.toDto(card); } // 카드 다건 조회(조건 O) + @Transactional public CardPageResponseDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index cdaf667..17aa0e9 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -10,6 +10,7 @@ import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import jakarta.servlet.http.HttpServletRequest; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; @@ -22,6 +23,7 @@ public class CommentService { private final WorkspaceMemberRepository workspaceMemberRepository; + @Transactional public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServletRequest servletRequest) { User user = (User) servletRequest.getSession().getAttribute("id"); @@ -42,6 +44,7 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServle return CommentResponseDto.toDto(comment); } + @Transactional public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { User user = (User) servletRequest.getSession().getAttribute("id"); @@ -60,6 +63,7 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto } + @Transactional public void deleteComment(Long commentId, HttpServletRequest servletRequest) { User user = (User) servletRequest.getSession().getAttribute("id"); From 8f0ca1d9f0dc9ea68a92c620be8e9890ca46f781 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 19:41:50 +0900 Subject: [PATCH 091/181] =?UTF-8?q?Fix=20:=20Mapping=20url=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/CardController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index cbd5a9a..a7e5c91 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -26,13 +26,13 @@ public ResponseEntity createdCard(@RequestBody CardRequestDto r return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } - @PatchMapping("/{cardsId}/updateCards") + @PatchMapping("/{cardId}") public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto, @SessionAttribute("id") Long userid) { CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, userid); return new ResponseEntity<>(responseDto, HttpStatus.OK); } - @DeleteMapping("/{cardsId}") + @DeleteMapping("/{cardId}") public ResponseEntity deleteCard(@PathVariable Long cardsId, @SessionAttribute("id") Long userid) { cardService.deleteCardService(cardsId, userid); return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); From 6fcda9c0f8d3829ca24231b0dded861f3f58485a Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 20:41:09 +0900 Subject: [PATCH 092/181] =?UTF-8?q?refactor=20:=20RuntimeException=20?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8D=98=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EC=BB=A4=EC=8A=A4=ED=85=80?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/board/BoardService.java | 11 +++---- .../java/com/example/trello/card/Card.java | 5 ++-- .../trello/card/dto/GetCardResponseDto.java | 7 +++-- .../common/exception/BoardErrorCode.java | 17 +++++++++++ .../common/exception/BoardException.java | 11 +++++++ .../exception/GlobalExceptionHandler.java | 30 +++++++++++++++++++ .../common/exception/WorkspaceErrorCode.java | 18 +++++++++++ .../common/exception/WorkspaceException.java | 10 +++++++ .../exception/WorkspaceMemberErrorCode.java | 19 ++++++++++++ .../exception/WorkspaceMemberException.java | 10 +++++++ .../trello/workspace/WorkspaceService.java | 8 +++-- .../WorkspaceMemberService.java | 10 +++++-- 12 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/example/trello/common/exception/BoardErrorCode.java create mode 100644 src/main/java/com/example/trello/common/exception/BoardException.java create mode 100644 src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java create mode 100644 src/main/java/com/example/trello/common/exception/WorkspaceException.java create mode 100644 src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java create mode 100644 src/main/java/com/example/trello/common/exception/WorkspaceMemberException.java diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 435e854..1f9eb51 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -7,6 +7,7 @@ import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; import com.example.trello.cardlist.dto.GetCardListResponseDto; +import com.example.trello.common.exception.*; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; @@ -32,7 +33,7 @@ public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, dto.getWorkspaceId()); if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new RuntimeException("읽기 전용 역할은 보드를 생성할 수 없습니다."); + throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); } Workspace workspace = findWorkspaceMember.getWorkspace(); @@ -52,7 +53,7 @@ public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { @Transactional(readOnly = true) public List viewAllBoard(viewAllBoardRequestDto dto, Long loginUserId) { if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(loginUserId, dto.getWorkspaceId())) { - throw new RuntimeException("해당 워크스페이스의 멤버가 아닙니다."); + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } List findBoardList = boardRepository.findAllByWorkspaceId(dto.getWorkspaceId()); @@ -68,7 +69,7 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(loginUserId, findBoard.getWorkspace().getId())) { - throw new RuntimeException("해당 워크스페이스의 멤버가 아닙니다."); + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } List findCardLists = cardListRepository.findByBoard(findBoard); @@ -90,7 +91,7 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new RuntimeException("읽기 전용 역할은 보드를 수정할 수 없습니다."); + throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); } findBoard.updateBoard(dto.getTitle(), dto.getColor(), dto.getImage()); @@ -104,7 +105,7 @@ public void deleteBoard(Long boardId, Long loginUserId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new RuntimeException("읽기 전용 역할은 보드를 삭제할 수 없습니다."); + throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); } boardRepository.delete(findBoard); diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index af88321..7540877 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -9,6 +9,7 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -35,11 +36,11 @@ public class Card { @Column(name = "start_at") @CreatedDate - private LocalDateTime startAt; + private LocalDate startAt; @Column(name = "end_at") @LastModifiedDate - private LocalDateTime endAt; + private LocalDate endAt; @ManyToOne(fetch = FetchType.LAZY) private CardList cardList; diff --git a/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java b/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java index 76edb41..0ccdd49 100644 --- a/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java +++ b/src/main/java/com/example/trello/card/dto/GetCardResponseDto.java @@ -5,6 +5,7 @@ import com.example.trello.cardlist.dto.GetCardListResponseDto; import lombok.Getter; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -13,10 +14,10 @@ public class GetCardResponseDto { private Long id; private String title; private String description; - private LocalDateTime startAt; - private LocalDateTime endAt; + private LocalDate startAt; + private LocalDate endAt; - public GetCardResponseDto(Long id, String title, String description, LocalDateTime startAt, LocalDateTime endAt) { + public GetCardResponseDto(Long id, String title, String description, LocalDate startAt, LocalDate endAt) { this.id = id; this.title = title; this.description = description; diff --git a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java new file mode 100644 index 0000000..da1ec2e --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java @@ -0,0 +1,17 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +import static org.springframework.http.HttpStatus.*; + +@RequiredArgsConstructor +@Getter +public enum BoardErrorCode { + READ_ONLY_CANT_NOT_HANDLE_BOARD("읽기 전용 역할은 할 수 없는 작업입니다.", FORBIDDEN); + + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/BoardException.java b/src/main/java/com/example/trello/common/exception/BoardException.java new file mode 100644 index 0000000..df05a60 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/BoardException.java @@ -0,0 +1,11 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import okhttp3.internal.http2.ErrorCode; + +@AllArgsConstructor +@Getter +public class BoardException extends RuntimeException { + private BoardErrorCode boardErrorCode; +} diff --git a/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java b/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java index 563e089..1a60ce1 100644 --- a/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java @@ -18,6 +18,36 @@ public ResponseEntity handleCardListException(CardListException e } + @ExceptionHandler(CardListException.class) + public ResponseEntity handleCardListException(WorkspaceException e) { + ErrorResponse message = ErrorResponse.builder() + .errorCode(e.getWorkspaceErrorCode().name()) + .message(e.getWorkspaceErrorCode().getMessage()) + .build(); + return new ResponseEntity<>(message, e.getWorkspaceErrorCode().getHttpStatus()); + + } + + @ExceptionHandler(CardListException.class) + public ResponseEntity handleCardListException(WorkspaceMemberException e) { + ErrorResponse message = ErrorResponse.builder() + .errorCode(e.getWorkspaceMemberErrorCode().name()) + .message(e.getWorkspaceMemberErrorCode().getMessage()) + .build(); + return new ResponseEntity<>(message, e.getWorkspaceMemberErrorCode().getHttpStatus()); + + } + + @ExceptionHandler(CardListException.class) + public ResponseEntity handleCardListException(BoardException e) { + ErrorResponse message = ErrorResponse.builder() + .errorCode(e.getBoardErrorCode().name()) + .message(e.getBoardErrorCode().getMessage()) + .build(); + return new ResponseEntity<>(message, e.getBoardErrorCode().getHttpStatus()); + + } + @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity handleValidException(MethodArgumentNotValidException e) { ErrorResponse message = ErrorResponse.builder() diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java b/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java new file mode 100644 index 0000000..ced0dd9 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java @@ -0,0 +1,18 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +import static org.springframework.http.HttpStatus.FORBIDDEN; + +@RequiredArgsConstructor +@Getter +public enum WorkspaceErrorCode { + ONLY_ADMIN_CAN_CREATE_WORKSPACE("ADMIN 역할의 USER만 워크스페이스를 생성할 수 있습니다.", FORBIDDEN), + ONLY_ADMIN_CAN_UPDATE_MEMBER_ROLE_TO_WORKSPACE("ADMIN 역할의 USER만 다른 MEMBER의 역할을 워크스페이스로 수정할 수 있습니다.", FORBIDDEN), + ONLY_WORKSPACE_ROLE_CAN_HANDLE_WORKSPACE("WORKSPACE 역할의 MEMBER만 워크스페이스를 관리할 수 있습니다.", FORBIDDEN); + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceException.java b/src/main/java/com/example/trello/common/exception/WorkspaceException.java new file mode 100644 index 0000000..7147606 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/WorkspaceException.java @@ -0,0 +1,10 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class WorkspaceException extends RuntimeException { + private WorkspaceErrorCode workspaceErrorCode; +} diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java new file mode 100644 index 0000000..f35c99b --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java @@ -0,0 +1,19 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +import static org.springframework.http.HttpStatus.FORBIDDEN; + +@RequiredArgsConstructor +@Getter +public enum WorkspaceMemberErrorCode { + IS_NOT_WORKSPACEMEMBER("WORKSPACE의 MEMBER가 아닙니다.", FORBIDDEN), + ONLY_WORKSPACE_ROLE_CAN_INVITE("WORKSPACE 역할의 MEMBER만 초대가 가능합니다.", FORBIDDEN), + ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE("WORKSPACE 역할의 MEMBER만 다른 유저의 권한을 (BOARD, READ_ONLY)로 변경이 가능합니다.", FORBIDDEN); + + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceMemberException.java b/src/main/java/com/example/trello/common/exception/WorkspaceMemberException.java new file mode 100644 index 0000000..e931231 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/WorkspaceMemberException.java @@ -0,0 +1,10 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class WorkspaceMemberException extends RuntimeException { + private WorkspaceMemberErrorCode workspaceMemberErrorCode; +} diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 3003ddf..9dfbca3 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -1,5 +1,7 @@ package com.example.trello.workspace; +import com.example.trello.common.exception.WorkspaceErrorCode; +import com.example.trello.common.exception.WorkspaceException; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.dto.UpdateWorkspaceRequestDto; @@ -32,7 +34,7 @@ public WorkspaceResponseDto createWorkspace(WorkspaceRequestDto dto, Long loginU User loginUser = userRepository.findByIdOrElseThrow(loginUserId); if (loginUser.getRole() != ADMIN) { - throw new RuntimeException("권한이 ADMIN 인 유저만 워크스페이스 생성이 가능합니다."); + throw new WorkspaceException(WorkspaceErrorCode.ONLY_ADMIN_CAN_CREATE_WORKSPACE); } Workspace workspace = Workspace.builder() @@ -82,7 +84,7 @@ public WorkspaceResponseDto updateWorkspace(Long workspaceId, UpdateWorkspaceReq WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("워크스페이스를 수정할 권한이 없습니다."); + throw new WorkspaceException(WorkspaceErrorCode.ONLY_WORKSPACE_ROLE_CAN_HANDLE_WORKSPACE); } Workspace workspace = findWorkspaceMember.getWorkspace(); @@ -97,7 +99,7 @@ public void deleteWorkspace(Long workspaceId, Long loginUserId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("워크스페이스를 삭제할 권한이 없습니다."); + throw new WorkspaceException(WorkspaceErrorCode.ONLY_WORKSPACE_ROLE_CAN_HANDLE_WORKSPACE); } Workspace workspace = findWorkspaceMember.getWorkspace(); diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index d33383b..bef6d45 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -1,5 +1,9 @@ package com.example.trello.workspace_member; +import com.example.trello.common.exception.WorkspaceErrorCode; +import com.example.trello.common.exception.WorkspaceException; +import com.example.trello.common.exception.WorkspaceMemberErrorCode; +import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; @@ -30,7 +34,7 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, Worksp WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (findWorkspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("멤버를 초대할 권한이 없습니다."); + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.ONLY_WORKSPACE_ROLE_CAN_INVITE); } User findUser = userRepository.findByEmailOrElseThrow(dto.getEmail()); @@ -52,11 +56,11 @@ public void updateWorkspaceMemberRole(Long workspaceId, UpdateWorkspaceMemberRol WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, workspaceId); if (dto.getRole() == WORKSPACE && findWorkspaceMember.getUser().getRole() != ADMIN) { - throw new RuntimeException("WORKSPACE 역할은 ADMIN 만 부여할 수 있습니다."); + throw new WorkspaceException(WorkspaceErrorCode.ONLY_ADMIN_CAN_UPDATE_MEMBER_ROLE_TO_WORKSPACE); } if (findWorkspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("멤버 역할을 수정할 권한이 없습니다."); + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE); } WorkspaceMember roleUpdatedWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(dto.getWorkspaceMemberId()); From 2a115a7d3151c10dfc1bb3e2e3ea8c53e910b88d Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 20:56:27 +0900 Subject: [PATCH 093/181] =?UTF-8?q?refactor=20:=20=EC=84=B8=EC=85=98?= =?UTF-8?q?=EC=97=90=EC=84=9C=20userId=EB=A5=BC=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=98=A4=EB=8A=94=EA=B2=83=EC=97=90=EC=84=9C=20UserDetailsImpl?= =?UTF-8?q?=EC=97=90=EC=84=9C=20userId=20=EA=B0=92=EC=9D=84=20=EB=B0=9B?= =?UTF-8?q?=EC=95=84=EC=98=A4=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/board/BoardController.java | 22 ++++++++++--------- .../example/trello/workspace/Workspace.java | 5 ++--- .../trello/workspace/WorkspaceController.java | 22 ++++++++++--------- .../workspace_member/WorkspaceMember.java | 2 +- .../WorkspaceMemberController.java | 10 +++++---- 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 8a255fe..952d280 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -1,9 +1,11 @@ package com.example.trello.board; import com.example.trello.board.dto.*; +import com.example.trello.config.auth.UserDetailsImpl; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -15,32 +17,32 @@ public class BoardController { private final BoardService boardService; @PostMapping - public ResponseEntity createBoard(@RequestBody BoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { - BoardResponseDto boardResponseDto = boardService.createBoard(dto, loginUserId); + public ResponseEntity createBoard(@RequestBody BoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + BoardResponseDto boardResponseDto = boardService.createBoard(dto, userDetails.getUser().getId()); return new ResponseEntity<>(boardResponseDto, HttpStatus.CREATED); } @GetMapping - public ResponseEntity> viewAllBoard(@RequestBody viewAllBoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { - List boardResponseDtoList = boardService.viewAllBoard(dto, loginUserId); + public ResponseEntity> viewAllBoard(@RequestBody viewAllBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + List boardResponseDtoList = boardService.viewAllBoard(dto, userDetails.getUser().getId()); return new ResponseEntity<>(boardResponseDtoList, HttpStatus.OK); } @GetMapping("/{boardId}") - public ResponseEntity viewBoard(@PathVariable Long boardId, @SessionAttribute("id") Long loginUserId) { - BoardDetailResponseDto boardDetailResponseDto = boardService.viewBoard(boardId, loginUserId); + public ResponseEntity viewBoard(@PathVariable Long boardId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + BoardDetailResponseDto boardDetailResponseDto = boardService.viewBoard(boardId, userDetails.getUser().getId()); return new ResponseEntity<>(boardDetailResponseDto, HttpStatus.OK); } @PatchMapping("/{boardId}") - public ResponseEntity updateBoard(@PathVariable Long boardId, @RequestBody UpdateBoardRequestDto dto, @SessionAttribute("id") Long loginUserId) { - BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto, loginUserId); + public ResponseEntity updateBoard(@PathVariable Long boardId, @RequestBody UpdateBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(updatedBoardResponseDto, HttpStatus.OK); } @DeleteMapping("/{boardId}") - public String deleteBoard(@PathVariable Long boardId, @SessionAttribute("id") Long loginUserId) { - boardService.deleteBoard(boardId, loginUserId); + public String deleteBoard(@PathVariable Long boardId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + boardService.deleteBoard(boardId, userDetails.getUser().getId()); return "보드가 정상적으로 삭제되었습니다."; } } diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index c0eb224..a97ebf9 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -12,16 +12,15 @@ @Entity @Getter -@DynamicUpdate public class Workspace { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "title") + @Column(name = "title", nullable = false) private String title; - @Column(name = "description") + @Column(name = "description", nullable = false) private String description; @OneToMany(mappedBy = "workspace", cascade = CascadeType.ALL, orphanRemoval = true) diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 231a3e6..a0e3d29 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -1,11 +1,13 @@ package com.example.trello.workspace; +import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.workspace.dto.UpdateWorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -17,33 +19,33 @@ public class WorkspaceController { private final WorkspaceService workspaceService; @PostMapping - public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto, @SessionAttribute("id") Long loginUserId) { - WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto, loginUserId); + public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto, userDetails.getUser().getId()); return new ResponseEntity<>(createdWorkspaceResponseDto, HttpStatus.CREATED); } @GetMapping - public ResponseEntity> viewAllWorkspace(@SessionAttribute("id") Long loginUserId) { - List workspaceResponseDtoList = workspaceService.viewAllWorkspace(loginUserId); + public ResponseEntity> viewAllWorkspace(@AuthenticationPrincipal UserDetailsImpl userDetails) { + List workspaceResponseDtoList = workspaceService.viewAllWorkspace(userDetails.getUser().getId()); return new ResponseEntity<>(workspaceResponseDtoList, HttpStatus.OK); } @GetMapping("/{workspaceId}") - public ResponseEntity viewWorkspace(@PathVariable Long workspaceId, @SessionAttribute("id") Long loginUserId) { - WorkspaceResponseDto findWorkspaceResponseDto = workspaceService.viewWorkspace(workspaceId, loginUserId); + public ResponseEntity viewWorkspace(@PathVariable Long workspaceId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + WorkspaceResponseDto findWorkspaceResponseDto = workspaceService.viewWorkspace(workspaceId, userDetails.getUser().getId()); return new ResponseEntity<>(findWorkspaceResponseDto, HttpStatus.OK); } @PatchMapping("/{workspaceId}") - public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto, @SessionAttribute("id") Long loginUserId) { - WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto, loginUserId); + public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(updatedWorkspaceResponseDto, HttpStatus.OK); } @DeleteMapping("/{workspaceId}") - public String deleteWorkspace(@PathVariable Long workspaceId, @SessionAttribute("id") Long loginUserId) { - workspaceService.deleteWorkspace(workspaceId, loginUserId); + public String deleteWorkspace(@PathVariable Long workspaceId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + workspaceService.deleteWorkspace(workspaceId, userDetails.getUser().getId()); return "워크스페이스가 정상적으로 삭제되었습니다."; } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMember.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMember.java index c699941..a72d016 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMember.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMember.java @@ -14,7 +14,7 @@ public class WorkspaceMember { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "role") + @Column(name = "role", nullable = false) @Enumerated(EnumType.STRING) private WorkspaceMemberRole role; diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java index ea63b92..d45bc27 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java @@ -1,11 +1,13 @@ package com.example.trello.workspace_member; +import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.workspace_member.dto.UpdateWorkspaceMemberRoleDto; import com.example.trello.workspace_member.dto.WorkspaceMemberRequestDto; import com.example.trello.workspace_member.dto.WorkspaceMemberResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; @RestController @@ -16,14 +18,14 @@ public class WorkspaceMemberController { private final WorkspaceMemberService workspaceMemberService; @PostMapping("/member-invite") - public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto, @SessionAttribute("id") Long loginUserId) { - WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto, loginUserId); + public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(workspaceMemberResponseDto, HttpStatus.CREATED); } @PatchMapping("/member-role") - public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto, @SessionAttribute("id") Long loginUserId) { - workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto, loginUserId); + public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto, userDetails.getUser().getId()); return "권한이 " + dto.getRole() + "로 변경되었습니다."; } } From beffc28255536bf32c1079f94c71bcf6c603470b Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 22:15:15 +0900 Subject: [PATCH 094/181] =?UTF-8?q?fix=20:=20=EB=A9=A4=EB=B2=84=EC=97=AD?= =?UTF-8?q?=ED=95=A0=20=EB=B3=80=EA=B2=BD=EC=8B=9C=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=9B=8C=ED=81=AC=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=EC=9D=98?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=EC=97=AD=ED=95=A0=EC=9D=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8D=98=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/GlobalExceptionHandler.java | 6 +++--- .../common/exception/WorkspaceMemberErrorCode.java | 5 +++-- .../workspace_member/WorkspaceMemberRepository.java | 11 ++++++++++- .../workspace_member/WorkspaceMemberService.java | 6 +++++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java b/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java index 1a60ce1..4e12725 100644 --- a/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/example/trello/common/exception/GlobalExceptionHandler.java @@ -18,7 +18,7 @@ public ResponseEntity handleCardListException(CardListException e } - @ExceptionHandler(CardListException.class) + @ExceptionHandler(WorkspaceException.class) public ResponseEntity handleCardListException(WorkspaceException e) { ErrorResponse message = ErrorResponse.builder() .errorCode(e.getWorkspaceErrorCode().name()) @@ -28,7 +28,7 @@ public ResponseEntity handleCardListException(WorkspaceException } - @ExceptionHandler(CardListException.class) + @ExceptionHandler(WorkspaceMemberException.class) public ResponseEntity handleCardListException(WorkspaceMemberException e) { ErrorResponse message = ErrorResponse.builder() .errorCode(e.getWorkspaceMemberErrorCode().name()) @@ -38,7 +38,7 @@ public ResponseEntity handleCardListException(WorkspaceMemberExce } - @ExceptionHandler(CardListException.class) + @ExceptionHandler(BoardException.class) public ResponseEntity handleCardListException(BoardException e) { ErrorResponse message = ErrorResponse.builder() .errorCode(e.getBoardErrorCode().name()) diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java index f35c99b..8d35666 100644 --- a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; +import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.FORBIDDEN; @RequiredArgsConstructor @@ -11,8 +12,8 @@ public enum WorkspaceMemberErrorCode { IS_NOT_WORKSPACEMEMBER("WORKSPACE의 MEMBER가 아닙니다.", FORBIDDEN), ONLY_WORKSPACE_ROLE_CAN_INVITE("WORKSPACE 역할의 MEMBER만 초대가 가능합니다.", FORBIDDEN), - ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE("WORKSPACE 역할의 MEMBER만 다른 유저의 권한을 (BOARD, READ_ONLY)로 변경이 가능합니다.", FORBIDDEN); - + ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE("WORKSPACE 역할의 MEMBER만 다른 유저의 권한을 (BOARD, READ_ONLY)로 변경이 가능합니다.", FORBIDDEN), + ALREADY_MEMBER("이미 워크스페이스의 멤버입니다.", BAD_REQUEST); private final String message; private final HttpStatus httpStatus; diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index 6148a65..c30573c 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -1,5 +1,7 @@ package com.example.trello.workspace_member; +import com.example.trello.common.exception.WorkspaceMemberErrorCode; +import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.user.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -7,17 +9,24 @@ import java.util.List; import java.util.Optional; +import static org.springframework.http.HttpStatus.FORBIDDEN; + @Repository public interface WorkspaceMemberRepository extends JpaRepository { List findByUserId(Long userId); Optional findByUserIdAndWorkspaceId(Long userId, Long workspaceId); + Optional findByIdAndWorkspaceId(Long id, Long workspaceId); Boolean existsByUserIdAndWorkspaceId(Long userId, Long workspaceId); default WorkspaceMember findByIdOrElseThrow(Long id){ return findById(id).orElseThrow(() -> new RuntimeException()); } + default WorkspaceMember findByIdAndWorkspaceIdOrElseThrow(Long id, Long workspaceId){ + return findByIdAndWorkspaceId(id, workspaceId).orElseThrow(() -> new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER)); + } + default WorkspaceMember findByUserIdAndWorkspaceIdOrElseThrow(Long userId, Long workspaceId) { - return findByUserIdAndWorkspaceId(userId, workspaceId).orElseThrow(() -> new RuntimeException("해당 워크스페이스의 멤버가 아닙니다.")); + return findByUserIdAndWorkspaceId(userId, workspaceId).orElseThrow(() -> new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER)); } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index bef6d45..53c1155 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -40,6 +40,10 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, Worksp User findUser = userRepository.findByEmailOrElseThrow(dto.getEmail()); Workspace workspace = findWorkspaceMember.getWorkspace(); + if (workspaceMemberRepository.existsByUserIdAndWorkspaceId(findUser.getId(), workspace.getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.ALREADY_MEMBER); + } + WorkspaceMember workspaceMember = WorkspaceMember.builder() .user(findUser) .workspace(workspace) @@ -63,7 +67,7 @@ public void updateWorkspaceMemberRole(Long workspaceId, UpdateWorkspaceMemberRol throw new WorkspaceMemberException(WorkspaceMemberErrorCode.ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE); } - WorkspaceMember roleUpdatedWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(dto.getWorkspaceMemberId()); + WorkspaceMember roleUpdatedWorkspaceMember = workspaceMemberRepository.findByIdAndWorkspaceIdOrElseThrow(dto.getWorkspaceMemberId(), workspaceId); roleUpdatedWorkspaceMember.updateRole(dto.getRole()); log.info("{}의 역할이 {}로 변경되었습니다.", roleUpdatedWorkspaceMember.getUser().getNickname(), dto.getRole()); From 7190a6a2b43da36465c8883586a68100e53d9a80 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 22:31:00 +0900 Subject: [PATCH 095/181] =?UTF-8?q?Fix=20:=20workSpaceMemberId=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/requestDto/CardRequestDto.java | 5 +---- .../example/trello/card/responsedto/CardResponseDto.java | 6 +----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java index aa7b2ea..fe16bf9 100644 --- a/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/CardRequestDto.java @@ -19,19 +19,16 @@ public class CardRequestDto { private String description; - private Long workSpaceMemberId; - @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate startAt; @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate endAt; - public CardRequestDto(Long cardListId, String title, String description, Long workspaceMemberId, LocalDate startAt, LocalDate endAt) { + public CardRequestDto(Long cardListId, String title, String description, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.title = title; this.description = description; - this.workSpaceMemberId = workspaceMemberId; this.startAt = startAt; this.endAt = endAt; } diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index 1d0e0bf..15a5e3a 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -21,8 +21,6 @@ public class CardResponseDto { private String description; - private Long workSpaceMemberId; - @JsonFormat(pattern = "yyyy-MM-dd") LocalDate startAt; @@ -30,12 +28,11 @@ public class CardResponseDto { LocalDate endAt; - public CardResponseDto(Long cardListId, Long cardId, String title, String description, Long workSpaceMemberId, LocalDate startAt, LocalDate endAt) { + public CardResponseDto(Long cardListId, Long cardId, String title, String description, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.cardId = cardId; this.title = title; this.description = description; - this.workSpaceMemberId = workSpaceMemberId; this.startAt = startAt; this.endAt =endAt; } @@ -46,7 +43,6 @@ public static CardResponseDto toDto(Card card) { card.getId(), card.getTitle(), card.getDescription(), - card.getWorkspaceMember().getId(), card.getStartAt(), card.getEndAt()); } From 725f347542dc4de6e88701e2d8dc1db92784e550 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 22:35:29 +0900 Subject: [PATCH 096/181] =?UTF-8?q?Fix=20:=20@AuthenticationPrincipal?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20=EC=B9=B4=EB=93=9C=20=EC=83=9D=EC=84=B1,?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8,=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=A9=A4=EB=B2=84=EC=9D=98=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=EA=B3=BC=20=EA=B4=80=EB=A0=A8=EB=90=9C=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/card/CardController.java | 15 ++++---- .../com/example/trello/card/CardService.java | 35 +++++++++++-------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index a7e5c91..a113ade 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -4,10 +4,13 @@ import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; +import com.example.trello.config.auth.UserDetailsImpl; +import com.example.trello.user.User; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.time.LocalDate; @@ -21,20 +24,20 @@ public class CardController { private final CardService cardService; @PostMapping - public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto, @SessionAttribute("id") Long userid) { - CardResponseDto responseDto = cardService.createdCardService(requestDto, userid); + public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + CardResponseDto responseDto = cardService.createdCardService(requestDto, userDetails); return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } @PatchMapping("/{cardId}") - public ResponseEntity updateCard(@PathVariable Long cardsId, @RequestBody UpdateCardRequestDto requestDto, @SessionAttribute("id") Long userid) { - CardResponseDto responseDto = cardService.updateCardService(cardsId, requestDto, userid); + public ResponseEntity updateCard(@PathVariable Long cardId, @RequestBody UpdateCardRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + CardResponseDto responseDto = cardService.updateCardService(cardId, requestDto, userDetails); return new ResponseEntity<>(responseDto, HttpStatus.OK); } @DeleteMapping("/{cardId}") - public ResponseEntity deleteCard(@PathVariable Long cardsId, @SessionAttribute("id") Long userid) { - cardService.deleteCardService(cardsId, userid); + public ResponseEntity deleteCard(@PathVariable Long cardId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + cardService.deleteCardService(cardId, userDetails); return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 067355e..a2f4633 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -8,6 +8,7 @@ import com.example.trello.card.requestDto.UpdateCardRequestDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; +import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; @@ -22,6 +23,7 @@ import java.time.LocalDate; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; +import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @RequiredArgsConstructor @@ -36,16 +38,16 @@ public class CardService { // 카드 생성 @Transactional - public CardResponseDto createdCardService(CardRequestDto requestDto, Long userId) { - - User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); + public CardResponseDto createdCardService(CardRequestDto requestDto, UserDetailsImpl userDetails) { CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByIdOrElseThrow(requestDto.getWorkSpaceMemberId()); + Long workspaceId = cardList.getBoard().getWorkspace().getId(); + + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); - if (workspaceMember.getRole().equals(READ_ONLY)) { - throw new RuntimeException(); + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("카드를 생성할 권한이 없습니다."); } Card card = Card.builder() @@ -63,15 +65,17 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, Long userId //카드 업데이트 @Transactional - public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, Long userId) { + public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); - User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); + Long workspaceId = cardList.getBoard().getWorkspace().getId(); + + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); - if (!user.getId().equals(card.getWorkspaceMember().getUser().getId())) { - throw new RuntimeException(); + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("카드를 수정할 권한이 없습니다."); } card.updateCard(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); @@ -83,14 +87,17 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque // 카드 삭제 @Transactional - public void deleteCardService(Long cardId, Long userId) { + public void deleteCardService(Long cardId, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); - User user = userRepository.findById(userId).orElseThrow(RuntimeException::new); + Long workspaceId = card.getCardList().getBoard().getWorkspace().getId(); - if (!user.getId().equals(card.getWorkspaceMember().getUser().getId())) { - throw new RuntimeException(); + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("카드를 삭제할 권한이 없습니다."); } + cardRepository.delete(card); } From 2a5faa161add6aa06435c09e2ed7811e38480d3d Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 22:48:58 +0900 Subject: [PATCH 097/181] =?UTF-8?q?Fix=20:=20@AuthenticationPrincipal?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1,?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8,=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=A9=A4=EB=B2=84=EC=9D=98=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=EA=B3=BC=20=EA=B4=80=EB=A0=A8=EB=90=9C=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/comment/CommentController.java | 13 +++--- .../trello/comment/CommentService.java | 42 +++++++++++++------ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentController.java b/src/main/java/com/example/trello/comment/CommentController.java index 5087a74..da64484 100644 --- a/src/main/java/com/example/trello/comment/CommentController.java +++ b/src/main/java/com/example/trello/comment/CommentController.java @@ -3,6 +3,7 @@ import com.example.trello.comment.dto.request.CommentRequestDto; import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; +import com.example.trello.config.auth.UserDetailsImpl; import jakarta.servlet.http.HttpServletRequest; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -18,20 +19,20 @@ public class CommentController { private final CommentService commentService; @PostMapping - public ResponseEntity createComment(@RequestBody CommentRequestDto requestDto, HttpServletRequest servletRequest) { - CommentResponseDto responseDto = commentService.createComment(requestDto, servletRequest); + public ResponseEntity createComment(@RequestBody CommentRequestDto requestDto, UserDetailsImpl userDetails) { + CommentResponseDto responseDto = commentService.createComment(requestDto, userDetails); return new ResponseEntity<>(responseDto, HttpStatus.OK); } @PatchMapping("/{commentId}") - public ResponseEntity updateComment(@PathVariable Long commentId, @RequestBody UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { - CommentResponseDto responseDto = commentService.updateComment(commentId, requestDto, servletRequest); + public ResponseEntity updateComment(@PathVariable Long commentId, @RequestBody UpdateCommentRequestDto requestDto, UserDetailsImpl userDetails) { + CommentResponseDto responseDto = commentService.updateComment(commentId, requestDto, userDetails); return new ResponseEntity<>(responseDto, HttpStatus.OK); } @DeleteMapping("/{commentId}") - public ResponseEntity deleteComment(@PathVariable Long commentId, HttpServletRequest servletRequest) { - commentService.deleteComment(commentId, servletRequest); + public ResponseEntity deleteComment(@PathVariable Long commentId, UserDetailsImpl userDetails) { + commentService.deleteComment(commentId, userDetails); return new ResponseEntity<>("삭제되었습니다" , HttpStatus.OK); } } diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 17aa0e9..f9579a1 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -5,6 +5,7 @@ import com.example.trello.comment.dto.request.CommentRequestDto; import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; +import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.user.User; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; @@ -15,6 +16,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; +import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; + @Service @RequiredArgsConstructor public class CommentService { @@ -24,18 +27,22 @@ public class CommentService { @Transactional - public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServletRequest servletRequest) { - - User user = (User) servletRequest.getSession().getAttribute("id"); + public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(requestDto.getCardId()); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByIdOrElseThrow(requestDto.getWorkSpaceMemberId()); + Long workspaceId = card.getCardList().getBoard().getWorkspace().getId(); + + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("댓글을 생성할 권한이 없습니다."); + } Comment comment = Comment.builder() .content(requestDto.getContent()) .card(card) - .user(user) + .user(userDetails.getUser()) .workspaceMember(workspaceMember) .build(); @@ -45,14 +52,17 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, HttpServle } @Transactional - public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, HttpServletRequest servletRequest) { + public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, UserDetailsImpl userDetails) { - User user = (User) servletRequest.getSession().getAttribute("id"); Comment comment = commentRepository.findByIdOrElseThrow(commentId); - if (!user.getId().equals(comment.getWorkspaceMember().getUser().getId())) { - throw new RuntimeException(); + Long workspaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); + + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("댓글을 생성할 권한이 없습니다."); } comment.updateComment(requestDto.getContent()); @@ -64,13 +74,19 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto } @Transactional - public void deleteComment(Long commentId, HttpServletRequest servletRequest) { - - User user = (User) servletRequest.getSession().getAttribute("id"); + public void deleteComment(Long commentId, UserDetailsImpl userDetails) { Comment comment = commentRepository.findByIdOrElseThrow(commentId); - if (!user.getId().equals(comment.getWorkspaceMember().getUser().getId())) { + Long workspaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); + + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("댓글을 생성할 권한이 없습니다."); + } + + if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { throw new RuntimeException(); } From 2cf8610dbb3cba02afbad962420a310a06144aaf Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 22:53:26 +0900 Subject: [PATCH 098/181] =?UTF-8?q?Fix=20:=20workSpaceMemberId=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/comment/dto/request/CommentRequestDto.java | 5 +---- .../trello/comment/dto/response/CommentResponseDto.java | 8 ++------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java index d255aed..60a5150 100644 --- a/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java +++ b/src/main/java/com/example/trello/comment/dto/request/CommentRequestDto.java @@ -9,11 +9,8 @@ public class CommentRequestDto { private Long cardId; - private Long workSpaceMemberId; - - public CommentRequestDto(String content, Long cardId, Long workSpaceMemberId) { + public CommentRequestDto(String content, Long cardId) { this.content = content; this.cardId = cardId; - this.workSpaceMemberId = workSpaceMemberId; } } diff --git a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java index 51552b8..d0a92b1 100644 --- a/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java +++ b/src/main/java/com/example/trello/comment/dto/response/CommentResponseDto.java @@ -16,14 +16,11 @@ public class CommentResponseDto { private Long userId; - private Long workSpaceMemberId; - - public CommentResponseDto(Long commentId, String content, Long cardId, Long userId, Long workSpaceMemberId) { + public CommentResponseDto(Long commentId, String content, Long cardId, Long userId) { this.commentId = commentId; this.content = content; this.cardId = cardId; this.userId = userId; - this.workSpaceMemberId = workSpaceMemberId; } public static CommentResponseDto toDto(Comment comment) { @@ -31,7 +28,6 @@ public static CommentResponseDto toDto(Comment comment) { comment.getId(), comment.getContent(), comment.getCard().getId(), - comment.getUser().getId(), - comment.getWorkspaceMember().getId()); + comment.getUser().getId()); } } From 7f9bab4a453036318ea23675ba53864f992c960f Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Fri, 27 Dec 2024 23:38:13 +0900 Subject: [PATCH 099/181] =?UTF-8?q?refactor=20:=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=A6=9D=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=EC=9D=84=20=EC=9C=84=ED=95=B4=20Validation=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/board/BoardController.java | 7 ++++--- .../com/example/trello/board/dto/BoardRequestDto.java | 10 ++++++++++ .../trello/board/dto/UpdateBoardRequestDto.java | 6 ++++++ .../trello/board/dto/viewAllBoardRequestDto.java | 2 ++ .../example/trello/workspace/WorkspaceController.java | 5 +++-- .../workspace/dto/UpdateWorkspaceRequestDto.java | 7 +++++++ .../trello/workspace/dto/WorkspaceRequestDto.java | 7 +++++++ .../workspace_member/WorkspaceMemberController.java | 5 +++-- .../dto/UpdateWorkspaceMemberRoleDto.java | 5 +++++ .../dto/WorkspaceMemberRequestDto.java | 4 ++++ 10 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 952d280..efccda4 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -2,6 +2,7 @@ import com.example.trello.board.dto.*; import com.example.trello.config.auth.UserDetailsImpl; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,13 +18,13 @@ public class BoardController { private final BoardService boardService; @PostMapping - public ResponseEntity createBoard(@RequestBody BoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity createBoard(@Valid @RequestBody BoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { BoardResponseDto boardResponseDto = boardService.createBoard(dto, userDetails.getUser().getId()); return new ResponseEntity<>(boardResponseDto, HttpStatus.CREATED); } @GetMapping - public ResponseEntity> viewAllBoard(@RequestBody viewAllBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity> viewAllBoard(@Valid @RequestBody viewAllBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { List boardResponseDtoList = boardService.viewAllBoard(dto, userDetails.getUser().getId()); return new ResponseEntity<>(boardResponseDtoList, HttpStatus.OK); } @@ -35,7 +36,7 @@ public ResponseEntity viewBoard(@PathVariable Long board } @PatchMapping("/{boardId}") - public ResponseEntity updateBoard(@PathVariable Long boardId, @RequestBody UpdateBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity updateBoard(@PathVariable Long boardId, @Valid @RequestBody UpdateBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(updatedBoardResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/board/dto/BoardRequestDto.java b/src/main/java/com/example/trello/board/dto/BoardRequestDto.java index b9af364..b494b74 100644 --- a/src/main/java/com/example/trello/board/dto/BoardRequestDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardRequestDto.java @@ -1,12 +1,22 @@ package com.example.trello.board.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Getter; @Getter public class BoardRequestDto { + @NotBlank(message = "title 은 Null 일 수 없습니다.") + @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; + private String color; + private String image; + + @NotNull private Long workspaceId; public BoardRequestDto(String title, String color, String image, Long workspaceId) { diff --git a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java index 25e62c4..51637a2 100644 --- a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java +++ b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java @@ -1,11 +1,17 @@ package com.example.trello.board.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Getter; @Getter public class UpdateBoardRequestDto { + @NotBlank(message = "title 은 Null 일 수 없습니다.") + @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; + private String color; + private String image; public UpdateBoardRequestDto(String title, String color, String image) { diff --git a/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java b/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java index ecbee31..729cb3b 100644 --- a/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java +++ b/src/main/java/com/example/trello/board/dto/viewAllBoardRequestDto.java @@ -1,9 +1,11 @@ package com.example.trello.board.dto; +import jakarta.validation.constraints.NotNull; import lombok.Getter; @Getter public class viewAllBoardRequestDto { + @NotNull private Long workspaceId; public viewAllBoardRequestDto(Long workspaceId) { diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index a0e3d29..791a8af 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -4,6 +4,7 @@ import com.example.trello.workspace.dto.UpdateWorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceRequestDto; import com.example.trello.workspace.dto.WorkspaceResponseDto; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -19,7 +20,7 @@ public class WorkspaceController { private final WorkspaceService workspaceService; @PostMapping - public ResponseEntity createWorkspace(@RequestBody WorkspaceRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity createWorkspace(@Valid @RequestBody WorkspaceRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { WorkspaceResponseDto createdWorkspaceResponseDto = workspaceService.createWorkspace(dto, userDetails.getUser().getId()); return new ResponseEntity<>(createdWorkspaceResponseDto, HttpStatus.CREATED); @@ -38,7 +39,7 @@ public ResponseEntity viewWorkspace(@PathVariable Long wor } @PatchMapping("/{workspaceId}") - public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity updateWorkspace(@PathVariable Long workspaceId, @Valid @RequestBody UpdateWorkspaceRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { WorkspaceResponseDto updatedWorkspaceResponseDto = workspaceService.updateWorkspace(workspaceId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(updatedWorkspaceResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java b/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java index 27d08f2..d327139 100644 --- a/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java +++ b/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java @@ -1,10 +1,17 @@ package com.example.trello.workspace.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Getter; @Getter public class UpdateWorkspaceRequestDto { + @NotBlank(message = "title 은 Null 일 수 없습니다.") + @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; + + @NotBlank(message = "description 은 Null 일 수 없습니다.") + @Size(min = 1, max = 255, message = "title 크기는 1에서 255사이여야합니다.") private String description; public UpdateWorkspaceRequestDto(String title, String description) { diff --git a/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java b/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java index 74c2676..05d4139 100644 --- a/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java +++ b/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java @@ -1,10 +1,17 @@ package com.example.trello.workspace.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Getter; @Getter public class WorkspaceRequestDto { + @NotBlank(message = "title 은 Null 일 수 없습니다.") + @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; + + @NotBlank(message = "description 은 Null 일 수 없습니다.") + @Size(min = 1, max = 255, message = "title 크기는 1에서 255사이여야합니다.") private String description; public WorkspaceRequestDto(String title, String description) { diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java index d45bc27..b3a19dc 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java @@ -4,6 +4,7 @@ import com.example.trello.workspace_member.dto.UpdateWorkspaceMemberRoleDto; import com.example.trello.workspace_member.dto.WorkspaceMemberRequestDto; import com.example.trello.workspace_member.dto.WorkspaceMemberResponseDto; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -18,13 +19,13 @@ public class WorkspaceMemberController { private final WorkspaceMemberService workspaceMemberService; @PostMapping("/member-invite") - public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @RequestBody WorkspaceMemberRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity inviteWorkspaceUser(@PathVariable Long workspaceId, @Valid @RequestBody WorkspaceMemberRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { WorkspaceMemberResponseDto workspaceMemberResponseDto = workspaceMemberService.inviteWorkspaceMember(workspaceId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(workspaceMemberResponseDto, HttpStatus.CREATED); } @PatchMapping("/member-role") - public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @RequestBody UpdateWorkspaceMemberRoleDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @Valid @RequestBody UpdateWorkspaceMemberRoleDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto, userDetails.getUser().getId()); return "권한이 " + dto.getRole() + "로 변경되었습니다."; } diff --git a/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java b/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java index 0eda279..4f43f5a 100644 --- a/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java +++ b/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java @@ -1,11 +1,16 @@ package com.example.trello.workspace_member.dto; import com.example.trello.workspace_member.WorkspaceMemberRole; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Getter; @Getter public class UpdateWorkspaceMemberRoleDto { + @NotNull private Long workspaceMemberId; + + @NotBlank private WorkspaceMemberRole role; public UpdateWorkspaceMemberRoleDto(Long workspaceMemberId, WorkspaceMemberRole role) { diff --git a/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java index 8acaac4..34d3951 100644 --- a/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java +++ b/src/main/java/com/example/trello/workspace_member/dto/WorkspaceMemberRequestDto.java @@ -1,9 +1,13 @@ package com.example.trello.workspace_member.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; import lombok.Getter; @Getter public class WorkspaceMemberRequestDto { + @NotBlank + @Pattern(regexp = "^[A-Za-z0-9.!@#$+]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", message = "이메일 형식이 올바르지 않습니다. 다시 입력해주세요") private String email; public WorkspaceMemberRequestDto(String email) { From 1a6519c7d54509a464de1c5c1078bfd7f5aa6527 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Fri, 27 Dec 2024 23:45:53 +0900 Subject: [PATCH 100/181] =?UTF-8?q?Fix=20:=20@AuthenticationPrincipal?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=8C=93=EA=B8=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1,=EC=88=98=EC=A0=95,=EC=82=AD=EC=A0=9C=EC=8B=9C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=AC=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/comment/CommentController.java | 5 +++-- .../java/com/example/trello/comment/CommentService.java | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentController.java b/src/main/java/com/example/trello/comment/CommentController.java index da64484..06d663c 100644 --- a/src/main/java/com/example/trello/comment/CommentController.java +++ b/src/main/java/com/example/trello/comment/CommentController.java @@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @@ -19,13 +20,13 @@ public class CommentController { private final CommentService commentService; @PostMapping - public ResponseEntity createComment(@RequestBody CommentRequestDto requestDto, UserDetailsImpl userDetails) { + public ResponseEntity createComment(@RequestBody CommentRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { CommentResponseDto responseDto = commentService.createComment(requestDto, userDetails); return new ResponseEntity<>(responseDto, HttpStatus.OK); } @PatchMapping("/{commentId}") - public ResponseEntity updateComment(@PathVariable Long commentId, @RequestBody UpdateCommentRequestDto requestDto, UserDetailsImpl userDetails) { + public ResponseEntity updateComment(@PathVariable Long commentId, @RequestBody UpdateCommentRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { CommentResponseDto responseDto = commentService.updateComment(commentId, requestDto, userDetails); return new ResponseEntity<>(responseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index f9579a1..4efc8f8 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -62,7 +62,11 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("댓글을 생성할 권한이 없습니다."); + throw new RuntimeException("댓글을 수정할 권한이 없습니다."); + } + + if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { + throw new RuntimeException(); } comment.updateComment(requestDto.getContent()); @@ -83,7 +87,7 @@ public void deleteComment(Long commentId, UserDetailsImpl userDetails) { WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("댓글을 생성할 권한이 없습니다."); + throw new RuntimeException("댓글을 삭제할 권한이 없습니다."); } if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { From 82a46206477d5e42b4382eae10e297cf0b2a8d17 Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Sat, 28 Dec 2024 13:05:18 +0900 Subject: [PATCH 101/181] =?UTF-8?q?chore=20:=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=97=90=20=EB=82=98=EC=98=AC=EB=B2=95=ED=95=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EB=A5=BC=20=EC=BB=A4=EC=8A=A4=ED=85=80=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/cardlist/CardList.java | 6 +-- .../trello/cardlist/CardListController.java | 5 ++- .../trello/cardlist/CardListRepository.java | 17 +++++--- .../trello/cardlist/CardListService.java | 42 ++++++++++--------- .../common/exception/CardListErrorCode.java | 3 +- 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/example/trello/cardlist/CardList.java b/src/main/java/com/example/trello/cardlist/CardList.java index 80befed..e71b8ac 100644 --- a/src/main/java/com/example/trello/cardlist/CardList.java +++ b/src/main/java/com/example/trello/cardlist/CardList.java @@ -2,8 +2,8 @@ import com.example.trello.board.Board; import com.example.trello.card.Card; -import com.example.trello.cardlist.dto.UpdateCardListRequestDto; import com.example.trello.cardlist.dto.CardListResponseDto; +import com.example.trello.cardlist.dto.UpdateCardListRequestDto; import jakarta.persistence.*; import lombok.*; @@ -39,7 +39,7 @@ public static CardListResponseDto toDto(CardList cardList) { .build(); } - public void update(UpdateCardListRequestDto requestDto, Integer sequence ) { + public void update(UpdateCardListRequestDto requestDto, Integer sequence) { this.title = requestDto.getTitle(); this.sequence = sequence; @@ -54,6 +54,6 @@ public void upSequence() { } public void updateSequence(Integer sequence) { - this.sequence=sequence; + this.sequence = sequence; } } diff --git a/src/main/java/com/example/trello/cardlist/CardListController.java b/src/main/java/com/example/trello/cardlist/CardListController.java index 14cd9f1..449a4e5 100644 --- a/src/main/java/com/example/trello/cardlist/CardListController.java +++ b/src/main/java/com/example/trello/cardlist/CardListController.java @@ -1,8 +1,8 @@ package com.example.trello.cardlist; -import com.example.trello.cardlist.dto.UpdateCardListRequestDto; -import com.example.trello.cardlist.dto.CreateCardListRequestDto; import com.example.trello.cardlist.dto.CardListResponseDto; +import com.example.trello.cardlist.dto.CreateCardListRequestDto; +import com.example.trello.cardlist.dto.UpdateCardListRequestDto; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -33,6 +33,7 @@ public ResponseEntity updateCardList(@PathVariable Long id, return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); } + @PatchMapping("/{id}/exchange") public ResponseEntity swapCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto) { CardListResponseDto cardListResponseDto = cardListService.swapSequence(id, requestDto); diff --git a/src/main/java/com/example/trello/cardlist/CardListRepository.java b/src/main/java/com/example/trello/cardlist/CardListRepository.java index 3531f6a..f3be8cc 100644 --- a/src/main/java/com/example/trello/cardlist/CardListRepository.java +++ b/src/main/java/com/example/trello/cardlist/CardListRepository.java @@ -1,6 +1,7 @@ package com.example.trello.cardlist; import com.example.trello.board.Board; +import com.example.trello.common.exception.CardListException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -9,22 +10,26 @@ import java.util.List; import java.util.Optional; +import static com.example.trello.common.exception.CardListErrorCode.CARD_LIST_NOT_FOUND; + @Repository public interface CardListRepository extends JpaRepository { List findByBoard(Board board); default CardList findByIdOrElseThrow(Long id) { - return findById(id).orElseThrow(() -> new RuntimeException()); + return findById(id).orElseThrow(() -> new CardListException(CARD_LIST_NOT_FOUND)); } - @Query(value = "select max(cardlist.sequence)from CardList cardlist where cardlist.board.id = :board_id" ) + + @Query(value = "select max(cardlist.sequence)from CardList cardlist where cardlist.board.id = :board_id") Optional findByMax(@Param("board_id") Long board_id); - Optional findBySequenceAndBoardId(Integer sequence,Long boardId); + Optional findBySequenceAndBoardId(Integer sequence, Long boardId); - default CardList findBySequenceAndBoardIdOrElseThrow(Integer sequence,Long boardId){ - return findBySequenceAndBoardId(sequence,boardId).orElseThrow(()->new RuntimeException()); + default CardList findBySequenceAndBoardIdOrElseThrow(Integer sequence, Long boardId) { + return findBySequenceAndBoardId(sequence, boardId).orElseThrow(() -> new CardListException(CARD_LIST_NOT_FOUND)); } - List findAllByBoardId(Long boardId); + + List findAllByBoardId(Long boardId); } diff --git a/src/main/java/com/example/trello/cardlist/CardListService.java b/src/main/java/com/example/trello/cardlist/CardListService.java index d25c3b4..9f79952 100644 --- a/src/main/java/com/example/trello/cardlist/CardListService.java +++ b/src/main/java/com/example/trello/cardlist/CardListService.java @@ -2,15 +2,18 @@ import com.example.trello.board.Board; import com.example.trello.board.BoardRepository; -import com.example.trello.cardlist.dto.UpdateCardListRequestDto; -import com.example.trello.cardlist.dto.CreateCardListRequestDto; import com.example.trello.cardlist.dto.CardListResponseDto; +import com.example.trello.cardlist.dto.CreateCardListRequestDto; +import com.example.trello.cardlist.dto.UpdateCardListRequestDto; +import com.example.trello.common.exception.CardListException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import static com.example.trello.common.exception.CardListErrorCode.INVALID_SEQUENCE; + @Service @RequiredArgsConstructor public class CardListService { @@ -31,7 +34,7 @@ public CardListResponseDto create(CreateCardListRequestDto requestDto) { } - public CardListResponseDto findCardList(Long id) { //todo dto 이름 바꾸기 + public CardListResponseDto findCardList(Long id) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); return CardList.toDto(cardList); } @@ -39,27 +42,26 @@ public CardListResponseDto findCardList(Long id) { //todo dto 이름 바꾸기 @Transactional public CardListResponseDto moveSequence(Long id, UpdateCardListRequestDto requestDto) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); - Integer currentSequence=cardList.getSequence(); - + Integer currentSequence = cardList.getSequence(); List cardLists = cardListRepository.findAllByBoardId(cardList.getBoard().getId()); - if(currentSequence!=requestDto.getSequence()) { - if(currentSequence cardLists.size()) { + throw new CardListException(INVALID_SEQUENCE); + } + + if (currentSequence != requestDto.getSequence()) { + if (currentSequence < requestDto.getSequence()) { cardLists.stream() - .filter(e->e.getSequence()>currentSequence) - .filter(e->e.getSequence()<=requestDto.getSequence()) - .forEach(e->e.downSequence()); - }else { + .filter(e -> e.getSequence() > currentSequence) + .filter(e -> e.getSequence() <= requestDto.getSequence()) + .forEach(e -> e.downSequence()); + } else { cardLists.stream() - .filter(e->e.getSequence()e.getSequence()>=requestDto.getSequence()) - .forEach(e->e.upSequence()); + .filter(e -> e.getSequence() < currentSequence) + .filter(e -> e.getSequence() >= requestDto.getSequence()) + .forEach(e -> e.upSequence()); } - } - - if (requestDto.getSequence()>cardLists.size()){ - - throw new RuntimeException(); + cardList.updateSequence(requestDto.getSequence()); } return CardList.toDto(cardList); @@ -68,7 +70,7 @@ public CardListResponseDto moveSequence(Long id, UpdateCardListRequestDto reques @Transactional public CardListResponseDto swapSequence(Long id, UpdateCardListRequestDto requestDto) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); - CardList exchangeCardList = cardListRepository.findBySequenceAndBoardIdOrElseThrow(requestDto.getSequence(),cardList.getBoard().getId()); + CardList exchangeCardList = cardListRepository.findBySequenceAndBoardIdOrElseThrow(requestDto.getSequence(), cardList.getBoard().getId()); Integer temp = cardList.getSequence(); cardList.update(requestDto, exchangeCardList.getSequence()); exchangeCardList.updateSequence(temp); diff --git a/src/main/java/com/example/trello/common/exception/CardListErrorCode.java b/src/main/java/com/example/trello/common/exception/CardListErrorCode.java index 4c830d7..087822a 100644 --- a/src/main/java/com/example/trello/common/exception/CardListErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/CardListErrorCode.java @@ -7,7 +7,8 @@ @RequiredArgsConstructor @Getter public enum CardListErrorCode { - CARD_LIST_NOT_FOUND("리스트를 찾을 수 없습니다.", HttpStatus.NOT_FOUND); + CARD_LIST_NOT_FOUND("리스트를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), + INVALID_SEQUENCE("지정한 순서로 변경할수 없습니다", HttpStatus.BAD_REQUEST); private final String message; private final HttpStatus httpStatus; From e9b950a55baf6d943bae7c64b245aad6f5bfc3ad Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 09:59:09 +0900 Subject: [PATCH 102/181] =?UTF-8?q?feat=20:=20Board=20=EC=97=90=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/board/BoardController.java | 7 +++- .../example/trello/board/BoardService.java | 37 +++++++++++++--- .../trello/board/FileUploadController.java | 42 ------------------- ...tDto.java => BoardRequestWithFileDto.java} | 14 +++---- 4 files changed, 44 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/com/example/trello/board/FileUploadController.java rename src/main/java/com/example/trello/board/dto/{BoardRequestDto.java => BoardRequestWithFileDto.java} (66%) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index efccda4..2ff7be4 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -17,8 +17,11 @@ public class BoardController { private final BoardService boardService; - @PostMapping - public ResponseEntity createBoard(@Valid @RequestBody BoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + @PostMapping // 추가 + public ResponseEntity createBoard( + @Valid @ModelAttribute BoardRequestWithFileDto dto, // 수정 + @AuthenticationPrincipal UserDetailsImpl userDetails) { + BoardResponseDto boardResponseDto = boardService.createBoard(dto, userDetails.getUser().getId()); return new ResponseEntity<>(boardResponseDto, HttpStatus.CREATED); } diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 2f7d7c2..d007b96 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -1,5 +1,7 @@ package com.example.trello.board; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.ObjectMetadata; import com.example.trello.board.dto.*; import com.example.trello.card.Card; import com.example.trello.card.cardrepository.CardRepository; @@ -12,9 +14,13 @@ import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -27,13 +33,21 @@ public class BoardService { private final WorkspaceMemberRepository workspaceMemberRepository; private final CardListRepository cardListRepository; private final CardRepository cardRepository; + private final AmazonS3Client amazonS3Client; + @Value("${cloud.aws.s3.bucket}") + private String bucket; @Transactional - public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, dto.getWorkspaceId()); + public BoardResponseDto createBoard(BoardRequestWithFileDto dto, Long userId) { + WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userId, dto.getWorkspaceId()); if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); + throw new RuntimeException("읽기 전용 역할은 보드를 생성할 수 없습니다."); + } + + String imageUrl = null; + if(dto.getFile() != null && !dto.getFile().isEmpty()) { + imageUrl = uploadFileToS3(dto.getFile()); } Workspace workspace = findWorkspaceMember.getWorkspace(); @@ -41,12 +55,11 @@ public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { Board board = Board.builder() .title(dto.getTitle()) .color(dto.getColor()) - .image(dto.getImage()) + .image(imageUrl) .workspace(workspace) .build(); boardRepository.save(board); - return BoardResponseDto.toDto(board); } @@ -110,4 +123,18 @@ public void deleteBoard(Long boardId, Long loginUserId) { boardRepository.delete(findBoard); } + + private String uploadFileToS3(MultipartFile file) { + try { + String fileName = file.getOriginalFilename(); + String fileUrl = "https://" + bucket + "/test" + fileName; + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(file.getContentType()); + metadata.setContentLength(file.getSize()); + amazonS3Client.putObject(bucket, fileName, file.getInputStream(), metadata); + return fileUrl; + } catch (IOException e) { + throw new RuntimeException("파일 업로드에 실패했습니다.", e); + } + } } diff --git a/src/main/java/com/example/trello/board/FileUploadController.java b/src/main/java/com/example/trello/board/FileUploadController.java deleted file mode 100644 index 635c12b..0000000 --- a/src/main/java/com/example/trello/board/FileUploadController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.example.trello.board; - -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.ObjectMetadata; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; - -@RestController -@RequestMapping("/upload") -@RequiredArgsConstructor -public class FileUploadController { - private final AmazonS3Client amazonS3Client; - - @Value("${cloud.aws.s3.bucket}") - private String bucket; - - @PostMapping - public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) { - try { - String fileName = file.getOriginalFilename(); - String fileUrl = "https://" + bucket + "/test" + fileName; - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(file.getContentType()); - metadata.setContentLength(file.getSize()); - amazonS3Client.putObject(bucket, fileName, file.getInputStream(), metadata); - return ResponseEntity.ok(fileUrl); - } catch (IOException e) { - e.printStackTrace(); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - } - } -} - diff --git a/src/main/java/com/example/trello/board/dto/BoardRequestDto.java b/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java similarity index 66% rename from src/main/java/com/example/trello/board/dto/BoardRequestDto.java rename to src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java index b494b74..64fa1c7 100644 --- a/src/main/java/com/example/trello/board/dto/BoardRequestDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java @@ -1,28 +1,28 @@ package com.example.trello.board.dto; - import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Getter; +import lombok.Setter; +import org.springframework.web.multipart.MultipartFile; @Getter -public class BoardRequestDto { +@Setter +public class BoardRequestWithFileDto { @NotBlank(message = "title 은 Null 일 수 없습니다.") @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; private String color; - - private String image; - @NotNull private Long workspaceId; + private MultipartFile file; - public BoardRequestDto(String title, String color, String image, Long workspaceId) { + public BoardRequestWithFileDto(String title, String color, Long workspaceId, MultipartFile file) { this.title = title; this.color = color; - this.image = image; this.workspaceId = workspaceId; + this.file = file; } } From 6d723005e5cf7182fd1c73727672c177087e13cd Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 10:05:37 +0900 Subject: [PATCH 103/181] =?UTF-8?q?refactor=20:=20Board=20=EC=97=90=20?= =?UTF-8?q?=EC=83=89=EA=B9=94=20=EC=BB=AC=EB=9F=BC=EC=9D=84=20ENUM=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit String 타입으로 받을시 아무 입력값이나 다 입력이 가능해 ENUM 타입으로 변경해 입력값을 받도록 변경 --- src/main/java/com/example/trello/board/Board.java | 7 ++++--- .../java/com/example/trello/board/BoardColor.java | 12 ++++++++++++ .../trello/board/dto/BoardDetailResponseDto.java | 5 +++-- .../trello/board/dto/BoardRequestWithFileDto.java | 5 +++-- .../example/trello/board/dto/BoardResponseDto.java | 5 +++-- .../trello/board/dto/UpdateBoardRequestDto.java | 5 +++-- 6 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/example/trello/board/BoardColor.java diff --git a/src/main/java/com/example/trello/board/Board.java b/src/main/java/com/example/trello/board/Board.java index 27349ff..d2ed11c 100644 --- a/src/main/java/com/example/trello/board/Board.java +++ b/src/main/java/com/example/trello/board/Board.java @@ -20,7 +20,8 @@ public class Board { private String title; @Column(name = "color") - private String color; + @Enumerated(EnumType.STRING) + private BoardColor color; @Column(name = "image") private String image; @@ -35,14 +36,14 @@ public Board() { } @Builder - public Board(String title, String color, String image, Workspace workspace) { + public Board(String title, BoardColor color, String image, Workspace workspace) { this.title = title; this.color = color; this.image = image; this.workspace = workspace; } - public void updateBoard(String title, String color, String image) { + public void updateBoard(String title, BoardColor color, String image) { this.title = title; this.color = color; this.image = image; diff --git a/src/main/java/com/example/trello/board/BoardColor.java b/src/main/java/com/example/trello/board/BoardColor.java new file mode 100644 index 0000000..5a6dbd5 --- /dev/null +++ b/src/main/java/com/example/trello/board/BoardColor.java @@ -0,0 +1,12 @@ +package com.example.trello.board; + +public enum BoardColor { + BLACK, + BLUE, + RED, + WHITE, + ORANGE, + PURPLE, + YELLOW, + GREEN +} diff --git a/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java b/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java index fa1383e..507a347 100644 --- a/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardDetailResponseDto.java @@ -1,6 +1,7 @@ package com.example.trello.board.dto; import com.example.trello.board.Board; +import com.example.trello.board.BoardColor; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.dto.GetCardListResponseDto; import lombok.Getter; @@ -11,11 +12,11 @@ public class BoardDetailResponseDto { private Long id; private String title; - private String color; + private BoardColor color; private String image; private List cardList; - public BoardDetailResponseDto(Long id, String title, String color, String image, List cardList) { + public BoardDetailResponseDto(Long id, String title, BoardColor color, String image, List cardList) { this.id = id; this.title = title; this.color = color; diff --git a/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java b/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java index 64fa1c7..9194e0d 100644 --- a/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java @@ -1,5 +1,6 @@ package com.example.trello.board.dto; +import com.example.trello.board.BoardColor; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -14,12 +15,12 @@ public class BoardRequestWithFileDto { @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; - private String color; + private BoardColor color; @NotNull private Long workspaceId; private MultipartFile file; - public BoardRequestWithFileDto(String title, String color, Long workspaceId, MultipartFile file) { + public BoardRequestWithFileDto(String title, BoardColor color, Long workspaceId, MultipartFile file) { this.title = title; this.color = color; this.workspaceId = workspaceId; diff --git a/src/main/java/com/example/trello/board/dto/BoardResponseDto.java b/src/main/java/com/example/trello/board/dto/BoardResponseDto.java index 22a83cb..32858ad 100644 --- a/src/main/java/com/example/trello/board/dto/BoardResponseDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardResponseDto.java @@ -1,16 +1,17 @@ package com.example.trello.board.dto; import com.example.trello.board.Board; +import com.example.trello.board.BoardColor; import lombok.Getter; @Getter public class BoardResponseDto { private Long id; private String title; - private String color; + private BoardColor color; private String image; - public BoardResponseDto(Long id, String title, String color, String image) { + public BoardResponseDto(Long id, String title, BoardColor color, String image) { this.id = id; this.title = title; this.color = color; diff --git a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java index 51637a2..c598fa7 100644 --- a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java +++ b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java @@ -1,5 +1,6 @@ package com.example.trello.board.dto; +import com.example.trello.board.BoardColor; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; import lombok.Getter; @@ -10,11 +11,11 @@ public class UpdateBoardRequestDto { @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; - private String color; + private BoardColor color; private String image; - public UpdateBoardRequestDto(String title, String color, String image) { + public UpdateBoardRequestDto(String title, BoardColor color, String image) { this.title = title; this.color = color; this.image = image; From b15d75e83a734913dda987063aff64357733d077 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 10:17:03 +0900 Subject: [PATCH 104/181] =?UTF-8?q?feat=20:=20Board=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=82=BD=EC=9E=85=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/board/BoardController.java | 4 ++-- .../java/com/example/trello/board/BoardService.java | 10 +++++++--- ...ardRequestWithFileDto.java => BoardRequestDto.java} | 4 ++-- .../trello/board/dto/UpdateBoardRequestDto.java | 7 ++++--- 4 files changed, 15 insertions(+), 10 deletions(-) rename src/main/java/com/example/trello/board/dto/{BoardRequestWithFileDto.java => BoardRequestDto.java} (83%) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 2ff7be4..f31d131 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -19,7 +19,7 @@ public class BoardController { @PostMapping // 추가 public ResponseEntity createBoard( - @Valid @ModelAttribute BoardRequestWithFileDto dto, // 수정 + @Valid @ModelAttribute BoardRequestDto dto, // 수정 @AuthenticationPrincipal UserDetailsImpl userDetails) { BoardResponseDto boardResponseDto = boardService.createBoard(dto, userDetails.getUser().getId()); @@ -39,7 +39,7 @@ public ResponseEntity viewBoard(@PathVariable Long board } @PatchMapping("/{boardId}") - public ResponseEntity updateBoard(@PathVariable Long boardId, @Valid @RequestBody UpdateBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity updateBoard(@PathVariable Long boardId, @Valid @ModelAttribute UpdateBoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { BoardResponseDto updatedBoardResponseDto = boardService.updateBoard(boardId, dto, userDetails.getUser().getId()); return new ResponseEntity<>(updatedBoardResponseDto, HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index d007b96..8730d4c 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -20,7 +20,6 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; -import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -38,7 +37,7 @@ public class BoardService { private String bucket; @Transactional - public BoardResponseDto createBoard(BoardRequestWithFileDto dto, Long userId) { + public BoardResponseDto createBoard(BoardRequestDto dto, Long userId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userId, dto.getWorkspaceId()); if (findWorkspaceMember.getRole() == READ_ONLY) { @@ -107,7 +106,12 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); } - findBoard.updateBoard(dto.getTitle(), dto.getColor(), dto.getImage()); + String imageUrl = null; + if(dto.getFile() != null && !dto.getFile().isEmpty()) { + imageUrl = uploadFileToS3(dto.getFile()); + } + + findBoard.updateBoard(dto.getTitle(), dto.getColor(), imageUrl); return BoardResponseDto.toDto(findBoard); } diff --git a/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java b/src/main/java/com/example/trello/board/dto/BoardRequestDto.java similarity index 83% rename from src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java rename to src/main/java/com/example/trello/board/dto/BoardRequestDto.java index 9194e0d..d7f0283 100644 --- a/src/main/java/com/example/trello/board/dto/BoardRequestWithFileDto.java +++ b/src/main/java/com/example/trello/board/dto/BoardRequestDto.java @@ -10,7 +10,7 @@ @Getter @Setter -public class BoardRequestWithFileDto { +public class BoardRequestDto { @NotBlank(message = "title 은 Null 일 수 없습니다.") @Size(min = 1, max = 50, message = "title 크기는 1에서 50사이여야합니다.") private String title; @@ -20,7 +20,7 @@ public class BoardRequestWithFileDto { private Long workspaceId; private MultipartFile file; - public BoardRequestWithFileDto(String title, BoardColor color, Long workspaceId, MultipartFile file) { + public BoardRequestDto(String title, BoardColor color, Long workspaceId, MultipartFile file) { this.title = title; this.color = color; this.workspaceId = workspaceId; diff --git a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java index c598fa7..433ffa9 100644 --- a/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java +++ b/src/main/java/com/example/trello/board/dto/UpdateBoardRequestDto.java @@ -4,6 +4,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; import lombok.Getter; +import org.springframework.web.multipart.MultipartFile; @Getter public class UpdateBoardRequestDto { @@ -13,11 +14,11 @@ public class UpdateBoardRequestDto { private BoardColor color; - private String image; + private MultipartFile file; - public UpdateBoardRequestDto(String title, BoardColor color, String image) { + public UpdateBoardRequestDto(String title, BoardColor color, MultipartFile file) { this.title = title; this.color = color; - this.image = image; + this.file = file; } } From dfe63616940231d303237ff86bcf92ab00079a47 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 10:17:56 +0900 Subject: [PATCH 105/181] =?UTF-8?q?refactor=20:=20=EA=B0=81=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=EB=B3=84=20findById=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=97=90=EB=9F=AC=EB=A5=BC=20=EA=B0=81=EA=B0=81?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EC=BB=A4=EC=8A=A4=ED=85=80?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardRepository.java | 4 +++- .../com/example/trello/common/exception/BoardErrorCode.java | 3 ++- .../example/trello/common/exception/WorkspaceErrorCode.java | 4 +++- .../trello/common/exception/WorkspaceMemberErrorCode.java | 3 ++- .../com/example/trello/workspace/WorkSpaceRepository.java | 6 +++++- .../trello/workspace_member/WorkspaceMemberRepository.java | 2 +- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardRepository.java b/src/main/java/com/example/trello/board/BoardRepository.java index 9f9f1ff..2d8012d 100644 --- a/src/main/java/com/example/trello/board/BoardRepository.java +++ b/src/main/java/com/example/trello/board/BoardRepository.java @@ -1,5 +1,7 @@ package com.example.trello.board; +import com.example.trello.common.exception.BoardErrorCode; +import com.example.trello.common.exception.BoardException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -10,6 +12,6 @@ public interface BoardRepository extends JpaRepository { List findAllByWorkspaceId(Long workspaceId); default Board findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + return findById(id).orElseThrow(() -> new BoardException(BoardErrorCode.CAN_NOT_FIND_BOARD_WITH_BOARD_ID)); } } diff --git a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java index da1ec2e..0f74868 100644 --- a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java @@ -9,7 +9,8 @@ @RequiredArgsConstructor @Getter public enum BoardErrorCode { - READ_ONLY_CANT_NOT_HANDLE_BOARD("읽기 전용 역할은 할 수 없는 작업입니다.", FORBIDDEN); + READ_ONLY_CANT_NOT_HANDLE_BOARD("읽기 전용 역할은 할 수 없는 작업입니다.", FORBIDDEN), + CAN_NOT_FIND_BOARD_WITH_BOARD_ID("보드를 찾을 수 없습니다.", BAD_REQUEST); private final String message; diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java b/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java index ced0dd9..ac67bbe 100644 --- a/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/WorkspaceErrorCode.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; +import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.FORBIDDEN; @RequiredArgsConstructor @@ -11,7 +12,8 @@ public enum WorkspaceErrorCode { ONLY_ADMIN_CAN_CREATE_WORKSPACE("ADMIN 역할의 USER만 워크스페이스를 생성할 수 있습니다.", FORBIDDEN), ONLY_ADMIN_CAN_UPDATE_MEMBER_ROLE_TO_WORKSPACE("ADMIN 역할의 USER만 다른 MEMBER의 역할을 워크스페이스로 수정할 수 있습니다.", FORBIDDEN), - ONLY_WORKSPACE_ROLE_CAN_HANDLE_WORKSPACE("WORKSPACE 역할의 MEMBER만 워크스페이스를 관리할 수 있습니다.", FORBIDDEN); + ONLY_WORKSPACE_ROLE_CAN_HANDLE_WORKSPACE("WORKSPACE 역할의 MEMBER만 워크스페이스를 관리할 수 있습니다.", FORBIDDEN), + CAN_NOT_FIND_WORKSPACE_WITH_WORKSPACE_ID("WORKSPACE 를 찾을 수 없습니다.", BAD_REQUEST); private final String message; private final HttpStatus httpStatus; diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java index 8d35666..5d1a07f 100644 --- a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java @@ -13,7 +13,8 @@ public enum WorkspaceMemberErrorCode { IS_NOT_WORKSPACEMEMBER("WORKSPACE의 MEMBER가 아닙니다.", FORBIDDEN), ONLY_WORKSPACE_ROLE_CAN_INVITE("WORKSPACE 역할의 MEMBER만 초대가 가능합니다.", FORBIDDEN), ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE("WORKSPACE 역할의 MEMBER만 다른 유저의 권한을 (BOARD, READ_ONLY)로 변경이 가능합니다.", FORBIDDEN), - ALREADY_MEMBER("이미 워크스페이스의 멤버입니다.", BAD_REQUEST); + ALREADY_MEMBER("이미 워크스페이스의 멤버입니다.", BAD_REQUEST), + CAN_NOT_FIND_WORKSPACEMEMBER_WITH_WORKSPACEMEMBER_ID("WORKSPACEMEMBER 를 찾을 수 없습니다.", BAD_REQUEST); private final String message; private final HttpStatus httpStatus; diff --git a/src/main/java/com/example/trello/workspace/WorkSpaceRepository.java b/src/main/java/com/example/trello/workspace/WorkSpaceRepository.java index f8382b1..4741a60 100644 --- a/src/main/java/com/example/trello/workspace/WorkSpaceRepository.java +++ b/src/main/java/com/example/trello/workspace/WorkSpaceRepository.java @@ -1,5 +1,9 @@ package com.example.trello.workspace; +import com.example.trello.common.exception.WorkspaceErrorCode; +import com.example.trello.common.exception.WorkspaceException; +import com.example.trello.common.exception.WorkspaceMemberErrorCode; +import com.example.trello.common.exception.WorkspaceMemberException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -7,7 +11,7 @@ public interface WorkSpaceRepository extends JpaRepository { default Workspace findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + return findById(id).orElseThrow(() -> new WorkspaceException(WorkspaceErrorCode.CAN_NOT_FIND_WORKSPACE_WITH_WORKSPACE_ID)); } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java index c30573c..85229a1 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberRepository.java @@ -19,7 +19,7 @@ public interface WorkspaceMemberRepository extends JpaRepository new RuntimeException()); + return findById(id).orElseThrow(() -> new WorkspaceMemberException(WorkspaceMemberErrorCode.CAN_NOT_FIND_WORKSPACEMEMBER_WITH_WORKSPACEMEMBER_ID)); } default WorkspaceMember findByIdAndWorkspaceIdOrElseThrow(Long id, Long workspaceId){ From 65f8453c89535d687402a51c01ffd3d7c1fe46eb Mon Sep 17 00:00:00 2001 From: jut Date: Sun, 29 Dec 2024 16:45:23 +0900 Subject: [PATCH 106/181] =?UTF-8?q?fix=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/user/User.java | 8 ++++++- .../example/trello/user/UserRepository.java | 9 ++++--- .../com/example/trello/user/UserService.java | 18 +++++++------- .../user/controller/UserController.java | 24 ++++++++++++------- .../com/example/trello/user/enums/Role.java | 6 ++--- .../com/example/trello/util/JwtProvider.java | 3 +-- 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/example/trello/user/User.java b/src/main/java/com/example/trello/user/User.java index 3decebb..4a80489 100644 --- a/src/main/java/com/example/trello/user/User.java +++ b/src/main/java/com/example/trello/user/User.java @@ -2,9 +2,13 @@ import com.example.trello.user.enums.AccountStatus; import com.example.trello.user.enums.Role; +import com.example.trello.workspace.Workspace; +import com.example.trello.workspace_member.WorkspaceMember; import jakarta.persistence.*; import lombok.*; +import java.util.List; + @Getter @Entity @Table(name = "users") @@ -29,11 +33,13 @@ public class User { @Enumerated(EnumType.STRING) private Role role; - @Setter @Column @Enumerated(EnumType.STRING) private AccountStatus status; + @OneToMany(mappedBy = "user") + private List workspaceMembers; + @Builder public User(String email, String password, String nickname, Role role, AccountStatus status) { this.email = email; diff --git a/src/main/java/com/example/trello/user/UserRepository.java b/src/main/java/com/example/trello/user/UserRepository.java index 5e0c096..fbbfc33 100644 --- a/src/main/java/com/example/trello/user/UserRepository.java +++ b/src/main/java/com/example/trello/user/UserRepository.java @@ -1,6 +1,7 @@ package com.example.trello.user; -import com.example.trello.comment.Comment; +import com.example.trello.common.exception.UserErrorCode; +import com.example.trello.common.exception.UserException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -9,13 +10,15 @@ @Repository public interface UserRepository extends JpaRepository { default User findByIdOrElseThrow(Long userId){ - return findById(userId).orElseThrow(()-> new RuntimeException()); + return findById(userId).orElseThrow(() -> new UserException(UserErrorCode.NOT_FOUND_ID)); } Optional findByEmail(String email); + boolean existsByEmail(String email); + default User findByEmailOrElseThrow(String email) { - return findByEmail(email).orElseThrow(()-> new RuntimeException()); + return findByEmail(email).orElseThrow(()-> new UserException(UserErrorCode.NOT_FOUND_EMAIL)); } } diff --git a/src/main/java/com/example/trello/user/UserService.java b/src/main/java/com/example/trello/user/UserService.java index 969ec45..352871b 100644 --- a/src/main/java/com/example/trello/user/UserService.java +++ b/src/main/java/com/example/trello/user/UserService.java @@ -1,5 +1,7 @@ package com.example.trello.user; +import com.example.trello.common.exception.UserErrorCode; +import com.example.trello.common.exception.UserException; import com.example.trello.user.dto.JwtAuthResponse; import com.example.trello.user.dto.LoginRequestDto; import com.example.trello.user.dto.SignupRequestDto; @@ -31,13 +33,9 @@ public class UserService { private final JwtProvider jwtProvider; public void signupUser(SignupRequestDto requestDto) { - Optional findUser = userRepository.findByEmail(requestDto.getEmail()); + boolean isUser = userRepository.existsByEmail(requestDto.getEmail()); - if (findUser.isPresent()) { - - if (AccountStatus.DELETED.equals(findUser.get().getStatus())) { - throw new RuntimeException(); - } + if (isUser) { throw new RuntimeException(); } @@ -58,7 +56,7 @@ public JwtAuthResponse login(LoginRequestDto requestDto) { User findUser = userRepository.findByEmailOrElseThrow(requestDto.getEmail()); if (findUser.isDeletedAccount(findUser)) { - throw new RuntimeException(); + throw new UserException(UserErrorCode.ALREADY_DELETED); } this.validatePassword(requestDto.getPassword(), findUser.getPassword()); @@ -72,7 +70,7 @@ public JwtAuthResponse login(LoginRequestDto requestDto) { SecurityContextHolder.getContext().setAuthentication(authentication); String accessToken = jwtProvider.generateToken(authentication); - log.info("토큰 생성: {}",accessToken); + log.info("토큰 생성: {}", accessToken); return new JwtAuthResponse(AuthenticationScheme.BEARER.getName(), accessToken); } @@ -84,10 +82,10 @@ public void leave(Long userId) { } private void validatePassword(String rawPassword, String encodedPassword) - throws RuntimeException { + throws RuntimeException { boolean notValid = !bCryptPasswordEncoder.matches(rawPassword, encodedPassword); if (notValid) { - throw new RuntimeException(); + throw new UserException(UserErrorCode.PASSWORD_INCORRECT); } } } diff --git a/src/main/java/com/example/trello/user/controller/UserController.java b/src/main/java/com/example/trello/user/controller/UserController.java index be78ec3..3fc4129 100644 --- a/src/main/java/com/example/trello/user/controller/UserController.java +++ b/src/main/java/com/example/trello/user/controller/UserController.java @@ -1,5 +1,8 @@ package com.example.trello.user.controller; +import com.example.trello.common.exception.UserErrorCode; +import com.example.trello.common.exception.UserException; +import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.user.User; import com.example.trello.user.UserService; import com.example.trello.user.dto.JwtAuthResponse; @@ -12,7 +15,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.jaas.SecurityContextLoginModule; import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; @@ -42,16 +48,15 @@ public ResponseEntity login( @PostMapping("/logout") public ResponseEntity logout( - HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, - Authentication authentication - ) throws RuntimeException { + HttpServletRequest request, + HttpServletResponse response, + Authentication authentication) throws RuntimeException { if (authentication != null && authentication.isAuthenticated()) { - new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, null); + new SecurityContextLogoutHandler().logout(request, response, null); return ResponseEntity.ok().body("로그아웃 되었습니다."); } - throw new RuntimeException(); + throw new UserException(UserErrorCode.REQUIRED_LOGIN); } @DeleteMapping("/{userId}") @@ -65,8 +70,11 @@ public ResponseEntity leave( if (authentication != null && authentication.isAuthenticated()) { new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, null); - } - return ResponseEntity.ok().body("회원 탈퇴가 정상적으로 처리되었습니다."); + return ResponseEntity.ok().body("회원 탈퇴가 정상적으로 처리되었습니다."); + + } + throw new UserException(UserErrorCode.REQUIRED_LOGIN); } + } diff --git a/src/main/java/com/example/trello/user/enums/Role.java b/src/main/java/com/example/trello/user/enums/Role.java index 634ec9d..90d3461 100644 --- a/src/main/java/com/example/trello/user/enums/Role.java +++ b/src/main/java/com/example/trello/user/enums/Role.java @@ -7,8 +7,8 @@ @Getter public enum Role { - USER("user"), - ADMIN("admin") + USER("USER"), + ADMIN("ADMIN") ; private final String name; @@ -19,7 +19,7 @@ public enum Role { public static Role of(String roleName) throws IllegalArgumentException { for (Role role : values()) { - if (role.getName().equals(roleName.toLowerCase())) { + if (role.getName().equals(roleName.toUpperCase())) { return role; } } diff --git a/src/main/java/com/example/trello/util/JwtProvider.java b/src/main/java/com/example/trello/util/JwtProvider.java index 9b689f0..d7ddac5 100644 --- a/src/main/java/com/example/trello/util/JwtProvider.java +++ b/src/main/java/com/example/trello/util/JwtProvider.java @@ -97,8 +97,7 @@ public boolean validToken(String token) throws JwtException { * @throws EntityNotFoundException 입력받은 이메일에 해당하는 사용자를 찾지 못했을 경우 */ private String generateTokenBy(String email) throws EntityNotFoundException { - User user = this.userRepository.findByEmail(email) - .orElseThrow(() -> new EntityNotFoundException("해당 email에 맞는 값이 존재하지 않습니다.")); + User user = this.userRepository.findByEmailOrElseThrow(email); Date currentDate = new Date(); Date expireDate = new Date(currentDate.getTime() + this.expiryMillis); From e37b1e915480d88e3e8e3925dc8b16f977a63b85 Mon Sep 17 00:00:00 2001 From: jut Date: Sun, 29 Dec 2024 16:55:27 +0900 Subject: [PATCH 107/181] =?UTF-8?q?feat=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=20=EC=85=89=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/UserErrorCode.java | 23 +++++++++++ .../common/exception/UserException.java | 11 +++++ .../example/trello/config/WebConfigImpl.java | 40 +++++++++++++++++++ .../config/interceptor/BoardInterceptor.java | 1 + .../interceptor/ReadOnlyInterceptor.java | 1 + .../interceptor/WorkSpaceInterceptor.java | 1 + 6 files changed, 77 insertions(+) create mode 100644 src/main/java/com/example/trello/common/exception/UserErrorCode.java create mode 100644 src/main/java/com/example/trello/common/exception/UserException.java create mode 100644 src/main/java/com/example/trello/config/WebConfigImpl.java create mode 100644 src/main/java/com/example/trello/config/interceptor/BoardInterceptor.java create mode 100644 src/main/java/com/example/trello/config/interceptor/ReadOnlyInterceptor.java create mode 100644 src/main/java/com/example/trello/config/interceptor/WorkSpaceInterceptor.java diff --git a/src/main/java/com/example/trello/common/exception/UserErrorCode.java b/src/main/java/com/example/trello/common/exception/UserErrorCode.java new file mode 100644 index 0000000..0bc6430 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/UserErrorCode.java @@ -0,0 +1,23 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +@Getter +public enum UserErrorCode { + + NOT_FOUND_ID("요청하신 아이디값을 찾을 수 없습니다.", HttpStatus.NOT_FOUND), + NOT_FOUND_EMAIL("요청하신 이메일값을 찾을 수 없습니다.", HttpStatus.NOT_FOUND), + + DUPLICATED_EMAIL("중복된 이메일입니다. 다시 입력해 주세요", HttpStatus.NOT_FOUND), + PASSWORD_INCORRECT("비밀번호가 일치하지 않습니다.", HttpStatus.BAD_REQUEST), + + ALREADY_DELETED("이미 탈퇴된 계정입니다.", HttpStatus.BAD_REQUEST), + REQUIRED_LOGIN("로그인이 필요합니다.", HttpStatus.UNAUTHORIZED); + + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/UserException.java b/src/main/java/com/example/trello/common/exception/UserException.java new file mode 100644 index 0000000..5d2ee81 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/UserException.java @@ -0,0 +1,11 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import okhttp3.internal.http2.ErrorCode; + +@RequiredArgsConstructor +@Getter +public class UserException extends RuntimeException { + private final UserErrorCode errorCode; +} diff --git a/src/main/java/com/example/trello/config/WebConfigImpl.java b/src/main/java/com/example/trello/config/WebConfigImpl.java new file mode 100644 index 0000000..6183dcf --- /dev/null +++ b/src/main/java/com/example/trello/config/WebConfigImpl.java @@ -0,0 +1,40 @@ +package com.example.trello.config; + +import com.example.trello.config.interceptor.BoardInterceptor; +import com.example.trello.config.interceptor.ReadOnlyInterceptor; +import com.example.trello.config.interceptor.WorkSpaceInterceptor; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@RequiredArgsConstructor +public class WebConfigImpl implements WebMvcConfigurer { + + private static final String[] AUTH_REQUIRED_PATH_PATTERNS = {"/users/login", "/users/sign-up", "/workspaces"}; + private static final String[] WORKSPACE_ROLE_REQUIRED_PATH_PATTERNS = {""}; + private static final String[] BOARD_ROLE_REQUIRED_PATH_PATTERNS = {""}; + private static final String[] READ_ONLY_ROLE_REQUIRED_PATH_PATTERNS = {""}; + + private final WorkSpaceInterceptor workSpaceInterceptor; + private final BoardInterceptor boardInterceptor; + private final ReadOnlyInterceptor readOnlyInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(workSpaceInterceptor) + .addPathPatterns(WORKSPACE_ROLE_REQUIRED_PATH_PATTERNS) + .excludePathPatterns(AUTH_REQUIRED_PATH_PATTERNS) + .order(Ordered.HIGHEST_PRECEDENCE); + registry.addInterceptor(boardInterceptor) + .addPathPatterns(BOARD_ROLE_REQUIRED_PATH_PATTERNS) + .excludePathPatterns(AUTH_REQUIRED_PATH_PATTERNS) + .order(Ordered.HIGHEST_PRECEDENCE + 1); + registry.addInterceptor(readOnlyInterceptor) + .addPathPatterns(READ_ONLY_ROLE_REQUIRED_PATH_PATTERNS) + .excludePathPatterns(AUTH_REQUIRED_PATH_PATTERNS) + .order(Ordered.HIGHEST_PRECEDENCE + 2); + } +} diff --git a/src/main/java/com/example/trello/config/interceptor/BoardInterceptor.java b/src/main/java/com/example/trello/config/interceptor/BoardInterceptor.java new file mode 100644 index 0000000..575493c --- /dev/null +++ b/src/main/java/com/example/trello/config/interceptor/BoardInterceptor.java @@ -0,0 +1 @@ +package com.example.trello.config.interceptor; import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.config.auth.UserDetailsServiceImpl; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberRole; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @RequiredArgsConstructor @Component public class BoardInterceptor implements HandlerInterceptor { private final WorkspaceMemberRepository workspaceMemberRepository; private final WorkSpaceRepository workSpaceRepository; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getMethod().equals("POST")) { return false; } UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); User user = userDetails.getUser(); Workspace workspace = workSpaceRepository.findByIdOrElseThrow(user.getId()); WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(user.getId(), workspace.getId()); if (workspaceMember.getRole() != WorkspaceMemberRole.WORKSPACE) { throw new RuntimeException(); } return true; } } \ No newline at end of file diff --git a/src/main/java/com/example/trello/config/interceptor/ReadOnlyInterceptor.java b/src/main/java/com/example/trello/config/interceptor/ReadOnlyInterceptor.java new file mode 100644 index 0000000..01c030e --- /dev/null +++ b/src/main/java/com/example/trello/config/interceptor/ReadOnlyInterceptor.java @@ -0,0 +1 @@ +package com.example.trello.config.interceptor; import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.config.auth.UserDetailsServiceImpl; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberRole; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @RequiredArgsConstructor @Component public class ReadOnlyInterceptor implements HandlerInterceptor { private final WorkspaceMemberRepository workspaceMemberRepository; private final WorkSpaceRepository workSpaceRepository; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); User user = userDetails.getUser(); Workspace workspace = workSpaceRepository.findByIdOrElseThrow(user.getId()); WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(user.getId(), workspace.getId()); if (workspaceMember.getRole() != WorkspaceMemberRole.WORKSPACE) { throw new RuntimeException(); } return true; } } \ No newline at end of file diff --git a/src/main/java/com/example/trello/config/interceptor/WorkSpaceInterceptor.java b/src/main/java/com/example/trello/config/interceptor/WorkSpaceInterceptor.java new file mode 100644 index 0000000..574e71e --- /dev/null +++ b/src/main/java/com/example/trello/config/interceptor/WorkSpaceInterceptor.java @@ -0,0 +1 @@ +package com.example.trello.config.interceptor; import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberRole; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @RequiredArgsConstructor @Component @Slf4j public class WorkSpaceInterceptor implements HandlerInterceptor { private final WorkSpaceRepository workSpaceRepository; private final WorkspaceMemberRepository workspaceMemberRepository; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getMethod().equals("POST")) { return false; } UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); User user = userDetails.getUser(); Workspace workspace = workSpaceRepository.findByIdOrElseThrow(user.getId()); WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(user.getId(), workspace.getId()); if (workspaceMember.getRole() != WorkspaceMemberRole.WORKSPACE) { throw new RuntimeException(); } log.info("request.getMethod(): " + request.getMethod()); return true; } } \ No newline at end of file From 2a0fb1592359eff39619b3fcef23216e73163e21 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 18:23:15 +0900 Subject: [PATCH 108/181] =?UTF-8?q?refactor=20:=20BoardService=20=EC=9D=98?= =?UTF-8?q?=20=EB=88=84=EB=9D=BD=EB=90=9C=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=BB=A4=EC=8A=A4=ED=85=80=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 8730d4c..b96b353 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -41,7 +41,7 @@ public BoardResponseDto createBoard(BoardRequestDto dto, Long userId) { WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userId, dto.getWorkspaceId()); if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new RuntimeException("읽기 전용 역할은 보드를 생성할 수 없습니다."); + throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); } String imageUrl = null; From 80935a4d8e44c5947b7d3fbc10b019093226b5de Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 18:38:36 +0900 Subject: [PATCH 109/181] =?UTF-8?q?feat=20:=20Board=20=EC=97=90=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C?= =?UTF-8?q?=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EB=A7=8C=20=EC=97=85=EB=A1=9C=EB=93=9C=EA=B0=80=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=ED=99=95=EC=9E=A5?= =?UTF-8?q?=EC=9E=90=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ .../com/example/trello/board/BoardService.java | 10 ++++++++++ .../trello/common/exception/BoardErrorCode.java | 3 ++- .../com/example/trello/util/FileUploadUtil.java | 17 +++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/trello/util/FileUploadUtil.java diff --git a/build.gradle b/build.gradle index ca7b66f..36d6442 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,9 @@ dependencies { //Slack implementation 'com.slack.api:slack-api-client:1.27.2' + + // Apache Commons IO 라이브러리 + implementation 'commons-io:commons-io:2.11.0' } tasks.named('test') { diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index b96b353..64de2b9 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -10,6 +10,7 @@ import com.example.trello.cardlist.CardListRepository; import com.example.trello.cardlist.dto.GetCardListResponseDto; import com.example.trello.common.exception.*; +import com.example.trello.util.FileUploadUtil; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; @@ -44,6 +45,8 @@ public BoardResponseDto createBoard(BoardRequestDto dto, Long userId) { throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); } + isValidExtension(dto.getFile()); + String imageUrl = null; if(dto.getFile() != null && !dto.getFile().isEmpty()) { imageUrl = uploadFileToS3(dto.getFile()); @@ -141,4 +144,11 @@ private String uploadFileToS3(MultipartFile file) { throw new RuntimeException("파일 업로드에 실패했습니다.", e); } } + + public void isValidExtension(MultipartFile file) { + String fileName = file.getOriginalFilename(); + if (!FileUploadUtil.isAllowedExtension(fileName)) { + throw new BoardException(BoardErrorCode.IS_NOT_ALLOWED_FILE_EXTENSION); + } + } } diff --git a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java index 0f74868..688369c 100644 --- a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java @@ -10,7 +10,8 @@ @Getter public enum BoardErrorCode { READ_ONLY_CANT_NOT_HANDLE_BOARD("읽기 전용 역할은 할 수 없는 작업입니다.", FORBIDDEN), - CAN_NOT_FIND_BOARD_WITH_BOARD_ID("보드를 찾을 수 없습니다.", BAD_REQUEST); + CAN_NOT_FIND_BOARD_WITH_BOARD_ID("보드를 찾을 수 없습니다.", BAD_REQUEST), + IS_NOT_ALLOWED_FILE_EXTENSION("이미지 파일(확장자)만 업로드가 가능합니다.", BAD_REQUEST); private final String message; diff --git a/src/main/java/com/example/trello/util/FileUploadUtil.java b/src/main/java/com/example/trello/util/FileUploadUtil.java new file mode 100644 index 0000000..839a794 --- /dev/null +++ b/src/main/java/com/example/trello/util/FileUploadUtil.java @@ -0,0 +1,17 @@ +package com.example.trello.util; + +import org.apache.commons.io.FilenameUtils; + +public class FileUploadUtil { + private static final String[] ALLOWED_EXTENSIONS = {"jpg", "png", "gif", "jpeg"}; + + public static boolean isAllowedExtension(String fileName) { + String ext = FilenameUtils.getExtension(fileName).toLowerCase(); + for (String allowedExt : ALLOWED_EXTENSIONS) { + if (allowedExt.equals(ext)) { + return true; + } + } + return false; + } +} From f865c742cec4b1d1ddd89f3b90e868be8f413221 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Sun, 29 Dec 2024 18:39:38 +0900 Subject: [PATCH 110/181] =?UTF-8?q?fix=20:=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20Dto=EC=97=90=EC=84=9C=20NotBlank=EB=8A=94?= =?UTF-8?q?=20ENUM=20=ED=83=80=EC=9E=85=EC=9D=84=20=EB=B0=9B=EC=9D=84=20?= =?UTF-8?q?=EC=88=98=20=EC=97=86=EC=96=B4=20NotNull=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workspace_member/dto/UpdateWorkspaceMemberRoleDto.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java b/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java index 4f43f5a..17cba52 100644 --- a/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java +++ b/src/main/java/com/example/trello/workspace_member/dto/UpdateWorkspaceMemberRoleDto.java @@ -10,7 +10,7 @@ public class UpdateWorkspaceMemberRoleDto { @NotNull private Long workspaceMemberId; - @NotBlank + @NotNull private WorkspaceMemberRole role; public UpdateWorkspaceMemberRoleDto(Long workspaceMemberId, WorkspaceMemberRole role) { From 035df27ffe05607d1fad0ef19597165b545070f3 Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Mon, 30 Dec 2024 10:03:55 +0900 Subject: [PATCH 111/181] =?UTF-8?q?fix=20:=20=EB=A6=AC=EB=93=9C=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=EC=9D=84=20=EA=B0=80=EC=A7=84=20=EB=A7=B4?= =?UTF-8?q?=EB=B2=84=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=B2=B4=ED=81=AC=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/common/exception/WorkspaceMemberErrorCode.java | 3 ++- .../trello/workspace_member/WorkspaceMemberService.java | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java index 5d1a07f..14dc821 100644 --- a/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/WorkspaceMemberErrorCode.java @@ -14,7 +14,8 @@ public enum WorkspaceMemberErrorCode { ONLY_WORKSPACE_ROLE_CAN_INVITE("WORKSPACE 역할의 MEMBER만 초대가 가능합니다.", FORBIDDEN), ONLY_WORKSPACE_ROLE_CAN_UPDATE_MEMBER_ROLE("WORKSPACE 역할의 MEMBER만 다른 유저의 권한을 (BOARD, READ_ONLY)로 변경이 가능합니다.", FORBIDDEN), ALREADY_MEMBER("이미 워크스페이스의 멤버입니다.", BAD_REQUEST), - CAN_NOT_FIND_WORKSPACEMEMBER_WITH_WORKSPACEMEMBER_ID("WORKSPACEMEMBER 를 찾을 수 없습니다.", BAD_REQUEST); + CAN_NOT_FIND_WORKSPACEMEMBER_WITH_WORKSPACEMEMBER_ID("WORKSPACEMEMBER 를 찾을 수 없습니다.", BAD_REQUEST), + CAN_NOT_READ_ROLE("권한이 없습니다",FORBIDDEN); private final String message; private final HttpStatus httpStatus; diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 53c1155..875dc87 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -16,6 +16,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import static com.example.trello.common.exception.WorkspaceMemberErrorCode.CAN_NOT_READ_ROLE; import static com.example.trello.user.enums.Role.ADMIN; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @@ -72,4 +73,11 @@ public void updateWorkspaceMemberRole(Long workspaceId, UpdateWorkspaceMemberRol roleUpdatedWorkspaceMember.updateRole(dto.getRole()); log.info("{}의 역할이 {}로 변경되었습니다.", roleUpdatedWorkspaceMember.getUser().getNickname(), dto.getRole()); } + + public void CheckReadRole(Long userId,Long workspaceId) { + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userId, workspaceId); + if(workspaceMember.getRole()==READ_ONLY) { + throw new WorkspaceMemberException(CAN_NOT_READ_ROLE); + } + } } From 9c5f03a330dcac607bfecb6adf44f93d90425aba Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 10:12:53 +0900 Subject: [PATCH 112/181] =?UTF-8?q?Fix=20:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/card/Card.java | 22 ++- .../example/trello/card/CardController.java | 37 +++- .../com/example/trello/card/CardService.java | 175 +++++++++++++++--- .../responsedto/UpdateCardResponseDto.java | 31 ++++ .../trello/comment/CommentService.java | 17 +- 5 files changed, 247 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index 03286eb..755d734 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -2,6 +2,7 @@ import com.example.trello.card.requestDto.UpdateCardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; +import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.comment.Comment; import com.example.trello.workspace_member.WorkspaceMember; @@ -31,8 +32,8 @@ public class Card { @Column(name = "description") private String description; - @Column(name = "image") - private String image; + @Column(name = "fileName") + private String fileName; @Column(name = "start_at") private LocalDate startAt; @@ -51,6 +52,7 @@ public class Card { + @Builder public Card(String title, String description, WorkspaceMember workspaceMember, LocalDate startAt, LocalDate endAt,CardList cardList) { this.title = title; @@ -62,12 +64,16 @@ public Card(String title, String description, WorkspaceMember workspaceMember, L } - public void updateCard(CardList cardList, String title, String description, LocalDate startAt, LocalDate endAt) { - this.cardList = cardList; - this.title = title; - this.description = description; - this.startAt = startAt; - this.endAt = endAt; + public void updateCard(UpdateCardResponseDto responseDto) { + this.cardList = responseDto.getCardList(); + this.title = responseDto.getTitle(); + this.description = responseDto.getDescription(); + this.startAt = responseDto.getStartAt(); + this.endAt = responseDto.getEndAt(); + } + + public void uploadFile(String fileName) { + this.fileName = fileName; } diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index a113ade..3a9325e 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -5,13 +5,15 @@ import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; import com.example.trello.config.auth.UserDetailsImpl; -import com.example.trello.user.User; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; 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.*; +import org.springframework.web.multipart.MultipartFile; + import java.time.LocalDate; @@ -23,6 +25,11 @@ public class CardController { private final CardService cardService; + + /** + * 카드 CRUD + */ + @PostMapping public ResponseEntity createdCard(@RequestBody CardRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { CardResponseDto responseDto = cardService.createdCardService(requestDto, userDetails); @@ -56,4 +63,32 @@ public ResponseEntity getCards(@RequestParam(defaultValue = CardPageResponseDto cards = cardService.searchCards(page, cardListId, startAt, endAt, boardId); return new ResponseEntity<>(cards, HttpStatus.OK); } + + + /** + * 파일 업로드 + */ + + @PostMapping(value = "/{cardId}/addAttachment", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ResponseEntity uploadAttachments(@PathVariable Long cardId, + @RequestPart("file") MultipartFile file, + @AuthenticationPrincipal UserDetailsImpl userDetails) { + String fileUrl = cardService .uploadFile(cardId, file, userDetails); + return new ResponseEntity<>(fileUrl + "업로드 완료", HttpStatus.OK); + } + + @DeleteMapping("/{cardId}/deleteAttachment") + public ResponseEntity deleteFile(@PathVariable Long cardId, + @RequestBody String fileName, + @AuthenticationPrincipal UserDetailsImpl userDetails) { + cardService.deleteFile(cardId, fileName, userDetails); + return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); + } + +// @GetMapping("/{cardId}/getAttachment") +// public ResponseEntity getFileUrl(@PathVariable Long cardId, +// @AuthenticationPrincipal UserDetailsImpl userDetails) { +// return new ResponseEntity<>(cardService.getFile(cardId, userDetails), HttpStatus.OK); +// +// } } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index a2f4633..586f424 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -1,28 +1,40 @@ package com.example.trello.card; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.S3Object; import com.example.trello.card.cardrepository.CardRepository; import com.example.trello.card.cardrepository.CardRepositoryCustomImpl; import com.example.trello.card.responsedto.CardPageResponseDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; import com.example.trello.card.requestDto.UpdateCardRequestDto; +import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; +import com.example.trello.common.exception.WorkspaceMemberErrorCode; +import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; -import com.example.trello.user.User; -import com.example.trello.user.UserRepository; -import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + + -import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @@ -31,10 +43,15 @@ public class CardService { private final CardRepository cardRepository; private final CardListRepository cardListRepository; - private final CardRepositoryCustomImpl cardRepositoryCustomImpl; - private final UserRepository userRepository; - private final WorkSpaceRepository workSpaceRepository; private final WorkspaceMemberRepository workspaceMemberRepository; + private final AmazonS3Client amazonS3Client; + + @Value("${cloud.aws.s3.bucket}") + private String bucketName; + + /** + * 카드 CRUD + */ // 카드 생성 @Transactional @@ -46,6 +63,10 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, UserDetails WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), workspaceId)) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + if (workspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("카드를 생성할 권한이 없습니다."); } @@ -68,17 +89,21 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, UserDetails public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); - CardList cardList = cardListRepository.findByIdOrElseThrow(requestDto.getCardListId()); + WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); - Long workspaceId = cardList.getBoard().getWorkspace().getId(); + CardList cardList = cardRepository.findByIdOrElseThrow(requestDto.getCardListId()).getCardList(); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + UpdateCardResponseDto responseDto = new UpdateCardResponseDto(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } if (workspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("카드를 수정할 권한이 없습니다."); } - card.updateCard(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + card.updateCard(responseDto); cardRepository.save(card); @@ -90,9 +115,11 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque public void deleteCardService(Long cardId, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); - Long workspaceId = card.getCardList().getBoard().getWorkspace().getId(); + WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } if (workspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("카드를 삭제할 권한이 없습니다."); @@ -111,6 +138,7 @@ public CardResponseDto findCardById(Long cardId) { // 카드 다건 조회(조건 O) @Transactional public CardPageResponseDto searchCards(int page , Long cardListId, LocalDate startAt, LocalDate endAt, Long boardId) { + PageRequest pageRequest = PageRequest.of(page,10, Sort.by(Sort.Direction.DESC, "id")); CardPageResponseDto cards = cardRepository.searchCard(pageRequest, cardListId, startAt, endAt, boardId); @@ -118,18 +146,115 @@ public CardPageResponseDto searchCards(int page , Long cardListId, LocalDate sta return cards; } -// private CardListDto convertToDto(List cards) { -// return cards.stream() -// .map(card -> new CardResponseDto( -// card.getCardList().getId(), -// card.getId(), -// card.getTitle(), -// card.getDescription(), -// card.getNikeName(), -// card.getStartAt(), -// card.getEndAt() -// )) -// .toList(); + + + /** + * 파일 업로드 + */ + + + // 파일 업로드 + @Transactional + public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDetails) { + + WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); + + Card card = cardRepository.findByIdOrElseThrow(cardId); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + + + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("파일을 업로드할 권한이 없습니다."); + } + + // 파일 형식 예외처리 + List contentTypeList = new ArrayList<>(); + contentTypeList.add("jpg"); + contentTypeList.add("png"); + contentTypeList.add("pdf"); + contentTypeList.add("csv"); + + if (StringUtils.hasText(file.getContentType())) { + if (!contentTypeList.contains(file.getName().substring(file.getName().lastIndexOf('.') + 1).toLowerCase())) { + throw new RuntimeException("지원하지 않는 파일 형식입니다"); + } + } + + + + + // 파일 크기 예외처리 + long maxSize = 5 * 1024 * 1024; + + if (file.getSize() > maxSize) { + throw new RuntimeException("파일의 크기가 5MB를 넘었습니다 파일의 크기를 줄여주세요"); + } + + String fileName = file.getOriginalFilename(); + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(file.getSize()); + metadata.setContentType(file.getContentType()); + + try { + amazonS3Client.putObject(bucketName, fileName, file.getInputStream(), metadata); + } catch (IOException e) { + throw new RuntimeException(); + } + + card.uploadFile(file.getOriginalFilename()); + return amazonS3Client.getUrl(bucketName, fileName).toString(); + } + + // 파일 삭제 + @Transactional + public void deleteFile(Long cardId, String fileName, UserDetailsImpl userDetails) { + Card card = cardRepository.findByIdOrElseThrow(cardId); + + WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + + if (workspaceMember.getRole() != WORKSPACE) { + throw new RuntimeException("파일을 삭제할 권한이 없습니다."); + } + + if (card.getFileName() == null) { + throw new RuntimeException(); + } + + amazonS3Client.deleteObject(bucketName, fileName); + } + +// @Transactional +// public String getFile(Long cardId, UserDetailsImpl userDetails) { +// Card card = cardRepository.findByIdOrElseThrow(cardId); // 카드 정보 가져오기 +// if (card == null || !fileName.equals(card.getAttachmentUrl())) { +// return ResponseEntity.status(404).body("File not found for this card."); +// } +// +// // S3에서 파일 URL 조회 +// String fileUrl = s3Service.getFileUrlByName(fileName); +// return ResponseEntity.ok(fileUrl); // } + + /** + * 편의성 메소드 + */ + + // WorkspaceMember 찾아주는 메소드 + @Transactional + public WorkspaceMember findWorkSpaceMember(UserDetailsImpl userDetails, Long cardId) { + Card card = cardRepository.findByIdOrElseThrow(cardId); + + Long workspaceId = card.getCardList().getBoard().getWorkspace().getId(); + + return workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + } + } diff --git a/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java new file mode 100644 index 0000000..8cd2901 --- /dev/null +++ b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java @@ -0,0 +1,31 @@ +package com.example.trello.card.responsedto; + +import com.example.trello.cardlist.CardList; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Getter; + +import java.time.LocalDate; + +@Getter +public class UpdateCardResponseDto { + + private CardList cardList; + + private String title; + + private String description; + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate startAt; + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endAt; + + public UpdateCardResponseDto(CardList cardListId, String title, String description, LocalDate startAt, LocalDate endAt) { + this.cardList = cardListId; + this.title = title; + this.description = description; + this.startAt = startAt; + this.endAt = endAt; + } +} diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 4efc8f8..7669f5f 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -5,6 +5,8 @@ import com.example.trello.comment.dto.request.CommentRequestDto; import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; +import com.example.trello.common.exception.WorkspaceMemberErrorCode; +import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.user.User; import com.example.trello.workspace.Workspace; @@ -35,6 +37,11 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + + if (workspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("댓글을 생성할 권한이 없습니다."); } @@ -54,13 +61,17 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail @Transactional public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto requestDto, UserDetailsImpl userDetails) { - Comment comment = commentRepository.findByIdOrElseThrow(commentId); Long workspaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), comment.getCard().getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + + if (workspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("댓글을 수정할 권한이 없습니다."); } @@ -86,6 +97,10 @@ public void deleteComment(Long commentId, UserDetailsImpl userDetails) { WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), comment.getCard().getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + if (workspaceMember.getRole() != WORKSPACE) { throw new RuntimeException("댓글을 삭제할 권한이 없습니다."); } From 272c715520560f345fa91c7b385959ecbbfa3094 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 10:26:45 +0900 Subject: [PATCH 113/181] =?UTF-8?q?refactor=20:=20ReadOnly=20=EC=97=AD?= =?UTF-8?q?=ED=95=A0=EC=9D=B4=20=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8A=94?= =?UTF-8?q?=20=EC=9E=91=EC=97=85=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EA=B3=B5=ED=86=B5?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EB=A7=8C=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EC=84=9C=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/board/BoardService.java | 32 +++++++------------ .../common/exception/BoardErrorCode.java | 2 -- .../example/trello/util/FileUploadUtil.java | 15 +++++++-- .../WorkspaceMemberService.java | 4 +++ 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 64de2b9..666fadf 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -11,9 +11,11 @@ import com.example.trello.cardlist.dto.GetCardListResponseDto; import com.example.trello.common.exception.*; import com.example.trello.util.FileUploadUtil; +import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; +import com.example.trello.workspace_member.WorkspaceMemberService; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -24,35 +26,33 @@ import java.util.ArrayList; import java.util.List; +import static com.example.trello.common.exception.WorkspaceMemberErrorCode.CAN_NOT_READ_ROLE; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; @Service @RequiredArgsConstructor public class BoardService { private final BoardRepository boardRepository; + private final WorkspaceMemberService workspaceMemberService; private final WorkspaceMemberRepository workspaceMemberRepository; private final CardListRepository cardListRepository; private final CardRepository cardRepository; private final AmazonS3Client amazonS3Client; + private final WorkSpaceRepository workSpaceRepository; @Value("${cloud.aws.s3.bucket}") private String bucket; @Transactional - public BoardResponseDto createBoard(BoardRequestDto dto, Long userId) { - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userId, dto.getWorkspaceId()); - - if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); - } - - isValidExtension(dto.getFile()); + public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { + workspaceMemberService.CheckReadRole(loginUserId, dto.getWorkspaceId()); + isValidBoardImage(dto.getFile()); String imageUrl = null; if(dto.getFile() != null && !dto.getFile().isEmpty()) { imageUrl = uploadFileToS3(dto.getFile()); } - Workspace workspace = findWorkspaceMember.getWorkspace(); + Workspace workspace = workSpaceRepository.findByIdOrElseThrow(dto.getWorkspaceId()); Board board = Board.builder() .title(dto.getTitle()) @@ -103,11 +103,7 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { @Transactional public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); - - if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); - } + workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); String imageUrl = null; if(dto.getFile() != null && !dto.getFile().isEmpty()) { @@ -122,11 +118,7 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon @Transactional public void deleteBoard(Long boardId, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); - WorkspaceMember findWorkspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(loginUserId, findBoard.getWorkspace().getId()); - - if (findWorkspaceMember.getRole() == READ_ONLY) { - throw new BoardException(BoardErrorCode.READ_ONLY_CANT_NOT_HANDLE_BOARD); - } + workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); boardRepository.delete(findBoard); } @@ -145,7 +137,7 @@ private String uploadFileToS3(MultipartFile file) { } } - public void isValidExtension(MultipartFile file) { + public void isValidBoardImage(MultipartFile file) { String fileName = file.getOriginalFilename(); if (!FileUploadUtil.isAllowedExtension(fileName)) { throw new BoardException(BoardErrorCode.IS_NOT_ALLOWED_FILE_EXTENSION); diff --git a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java index 688369c..cdfca57 100644 --- a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java @@ -9,11 +9,9 @@ @RequiredArgsConstructor @Getter public enum BoardErrorCode { - READ_ONLY_CANT_NOT_HANDLE_BOARD("읽기 전용 역할은 할 수 없는 작업입니다.", FORBIDDEN), CAN_NOT_FIND_BOARD_WITH_BOARD_ID("보드를 찾을 수 없습니다.", BAD_REQUEST), IS_NOT_ALLOWED_FILE_EXTENSION("이미지 파일(확장자)만 업로드가 가능합니다.", BAD_REQUEST); - private final String message; private final HttpStatus httpStatus; } diff --git a/src/main/java/com/example/trello/util/FileUploadUtil.java b/src/main/java/com/example/trello/util/FileUploadUtil.java index 839a794..2493c98 100644 --- a/src/main/java/com/example/trello/util/FileUploadUtil.java +++ b/src/main/java/com/example/trello/util/FileUploadUtil.java @@ -3,11 +3,22 @@ import org.apache.commons.io.FilenameUtils; public class FileUploadUtil { - private static final String[] ALLOWED_EXTENSIONS = {"jpg", "png", "gif", "jpeg"}; + private static final String[] ALLOWED_BOARD_IMAGE = {"jpg", "png", "gif", "jpeg"}; + private static final String[] ALLOWED_ATTACHMENT_EXTENSIONS = {"jpg", "png", "jpeg", "gif", "pdf", "csv"}; public static boolean isAllowedExtension(String fileName) { String ext = FilenameUtils.getExtension(fileName).toLowerCase(); - for (String allowedExt : ALLOWED_EXTENSIONS) { + for (String allowedExt : ALLOWED_BOARD_IMAGE) { + if (allowedExt.equals(ext)) { + return true; + } + } + return false; + } + + public static boolean isAllowedAttachmentExtension(String fileName) { + String ext = FilenameUtils.getExtension(fileName).toLowerCase(); + for (String allowedExt : ALLOWED_ATTACHMENT_EXTENSIONS) { if (allowedExt.equals(ext)) { return true; } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 875dc87..3c01f7b 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -4,6 +4,7 @@ import com.example.trello.common.exception.WorkspaceException; import com.example.trello.common.exception.WorkspaceMemberErrorCode; import com.example.trello.common.exception.WorkspaceMemberException; +import com.example.trello.notification.NotificationService; import com.example.trello.user.User; import com.example.trello.user.UserRepository; import com.example.trello.workspace.WorkSpaceRepository; @@ -17,6 +18,7 @@ import org.springframework.stereotype.Service; import static com.example.trello.common.exception.WorkspaceMemberErrorCode.CAN_NOT_READ_ROLE; +import static com.example.trello.notification.NotificationType.ADD_MEMBER; import static com.example.trello.user.enums.Role.ADMIN; import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @@ -29,6 +31,7 @@ public class WorkspaceMemberService { private final WorkspaceMemberRepository workspaceMemberRepository; private final WorkSpaceRepository workSpaceRepository; private final UserRepository userRepository; + private final NotificationService notificationService; @Transactional public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, WorkspaceMemberRequestDto dto, Long loginUserId) { @@ -52,6 +55,7 @@ public WorkspaceMemberResponseDto inviteWorkspaceMember(Long workspaceId, Worksp .build(); workspaceMemberRepository.save(workspaceMember); + notificationService.sendSlack(ADD_MEMBER, workspace); return WorkspaceMemberResponseDto.toDto(workspaceMember); } From c460c759c676a3bd65840dccb4a4a7cce50fa010 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 10:52:46 +0900 Subject: [PATCH 114/181] =?UTF-8?q?Fix=20:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/card/Card.java | 4 +++ .../example/trello/card/CardController.java | 23 +++++++------- .../com/example/trello/card/CardService.java | 31 +++++++++---------- .../card/requestDto/FileNameRequestDto.java | 13 ++++++++ 4 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/example/trello/card/requestDto/FileNameRequestDto.java diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index 755d734..621b3b9 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -76,6 +76,10 @@ public void uploadFile(String fileName) { this.fileName = fileName; } + public void deleteFile () { + this.fileName = null; + } + } diff --git a/src/main/java/com/example/trello/card/CardController.java b/src/main/java/com/example/trello/card/CardController.java index 3a9325e..a6d8931 100644 --- a/src/main/java/com/example/trello/card/CardController.java +++ b/src/main/java/com/example/trello/card/CardController.java @@ -1,5 +1,6 @@ package com.example.trello.card; +import com.example.trello.card.requestDto.FileNameRequestDto; import com.example.trello.card.responsedto.CardPageResponseDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; @@ -69,7 +70,7 @@ public ResponseEntity getCards(@RequestParam(defaultValue = * 파일 업로드 */ - @PostMapping(value = "/{cardId}/addAttachment", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/{cardId}/attachment", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity uploadAttachments(@PathVariable Long cardId, @RequestPart("file") MultipartFile file, @AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -77,18 +78,18 @@ public ResponseEntity uploadAttachments(@PathVariable Long cardId, return new ResponseEntity<>(fileUrl + "업로드 완료", HttpStatus.OK); } - @DeleteMapping("/{cardId}/deleteAttachment") + @DeleteMapping("/{cardId}/attachment") public ResponseEntity deleteFile(@PathVariable Long cardId, - @RequestBody String fileName, - @AuthenticationPrincipal UserDetailsImpl userDetails) { - cardService.deleteFile(cardId, fileName, userDetails); + @RequestBody FileNameRequestDto requestDto, + @AuthenticationPrincipal UserDetailsImpl userDetails) { + cardService.deleteFile(cardId, requestDto.getFileName(), userDetails); return new ResponseEntity<>("삭제 완료되었습니다", HttpStatus.OK); } -// @GetMapping("/{cardId}/getAttachment") -// public ResponseEntity getFileUrl(@PathVariable Long cardId, -// @AuthenticationPrincipal UserDetailsImpl userDetails) { -// return new ResponseEntity<>(cardService.getFile(cardId, userDetails), HttpStatus.OK); -// -// } + @GetMapping("/{cardId}/attachment") + public ResponseEntity getFileUrl(@PathVariable Long cardId, + @AuthenticationPrincipal UserDetailsImpl userDetails) { + return new ResponseEntity<>(cardService.getFile(cardId, userDetails), HttpStatus.OK); + + } } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 586f424..09a1dbd 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -184,8 +184,6 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe } - - // 파일 크기 예외처리 long maxSize = 5 * 1024 * 1024; @@ -223,24 +221,25 @@ public void deleteFile(Long cardId, String fileName, UserDetailsImpl userDetails throw new RuntimeException("파일을 삭제할 권한이 없습니다."); } - if (card.getFileName() == null) { - throw new RuntimeException(); - } +// if (card.getFileName() == null) { +// throw new RuntimeException(); +// } + card.deleteFile(); amazonS3Client.deleteObject(bucketName, fileName); } -// @Transactional -// public String getFile(Long cardId, UserDetailsImpl userDetails) { -// Card card = cardRepository.findByIdOrElseThrow(cardId); // 카드 정보 가져오기 -// if (card == null || !fileName.equals(card.getAttachmentUrl())) { -// return ResponseEntity.status(404).body("File not found for this card."); -// } -// -// // S3에서 파일 URL 조회 -// String fileUrl = s3Service.getFileUrlByName(fileName); -// return ResponseEntity.ok(fileUrl); -// } + @Transactional + public String getFile(Long cardId, UserDetailsImpl userDetails) { + + Card card = cardRepository.findByIdOrElseThrow(cardId); + + try { + return amazonS3Client.getUrl(bucketName, card.getFileName()).toString(); + } catch (Exception e) { + throw new RuntimeException("File not found: " + card.getFileName(), e); + } + } /** diff --git a/src/main/java/com/example/trello/card/requestDto/FileNameRequestDto.java b/src/main/java/com/example/trello/card/requestDto/FileNameRequestDto.java new file mode 100644 index 0000000..f0a01a3 --- /dev/null +++ b/src/main/java/com/example/trello/card/requestDto/FileNameRequestDto.java @@ -0,0 +1,13 @@ +package com.example.trello.card.requestDto; + +import lombok.Getter; + +@Getter +public class FileNameRequestDto { + + private String fileName; + + public FileNameRequestDto(String fileName) { + this.fileName = fileName; + } +} From 3d8e9b3f0b108ece7a2048c847b6f000f62d0798 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 11:04:35 +0900 Subject: [PATCH 115/181] =?UTF-8?q?feat=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=82=AD=EC=A0=9C=EC=8B=9C=20?= =?UTF-8?q?s3=EC=97=90=20=EA=B8=B0=EC=A1=B4=EC=97=90=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=EB=90=9C=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=8F=84=20=EC=82=AD=EC=A0=9C=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/board/BoardService.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 666fadf..0bd297d 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -1,5 +1,6 @@ package com.example.trello.board; +import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectMetadata; import com.example.trello.board.dto.*; @@ -13,7 +14,6 @@ import com.example.trello.util.FileUploadUtil; import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; -import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberService; import lombok.RequiredArgsConstructor; @@ -26,9 +26,6 @@ import java.util.ArrayList; import java.util.List; -import static com.example.trello.common.exception.WorkspaceMemberErrorCode.CAN_NOT_READ_ROLE; -import static com.example.trello.workspace_member.WorkspaceMemberRole.READ_ONLY; - @Service @RequiredArgsConstructor public class BoardService { @@ -104,6 +101,7 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); + deleteFile(findBoard.getImage()); String imageUrl = null; if(dto.getFile() != null && !dto.getFile().isEmpty()) { @@ -119,6 +117,7 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon public void deleteBoard(Long boardId, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); + deleteFile(findBoard.getImage()); boardRepository.delete(findBoard); } @@ -137,6 +136,15 @@ private String uploadFileToS3(MultipartFile file) { } } + public void deleteFile(String image) { + try { + String fileName = image.substring(24); + amazonS3Client.deleteObject(bucket, fileName); + } catch (SdkClientException e) { + throw new RuntimeException("Error deleting file from S3", e); + } + } + public void isValidBoardImage(MultipartFile file) { String fileName = file.getOriginalFilename(); if (!FileUploadUtil.isAllowedExtension(fileName)) { From 4f3fe9502408d57a7e447a10116e907c26b14c65 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 11:38:32 +0900 Subject: [PATCH 116/181] =?UTF-8?q?Fix=20:=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/CardService.java | 65 ++++++++++--------- .../card/cardrepository/CardRepository.java | 4 +- .../common/exception/CardErrorCoed.java | 17 +++++ .../common/exception/CardException.java | 10 +++ 4 files changed, 65 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/example/trello/common/exception/CardErrorCoed.java create mode 100644 src/main/java/com/example/trello/common/exception/CardException.java diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 09a1dbd..7a39a55 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -12,11 +12,15 @@ import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; +import com.example.trello.common.exception.CardErrorCoed; +import com.example.trello.common.exception.CardException; import com.example.trello.common.exception.WorkspaceMemberErrorCode; import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; +import com.example.trello.util.FileUploadUtil; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; +import com.example.trello.workspace_member.WorkspaceMemberService; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; @@ -34,7 +38,7 @@ import java.util.List; - +import static com.example.trello.util.FileUploadUtil.isAllowedExtension; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @@ -45,6 +49,7 @@ public class CardService { private final CardListRepository cardListRepository; private final WorkspaceMemberRepository workspaceMemberRepository; private final AmazonS3Client amazonS3Client; + private final WorkspaceMemberService workspaceMemberService; @Value("${cloud.aws.s3.bucket}") private String bucketName; @@ -67,9 +72,9 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, UserDetails throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("카드를 생성할 권한이 없습니다."); - } + Long workSpaceId = cardList.getBoard().getWorkspace().getId(); + + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); Card card = Card.builder() .title(requestDto.getTitle()) @@ -99,9 +104,8 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("카드를 수정할 권한이 없습니다."); - } + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); card.updateCard(responseDto); @@ -121,9 +125,9 @@ public void deleteCardService(Long cardId, UserDetailsImpl userDetails) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("카드를 삭제할 권한이 없습니다."); - } + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); + + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); cardRepository.delete(card); } @@ -165,22 +169,13 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("파일을 업로드할 권한이 없습니다."); - } + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); // 파일 형식 예외처리 - List contentTypeList = new ArrayList<>(); - contentTypeList.add("jpg"); - contentTypeList.add("png"); - contentTypeList.add("pdf"); - contentTypeList.add("csv"); - - if (StringUtils.hasText(file.getContentType())) { - if (!contentTypeList.contains(file.getName().substring(file.getName().lastIndexOf('.') + 1).toLowerCase())) { - throw new RuntimeException("지원하지 않는 파일 형식입니다"); - } + if (!isAllowedExtension(file.getOriginalFilename())) { + throw new CardException(CardErrorCoed.FORMAT_NOT_SUPPORTED); } @@ -188,7 +183,7 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe long maxSize = 5 * 1024 * 1024; if (file.getSize() > maxSize) { - throw new RuntimeException("파일의 크기가 5MB를 넘었습니다 파일의 크기를 줄여주세요"); + throw new CardException(CardErrorCoed.FILE_SIZE_EXCEEDED); } String fileName = file.getOriginalFilename(); @@ -217,13 +212,13 @@ public void deleteFile(Long cardId, String fileName, UserDetailsImpl userDetails throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("파일을 삭제할 권한이 없습니다."); - } + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); -// if (card.getFileName() == null) { -// throw new RuntimeException(); -// } + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + + if (!card.getFileName().equals(fileName)) { + throw new RuntimeException(); + } card.deleteFile(); amazonS3Client.deleteObject(bucketName, fileName); @@ -234,6 +229,16 @@ public String getFile(Long cardId, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); + WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); + } + + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); + + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + try { return amazonS3Client.getUrl(bucketName, card.getFileName()).toString(); } catch (Exception e) { diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepository.java b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java index 9ef8a1e..dd56eb3 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepository.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java @@ -2,6 +2,8 @@ import com.example.trello.card.Card; import com.example.trello.cardlist.CardList; +import com.example.trello.common.exception.CardErrorCoed; +import com.example.trello.common.exception.CardException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -13,6 +15,6 @@ public interface CardRepository extends JpaRepository, CardRepositor List findByCardList(CardList cardList); default Card findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + return findById(id).orElseThrow(()->new CardException(CardErrorCoed.CARD_NOT_FOUND)); } } diff --git a/src/main/java/com/example/trello/common/exception/CardErrorCoed.java b/src/main/java/com/example/trello/common/exception/CardErrorCoed.java new file mode 100644 index 0000000..626b6a8 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/CardErrorCoed.java @@ -0,0 +1,17 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +@Getter +public enum CardErrorCoed { + + CARD_NOT_FOUND("카드를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), + FORMAT_NOT_SUPPORTED("지원하지 않는 형식입니다", HttpStatus.BAD_REQUEST), + FILE_SIZE_EXCEEDED("파일의 크기가 5MB를 넘었습니다 파일의 크기를 줄여주세요", HttpStatus.BAD_REQUEST); + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/CardException.java b/src/main/java/com/example/trello/common/exception/CardException.java new file mode 100644 index 0000000..fbb32f7 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/CardException.java @@ -0,0 +1,10 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class CardException extends RuntimeException { + private CardErrorCoed errorCoed; +} From c2055d7fac50cfafcb07955bf3f78ce18ff17cb5 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 11:59:49 +0900 Subject: [PATCH 117/181] =?UTF-8?q?Fix=20:=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=83=9D=EC=84=B1=EC=8B=9C=20=EC=8A=AC=EB=9E=99=20?= =?UTF-8?q?=EC=95=8C=EB=9E=8C=20=EC=A0=84=EC=86=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/comment/CommentService.java | 45 ++++++++++++------- .../common/exception/CommentErrorCoed.java | 15 +++++++ .../common/exception/CommentException.java | 10 +++++ 3 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/example/trello/common/exception/CommentErrorCoed.java create mode 100644 src/main/java/com/example/trello/common/exception/CommentException.java diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 7669f5f..81c50e6 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -5,19 +5,26 @@ import com.example.trello.comment.dto.request.CommentRequestDto; import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; +import com.example.trello.common.exception.CommentErrorCoed; +import com.example.trello.common.exception.CommentException; import com.example.trello.common.exception.WorkspaceMemberErrorCode; import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; +import com.example.trello.notification.Notification; +import com.example.trello.notification.NotificationService; import com.example.trello.user.User; +import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; +import com.example.trello.workspace_member.WorkspaceMemberService; import jakarta.servlet.http.HttpServletRequest; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; +import static com.example.trello.notification.NotificationType.CREATE_COMMENT; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @@ -26,7 +33,9 @@ public class CommentService { private final CardRepository cardRepository; private final CommentRepository commentRepository; private final WorkspaceMemberRepository workspaceMemberRepository; - + private final WorkspaceMemberService workspaceMemberService; + private final NotificationService notificationService; + private final WorkSpaceRepository workSpaceRepository; @Transactional public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetailsImpl userDetails) { @@ -42,9 +51,9 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail } - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("댓글을 생성할 권한이 없습니다."); - } + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); + + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); Comment comment = Comment.builder() .content(requestDto.getContent()) @@ -55,6 +64,9 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail commentRepository.save(comment); + Workspace workSpace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + + notificationService.sendSlack(CREATE_COMMENT, workSpace); return CommentResponseDto.toDto(comment); } @@ -63,21 +75,19 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto Comment comment = commentRepository.findByIdOrElseThrow(commentId); - Long workspaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); + Long workSpaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workSpaceId); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), comment.getCard().getCardList().getBoard().getWorkspace().getId())) { + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("댓글을 수정할 권한이 없습니다."); - } + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { - throw new RuntimeException(); + throw new CommentException(CommentErrorCoed.CANNOT_BE_MODIFIED); } comment.updateComment(requestDto.getContent()); @@ -97,16 +107,17 @@ public void deleteComment(Long commentId, UserDetailsImpl userDetails) { WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), comment.getCard().getCardList().getBoard().getWorkspace().getId())) { + Long workSpaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - if (workspaceMember.getRole() != WORKSPACE) { - throw new RuntimeException("댓글을 삭제할 권한이 없습니다."); - } + + workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { - throw new RuntimeException(); + throw new CommentException(CommentErrorCoed.CANNOT_BE_MODIFIED); } commentRepository.delete(comment); diff --git a/src/main/java/com/example/trello/common/exception/CommentErrorCoed.java b/src/main/java/com/example/trello/common/exception/CommentErrorCoed.java new file mode 100644 index 0000000..6971c31 --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/CommentErrorCoed.java @@ -0,0 +1,15 @@ +package com.example.trello.common.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +@Getter +public enum CommentErrorCoed { + + CANNOT_BE_MODIFIED("댓글 수정은 작성자만 가능합니다", HttpStatus.FORBIDDEN); + + private final String message; + private final HttpStatus httpStatus; +} diff --git a/src/main/java/com/example/trello/common/exception/CommentException.java b/src/main/java/com/example/trello/common/exception/CommentException.java new file mode 100644 index 0000000..9827efb --- /dev/null +++ b/src/main/java/com/example/trello/common/exception/CommentException.java @@ -0,0 +1,10 @@ +package com.example.trello.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class CommentException extends RuntimeException { + private CommentErrorCoed commentErrorCoed; +} From fc96008c9706781b2cc4fec5d18acae62556565b Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 12:04:03 +0900 Subject: [PATCH 118/181] =?UTF-8?q?Fix=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=8B=9C=20=EC=8A=AC=EB=9E=99=20=EC=95=8C?= =?UTF-8?q?=EB=9E=8C=20=EC=A0=84=EC=86=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/CardService.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 7a39a55..68e88ce 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -17,7 +17,10 @@ import com.example.trello.common.exception.WorkspaceMemberErrorCode; import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; +import com.example.trello.notification.NotificationService; import com.example.trello.util.FileUploadUtil; +import com.example.trello.workspace.WorkSpaceRepository; +import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberService; @@ -38,6 +41,7 @@ import java.util.List; +import static com.example.trello.notification.NotificationType.UPDATE_CARD; import static com.example.trello.util.FileUploadUtil.isAllowedExtension; import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @@ -50,6 +54,8 @@ public class CardService { private final WorkspaceMemberRepository workspaceMemberRepository; private final AmazonS3Client amazonS3Client; private final WorkspaceMemberService workspaceMemberService; + private final NotificationService notificationService; + private final WorkSpaceRepository workSpaceRepository; @Value("${cloud.aws.s3.bucket}") private String bucketName; @@ -111,6 +117,10 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque cardRepository.save(card); + + + notificationService.sendSlack(UPDATE_CARD, card.getCardList().getBoard().getWorkspace()); + return CardResponseDto.toDto(card); } From fbf8b53bb92665df3b799c8b6ca5b6e488ff33d8 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 13:35:34 +0900 Subject: [PATCH 119/181] =?UTF-8?q?Fix=20:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=20=EC=98=A4=ED=83=80=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/CardService.java | 18 +++--------------- .../card/cardrepository/CardRepository.java | 4 ++-- .../{CardErrorCoed.java => CardErrorCode.java} | 2 +- .../trello/common/exception/CardException.java | 2 +- 4 files changed, 7 insertions(+), 19 deletions(-) rename src/main/java/com/example/trello/common/exception/{CardErrorCoed.java => CardErrorCode.java} (95%) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 68e88ce..9a0154e 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -2,9 +2,7 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectMetadata; -import com.amazonaws.services.s3.model.S3Object; import com.example.trello.card.cardrepository.CardRepository; -import com.example.trello.card.cardrepository.CardRepositoryCustomImpl; import com.example.trello.card.responsedto.CardPageResponseDto; import com.example.trello.card.requestDto.CardRequestDto; import com.example.trello.card.responsedto.CardResponseDto; @@ -12,15 +10,13 @@ import com.example.trello.card.responsedto.UpdateCardResponseDto; import com.example.trello.cardlist.CardList; import com.example.trello.cardlist.CardListRepository; -import com.example.trello.common.exception.CardErrorCoed; +import com.example.trello.common.exception.CardErrorCode; import com.example.trello.common.exception.CardException; import com.example.trello.common.exception.WorkspaceMemberErrorCode; import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; import com.example.trello.notification.NotificationService; -import com.example.trello.util.FileUploadUtil; import com.example.trello.workspace.WorkSpaceRepository; -import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberService; @@ -29,21 +25,16 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; import static com.example.trello.notification.NotificationType.UPDATE_CARD; import static com.example.trello.util.FileUploadUtil.isAllowedExtension; -import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @RequiredArgsConstructor @@ -185,7 +176,7 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe // 파일 형식 예외처리 if (!isAllowedExtension(file.getOriginalFilename())) { - throw new CardException(CardErrorCoed.FORMAT_NOT_SUPPORTED); + throw new CardException(CardErrorCode.FORMAT_NOT_SUPPORTED); } @@ -193,7 +184,7 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe long maxSize = 5 * 1024 * 1024; if (file.getSize() > maxSize) { - throw new CardException(CardErrorCoed.FILE_SIZE_EXCEEDED); + throw new CardException(CardErrorCode.FILE_SIZE_EXCEEDED); } String fileName = file.getOriginalFilename(); @@ -245,9 +236,6 @@ public String getFile(Long cardId, UserDetailsImpl userDetails) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); try { return amazonS3Client.getUrl(bucketName, card.getFileName()).toString(); diff --git a/src/main/java/com/example/trello/card/cardrepository/CardRepository.java b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java index dd56eb3..55c0181 100644 --- a/src/main/java/com/example/trello/card/cardrepository/CardRepository.java +++ b/src/main/java/com/example/trello/card/cardrepository/CardRepository.java @@ -2,7 +2,7 @@ import com.example.trello.card.Card; import com.example.trello.cardlist.CardList; -import com.example.trello.common.exception.CardErrorCoed; +import com.example.trello.common.exception.CardErrorCode; import com.example.trello.common.exception.CardException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -15,6 +15,6 @@ public interface CardRepository extends JpaRepository, CardRepositor List findByCardList(CardList cardList); default Card findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new CardException(CardErrorCoed.CARD_NOT_FOUND)); + return findById(id).orElseThrow(()->new CardException(CardErrorCode.CARD_NOT_FOUND)); } } diff --git a/src/main/java/com/example/trello/common/exception/CardErrorCoed.java b/src/main/java/com/example/trello/common/exception/CardErrorCode.java similarity index 95% rename from src/main/java/com/example/trello/common/exception/CardErrorCoed.java rename to src/main/java/com/example/trello/common/exception/CardErrorCode.java index 626b6a8..397b9d3 100644 --- a/src/main/java/com/example/trello/common/exception/CardErrorCoed.java +++ b/src/main/java/com/example/trello/common/exception/CardErrorCode.java @@ -6,7 +6,7 @@ @RequiredArgsConstructor @Getter -public enum CardErrorCoed { +public enum CardErrorCode { CARD_NOT_FOUND("카드를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), FORMAT_NOT_SUPPORTED("지원하지 않는 형식입니다", HttpStatus.BAD_REQUEST), diff --git a/src/main/java/com/example/trello/common/exception/CardException.java b/src/main/java/com/example/trello/common/exception/CardException.java index fbb32f7..5e9fa55 100644 --- a/src/main/java/com/example/trello/common/exception/CardException.java +++ b/src/main/java/com/example/trello/common/exception/CardException.java @@ -6,5 +6,5 @@ @AllArgsConstructor @Getter public class CardException extends RuntimeException { - private CardErrorCoed errorCoed; + private CardErrorCode errorCoed; } From 14c3b9b708d6f070a8885519015d828413d5f92a Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 13:44:30 +0900 Subject: [PATCH 120/181] =?UTF-8?q?feat=20:=20=EC=9B=8C=ED=81=AC=EC=8A=A4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=EC=97=90=20slackUrl=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/workspace/Workspace.java | 9 +++++++-- .../com/example/trello/workspace/WorkspaceService.java | 3 ++- .../trello/workspace/dto/UpdateWorkspaceRequestDto.java | 5 ++++- .../trello/workspace/dto/WorkspaceRequestDto.java | 5 ++++- .../trello/workspace/dto/WorkspaceResponseDto.java | 6 ++++-- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/workspace/Workspace.java b/src/main/java/com/example/trello/workspace/Workspace.java index a97ebf9..257d8e7 100644 --- a/src/main/java/com/example/trello/workspace/Workspace.java +++ b/src/main/java/com/example/trello/workspace/Workspace.java @@ -23,6 +23,9 @@ public class Workspace { @Column(name = "description", nullable = false) private String description; + @Column(name = "slack_url") + private String slackUrl; + @OneToMany(mappedBy = "workspace", cascade = CascadeType.ALL, orphanRemoval = true) private List boards; @@ -36,14 +39,16 @@ public Workspace() { } @Builder - public Workspace(String title, String description, User user) { + public Workspace(String title, String description, String slackUrl, User user) { this.title = title; this.description = description; + this.slackUrl = slackUrl; this.user = user; } - public void updateWorkspace(String title, String description) { + public void updateWorkspace(String title, String description, String slackUrl) { this.title = title; this.description = description; + this.slackUrl = slackUrl; } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceService.java b/src/main/java/com/example/trello/workspace/WorkspaceService.java index 9dfbca3..d4fa716 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceService.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceService.java @@ -40,6 +40,7 @@ public WorkspaceResponseDto createWorkspace(WorkspaceRequestDto dto, Long loginU Workspace workspace = Workspace.builder() .title(dto.getTitle()) .description(dto.getDescription()) + .slackUrl(dto.getSlackUrl()) .user(loginUser) .build(); @@ -89,7 +90,7 @@ public WorkspaceResponseDto updateWorkspace(Long workspaceId, UpdateWorkspaceReq Workspace workspace = findWorkspaceMember.getWorkspace(); - workspace.updateWorkspace(dto.getTitle(), dto.getDescription()); + workspace.updateWorkspace(dto.getTitle(), dto.getDescription(), dto.getSlackUrl()); return WorkspaceResponseDto.toDto(workspace); } diff --git a/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java b/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java index d327139..8352c97 100644 --- a/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java +++ b/src/main/java/com/example/trello/workspace/dto/UpdateWorkspaceRequestDto.java @@ -14,8 +14,11 @@ public class UpdateWorkspaceRequestDto { @Size(min = 1, max = 255, message = "title 크기는 1에서 255사이여야합니다.") private String description; - public UpdateWorkspaceRequestDto(String title, String description) { + private String slackUrl; + + public UpdateWorkspaceRequestDto(String title, String description, String slackUrl) { this.title = title; this.description = description; + this.slackUrl = slackUrl; } } diff --git a/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java b/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java index 05d4139..d6f89c8 100644 --- a/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java +++ b/src/main/java/com/example/trello/workspace/dto/WorkspaceRequestDto.java @@ -14,8 +14,11 @@ public class WorkspaceRequestDto { @Size(min = 1, max = 255, message = "title 크기는 1에서 255사이여야합니다.") private String description; - public WorkspaceRequestDto(String title, String description) { + private String slackUrl; + + public WorkspaceRequestDto(String title, String description, String slackUrl) { this.title = title; this.description = description; + this.slackUrl = slackUrl; } } diff --git a/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java b/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java index a0f373b..dbeef98 100644 --- a/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java +++ b/src/main/java/com/example/trello/workspace/dto/WorkspaceResponseDto.java @@ -8,14 +8,16 @@ public class WorkspaceResponseDto { private Long workspaceId; private String title; private String description; + private String slackUrl; - public WorkspaceResponseDto(Long workspaceId, String title, String description) { + public WorkspaceResponseDto(Long workspaceId, String title, String description, String slackUrl) { this.workspaceId = workspaceId; this.title = title; this.description = description; + this.slackUrl = slackUrl; } public static WorkspaceResponseDto toDto(Workspace workspace) { - return new WorkspaceResponseDto(workspace.getId(), workspace.getTitle(), workspace.getDescription()); + return new WorkspaceResponseDto(workspace.getId(), workspace.getTitle(), workspace.getDescription(), workspace.getSlackUrl()); } } From 8427e6cbd60a7a5d1ba42f1254c8a822f4c6ab13 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 14:02:48 +0900 Subject: [PATCH 121/181] =?UTF-8?q?Fix=20:=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/trello/card/CardService.java | 18 +++++++--------- .../trello/comment/CommentService.java | 21 +++++-------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 9a0154e..31a01ff 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -162,16 +162,14 @@ public CardPageResponseDto searchCards(int page , Long cardListId, LocalDate sta @Transactional public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDetails) { - WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); - Card card = cardRepository.findByIdOrElseThrow(cardId); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); + + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(userDetails.getUser().getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); // 파일 형식 예외처리 @@ -207,14 +205,12 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe public void deleteFile(Long cardId, String fileName, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); - WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(userDetails.getUser().getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); if (!card.getFileName().equals(fileName)) { @@ -230,9 +226,9 @@ public String getFile(Long cardId, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); - WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(userDetails.getUser().getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 81c50e6..a6fe8d7 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -42,17 +42,14 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail Card card = cardRepository.findByIdOrElseThrow(requestDto.getCardId()); - Long workspaceId = card.getCardList().getBoard().getWorkspace().getId(); + Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); + WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workSpaceId); if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - - Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); Comment comment = Comment.builder() @@ -64,7 +61,7 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail commentRepository.save(comment); - Workspace workSpace = workSpaceRepository.findByIdOrElseThrow(workspaceId); + Workspace workSpace = workSpaceRepository.findByIdOrElseThrow(workSpaceId); notificationService.sendSlack(CREATE_COMMENT, workSpace); return CommentResponseDto.toDto(comment); @@ -77,10 +74,7 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto Long workSpaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); - WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workSpaceId); - - - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), workSpaceId)) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workSpaceId, workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } @@ -103,17 +97,12 @@ public void deleteComment(Long commentId, UserDetailsImpl userDetails) { Comment comment = commentRepository.findByIdOrElseThrow(commentId); - Long workspaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); - - WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workspaceId); - Long workSpaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), workSpaceId)) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workSpaceId, workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { From eac32d23fd5123d98b9dd1074e2125cec1090ca2 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 14:22:17 +0900 Subject: [PATCH 122/181] =?UTF-8?q?Fix=20:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/common/exception/CardException.java | 2 +- .../exception/{CommentErrorCoed.java => CommentErrorCode.java} | 2 +- .../com/example/trello/common/exception/CommentException.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/com/example/trello/common/exception/{CommentErrorCoed.java => CommentErrorCode.java} (92%) diff --git a/src/main/java/com/example/trello/common/exception/CardException.java b/src/main/java/com/example/trello/common/exception/CardException.java index 5e9fa55..ad3c672 100644 --- a/src/main/java/com/example/trello/common/exception/CardException.java +++ b/src/main/java/com/example/trello/common/exception/CardException.java @@ -6,5 +6,5 @@ @AllArgsConstructor @Getter public class CardException extends RuntimeException { - private CardErrorCode errorCoed; + private CardErrorCode cardErrorCode; } diff --git a/src/main/java/com/example/trello/common/exception/CommentErrorCoed.java b/src/main/java/com/example/trello/common/exception/CommentErrorCode.java similarity index 92% rename from src/main/java/com/example/trello/common/exception/CommentErrorCoed.java rename to src/main/java/com/example/trello/common/exception/CommentErrorCode.java index 6971c31..c6199e4 100644 --- a/src/main/java/com/example/trello/common/exception/CommentErrorCoed.java +++ b/src/main/java/com/example/trello/common/exception/CommentErrorCode.java @@ -6,7 +6,7 @@ @RequiredArgsConstructor @Getter -public enum CommentErrorCoed { +public enum CommentErrorCode { CANNOT_BE_MODIFIED("댓글 수정은 작성자만 가능합니다", HttpStatus.FORBIDDEN); diff --git a/src/main/java/com/example/trello/common/exception/CommentException.java b/src/main/java/com/example/trello/common/exception/CommentException.java index 9827efb..61cd551 100644 --- a/src/main/java/com/example/trello/common/exception/CommentException.java +++ b/src/main/java/com/example/trello/common/exception/CommentException.java @@ -6,5 +6,5 @@ @AllArgsConstructor @Getter public class CommentException extends RuntimeException { - private CommentErrorCoed commentErrorCoed; + private CommentErrorCode commentErrorCode; } From 79c495530b6051c9d5fa2138ba5c99d6a2881617 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Mon, 30 Dec 2024 14:24:11 +0900 Subject: [PATCH 123/181] =?UTF-8?q?Fix=20:=20=EA=B0=99=EC=9D=80=20?= =?UTF-8?q?=EC=97=AD=ED=95=A0=EC=9D=84=20=ED=95=98=EB=8A=94=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trello/comment/CommentService.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index a6fe8d7..4a19874 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -5,27 +5,22 @@ import com.example.trello.comment.dto.request.CommentRequestDto; import com.example.trello.comment.dto.request.UpdateCommentRequestDto; import com.example.trello.comment.dto.response.CommentResponseDto; -import com.example.trello.common.exception.CommentErrorCoed; +import com.example.trello.common.exception.CommentErrorCode; import com.example.trello.common.exception.CommentException; import com.example.trello.common.exception.WorkspaceMemberErrorCode; import com.example.trello.common.exception.WorkspaceMemberException; import com.example.trello.config.auth.UserDetailsImpl; -import com.example.trello.notification.Notification; import com.example.trello.notification.NotificationService; -import com.example.trello.user.User; import com.example.trello.workspace.WorkSpaceRepository; import com.example.trello.workspace.Workspace; import com.example.trello.workspace_member.WorkspaceMember; import com.example.trello.workspace_member.WorkspaceMemberRepository; import com.example.trello.workspace_member.WorkspaceMemberService; -import jakarta.servlet.http.HttpServletRequest; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.PostMapping; import static com.example.trello.notification.NotificationType.CREATE_COMMENT; -import static com.example.trello.workspace_member.WorkspaceMemberRole.WORKSPACE; @Service @RequiredArgsConstructor @@ -46,10 +41,6 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workSpaceId); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { - throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); - } - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); Comment comment = Comment.builder() @@ -74,14 +65,14 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto Long workSpaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workSpaceId, workSpaceId)) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(userDetails.getUser().getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { - throw new CommentException(CommentErrorCoed.CANNOT_BE_MODIFIED); + throw new CommentException(CommentErrorCode.CANNOT_BE_MODIFIED); } comment.updateComment(requestDto.getContent()); @@ -99,14 +90,14 @@ public void deleteComment(Long commentId, UserDetailsImpl userDetails) { Long workSpaceId = comment.getCard().getCardList().getBoard().getWorkspace().getId(); - if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workSpaceId, workSpaceId)) { + if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(userDetails.getUser().getId(), workSpaceId)) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { - throw new CommentException(CommentErrorCoed.CANNOT_BE_MODIFIED); + throw new CommentException(CommentErrorCode.CANNOT_BE_MODIFIED); } commentRepository.delete(comment); From 999bbba7d200988c6b06c0107d3684558ebd32d0 Mon Sep 17 00:00:00 2001 From: 2unmi <2unmin4030@gmail.com> Date: Mon, 30 Dec 2024 14:39:26 +0900 Subject: [PATCH 124/181] =?UTF-8?q?fix=20:=20=EC=8A=AC=EB=9E=99=20?= =?UTF-8?q?=EC=95=8C=EB=9E=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/trello/board/BoardService.java | 6 +++--- .../com/example/trello/card/CardService.java | 10 +++++----- .../trello/cardlist/CardListController.java | 18 ++++++++++-------- .../trello/cardlist/CardListService.java | 19 ++++++++++++++----- .../trello/comment/CommentService.java | 6 +++--- .../notification/NotificationService.java | 5 +---- .../WorkspaceMemberService.java | 2 +- 7 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 0bd297d..44b9f30 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -41,7 +41,7 @@ public class BoardService { @Transactional public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { - workspaceMemberService.CheckReadRole(loginUserId, dto.getWorkspaceId()); + workspaceMemberService.checkReadRole(loginUserId, dto.getWorkspaceId()); isValidBoardImage(dto.getFile()); String imageUrl = null; @@ -100,7 +100,7 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { @Transactional public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); - workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); + workspaceMemberService.checkReadRole(loginUserId, findBoard.getWorkspace().getId()); deleteFile(findBoard.getImage()); String imageUrl = null; @@ -116,7 +116,7 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon @Transactional public void deleteBoard(Long boardId, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); - workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); + workspaceMemberService.checkReadRole(loginUserId, findBoard.getWorkspace().getId()); deleteFile(findBoard.getImage()); boardRepository.delete(findBoard); diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index 31a01ff..af8a216 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -71,7 +71,7 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, UserDetails Long workSpaceId = cardList.getBoard().getWorkspace().getId(); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); Card card = Card.builder() .title(requestDto.getTitle()) @@ -102,7 +102,7 @@ public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto reque } Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); card.updateCard(responseDto); @@ -128,7 +128,7 @@ public void deleteCardService(Long cardId, UserDetailsImpl userDetails) { Long workSpaceId = card.getCardList().getBoard().getWorkspace().getId(); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); cardRepository.delete(card); } @@ -170,7 +170,7 @@ public String uploadFile(Long cardId, MultipartFile file, UserDetailsImpl userDe throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); // 파일 형식 예외처리 if (!isAllowedExtension(file.getOriginalFilename())) { @@ -211,7 +211,7 @@ public void deleteFile(Long cardId, String fileName, UserDetailsImpl userDetails throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); if (!card.getFileName().equals(fileName)) { throw new RuntimeException(); diff --git a/src/main/java/com/example/trello/cardlist/CardListController.java b/src/main/java/com/example/trello/cardlist/CardListController.java index 449a4e5..b8758b6 100644 --- a/src/main/java/com/example/trello/cardlist/CardListController.java +++ b/src/main/java/com/example/trello/cardlist/CardListController.java @@ -3,9 +3,11 @@ import com.example.trello.cardlist.dto.CardListResponseDto; import com.example.trello.cardlist.dto.CreateCardListRequestDto; import com.example.trello.cardlist.dto.UpdateCardListRequestDto; +import com.example.trello.config.auth.UserDetailsImpl; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; @RestController @@ -16,8 +18,8 @@ public class CardListController { private final CardListService cardListService; @PostMapping - public ResponseEntity createCardList(@RequestBody CreateCardListRequestDto requestDto) { - CardListResponseDto cardListResponseDto = cardListService.create(requestDto); + public ResponseEntity createCardList(@RequestBody CreateCardListRequestDto requestDto,@AuthenticationPrincipal UserDetailsImpl userDetails) { + CardListResponseDto cardListResponseDto = cardListService.create(requestDto,userDetails.getUser()); return new ResponseEntity<>(cardListResponseDto, HttpStatus.CREATED); } @@ -28,22 +30,22 @@ public ResponseEntity findCardList(@PathVariable Long id) { } @PatchMapping("/{id}") - public ResponseEntity updateCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto) { - CardListResponseDto cardListResponseDto = cardListService.moveSequence(id, requestDto); + public ResponseEntity updateCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto,@AuthenticationPrincipal UserDetailsImpl userDetails) { + CardListResponseDto cardListResponseDto = cardListService.moveSequence(id, requestDto,userDetails.getUser()); return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); } @PatchMapping("/{id}/exchange") - public ResponseEntity swapCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto) { - CardListResponseDto cardListResponseDto = cardListService.swapSequence(id, requestDto); + public ResponseEntity swapCardList(@PathVariable Long id, @RequestBody UpdateCardListRequestDto requestDto,@AuthenticationPrincipal UserDetailsImpl userDetails) { + CardListResponseDto cardListResponseDto = cardListService.swapSequence(id, requestDto,userDetails.getUser()); return new ResponseEntity<>(cardListResponseDto, HttpStatus.OK); } @DeleteMapping("/{id}") - public ResponseEntity deleteCardList(@PathVariable Long id) { - cardListService.delete(id); + public ResponseEntity deleteCardList(@PathVariable Long id,@AuthenticationPrincipal UserDetailsImpl userDetails) { + cardListService.delete(id,userDetails.getUser()); return new ResponseEntity<>(HttpStatus.OK); } diff --git a/src/main/java/com/example/trello/cardlist/CardListService.java b/src/main/java/com/example/trello/cardlist/CardListService.java index 9f79952..7157b0e 100644 --- a/src/main/java/com/example/trello/cardlist/CardListService.java +++ b/src/main/java/com/example/trello/cardlist/CardListService.java @@ -6,6 +6,8 @@ import com.example.trello.cardlist.dto.CreateCardListRequestDto; import com.example.trello.cardlist.dto.UpdateCardListRequestDto; import com.example.trello.common.exception.CardListException; +import com.example.trello.user.User; +import com.example.trello.workspace_member.WorkspaceMemberService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,12 +22,14 @@ public class CardListService { private final CardListRepository cardListRepository; private final BoardRepository boardRepository; + private final WorkspaceMemberService workspaceMemberService; private Integer maxSequence; // 보드에서 가장 큰 순서 @Transactional - public CardListResponseDto create(CreateCardListRequestDto requestDto) { + public CardListResponseDto create(CreateCardListRequestDto requestDto, User user) { Board board = boardRepository.findByIdOrElseThrow(requestDto.getBoardId()); + workspaceMemberService.checkReadRole(user.getId(), board.getWorkspace().getId()); maxSequence = cardListRepository.findByMax(board.getId()).orElse(0); CardList cardList = requestDto.toEntity(requestDto, board, ++maxSequence); CardList savedCardList = cardListRepository.save(cardList); @@ -40,8 +44,10 @@ public CardListResponseDto findCardList(Long id) { } @Transactional - public CardListResponseDto moveSequence(Long id, UpdateCardListRequestDto requestDto) { + public CardListResponseDto moveSequence(Long id, UpdateCardListRequestDto requestDto, User user) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); + Board board = cardList.getBoard(); + workspaceMemberService.checkReadRole(user.getId(), board.getWorkspace().getId()); Integer currentSequence = cardList.getSequence(); List cardLists = cardListRepository.findAllByBoardId(cardList.getBoard().getId()); @@ -68,8 +74,10 @@ public CardListResponseDto moveSequence(Long id, UpdateCardListRequestDto reques } @Transactional - public CardListResponseDto swapSequence(Long id, UpdateCardListRequestDto requestDto) { + public CardListResponseDto swapSequence(Long id, UpdateCardListRequestDto requestDto, User user) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); + Board board = cardList.getBoard(); + workspaceMemberService.checkReadRole(user.getId(), board.getWorkspace().getId()); CardList exchangeCardList = cardListRepository.findBySequenceAndBoardIdOrElseThrow(requestDto.getSequence(), cardList.getBoard().getId()); Integer temp = cardList.getSequence(); cardList.update(requestDto, exchangeCardList.getSequence()); @@ -80,10 +88,11 @@ public CardListResponseDto swapSequence(Long id, UpdateCardListRequestDto reques @Transactional - public void delete(Long id) { + public void delete(Long id, User user) { CardList cardList = cardListRepository.findByIdOrElseThrow(id); - Board board = boardRepository.findByIdOrElseThrow(cardList.getBoard().getId()); + Board board = cardList.getBoard(); + workspaceMemberService.checkReadRole(user.getId(), board.getWorkspace().getId()); Integer deleteSequence = cardList.getSequence(); cardListRepository.delete(cardList); List cardLists = cardListRepository.findAllByBoardId(board.getId()); diff --git a/src/main/java/com/example/trello/comment/CommentService.java b/src/main/java/com/example/trello/comment/CommentService.java index 4a19874..d1c048f 100644 --- a/src/main/java/com/example/trello/comment/CommentService.java +++ b/src/main/java/com/example/trello/comment/CommentService.java @@ -41,7 +41,7 @@ public CommentResponseDto createComment(CommentRequestDto requestDto, UserDetail WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userDetails.getUser().getId(), workSpaceId); - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); Comment comment = Comment.builder() .content(requestDto.getContent()) @@ -69,7 +69,7 @@ public CommentResponseDto updateComment(Long commentId, UpdateCommentRequestDto throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { throw new CommentException(CommentErrorCode.CANNOT_BE_MODIFIED); @@ -94,7 +94,7 @@ public void deleteComment(Long commentId, UserDetailsImpl userDetails) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); } - workspaceMemberService.CheckReadRole(userDetails.getUser().getId(), workSpaceId); + workspaceMemberService.checkReadRole(userDetails.getUser().getId(), workSpaceId); if (!userDetails.getUser().getId().equals(comment.getWorkspaceMember().getUser().getId())) { throw new CommentException(CommentErrorCode.CANNOT_BE_MODIFIED); diff --git a/src/main/java/com/example/trello/notification/NotificationService.java b/src/main/java/com/example/trello/notification/NotificationService.java index ccf0a4d..d25eeb7 100644 --- a/src/main/java/com/example/trello/notification/NotificationService.java +++ b/src/main/java/com/example/trello/notification/NotificationService.java @@ -16,15 +16,12 @@ public class NotificationService { private final NotificationRepository notificationRepository; - @Value("${SLACK_URL}") - private String slackUrl; - @Transactional public void sendSlack(NotificationType notificationType ,Workspace workspace) { Slack slack =Slack.getInstance(); String message = NotificationType.createMessage(notificationType); try { - slack.send(slackUrl,message); + slack.send(workspace.getSlackUrl(), message); Notification notification = Notification.builder() .content(notificationType.getMessage()) .notificationType(notificationType) diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java index 3c01f7b..e664846 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberService.java @@ -78,7 +78,7 @@ public void updateWorkspaceMemberRole(Long workspaceId, UpdateWorkspaceMemberRol log.info("{}의 역할이 {}로 변경되었습니다.", roleUpdatedWorkspaceMember.getUser().getNickname(), dto.getRole()); } - public void CheckReadRole(Long userId,Long workspaceId) { + public void checkReadRole(Long userId, Long workspaceId) { WorkspaceMember workspaceMember = workspaceMemberRepository.findByUserIdAndWorkspaceIdOrElseThrow(userId, workspaceId); if(workspaceMember.getRole()==READ_ONLY) { throw new WorkspaceMemberException(CAN_NOT_READ_ROLE); From a46f4c304a83063dc35075218bc4086a439b7119 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 14:56:17 +0900 Subject: [PATCH 125/181] =?UTF-8?q?refactor=20:=20=EB=B3=B4=EB=93=9C,=20?= =?UTF-8?q?=EC=9B=8C=ED=81=AC=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=20Contro?= =?UTF-8?q?ller=20=EC=9D=98=20=EB=B0=98=ED=99=98=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit String -> ResponseEntity 으로 반환타입 통일 --- src/main/java/com/example/trello/board/BoardController.java | 4 ++-- .../com/example/trello/workspace/WorkspaceController.java | 4 ++-- .../trello/workspace_member/WorkspaceMemberController.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index f31d131..003f940 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -45,8 +45,8 @@ public ResponseEntity updateBoard(@PathVariable Long boardId, } @DeleteMapping("/{boardId}") - public String deleteBoard(@PathVariable Long boardId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity deleteBoard(@PathVariable Long boardId, @AuthenticationPrincipal UserDetailsImpl userDetails) { boardService.deleteBoard(boardId, userDetails.getUser().getId()); - return "보드가 정상적으로 삭제되었습니다."; + return new ResponseEntity<>("보드가 정상적으로 삭제되었습니다.", HttpStatus.OK); } } diff --git a/src/main/java/com/example/trello/workspace/WorkspaceController.java b/src/main/java/com/example/trello/workspace/WorkspaceController.java index 791a8af..6af578f 100644 --- a/src/main/java/com/example/trello/workspace/WorkspaceController.java +++ b/src/main/java/com/example/trello/workspace/WorkspaceController.java @@ -45,8 +45,8 @@ public ResponseEntity updateWorkspace(@PathVariable Long w } @DeleteMapping("/{workspaceId}") - public String deleteWorkspace(@PathVariable Long workspaceId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity deleteWorkspace(@PathVariable Long workspaceId, @AuthenticationPrincipal UserDetailsImpl userDetails) { workspaceService.deleteWorkspace(workspaceId, userDetails.getUser().getId()); - return "워크스페이스가 정상적으로 삭제되었습니다."; + return new ResponseEntity<>("워크스페이스가 정상적으로 삭제되었습니다.", HttpStatus.OK); } } diff --git a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java index b3a19dc..a8583e6 100644 --- a/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java +++ b/src/main/java/com/example/trello/workspace_member/WorkspaceMemberController.java @@ -25,8 +25,8 @@ public ResponseEntity inviteWorkspaceUser(@PathVaria } @PatchMapping("/member-role") - public String updateWorkspaceUserRole(@PathVariable Long workspaceId, @Valid @RequestBody UpdateWorkspaceMemberRoleDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public ResponseEntity updateWorkspaceUserRole(@PathVariable Long workspaceId, @Valid @RequestBody UpdateWorkspaceMemberRoleDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { workspaceMemberService.updateWorkspaceMemberRole(workspaceId, dto, userDetails.getUser().getId()); - return "권한이 " + dto.getRole() + "로 변경되었습니다."; + return new ResponseEntity<>("권한이 " + dto.getRole() + "로 변경되었습니다.", HttpStatus.OK); } } From 9c351e9faf87b0ad50e42b4a59187fee011d15a0 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 14:57:15 +0900 Subject: [PATCH 126/181] =?UTF-8?q?fix=20:=20=EC=97=85=EB=A1=9C=EB=93=9C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=9D=B4=20null=20=EC=9D=BC=EB=95=8C=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=EA=B0=80=20=EB=B0=9C=EC=83=9D=ED=95=98=EB=8D=98=20?= =?UTF-8?q?=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if 문으로 file 이 null 인지 체크후 null 이 아닐때만 확장자 검사를 하도록 수정 --- src/main/java/com/example/trello/board/BoardService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 0bd297d..221d965 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -42,7 +42,10 @@ public class BoardService { @Transactional public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { workspaceMemberService.CheckReadRole(loginUserId, dto.getWorkspaceId()); - isValidBoardImage(dto.getFile()); + + if (dto.getFile() != null) { + isValidBoardImage(dto.getFile()); + } String imageUrl = null; if(dto.getFile() != null && !dto.getFile().isEmpty()) { From 7f73949ca33490ade5472a412eb74035819a9ea2 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 15:00:42 +0900 Subject: [PATCH 127/181] =?UTF-8?q?fix=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=EC=8B=9C=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=9D=98=20=ED=99=95=EC=9E=A5=EC=9E=90=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=EB=A5=BC=20=EC=8B=A4=EC=8B=9C=20=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 221d965..7a7e729 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -106,6 +106,10 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); deleteFile(findBoard.getImage()); + if (dto.getFile() != null) { + isValidBoardImage(dto.getFile()); + } + String imageUrl = null; if(dto.getFile() != null && !dto.getFile().isEmpty()) { imageUrl = uploadFileToS3(dto.getFile()); From d0f4bfc830d5f9c42e44aa43b1e8e27522979e7b Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 16:32:20 +0900 Subject: [PATCH 128/181] =?UTF-8?q?fix=20:=20BoardService=20=EC=97=90=20ch?= =?UTF-8?q?eckReadRole=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=EC=9D=B4=20?= =?UTF-8?q?=EC=9E=98=EB=AA=BB=EC=8D=A8=EC=A0=B8=EC=9E=88=EB=8D=98=EA=B2=83?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/board/BoardController.java | 4 ++-- .../java/com/example/trello/board/BoardService.java | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardController.java b/src/main/java/com/example/trello/board/BoardController.java index 003f940..2fd88dd 100644 --- a/src/main/java/com/example/trello/board/BoardController.java +++ b/src/main/java/com/example/trello/board/BoardController.java @@ -17,9 +17,9 @@ public class BoardController { private final BoardService boardService; - @PostMapping // 추가 + @PostMapping public ResponseEntity createBoard( - @Valid @ModelAttribute BoardRequestDto dto, // 수정 + @Valid @ModelAttribute BoardRequestDto dto, @AuthenticationPrincipal UserDetailsImpl userDetails) { BoardResponseDto boardResponseDto = boardService.createBoard(dto, userDetails.getUser().getId()); diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 146ea29..0c230a4 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -42,12 +42,10 @@ public class BoardService { @Transactional public BoardResponseDto createBoard(BoardRequestDto dto, Long loginUserId) { workspaceMemberService.checkReadRole(loginUserId, dto.getWorkspaceId()); - if (dto.getFile() != null) { - isValidBoardImage(dto.getFile()); - } String imageUrl = null; - if(dto.getFile() != null && !dto.getFile().isEmpty()) { + if (dto.getFile() != null && !dto.getFile().isEmpty()) { + isValidBoardImage(dto.getFile()); imageUrl = uploadFileToS3(dto.getFile()); } @@ -102,7 +100,7 @@ public BoardDetailResponseDto viewBoard(Long boardId, Long loginUserId) { @Transactional public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); - workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); + workspaceMemberService.checkReadRole(loginUserId, findBoard.getWorkspace().getId()); deleteFile(findBoard.getImage()); String imageUrl = null; @@ -118,7 +116,7 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon @Transactional public void deleteBoard(Long boardId, Long loginUserId) { Board findBoard = boardRepository.findByIdOrElseThrow(boardId); - workspaceMemberService.CheckReadRole(loginUserId, findBoard.getWorkspace().getId()); + workspaceMemberService.checkReadRole(loginUserId, findBoard.getWorkspace().getId()); deleteFile(findBoard.getImage()); boardRepository.delete(findBoard); From a5b8ae11503df20428892310a4879398c6ea4488 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 16:34:02 +0900 Subject: [PATCH 129/181] =?UTF-8?q?feat=20:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=EC=8B=9C=20=EC=B5=9C=EB=8C=80?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=A6=88(5MB)=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b419c31..697e26a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -9,8 +9,11 @@ spring.jpa.hibernate.ddl-auto=create spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect +spring.servlet.multipart.enabled=true +spring.servlet.multipart.max-file-size=5MB +spring.servlet.multipart.max-request-size=5MB + jwt.secret="036c4fe3ec667532545b9e8fa7e2a98a22f439dff102623c097715060e2da68c" jwt.expiry-millis=3600000 \ No newline at end of file From 22622ad265c692b3452c83ac475dfac522949d46 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 16:36:52 +0900 Subject: [PATCH 130/181] =?UTF-8?q?fix=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=EC=8B=9C=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=9D=98=20=ED=99=95=EC=9E=A5=EC=9E=90=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=EB=A5=BC=20=EC=8B=A4=EC=8B=9C=20=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 0c230a4..0612a25 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -104,7 +104,8 @@ public BoardResponseDto updateBoard(Long boardId, UpdateBoardRequestDto dto, Lon deleteFile(findBoard.getImage()); String imageUrl = null; - if(dto.getFile() != null && !dto.getFile().isEmpty()) { + if (dto.getFile() != null && !dto.getFile().isEmpty()) { + isValidBoardImage(dto.getFile()); imageUrl = uploadFileToS3(dto.getFile()); } From 13a0c291bbc56abee29b811c729ded25e9d927f0 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 16:46:35 +0900 Subject: [PATCH 131/181] =?UTF-8?q?refactor=20:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C?= =?UTF-8?q?=EC=99=80=20=EC=B9=B4=EB=93=9C=20=EC=B2=A8=EB=B6=80=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=97=85=EB=A1=9C=EB=93=9C=EC=8B=9C=20DB=EC=97=90?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=EB=90=98=EB=8A=94=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index 0612a25..bcbdf99 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -126,12 +126,11 @@ public void deleteBoard(Long boardId, Long loginUserId) { private String uploadFileToS3(MultipartFile file) { try { String fileName = file.getOriginalFilename(); - String fileUrl = "https://" + bucket + "/test" + fileName; ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(file.getContentType()); metadata.setContentLength(file.getSize()); amazonS3Client.putObject(bucket, fileName, file.getInputStream(), metadata); - return fileUrl; + return fileName; } catch (IOException e) { throw new RuntimeException("파일 업로드에 실패했습니다.", e); } From e4be9cb7fc125740e2adc8c9199c07563eda3bb9 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 16:52:39 +0900 Subject: [PATCH 132/181] =?UTF-8?q?refactor=20:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C,=20=EC=82=AD=EC=A0=9C=EC=8B=9C=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EB=A5=BC=20BoardException=20=EC=9C=BC=EB=A1=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 4 ++-- .../com/example/trello/common/exception/BoardErrorCode.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index bcbdf99..e4c181a 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -132,7 +132,7 @@ private String uploadFileToS3(MultipartFile file) { amazonS3Client.putObject(bucket, fileName, file.getInputStream(), metadata); return fileName; } catch (IOException e) { - throw new RuntimeException("파일 업로드에 실패했습니다.", e); + throw new BoardException(BoardErrorCode.FAILED_IMAGE_UPLOAD); } } @@ -141,7 +141,7 @@ public void deleteFile(String image) { String fileName = image.substring(24); amazonS3Client.deleteObject(bucket, fileName); } catch (SdkClientException e) { - throw new RuntimeException("Error deleting file from S3", e); + throw new BoardException(BoardErrorCode.FAILED_IMAGE_DELETE); } } diff --git a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java index cdfca57..dd50ada 100644 --- a/src/main/java/com/example/trello/common/exception/BoardErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/BoardErrorCode.java @@ -10,7 +10,9 @@ @Getter public enum BoardErrorCode { CAN_NOT_FIND_BOARD_WITH_BOARD_ID("보드를 찾을 수 없습니다.", BAD_REQUEST), - IS_NOT_ALLOWED_FILE_EXTENSION("이미지 파일(확장자)만 업로드가 가능합니다.", BAD_REQUEST); + IS_NOT_ALLOWED_FILE_EXTENSION("이미지 파일(확장자)만 업로드가 가능합니다.", BAD_REQUEST), + FAILED_IMAGE_UPLOAD("이미지 업로드에 실패했습니다.", BAD_REQUEST), + FAILED_IMAGE_DELETE("이미지 삭제에 실패했습니다.", BAD_REQUEST); private final String message; private final HttpStatus httpStatus; From 46fbd8f1ebffb7296b79bbbb4710573a553ae86e Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Mon, 30 Dec 2024 16:57:49 +0900 Subject: [PATCH 133/181] =?UTF-8?q?fix=20:=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=EC=8B=9C=20subString=20=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EC=9E=90=EB=A5=B4=EB=8D=98=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/board/BoardService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/board/BoardService.java b/src/main/java/com/example/trello/board/BoardService.java index e4c181a..fb89bd7 100644 --- a/src/main/java/com/example/trello/board/BoardService.java +++ b/src/main/java/com/example/trello/board/BoardService.java @@ -138,8 +138,7 @@ private String uploadFileToS3(MultipartFile file) { public void deleteFile(String image) { try { - String fileName = image.substring(24); - amazonS3Client.deleteObject(bucket, fileName); + amazonS3Client.deleteObject(bucket, image); } catch (SdkClientException e) { throw new BoardException(BoardErrorCode.FAILED_IMAGE_DELETE); } From 8fcb866e319bc973896b899a007c0855bcd38168 Mon Sep 17 00:00:00 2001 From: 2unmini <2unmin4030@gmail.com> Date: Mon, 30 Dec 2024 23:31:11 +0900 Subject: [PATCH 134/181] Create gradle-publish.yml --- .github/workflows/gradle-publish.yml | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/gradle-publish.yml diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml new file mode 100644 index 0000000..3415ee6 --- /dev/null +++ b/.github/workflows/gradle-publish.yml @@ -0,0 +1,42 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created +# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle + +name: Gradle Package + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + + - name: Build with Gradle + run: ./gradlew build + + # The USERNAME and TOKEN need to correspond to the credentials environment variables used in + # the publishing section of your build.gradle + - name: Publish to GitHub Packages + run: ./gradlew publish + env: + USERNAME: ${{ github.actor }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} From 6c6cc42cc7cc97de17622ccc46355806026bc115 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 00:16:10 +0900 Subject: [PATCH 135/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 80 ++++++++++++++++++---------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 3415ee6..b1d28ef 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -7,36 +7,58 @@ name: Gradle Package -on: [push] +on: + push: + branches: [ main ] # 해당 branch에 push 되었을 경우 + # https://github.com/marketplace/actions/build-and-push-docker-images jobs: - build: - + docker-build-and-push: runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' - server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 - - - name: Build with Gradle - run: ./gradlew build - - # The USERNAME and TOKEN need to correspond to the credentials environment variables used in - # the publishing section of your build.gradle - - name: Publish to GitHub Packages - run: ./gradlew publish - env: - USERNAME: ${{ github.actor }} - TOKEN: ${{ secrets.GITHUB_TOKEN }} + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Builds + uses: docker/setup-buildx-action@v3 + - + name: Build and push + uses: docker/build-push-action@v6 + with: + file: ./docker/Dockerfile + push: true + tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + # Ec2 에 배포 + deploy-to-ec2: + needs: docker-build-and-push + runs-on: ubuntu-latest + # https://github.com/marketplace/actions/ssh-remote-commands + steps: + - name: Deploy to EC2 + uses: appleboy/ssh-action@v1.2.0 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_KEY }} + script: | + # 기존 컨테이너 중지 및 제거 + CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") + if [ ! -z "$CONTAINER_ID" ]; then + sudo docker stop $CONTAINER_ID + sudo docker rm $CONTAINER_ID + fi + + # 새 이미지 Pull 및 실행 + sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + sudo docker run -d -p 8080:8080 \ + -e DB_USERNAME=${{secrets.DB_USERNAME}} \ + -e DB_PASSWORD=${{secrets.DB_PASSWORD}} \ + -e DB_URL=${{secrets.DB_URL}} \ + ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From 933a50f484408984a6a49c388b77edd9d5f82119 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 00:18:23 +0900 Subject: [PATCH 136/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index b1d28ef..86b2b47 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -7,9 +7,7 @@ name: Gradle Package -on: - push: - branches: [ main ] # 해당 branch에 push 되었을 경우 +on: [push] # https://github.com/marketplace/actions/build-and-push-docker-images jobs: From 772f2ddd96c8d9c87d0e4e4ec0e50c7b011584b9 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 00:25:55 +0900 Subject: [PATCH 137/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 86b2b47..aafd8b3 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -19,7 +19,7 @@ jobs: uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + password: ${{ vars.DOCKERHUB_TOKEN }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -42,9 +42,9 @@ jobs: - name: Deploy to EC2 uses: appleboy/ssh-action@v1.2.0 with: - host: ${{ secrets.EC2_HOST }} - username: ${{ secrets.EC2_USER }} - key: ${{ secrets.EC2_KEY }} + host: ${{ vars.EC2_HOST }} + username: ${{ vars.EC2_USER }} + key: ${{ vars.EC2_KEY }} script: | # 기존 컨테이너 중지 및 제거 CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") @@ -56,7 +56,7 @@ jobs: # 새 이미지 Pull 및 실행 sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest sudo docker run -d -p 8080:8080 \ - -e DB_USERNAME=${{secrets.DB_USERNAME}} \ - -e DB_PASSWORD=${{secrets.DB_PASSWORD}} \ - -e DB_URL=${{secrets.DB_URL}} \ + -e DB_USERNAME=${{vars.DB_USERNAME}} \ + -e DB_PASSWORD=${{vars.DB_PASSWORD}} \ + -e DB_URL=${{vars.DB_URL}} \ ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From 8790d988d22eb03532539351892a0f156114e472 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 00:42:42 +0900 Subject: [PATCH 138/181] =?UTF-8?q?Feat=20:=20docker=20=EC=85=8B=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 7 +++ .../workflows/docker-multi-stage-build.yml | 57 +++++++++++++++++++ Docker-compose.yml | 38 +++++++++++++ Dockerfile | 7 +++ .../trello/TrelloApplicationTests.java | 13 ----- 5 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 .env create mode 100644 .github/workflows/docker-multi-stage-build.yml create mode 100644 Docker-compose.yml create mode 100644 Dockerfile delete mode 100644 src/test/java/com/example/trello/TrelloApplicationTests.java diff --git a/.env b/.env new file mode 100644 index 0000000..06449ad --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +DB_NAME=${{ secrets.DB_NAME }} +DB_USERNAME=${{ secrets.DB_PASSWORD }} +DB_PASSWORD=${{ secrets.DB_USERNAME }} + +BUCKET_ACCESSKEY=${{ secrets.BUCKET_ACCESSORY }} +BUCKET_SECRETKEY=${{ secrets.BUCKET_SECRETARY }} +BUCKET_NAME=${{ secrets.BUCKET_NAME }} \ No newline at end of file diff --git a/.github/workflows/docker-multi-stage-build.yml b/.github/workflows/docker-multi-stage-build.yml new file mode 100644 index 0000000..275918f --- /dev/null +++ b/.github/workflows/docker-multi-stage-build.yml @@ -0,0 +1,57 @@ +name: docker-multi-stage-build.yml + +on: + push: + branches: [ main ] # 해당 branch에 push 되었을 경우 + + # https://github.com/marketplace/actions/build-and-push-docker-images +jobs: + docker-build-and-push: + runs-on: ubuntu-latest + steps: + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Builds + uses: docker/setup-buildx-action@v3 + - + name: Build and push + uses: docker/build-push-action@v6 + with: + file: ./docker/Dockerfile + push: true + tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + # Ec2 에 배포 + deploy-to-ec2: + needs: docker-build-and-push + runs-on: ubuntu-latest + # https://github.com/marketplace/actions/ssh-remote-commands + steps: + - name: Deploy to EC2 + uses: appleboy/ssh-action@v1.2.0 + with: + host: ${{ vars.EC2_HOST }} + username: ${{ vars.EC2_USER }} + key: ${{ vars.EC2_KEY }} + script: | + # 기존 컨테이너 중지 및 제거 + CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") + if [ ! -z "$CONTAINER_ID" ]; then + sudo docker stop $CONTAINER_ID + sudo docker rm $CONTAINER_ID + fi + + # 새 이미지 Pull 및 실행 + sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + sudo docker run -d -p 8080:8080 \ + -e DB_USERNAME=${{vars.DB_USERNAME}} \ + -e DB_PASSWORD=${{vars.DB_PASSWORD}} \ + -e DB_URL=${{vars.DB_URL}} \ + ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest diff --git a/Docker-compose.yml b/Docker-compose.yml new file mode 100644 index 0000000..279e68d --- /dev/null +++ b/Docker-compose.yml @@ -0,0 +1,38 @@ +version: '3' +services: + app: + image: trello:latest + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:8080" + environment: + BUCKET_ACCESSKEY: ${BUCKET_ACCESSKEY} + BUCKET_SECRETKEY: ${BUCKET_SECRETKEY} + BUCKET_NAME: ${BUCKET_NAME} + SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/trello?serverTimezone=Asia/Seoul&useSSL=false&allowPublicKeyRetrieval=true + SPRING_DATASOURCE_USERNAME: root + SPRING_DATASOURCE_PASSWORD: 1111 + depends_on: + - db + + db: + image: mysql:8.0 + container_name: my-mysql + environment: + MYSQL_ROOT_PASSWORD: 1111 + MYSQL_DATABASE: trello + MYSQL_USER: demo + MYSQL_PASSWORD: demo + ports: + - "3307:3306" + volumes: + - db_data:/var/lib/mysql + command: + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_unicode_ci + - --default-authentication-plugin=mysql_native_password + +volumes: + db_data: \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ee0d4eb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM eclipse-temurin:17-jdk-alpine + +ARG JAR_FILE=build/libs/*.jar + +COPY ${JAR_FILE} app.jar + +ENTRYPOINT ["java", "-jar", "/app.jar"] \ No newline at end of file diff --git a/src/test/java/com/example/trello/TrelloApplicationTests.java b/src/test/java/com/example/trello/TrelloApplicationTests.java deleted file mode 100644 index 6281f09..0000000 --- a/src/test/java/com/example/trello/TrelloApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.trello; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class TrelloApplicationTests { - - @Test - void contextLoads() { - } - -} From 9282c91e2037491a7ac71f515093cb2349dcf931 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 00:48:45 +0900 Subject: [PATCH 139/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index aafd8b3..4b6a94a 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -1,9 +1,3 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created -# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle name: Gradle Package From 60d7843300662604690a69e0a93f910689947b0a Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 00:50:56 +0900 Subject: [PATCH 140/181] Feat : --- .../workflows/docker-multi-stage-build.yml | 57 ------------------- .github/workflows/gradle-publish.yml | 6 -- 2 files changed, 63 deletions(-) delete mode 100644 .github/workflows/docker-multi-stage-build.yml diff --git a/.github/workflows/docker-multi-stage-build.yml b/.github/workflows/docker-multi-stage-build.yml deleted file mode 100644 index 275918f..0000000 --- a/.github/workflows/docker-multi-stage-build.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: docker-multi-stage-build.yml - -on: - push: - branches: [ main ] # 해당 branch에 push 되었을 경우 - - # https://github.com/marketplace/actions/build-and-push-docker-images -jobs: - docker-build-and-push: - runs-on: ubuntu-latest - steps: - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Builds - uses: docker/setup-buildx-action@v3 - - - name: Build and push - uses: docker/build-push-action@v6 - with: - file: ./docker/Dockerfile - push: true - tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest - # Ec2 에 배포 - deploy-to-ec2: - needs: docker-build-and-push - runs-on: ubuntu-latest - # https://github.com/marketplace/actions/ssh-remote-commands - steps: - - name: Deploy to EC2 - uses: appleboy/ssh-action@v1.2.0 - with: - host: ${{ vars.EC2_HOST }} - username: ${{ vars.EC2_USER }} - key: ${{ vars.EC2_KEY }} - script: | - # 기존 컨테이너 중지 및 제거 - CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") - if [ ! -z "$CONTAINER_ID" ]; then - sudo docker stop $CONTAINER_ID - sudo docker rm $CONTAINER_ID - fi - - # 새 이미지 Pull 및 실행 - sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest - sudo docker run -d -p 8080:8080 \ - -e DB_USERNAME=${{vars.DB_USERNAME}} \ - -e DB_PASSWORD=${{vars.DB_PASSWORD}} \ - -e DB_URL=${{vars.DB_URL}} \ - ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index aafd8b3..4b6a94a 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -1,9 +1,3 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created -# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle name: Gradle Package From 5af98d90000f7ba6ac5dbb501f78d9648e35416e Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 00:58:58 +0900 Subject: [PATCH 141/181] Update gradle-publish.yml From 475ad67a2f11133f40e06766319d67d645657b20 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 01:03:24 +0900 Subject: [PATCH 142/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index aafd8b3..8d8b9d6 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -51,7 +51,7 @@ jobs: if [ ! -z "$CONTAINER_ID" ]; then sudo docker stop $CONTAINER_ID sudo docker rm $CONTAINER_ID - fi + # 새 이미지 Pull 및 실행 sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From c80c6171da3837365eda2f61732d3d872adb4f11 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 01:04:06 +0900 Subject: [PATCH 143/181] =?UTF-8?q?Feat=20:=201=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 1 + 1 file changed, 1 insertion(+) diff --git a/.env b/.env index 06449ad..db4d196 100644 --- a/.env +++ b/.env @@ -2,6 +2,7 @@ DB_NAME=${{ secrets.DB_NAME }} DB_USERNAME=${{ secrets.DB_PASSWORD }} DB_PASSWORD=${{ secrets.DB_USERNAME }} + BUCKET_ACCESSKEY=${{ secrets.BUCKET_ACCESSORY }} BUCKET_SECRETKEY=${{ secrets.BUCKET_SECRETARY }} BUCKET_NAME=${{ secrets.BUCKET_NAME }} \ No newline at end of file From 911d30b32819d5dd6ef1d6f83ca956bc08429bda Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 01:04:59 +0900 Subject: [PATCH 144/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 4b6a94a..570ae16 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -45,7 +45,7 @@ jobs: if [ ! -z "$CONTAINER_ID" ]; then sudo docker stop $CONTAINER_ID sudo docker rm $CONTAINER_ID - fi + # 새 이미지 Pull 및 실행 sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From 5d8f2c0a055b70ff16e134c3ad782596287b75e5 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 01:05:37 +0900 Subject: [PATCH 145/181] =?UTF-8?q?Feat=20:=202=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ee0d4eb..a4a1865 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,4 +4,4 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -ENTRYPOINT ["java", "-jar", "/app.jar"] \ No newline at end of file +ENTRYPOINT ["java", "-jar", "/app.jar"] From 86cce1d02f4f03b1c9cca7bd5b403f24b6f058de Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 01:06:42 +0900 Subject: [PATCH 146/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 570ae16..4b6a94a 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -45,7 +45,7 @@ jobs: if [ ! -z "$CONTAINER_ID" ]; then sudo docker stop $CONTAINER_ID sudo docker rm $CONTAINER_ID - + fi # 새 이미지 Pull 및 실행 sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From f6c2ada4e2497e70bd2bc184c9e1ec9374ce3fe2 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 01:45:24 +0900 Subject: [PATCH 147/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 34 ++++++++++++---------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 8d8b9d6..5475561 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -19,12 +19,12 @@ jobs: uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ vars.DOCKERHUB_TOKEN }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - name: Set up Docker Builds + name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push @@ -42,21 +42,17 @@ jobs: - name: Deploy to EC2 uses: appleboy/ssh-action@v1.2.0 with: - host: ${{ vars.EC2_HOST }} - username: ${{ vars.EC2_USER }} - key: ${{ vars.EC2_KEY }} + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_KEY }} script: | - # 기존 컨테이너 중지 및 제거 - CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") - if [ ! -z "$CONTAINER_ID" ]; then - sudo docker stop $CONTAINER_ID - sudo docker rm $CONTAINER_ID - - - # 새 이미지 Pull 및 실행 - sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest - sudo docker run -d -p 8080:8080 \ - -e DB_USERNAME=${{vars.DB_USERNAME}} \ - -e DB_PASSWORD=${{vars.DB_PASSWORD}} \ - -e DB_URL=${{vars.DB_URL}} \ - ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") + + if [ ! -z "$CONTAINER_ID" ]; then + sudo docker stop $CONTAINER_ID + sudo docker rm $CONTAINER_ID + fi + + sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + sudo docker run -d -p 8080:8080 \ + ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From 88ff1db1f8361c2970b3ef7a5c01271e88385307 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 01:56:46 +0900 Subject: [PATCH 148/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 40 +++++++++++++--------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 4b6a94a..5d912d2 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -1,9 +1,9 @@ +name: docker multi-stage build -name: Gradle Package - -on: [push] +on: [ push ] # 해당 branch에 push 되었을 경우 # https://github.com/marketplace/actions/build-and-push-docker-images + jobs: docker-build-and-push: runs-on: ubuntu-latest @@ -13,12 +13,12 @@ jobs: uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ vars.DOCKERHUB_TOKEN }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - name: Set up Docker Builds + name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push @@ -36,21 +36,17 @@ jobs: - name: Deploy to EC2 uses: appleboy/ssh-action@v1.2.0 with: - host: ${{ vars.EC2_HOST }} - username: ${{ vars.EC2_USER }} - key: ${{ vars.EC2_KEY }} + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_KEY }} script: | - # 기존 컨테이너 중지 및 제거 - CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") - if [ ! -z "$CONTAINER_ID" ]; then - sudo docker stop $CONTAINER_ID - sudo docker rm $CONTAINER_ID - fi - - # 새 이미지 Pull 및 실행 - sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest - sudo docker run -d -p 8080:8080 \ - -e DB_USERNAME=${{vars.DB_USERNAME}} \ - -e DB_PASSWORD=${{vars.DB_PASSWORD}} \ - -e DB_URL=${{vars.DB_URL}} \ - ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + CONTAINER_ID=$(sudo docker ps -q --filter "publish=8080-8080") + + if [ ! -z "$CONTAINER_ID" ]; then + sudo docker stop $CONTAINER_ID + sudo docker rm $CONTAINER_ID + fi + + sudo docker pull ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest + sudo docker run -d -p 8080:8080 \ + ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest From 62e6d23453aa2f187c628d23d2a01fc400e96d1d Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 01:56:57 +0900 Subject: [PATCH 149/181] =?UTF-8?q?Feat=20:=204=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index a4a1865..c23c73c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,3 +5,5 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] + + From 5ef68ca1b17e5a4785e28aa055e272c5e8d94542 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:03:12 +0900 Subject: [PATCH 150/181] =?UTF-8?q?Feat=20:=205=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index c23c73c..fd2b73e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,3 +7,4 @@ COPY ${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] + From 79d6612bed58be52fa70bb2ca517cd4a45053f64 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:08:49 +0900 Subject: [PATCH 151/181] =?UTF-8?q?Feat=20:=206=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index fd2b73e..144ae86 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,3 +8,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 552db26229d09bedddcb8aec32df90df3643bf0f Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 02:30:18 +0900 Subject: [PATCH 152/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 5475561..a2cbd40 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: ./docker/Dockerfile + file: C:\ProgramData\DockerDesktop push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 9531a515616f2b0758e89ca6736e7a63ea6bfdc3 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:30:30 +0900 Subject: [PATCH 153/181] =?UTF-8?q?Feat=20:=207=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 144ae86..12fc962 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,3 +9,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 4216587fcd5a9eeb832ec4c5b374fd2d44a415b9 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 02:33:40 +0900 Subject: [PATCH 154/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index a2cbd40..c1a7ff9 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: C:\ProgramData\DockerDesktop + file: /var/lib/docker push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 1d418c4038ce878f8ba497fc95739c888af34d2f Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:33:49 +0900 Subject: [PATCH 155/181] =?UTF-8?q?Feat=20:=208=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 12fc962..9aa7c6b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,3 +10,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 7827a41bbab8996b5b58113ef359773a90c37952 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 02:40:28 +0900 Subject: [PATCH 156/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index c1a7ff9..e19db68 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: /var/lib/docker + file: /build/libs/* push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 3a4faf101ebe0a07835a83824ee51bff6d432070 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:40:42 +0900 Subject: [PATCH 157/181] =?UTF-8?q?Feat=20:=209=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 9aa7c6b..5f24a4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,3 +11,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From d7b75e63b0b5a06d61675028ecf0ee64742060a2 Mon Sep 17 00:00:00 2001 From: 2unmini <2unmin4030@gmail.com> Date: Tue, 31 Dec 2024 02:44:39 +0900 Subject: [PATCH 158/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index e19db68..0ea2094 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -7,7 +7,9 @@ name: Gradle Package -on: [push] +on: + push: + branches: [ main ] # https://github.com/marketplace/actions/build-and-push-docker-images jobs: From 20bc33238136b534ff337ab2885a30305ba00302 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 02:48:56 +0900 Subject: [PATCH 159/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 082069b..a46b7bc 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -7,9 +7,7 @@ name: Gradle Package -on: - push: - branches: [ main ] +on: [ push ] # https://github.com/marketplace/actions/build-and-push-docker-images jobs: From 0ea952641468cba65ea27768c0546ac48da248a2 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:49:08 +0900 Subject: [PATCH 160/181] =?UTF-8?q?Feat=20:=209=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 5f24a4c..a9dc9c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,3 +12,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 40915a42952d2258e98ea1b3997d1f887205d6e6 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 02:51:52 +0900 Subject: [PATCH 161/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index a46b7bc..32c6611 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: /build/libs/* + file: /var/lib/docker push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From c41c97cc7ac43342cab997af5e3a72728360f07a Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 02:51:59 +0900 Subject: [PATCH 162/181] =?UTF-8?q?Feat=20:=2011=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index a9dc9c1..172f42d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,3 +13,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From d17a391a8a9df202891048afabe250b7b9f55822 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:05:36 +0900 Subject: [PATCH 163/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 32c6611..1b3d93c 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: /var/lib/docker + file: ./docker/Dockerfile push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 224e690f5a72cbf25c9290bd24c370d430de2db9 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:05:46 +0900 Subject: [PATCH 164/181] =?UTF-8?q?Feat=20:=2012=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 172f42d..b56b80c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,3 +14,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From fe4324d320dbf9e6f08fe0de210c556750ce8c66 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:08:45 +0900 Subject: [PATCH 165/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 1b3d93c..896246a 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: ./docker/Dockerfile + file: C:\Users\PC\Desktop\코딩 모음\Spring\주특기 플러스\Dockerfile push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 806bb02cee2f2e9b67b1257c2f18041d4e4b1dc1 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:08:55 +0900 Subject: [PATCH 166/181] =?UTF-8?q?Feat=20:=2013=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index b56b80c..f93a969 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,3 +15,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From ecf4134e89e76e6ea5a91b837acd1f4691a5866d Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:10:13 +0900 Subject: [PATCH 167/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 896246a..2671609 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: C:\Users\PC\Desktop\코딩 모음\Spring\주특기 플러스\Dockerfile + file: ./var/lib/docker push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 7446969ad44710ca1a6dadf92f1f0717b1cd14bf Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:10:22 +0900 Subject: [PATCH 168/181] =?UTF-8?q?Feat=20:=2014=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index f93a969..d7e7204 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,3 +16,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From b21633664f85a5b0d65adf388f9b2a9ff5570230 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:18:10 +0900 Subject: [PATCH 169/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 2671609..1b3d93c 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: ./var/lib/docker + file: ./docker/Dockerfile push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From a960a8c49a5d2781e3b3351b595db1926ebd14a7 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:18:17 +0900 Subject: [PATCH 170/181] =?UTF-8?q?Feat=20:=2015=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index d7e7204..ee6abd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,3 +17,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 2648b451177aa47f5d9825c53691a9d16f646983 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:26:41 +0900 Subject: [PATCH 171/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 1b3d93c..8fabb13 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: ./docker/Dockerfile + file: ./Dockerfile.dev push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From b73121b286c82f2199d44d697fa4590bc4190750 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:26:52 +0900 Subject: [PATCH 172/181] =?UTF-8?q?Feat=20:=2016=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index ee6abd2..a8d584a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,3 +18,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 7b11b34302dbd2901a379fefb8f564f8dec44ae0 Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:28:42 +0900 Subject: [PATCH 173/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 8fabb13..1c83242 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: ./Dockerfile.dev + file: /var/lib/Docker push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 5e3a929deabe28f11156552a0bd9ee54f2c2dce3 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:28:52 +0900 Subject: [PATCH 174/181] =?UTF-8?q?Feat=20:=2017=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index a8d584a..b7c84ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,3 +19,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 6e7440e0a229379b65b92e39e6d5b8046bef35fb Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:33:15 +0900 Subject: [PATCH 175/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 1c83242..ae3a172 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: /var/lib/Docker + file: /build/libs push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 050b95ad0c0e6c2b49358d5ab9243704c567a942 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:33:24 +0900 Subject: [PATCH 176/181] =?UTF-8?q?Feat=20:=2018=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index b7c84ef..c76a011 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,3 +20,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From a6e817ad6698ad9a673e84b69c91322d2e2fa67b Mon Sep 17 00:00:00 2001 From: kangjunhyuk1 Date: Tue, 31 Dec 2024 03:34:01 +0900 Subject: [PATCH 177/181] Update gradle-publish.yml --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index ae3a172..a46b7bc 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,7 +30,7 @@ jobs: name: Build and push uses: docker/build-push-action@v6 with: - file: /build/libs + file: /build/libs/* push: true tags: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_TAG_NAME }}:latest # Ec2 에 배포 From 0485659b12454b0d692514e7a32755a755a54f5d Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 03:34:11 +0900 Subject: [PATCH 178/181] =?UTF-8?q?Feat=20:=2019=EC=B0=A8=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index c76a011..f1ef194 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,3 +21,4 @@ ENTRYPOINT ["java", "-jar", "/app.jar"] + From 5e55f1ca4e30e898fca79a501bda279287fa2487 Mon Sep 17 00:00:00 2001 From: Newbiekk Date: Tue, 31 Dec 2024 05:03:27 +0900 Subject: [PATCH 179/181] =?UTF-8?q?docs=20:=20README.MD=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..894f49a --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# Trello TeamProject +--- +## 🦹‍ 12조 3FT1 팀원소개 +||||| +|:-:|:-:|:-:|:-:| +|강준혁|고강혁|천준민|장우태| +|kangjunhyuk1
[@kangjunhyuk1](https://github.com/kangjunhyuk1)|Newbiekk
[@Newbiekk-kkh](https://github.com/Newbiekk-kkh)|2unmini
[@2unmini](https://github.com/2unmini)|jangutae
[@jangutae](https://github.com/jangutae)| +--- +## 🛠️ Tools : Java Java ![Amazon S3](https://img.shields.io/badge/Amazon%20S3-FF9900?style=for-the-badge&logo=amazons3&logoColor=white) ![Git](https://img.shields.io/badge/git-%23F05033.svg?style=for-the-badge&logo=git&logoColor=white) ![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white) ![Slack](https://img.shields.io/badge/Slack-4A154B?style=for-the-badge&logo=slack&logoColor=white) +- MySql 8.0 +- Java 17 +- SpringBoot 3.4.1 +--- +## 👨‍💻 Period : 2024/12/23 ~ 2024/12/30 +--- +## 👨‍💻 ERD +![image](https://github.com/user-attachments/assets/aba1e1ad-adc4-47e4-95e6-b416657efee3) + + +--- +## 👨‍💻 API명세서 + +![플러스](https://github.com/user-attachments/assets/1833f1c6-2298-4244-bc2a-dbb4ecb02ff2) + +--- +## 👨‍💻 About Project + +- 회원가입/로그인 + - Spring security, JWT 를 사용해 인증 구현 + - 아이디는 이메일 형식 + - 탈퇴한 이메일 재사용 불가능 (회원 삭제를 STATUS ENUM 으로 관리) + - 비밀번호는 대소문자 포함 영문 + 숫자 + 특수문자 최소 1글자씩 포함 + - 역할(ADMIN, USER) 에 따라 권한 부여 + +- 워크스페이스 + - 제목, 설명, 슬랙URL 로 구성 + - ADMIN 역할인 회원만 생성 가능 + - 수정, 삭제 등 관리는 WORKSPACE 멤버역할을 가진 멤버만 가능 + +- 워크스페이스 멤버 + - 멤버 역할(WORKSPACE, BOARD, READ_ONLY)로 구성 + - ADMIN 역할을 가진 회원만 WORKSPACE 역할 부여 가능 + - 워크스페이스 멤버 초대는 WORKSPACE 역할만 가능 + +- 보드 + - READ_ONLY 역할을 제외한 워크스페이스의 멤버만 생성, 수정, 삭제 가능 + - 보드는 제목, 배경색, 이미지 설정 가능 + - 배경으로 쓸 이미지 업로드 기능 구현 (jpg, png, jpeg, gif 이외의 확장자는 업로드 불가능) + - 단일 조회시, 보드에 속한 리스트, 카드 전체 조회 가능 + +- 리스트 + - READ_ONLY 역할을 제외한 워크스페이스의 멤버만 생성, 수정, 삭제 가능 + - 리스트는 제목, 순서 설정 가능 + +- 카드 + - READ_ONLY 역할을 제외한 워크스페이스의 멤버만 생성, 수정, 삭제 가능 + - 카드는 제목, 설명, 마감일, 담당자 멤버 등을 추가 가능 + - 카드의 제목, 내용, 마감일, 담당자 이름 등을 기준으로 페이징하여 검색 (쿼리DSL 활용) + - 첨부파일 기능 구현 (첨부파일 업로드, 삭제, 조회) / 정해진 확장자(jpg, png, jpeg, gif, pdf, csv) 이외는 업로드 불가능 + +- 댓글 + - 카드 내에 댓글 작성 기능 ( 텍스트와 이모지 작성 ) + - READ_ONLY 역할을 제외한 워크스페이스의 멤버만 생성 가능 + - 댓글은 작성자만 수정, 삭제 가능 + +- 알림 + - 멤버 추가 / 카드 변경 / 댓글 작성 시 워크스페이스 생성시 등록했던 슬랙Url로 실시간 알림 제공 +--- + +## 😭 아쉬운점 +- 제출 당일 새벽 4시까지 팀원들 모두가 모여서 CI/CD 배포를 하려했으나, 지속되는 오류에 포기한 점이 아쉽습니다. 다음 최종 프로젝트에선 꼭 누락되는 기능 없이 구현해보고 싶습니다. +- Spring security 로 인증은 구현하였으나, 인가는 구현하지 못했습니다. 이또한 추가적인 학습 후에 구현해보고 싶습니다. From ac561ab4f07fa23be15611fd76dce1c2f413a125 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 06:31:53 +0900 Subject: [PATCH 180/181] =?UTF-8?q?Feat=20:=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/trello/comment/CommentRepository.java | 4 +++- .../com/example/trello/common/exception/CommentErrorCode.java | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/trello/comment/CommentRepository.java b/src/main/java/com/example/trello/comment/CommentRepository.java index 1d9f114..797dda4 100644 --- a/src/main/java/com/example/trello/comment/CommentRepository.java +++ b/src/main/java/com/example/trello/comment/CommentRepository.java @@ -1,6 +1,8 @@ package com.example.trello.comment; import com.example.trello.board.Board; +import com.example.trello.common.exception.CommentErrorCode; +import com.example.trello.common.exception.CommentException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -8,6 +10,6 @@ public interface CommentRepository extends JpaRepository { default Comment findByIdOrElseThrow(Long id){ - return findById(id).orElseThrow(()->new RuntimeException()); + return findById(id).orElseThrow(()->new CommentException(CommentErrorCode.COMMENT_NOT_FOUND)); } } diff --git a/src/main/java/com/example/trello/common/exception/CommentErrorCode.java b/src/main/java/com/example/trello/common/exception/CommentErrorCode.java index c6199e4..f6668fa 100644 --- a/src/main/java/com/example/trello/common/exception/CommentErrorCode.java +++ b/src/main/java/com/example/trello/common/exception/CommentErrorCode.java @@ -8,7 +8,8 @@ @Getter public enum CommentErrorCode { - CANNOT_BE_MODIFIED("댓글 수정은 작성자만 가능합니다", HttpStatus.FORBIDDEN); + CANNOT_BE_MODIFIED("댓글 수정은 작성자만 가능합니다", HttpStatus.FORBIDDEN), + COMMENT_NOT_FOUND("댓글을 찾을 수 없습니다", HttpStatus.NOT_FOUND); private final String message; private final HttpStatus httpStatus; From 1bb19cd736cebc00ad54744f5de6585603f41660 Mon Sep 17 00:00:00 2001 From: kangjunhyuk Date: Tue, 31 Dec 2024 06:32:21 +0900 Subject: [PATCH 181/181] =?UTF-8?q?Feat=20:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=EC=8B=9C=20=EC=9B=8C?= =?UTF-8?q?=ED=81=AC=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=A7=B4?= =?UTF-8?q?=EB=B2=84=EB=A5=BC=20=EB=B0=94=EA=BF=80=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/trello/card/Card.java | 1 + src/main/java/com/example/trello/card/CardService.java | 6 ++++-- .../trello/card/requestDto/UpdateCardRequestDto.java | 6 +++--- .../example/trello/card/responsedto/CardResponseDto.java | 6 +++++- .../trello/card/responsedto/UpdateCardResponseDto.java | 6 +++++- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/trello/card/Card.java b/src/main/java/com/example/trello/card/Card.java index 621b3b9..58710af 100644 --- a/src/main/java/com/example/trello/card/Card.java +++ b/src/main/java/com/example/trello/card/Card.java @@ -68,6 +68,7 @@ public void updateCard(UpdateCardResponseDto responseDto) { this.cardList = responseDto.getCardList(); this.title = responseDto.getTitle(); this.description = responseDto.getDescription(); + this.workspaceMember = responseDto.getWorkspaceMember(); this.startAt = responseDto.getStartAt(); this.endAt = responseDto.getEndAt(); } diff --git a/src/main/java/com/example/trello/card/CardService.java b/src/main/java/com/example/trello/card/CardService.java index af8a216..1dca14d 100644 --- a/src/main/java/com/example/trello/card/CardService.java +++ b/src/main/java/com/example/trello/card/CardService.java @@ -91,11 +91,13 @@ public CardResponseDto createdCardService(CardRequestDto requestDto, UserDetails public CardResponseDto updateCardService(Long cardId, UpdateCardRequestDto requestDto, UserDetailsImpl userDetails) { Card card = cardRepository.findByIdOrElseThrow(cardId); - WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); + WorkspaceMember changeWorkspaceMember = workspaceMemberRepository.findByIdOrElseThrow(requestDto.getWorkspaceMemberId()); CardList cardList = cardRepository.findByIdOrElseThrow(requestDto.getCardListId()).getCardList(); - UpdateCardResponseDto responseDto = new UpdateCardResponseDto(cardList, requestDto.getTitle(), requestDto.getDescription(), requestDto.getStartAt(), requestDto.getEndAt()); + UpdateCardResponseDto responseDto = new UpdateCardResponseDto(cardList, requestDto.getTitle(), requestDto.getDescription(), changeWorkspaceMember, requestDto.getStartAt(), requestDto.getEndAt()); + + WorkspaceMember workspaceMember = findWorkSpaceMember(userDetails, cardId); if (!workspaceMemberRepository.existsByUserIdAndWorkspaceId(workspaceMember.getId(), card.getCardList().getBoard().getWorkspace().getId())) { throw new WorkspaceMemberException(WorkspaceMemberErrorCode.IS_NOT_WORKSPACEMEMBER); diff --git a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java index 0c06299..745910f 100644 --- a/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java +++ b/src/main/java/com/example/trello/card/requestDto/UpdateCardRequestDto.java @@ -15,7 +15,7 @@ public class UpdateCardRequestDto { private String description; - private Long workSpaceMemberId; + private Long workspaceMemberId; @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate startAt; @@ -23,11 +23,11 @@ public class UpdateCardRequestDto { @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate endAt; - public UpdateCardRequestDto(String title, Long cardListId, String description, Long workSpaceMemberId, LocalDate startAt, LocalDate endAt) { + public UpdateCardRequestDto(String title, Long cardListId, String description, Long workspaceMemberId, LocalDate startAt, LocalDate endAt) { this.title = title; this.CardListId = cardListId; this.description = description; - this.workSpaceMemberId = workSpaceMemberId; + this.workspaceMemberId = workspaceMemberId; this.startAt = startAt; this.endAt = endAt; } diff --git a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java index 15a5e3a..41a4b05 100644 --- a/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/CardResponseDto.java @@ -21,6 +21,8 @@ public class CardResponseDto { private String description; + private Long workspaceMemberId; + @JsonFormat(pattern = "yyyy-MM-dd") LocalDate startAt; @@ -28,11 +30,12 @@ public class CardResponseDto { LocalDate endAt; - public CardResponseDto(Long cardListId, Long cardId, String title, String description, LocalDate startAt, LocalDate endAt) { + public CardResponseDto(Long cardListId, Long cardId, String title, String description, Long workspaceMemberId, LocalDate startAt, LocalDate endAt) { this.cardListId = cardListId; this.cardId = cardId; this.title = title; this.description = description; + this.workspaceMemberId = workspaceMemberId; this.startAt = startAt; this.endAt =endAt; } @@ -43,6 +46,7 @@ public static CardResponseDto toDto(Card card) { card.getId(), card.getTitle(), card.getDescription(), + card.getWorkspaceMember().getId(), card.getStartAt(), card.getEndAt()); } diff --git a/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java index 8cd2901..003149c 100644 --- a/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java +++ b/src/main/java/com/example/trello/card/responsedto/UpdateCardResponseDto.java @@ -1,6 +1,7 @@ package com.example.trello.card.responsedto; import com.example.trello.cardlist.CardList; +import com.example.trello.workspace_member.WorkspaceMember; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Getter; @@ -15,16 +16,19 @@ public class UpdateCardResponseDto { private String description; + private WorkspaceMember workspaceMember; + @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate startAt; @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate endAt; - public UpdateCardResponseDto(CardList cardListId, String title, String description, LocalDate startAt, LocalDate endAt) { + public UpdateCardResponseDto(CardList cardListId, String title, String description, WorkspaceMember workspaceMember, LocalDate startAt, LocalDate endAt) { this.cardList = cardListId; this.title = title; this.description = description; + this.workspaceMember = workspaceMember; this.startAt = startAt; this.endAt = endAt; }