Skip to content

Commit

Permalink
Merge pull request #107 from wafflestudio/feat/refactor-profile
Browse files Browse the repository at this point in the history
Changed profile&review implementations to match notion requirements
  • Loading branch information
dennis0405 authored Jan 16, 2025
2 parents f088a25 + 96f69b5 commit d381f82
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ package com.example.toyTeam6Airbnb.profile.controller
import com.example.toyTeam6Airbnb.profile.persistence.ProfileEntity

data class Profile(
val id: Long,
val userId: Long,
val nickname: String,
val bio: String,
val isSuperHost: Boolean
val isSuperHost: Boolean,
val showMyReviews: Boolean,
val showMyReservations: Boolean
) {
companion object {
fun fromEntity(profileEntity: ProfileEntity): Profile {
return Profile(
id = profileEntity.id!!,
userId = profileEntity.user.id!!,
nickname = profileEntity.nickname,
bio = profileEntity.bio,
isSuperHost = profileEntity.isSuperHost
isSuperHost = profileEntity.isSuperHost,
showMyReviews = profileEntity.showMyReviews,
showMyReservations = profileEntity.showMyReservations
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody
Expand All @@ -30,24 +31,33 @@ class ProfileController(
return ResponseEntity.ok(profile)
}

@GetMapping("/{userId}")
@Operation(summary = "특정 유저 프로필 가져오기", description = "특정 user의 프로필을 가져옵니다.")
fun getProfileByUserId(
@PathVariable userId: Long
): ResponseEntity<Profile> {
val profile = profileService.getProfileByUserId(userId)
return ResponseEntity.ok(profile)
}

@PutMapping
@Operation(summary = "유저 프로필 업데이트하기", description = "현재 로그인 되어 있는 user의 프로필을 업데이트합니다.")
fun updateCurrentUserProfile(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@RequestBody request: UpdateProfileRequest
): ResponseEntity<Profile> {
val updatedProfile = profileService.updateCurrentUserProfile(principalDetails.getUser(), request)
return ResponseEntity.ok(updatedProfile)
): ResponseEntity<Unit> {
profileService.updateCurrentUserProfile(principalDetails.getUser(), request)
return ResponseEntity.ok().build()
}

@PostMapping
@Operation(summary = "유저 프로필 추가", description = "현재 로그인 되어 있는 user에게 프로필을 추가합니다. (소셜 로그인 전용)")
fun addProfileToCurrentUser(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@RequestBody request: CreateProfileRequest
): ResponseEntity<Profile> {
val profile = profileService.addProfileToCurrentUser(principalDetails.getUser(), request)
return ResponseEntity.status(HttpStatus.CREATED).body(profile)
): ResponseEntity<Unit> {
profileService.addProfileToCurrentUser(principalDetails.getUser(), request)
return ResponseEntity.status(HttpStatus.CREATED).build()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository
interface ProfileRepository : JpaRepository<ProfileEntity, Long> {
fun findByUser(user: UserEntity): ProfileEntity?

fun findByUserId(userId: Long): ProfileEntity?

fun existsByUser(user: UserEntity): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ interface ProfileService {
user: UserEntity
): Profile

fun getProfileByUserId(
userId: Long
): Profile

fun updateCurrentUserProfile(
user: UserEntity,
request: UpdateProfileRequest
): Profile
)

fun addProfileToCurrentUser(
user: UserEntity,
request: CreateProfileRequest
): Profile
)

fun updateSuperHostStatus(
profile: ProfileEntity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,18 @@ class ProfileServiceImpl(
return Profile.fromEntity(profile)
}

override fun getProfileByUserId(
userId: Long
): Profile {
val profile = profileRepository.findByUserId(userId) ?: throw ProfileNotFoundException()
return Profile.fromEntity(profile)
}

@Transactional
override fun updateCurrentUserProfile(
user: UserEntity,
request: UpdateProfileRequest
): Profile {
) {
val profile = profileRepository.findByUser(user) ?: ProfileEntity(user = user, nickname = "", bio = "")

profile.nickname = request.nickname
Expand All @@ -39,15 +46,13 @@ class ProfileServiceImpl(
profile.showMyReservations = request.showMyReservations
updateSuperHostStatus(profile)
profileRepository.save(profile)

return Profile.fromEntity(profile)
}

@Transactional
override fun addProfileToCurrentUser(
user: UserEntity,
request: CreateProfileRequest
): Profile {
) {
if (profileRepository.existsByUser(user)) throw ProfileAlreadyExistException()

val profile = ProfileEntity(
Expand All @@ -58,8 +63,6 @@ class ProfileServiceImpl(
showMyReservations = request.showMyReservations
)
updateSuperHostStatus(profile)

return Profile.fromEntity(profileRepository.save(profile))
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ class ReservationController(
@GetMapping("/{reservationId}")
@Operation(summary = "예약 상세 조회", description = "예약 상세 정보를 조회합니다")
fun getReservation(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@PathVariable reservationId: Long
): ResponseEntity<Reservation> {
val reservation = reservationService.getReservation(reservationId)
val reservation = reservationService.getReservation(principalDetails.getUser().id!!, reservationId)

return ResponseEntity.ok(reservation)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface ReservationService {
): Reservation

fun getReservation(
userId: Long,
reservationId: Long
): Reservation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,12 @@ class ReservationServiceImpl(
}

@Transactional
override fun getReservation(reservationId: Long): Reservation {
override fun getReservation(
userId: Long,
reservationId: Long
): Reservation {
val reservationEntity = reservationRepository.findByIdOrNull(reservationId) ?: throw ReservationNotFound()
if (reservationEntity.user.id != userId) throw ReservationPermissionDenied()

return Reservation.fromEntity(reservationEntity)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,45 @@ import com.example.toyTeam6Airbnb.review.persistence.ReviewEntity
import java.time.Instant
import java.time.LocalDate

data class Review(
val id: Long,
data class ReviewByRoomDTO(
val userId: Long,
val reservationId: Long,
val roomId: Long,
val nickname: String,
val profileImage: String,
val content: String,
val rating: Int,
val createdAt: Instant,
val updatedAt: Instant
val startDate: LocalDate,
val endDate: LocalDate
) {
companion object {
fun fromEntity(entity: ReviewEntity): Review {
return Review(
id = entity.id!!,
fun fromEntity(entity: ReviewEntity): ReviewByRoomDTO {
return ReviewByRoomDTO(
userId = entity.user.id!!,
reservationId = entity.reservation.id!!,
roomId = entity.room.id!!,
nickname = entity.user.profile?.nickname ?: entity.user.username,
profileImage = "",
content = entity.content,
rating = entity.rating,
createdAt = entity.createdAt,
updatedAt = entity.updatedAt
startDate = entity.reservation.startDate,
endDate = entity.reservation.endDate
)
}
}
}

data class ReviewByUserDTO(
val content: String,
val rating: Int,
val place: String,
val startDate: LocalDate,
val endDate: LocalDate
) {
companion object {
fun fromEntity(entity: ReviewEntity): ReviewByUserDTO {
return ReviewByUserDTO(
content = entity.content,
rating = entity.rating,
place = entity.room.address.sido,
startDate = entity.reservation.startDate,
endDate = entity.reservation.endDate
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,33 @@ class ReviewController(
) {

@PostMapping
@Operation(summary = "리뷰 생성", description = "새로운 리뷰를 생성합니다")
@Operation(summary = "리뷰 생성", description = "새로운 리뷰를 생성합니다. 리뷰는 예약 당 1개입니다. Response body에는 생성된 review의 id가 들어갑니다.")
fun createReview(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@RequestBody request: CreateReviewRequest
): ResponseEntity<Review> {
val review = reviewService.createReview(
request.roomId,
): ResponseEntity<Long> {
val reviewId = reviewService.createReview(
User.fromEntity(principalDetails.getUser()),
request.reservationId,
request.content,
request.rating
)
return ResponseEntity.status(HttpStatus.CREATED).body(review)
return ResponseEntity.status(HttpStatus.CREATED).body(reviewId)
}

@GetMapping("/room/{roomId}")
@Operation(summary = "특정 방의 리뷰 조회", description = "특정 방의 모든 리뷰를 조회합니다")
@Operation(summary = "특정 방의 리뷰 조회", description = "특정 방의 모든 리뷰를 조회합니다.")
fun getReviewsByRoom(
@PathVariable roomId: Long,
pageable: Pageable
): ResponseEntity<Page<ReviewDTO>> {
): ResponseEntity<Page<ReviewByRoomDTO>> {
val reviews = reviewService.getReviewsByRoom(roomId, pageable)
return ResponseEntity.ok(reviews)
}

// hidden
@GetMapping("/{reviewId}")
@Operation(summary = "특정 리뷰 상세 조회", description = "특정 리뷰의 상세정보를 조회합니다")
@Operation(summary = "특정 리뷰 상세 조회", description = "특정 리뷰의 상세 정보를 조회합니다.", hidden = true)
fun getReviewDetails(
@PathVariable reviewId: Long
): ResponseEntity<ReviewDTO> {
Expand All @@ -63,11 +63,11 @@ class ReviewController(
}

@GetMapping("/user/{userId}")
@Operation(summary = "특정 유저의 리뷰 조회", description = "특정 유저의 모든 리뷰를 조회합니다")
@Operation(summary = "특정 유저의 리뷰 조회", description = "특정 유저의 모든 리뷰를 조회합니다.")
fun getReviewsByUser(
@PathVariable userId: Long,
pageable: Pageable
): ResponseEntity<Page<ReviewDTO>> {
): ResponseEntity<Page<ReviewByUserDTO>> {
val viewerId =
try {
val principalDetails = SecurityContextHolder.getContext().authentication.principal as PrincipalDetails
Expand All @@ -82,23 +82,23 @@ class ReviewController(
}

@PutMapping("/{reviewId}")
@Operation(summary = "리뷰 수정", description = "존재하는 리뷰를 수정합니다")
@Operation(summary = "리뷰 수정", description = "존재하는 리뷰를 수정합니다. 수정할 내용은 content와 rating입니다. Response body에는 수정된 review의 id가 들어갑니다. POST API와의 통일성을 위해 response body에 review id가 포함되긴 하나, 수정 시에도 id는 바뀌지 않으므로 큰 의미는 없습니다.")
fun updateReview(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@PathVariable reviewId: Long,
@RequestBody request: UpdateReviewRequest
): ResponseEntity<Review> {
val review = reviewService.updateReview(
): ResponseEntity<Long> {
reviewService.updateReview(
User.fromEntity(principalDetails.getUser()),
reviewId,
request.content,
request.rating
)
return ResponseEntity.ok(review)
return ResponseEntity.ok(reviewId)
}

@DeleteMapping("/{reviewId}")
@Operation(summary = "리뷰 삭제", description = "리뷰를 삭제합니다")
@Operation(summary = "리뷰 삭제", description = "리뷰를 삭제합니다.")
fun deleteReview(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@PathVariable reviewId: Long
Expand All @@ -109,7 +109,6 @@ class ReviewController(
}

data class CreateReviewRequest(
val roomId: Long,
val reservationId: Long,
val content: String,
val rating: Int
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.toyTeam6Airbnb.review.service

import com.example.toyTeam6Airbnb.review.controller.Review
import com.example.toyTeam6Airbnb.review.controller.ReviewByRoomDTO
import com.example.toyTeam6Airbnb.review.controller.ReviewByUserDTO
import com.example.toyTeam6Airbnb.review.controller.ReviewDTO
import com.example.toyTeam6Airbnb.user.controller.User
import org.springframework.data.domain.Page
Expand All @@ -9,17 +10,16 @@ import org.springframework.data.domain.Pageable
interface ReviewService {

fun createReview(
roomId: Long,
user: User,
reservationId: Long,
content: String,
rating: Int
): Review
): Long

fun getReviewsByRoom(
roomId: Long,
pageable: Pageable
): Page<ReviewDTO>
): Page<ReviewByRoomDTO>

fun getReviewDetails(
reviewId: Long
Expand All @@ -29,14 +29,14 @@ interface ReviewService {
viewerId: Long?,
userId: Long,
pageable: Pageable
): Page<ReviewDTO>
): Page<ReviewByUserDTO>

fun updateReview(
user: User,
reviewId: Long,
content: String?,
rating: Int?
): Review
): Long

fun deleteReview(
user: User,
Expand Down
Loading

0 comments on commit d381f82

Please sign in to comment.