diff --git a/src/main/java/com/jobnote/domain/applicationform/api/ApplicationFormApi.java b/src/main/java/com/jobnote/domain/applicationform/api/ApplicationFormApi.java index eb9ef50..e8aec4c 100644 --- a/src/main/java/com/jobnote/domain/applicationform/api/ApplicationFormApi.java +++ b/src/main/java/com/jobnote/domain/applicationform/api/ApplicationFormApi.java @@ -2,18 +2,20 @@ import com.jobnote.auth.config.LoginUser; import com.jobnote.auth.dto.CustomUserDetails; -import com.jobnote.domain.applicationform.dto.ApplicationFormListResponse; import com.jobnote.domain.applicationform.dto.ApplicationFormRequest; import com.jobnote.domain.applicationform.dto.ApplicationFormResponse; import com.jobnote.global.annotation.swagger.ApiErrorResponseExplanation; import com.jobnote.global.annotation.swagger.ApiResponseExplanations; import com.jobnote.global.annotation.swagger.ApiSuccessResponseExplanation; +import com.jobnote.global.annotation.swagger.PageableAsQueryParam; import com.jobnote.global.common.ApiResponse; import com.jobnote.global.common.ResponseCode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -50,14 +52,10 @@ ResponseEntity> getApplicationForm( ); @Operation(summary = "지원서 목록 조회") - @ApiResponseExplanations( - success = @ApiSuccessResponseExplanation( - responseClass = ApplicationFormListResponse.class, - description = "조회 성공" - ) - ) - ResponseEntity> getAllApplicationForms( - @Parameter(hidden = true) @LoginUser final CustomUserDetails principal + @PageableAsQueryParam + ResponseEntity>> getAllApplicationForms( + @Parameter(hidden = true) @LoginUser final CustomUserDetails principal, + @Parameter(hidden = true) Pageable pageable ); @Operation(summary = "지원서 업데이트", diff --git a/src/main/java/com/jobnote/domain/applicationform/controller/ApplicationFormController.java b/src/main/java/com/jobnote/domain/applicationform/controller/ApplicationFormController.java index bcd3e52..09d38c3 100644 --- a/src/main/java/com/jobnote/domain/applicationform/controller/ApplicationFormController.java +++ b/src/main/java/com/jobnote/domain/applicationform/controller/ApplicationFormController.java @@ -3,7 +3,6 @@ import com.jobnote.auth.config.LoginUser; import com.jobnote.auth.dto.CustomUserDetails; import com.jobnote.domain.applicationform.api.ApplicationFormApi; -import com.jobnote.domain.applicationform.dto.ApplicationFormListResponse; import com.jobnote.domain.applicationform.dto.ApplicationFormRequest; import com.jobnote.domain.applicationform.dto.ApplicationFormResponse; import com.jobnote.domain.applicationform.service.ApplicationFormService; @@ -11,12 +10,13 @@ import com.jobnote.global.common.ResponseCode; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import java.net.URI; -import java.util.List; @RestController @RequestMapping("/api/v1/application-forms") @@ -53,13 +53,13 @@ public ResponseEntity> getApplicationForm( @Override @GetMapping - public ResponseEntity> getAllApplicationForms( - @LoginUser final CustomUserDetails principal + public ResponseEntity>> getAllApplicationForms( + @LoginUser final CustomUserDetails principal, + Pageable pageable ) { - List forms = applicationFormService.getAll(principal.getUserId()); - ApplicationFormListResponse listResponse = ApplicationFormListResponse.from(forms); + Page forms = applicationFormService.getAll(principal.getUserId(), pageable); - return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, listResponse)); + return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, forms)); } /* UPDATE */ diff --git a/src/main/java/com/jobnote/domain/applicationform/dto/ApplicationFormListResponse.java b/src/main/java/com/jobnote/domain/applicationform/dto/ApplicationFormListResponse.java deleted file mode 100644 index 06824e6..0000000 --- a/src/main/java/com/jobnote/domain/applicationform/dto/ApplicationFormListResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jobnote.domain.applicationform.dto; - -import lombok.AccessLevel; -import lombok.Builder; - -import java.util.List; - -@Builder(access = AccessLevel.PRIVATE) -public record ApplicationFormListResponse( - List applicationForms -) { - public static ApplicationFormListResponse from(final List applicationForms) { - return ApplicationFormListResponse.builder() - .applicationForms(applicationForms) - .build(); - } -} \ No newline at end of file diff --git a/src/main/java/com/jobnote/domain/applicationform/repository/ApplicationFormRepository.java b/src/main/java/com/jobnote/domain/applicationform/repository/ApplicationFormRepository.java index cb0e0b6..3ffe805 100644 --- a/src/main/java/com/jobnote/domain/applicationform/repository/ApplicationFormRepository.java +++ b/src/main/java/com/jobnote/domain/applicationform/repository/ApplicationFormRepository.java @@ -1,10 +1,10 @@ package com.jobnote.domain.applicationform.repository; import com.jobnote.domain.applicationform.domain.ApplicationForm; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface ApplicationFormRepository extends JpaRepository { - List findAllByUserId(final Long id); + Page findAllByUserId(final Long id, final Pageable pageable); } diff --git a/src/main/java/com/jobnote/domain/applicationform/service/ApplicationFormService.java b/src/main/java/com/jobnote/domain/applicationform/service/ApplicationFormService.java index e97b221..4e353aa 100644 --- a/src/main/java/com/jobnote/domain/applicationform/service/ApplicationFormService.java +++ b/src/main/java/com/jobnote/domain/applicationform/service/ApplicationFormService.java @@ -15,6 +15,8 @@ import com.jobnote.domain.user.domain.User; import com.jobnote.domain.user.service.UserService; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -47,28 +49,24 @@ public ApplicationFormResponse getById(final Long userId, final Long formId) { return ApplicationFormResponse.from(form, schedules, documents); } - public List getAll(final Long userId) { - List forms = applicationFormRepository.findAllByUserId(userId); - List formIds = forms.stream().map(ApplicationForm::getId).toList(); + public Page getAll(final Long userId, final Pageable pageable) { + Page forms = applicationFormRepository.findAllByUserId(userId, pageable); + List formIds = forms.map(ApplicationForm::getId).toList(); Map> schedulesByFormId = scheduleService.getAllGroupedByApplicationFormIds(userId, formIds); Map> documentsByFormId = applicationFormDocumentService.getSimpleResponsesGroupedByApplicationFormIds(userId, formIds); - return forms.stream() - .map(form -> ApplicationFormResponse.from( - form, - schedulesByFormId.getOrDefault(form.getId(), List.of()), - documentsByFormId.getOrDefault(form.getId(), List.of())) - ) - .toList(); + return forms.map(form -> ApplicationFormResponse.from( + form, + schedulesByFormId.getOrDefault(form.getId(), List.of()), + documentsByFormId.getOrDefault(form.getId(), List.of())) + ); } public List getAllSimple(final Long userId) { - List forms = applicationFormRepository.findAllByUserId(userId); + Page forms = applicationFormRepository.findAllByUserId(userId, Pageable.unpaged()); - return forms.stream() - .map(ApplicationFormSimpleResponse::from) - .toList(); + return forms.map(ApplicationFormSimpleResponse::from).toList(); } /* CREATE */ diff --git a/src/main/java/com/jobnote/domain/document/api/DocumentApi.java b/src/main/java/com/jobnote/domain/document/api/DocumentApi.java index 0e15669..06eb70c 100644 --- a/src/main/java/com/jobnote/domain/document/api/DocumentApi.java +++ b/src/main/java/com/jobnote/domain/document/api/DocumentApi.java @@ -6,12 +6,15 @@ import com.jobnote.global.annotation.swagger.ApiErrorResponseExplanation; import com.jobnote.global.annotation.swagger.ApiResponseExplanations; import com.jobnote.global.annotation.swagger.ApiSuccessResponseExplanation; +import com.jobnote.global.annotation.swagger.PageableAsQueryParam; import com.jobnote.global.common.ApiResponse; import com.jobnote.global.common.ResponseCode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -58,26 +61,18 @@ ResponseEntity> uploadNewVersionDocument( ); @Operation(summary = "문서 목록 조회") - @ApiResponseExplanations( - success = @ApiSuccessResponseExplanation( - responseClass = DocumentListResponse.class, - description = "조회 성공" - ) - ) - ResponseEntity> getAllDocuments( - @Parameter(hidden = true) @LoginUser final CustomUserDetails principal + @PageableAsQueryParam + ResponseEntity>> getAllDocuments( + @Parameter(hidden = true) @LoginUser final CustomUserDetails principal, + @Parameter(hidden = true) Pageable pageable ); @Operation(summary = "문서의 모든 버전 목록 조회") - @ApiResponseExplanations( - success = @ApiSuccessResponseExplanation( - responseClass = DocumentVersionListResponse.class, - description = "조회 성공" - ) - ) - ResponseEntity> getAllDocumentVersions( + @PageableAsQueryParam + ResponseEntity>> getAllDocumentVersions( @PathVariable final Long documentId, - @Parameter(hidden = true) @LoginUser final CustomUserDetails principal + @Parameter(hidden = true) @LoginUser final CustomUserDetails principal, + @Parameter(hidden = true) Pageable pageable ); @Operation(summary = "문서 삭제") diff --git a/src/main/java/com/jobnote/domain/document/controller/DocumentController.java b/src/main/java/com/jobnote/domain/document/controller/DocumentController.java index 6c29761..c8ce441 100644 --- a/src/main/java/com/jobnote/domain/document/controller/DocumentController.java +++ b/src/main/java/com/jobnote/domain/document/controller/DocumentController.java @@ -9,12 +9,13 @@ import com.jobnote.global.common.ResponseCode; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import java.net.URI; -import java.util.List; @RestController @RequestMapping("/api/v1/documents") @@ -54,25 +55,25 @@ public ResponseEntity> uploadNewVersionDocument( /* READ */ @Override @GetMapping - public ResponseEntity> getAllDocuments( - @LoginUser final CustomUserDetails principal + public ResponseEntity>> getAllDocuments( + @LoginUser final CustomUserDetails principal, + Pageable pageable ) { - List documents = documentService.getAll(principal.getUserId()); - DocumentListResponse listResponse = DocumentListResponse.from(documents); + Page documents = documentService.getAll(principal.getUserId(), pageable); - return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, listResponse)); + return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, documents)); } @Override @GetMapping("/{documentId}") - public ResponseEntity> getAllDocumentVersions( + public ResponseEntity>> getAllDocumentVersions( @PathVariable final Long documentId, - @LoginUser final CustomUserDetails principal + @LoginUser final CustomUserDetails principal, + Pageable pageable ) { - List documents = documentService.getAllVersions(principal.getUserId(), documentId); - DocumentVersionListResponse listResponse = DocumentVersionListResponse.from(documents); + Page documents = documentService.getAllVersions(principal.getUserId(), documentId, pageable); - return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, listResponse)); + return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, documents)); } /* DELETE */ diff --git a/src/main/java/com/jobnote/domain/document/dto/DocumentListResponse.java b/src/main/java/com/jobnote/domain/document/dto/DocumentListResponse.java deleted file mode 100644 index c101e2a..0000000 --- a/src/main/java/com/jobnote/domain/document/dto/DocumentListResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jobnote.domain.document.dto; - -import lombok.AccessLevel; -import lombok.Builder; - -import java.util.List; - -@Builder(access = AccessLevel.PRIVATE) -public record DocumentListResponse( - List documents -) { - public static DocumentListResponse from(final List documents) { - return DocumentListResponse.builder() - .documents(documents) - .build(); - } -} diff --git a/src/main/java/com/jobnote/domain/document/dto/DocumentVersionListResponse.java b/src/main/java/com/jobnote/domain/document/dto/DocumentVersionListResponse.java deleted file mode 100644 index 9f5c7b5..0000000 --- a/src/main/java/com/jobnote/domain/document/dto/DocumentVersionListResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jobnote.domain.document.dto; - -import lombok.AccessLevel; -import lombok.Builder; - -import java.util.List; - -@Builder(access = AccessLevel.PRIVATE) -public record DocumentVersionListResponse( - List documentVersions -) { - public static DocumentVersionListResponse from(List documentVersions) { - return DocumentVersionListResponse.builder() - .documentVersions(documentVersions) - .build(); - } -} diff --git a/src/main/java/com/jobnote/domain/document/repository/DocumentRepository.java b/src/main/java/com/jobnote/domain/document/repository/DocumentRepository.java index 57280a4..1cc7717 100644 --- a/src/main/java/com/jobnote/domain/document/repository/DocumentRepository.java +++ b/src/main/java/com/jobnote/domain/document/repository/DocumentRepository.java @@ -1,10 +1,10 @@ package com.jobnote.domain.document.repository; import com.jobnote.domain.document.domain.Document; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface DocumentRepository extends JpaRepository { - List findAllByUserId(final Long userId); + Page findAllByUserId(final Long userId, final Pageable pageable); } diff --git a/src/main/java/com/jobnote/domain/document/repository/DocumentVersionRepository.java b/src/main/java/com/jobnote/domain/document/repository/DocumentVersionRepository.java index f0b4769..5755d0e 100644 --- a/src/main/java/com/jobnote/domain/document/repository/DocumentVersionRepository.java +++ b/src/main/java/com/jobnote/domain/document/repository/DocumentVersionRepository.java @@ -1,11 +1,12 @@ package com.jobnote.domain.document.repository; import com.jobnote.domain.document.domain.DocumentVersion; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import java.util.List; import java.util.Optional; public interface DocumentVersionRepository extends JpaRepository { @@ -13,7 +14,7 @@ public interface DocumentVersionRepository extends JpaRepository findMaxVersionByDocumentId(final Long documentId); @Query("select v from DocumentVersion v join fetch v.document d join d.user u where u.id = :userId and d.id = :documentId order by v.version desc") - List findAllByUserIdAndDocumentId(final Long userId, final Long documentId); + Page findAllByUserIdAndDocumentId(final Long userId, final Long documentId, final Pageable pageable); @Query("select COALESCE(SUM(v.fileSize), 0) from DocumentVersion v join v.document d where d.user.id = :userId") Long getTotalFileSizeByUserId(final Long userId); diff --git a/src/main/java/com/jobnote/domain/document/service/DocumentService.java b/src/main/java/com/jobnote/domain/document/service/DocumentService.java index 53d2837..4ab51a0 100644 --- a/src/main/java/com/jobnote/domain/document/service/DocumentService.java +++ b/src/main/java/com/jobnote/domain/document/service/DocumentService.java @@ -14,11 +14,11 @@ import com.jobnote.global.exception.JobNoteException; import com.jobnote.infra.s3.service.S3Service; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - import static com.jobnote.global.common.ResponseCode.NOT_FOUND_DOCUMENT; @Service @@ -52,16 +52,15 @@ public Long uploadNewVersionDocument(final Long userId, final Long documentId, f return saveDocumentVersion(userId, document, request, version); } - public List getAll(final Long userId) { - return documentRepository.findAllByUserId(userId).stream() - .map(document -> DocumentResponse.from(document, applicationFormService.getAllSimple(userId))).toList(); + public Page getAll(final Long userId, final Pageable pageable) { + return documentRepository.findAllByUserId(userId, pageable) + .map(document -> DocumentResponse.from(document, applicationFormService.getAllSimple(userId))); } - public List getAllVersions(final Long userId, final Long documentId) { - return documentVersionRepository.findAllByUserIdAndDocumentId(userId, documentId).stream() + public Page getAllVersions(final Long userId, final Long documentId, final Pageable pageable) { + return documentVersionRepository.findAllByUserIdAndDocumentId(userId, documentId, pageable) .map(docVer -> - DocumentVersionResponse.of(docVer, s3Service.generateFileUrl(docVer.getFileKey()))) - .toList(); + DocumentVersionResponse.of(docVer, s3Service.generateFileUrl(docVer.getFileKey()))); } @Transactional @@ -70,7 +69,7 @@ public void delete(final Long userId, final Long documentId) { document.validateOwner(userId); // s3에서 삭제 - List allByDocumentId = documentVersionRepository.findAllByUserIdAndDocumentId(userId, documentId); + Page allByDocumentId = documentVersionRepository.findAllByUserIdAndDocumentId(userId, documentId, Pageable.unpaged()); for (DocumentVersion documentVersion : allByDocumentId) { s3Service.deleteFile(documentVersion.getFileKey()); } @@ -83,7 +82,7 @@ public void delete(final Long userId, final Long documentId) { @Transactional public void deleteAllDocuments(final Long userId) { - List documents = documentRepository.findAllByUserId(userId); + Page documents = documentRepository.findAllByUserId(userId, Pageable.unpaged()); for (Document document : documents) { delete(userId, document.getId()); } diff --git a/src/main/java/com/jobnote/domain/schedule/api/UserScheduleApi.java b/src/main/java/com/jobnote/domain/schedule/api/UserScheduleApi.java index 1a03473..f105c02 100644 --- a/src/main/java/com/jobnote/domain/schedule/api/UserScheduleApi.java +++ b/src/main/java/com/jobnote/domain/schedule/api/UserScheduleApi.java @@ -2,13 +2,14 @@ import com.jobnote.auth.config.LoginUser; import com.jobnote.auth.dto.CustomUserDetails; -import com.jobnote.domain.schedule.dto.ScheduleListResponse; -import com.jobnote.global.annotation.swagger.ApiResponseExplanations; -import com.jobnote.global.annotation.swagger.ApiSuccessResponseExplanation; +import com.jobnote.domain.schedule.dto.ScheduleResponse; +import com.jobnote.global.annotation.swagger.PageableAsQueryParam; import com.jobnote.global.common.ApiResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestParam; @@ -19,15 +20,11 @@ public interface UserScheduleApi { @Operation(summary = "일정 목록 조회") - @ApiResponseExplanations( - success = @ApiSuccessResponseExplanation( - responseClass = ScheduleListResponse.class, - description = "조회 성공" - ) - ) - ResponseEntity> getAllSchedules( + @PageableAsQueryParam + ResponseEntity>> getAllSchedules( @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final LocalDateTime startDate, @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final LocalDateTime endDate, - @Parameter(hidden = true) @LoginUser final CustomUserDetails principal + @Parameter(hidden = true) @LoginUser final CustomUserDetails principal, + @Parameter(hidden = true) Pageable pageable ); } diff --git a/src/main/java/com/jobnote/domain/schedule/controller/UserScheduleController.java b/src/main/java/com/jobnote/domain/schedule/controller/UserScheduleController.java index ae73d39..d7f6045 100644 --- a/src/main/java/com/jobnote/domain/schedule/controller/UserScheduleController.java +++ b/src/main/java/com/jobnote/domain/schedule/controller/UserScheduleController.java @@ -3,13 +3,14 @@ import com.jobnote.auth.config.LoginUser; import com.jobnote.auth.dto.CustomUserDetails; import com.jobnote.domain.schedule.api.UserScheduleApi; -import com.jobnote.domain.schedule.dto.ScheduleListResponse; import com.jobnote.domain.schedule.dto.ScheduleResponse; import com.jobnote.domain.schedule.service.ScheduleService; import com.jobnote.global.common.ApiResponse; import com.jobnote.global.common.ResponseCode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -18,7 +19,6 @@ import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; -import java.util.List; @Slf4j @RestController @@ -30,14 +30,14 @@ public class UserScheduleController implements UserScheduleApi { @Override @GetMapping - public ResponseEntity> getAllSchedules( + public ResponseEntity>> getAllSchedules( @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final LocalDateTime startDate, @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final LocalDateTime endDate, - @LoginUser final CustomUserDetails principal + @LoginUser final CustomUserDetails principal, + Pageable pageable ) { - List schedules = scheduleService.getAll(principal.getUserId(), startDate, endDate); - ScheduleListResponse listResponse = ScheduleListResponse.from(schedules); + Page schedules = scheduleService.getAll(principal.getUserId(), startDate, endDate, pageable); - return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, listResponse)); + return ResponseEntity.ok(ApiResponse.ofSuccess(ResponseCode.OK, schedules)); } } diff --git a/src/main/java/com/jobnote/domain/schedule/dto/ScheduleListResponse.java b/src/main/java/com/jobnote/domain/schedule/dto/ScheduleListResponse.java deleted file mode 100644 index 0d18883..0000000 --- a/src/main/java/com/jobnote/domain/schedule/dto/ScheduleListResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jobnote.domain.schedule.dto; - -import lombok.AccessLevel; -import lombok.Builder; - -import java.util.List; - -@Builder(access = AccessLevel.PRIVATE) -public record ScheduleListResponse( - List schedules -) { - public static ScheduleListResponse from(final List schedules) { - return ScheduleListResponse.builder() - .schedules(schedules) - .build(); - } -} diff --git a/src/main/java/com/jobnote/domain/schedule/repository/ScheduleRepository.java b/src/main/java/com/jobnote/domain/schedule/repository/ScheduleRepository.java index c04fdf8..f15323b 100644 --- a/src/main/java/com/jobnote/domain/schedule/repository/ScheduleRepository.java +++ b/src/main/java/com/jobnote/domain/schedule/repository/ScheduleRepository.java @@ -1,6 +1,8 @@ package com.jobnote.domain.schedule.repository; import com.jobnote.domain.schedule.domain.Schedule; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -10,7 +12,7 @@ public interface ScheduleRepository extends JpaRepository { /* 해당 유저의 일정 목록 조회 */ @Query("select s from Schedule s join fetch s.applicationForm af join fetch af.user where af.user.id = :userId and s.dateTime between :startDate and :endDate") - List findAllByUserIdAndDateTimeBetween(final Long userId, final LocalDateTime startDate, final LocalDateTime endDate); + Page findAllByUserIdAndDateTimeBetween(final Long userId, final LocalDateTime startDate, final LocalDateTime endDate, final Pageable pageable); /* 여러 지원서의 일정 목록 전체 조회 */ @Query("select s from Schedule s join fetch s.applicationForm af join fetch af.user where af.user.id = :userId and af.id in :formIds") diff --git a/src/main/java/com/jobnote/domain/schedule/service/ScheduleService.java b/src/main/java/com/jobnote/domain/schedule/service/ScheduleService.java index ef88ae3..a193f63 100644 --- a/src/main/java/com/jobnote/domain/schedule/service/ScheduleService.java +++ b/src/main/java/com/jobnote/domain/schedule/service/ScheduleService.java @@ -7,6 +7,8 @@ import com.jobnote.domain.schedule.repository.ScheduleRepository; import com.jobnote.global.exception.JobNoteException; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,10 +37,9 @@ public ScheduleResponse getById(final Long userId, final Long formId, final Long return ScheduleResponse.from(schedule); } - public List getAll(final Long userId, final LocalDateTime startDate, final LocalDateTime endDate) { - return scheduleRepository.findAllByUserIdAndDateTimeBetween(userId, startDate, endDate).stream() - .map(ScheduleResponse::from) - .toList(); + public Page getAll(final Long userId, final LocalDateTime startDate, final LocalDateTime endDate, final Pageable pageable) { + return scheduleRepository.findAllByUserIdAndDateTimeBetween(userId, startDate, endDate, pageable) + .map(ScheduleResponse::from); } public List getAllByApplicationFormId(final Long userId, final Long formId) { diff --git a/src/main/java/com/jobnote/global/annotation/swagger/PageableAsQueryParam.java b/src/main/java/com/jobnote/global/annotation/swagger/PageableAsQueryParam.java new file mode 100644 index 0000000..c63613a --- /dev/null +++ b/src/main/java/com/jobnote/global/annotation/swagger/PageableAsQueryParam.java @@ -0,0 +1,37 @@ +package com.jobnote.global.annotation.swagger; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Parameters({ + @Parameter( + in = ParameterIn.QUERY, + description = "0부터 시작하는 페이지 번호 (0..N)", + name = "page", + schema = @Schema(type = "integer", defaultValue = "0") + ), + @Parameter( + in = ParameterIn.QUERY, + description = "한 페이지에 포함될 항목 수", + name = "size", + schema = @Schema(type = "integer", defaultValue = "20") + ), + @Parameter( + in = ParameterIn.QUERY, + description = "정렬 기준 (property,(asc|desc)). 기본은 오름차순. 여러 기준 가능.", + name = "sort", + array = @ArraySchema(schema = @Schema(type = "string")) + ) +}) +public @interface PageableAsQueryParam { +} diff --git a/src/test/java/com/jobnote/domain/applicationform/service/ApplicationFormServiceTest.java b/src/test/java/com/jobnote/domain/applicationform/service/ApplicationFormServiceTest.java index f7aa6e6..7bc88eb 100644 --- a/src/test/java/com/jobnote/domain/applicationform/service/ApplicationFormServiceTest.java +++ b/src/test/java/com/jobnote/domain/applicationform/service/ApplicationFormServiceTest.java @@ -21,6 +21,9 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.test.util.ReflectionTestUtils; import java.time.LocalDateTime; @@ -83,15 +86,17 @@ void getAllApplicationForms() { ApplicationForm form2 = ApplicationForm.builder().user(user).companyName("카카오").status(DOCUMENT_PASSED).build(); List expectedResult = Arrays.asList(form1, form2); - given(applicationFormRepository.findAllByUserId(userId)).willReturn(expectedResult); + Page pageExpectedResult = new PageImpl<>(expectedResult); + given(applicationFormRepository.findAllByUserId(eq(userId), any(Pageable.class))).willReturn(pageExpectedResult); // when - List actualResult = applicationFormService.getAll(userId); + Page pageActualResult = applicationFormService.getAll(userId, Pageable.unpaged()); + List actualResult = pageActualResult.getContent(); // then assertThat(actualResult).hasSize(2); assertThat(actualResult.get(0).companyName()).isEqualTo("네이버"); - then(applicationFormRepository).should().findAllByUserId(userId); + then(applicationFormRepository).should().findAllByUserId(userId, Pageable.unpaged()); } @Test @@ -104,7 +109,8 @@ void getAllApplicationForms_withSchedules() { ReflectionTestUtils.setField(form2, "id", 2L); List forms = List.of(form1, form2); - given(applicationFormRepository.findAllByUserId(userId)).willReturn(forms); + Page pageForms = new PageImpl<>(forms); + given(applicationFormRepository.findAllByUserId(eq(userId), any(Pageable.class))).willReturn(pageForms); ScheduleResponse schedule1 = new ScheduleResponse(101L, "지원서 제출", "오전", LocalDateTime.of(2025, 8, 1, 10, 0), PLANNED); ScheduleResponse schedule2 = new ScheduleResponse(102L, "코딩테스트", "연습문제 풀이", LocalDateTime.of(2025, 8, 2, 9, 0), PLANNED); @@ -117,22 +123,22 @@ void getAllApplicationForms_withSchedules() { )); // when - List actualResult = applicationFormService.getAll(userId); + Page actualResult = applicationFormService.getAll(userId, Pageable.unpaged()); // then assertThat(actualResult).hasSize(2); - ApplicationFormResponse result1 = actualResult.get(0); + ApplicationFormResponse result1 = actualResult.getContent().get(0); assertThat(result1.companyName()).isEqualTo("네이버"); assertThat(result1.schedules()).hasSize(1); assertThat(result1.schedules().get(0).title()).isEqualTo("지원서 제출"); - ApplicationFormResponse result2 = actualResult.get(1); + ApplicationFormResponse result2 = actualResult.getContent().get(1); assertThat(result2.companyName()).isEqualTo("카카오"); assertThat(result2.schedules()).hasSize(2); assertThat(result2.schedules().get(0).title()).isEqualTo("코딩테스트"); - then(applicationFormRepository).should().findAllByUserId(userId); + then(applicationFormRepository).should().findAllByUserId(eq(userId), any(Pageable.class)); then(scheduleService).should().getAllGroupedByApplicationFormIds(eq(userId), eq(List.of(1L, 2L))); } @@ -146,7 +152,8 @@ void getAllApplicationForms_withDocuments() { ReflectionTestUtils.setField(form2, "id", 2L); List forms = List.of(form1, form2); - given(applicationFormRepository.findAllByUserId(userId)).willReturn(forms); + Page pageForms = new PageImpl<>(forms); + given(applicationFormRepository.findAllByUserId(eq(userId), any(Pageable.class))).willReturn(pageForms); DocumentSimpleResponse document1 = new DocumentSimpleResponse(101L, DocumentType.RESUME, "네이버 이력서"); DocumentSimpleResponse document2 = new DocumentSimpleResponse(102L, DocumentType.COVER_LETTER, "네이버 자소서"); @@ -159,22 +166,22 @@ void getAllApplicationForms_withDocuments() { )); // when - List actualResult = applicationFormService.getAll(userId); + Page actualResult = applicationFormService.getAll(userId, Pageable.unpaged()); // then assertThat(actualResult).hasSize(2); - ApplicationFormResponse result1 = actualResult.get(0); + ApplicationFormResponse result1 = actualResult.getContent().get(0); assertThat(result1.companyName()).isEqualTo("네이버"); assertThat(result1.documents()).hasSize(2); assertThat(result1.documents().get(0).title()).isEqualTo("네이버 이력서"); - ApplicationFormResponse result2 = actualResult.get(1); + ApplicationFormResponse result2 = actualResult.getContent().get(1); assertThat(result2.companyName()).isEqualTo("카카오"); assertThat(result2.documents()).hasSize(1); assertThat(result2.documents().get(0).title()).isEqualTo("카카오 이력서"); - then(applicationFormRepository).should().findAllByUserId(userId); + then(applicationFormRepository).should().findAllByUserId(eq(userId), any(Pageable.class)); then(applicationFormDocumentService).should().getSimpleResponsesGroupedByApplicationFormIds(eq(userId), eq(List.of(1L, 2L))); }