Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YS-173] refact: ExperimentPost의 recruitDone 컬럼명 변경 및 공고 전체 조회 API, 지역별 공고 개수 조회 API 로직 리팩터링 #42

Merged
merged 8 commits into from
Jan 19, 2025
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 @@ -38,7 +38,7 @@ fun ExperimentPost.toDetailResponse(): ExperimentPostDetailResponse {
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)
}
Comment on lines +28 to +31
Copy link
Member Author

@Ji-soo708 Ji-soo708 Jan 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 로직에서는 모집 중인 공고 / 모집 완료인 공고 둘로 나누어 진행이 되던데 기획 상으로는 모집 중인 공고 / 모든 공고 둘로 나누는 것이 맞다고 생각해 수정했습니다! 틀렸다면 알려주세요~

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CustomFilter에서는 기획 요청 상 ALLOPEN 으로 나누어보는 것이 맞는 것 같습니다. 👍👍


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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 enum값으로 정의한 recruitStatus 를 왜 쿼리 파라미터로 받아오실때는 String으로 받아오시는지 궁금합니다!

앞서 다른 Region 이나 Area 같이 다른 enum 클래스의 경우에는 그냥 enum의 형태로 파라미터를 가져왔어서요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 그 부분은 제가 놓치고 개발했었네요. Enum으로 수정하겠습니다! 감사합니다 👍

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
Loading