Skip to content

Commit

Permalink
Merge pull request #181 from depromeet/feature/#171
Browse files Browse the repository at this point in the history
목표 기반 피드 추가
  • Loading branch information
ManHyuk authored Feb 20, 2024
2 parents 4958fc7 + 5759f60 commit 059d83c
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.raemian.api.goal.controller.request.CreateGoalRequest
import io.raemian.api.goal.controller.request.UpdateGoalRequest
import io.raemian.api.goal.controller.response.CreateGoalResponse
import io.raemian.api.goal.controller.response.GoalResponse
import io.raemian.api.goal.domain.GoalExploreDTO
import io.raemian.api.goal.event.CreateGoalEvent
import io.raemian.api.sticker.StickerService
import io.raemian.api.support.RaemianLocalDate
Expand Down Expand Up @@ -83,6 +84,13 @@ class GoalService(
goalRepository.delete(goal)
}

@Transactional(readOnly = true)
fun explore(goalId: Long): List<GoalExploreDTO> {
val results = goalRepository.explore(goalId)

return results.map { GoalExploreDTO(it) }
}

private fun createFirstLifeMap(userId: Long): LifeMap {
val user = userRepository.getReferenceById(userId)
return LifeMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import io.raemian.api.goal.GoalService
import io.raemian.api.goal.controller.request.CreateGoalRequest
import io.raemian.api.goal.controller.request.UpdateGoalRequest
import io.raemian.api.goal.controller.response.CreateGoalResponse
import io.raemian.api.goal.controller.response.GoalExploreResponse
import io.raemian.api.goal.controller.response.GoalResponse
import io.raemian.api.support.response.ApiResponse
import io.swagger.v3.oas.annotations.Operation
Expand All @@ -17,6 +18,7 @@ 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.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import java.net.URI

Expand Down Expand Up @@ -71,4 +73,16 @@ class GoalController(
goalService.delete(currentUser.id, goalId)
return ResponseEntity.noContent().build()
}

@Operation(summary = "explore goal")
@GetMapping("/explore")
fun exploreGoals(
@AuthenticationPrincipal currentUser: CurrentUser,
@RequestParam(required = false, defaultValue = Long.MAX_VALUE.toString()) cursor: Long,
): ResponseEntity<ApiResponse<GoalExploreResponse>> {
val goals = goalService.explore(goalId = cursor)

return ResponseEntity.ok()
.body(ApiResponse.success(GoalExploreResponse(goals)))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.raemian.api.goal.controller.response

import io.raemian.api.goal.domain.GoalExploreDTO

data class GoalExploreResponse(
val goals: List<GoalExploreDTO>,
val cursor: GoalExploreCursor,
) {

constructor(goals: List<GoalExploreDTO>) : this(
goals = goals,
cursor = GoalExploreCursor(goals.lastOrNull()?.goal?.id ?: Long.MIN_VALUE),
)
data class GoalExploreCursor(
val next: Long,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.raemian.api.goal.domain

import io.raemian.storage.db.core.model.GoalExploreQueryResult

data class GoalCountSubset(
val reaction: Long,
val comment: Long,
val task: Long,
val goal: Long,
) {
constructor(result: GoalExploreQueryResult) : this(
reaction = 0,
comment = 0,
task = 0,
goal = result.goalCount,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.raemian.api.goal.domain

import io.raemian.api.user.domain.UserSubset
import io.raemian.storage.db.core.model.GoalExploreQueryResult

data class GoalExploreDTO(
val user: UserSubset,
val goal: GoalSubset,
val count: GoalCountSubset,
) {
constructor(result: GoalExploreQueryResult) : this(
goal = GoalSubset(result),
user = UserSubset(result),
count = GoalCountSubset(result),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.raemian.api.goal.domain

import io.raemian.storage.db.core.model.GoalExploreQueryResult
import java.time.LocalDate

data class GoalSubset(
val id: Long,
val title: String,
val description: String,
val deadline: LocalDate,
val sticker: String,
val tag: String,
) {
constructor(result: GoalExploreQueryResult) : this(
id = result.goalId,
title = result.title,
description = result.description,
deadline = result.deadline,
sticker = result.stickerUrl,
tag = result.tagContent,
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.raemian.api.lifemap

import io.raemian.api.lifemap.domain.ExploreDTO
import io.raemian.api.lifemap.domain.LifeMapCountDTO
import io.raemian.api.lifemap.domain.LifeMapDTO
import io.raemian.api.lifemap.domain.UpdatePublicRequest
Expand All @@ -23,23 +22,6 @@ class LifeMapService(
private val lifeMapCountRepository: LifeMapCountRepository,
private val lifeMapHistoryRepository: LifeMapHistoryRepository,
) {

@Transactional(readOnly = true)
fun explore(lifeMapId: Long): List<ExploreDTO> {
val ids = lifeMapRepository.explore(lifeMapId)
val lifeMaps = lifeMapRepository.findAllByIdInOrderByIdDesc(ids)
val countMap = lifeMapCountRepository.findAllByLifeMapIdIn(ids)
.associateBy { it.lifeMapId }
return lifeMaps
.map { LifeMapDTO(it) }
.map {
ExploreDTO(
lifeMapDTO = it,
lifeMapCountDTO = LifeMapCountDTO(countMap[it.lifeMapId] ?: LifeMapCount.of(lifeMapId)),
)
}
}

@Transactional(readOnly = true)
fun findFirstByUserId(userId: Long): LifeMapDTO {
val lifeMap = lifeMapRepository.findFirstByUserId(userId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package io.raemian.api.lifemap.controller
import io.raemian.api.auth.domain.CurrentUser
import io.raemian.api.cheer.CheeringService
import io.raemian.api.lifemap.LifeMapService
import io.raemian.api.lifemap.domain.ExploreResponses
import io.raemian.api.lifemap.domain.LifeMapResponse
import io.raemian.api.lifemap.domain.UpdatePublicRequest
import io.raemian.api.support.response.ApiResponse
Expand All @@ -14,7 +13,6 @@ import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PatchMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
Expand All @@ -37,18 +35,6 @@ class LifeMapController(
.ok(ApiResponse.success(LifeMapResponse(lifeMap, count, cheeringCount)))
}

@Operation(summary = "explore life map")
@GetMapping("/explore")
fun explore(
@AuthenticationPrincipal currentUser: CurrentUser,
@RequestParam(required = false, defaultValue = Long.MAX_VALUE.toString()) cursor: Long,
): ResponseEntity<ApiResponse<ExploreResponses>> {
val maps = lifeMapService.explore(lifeMapId = cursor)

return ResponseEntity.ok()
.body(ApiResponse.success(ExploreResponses(maps)))
}

@Operation(summary = "인생 지도 공개 여부를 수정하는 API")
@PatchMapping("/publication")
fun updatePublic(
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.raemian.api.user.domain

import io.raemian.storage.db.core.model.GoalExploreQueryResult
import io.raemian.storage.db.core.user.User

data class UserSubset(
Expand All @@ -12,4 +13,10 @@ data class UserSubset(
nickname = user.nickname ?: "",
image = user.image,
)

constructor(result: GoalExploreQueryResult) : this(
id = result.userId,
nickname = result.nickname,
image = result.userImage,
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package io.raemian.storage.db.core.goal

import io.raemian.storage.db.core.lifemap.LifeMap
import io.raemian.storage.db.core.model.GoalExploreQueryResult
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import java.time.LocalDateTime

interface GoalRepository : JpaRepository<Goal, Long> {
Expand All @@ -11,4 +14,43 @@ interface GoalRepository : JpaRepository<Goal, Long> {

override fun getById(id: Long): Goal =
findById(id).orElseThrow() { NoSuchElementException("목표가 없습니다 $id") }

@Query(
"""
SELECT
new io.raemian.storage.db.core.model.GoalExploreQueryResult(
goal.id,
goal.title,
goal.description,
goal.deadline,
goal.sticker.url,
goal.tag.content,
goal.createdAt,
map.id,
count.goalCount,
count.historyCount,
count.viewCount,
user.id,
user.nickname,
user.image
)
FROM
Goal as goal,
LifeMap as map,
USERS as user,
LifeMapCount as count,
Task as task
WHERE 1 = 1
AND goal.lifeMap.id = map.id
AND map.user.id = user.id
AND map.id = count.lifeMapId
AND goal.id = task.goal.id
AND map.isPublic = true
AND goal.id < :cursor
ORDER BY
goal.id DESC
LIMIT 10
""",
)
fun explore(@Param("cursor") goalId: Long): List<GoalExploreQueryResult>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.raemian.storage.db.core.model

import java.time.LocalDate
import java.time.LocalDateTime

data class GoalExploreQueryResult(
val goalId: Long,
val title: String,
val description: String,
val deadline: LocalDate,
val stickerUrl: String,
val tagContent: String,
val createdAt: LocalDateTime,
val lifeMapId: Long,
val goalCount: Long,
val historyCount: Long,
val viewCount: Long,
val userId: Long,
val nickname: String,
val userImage: String,
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package io.raemian.storage.db.core.lifemap

import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param

interface LifeMapRepository : JpaRepository<LifeMap, Long> {

Expand All @@ -11,25 +9,4 @@ interface LifeMapRepository : JpaRepository<LifeMap, Long> {
fun findFirstByUserUsername(username: String): LifeMap?

fun findAllByIdInOrderByIdDesc(ids: List<Long>): List<LifeMap>

@Query(
"""
SELECT
map.id
FROM
LifeMap as map,
LifeMapCount as count
WHERE 1 = 1
AND map.id = count.lifeMapId
AND count.goalCount > 2
AND map.id < :cursor
AND map.isPublic = true
ORDER BY
map.id DESC
LIMIT 5
""",
)
fun explore(
@Param("cursor") lifeMapId: Long,
): List<Long>
}

0 comments on commit 059d83c

Please sign in to comment.