From bf3684da63140cf7710246258019fdb2a0a97e47 Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:49:11 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat=20:=20JD=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EB=94=94=EB=8D=B0=EC=9D=B4=20=EA=B3=84=EC=82=B0=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/jobDescription/aggregate/JobDescription.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/aggregate/JobDescription.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/aggregate/JobDescription.kt index 3322b091..a704785a 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/aggregate/JobDescription.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/aggregate/JobDescription.kt @@ -26,6 +26,10 @@ data class JobDescription( require(startedAt.isBefore(endedAt)) { "시작일은 종료일보다 빨라야 합니다." } } + fun getRemainingDate(): Int { + return LocalDateTime.now().until(endedAt, java.time.temporal.ChronoUnit.DAYS).toInt() + } + companion object { fun create( enterpriseName: String, From d024c0258ed4fd1c1bd806a73141985c7b1900e6 Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:49:28 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat=20:=20Slice=20=EC=B6=94=EC=83=81?= =?UTF-8?q?=ED=99=94=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1(#6?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domainmodule/common/pagination/SliceDomain.kt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/common/pagination/SliceDomain.kt diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/common/pagination/SliceDomain.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/common/pagination/SliceDomain.kt new file mode 100644 index 00000000..228634d0 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/common/pagination/SliceDomain.kt @@ -0,0 +1,8 @@ +package com.bamyanggang.domainmodule.common.pagination + +data class SliceDomain( + val content: List, + val pageNumber: Int, + val pageSize: Int, + val hasNext: Boolean +) From f50505a37a2a99d8bc88f2333efcb5417e0a89af Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:49:59 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat=20:=20=EC=9E=91=EC=84=B1=20=EC=83=81?= =?UTF-8?q?=ED=83=9C,=20=EC=A0=95=EB=A0=AC=20=EA=B8=B0=EC=A4=80=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20enum=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domainmodule/domain/jobDescription/enums/SortType.kt | 6 ++++++ .../domainmodule/domain/jobDescription/enums/WriteStatus.kt | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/SortType.kt diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/SortType.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/SortType.kt new file mode 100644 index 00000000..034c9ec7 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/SortType.kt @@ -0,0 +1,6 @@ +package com.bamyanggang.domainmodule.domain.jobDescription.enums + +enum class SortType { + CREATED, // 등록순 + ENDED // 마감순 +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/WriteStatus.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/WriteStatus.kt index 3e4edbad..3423ccd5 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/WriteStatus.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/enums/WriteStatus.kt @@ -3,5 +3,6 @@ package com.bamyanggang.domainmodule.domain.jobDescription.enums enum class WriteStatus { WRITING, WRITTEN, - CLOSED + CLOSED, + NOT_APPLIED } From a69412be5d7cc94d3e3c15284ab0052183da53fe Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:50:41 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat=20:=20JD=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A6=AC=ED=8F=AC=EC=A7=80?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=83=9D=EC=84=B1(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/jobDescription/repository/ApplyRepository.kt | 3 +++ .../jobDescription/repository/JobDescriptionRepository.kt | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/ApplyRepository.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/ApplyRepository.kt index 0a0d510e..04d706c3 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/ApplyRepository.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/ApplyRepository.kt @@ -1,8 +1,11 @@ package com.bamyanggang.domainmodule.domain.jobDescription.repository import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.Apply +import java.util.* interface ApplyRepository { fun save(apply: Apply) + fun findByJobDescriptionId(jobDescriptionId: UUID): Apply? + } diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/JobDescriptionRepository.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/JobDescriptionRepository.kt index c559ca0f..abd3e400 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/JobDescriptionRepository.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/repository/JobDescriptionRepository.kt @@ -1,9 +1,15 @@ package com.bamyanggang.domainmodule.domain.jobDescription.repository +import com.bamyanggang.domainmodule.common.pagination.SliceDomain import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.JobDescription +import java.util.* interface JobDescriptionRepository { fun save(jobDescription: JobDescription) + fun findAllByUserIdAndSortByCreatedAt(userId: UUID, page: Int, size: Int): SliceDomain + + fun findAllByUserId(userId: UUID, page: Int, size: Int): SliceDomain + } From 76cf594c317dfd3ffebf555710779194eeebb22c Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:52:50 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat=20:=20JD=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jobDescription/service/ApplyReader.kt | 17 ++++++++++++ .../service/JobDescriptionReader.kt | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/ApplyReader.kt create mode 100644 Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/JobDescriptionReader.kt diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/ApplyReader.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/ApplyReader.kt new file mode 100644 index 00000000..705100b6 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/ApplyReader.kt @@ -0,0 +1,17 @@ +package com.bamyanggang.domainmodule.domain.jobDescription.service + +import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.Apply +import com.bamyanggang.domainmodule.domain.jobDescription.repository.ApplyRepository +import org.springframework.stereotype.Service +import java.util.* + +@Service +class ApplyReader( + private val applyRepository: ApplyRepository +) { + + fun readApplyByJobDescriptionId(JobDescriptionId: UUID): Apply?{ + return applyRepository.findByJobDescriptionId(JobDescriptionId) + } + +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/JobDescriptionReader.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/JobDescriptionReader.kt new file mode 100644 index 00000000..01bb6dd6 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/jobDescription/service/JobDescriptionReader.kt @@ -0,0 +1,26 @@ +package com.bamyanggang.domainmodule.domain.jobDescription.service + +import com.bamyanggang.domainmodule.common.pagination.SliceDomain +import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.JobDescription +import com.bamyanggang.domainmodule.domain.jobDescription.enums.SortType +import com.bamyanggang.domainmodule.domain.jobDescription.repository.JobDescriptionRepository +import org.springframework.stereotype.Service +import java.util.* + +@Service +class JobDescriptionReader( + private val jobDescriptionRepository: JobDescriptionRepository +) { + /** + * TODO: 마감순 필터링 추가 + */ + fun readJobDescriptionByUserIdAndSortType(userId: UUID, page: Int, size: Int, sortType: SortType?): SliceDomain { + return when(sortType) { + SortType.CREATED -> jobDescriptionRepository.findAllByUserIdAndSortByCreatedAt(userId, page, size) +// SortType.ENDED -> jobDescriptionRepository.findAllByUserIdWithApply(userId, pageable) + else -> jobDescriptionRepository.findAllByUserId(userId, page, size) + } + } + + +} From c6801a25a5cbb846dc16da9d122e3921d1ee4907 Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:53:53 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat=20:=20JD=20=EC=A1=B0=ED=9A=8C=20Persis?= =?UTF-8?q?tence=20=EA=B3=84=EC=B8=B5=20=EC=83=9D=EC=84=B1(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jobDescription/ApplyRepositoryImpl.java | 8 +++++ .../JobDescriptionRepositoryImpl.java | 33 +++++++++++++++++++ .../jpa/repository/ApplyJpaRepository.java | 4 +++ .../JobDescriptionJpaRepository.java | 8 +++++ .../persistence/user/TokenRepositoryImpl.java | 2 +- 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/ApplyRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/ApplyRepositoryImpl.java index d5922621..4e4a5dff 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/ApplyRepositoryImpl.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/ApplyRepositoryImpl.java @@ -2,9 +2,11 @@ import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.Apply; import com.bamyanggang.domainmodule.domain.jobDescription.repository.ApplyRepository; +import com.bamyanggang.persistence.common.exception.PersistenceException; import com.bamyanggang.persistence.jobDescription.jpa.entity.ApplyJpaEntity; import com.bamyanggang.persistence.jobDescription.jpa.repository.ApplyJpaRepository; import com.bamyanggang.persistence.jobDescription.mapper.JobDescriptionMapper; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -20,4 +22,10 @@ public void save(Apply apply) { applyJpaRepository.save(applyJpaEntity); } + @Override + public Apply findByJobDescriptionId(UUID jobDescriptionId) { + return applyJpaRepository.findByJobDescriptionId(jobDescriptionId) + .map(jobDescriptionMapper::toApplyDomainEntity) + .orElse(null); + } } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/JobDescriptionRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/JobDescriptionRepositoryImpl.java index 47c56db5..bd54c1d1 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/JobDescriptionRepositoryImpl.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/JobDescriptionRepositoryImpl.java @@ -1,11 +1,15 @@ package com.bamyanggang.persistence.jobDescription; +import com.bamyanggang.domainmodule.common.pagination.SliceDomain; import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.JobDescription; import com.bamyanggang.domainmodule.domain.jobDescription.repository.JobDescriptionRepository; import com.bamyanggang.persistence.jobDescription.jpa.entity.JobDescriptionJpaEntity; import com.bamyanggang.persistence.jobDescription.jpa.repository.JobDescriptionJpaRepository; import com.bamyanggang.persistence.jobDescription.mapper.JobDescriptionMapper; +import java.util.UUID; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.stereotype.Repository; @Repository @@ -20,4 +24,33 @@ public void save(JobDescription jobDescription) { jobDescriptionJpaRepository.save(jobDescriptionJpaEntity); } + @Override + public SliceDomain findAllByUserIdAndSortByCreatedAt(UUID userId, int page, int size) { + Pageable pageable = Pageable.ofSize(size).withPage(page); + Slice jobDescriptionJpaEntitySlice = jobDescriptionJpaRepository.findAllByUserIdOrderByCreatedAtDesc(userId, pageable); + Slice jobDescriptionSlice = jobDescriptionJpaEntitySlice.map(jobDescriptionMapper::toDomainEntity); + return new SliceDomain<>(jobDescriptionSlice.getContent(), jobDescriptionSlice.getNumber(), jobDescriptionSlice.getSize(), jobDescriptionSlice.hasNext()); + } + + @Override + public SliceDomain findAllByUserId(UUID userId, int page, int size) { + Pageable pageable = Pageable.ofSize(size).withPage(page); + Slice jobDescriptionJpaEntitySlice = jobDescriptionJpaRepository.findAllByUserIdOrderByCreatedAtDesc(userId, pageable); + Slice jobDescriptionSlice = jobDescriptionJpaEntitySlice.map(jobDescriptionMapper::toDomainEntity); + return new SliceDomain<>(jobDescriptionSlice.getContent(), jobDescriptionSlice.getNumber(), jobDescriptionSlice.getSize(), jobDescriptionSlice.hasNext()); + } + +// @Override +// public Slice findAllByUserIdAndSortByCreatedAt(UUID userId, Integer page, Integer size) { +// Pageable pageable = Pageable.ofSize(size).withPage(page); +// Slice jobDescriptionJpaEntitySlice = jobDescriptionJpaRepository.findAllByUserIdOrderByCreatedAtDesc(userId, pageable); +// return jobDescriptionJpaEntitySlice.map(jobDescriptionMapper::toDomainEntity); +// } +// +// @Override +// public Slice findAllByUserIdAndSortType(UUID userId, Pageable pageable) { +// Slice jobDescriptionJpaEntitySlice = jobDescriptionJpaRepository.findAllByUserId(userId, pageable); +// return jobDescriptionJpaEntitySlice.map(jobDescriptionMapper::toDomainEntity); +// } + } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/ApplyJpaRepository.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/ApplyJpaRepository.java index d98aaec0..4c5092f6 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/ApplyJpaRepository.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/ApplyJpaRepository.java @@ -1,8 +1,12 @@ package com.bamyanggang.persistence.jobDescription.jpa.repository; import com.bamyanggang.persistence.jobDescription.jpa.entity.ApplyJpaEntity; +import java.util.Optional; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; public interface ApplyJpaRepository extends JpaRepository { + + Optional findByJobDescriptionId(UUID jobDescriptionId); + } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/JobDescriptionJpaRepository.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/JobDescriptionJpaRepository.java index 16050490..9949b75f 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/JobDescriptionJpaRepository.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/jobDescription/jpa/repository/JobDescriptionJpaRepository.java @@ -2,7 +2,15 @@ import com.bamyanggang.persistence.jobDescription.jpa.entity.JobDescriptionJpaEntity; import java.util.UUID; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; public interface JobDescriptionJpaRepository extends JpaRepository { + + Slice findAllByUserId(UUID userId, Pageable pageable); + + Slice findAllByUserIdOrderByCreatedAtDesc(UUID userId, Pageable pageable); + + } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/user/TokenRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/user/TokenRepositoryImpl.java index 4abb9d57..bd303b05 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/user/TokenRepositoryImpl.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/user/TokenRepositoryImpl.java @@ -29,7 +29,7 @@ public void deleteByValue(Token token) { } @Override - public Token findByValue(@NotNull String value) { + public Token findByValue(String value) { TokenJpaEntity tokenJpaEntity = tokenJpaRepository.findByValue(value) .orElseThrow(() -> new PersistenceException.NotFound()); return userMapper.toDomainEntity(tokenJpaEntity); From 15c3ef6e2fbf9ccfa499587779e67d59bc387b6e Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:54:34 +0900 Subject: [PATCH 7/9] =?UTF-8?q?feat=20:=20JD=20=EC=A1=B0=ED=9A=8C=20applic?= =?UTF-8?q?ation=20=EA=B3=84=EC=B8=B5=20=EC=83=9D=EC=84=B1,=20SliceRespons?= =?UTF-8?q?e=20=EC=83=9D=EC=84=B1(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apimodule/common/dto/SliceResponse.kt | 21 ++++++++ .../application/dto/GetJobDescriptionInfo.kt | 20 ++++++++ .../service/JobDescriptionInfoGetService.kt | 48 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 Api-Module/src/main/kotlin/com/bamyanggang/apimodule/common/dto/SliceResponse.kt create mode 100644 Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/dto/GetJobDescriptionInfo.kt create mode 100644 Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionInfoGetService.kt diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/common/dto/SliceResponse.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/common/dto/SliceResponse.kt new file mode 100644 index 00000000..7d6404de --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/common/dto/SliceResponse.kt @@ -0,0 +1,21 @@ +package com.bamyanggang.apimodule.common.dto + +import com.bamyanggang.domainmodule.common.pagination.SliceDomain + +data class SliceResponse( + val content: List, + val page: Int, + val size: Int, + val hasNext: Boolean +) { + companion object { + fun from(slice: SliceDomain): SliceResponse { + return SliceResponse( + content = slice.content, + page = slice.pageNumber, + size = slice.pageSize, + hasNext = slice.hasNext + ) + } + } +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/dto/GetJobDescriptionInfo.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/dto/GetJobDescriptionInfo.kt new file mode 100644 index 00000000..b5ce7963 --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/dto/GetJobDescriptionInfo.kt @@ -0,0 +1,20 @@ +package com.bamyanggang.apimodule.domain.jobDescription.application.dto + +import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus +import java.time.LocalDateTime +import java.util.UUID + +class GetJobDescriptionInfo { + + data class Response( + val jobDescriptionId: UUID, + val remainingDate: Int, + val enterpriseName: String, + val title: String, + val writeStatus: WriteStatus, + val createdAt: LocalDateTime, + val startedAt: LocalDateTime, + val endedAt: LocalDateTime, + ) + +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionInfoGetService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionInfoGetService.kt new file mode 100644 index 00000000..7acadeb5 --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionInfoGetService.kt @@ -0,0 +1,48 @@ +package com.bamyanggang.apimodule.domain.jobDescription.application.service + +import com.bamyanggang.apimodule.common.dto.SliceResponse +import com.bamyanggang.apimodule.common.getAuthenticationPrincipal +import com.bamyanggang.apimodule.domain.jobDescription.application.dto.GetJobDescriptionInfo +import com.bamyanggang.domainmodule.common.pagination.SliceDomain +import com.bamyanggang.domainmodule.domain.jobDescription.enums.SortType +import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus +import com.bamyanggang.domainmodule.domain.jobDescription.service.ApplyReader +import com.bamyanggang.domainmodule.domain.jobDescription.service.JobDescriptionReader +import org.springframework.data.domain.Pageable +import org.springframework.data.domain.SliceImpl +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + + +@Service +class JobDescriptionInfoGetService( + private val jobDescriptionReader: JobDescriptionReader, + private val applyReader: ApplyReader +) { + + @Transactional(readOnly = true) + fun getJobDescriptionInfo(pageable: Pageable, writeStatus: WriteStatus?, sortType: SortType?): SliceResponse { + return getAuthenticationPrincipal().let{ userId -> + val jobDescriptions = jobDescriptionReader.readJobDescriptionByUserIdAndSortType(userId, pageable.pageNumber, pageable.pageSize, sortType) + + val jobDescriptionInfoResponses = jobDescriptions.content.map{ jobDescription -> + val apply = applyReader.readApplyByJobDescriptionId(jobDescription.id) + GetJobDescriptionInfo.Response( + jobDescription.id, + jobDescription.getRemainingDate(), + jobDescription.enterpriseName, + jobDescription.title, + apply?.writeStatus?: WriteStatus.NOT_APPLIED, + jobDescription.createdAt, + jobDescription.startedAt, + jobDescription.endedAt + ) + } + + val jobDescriptionsSlice = SliceDomain(jobDescriptionInfoResponses, jobDescriptions.pageNumber, jobDescriptions.pageSize, jobDescriptions.hasNext) + SliceResponse.from(jobDescriptionsSlice) + } + } + + +} From a823502749cda138ccc4c357d84b9827088b5605 Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:54:51 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat=20:=20JD=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EC=8A=A4=ED=8E=99=20=EC=A0=95=EC=9D=98(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/JobDescriptionApi.kt | 1 + .../presentation/JobDescriptionController.kt | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionApi.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionApi.kt index 9ee7d5fa..95a7c506 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionApi.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionApi.kt @@ -3,4 +3,5 @@ package com.bamyanggang.apimodule.domain.jobDescription.presentation object JobDescriptionApi { const val BASE_URL = "/api/job-description" const val APPLY = "${BASE_URL}/apply/{jobDescriptionId}" + } diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionController.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionController.kt index af2572a3..50521e7c 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionController.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionController.kt @@ -1,19 +1,28 @@ package com.bamyanggang.apimodule.domain.jobDescription.presentation +import com.bamyanggang.apimodule.common.dto.SliceResponse import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApply import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateJobDescription +import com.bamyanggang.apimodule.domain.jobDescription.application.dto.GetJobDescriptionInfo import com.bamyanggang.apimodule.domain.jobDescription.application.service.ApplyCreateService import com.bamyanggang.apimodule.domain.jobDescription.application.service.JobDescriptionCreateService +import com.bamyanggang.apimodule.domain.jobDescription.application.service.JobDescriptionInfoGetService +import com.bamyanggang.domainmodule.domain.jobDescription.enums.SortType +import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus +import org.springframework.data.domain.Pageable +import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController import java.util.UUID @RestController class JobDescriptionController( private val jobDescriptionCreateService: JobDescriptionCreateService, - private val applyCreateService: ApplyCreateService + private val applyCreateService: ApplyCreateService, + private val jobDescriptionInfoGetService: JobDescriptionInfoGetService ) { @PostMapping(JobDescriptionApi.BASE_URL) @@ -27,4 +36,13 @@ class JobDescriptionController( @RequestBody request: CreateApply.Request ) = applyCreateService.createApply(request, jobDescriptionId) + @GetMapping(JobDescriptionApi.BASE_URL) + fun getJobDescription( + pageable: Pageable, + @RequestParam writeStatus: WriteStatus?, + @RequestParam sortType: SortType? + ): SliceResponse { + return jobDescriptionInfoGetService.getJobDescriptionInfo(pageable, writeStatus, sortType) + } + } From 29765f3722c55b8aa29ddfe18a42bd8f1d1c5e78 Mon Sep 17 00:00:00 2001 From: seeunjang Date: Sun, 19 May 2024 12:55:18 +0900 Subject: [PATCH 9/9] =?UTF-8?q?test=20:=20JD=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1,=20=EB=AA=85=EC=84=B8=20=EB=B0=98=EC=98=81(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/docs/asciidoc/JobDescription.adoc | 4 +- .../JobDescriptionControllerTest.kt | 94 ++++++++++++++++++- 2 files changed, 92 insertions(+), 6 deletions(-) diff --git a/Api-Module/src/docs/asciidoc/JobDescription.adoc b/Api-Module/src/docs/asciidoc/JobDescription.adoc index 64d642e2..bfa7047f 100644 --- a/Api-Module/src/docs/asciidoc/JobDescription.adoc +++ b/Api-Module/src/docs/asciidoc/JobDescription.adoc @@ -31,7 +31,9 @@ operation::JobDescriptionControllerTest/createApplyWithEmptyTitle[snippets='http operation::JobDescriptionControllerTest/createApplyWithEmptyContent[snippets='http-request,request-headers,http-response'] +[[GET-JD-LIST]] +=== JD 목록 조회 - +operation::JobDescriptionControllerTest/getJobDescription[snippets='http-request,request-headers,query-parameters,http-response,response-fields'] diff --git a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionControllerTest.kt b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionControllerTest.kt index 005e4fa1..d37e4c81 100644 --- a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionControllerTest.kt +++ b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/jobDescription/presentation/JobDescriptionControllerTest.kt @@ -1,27 +1,38 @@ package com.bamyanggang.apimodule.domain.jobDescription.presentation import com.bamyanggang.apimodule.BaseRestDocsTest +import com.bamyanggang.apimodule.common.dto.SliceResponse import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApply import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApplyContent import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateJobDescription +import com.bamyanggang.apimodule.domain.jobDescription.application.dto.GetJobDescriptionInfo import com.bamyanggang.apimodule.domain.jobDescription.application.service.ApplyCreateService import com.bamyanggang.apimodule.domain.jobDescription.application.service.JobDescriptionCreateService +import com.bamyanggang.apimodule.domain.jobDescription.application.service.JobDescriptionInfoGetService import com.bamyanggang.commonmodule.exception.ExceptionHandler import com.bamyanggang.commonmodule.fixture.generateFixture +import com.bamyanggang.domainmodule.common.pagination.SliceDomain +import com.bamyanggang.domainmodule.domain.jobDescription.enums.SortType +import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus +import io.kotest.assertions.print.printWithType import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.mockito.BDDMockito.given -import org.springframework.http.MediaType import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.context.annotation.Import +import org.springframework.data.domain.PageRequest +import org.springframework.data.domain.Slice +import org.springframework.data.domain.SliceImpl +import org.springframework.http.MediaType import org.springframework.restdocs.headers.HeaderDocumentation.headerWithName import org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders import org.springframework.restdocs.payload.PayloadDocumentation.* +import org.springframework.restdocs.request.RequestDocumentation import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import java.time.LocalDateTime -import java.util.UUID +import java.util.* @WebMvcTest(JobDescriptionController::class) @Import(ExceptionHandler::class) @@ -29,9 +40,13 @@ class JobDescriptionControllerTest : BaseRestDocsTest() { @MockBean private lateinit var jobDescriptionCreateService: JobDescriptionCreateService + @MockBean private lateinit var applyCreateService: ApplyCreateService + @MockBean + private lateinit var jobDescriptionInfoGetService: JobDescriptionInfoGetService + @Test @DisplayName("직무 공고를 등록한다.") fun createJobDescription() { @@ -48,7 +63,9 @@ class JobDescriptionControllerTest : BaseRestDocsTest() { it.set("jobDescriptionId", UUID.randomUUID()) } - given(jobDescriptionCreateService.createJobDescription(createJobDescriptionRequest)).willReturn(createJobDescriptionResponse) + given(jobDescriptionCreateService.createJobDescription(createJobDescriptionRequest)).willReturn( + createJobDescriptionResponse + ) val request = RestDocumentationRequestBuilders.post(JobDescriptionApi.BASE_URL) .header("Authorization", "Bearer Access Token") @@ -91,7 +108,9 @@ class JobDescriptionControllerTest : BaseRestDocsTest() { it.set("endedAt", LocalDateTime.now()) } - given(jobDescriptionCreateService.createJobDescription(createJobDescriptionRequest)).willThrow(IllegalArgumentException("내용은 필수입니다.")) + given(jobDescriptionCreateService.createJobDescription(createJobDescriptionRequest)).willThrow( + IllegalArgumentException("내용은 필수입니다.") + ) val request = RestDocumentationRequestBuilders.post(JobDescriptionApi.BASE_URL) .header("Authorization", "Bearer Access Token") @@ -129,7 +148,9 @@ class JobDescriptionControllerTest : BaseRestDocsTest() { it.set("endedAt", LocalDateTime.now().minusDays(1)) } - given(jobDescriptionCreateService.createJobDescription(createJobDescriptionRequest)).willThrow(IllegalArgumentException("시작일은 종료일보다 빨라야 합니다.")) + given(jobDescriptionCreateService.createJobDescription(createJobDescriptionRequest)).willThrow( + IllegalArgumentException("시작일은 종료일보다 빨라야 합니다.") + ) val request = RestDocumentationRequestBuilders.post(JobDescriptionApi.BASE_URL) .header("Authorization", "Bearer Access Token") @@ -224,4 +245,67 @@ class JobDescriptionControllerTest : BaseRestDocsTest() { ) } + @Test + @DisplayName("JD 공고를 조회한다") + fun getJobDescription() { + // given + val pageRequest = PageRequest.of(0, 6) + val getJobDescriptionInfoResponse: GetJobDescriptionInfo.Response = generateFixture { + it.set("jobDescriptionId", UUID.randomUUID()) + it.set("remainingDate", 1) + it.set("enterpriseName", "기업 이름") + it.set("title", "직무 공고 제목") + it.set("writeStatus", WriteStatus.WRITING) + it.set("createdAt", LocalDateTime.now()) + it.set("startedAt", LocalDateTime.now()) + it.set("endedAt", LocalDateTime.now()) } + + val slice = SliceDomain(listOf(getJobDescriptionInfoResponse), 0, 1, true) + val sliceResponse = SliceResponse.from(slice) + given(jobDescriptionInfoGetService.getJobDescriptionInfo(pageRequest, WriteStatus.WRITING, SortType.ENDED)).willReturn(sliceResponse) + + + val request = RestDocumentationRequestBuilders.get(JobDescriptionApi.BASE_URL) + .header("Authorization", "Bearer Access Token") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .queryParam("page", pageRequest.pageNumber.toString()) + .queryParam("size", pageRequest.pageSize.toString()) + .queryParam("writeStatus", WriteStatus.WRITING.toString()) + .queryParam("sortType", SortType.ENDED.toString()) + + //when + val result = mockMvc.perform(request) + + //then + result.andExpect(status().isOk) + .andDo( + resultHandler.document( + requestHeaders( + headerWithName("Authorization").description("엑세스 토큰") + ), + RequestDocumentation.queryParameters( + RequestDocumentation.parameterWithName("page").description("요청 페이지"), + RequestDocumentation.parameterWithName("size").description("요청 사이즈"), + RequestDocumentation.parameterWithName("writeStatus") + .description("작성 상태. NOT_APPLIED(칩 없음, 작성 전), WRITING(작성 중), WRITTEN(작성 완료), CLOSED(마감)"), + RequestDocumentation.parameterWithName("sortType") + .description("정렬 타입 CREATED(등록순), ENDED(마감순)"), + ), + responseFields( + fieldWithPath("content[].jobDescriptionId").description("직무 공고 ID"), + fieldWithPath("content[].remainingDate").description("디데이"), + fieldWithPath("content[].enterpriseName").description("기업 이름"), + fieldWithPath("content[].title").description("직무 공고 제목"), + fieldWithPath("content[].writeStatus").description("작성 상태. NOT_APPLIED(칩 없음, 작성 전), WRITING(작성 중), WRITTEN(작성 완료), CLOSED(마감)"), + fieldWithPath("content[].createdAt").description("생성일"), + fieldWithPath("content[].startedAt").description("시작일"), + fieldWithPath("content[].endedAt").description("종료일"), + fieldWithPath("page").description("요청 페이지"), + fieldWithPath("size").description("요청 사이즈"), + fieldWithPath("hasNext").description("다음 데이터 존재 여부") + ) + ) + ) + } + }