diff --git a/src/main/java/io/oeid/mogakgo/domain/achievement/application/AchievementEventService.java b/src/main/java/io/oeid/mogakgo/domain/achievement/application/AchievementEventService.java index 4db4fe1d..446af98d 100644 --- a/src/main/java/io/oeid/mogakgo/domain/achievement/application/AchievementEventService.java +++ b/src/main/java/io/oeid/mogakgo/domain/achievement/application/AchievementEventService.java @@ -32,6 +32,9 @@ public class AchievementEventService { private final AchievementFacadeService achievementFacadeService; private final ApplicationEventPublisher eventPublisher; + // 작업과 동시에 업적 달성이 가능한, progressCount 최솟값 + private final Integer MIN_PROGRESS_COUNT = 1; + // 달성 자격요건의 검증 없이 한 번에 달성 가능한 업적에 대한 이벤트 발행 @Async("threadPoolTaskExecutor") @Retryable(retryFor = EventListenerProcessingException.class, maxAttempts = 3, backoff = @Backoff(1000)) @@ -48,6 +51,8 @@ public void publishCompletedEventWithoutVerify(Long userId, ActivityType activit UserActivityEvent.builder() .userId(userId) .activityType(activityType) + .achievementId(achievementId) + .progressCount(MIN_PROGRESS_COUNT) .build() ); @@ -91,6 +96,8 @@ public void publishCompletedEventWithVerify(Long userId, ActivityType activityTy UserActivityEvent.builder() .userId(userId) .activityType(activityType) + .achievementId(achievementId) + .progressCount((Integer) target) .build() ); @@ -131,6 +138,8 @@ public void publishAccumulateEventWithVerify(Long userId, ActivityType activityT UserActivityEvent.builder() .userId(userId) .activityType(activityType) + .achievementId(achievementId) + .progressCount(progressCount) .build() ); @@ -247,6 +256,18 @@ public void recoverForEventListenerProcess( throw new AchievementException(ErrorCode400.EVENT_LISTENER_REQUEST_FAILED); } + @Recover + public void recoverForEventListenerProcess( + EventListenerProcessingException e, Long userId, ActivityType activityType, Integer progressCount) { + throw new AchievementException(ErrorCode400.EVENT_LISTENER_REQUEST_FAILED); + } + + @Recover + public void recoverForEventListenerProcess( + EventListenerProcessingException e, Long userId, ActivityType activityType, Object target) { + throw new AchievementException(ErrorCode400.EVENT_LISTENER_REQUEST_FAILED); + } + private boolean validateAvailabilityToAchieve(Object target, Long achievementId) { Achievement achievement = achievementFacadeService.getById(achievementId); if (target instanceof Integer) { diff --git a/src/main/java/io/oeid/mogakgo/domain/auth/presentation/AuthController.java b/src/main/java/io/oeid/mogakgo/domain/auth/presentation/AuthController.java index 8c706f26..1b79b950 100644 --- a/src/main/java/io/oeid/mogakgo/domain/auth/presentation/AuthController.java +++ b/src/main/java/io/oeid/mogakgo/domain/auth/presentation/AuthController.java @@ -7,8 +7,9 @@ import io.oeid.mogakgo.domain.auth.presentation.dto.res.AuthTokenApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.lang.NonNull; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -24,7 +25,7 @@ public class AuthController implements AuthSwagger { @PostMapping("/reissue") public ResponseEntity reissue( @RequestHeader(AUTHORIZATION) String accessToken, - @CookieValue(value = "refreshToken") String refreshToken) { + @RequestBody @NonNull String refreshToken) { var accessTokenDto = authService.reissue(accessToken, refreshToken); return ResponseEntity.ok( AuthTokenApiResponse.of(accessTokenDto.getAccessToken(), null, null)); diff --git a/src/main/java/io/oeid/mogakgo/domain/project/presentation/ProjectController.java b/src/main/java/io/oeid/mogakgo/domain/project/presentation/ProjectController.java index 89cd4f78..86b9ab20 100644 --- a/src/main/java/io/oeid/mogakgo/domain/project/presentation/ProjectController.java +++ b/src/main/java/io/oeid/mogakgo/domain/project/presentation/ProjectController.java @@ -89,7 +89,8 @@ public ResponseEntity> getProjectsByCr .body(projectService.getByCreatorId(userId, creatorId, pageable)); } - @GetMapping("{projectId}/{id}") + // TODO: 유저 id 따로 받는 이유? + @GetMapping("/{projectId}/{id}") public ResponseEntity getById( @UserId Long userId, @PathVariable Long projectId, @PathVariable Long id ) { diff --git a/src/main/java/io/oeid/mogakgo/domain/project_join_req/application/ProjectJoinRequestService.java b/src/main/java/io/oeid/mogakgo/domain/project_join_req/application/ProjectJoinRequestService.java index 70b4adaa..36886c92 100644 --- a/src/main/java/io/oeid/mogakgo/domain/project_join_req/application/ProjectJoinRequestService.java +++ b/src/main/java/io/oeid/mogakgo/domain/project_join_req/application/ProjectJoinRequestService.java @@ -102,10 +102,6 @@ public Long accept(Long userId, Long projectRequestId) { // TODO: 로그 처리 } - // TODO: 무한 대기로 인해 Batch로 일괄 거절 처리되는 경우, 이벤트 발행 어떻게 할 것인지? - List rejectedList = projectJoinRequestRepository - .findRejectedRequestByProjectId(projectJoinRequest.getProject().getId()); - fcmNotificationService.sendNotification(projectJoinRequest.getSender().getId(), MATCHING_SUCCESS_MESSAGE.getTitle(), MATCHING_SUCCESS_MESSAGE.getMessage(), MATCHING_SUCCEEDED); @@ -114,16 +110,6 @@ public Long accept(Long userId, Long projectRequestId) { return matchingId; } - private void cancelMyPendingProjectJoinRequest(User sender) { - projectJoinRequestRepository.findPendingBySenderId(sender.getId()) - .ifPresent(pendingProjectJoinRequest -> pendingProjectJoinRequest.cancel(sender)); - } - - private ProjectJoinRequest getProjectJoinRequestWithProject(Long projectRequestId) { - return projectJoinRequestRepository.findByIdWithProject(projectRequestId) - .orElseThrow(() -> new ProjectJoinRequestException(PROJECT_JOIN_REQUEST_NOT_FOUND)); - } - public CursorPaginationResult getBySenderIdWithPagination( Long userId, Long senderId, CursorPaginationInfoReq pageable ) { @@ -136,6 +122,16 @@ public CursorPaginationResult getBySenderIdWithP ); } + private void cancelMyPendingProjectJoinRequest(User sender) { + projectJoinRequestRepository.findPendingBySenderId(sender.getId()) + .ifPresent(pendingProjectJoinRequest -> pendingProjectJoinRequest.cancel(sender)); + } + + private ProjectJoinRequest getProjectJoinRequestWithProject(Long projectRequestId) { + return projectJoinRequestRepository.findByIdWithProject(projectRequestId) + .orElseThrow(() -> new ProjectJoinRequestException(PROJECT_JOIN_REQUEST_NOT_FOUND)); + } + private User validateToken(Long userId) { return userRepository.findById(userId) .orElseThrow(() -> new UserException(USER_NOT_FOUND)); diff --git a/src/main/java/io/oeid/mogakgo/domain/project_join_req/infrastructure/ProjectJoinRequestRepositoryCustomImpl.java b/src/main/java/io/oeid/mogakgo/domain/project_join_req/infrastructure/ProjectJoinRequestRepositoryCustomImpl.java index 6fb4aadd..110408d6 100644 --- a/src/main/java/io/oeid/mogakgo/domain/project_join_req/infrastructure/ProjectJoinRequestRepositoryCustomImpl.java +++ b/src/main/java/io/oeid/mogakgo/domain/project_join_req/infrastructure/ProjectJoinRequestRepositoryCustomImpl.java @@ -25,6 +25,7 @@ public class ProjectJoinRequestRepositoryCustomImpl implements ProjectJoinReques public CursorPaginationResult findByConditionWithPagination( Long senderId, Long projectId, RequestStatus requestStatus, CursorPaginationInfoReq pageable ) { + // 배치 사이즈가 작동하지 않는 이슈로 인해 주석 처리 // List result = jpaQueryFactory.select( // Projections.constructor( // projectJoinRequestRes.class, diff --git a/src/main/java/io/oeid/mogakgo/domain/project_join_req/presentation/dto/res/ProjectJoinRequestDetailAPIRes.java b/src/main/java/io/oeid/mogakgo/domain/project_join_req/presentation/dto/res/ProjectJoinRequestDetailAPIRes.java index 3dc4401e..4555b21d 100644 --- a/src/main/java/io/oeid/mogakgo/domain/project_join_req/presentation/dto/res/ProjectJoinRequestDetailAPIRes.java +++ b/src/main/java/io/oeid/mogakgo/domain/project_join_req/presentation/dto/res/ProjectJoinRequestDetailAPIRes.java @@ -17,6 +17,7 @@ public class ProjectJoinRequestDetailAPIRes { @NotNull private final Long projectId; + // TODO: creatorAvatorUrl -> creatorAvatarUrl @Schema(description = "프로젝트 생성자 아바타 URL", example = "https://avatars.githubusercontent.com/u/85854384?v=4") private final String creatorAvatorUrl;