Skip to content

Commit

Permalink
feat: 추천 백신 조회 API (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
h-beeen authored Mar 22, 2024
1 parent 1411b78 commit 8b02c12
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ enum class AgeCondition(
AGE40TO49("만 40-49세", 0b001000),
AGE50TO59("만 50-59세", 0b000100),
AGE60TO64("만 60-64세", 0b000010),
AGEOVER65("만 65세 이상", 0b000001),
;
AGEOVER65("만 65세 이상", 0b000001);

fun isMatching(value: Int): Boolean {
return value and this.value == this.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class CustomRequestMatcher {

fun userEndpoints(): RequestMatcher {
return OrRequestMatcher(
AntPathRequestMatcher("/api/v1/inoculation/**")
AntPathRequestMatcher("/api/v1/inoculation/**"),
AntPathRequestMatcher("/api/v1/search/**"),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ interface InoculationRepository : JpaRepository<Inoculation, UUID> {
"and i.vaccination.vaccinationType = :vaccinationType")
fun findInoculationsByMemberIdAndVaccinationType(memberId: UUID, vaccinationType: VaccinationType): List<Inoculation>

@Query("select distinct i.vaccination.diseaseName " +
"from Inoculation i " +
"where i.member.id = :memberId")
fun findDistinctDiseaseNameByMemberId(memberId: UUID): List<String>

@Query("select i " +
"from Inoculation i " +
"where i.member.id = :memberId and i.vaccination.diseaseName = :diseaseName " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.vacgom.backend.presentation.search
import com.vacgom.backend.disease.application.dto.request.FilterRequest
import com.vacgom.backend.disease.domain.constants.AgeCondition
import com.vacgom.backend.disease.domain.constants.HealthCondition
import com.vacgom.backend.global.security.annotation.AuthId
import com.vacgom.backend.search.application.SearchService
import com.vacgom.backend.search.application.dto.DiseaseSearchResponse
import com.vacgom.backend.search.application.dto.VaccinationSearchResponse
Expand All @@ -11,6 +12,7 @@ import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.util.*

@RestController
@RequestMapping("/api/v1/search")
Expand All @@ -33,11 +35,11 @@ class SearchController(
fun vaccination(
@RequestBody body: FilterRequest,
): ResponseEntity<List<VaccinationSearchResponse>> {
return ResponseEntity.ok(
searchService.searchVaccination(
body.age.map { AgeCondition.valueOf(it) },
body.condition.map { HealthCondition.valueOf(it) },
),
)
return ResponseEntity.ok(searchService.searchVaccination(body))
}

@GetMapping("/recommend")
fun recommendVaccination(@AuthId id: UUID): ResponseEntity<List<VaccinationSearchResponse>> {
return ResponseEntity.ok(searchService.searchRecommendVaccination(id))
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package com.vacgom.backend.search.application

import com.vacgom.backend.disease.application.DiseaseService
import com.vacgom.backend.disease.application.dto.request.FilterRequest
import com.vacgom.backend.disease.domain.Disease
import com.vacgom.backend.disease.domain.constants.AgeCondition
import com.vacgom.backend.disease.domain.constants.HealthCondition
import com.vacgom.backend.global.exception.error.BusinessException
import com.vacgom.backend.inoculation.domain.Vaccination
import com.vacgom.backend.inoculation.infrastructure.persistence.InoculationRepository
import com.vacgom.backend.inoculation.infrastructure.persistence.VaccinationRepository
import com.vacgom.backend.member.exception.MemberError
import com.vacgom.backend.member.infrastructure.persistence.MemberRepository
import com.vacgom.backend.search.application.dto.DiseaseSearchResponse
import com.vacgom.backend.search.application.dto.VaccinationSearchResponse
import org.springframework.stereotype.Service
import java.util.*


@Service
class SearchService(
val vaccinationRepository: VaccinationRepository,
val inoculationRepository: InoculationRepository,
val memberRepository: MemberRepository,
val diseaseService: DiseaseService,
) {
private fun findAllVaccinations(): List<Vaccination> {
Expand All @@ -31,17 +40,38 @@ class SearchService(
}

fun searchVaccination(
age: List<AgeCondition>,
condition: List<HealthCondition>,
request: FilterRequest,
): List<VaccinationSearchResponse> {
val age = request.age.map { AgeCondition.valueOf(it) }
val condition = request.condition.map { HealthCondition.valueOf(it) }
val diseases = this.searchDisease(age, condition)
val vaccinations = findAllVaccinations()

return vaccinations.filter {
diseases.any { disease -> it.diseaseName.contains(disease.name) }
}.map { VaccinationSearchResponse.of(it) }
return filterByDisease(vaccinations, diseases)
}

fun searchRecommendVaccination(memberId: UUID): List<VaccinationSearchResponse> {
val ageCondition = AgeCondition.AGE19TO29

val vaccinations = findAllVaccinations()
val inoculatedDiseaseName = inoculationRepository.findDistinctDiseaseNameByMemberId(memberId).flatMap { it.split("·") }.toSet()
val recommendedVaccinations = vaccinations.filter { vaccination -> !inoculatedDiseaseName.contains(vaccination.vaccineName) }

val healthProfiles = memberRepository.findById(memberId).orElseThrow {
BusinessException(MemberError.NOT_FOUND)
}.healthProfiles.map { it.healthCondition }.toList()

val diseases = this.searchDisease(listOf(ageCondition), healthProfiles).filter { response ->
!inoculatedDiseaseName.contains(response.name)
}.toList()
return filterByDisease(recommendedVaccinations, diseases)
}

private fun filterByDisease(vaccinations: List<Vaccination>, diseases: List<DiseaseSearchResponse>) =
vaccinations.filter {
diseases.any { disease -> it.diseaseName.contains(disease.name) }
}.map { VaccinationSearchResponse.of(it) }

fun isMatched(
disease: Disease,
age: List<AgeCondition>,
Expand Down

0 comments on commit 8b02c12

Please sign in to comment.