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

feat: 북마크 여부 포함 경험 전체 조회 API 구현 #136

Merged
merged 25 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f3118af
chore: 트랜잭션 추가 및 API 명세 누락 추가(#115)
whereami2048 May 20, 2024
15e6a7c
feat: 경험 id 리스트 조회 기능 구현(#115)
whereami2048 May 20, 2024
253c09b
feat: 북마크 조회 기능 구현(직무 공고, 상태 기준)(#115)
whereami2048 May 20, 2024
7f033e4
feat: 북마크한 경험 조회 APi 구현(#115)
whereami2048 May 20, 2024
e211d19
feat: JD id & 상태 별 북마크 조회 기능 구현(#115)
whereami2048 May 21, 2024
3709f5c
feat: 북마크 Boolean 상태 값 추가(#115)
whereami2048 May 21, 2024
20d0956
feat: 북마크 경험 전체 조회 API 구현(#115)
whereami2048 May 21, 2024
7671660
feat: 경험 검색 API 정의
whereami2048 May 21, 2024
e4759a6
feat: 북마크 경험 아이디로 조회 기능 정의(#115)
whereami2048 May 21, 2024
cd6bbdb
feat: 경험 검색 기능 정의(#115)
whereami2048 May 21, 2024
1437a15
feat: 태그 이름 검색 기능 구현(#115)
whereami2048 May 21, 2024
36734b1
feat: 역량 키워드 이름 검색 기능 구현(#115)
whereami2048 May 21, 2024
8e7c404
feat: 경험 제목 & 내용 검색 기능 구현체 추가 및 북마크 경험 id 배열 조회 기능 구현(#115)
whereami2048 May 21, 2024
1f1dc61
feat: 경험 검색 기능 API 구현(#115)
whereami2048 May 21, 2024
bd22466
feat: 북마크 경험 id 배열 조회 기능 구현(#115)
whereami2048 May 21, 2024
48858c8
Merge branch 'develop' into feat/flight-115
whereami2048 May 21, 2024
6b24765
feat: 북마크 상태 Boolean 값 제거(#115)
whereami2048 May 21, 2024
036e217
Merge branch 'feat/flight-115' of github.com:KUSITMS-29th-TEAM-B/Back…
whereami2048 May 21, 2024
96aafc9
chore: 깃 충돌 문제 해결(#115)
whereami2048 May 21, 2024
544058f
fix: 엔티티 오타 수정(#115)
whereami2048 May 21, 2024
f63d98e
fix: @Modifying 제거(#115)
whereami2048 May 21, 2024
7581227
fix: 하위 태그 관련 조회 연도 기준 활동 시작일로 변경(#115)
whereami2048 May 21, 2024
1ce8466
feat: 태그로 경험 조회 기능 구현(#115)
whereami2048 May 21, 2024
9f7c022
feat: 태그 삭제 시 관련 경험 삭제 로직 추가(#115)
whereami2048 May 21, 2024
8a4c29d
fix: @Modifying 누락 추가(#115)
whereami2048 May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Api-Module/src/docs/asciidoc/Tag.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ operation::TagControllerTest/createChildTagTest/[snippets='http-request,path-par
[[GetParentTagTest]]
=== 상위 태그 조회 API

operation::TagControllerTest/getAllParentTagByUserRegisterTest/[snippets='http-request,request-headers,http-response,response-fields']
operation::TagControllerTest/getAllParentTagByUserTest/[snippets='http-request,request-headers,http-response,response-fields']

[[GetTopRankTagTest]]
=== 연도 내 경험 최근 추가 순 태그 조회 API
Expand All @@ -24,7 +24,7 @@ operation::TagControllerTest/getTopRankParentTagTest/[snippets='http-request,req
[[GetParentTagsByFilter]]
=== 연도 내 상위 태그 조회 API

operation::TagControllerTest/getParentTagsByFilter/[snippets='http-request,http-response,response-fields']
operation::TagControllerTest/getParentTagsByYear/[snippets='http-request,http-response,response-fields']

[[GetChildTagTest]]
=== 하위 태그 전체 조회 API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ class BookmarkService(
bookmarkModifier.modifyBookmarkStatus(it)
} ?: bookmarkAppender.appendBookmark(jobDescriptionId, experienceId)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ class GetExperience {
val endedAt: LocalDateTime,
)

data class BookmarkResponse(
val experience: List<BookmarkDetailExperience>
)

data class BookmarkDetailExperience(
val id: UUID,
val title: String,
val parentTag: DetailTag,
val childTag: DetailTag,
val strongPoints: List<DetailStrongPoint>,
val contents: List<DetailExperienceContent>,
val startedAt: LocalDateTime,
val endedAt: LocalDateTime,
val bookmarked: Boolean,
)


data class DetailExperienceContent(
val question: String,
val answer: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,40 @@ package com.bamyanggang.apimodule.domain.experience.application.service
import com.bamyanggang.apimodule.common.getAuthenticationPrincipal
import com.bamyanggang.apimodule.domain.experience.application.dto.ExperienceYear
import com.bamyanggang.apimodule.domain.experience.application.dto.GetExperience
import com.bamyanggang.domainmodule.domain.bookmark.enums.BookmarkStatus
import com.bamyanggang.domainmodule.domain.bookmark.service.BookmarkReader
import com.bamyanggang.domainmodule.domain.experience.aggregate.Experience
import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent
import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceStrongPoint
import com.bamyanggang.domainmodule.domain.experience.service.ExperienceReader
import com.bamyanggang.domainmodule.domain.strongpoint.service.StrongPointReader
import com.bamyanggang.domainmodule.domain.tag.service.TagReader
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*

@Service
class ExperienceGetService(
private val experienceReader: ExperienceReader,
private val strongPointReader: StrongPointReader,
private val tagReader: TagReader,
private val bookMarkReader: BookmarkReader,
) {
@Transactional(readOnly = true)
fun getExperienceDetailById(experienceId: UUID) : GetExperience.DetailExperience {
val oneExperience = experienceReader.readExperience(experienceId)
return createExperienceDetailResponse(oneExperience)
}

@Transactional(readOnly = true)
fun getAllYearsByExistExperience(): ExperienceYear.Response {
val currentUserId = getAuthenticationPrincipal()

return experienceReader.readAllYearsByExistExperience(currentUserId)
.let { ExperienceYear.Response(it) }
}

@Transactional(readOnly = true)
fun getExperienceByYearAndParentTag(year: Int, parentTagId: UUID): GetExperience.Response {
val experiences = experienceReader.readByYearAndParentTagId(year, parentTagId).map {
createExperienceDetailResponse(it)
Expand All @@ -36,19 +45,58 @@ class ExperienceGetService(
return GetExperience.Response(experiences)
}

@Transactional(readOnly = true)
fun getExperienceByYearAndChildTag(year: Int, childTagId: UUID): GetExperience.Response {
val experiences = experienceReader.readByYearAndParentTagId(year, childTagId).map {
val experiences = experienceReader.readByYearAndChildTagId(year, childTagId).map {
createExperienceDetailResponse(it)
}

return GetExperience.Response(experiences)
}

@Transactional(readOnly = true)
fun getAllBookmarkExperiences(jobDescriptionId: UUID): GetExperience.BookmarkResponse {
val experienceIds = bookMarkReader.readByStatusAndJobDescriptionId(jobDescriptionId, BookmarkStatus.ON).map { it.experienceId }

val userExperiences = experienceReader.readAllByUserId(getAuthenticationPrincipal())

val bookmarkExperienceDetails = userExperiences.map {
when {
it.id in experienceIds -> createBookmarkExperienceDetailResponse(it, BookmarkStatus.ON)
else -> createBookmarkExperienceDetailResponse(it, BookmarkStatus.OFF)
}
}

return GetExperience.BookmarkResponse(bookmarkExperienceDetails)
}

@Transactional(readOnly = true)
fun getBookmarkExperienceBySearch(jobDescriptionId: UUID, search: String): GetExperience.BookmarkResponse {
val currentUserId = getAuthenticationPrincipal()

val experiencesIds = experienceReader.readByTitleContains(search) +
experienceReader.readByContentsContains(currentUserId, search) +
tagReader.readIdsByNameContains(search) +
strongPointReader.readIdsByNameContains(search)

val searchExperiences = experienceReader.readByIds(experiencesIds)
val bookmarkExperienceIds = bookMarkReader.readByExperienceIds(experiencesIds).map { it.experienceId }

val bookmarkExperienceDetails = searchExperiences.map {
when {
it.id in bookmarkExperienceIds -> createBookmarkExperienceDetailResponse(it, BookmarkStatus.ON)
else -> createBookmarkExperienceDetailResponse(it, BookmarkStatus.OFF)
}
}

return GetExperience.BookmarkResponse(bookmarkExperienceDetails)
}

private fun createExperienceDetailResponse(experience: Experience): GetExperience.DetailExperience {
val detailExperienceContents = convertDetailExperienceContent(experience)
val strongPointDetails = convertStrongPoints(experience)
val detailParentTag = convertParentTag(experience)
val detailChildTag = convertChildTag(experience)
val detailExperienceContents = convertExperienceContent(experience.contents)
val strongPointDetails = convertStrongPoints(experience.strongPoints)
val detailParentTag = convertParentTag(experience.parentTagId)
val detailChildTag = convertChildTag(experience.childTagId)

return GetExperience.DetailExperience(
id = experience.id,
Expand All @@ -62,36 +110,55 @@ class ExperienceGetService(
)
}

private fun convertChildTag(oneExperience: Experience) =
tagReader.readById(oneExperience.childTagId).let {
private fun createBookmarkExperienceDetailResponse(experience: Experience, bookmarkStatus: BookmarkStatus): GetExperience.BookmarkDetailExperience {
val detailExperienceContents = convertExperienceContent(experience.contents)
val strongPointDetails = convertStrongPoints(experience.strongPoints)
val detailParentTag = convertParentTag(experience.parentTagId)
val detailChildTag = convertChildTag(experience.childTagId)

return GetExperience.BookmarkDetailExperience(
id = experience.id,
title = experience.title,
parentTag = detailParentTag,
childTag = detailChildTag,
strongPoints = strongPointDetails,
contents = detailExperienceContents,
startedAt = experience.startedAt,
endedAt = experience.endedAt,
bookmarked = bookmarkStatus.boolStatus
)
}

private fun convertChildTag(childTagId: UUID) =
tagReader.readById(childTagId).let {
GetExperience.DetailTag(
it.id,
it.name
)
}

private fun convertParentTag(oneExperience: Experience) =
tagReader.readById(oneExperience.parentTagId).let {
private fun convertParentTag(parentTagId: UUID) =
tagReader.readById(parentTagId).let {
GetExperience.DetailTag(
it.id,
it.name
)
}

private fun convertDetailExperienceContent(experience: Experience) =
experience.contents.map { GetExperience.DetailExperienceContent(
private fun convertExperienceContent(contents: List<ExperienceContent>) =
contents.map { GetExperience.DetailExperienceContent(
it.question,
it.answer
)
}

private fun convertStrongPoints(experience: Experience) =
experience.strongPoints.map { it.strongPointId }.let {
private fun convertStrongPoints(strongPoints: List<ExperienceStrongPoint>) =
strongPoints.map { it.strongPointId }.let {
strongPointReader.readByIds(it).map { strongPoint ->
GetExperience.DetailStrongPoint(
strongPoint.id,
strongPoint.name
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ object ExperienceApi {
const val BASE_URL = "/api/experiences"
const val EXPERIENCE_PATH_VARIABLE_URL = "$BASE_URL/{experienceId}"
const val ALL_YEARS = "$BASE_URL/all-years"
const val BOOKMARK_EXPERIENCE_URL = "$BASE_URL/bookmark/{jobDescriptionId}"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.bamyanggang.apimodule.domain.experience.presentation

import com.bamyanggang.apimodule.domain.experience.application.dto.*
import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience
import com.bamyanggang.apimodule.domain.experience.application.dto.EditExperience
import com.bamyanggang.apimodule.domain.experience.application.dto.ExperienceYear
import com.bamyanggang.apimodule.domain.experience.application.dto.GetExperience
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceCreateService
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceDeleteService
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceEditService
Expand All @@ -15,6 +18,16 @@ class ExperienceController(
private val experienceEditService: ExperienceEditService,
private val experienceGetService: ExperienceGetService
) {
@GetMapping(ExperienceApi.BOOKMARK_EXPERIENCE_URL)
fun getBookMarkExperiences(
@PathVariable("jobDescriptionId") jobDescriptionId: UUID,
@RequestParam("search", required = false) search: String?,
) : GetExperience.BookmarkResponse =
when (search) {
null -> experienceGetService.getAllBookmarkExperiences(jobDescriptionId)
else -> experienceGetService.getBookmarkExperienceBySearch(jobDescriptionId, search)
}

@GetMapping(ExperienceApi.BASE_URL)
fun getExperienceByFilter(@RequestParam("year") year: Int,
@RequestParam("parent-tag") parentTagId: UUID,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.bamyanggang.apimodule.domain.strongpoint.application.service

import ch.qos.logback.core.rolling.helper.ArchiveRemover
import com.bamyanggang.domainmodule.domain.strongpoint.service.StrongPointRemover
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*

@Service
class StrongPointDeleteService(
private val strongPointRemover: StrongPointRemover
) {
@Transactional
fun deleteStrongPoint(strongPointId: UUID) {
strongPointRemover.removeStrongPoint(strongPointId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import com.bamyanggang.apimodule.common.getAuthenticationPrincipal
import com.bamyanggang.apimodule.domain.strongpoint.application.dto.GetStrongPoint
import com.bamyanggang.domainmodule.domain.strongpoint.service.StrongPointReader
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class StrongPointGetService(
private val strongPointReader: StrongPointReader,
) {
@Transactional(readOnly = true)
fun getAllStrongPoints(): GetStrongPoint.Response {
return getAuthenticationPrincipal().let {
val detailStrongPoints = strongPointReader.readAllByUserId(it).map { strongPoint ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ class TagControllerTest : BaseRestDocsTest() {
fieldWithPath("tags[].name").description("태그 이름"),
)
)
)
)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.bamyanggang.domainmodule.domain.bookmark.enums

enum class BookmarkStatus {
ON,
OFF
enum class BookmarkStatus(val boolStatus: Boolean) {
ON(true),
OFF(false)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.bamyanggang.domainmodule.domain.bookmark.repository

import com.bamyanggang.domainmodule.domain.bookmark.aggregate.Bookmark
import com.bamyanggang.domainmodule.domain.bookmark.enums.BookmarkStatus
import java.util.*

interface BookmarkRepository {

fun findByIds(jobDescriptionId : UUID, experienceId : UUID) : Bookmark?

fun findById(jobDescriptionId : UUID, experienceId : UUID) : Bookmark?
fun save(bookmark: Bookmark)

fun findByStatusAndJobDescriptionId(jobDescriptionId: UUID, status: BookmarkStatus): List<Bookmark>
fun findByExperienceIds(experiences: List<UUID>): List<Bookmark>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bamyanggang.domainmodule.domain.bookmark.service

import com.bamyanggang.domainmodule.domain.bookmark.aggregate.Bookmark
import com.bamyanggang.domainmodule.domain.bookmark.enums.BookmarkStatus
import com.bamyanggang.domainmodule.domain.bookmark.repository.BookmarkRepository
import org.springframework.stereotype.Service
import java.util.*
Expand All @@ -11,7 +12,14 @@ class BookmarkReader(
) {

fun readBookmark(jobDescriptionId: UUID, experienceId: UUID) : Bookmark? {
return bookmarkRepository.findByIds(jobDescriptionId, experienceId)
return bookmarkRepository.findById(jobDescriptionId, experienceId)
}

fun readByStatusAndJobDescriptionId(jobDescriptionId: UUID, status: BookmarkStatus): List<Bookmark> {
return bookmarkRepository.findByStatusAndJobDescriptionId(jobDescriptionId, status)
}

fun readByExperienceIds(experiencesIds: List<UUID>) : List<Bookmark>{
return bookmarkRepository.findByExperienceIds(experiencesIds)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ interface ExperienceRepository {
fun findByUserIdAndYearDesc(year: Int, userId: UUID): List<Experience>
fun findByYearAndParentTagId(year: Int, parentTagId: UUID): List<Experience>
fun findByYearAndChildTagId(year: Int, childTagId: UUID): List<Experience>
fun findByIds(experienceIds: List<UUID>): List<Experience>
fun findByTitleContains(search: String): List<Experience>
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,21 @@ class ExperienceReader(
fun readByYearAndChildTagId(year: Int, childTagId: UUID): List<Experience> {
return experienceRepository.findByYearAndChildTagId(year, childTagId)
}

fun readByIds(experienceIds: List<UUID>) : List<Experience> {
return experienceRepository.findByIds(experienceIds)
}

fun readByTitleContains(search: String): List<UUID> {
return experienceRepository.findByTitleContains(search).map { it.id }
}

fun readByContentsContains(userId: UUID, search: String): List<UUID> {
val experiences = experienceRepository.findAllByUserId(userId)

return experiences.filter {
it.contents.map { content ->
content.question.contains(search) || content.answer.contains(search)
}.contains(true) }.map { it.id }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ interface StrongPointRepository {
fun isExistByStrongPointId(strongPointId: UUID): Boolean
fun findByIds(strongPointIds: List<UUID>) : List<StrongPoint>
fun saveAll(strongPoints: List<StrongPoint>)
fun findByNameContains(search: String): List<StrongPoint>
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ class StrongPointReader(
fun readByIds(strongPointIds: List<UUID>) : List<StrongPoint> {
return strongPointRepository.findByIds(strongPointIds)
}

fun readIdsByNameContains(search: String) : List<UUID> {
return strongPointRepository.findByNameContains(search).map { it.id }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ interface TagRepository {
fun deleteByTagId(tagId: UUID)
fun isExistById(tagId: UUID): Boolean
fun findByParentTagIds(tagParentTagIds: List<UUID>): List<Tag>
fun findByNameContains(search: String): List<Tag>
}
Loading