Skip to content

Commit

Permalink
[YS-173] refact: ExperimentPost의 recruitDone 컬럼명 변경 및 공고 전체 조회 API,…
Browse files Browse the repository at this point in the history
… 지역별 공고 개수 조회 API 로직 리팩터링 (#42)

* refact: rename recruitDone field name to recruitStatus

* refact: refact GetExperimentPosts logic due to renamed field and parameter

* fix: alter recruitStatus's default value

* refact: add recruitStatus condition to GetExperimentPostCountsByRegionUseCase

* refact: add recruitStatus condition to GetExperimentPostCountsByAreaUseCase

* test: fix failed test due to added condition

* refact: delete unused file and alter description

* refact: alter recruitStatus's parameter type
  • Loading branch information
Ji-soo708 authored Jan 19, 2025
1 parent d33193a commit fee3f17
Show file tree
Hide file tree
Showing 28 changed files with 190 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ object ExperimentMapper {
areas = it.areas
)
},
recruitDone = customFilter.recruitDone
recruitStatus = customFilter.recruitStatus
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import com.dobby.backend.application.usecase.UseCase
import com.dobby.backend.domain.gateway.experiment.ExperimentPostGateway
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Area
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Region
import com.dobby.backend.infrastructure.database.entity.enums.experiment.RecruitStatus
import jakarta.persistence.Tuple

class GetExperimentPostCountsByAreaUseCase(
private val experimentPostGateway: ExperimentPostGateway
) : UseCase<GetExperimentPostCountsByAreaUseCase.Input, GetExperimentPostCountsByAreaUseCase.Output> {

data class Input(
val region: String
val region: String,
val recruitStatus: RecruitStatus
)

data class Output(
Expand All @@ -27,8 +29,15 @@ class GetExperimentPostCountsByAreaUseCase(
override fun execute(input: Input): Output {
val region = Region.fromDisplayName(input.region)

val total = experimentPostGateway.countExperimentPostsByRegion(region)
val regionData = region.let { experimentPostGateway.countExperimentPostByRegionGroupedByArea(it) }
val total = when (input.recruitStatus) {
RecruitStatus.ALL -> experimentPostGateway.countExperimentPostsByRegion(region)
RecruitStatus.OPEN -> experimentPostGateway.countExperimentPostsByRegionAndRecruitStatus(region, true)
}

val regionData = when (input.recruitStatus) {
RecruitStatus.ALL -> region.let { experimentPostGateway.countExperimentPostByRegionGroupedByArea(it) }
RecruitStatus.OPEN -> region.let { experimentPostGateway.countExperimentPostByRegionAndRecruitStatusGroupedByArea(it, true) }
}
val areaCounts = getAreaCounts(region, regionData)

return Output(total, areaCounts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package com.dobby.backend.application.usecase.experiment
import com.dobby.backend.application.usecase.UseCase
import com.dobby.backend.domain.gateway.experiment.ExperimentPostGateway
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Region
import com.dobby.backend.infrastructure.database.entity.enums.experiment.RecruitStatus

class GetExperimentPostCountsByRegionUseCase(
private val experimentPostGateway: ExperimentPostGateway
) : UseCase<GetExperimentPostCountsByRegionUseCase.Input, GetExperimentPostCountsByRegionUseCase.Output> {

data class Input(
val region: String?
val region: String?,
val recruitStatus: RecruitStatus
)

data class Output(
Expand All @@ -23,10 +25,16 @@ class GetExperimentPostCountsByRegionUseCase(
)

override fun execute(input: Input): Output {
val total = experimentPostGateway.countExperimentPosts()
val total = when (input.recruitStatus) {
RecruitStatus.ALL -> experimentPostGateway.countExperimentPosts()
RecruitStatus.OPEN -> experimentPostGateway.countExperimentPostsByRecruitStatus(true)
}

val allRegions = Region.values().filter { it != Region.NONE }
val regionData = experimentPostGateway.countExperimentPostGroupedByRegion()
val regionData = when (input.recruitStatus) {
RecruitStatus.ALL -> experimentPostGateway.countExperimentPostGroupedByRegion()
RecruitStatus.OPEN -> experimentPostGateway.countExperimentPostsByRecruitStatusGroupedByRegion(true)
}
val regionDataMap = regionData.associateBy { it.get(0, Region::class.java) }

val area = allRegions.map { region ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fun ExperimentPost.toDetailResponse(memberId: Long?): ExperimentPostDetailRespon
uploadDate = this.createdAt.toLocalDate(),
uploaderName = this.member.name,
views = this.views,
recruitDone = this.recruitDone,
recruitStatus = this.recruitStatus,
summary = this.toSummaryResponse(),
targetGroup = this.targetGroup.toResponse(),
address = this.toAddressResponse(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.dobby.backend.infrastructure.database.entity.enums.GenderType
import com.dobby.backend.infrastructure.database.entity.enums.MatchType
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Area
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Region
import com.dobby.backend.infrastructure.database.entity.enums.experiment.RecruitStatus
import java.time.LocalDate

class GetExperimentPostsUseCase (
Expand All @@ -20,7 +21,7 @@ class GetExperimentPostsUseCase (
val matchType : MatchType?,
val studyTarget: StudyTargetInput?,
val locationTarget: LocationTargetInput?,
val recruitDone: Boolean?,
val recruitStatus: RecruitStatus,
)

data class StudyTargetInput(
Expand Down Expand Up @@ -48,7 +49,7 @@ class GetExperimentPostsUseCase (
val views: Int,
val univName: String,
val reward: String,
val recruitDone: Boolean,
val recruitStatus: Boolean,
val durationInfo: DurationInfoOutput
)

Expand All @@ -71,7 +72,7 @@ class GetExperimentPostsUseCase (
views = post.views,
univName = post.univName,
reward = post.reward,
recruitDone = post.recruitDone,
recruitStatus = post.recruitStatus,
durationInfo = DurationInfoOutput(
startDate = post.startDate,
endDate = post.endDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class GetMyExperimentPostsUseCase(
val title: String,
val content: String,
val views: Int,
val recruitDone: Boolean,
val recruitStatus: Boolean,
val uploadDate: LocalDate
)

Expand All @@ -42,7 +42,7 @@ class GetMyExperimentPostsUseCase(
title = post.title,
content = post.content,
views = post.views,
recruitDone = post.recruitDone,
recruitStatus = post.recruitStatus,
uploadDate = post.createdAt.toLocalDate()
)
} ?: emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ interface ExperimentPostGateway {
fun findExperimentPostsByCustomFilter(customFilter: CustomFilter, pagination: Pagination): List<ExperimentPost>?
fun findById(experimentPostId: Long): ExperimentPost?
fun countExperimentPostsByRegion(region: Region): Int
fun countExperimentPostsByRegionAndRecruitStatus(region: Region, recruitStatus: Boolean): Int
fun countExperimentPosts(): Int
fun countExperimentPostsByRecruitStatus(recruitStatus: Boolean): Int
fun countExperimentPostByRegionGroupedByArea(region: Region): List<Tuple>
fun countExperimentPostByRegionAndRecruitStatusGroupedByArea(region: Region, recruitStatus: Boolean): List<Tuple>
fun countExperimentPostGroupedByRegion(): List<Tuple>
fun updateExperimentPostStatus(todayDate : LocalDate) : Long
fun countExperimentPostsByRecruitStatusGroupedByRegion(recruitStatus: Boolean): List<Tuple>
fun updateExperimentPostStatus(currentDate : LocalDate) : Long
fun findExperimentPostsByMemberIdWithPagination(memberId: Long, pagination: Pagination, order: String): List<ExperimentPost>?
fun countExperimentPostsByMemberId(memberId: Long): Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import com.dobby.backend.infrastructure.database.entity.enums.GenderType
import com.dobby.backend.infrastructure.database.entity.enums.MatchType
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Area
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Region
import com.dobby.backend.infrastructure.database.entity.enums.experiment.RecruitStatus

data class CustomFilter(
val matchType: MatchType?,
val studyTarget: StudyTarget?,
val locationTarget: LocationTarget?,
val recruitDone: Boolean?
val recruitStatus: RecruitStatus
)
data class StudyTarget(
val gender: GenderType?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ data class ExperimentPost(
val area: Area,
val detailedAddress: String?,
val alarmAgree: Boolean,
val recruitDone: Boolean = false,
val recruitStatus: Boolean = true,
val images: List<ExperimentImage>,
var createdAt: LocalDateTime,
var updatedAt: LocalDateTime
Expand Down Expand Up @@ -59,7 +59,7 @@ data class ExperimentPost(
area: Area,
detailedAddress: String,
alarmAgree: Boolean,
recruitDone: Boolean,
recruitStatus: Boolean,
images: List<ExperimentImage>,
createdAt: LocalDateTime = LocalDateTime.now(),
updatedAt: LocalDateTime = LocalDateTime.now()
Expand All @@ -83,7 +83,7 @@ data class ExperimentPost(
area = area,
detailedAddress = detailedAddress,
alarmAgree = alarmAgree,
recruitDone = recruitDone,
recruitStatus = true,
images = images,
createdAt = createdAt,
updatedAt = updatedAt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.dobby.backend.infrastructure.database.entity.enums.experiment

import java.security.InvalidParameterException

enum class RecruitStatus {
ALL, OPEN;

companion object {
fun fromString(value: String): RecruitStatus {
return when (value) {
"ALL" -> ALL
"OPEN" -> OPEN
else -> throw InvalidParameterException()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ class ExperimentPostEntity(
@Column(name = "alarm_agree", nullable = false)
val alarmAgree: Boolean,

@Column(name = "recruit_done", nullable = false)
val recruitDone: Boolean = false,
@Column(name = "recruit_status", nullable = false)
val recruitStatus: Boolean = true,

@OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true)
@JoinColumn(name = "experiment_image_id")
Expand Down Expand Up @@ -111,7 +111,7 @@ class ExperimentPostEntity(
area = area,
detailedAddress = detailedAddress,
alarmAgree = alarmAgree,
recruitDone = recruitDone,
recruitStatus = recruitStatus,
images = images.map { it.toDomain() },
createdAt = createdAt,
updatedAt = updatedAt
Expand Down Expand Up @@ -139,7 +139,7 @@ class ExperimentPostEntity(
area = area,
detailedAddress = detailedAddress,
alarmAgree = alarmAgree,
recruitDone = recruitDone,
recruitStatus = recruitStatus,
images = images.map { ExperimentImageEntity.fromDomain(it) },
createdAt = createdAt,
updatedAt = updatedAt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.dobby.backend.infrastructure.database.entity.enums.MatchType
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Area
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Area.Companion.isAll
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Region
import com.dobby.backend.infrastructure.database.entity.enums.experiment.RecruitStatus
import com.dobby.backend.infrastructure.database.entity.experiment.ExperimentPostEntity
import com.dobby.backend.infrastructure.database.entity.experiment.QExperimentPostEntity
import com.querydsl.core.types.OrderSpecifier
Expand All @@ -24,6 +25,10 @@ class ExperimentPostCustomRepositoryImpl (
pagination: Pagination
): List<ExperimentPostEntity>? {
val post = QExperimentPostEntity.experimentPostEntity
val recruitStatusCondition = when (customFilter.recruitStatus) {
RecruitStatus.ALL -> null
RecruitStatus.OPEN -> post.recruitStatus.eq(true)
}

return jpaQueryFactory.selectFrom(post)
.join(post.targetGroup).fetchJoin()
Expand All @@ -34,7 +39,7 @@ class ExperimentPostCustomRepositoryImpl (
ageBetween(post, customFilter.studyTarget?.age),
regionEq(post, customFilter.locationTarget?.region),
areasIn(post, customFilter.locationTarget?.areas),
recruitDoneEq(post, customFilter.recruitDone)
recruitStatusCondition
)
.offset((pagination.page - 1L) * pagination.count)
.limit(pagination.count.toLong())
Expand Down Expand Up @@ -84,19 +89,19 @@ class ExperimentPostCustomRepositoryImpl (
}
}

private fun recruitDoneEq(post: QExperimentPostEntity, recruitDone: Boolean?): BooleanExpression? {
return recruitDone?.let { post.recruitDone.eq(it) }
private fun recruitStatusEq(post: QExperimentPostEntity, recruitStatus: Boolean?): BooleanExpression? {
return recruitStatus?.let { post.recruitStatus.eq(it) }
}

@Override
override fun updateExperimentPostStatus(currentDate: LocalDate): Long {
val experimentPost = QExperimentPostEntity.experimentPostEntity

return jpaQueryFactory.update(experimentPost)
.set(experimentPost.recruitDone, true)
.set(experimentPost.recruitStatus, true)
.where(
experimentPost.endDate.lt(currentDate)
.and(experimentPost.recruitDone.eq(false))
.and(experimentPost.recruitStatus.eq(false))
)
.execute()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,21 @@ import org.springframework.data.repository.query.Param
interface ExperimentPostRepository : JpaRepository<ExperimentPostEntity, Long> {
fun countByRegion(region: Region): Int

fun countByRegionAndRecruitStatus(region: Region, recruitStatus: Boolean): Int

@Query("SELECT e.area, COUNT(e) FROM experiment_post e WHERE e.region = :region GROUP BY e.area")
fun countExperimentPostByRegionGroupedByArea(@Param("region") region: Region): List<Tuple>

@Query("SELECT e.area, COUNT(e) FROM experiment_post e WHERE e.region = :region AND e.recruitStatus = :recruitStatus GROUP BY e.area")
fun countExperimentPostByRegionAndRecruitStatusGroupedByArea(region: Region, recruitStatus: Boolean): List<Tuple>

@Query("SELECT e.region, COUNT(e) FROM experiment_post e GROUP BY e.region")
fun countExperimentPostGroupedByRegion(): List<Tuple>

fun countByMemberId(memberId: Long): Int

fun countByRecruitStatus(recruitStatus: Boolean): Int

@Query("SELECT e.region, COUNT(e) FROM experiment_post e WHERE e.recruitStatus = :recruitStatus GROUP BY e.region")
fun countExperimentPostsByRecruitStatusGroupedByRegion(recruitStatus: Boolean): List<Tuple>
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,38 @@ class ExperimentPostGatewayImpl(
return experimentPostRepository.countByRegion(region)
}

override fun countExperimentPostsByRegionAndRecruitStatus(region: Region, recruitStatus: Boolean): Int {
return experimentPostRepository.countByRegionAndRecruitStatus(region, recruitStatus)
}

override fun countExperimentPosts(): Int {
return experimentPostRepository.count().toInt()
}

override fun countExperimentPostsByRecruitStatus(recruitStatus: Boolean): Int {
return experimentPostRepository.countByRecruitStatus(recruitStatus)
}

override fun countExperimentPostByRegionGroupedByArea(region: Region): List<Tuple> {
return experimentPostRepository.countExperimentPostByRegionGroupedByArea(region)
}

override fun countExperimentPostByRegionAndRecruitStatusGroupedByArea(region: Region, recruitStatus: Boolean): List<Tuple> {
return experimentPostRepository.countExperimentPostByRegionAndRecruitStatusGroupedByArea(region, recruitStatus)
}

override fun countExperimentPostGroupedByRegion(): List<Tuple> {
return experimentPostRepository.countExperimentPostGroupedByRegion()
}

override fun countExperimentPostsByRecruitStatusGroupedByRegion(recruitStatus: Boolean): List<Tuple> {
return experimentPostRepository.countExperimentPostsByRecruitStatusGroupedByRegion(recruitStatus)
}

override fun updateExperimentPostStatus(currentDate: LocalDate): Long {
return experimentPostCustomRepository.updateExperimentPostStatus(currentDate)
}

override fun findExperimentPostsByMemberIdWithPagination(
memberId: Long,
pagination: Pagination,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.dobby.backend.infrastructure.database.entity.enums.GenderType
import com.dobby.backend.infrastructure.database.entity.enums.MatchType
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Area
import com.dobby.backend.infrastructure.database.entity.enums.areaInfo.Region
import com.dobby.backend.infrastructure.database.entity.enums.experiment.RecruitStatus
import com.dobby.backend.presentation.api.dto.request.experiment.CreateExperimentPostRequest
import com.dobby.backend.presentation.api.dto.response.experiment.*
import com.dobby.backend.presentation.api.dto.response.experiment.CreateExperimentPostResponse
Expand Down Expand Up @@ -73,9 +74,10 @@ class ExperimentPostController (
description = "지역 별로 등록된 공고 수를 조회합니다"
)
fun getExperimentPostCounts(
@RequestParam(required = false) region: String?
@RequestParam(required = false) region: String?,
@RequestParam(required = false, defaultValue = "ALL") recruitStatus: RecruitStatus
): ExperimentPostCountsResponse {
val input = ExperimentPostMapper.toGetExperimentPostCountsUseCaseInput(region)
val input = ExperimentPostMapper.toGetExperimentPostCountsUseCaseInput(region, recruitStatus)
val output = experimentPostService.getExperimentPostCounts(input)
return ExperimentPostMapper.toGetExperimentPostCountsResponse(output)
}
Expand Down Expand Up @@ -104,11 +106,11 @@ class ExperimentPostController (
@RequestParam(required = false) age: Int?,
@RequestParam(required = false) region: Region?,
@RequestParam(required = false) areas: List<Area>?,
@RequestParam(required = false) recruitDone: Boolean?,
@RequestParam(required = false, defaultValue = "ALL") recruitStatus: RecruitStatus,
@RequestParam(defaultValue = "1") page: Int,
@RequestParam(defaultValue = "6") count: Int
): List<ExperimentPostsResponse> {
val customFilter = ExperimentPostMapper.toUseCaseCustomFilter(matchType, gender, age, region, areas, recruitDone)
val customFilter = ExperimentPostMapper.toUseCaseCustomFilter(matchType, gender, age, region, areas, recruitStatus)
val pagination = ExperimentPostMapper.toUseCasePagination(page, count)
val input = ExperimentPostMapper.toGetExperimentPostsUseCaseInput(customFilter, pagination)
val output = experimentPostService.getExperimentPosts(input)
Expand Down
Loading

0 comments on commit fee3f17

Please sign in to comment.