Skip to content

Commit

Permalink
✨ Add review package(createReview)
Browse files Browse the repository at this point in the history
  • Loading branch information
wonseok committed Jan 7, 2025
1 parent 5ace047 commit 83bf034
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne

@Entity(name = "manners")
@Entity(name = "manner")
class MannerEntity(
@Id
@GeneratedValue(strategy = GenerationType.UUID)
Expand Down
25 changes: 25 additions & 0 deletions src/main/kotlin/com/toyProject7/karrot/review/ReviewException.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.toyProject7.karrot.review

import com.toyProject7.karrot.DomainException
import org.springframework.http.HttpStatus
import org.springframework.http.HttpStatusCode

sealed class ReviewException(
errorCode: Int,
httpStatusCode: HttpStatusCode,
msg: String,
cause: Throwable? = null,
) : DomainException(errorCode, httpStatusCode, msg, cause)

class ReviewContentLengthOutOfRangeException :
ReviewException(
errorCode = 0,
httpStatusCode = HttpStatus.BAD_REQUEST,
msg = "Review content length out of range",
)

class UserNotFoundException : ReviewException(
errorCode = 0,
httpStatusCode = HttpStatus.NOT_FOUND,
msg = "User not found",
)
29 changes: 29 additions & 0 deletions src/main/kotlin/com/toyProject7/karrot/review/controller/Review.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.toyProject7.karrot.review.controller

import com.toyProject7.karrot.review.persistence.ReviewEntity
import com.toyProject7.karrot.user.controller.User
import java.time.Instant

data class Review(
val id: Long,
val content: String,
val seller: User,
val buyer: User,
val location: String,
val createdAt: Instant,
val updatedAt: Instant,
) {
companion object {
fun fromEntity(entity: ReviewEntity): Review {
return Review(
id = entity.id!!,
content = entity.content,
seller = User.fromEntity(entity.seller),
buyer = User.fromEntity(entity.buyer),
location = entity.location,
createdAt = entity.createdAt,
updatedAt = entity.updatedAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.toyProject7.karrot.review.controller

import com.toyProject7.karrot.review.service.ReviewService
import com.toyProject7.karrot.user.AuthUser
import com.toyProject7.karrot.user.controller.User
import org.springframework.http.ResponseEntity
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.RestController

@RestController
class ReviewController(
private val reviewService: ReviewService,
) {
@PostMapping("/api/{sellerNickname}/review")
fun createReview(
@RequestBody request: ReviewCreateRequest,
@PathVariable sellerNickname: String,
@AuthUser user: User,
): ResponseEntity<ReviewCreateResponse> {
val review = reviewService.createReview(sellerNickname, user.nickname, request.content, request.location)
return ResponseEntity.status(201).body(review)
}
}

data class ReviewCreateRequest(
val content: String,
val location: String,
)

typealias ReviewCreateResponse = Review
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.toyProject7.karrot.review.persistence

import com.toyProject7.karrot.user.persistence.UserEntity
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import java.time.Instant

@Entity(name = "review")
class ReviewEntity(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
@Column(columnDefinition = "TEXT")
var content: String,
@ManyToOne
@JoinColumn(name = "seller_id", nullable = false)
val seller: UserEntity,
@ManyToOne
@JoinColumn(name = "buyer_id", nullable = false)
val buyer: UserEntity,
@Column(name = "location", nullable = false)
var location: String,
@Column(name = "created_at", nullable = false)
var createdAt: Instant,
@Column(name = "updated_at", nullable = false)
var updatedAt: Instant,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.toyProject7.karrot.review.persistence

import org.springframework.data.jpa.repository.JpaRepository

interface ReviewRepository : JpaRepository<ReviewEntity, String> {
fun findTop10ByIdBeforeOrderByCreatedAtDesc(id: Long): List<ReviewEntity>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.toyProject7.karrot.review.service

import com.toyProject7.karrot.review.ReviewContentLengthOutOfRangeException
import com.toyProject7.karrot.review.UserNotFoundException
import com.toyProject7.karrot.review.controller.Review
import com.toyProject7.karrot.review.persistence.ReviewEntity
import com.toyProject7.karrot.review.persistence.ReviewRepository
import com.toyProject7.karrot.user.persistence.UserRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.Instant

@Service
class ReviewService(
private val reviewRepository: ReviewRepository,
private val userRepository: UserRepository,
) {
@Transactional
fun createReview(
sellerNickname: String,
buyerNickname: String,
content: String,
location: String,
): Review {
validateContent(content)

val sellerEntity = userRepository.findByNickname(sellerNickname) ?: throw UserNotFoundException()
val buyerEntity = userRepository.findByNickname(buyerNickname) ?: throw UserNotFoundException()
val reviewEntity =
ReviewEntity(
seller = sellerEntity,
buyer = buyerEntity,
content = content,
location = location,
createdAt = Instant.now(),
updatedAt = Instant.now(),
).let {
reviewRepository.save(it)
}
return Review.fromEntity(reviewEntity)
}

private fun validateContent(content: String) {
if (content.isBlank()) {
throw ReviewContentLengthOutOfRangeException()
}
if (content.length > 100) {
throw ReviewContentLengthOutOfRangeException()
}
}
}

0 comments on commit 83bf034

Please sign in to comment.