diff --git a/src/main/java/com/back/catchmate/domain/board/entity/Board.java b/src/main/java/com/back/catchmate/domain/board/entity/Board.java index 785d4f1..bb640ad 100644 --- a/src/main/java/com/back/catchmate/domain/board/entity/Board.java +++ b/src/main/java/com/back/catchmate/domain/board/entity/Board.java @@ -92,4 +92,27 @@ public void updateBoard(Club cheerClub, Game game, CreateOrUpdateBoardRequest bo this.club = cheerClub; this.game = game; } + + public void deleteBoard() { + // Enroll 리스트 삭제 + for (Enroll enroll : enrollList) { + enroll.delete(); + } + enrollList.clear(); + + // Notification 리스트 삭제 + for (Notification notification : notificationList) { + notification.delete(); + } + notificationList.clear(); + + // BookMark 리스트 삭제 + for (BookMark bookMark : bookMarkList) { + bookMark.delete(); + } + bookMarkList.clear(); + + // 삭제 시간 기록 + super.delete(); + } } diff --git a/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java b/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java index 3070f5e..933ea74 100644 --- a/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java +++ b/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java @@ -68,7 +68,7 @@ public BoardInfo createOrUpdateBoard(Long userId, Long boardId, CreateOrUpdateBo // 작성자가 동일하지 않은 경우 예외 처리 if (user.isDifferentUserFrom(board.getUser())) { - throw new BaseException(ErrorCode.BOARD_BAD_REQUEST); + throw new BaseException(ErrorCode.BOARD_UPDATE_BAD_REQUEST); } // Board 업데이트 @@ -153,12 +153,18 @@ public BoardInfo getTempBoard(Long userId, Long boardId) { @Override @Transactional public BoardDeleteInfo deleteBoard(Long userId, Long boardId) { - int updatedRows = boardRepository.softDeleteByUserIdAndBoardId(userId, boardId); + User user = userRepository.findById(userId) + .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - if (updatedRows == 0) { - throw new BaseException(ErrorCode.BOARD_NOT_FOUND); + Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId) + .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); + + + if (user.isDifferentUserFrom(board.getUser())) { + throw new BaseException(ErrorCode.BOARD_DELETE_BAD_REQUEST); } + board.deleteBoard(); return boardConverter.toBoardDeleteInfo(boardId); } @@ -172,14 +178,14 @@ public BoardInfo updateLiftUpDate(Long userId, Long boardId) { .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); if (user.isDifferentUserFrom(board.getUser())) { - throw new BaseException(ErrorCode.BOARD_BAD_REQUEST); + throw new BaseException(ErrorCode.BOARD_LIFT_UP_BAD_REQUEST); } // note: 3일 간격으로 수정할 수 있음. if (board.getLiftUpDate().plusDays(3).isBefore(LocalDateTime.now())) { board.setLiftUpDate(LocalDateTime.now()); } else { - throw new BaseException(ErrorCode.BOARD_NOT_ALLOWED_UPDATE_LIFTUPDATE); + throw new BaseException(ErrorCode.BOARD_NOT_ALLOWED_UPDATE_LIFT_UPDATE); } return boardConverter.toBoardInfo(board, board.getGame()); diff --git a/src/main/java/com/back/catchmate/domain/enroll/entity/Enroll.java b/src/main/java/com/back/catchmate/domain/enroll/entity/Enroll.java index 0f574f5..f10433d 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/entity/Enroll.java +++ b/src/main/java/com/back/catchmate/domain/enroll/entity/Enroll.java @@ -57,4 +57,8 @@ public boolean isDifferentFromLoginUser(User user) { public void respondToEnroll(AcceptStatus acceptStatus) { this.acceptStatus = acceptStatus; } + + public void updateIsNew(boolean isNew) { + this.isNew = isNew; + } } diff --git a/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java b/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java index 6af044d..d57682f 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java +++ b/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java @@ -10,15 +10,17 @@ import java.util.Optional; public interface EnrollRepository extends JpaRepository { - Optional findByUserIdAndBoardId(Long userId, Long boardId); + Optional findByIdAndDeletedAtIsNull(Long enrollId); - Page findByUserId(Long userId, Pageable pageable); + Optional findByUserIdAndBoardIdAndDeletedAtIsNull(Long userId, Long boardId); - @Query("SELECT e FROM Enroll e WHERE e.board.user.id = :userId") + Page findByUserIdAndDeletedAtIsNull(Long userId, Pageable pageable); + + @Query("SELECT e FROM Enroll e WHERE e.board.user.id = :userId AND e.deletedAt IS NULL") Page findEnrollListByBoardWriter(@Param("userId") Long userId, Pageable pageable); - Page findByBoardId(Long boardId, Pageable pageable); + Page findByBoardIdAndDeletedAtIsNull(Long boardId, Pageable pageable); - @Query("SELECT COUNT(e) FROM Enroll e JOIN e.board b WHERE e.isNew = true AND b.user.id = :userId") + @Query("SELECT COUNT(e) FROM Enroll e JOIN e.board b WHERE e.isNew = true AND b.user.id = :userId AND e.deletedAt IS NULL") int countNewEnrollListByUserId(@Param("userId") Long userId); } diff --git a/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java b/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java index 4cde274..88594e3 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java +++ b/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java @@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.IOException; +import java.util.List; import static com.back.catchmate.domain.notification.message.NotificationMessages.*; @@ -46,13 +47,13 @@ public CreateEnrollInfo requestEnroll(CreateEnrollRequest request, Long boardId, .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); // 존재하는 게시글인지, 자신의 게시글인지 확인 - Board board = boardRepository.findById(boardId) + Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId) .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); if (board.isWriterSameAsLoginUser(user)) { throw new BaseException(ErrorCode.ENROLL_BAD_REQUEST); } - enrollRepository.findByUserIdAndBoardId(user.getId(), board.getId()) + enrollRepository.findByUserIdAndBoardIdAndDeletedAtIsNull(user.getId(), board.getId()) .ifPresent(enroll -> { throw new BaseException(ErrorCode.ENROLL_ALREADY_EXIST); }); @@ -80,7 +81,7 @@ public CancelEnrollInfo cancelEnroll(Long enrollId, Long userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Enroll enroll = enrollRepository.findById(enrollId) + Enroll enroll = enrollRepository.findByIdAndDeletedAtIsNull(enrollId) .orElseThrow(() -> new BaseException(ErrorCode.ENROLL_NOT_FOUND)); // 직관 신청한 사용자와 로그인한 사용자가 일치하는지 확인 @@ -88,7 +89,7 @@ public CancelEnrollInfo cancelEnroll(Long enrollId, Long userId) { throw new BaseException(ErrorCode.ENROLL_CANCEL_INVALID); } - enrollRepository.delete(enroll); + enroll.delete(); return enrollConverter.toCancelEnrollInfo(enroll); } @@ -98,12 +99,12 @@ public PagedEnrollRequestInfo getRequestEnrollList(Long userId, Pageable pageabl User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Page enrollList = enrollRepository.findByUserId(user.getId(), pageable); + Page enrollList = enrollRepository.findByUserIdAndDeletedAtIsNull(user.getId(), pageable); return enrollConverter.toPagedEnrollRequestInfo(enrollList); } @Override - @Transactional(readOnly = true) + @Transactional public PagedEnrollReceiveInfo getReceiveEnrollList(Long userId, Pageable pageable) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); @@ -113,12 +114,12 @@ public PagedEnrollReceiveInfo getReceiveEnrollList(Long userId, Pageable pageabl } @Override - @Transactional(readOnly = true) + @Transactional public PagedEnrollReceiveInfo getReceiveEnrollListByBoardId(Long userId, Long boardId, Pageable pageable) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Board board = boardRepository.findById(boardId) + Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId) .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); // 게시글 작성자가 맞는지 확인 @@ -127,7 +128,13 @@ public PagedEnrollReceiveInfo getReceiveEnrollListByBoardId(Long userId, Long bo } // 게시글에 신청된 목록 조회 - Page enrollList = enrollRepository.findByBoardId(boardId, pageable); + Page enrollList = enrollRepository.findByBoardIdAndDeletedAtIsNull(boardId, pageable); + + if (enrollList.hasContent()) { + List enrollsToUpdate = enrollList.getContent(); + enrollsToUpdate.forEach(enroll -> enroll.updateIsNew(false)); // 읽음 상태로 변경 + } + return enrollConverter.toPagedEnrollReceiveInfo(enrollList); } diff --git a/src/main/java/com/back/catchmate/domain/notification/repository/NotificationRepository.java b/src/main/java/com/back/catchmate/domain/notification/repository/NotificationRepository.java index a2c20ca..fd9abba 100644 --- a/src/main/java/com/back/catchmate/domain/notification/repository/NotificationRepository.java +++ b/src/main/java/com/back/catchmate/domain/notification/repository/NotificationRepository.java @@ -8,7 +8,7 @@ import java.util.Optional; public interface NotificationRepository extends JpaRepository { - Page findByUserId(Long userId, Pageable pageable); + Page findByUserIdAndDeletedAtIsNull(Long userId, Pageable pageable); - Optional findByIdAndUserId(Long notificationId, Long userId); + Optional findByIdAndUserIdAndDeletedAtIsNull(Long notificationId, Long userId); } diff --git a/src/main/java/com/back/catchmate/domain/notification/service/NotificationServiceImpl.java b/src/main/java/com/back/catchmate/domain/notification/service/NotificationServiceImpl.java index c78e129..f773972 100644 --- a/src/main/java/com/back/catchmate/domain/notification/service/NotificationServiceImpl.java +++ b/src/main/java/com/back/catchmate/domain/notification/service/NotificationServiceImpl.java @@ -32,7 +32,7 @@ public void createNotification(String title, String body, String senderProfileIm User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Board board = boardRepository.findById(boardId) + Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId) .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); Notification notification = notificationConverter.toEntity(user, board, senderProfileImageUrl, title, body); @@ -45,7 +45,7 @@ public PagedNotificationInfo getNotificationList(Long userId, Pageable pageable) User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Page notificationList = notificationRepository.findByUserId(user.getId(), pageable); + Page notificationList = notificationRepository.findByUserIdAndDeletedAtIsNull(user.getId(), pageable); return notificationConverter.toPagedNotificationInfo(notificationList); } @@ -55,7 +55,7 @@ public NotificationInfo getNotification(Long userId, Long notificationId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Notification notification = notificationRepository.findByIdAndUserId(notificationId, user.getId()) + Notification notification = notificationRepository.findByIdAndUserIdAndDeletedAtIsNull(notificationId, user.getId()) .orElseThrow(() -> new BaseException(ErrorCode.NOTIFICATION_NOT_FOUND)); // 읽지 않은 알림일 경우, 읽음으로 표시 @@ -72,10 +72,10 @@ public StateResponse deleteNotification(Long userId, Long notificationId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Notification notification = notificationRepository.findByIdAndUserId(notificationId, user.getId()) + Notification notification = notificationRepository.findByIdAndUserIdAndDeletedAtIsNull(notificationId, user.getId()) .orElseThrow(() -> new BaseException(ErrorCode.NOTIFICATION_NOT_FOUND)); - notificationRepository.delete(notification); + notification.delete(); return new StateResponse(true); } } diff --git a/src/main/java/com/back/catchmate/global/auth/converter/AuthConverter.java b/src/main/java/com/back/catchmate/global/auth/converter/AuthConverter.java index 73ac5c2..71dd3e4 100644 --- a/src/main/java/com/back/catchmate/global/auth/converter/AuthConverter.java +++ b/src/main/java/com/back/catchmate/global/auth/converter/AuthConverter.java @@ -6,7 +6,7 @@ @Component public class AuthConverter { - public AuthInfo toLoginInfo(String accessToken, String refreshToken, Boolean isFirstLogin) { + public AuthInfo toAuthInfo(String accessToken, String refreshToken, Boolean isFirstLogin) { return AuthInfo.builder() .accessToken(accessToken) .refreshToken(refreshToken) diff --git a/src/main/java/com/back/catchmate/global/auth/service/AuthServiceImpl.java b/src/main/java/com/back/catchmate/global/auth/service/AuthServiceImpl.java index ca17fdb..083c2a7 100644 --- a/src/main/java/com/back/catchmate/global/auth/service/AuthServiceImpl.java +++ b/src/main/java/com/back/catchmate/global/auth/service/AuthServiceImpl.java @@ -45,7 +45,7 @@ public AuthInfo login(AuthRequest.LoginRequest loginRequest) { if (findUserOptional.isEmpty()) { // 사용자가 없으면 최초 회원가입 여부를 true 반환 isFirstLogin = true; - authInfo = authConverter.toLoginInfo(null, null, isFirstLogin); + authInfo = authConverter.toAuthInfo(null, null, isFirstLogin); } else { // 회원가입된 사용자가 있으면 AccessToken과 RefreshToken 반환 User user = findUserOptional.get(); @@ -60,7 +60,7 @@ public AuthInfo login(AuthRequest.LoginRequest loginRequest) { // RefreshToken을 Redis에 저장 refreshTokenRepository.save(RefreshToken.of(refreshToken, userId)); - authInfo = authConverter.toLoginInfo(accessToken, refreshToken, isFirstLogin); + authInfo = authConverter.toAuthInfo(accessToken, refreshToken, isFirstLogin); } return authInfo; diff --git a/src/main/java/com/back/catchmate/global/error/ErrorCode.java b/src/main/java/com/back/catchmate/global/error/ErrorCode.java index 2bfacbb..01828c2 100644 --- a/src/main/java/com/back/catchmate/global/error/ErrorCode.java +++ b/src/main/java/com/back/catchmate/global/error/ErrorCode.java @@ -31,8 +31,10 @@ public enum ErrorCode { TEMP_BOARD_NOT_FOUND(HttpStatus.NOT_FOUND, "임시 저장된 글이 존재하지 않습니다."), TEMP_BOARD_BAD_REQUEST(HttpStatus.NOT_FOUND, "임시 저장된 글을 불러올 권한이 없습니다."), BOARD_DELETED(HttpStatus.NOT_FOUND, "삭제된 게시글이거나 잘못된 접근입니다."), - BOARD_BAD_REQUEST(HttpStatus.BAD_REQUEST, "자신의 게시글만 수정할 수 있습니다."), - BOARD_NOT_ALLOWED_UPDATE_LIFTUPDATE(HttpStatus.BAD_REQUEST, "마지막으로 끌어올리기 한 지 3일이 지나야 업데이트 가능합니다."), + BOARD_UPDATE_BAD_REQUEST(HttpStatus.BAD_REQUEST, "자신의 게시글만 수정할 수 있습니다."), + BOARD_DELETE_BAD_REQUEST(HttpStatus.BAD_REQUEST, "자신의 게시글만 삭제할 수 있습니다."), + BOARD_LIFT_UP_BAD_REQUEST(HttpStatus.BAD_REQUEST, "자신의 게시글만 삭제할 수 있습니다."), + BOARD_NOT_ALLOWED_UPDATE_LIFT_UPDATE(HttpStatus.BAD_REQUEST, "마지막으로 끌어올리기 한 지 3일이 지나야 업데이트 가능합니다."), INVALID_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 액세스 토큰입니다."), INVALID_REFRESH_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 리프레시 토큰입니다."), ALREADY_BOOKMARK(HttpStatus.BAD_REQUEST, "이미 찜한 게시글입니다."),