Skip to content

Commit ab88480

Browse files
authored
[SSD-143] 타임페이퍼 삭제 기능 (#84)
* [SSD-143] chore: 전역 예외 처리 * [SSD-143] refactor: 롤링페이퍼 삭제 로직 - 롤링페이퍼 삭제 시 포스트잇 연관 관계만 해제하도록 변경 * [SSD-143] fix: 롤링페이퍼 삭제시 author 유효성 검증
1 parent 617111a commit ab88480

File tree

8 files changed

+45
-2595
lines changed

8 files changed

+45
-2595
lines changed

backend/src/main/java/com/timepaper/backend/domain/postit/entity/Postit.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class Postit extends BaseTimeEntity {
3636
private Long id;
3737

3838
@ManyToOne(fetch = FetchType.LAZY)
39-
@JoinColumn(name = "time_paper_id", nullable = false)
39+
@JoinColumn(name = "time_paper_id", nullable = true)
4040
private TimePaper timePaper;
4141

4242
@ManyToOne(fetch = FetchType.LAZY)

backend/src/main/java/com/timepaper/backend/domain/postit/repository/PostitRepository.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import org.springframework.data.domain.Page;
88
import org.springframework.data.domain.Pageable;
99
import org.springframework.data.jpa.repository.JpaRepository;
10+
import org.springframework.data.jpa.repository.Modifying;
11+
import org.springframework.data.jpa.repository.Query;
12+
import org.springframework.data.repository.query.Param;
1013

1114
public interface PostitRepository extends JpaRepository<Postit, Long> {
1215

@@ -15,4 +18,8 @@ public interface PostitRepository extends JpaRepository<Postit, Long> {
1518
List<Postit> findAllByAuthor(User author);
1619

1720
void deleteByTimePaperId(UUID timepaperId);
21+
22+
@Modifying
23+
@Query("UPDATE Postit p SET p.timePaper = NULL WHERE p.timePaper.id = :timePaperId")
24+
void unLinkPostits(@Param("timePaperId") UUID timePaperId);
1825
}

backend/src/main/java/com/timepaper/backend/domain/timepaper/controller/TimePaperController.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,33 @@ public ResponseEntity<ApiResponse<TimePaperResponseDto>> createTimePaper(
4040
timePaperService.createTimePaper(timePaperCreateRequestDto, authentication);
4141

4242
return ResponseEntity.status(HttpStatus.CREATED)
43-
.body(ApiResponse
44-
.ok("타임페이퍼 생성 성공",
45-
"CREATED",
46-
responseDto));
43+
.body(ApiResponse
44+
.ok("타임페이퍼 생성 성공",
45+
"CREATED",
46+
responseDto));
4747
}
4848

4949
@GetMapping("/{timepaperId}")
50-
public ResponseEntity<ApiResponse<TimePaperResponseDto>> getTimePaperById(@PathVariable UUID timepaperId) {
50+
public ResponseEntity<ApiResponse<TimePaperResponseDto>> getTimePaperById(
51+
@PathVariable UUID timepaperId) {
5152

5253
TimePaperResponseDto responseDto = timePaperService.getTimePaperById(timepaperId);
5354
return ResponseEntity.status(HttpStatus.OK)
54-
.body(ApiResponse
55-
.ok("타임페이퍼 조회 성공",
56-
"OK",
57-
responseDto));
55+
.body(ApiResponse
56+
.ok("타임페이퍼 조회 성공",
57+
"OK",
58+
responseDto));
5859
}
5960

6061
@DeleteMapping("/{timepaperId}")
61-
public ResponseEntity<ApiResponse<Void>> deleteTimePaper(@PathVariable UUID timepaperId) {
62-
timePaperService.deleteTimePaper(timepaperId);
62+
public ResponseEntity<ApiResponse<Void>> deleteTimePaper(@PathVariable UUID timepaperId,
63+
@AuthenticationPrincipal User user) {
64+
timePaperService.deleteTimePaper(timepaperId, user.getId());
6365
return ResponseEntity.status(HttpStatus.NO_CONTENT)
64-
.body(ApiResponse
65-
.ok("타임페이퍼 삭제 성공",
66-
"NO_CONTENT",
67-
null));
66+
.body(ApiResponse
67+
.ok("타임페이퍼 삭제 성공",
68+
"NO_CONTENT",
69+
null));
6870
}
6971

7072
@PatchMapping("/{timePaperId}/lock")
@@ -77,7 +79,7 @@ public ResponseEntity<ApiResponse<TimePaperLockResponseDto>> lockTimePaper(
7779
TimePaperLockResponseDto responseDto = timePaperService.lockTimePaper(timePaperId,
7880
timePaperLockRequestDto, requester.getId());
7981
return ResponseEntity.status(HttpStatus.OK)
80-
.body(ApiResponse.ok("타임페이퍼 잠금 처리 성공", "OK", responseDto));
82+
.body(ApiResponse.ok("타임페이퍼 잠금 처리 성공", "OK", responseDto));
8183
}
8284

8385
}

backend/src/main/java/com/timepaper/backend/domain/timepaper/service/TimePaperService.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
import com.timepaper.backend.global.exception.custom.common.ResourceNotFoundException;
1515
import java.util.UUID;
1616
import lombok.RequiredArgsConstructor;
17+
import lombok.extern.slf4j.Slf4j;
1718
import org.springframework.security.core.Authentication;
1819
import org.springframework.stereotype.Service;
1920
import org.springframework.transaction.annotation.Transactional;
2021

22+
@Slf4j
2123
@Service
2224
@RequiredArgsConstructor
2325
@Transactional(readOnly = true)
@@ -54,15 +56,16 @@ public TimePaperResponseDto getTimePaperById(UUID timepaperId) {
5456
}
5557

5658
@Transactional
57-
public void deleteTimePaper(UUID timepaperId) {
58-
// 삭제할 타임페이퍼 조회
59+
public void deleteTimePaper(UUID timepaperId, Long userId) {
60+
5961
TimePaper timePaper = timePaperRepository.findById(timepaperId)
6062
.orElseThrow(() -> new ResourceNotFoundException(ErrorCode.TIMEPAPER_NOT_FOUND));
6163

62-
// 1. 해당 타임페이퍼를 참조하는 모든 포스트잇 삭제
63-
postitRepository.deleteByTimePaperId(timepaperId);
64+
if (timePaper.getCreator().getId() != userId) {
65+
throw new ForBiddenException(ErrorCode.AUTHOR_ONLY);
66+
}
6467

65-
// 2. 타임페이퍼 삭제
68+
postitRepository.unLinkPostits(timepaperId);
6669
timePaperRepository.delete(timePaper);
6770
}
6871

backend/src/main/java/com/timepaper/backend/global/exception/handler/GlobalExceptionHandler.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,13 @@ public ResponseEntity<ApiResponse<Object>> malUploadSizeExceededHandler(
3535
.error(ErrorCode.PAYLOAD_TOO_LARGE.getMessage(),
3636
ErrorCode.PAYLOAD_TOO_LARGE.getCode()));
3737
}
38+
39+
// @ExceptionHandler(RuntimeException.class)
40+
// public ResponseEntity<ApiResponse<Object>> exceptionHandler(RuntimeException ex) {
41+
// return ResponseEntity.status(ErrorCode.SERVER_ERROR.getStatus())
42+
// .body(ApiResponse
43+
// .error(ErrorCode.SERVER_ERROR.getMessage(), ErrorCode.SERVER_ERROR.getCode()));
44+
// }
45+
46+
3847
}

backend/src/main/resources/application.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jwt.secret=${JWT_SECRET}
1111
spring.data.redis.host=${REDIS_HOST}
1212
spring.data.redis.port=${REDIS_PORT}
1313
spring.data.redis.password=${REDIS_PASSWORD}
14-
#JavaEmailSender관련 설정
14+
#JavaEmailSender관련 설정l
1515
spring.mail.host=${MAIL_HOST}
1616
spring.mail.port=${MAIL_PORT}
1717
spring.mail.username=${MAIL_USERNAME}

frontend/src/pages/login/Login.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default function Login() {
1818
const location = useLocation();
1919
const { isLoggedIn } = useSelector((state) => state.auth);
2020

21-
const handleLoginButtonClick = (event) => {
21+
const handleLoginButtonClick = async (event) => {
2222
setIsLoginButtonEnable(false);
2323
event.preventDefault();
2424
(async () => {

0 commit comments

Comments
 (0)