Skip to content

Commit 2f86d04

Browse files
gw0215JoosungKwon
andauthored
[#176] 신청서 삭제 (#182)
* feat(CrewMember): 올바르지 않는 유저 예외추가 - 유저가 해당 모임, 신청서등의 작성자가 아닐 때 발생하는 에러입니다. * feat(CrewMember): 신청서 삭제 기능 추가 - 신청서는 신청서 아이디를 사용하여 삭제합니다. - 신청서는 자신의 신청서만 삭제할 수 있습니다. - 자신의 신청서인지 검증을 진행합니다. * test(CrewMember): 신청서 삭제 기능 테스트 * test(CrewMember): Scheduler를 사용하여 신청서 매일 12시마다 삭제 * feat(Config): Scheduler 스레드 개수 설정하기 * feat(Config): Scheduling 비동기로 설정 --------- Co-authored-by: kwonjoosung <[email protected]>
1 parent b239fbb commit 2f86d04

File tree

16 files changed

+178
-19
lines changed

16 files changed

+178
-19
lines changed

src/main/java/com/prgrms/mukvengers/domain/crew/repository/CrewRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ public interface CrewRepository extends JpaRepository<Crew, Long> {
3636
SET c.status = 'FINISH'
3737
WHERE c.status != 'FINISH' AND c.promiseTime < :time
3838
""")
39-
int updateStatusAll(@Param("time")LocalDateTime now);
39+
int updateAllStatusToFinish(@Param("time") LocalDateTime now);
4040

4141
}

src/main/java/com/prgrms/mukvengers/domain/proposal/api/ProposalController.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import org.springframework.http.ResponseEntity;
1010
import org.springframework.security.core.annotation.AuthenticationPrincipal;
11+
import org.springframework.web.bind.annotation.DeleteMapping;
1112
import org.springframework.web.bind.annotation.GetMapping;
1213
import org.springframework.web.bind.annotation.PatchMapping;
1314
import org.springframework.web.bind.annotation.PathVariable;
@@ -128,4 +129,15 @@ public class ProposalController {
128129

129130
return ResponseEntity.ok().build();
130131
}
132+
133+
@DeleteMapping(value = "/proposals/{proposalId}")
134+
public ResponseEntity<Void> delete
135+
(
136+
@PathVariable Long proposalId,
137+
@AuthenticationPrincipal JwtAuthentication user
138+
) {
139+
proposalService.delete(proposalId, user.id());
140+
141+
return ResponseEntity.ok().build();
142+
}
131143
}

src/main/java/com/prgrms/mukvengers/domain/proposal/repository/ProposalRepository.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.prgrms.mukvengers.domain.proposal.repository;
22

3+
import java.time.LocalDateTime;
34
import java.util.List;
45
import java.util.Optional;
56

67
import org.springframework.data.jpa.repository.JpaRepository;
8+
import org.springframework.data.jpa.repository.Modifying;
79
import org.springframework.data.jpa.repository.Query;
810
import org.springframework.data.repository.query.Param;
911

@@ -39,4 +41,12 @@ public interface ProposalRepository extends JpaRepository<Proposal, Long> {
3941
""")
4042
Optional<ProposalStatus> findByUserIdAndCrewId(@Param("userId") Long userId, @Param("crewId") Long crewId);
4143

44+
@Modifying
45+
@Query(value = """
46+
DELETE
47+
FROM Proposal p
48+
WHERE p.crewId IN (SELECT c.id FROM Crew c WHERE c.promiseTime < :time)
49+
""")
50+
int deleteProposalsByPromiseTime(@Param("time") LocalDateTime now);
51+
4252
}

src/main/java/com/prgrms/mukvengers/domain/proposal/service/ProposalService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ public interface ProposalService {
1717
ProposalResponses getProposalsByMemberId(Long userId);
1818

1919
void updateProposalStatus(UpdateProposalRequest proposalRequest, Long userId, Long proposalId);
20+
21+
void delete(Long proposalId, Long userId);
2022
}

src/main/java/com/prgrms/mukvengers/domain/proposal/service/ProposalServiceImpl.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.prgrms.mukvengers.domain.proposal.model.Proposal;
2929
import com.prgrms.mukvengers.domain.proposal.model.vo.ProposalStatus;
3030
import com.prgrms.mukvengers.domain.proposal.repository.ProposalRepository;
31+
import com.prgrms.mukvengers.domain.user.exception.InvalidUserException;
3132
import com.prgrms.mukvengers.domain.user.exception.UserNotFoundException;
3233
import com.prgrms.mukvengers.domain.user.model.User;
3334
import com.prgrms.mukvengers.domain.user.repository.UserRepository;
@@ -180,4 +181,19 @@ private void registerCrewMember(Proposal proposal, Crew crew) {
180181

181182
crew.addCrewMember(crewMember);
182183
}
184+
185+
@Override
186+
@Transactional
187+
public void delete(Long proposalId, Long userId) {
188+
189+
Proposal proposal = proposalRepository.findById(proposalId)
190+
.orElseThrow(() -> new ProposalNotFoundException(proposalId));
191+
192+
if (!proposal.getUser().getId().equals(userId)) {
193+
throw new InvalidUserException(userId);
194+
}
195+
196+
proposalRepository.deleteById(proposalId);
197+
198+
}
183199
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.prgrms.mukvengers.domain.user.exception;
2+
3+
import com.prgrms.mukvengers.global.exception.ErrorCode;
4+
import com.prgrms.mukvengers.global.exception.ServiceException;
5+
6+
public class InvalidUserException extends ServiceException {
7+
8+
private static final ErrorCode ERROR_CODE = ErrorCode.USER_INVALID;
9+
private static final String MESSAGE_KEY = "exception.user.invalid";
10+
11+
public InvalidUserException(Long userId) {
12+
super(ERROR_CODE, MESSAGE_KEY, new Object[] {userId});
13+
}
14+
15+
}

src/main/java/com/prgrms/mukvengers/global/exception/ErrorCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public enum ErrorCode {
2121

2222
// User
2323
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "U001", "존재하지 않는 사용자입니다."),
24-
24+
USER_INVALID(HttpStatus.BAD_REQUEST, "U002", "권한이 없는 사용자입니다."),
2525
// Store
2626
STORE_NOT_FOUND(HttpStatus.NOT_FOUND, "S001", "존재하지 않는 가게입니다."),
2727

src/main/java/com/prgrms/mukvengers/global/scheduler/Scheduler.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,38 @@
22

33
import java.time.LocalDateTime;
44

5+
import org.springframework.scheduling.annotation.Async;
6+
import org.springframework.scheduling.annotation.EnableAsync;
57
import org.springframework.scheduling.annotation.EnableScheduling;
68
import org.springframework.scheduling.annotation.Scheduled;
79
import org.springframework.stereotype.Component;
810
import org.springframework.transaction.annotation.Transactional;
911

1012
import com.prgrms.mukvengers.domain.crew.repository.CrewRepository;
13+
import com.prgrms.mukvengers.domain.proposal.repository.ProposalRepository;
1114

1215
import lombok.RequiredArgsConstructor;
1316

1417
@Component
18+
@EnableAsync
1519
@EnableScheduling
1620
@RequiredArgsConstructor
1721
public class Scheduler {
1822

1923
private final CrewRepository crewRepository;
24+
private final ProposalRepository proposalRepository;
2025

26+
@Async
2127
@Scheduled(cron = "0 0 * * * *", zone = "Asia/Seoul")
2228
@Transactional
2329
public void changStatusOvertimeCrew() {
24-
crewRepository.updateStatusAll(LocalDateTime.now());
30+
crewRepository.updateAllStatusToFinish(LocalDateTime.now());
31+
}
32+
33+
@Async
34+
@Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul")
35+
@Transactional
36+
public void deleteProposalOverTimeCrew() {
37+
proposalRepository.deleteProposalsByPromiseTime(LocalDateTime.now());
2538
}
2639
}

src/main/resources/application.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ spring:
2929
slack:
3030
webhook: ${SLACK_WEBHOOK}
3131

32+
task:
33+
scheduling:
34+
pool:
35+
size: 2
36+
3237
# front server
3338
front:
3439
server: "https://kkini.vercel.app"

src/test/java/com/prgrms/mukvengers/base/RepositoryTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.prgrms.mukvengers.domain.crew.model.Crew;
1818
import com.prgrms.mukvengers.domain.crew.repository.CrewRepository;
1919
import com.prgrms.mukvengers.domain.crewmember.repository.CrewMemberRepository;
20+
import com.prgrms.mukvengers.domain.proposal.repository.ProposalRepository;
2021
import com.prgrms.mukvengers.domain.review.repository.ReviewRepository;
2122
import com.prgrms.mukvengers.domain.store.model.Store;
2223
import com.prgrms.mukvengers.domain.store.repository.StoreRepository;
@@ -47,20 +48,31 @@ public abstract class RepositoryTest {
4748
@Autowired
4849
protected ChatRepository chatRepository;
4950

50-
protected User savedUser;
51+
@Autowired
52+
protected ProposalRepository proposalRepository;
53+
54+
protected User savedUser1;
55+
56+
protected User savedUser2;
5157

5258
protected Store savedStore;
5359

5460
protected List<Crew> crews;
5561

56-
protected Long savedUserId;
62+
protected Long savedUser1Id;
63+
64+
protected Long savedUser2Id;
5765

5866
@BeforeEach
5967
void setUp() {
6068

61-
savedUser = userRepository.save(createUser());
69+
savedUser1 = userRepository.save(createUser("123"));
70+
71+
savedUser2 = userRepository.save(createUser("456"));
72+
73+
savedUser1Id = savedUser1.getId();
6274

63-
savedUserId = savedUser.getId();
75+
savedUser2Id = savedUser2.getId();
6476

6577
savedStore = storeRepository.save(createStore());
6678

0 commit comments

Comments
 (0)