From 27da6554ddfb690f435e008ac06b3ec7d85814eb Mon Sep 17 00:00:00 2001 From: taerimiiii Date: Tue, 16 Jun 2026 21:27:00 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EB=82=B4=20=EC=8B=9C=EB=AF=BC?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=EC=82=AC=20=EC=A1=B0=ED=9A=8C=20API=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 --- .../user/controller/UserController.java | 16 ++++ .../user/dto/res/UserMySolverItemResDTO.java | 11 +++ .../user/dto/res/UserMySolversResDTO.java | 5 ++ .../user/exception/code/UserErrorCode.java | 2 + .../user/exception/code/UserSuccessCode.java | 1 + .../repository/UserMySolverRepository.java | 51 +++++++++++ .../user/repository/UserMySolverRow.java | 17 ++++ .../service/query/UserSolverQueryService.java | 8 ++ .../query/UserSolverQueryServiceImpl.java | 86 +++++++++++++++++++ .../user/support/UserSolverCursorCodec.java | 55 ++++++++++++ 10 files changed, 252 insertions(+) create mode 100644 src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolverItemResDTO.java create mode 100644 src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolversResDTO.java create mode 100644 src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRepository.java create mode 100644 src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRow.java create mode 100644 src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryService.java create mode 100644 src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java create mode 100644 src/main/java/issueissyu/backend/domain/user/support/UserSolverCursorCodec.java diff --git a/src/main/java/issueissyu/backend/domain/user/controller/UserController.java b/src/main/java/issueissyu/backend/domain/user/controller/UserController.java index 8912d0fd..e22be6cf 100644 --- a/src/main/java/issueissyu/backend/domain/user/controller/UserController.java +++ b/src/main/java/issueissyu/backend/domain/user/controller/UserController.java @@ -8,12 +8,14 @@ import issueissyu.backend.domain.user.dto.res.UserAlarmStateResDTO; import issueissyu.backend.domain.user.dto.res.UserAlarmToggleResDTO; import issueissyu.backend.domain.user.dto.res.UserMyPinsResDTO; +import issueissyu.backend.domain.user.dto.res.UserMySolversResDTO; import issueissyu.backend.domain.user.enums.UserAlarmType; import issueissyu.backend.domain.alarm.exception.code.AlarmSuccessCode; import issueissyu.backend.domain.user.exception.code.UserSuccessCode; import issueissyu.backend.domain.user.service.command.UserCommandService; import issueissyu.backend.domain.user.service.query.UserAlarmStateQueryService; import issueissyu.backend.domain.user.service.query.UserPinQueryService; +import issueissyu.backend.domain.user.service.query.UserSolverQueryService; import issueissyu.backend.global.api.ApiResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -33,6 +35,7 @@ public class UserController { private final UserPinQueryService userPinQueryService; + private final UserSolverQueryService userSolverQueryService; private final UserAlarmStateQueryService userAlarmStateQueryService; private final UserCommandService userCommandService; @@ -87,4 +90,17 @@ public ApiResponse getMyPins( @RequestParam(required = false) String cursor) { return ApiResponse.onSuccess(UserSuccessCode.USER_PIN_200, userPinQueryService.getMyPins(uid, size, cursor)); } + + @Operation( + summary = "내 시민해결사 참여 핀 조회", + description = + "로그인한 사용자가 시민해결사(EN_ROUTE)로 참여 중인 핀을 problem_solver.created_at 내림차순으로 커서 페이징 조회합니다.") + @GetMapping("/me/solvers") + public ApiResponse getMySolvers( + @AuthenticationPrincipal String uid, + @RequestParam(required = false) Integer size, + @RequestParam(required = false) String cursor) { + return ApiResponse.onSuccess( + UserSuccessCode.USER_SOLVER_200, userSolverQueryService.getMySolvers(uid, size, cursor)); + } } diff --git a/src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolverItemResDTO.java b/src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolverItemResDTO.java new file mode 100644 index 00000000..e3e16393 --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolverItemResDTO.java @@ -0,0 +1,11 @@ +package issueissyu.backend.domain.user.dto.res; + +import com.fasterxml.jackson.annotation.JsonFormat; +import java.time.LocalDateTime; + +public record UserMySolverItemResDTO( + Long pinId, + String pinTitle, + String pinDetailAddress, + String issuePinState, + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSSSS") LocalDateTime createdAt) {} diff --git a/src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolversResDTO.java b/src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolversResDTO.java new file mode 100644 index 00000000..f910d25e --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/dto/res/UserMySolversResDTO.java @@ -0,0 +1,5 @@ +package issueissyu.backend.domain.user.dto.res; + +import java.util.List; + +public record UserMySolversResDTO(List pins, UserMyPinPageInfoResDTO pageInfo) {} diff --git a/src/main/java/issueissyu/backend/domain/user/exception/code/UserErrorCode.java b/src/main/java/issueissyu/backend/domain/user/exception/code/UserErrorCode.java index 235e1ac6..9024cf8c 100644 --- a/src/main/java/issueissyu/backend/domain/user/exception/code/UserErrorCode.java +++ b/src/main/java/issueissyu/backend/domain/user/exception/code/UserErrorCode.java @@ -11,6 +11,8 @@ public enum UserErrorCode implements BaseErrorCode { USER_PIN_400_1(HttpStatus.BAD_REQUEST, "USER_PIN_400_1", "조회 불가능한 사이즈 입니다."), USER_PIN_400_2(HttpStatus.BAD_REQUEST, "USER_PIN_400_2", "조회 불가능한 cursor 입니다."), + USER_SOLVER_400_1(HttpStatus.BAD_REQUEST, "USER_SOLVER_400_1", "조회 불가능한 사이즈 입니다."), + USER_SOLVER_400_2(HttpStatus.BAD_REQUEST, "USER_SOLVER_400_2", "조회 불가능한 cursor 입니다."), USER_NICKNAME_400(HttpStatus.BAD_REQUEST, "USER_NICKNAME_400", "닉네임은 15자 이내의 영문, 숫자, 한글만 사용 가능합니다."), USER_NICKNAME_409(HttpStatus.CONFLICT, "USER_NICKNAME_409", "이미 사용 중인 닉네임입니다."), USER_ALARM_400(HttpStatus.BAD_REQUEST, "USER_ALARM_400", "존재하지 않는 알람 설정입니다."); diff --git a/src/main/java/issueissyu/backend/domain/user/exception/code/UserSuccessCode.java b/src/main/java/issueissyu/backend/domain/user/exception/code/UserSuccessCode.java index 522bb36e..4ddb0886 100644 --- a/src/main/java/issueissyu/backend/domain/user/exception/code/UserSuccessCode.java +++ b/src/main/java/issueissyu/backend/domain/user/exception/code/UserSuccessCode.java @@ -10,6 +10,7 @@ public enum UserSuccessCode implements BaseSuccessCode { USER_PIN_200(HttpStatus.OK, "USER_PIN_200", "내 핀 조회에 성공했습니다."), + USER_SOLVER_200(HttpStatus.OK, "USER_SOLVER_200", "내 시민해결사 조회에 성공했습니다."), USER_NICKNAME_200(HttpStatus.OK, "USER_NICKNAME_200", "닉네임 변경에 성공했습니다."), USER_ALARM_200_1(HttpStatus.OK, "USER_ALARM_200_1", "핀 좋아요 알람 비/활성화에 성공했습니다."), USER_ALARM_200_2(HttpStatus.OK, "USER_ALARM_200_2", "이벤트 알람 비/활성화에 성공했습니다."), diff --git a/src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRepository.java b/src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRepository.java new file mode 100644 index 00000000..1b44a74d --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRepository.java @@ -0,0 +1,51 @@ +package issueissyu.backend.domain.user.repository; + +import issueissyu.backend.domain.issue.entity.ProblemSolver; +import java.time.LocalDateTime; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface UserMySolverRepository extends JpaRepository { + + @Query( + value = + """ + SELECT p.pin_id AS pinId, + p.pin_title AS pinTitle, + pl.detail_address AS pinDetailAddress, + ip.issue_pin_state AS issuePinState, + ps.created_at AS createdAt, + ps.problem_solver_id AS problemSolverId + FROM problem_solver ps + JOIN issue_pin ip ON ip.issue_pin_id = ps.issue_pin_id + JOIN pin p ON p.pin_id = ip.pin_id + LEFT JOIN LATERAL ( + SELECT pl2.detail_address + FROM pin_location pl2 + WHERE pl2.pin_id = p.pin_id + ORDER BY pl2.pin_location_id ASC + LIMIT 1 + ) pl ON TRUE + WHERE ps.uid = :uid + AND ps.problem_solve_state = 'EN_ROUTE' + AND ( + NOT CAST(:applyCursor AS boolean) + OR ps.created_at < CAST(:cursorCreatedAt AS timestamp) + OR ( + ps.created_at = CAST(:cursorCreatedAt AS timestamp) + AND ps.problem_solver_id < :cursorProblemSolverId + ) + ) + ORDER BY ps.created_at DESC, ps.problem_solver_id DESC + LIMIT :limit + """, + nativeQuery = true) + List findMySolvers( + @Param("uid") String uid, + @Param("applyCursor") boolean applyCursor, + @Param("cursorCreatedAt") LocalDateTime cursorCreatedAt, + @Param("cursorProblemSolverId") long cursorProblemSolverId, + @Param("limit") int limit); +} diff --git a/src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRow.java b/src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRow.java new file mode 100644 index 00000000..fa95c531 --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/repository/UserMySolverRow.java @@ -0,0 +1,17 @@ +package issueissyu.backend.domain.user.repository; + +import java.time.LocalDateTime; + +public interface UserMySolverRow { + Long getPinId(); + + String getPinTitle(); + + String getPinDetailAddress(); + + String getIssuePinState(); + + LocalDateTime getCreatedAt(); + + Long getProblemSolverId(); +} diff --git a/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryService.java b/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryService.java new file mode 100644 index 00000000..360ff485 --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryService.java @@ -0,0 +1,8 @@ +package issueissyu.backend.domain.user.service.query; + +import issueissyu.backend.domain.user.dto.res.UserMySolversResDTO; + +public interface UserSolverQueryService { + + UserMySolversResDTO getMySolvers(String uid, Integer size, String cursor); +} diff --git a/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java b/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java new file mode 100644 index 00000000..5f9f7f9a --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java @@ -0,0 +1,86 @@ +package issueissyu.backend.domain.user.service.query; + +import issueissyu.backend.domain.user.dto.res.UserMyPinPageInfoResDTO; +import issueissyu.backend.domain.user.dto.res.UserMySolverItemResDTO; +import issueissyu.backend.domain.user.dto.res.UserMySolversResDTO; +import issueissyu.backend.domain.user.exception.UserException; +import issueissyu.backend.domain.user.exception.code.UserErrorCode; +import issueissyu.backend.domain.user.repository.UserMySolverRepository; +import issueissyu.backend.domain.user.repository.UserMySolverRow; +import issueissyu.backend.domain.user.repository.UserRepository; +import issueissyu.backend.domain.user.support.UserSolverCursorCodec; +import issueissyu.backend.global.api.code.GeneralErrorCode; +import issueissyu.backend.global.exception.GeneralException; +import java.time.LocalDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class UserSolverQueryServiceImpl implements UserSolverQueryService { + + private static final int SIZE_DEFAULT = 10; + private static final int SIZE_MIN = 1; + private static final int SIZE_MAX = 100; + + private static final LocalDateTime CURSOR_DUMMY_TIME = LocalDateTime.of(1970, 1, 1, 0, 0, 0); + + private final UserRepository userRepository; + private final UserMySolverRepository userMySolverRepository; + private final UserSolverCursorCodec userSolverCursorCodec; + + @Override + public UserMySolversResDTO getMySolvers(String uid, Integer size, String cursor) { + int pageSize = resolveSize(size); + + userRepository.findById(uid).orElseThrow(() -> GeneralException.of(GeneralErrorCode.USER_NOT_FOUND)); + + boolean applyCursor = StringUtils.hasText(cursor); + LocalDateTime cursorCreatedAt = CURSOR_DUMMY_TIME; + long cursorProblemSolverId = 0L; + if (applyCursor) { + UserSolverCursorCodec.Decoded decoded = userSolverCursorCodec.decode(cursor.trim()); + cursorCreatedAt = decoded.createdAt(); + cursorProblemSolverId = decoded.problemSolverId(); + } + + List rows = + userMySolverRepository.findMySolvers( + uid, applyCursor, cursorCreatedAt, cursorProblemSolverId, pageSize + 1); + + boolean hasNext = rows.size() > pageSize; + List pageRows = hasNext ? rows.subList(0, pageSize) : rows; + + List pins = + pageRows.stream() + .map( + r -> + new UserMySolverItemResDTO( + r.getPinId(), + r.getPinTitle(), + r.getPinDetailAddress(), + r.getIssuePinState(), + r.getCreatedAt())) + .toList(); + + String nextCursor = null; + if (hasNext && !pageRows.isEmpty()) { + UserMySolverRow last = pageRows.get(pageRows.size() - 1); + nextCursor = userSolverCursorCodec.encode(last.getCreatedAt(), last.getProblemSolverId()); + } + + return new UserMySolversResDTO(pins, new UserMyPinPageInfoResDTO(hasNext, nextCursor)); + } + + private int resolveSize(Integer size) { + int s = size == null ? SIZE_DEFAULT : size; + if (s < SIZE_MIN || s > SIZE_MAX) { + throw UserException.of(UserErrorCode.USER_SOLVER_400_1); + } + return s; + } +} diff --git a/src/main/java/issueissyu/backend/domain/user/support/UserSolverCursorCodec.java b/src/main/java/issueissyu/backend/domain/user/support/UserSolverCursorCodec.java new file mode 100644 index 00000000..fa50a97c --- /dev/null +++ b/src/main/java/issueissyu/backend/domain/user/support/UserSolverCursorCodec.java @@ -0,0 +1,55 @@ +package issueissyu.backend.domain.user.support; + +import issueissyu.backend.domain.user.exception.UserException; +import issueissyu.backend.domain.user.exception.code.UserErrorCode; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.temporal.ChronoField; +import java.util.Base64; +import org.springframework.stereotype.Component; + +@Component +public class UserSolverCursorCodec { + + private static final DateTimeFormatter CURSOR_TIME = + new DateTimeFormatterBuilder() + .appendPattern("yyyy-MM-dd HH:mm:ss") + .appendFraction(ChronoField.NANO_OF_SECOND, 6, 9, true) + .toFormatter(); + + public record Decoded(LocalDateTime createdAt, long problemSolverId) {} + + public String encode(LocalDateTime createdAt, long problemSolverId) { + String raw = createdAt.format(CURSOR_TIME) + ":" + problemSolverId; + return Base64.getUrlEncoder() + .withoutPadding() + .encodeToString(raw.getBytes(StandardCharsets.UTF_8)); + } + + public Decoded decode(String cursor) { + if (cursor == null || cursor.isBlank()) { + throw UserException.of(UserErrorCode.USER_SOLVER_400_2); + } + try { + String raw = new String(Base64.getUrlDecoder().decode(cursor.trim()), StandardCharsets.UTF_8); + int delim = raw.lastIndexOf(':'); + if (delim < 0 || delim == raw.length() - 1) { + throw UserException.of(UserErrorCode.USER_SOLVER_400_2); + } + String createdAtRaw = raw.substring(0, delim); + String problemSolverIdRaw = raw.substring(delim + 1); + long problemSolverId = Long.parseLong(problemSolverIdRaw); + if (problemSolverId <= 0) { + throw UserException.of(UserErrorCode.USER_SOLVER_400_2); + } + LocalDateTime createdAt = LocalDateTime.parse(createdAtRaw, CURSOR_TIME); + return new Decoded(createdAt, problemSolverId); + } catch (UserException e) { + throw e; + } catch (Exception e) { + throw UserException.of(UserErrorCode.USER_SOLVER_400_2); + } + } +} From 122b13966e548b7fd589e7c886bba8a43e74f42b Mon Sep 17 00:00:00 2001 From: taerimiiii Date: Tue, 16 Jun 2026 21:35:49 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EC=95=8C=EB=9E=8C=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=20=EC=8B=9C=EA=B0=84=20=EC=98=81=EC=97=AD=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/alarm/controller/UserAlarmController.java | 4 ++-- .../service/command/RegionalAlarmCommandServiceImpl.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/issueissyu/backend/domain/alarm/controller/UserAlarmController.java b/src/main/java/issueissyu/backend/domain/alarm/controller/UserAlarmController.java index 84f3e459..e2b57e81 100644 --- a/src/main/java/issueissyu/backend/domain/alarm/controller/UserAlarmController.java +++ b/src/main/java/issueissyu/backend/domain/alarm/controller/UserAlarmController.java @@ -85,7 +85,7 @@ public ApiResponse sendLikeAlarm( description = """ 동네 인증 지역의 축제(FESTIVAL) 핀에 대한 푸시 알람을 요청자에게 전송합니다. - event_start_time 이 현재 시각 ±12시간 이내인 핀만 대상이며, 제목·본문은 서버에서 고정값으로 생성합니다. + event_start_time 이 현재 시각 24시간 이내인 핀만 대상이며, 제목·본문은 서버에서 고정값으로 생성합니다. user.event_alarm_active 가 false 이면 EVENT_ALARM_403 을 반환합니다. EVENT_ALARM_404_1(동네 인증 없음), EVENT_ALARM_404_2(대상 축제 없음), EVENT_ALARM_404_3(커뮤니티 없음). 알람 클릭 시 GET /api/communities/{communityId} 로 이동합니다. @@ -101,7 +101,7 @@ public ApiResponse sendEventAlarm(@AuthenticationPrincipal description = """ 동네 인증 지역의 가게(STORE) 핀에 대한 푸시 알람을 요청자에게 전송합니다. - event_start_time 이 현재 시각 ±12시간 이내인 핀만 대상이며, 제목·본문은 서버에서 고정값으로 생성합니다. + event_start_time 이 현재 시각 24시간 이내인 핀만 대상이며, 제목·본문은 서버에서 고정값으로 생성합니다. user.store_alarm_active 가 false 이면 STORE_ALARM_403 을 반환합니다. 알람 클릭 시 GET /api/communities/{communityId} 로 이동합니다. """) diff --git a/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java b/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java index 4e923321..1b0134d0 100644 --- a/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java +++ b/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java @@ -183,10 +183,9 @@ private void dispatchFcmBatch(List payloads, String alar fcmService.sendNotificationsBatchAsync(payloads); log.info("[RegionalAlarm] {} FCM batch dispatched count={}", alarmType, payloads.size()); } - private static LocalDateTime[] alarmTimeWindow() { LocalDateTime now = LocalDateTime.now(); - return new LocalDateTime[] {now.minusHours(12), now.plusHours(12)}; + return new LocalDateTime[] {now.minusHours(24), now}; } private User findUser(String uid) { From 1011b9108fe8d560f233e07ce9cc4d9b7c3d311b Mon Sep 17 00:00:00 2001 From: taerimiiii Date: Tue, 16 Jun 2026 21:43:19 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=EC=82=AC=EC=9A=A9=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=20=EC=8B=9C=EA=B0=84=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alarm/service/command/RegionalAlarmCommandServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java b/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java index 1b0134d0..1c17144c 100644 --- a/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java +++ b/src/main/java/issueissyu/backend/domain/alarm/service/command/RegionalAlarmCommandServiceImpl.java @@ -184,7 +184,7 @@ private void dispatchFcmBatch(List payloads, String alar log.info("[RegionalAlarm] {} FCM batch dispatched count={}", alarmType, payloads.size()); } private static LocalDateTime[] alarmTimeWindow() { - LocalDateTime now = LocalDateTime.now(); + LocalDateTime now = LocalDateTime.now(java.time.ZoneId.of("Asia/Seoul")); return new LocalDateTime[] {now.minusHours(24), now}; } From 721d7ac17838bffd07616d848f7e365f9abd5ba0 Mon Sep 17 00:00:00 2001 From: taerimiiii Date: Tue, 16 Jun 2026 21:47:28 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20=EB=A9=94=EB=AA=A8=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EC=98=A4=EB=B2=84=ED=97=A4=EB=93=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/service/query/UserSolverQueryServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java b/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java index 5f9f7f9a..6f2d5781 100644 --- a/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java +++ b/src/main/java/issueissyu/backend/domain/user/service/query/UserSolverQueryServiceImpl.java @@ -37,7 +37,9 @@ public class UserSolverQueryServiceImpl implements UserSolverQueryService { public UserMySolversResDTO getMySolvers(String uid, Integer size, String cursor) { int pageSize = resolveSize(size); - userRepository.findById(uid).orElseThrow(() -> GeneralException.of(GeneralErrorCode.USER_NOT_FOUND)); + if (!userRepository.existsById(uid)) { + throw GeneralException.of(GeneralErrorCode.USER_NOT_FOUND); + } boolean applyCursor = StringUtils.hasText(cursor); LocalDateTime cursorCreatedAt = CURSOR_DUMMY_TIME;