Skip to content

Commit

Permalink
Merge branch 'main' into feat/security
Browse files Browse the repository at this point in the history
  • Loading branch information
jafacode authored Jan 26, 2025
2 parents d8613c6 + 40fbffe commit 5f88e66
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ class AuctionPermissionDeniedException : AuctionException(
msg = "Permission denied",
)

class AuctionBadPriceException : AuctionException(
class AuctionTooLowPriceException : AuctionException(
errorCode = 0,
httpStatusCode = HttpStatus.BAD_REQUEST,
msg = "Your price is lower than current price",
)

class AuctionTooFineUnitExceptions : AuctionException(
errorCode = 0,
httpStatusCode = HttpStatus.BAD_REQUEST,
msg = "Minimum unit is 5% of the start price",
)

class AuctionOverException : AuctionException(
errorCode = 0,
httpStatusCode = HttpStatus.BAD_REQUEST,
msg = "Over auction time",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.toyProject7.karrot.auction.service

import com.toyProject7.karrot.article.ArticlePermissionDeniedException
import com.toyProject7.karrot.article.controller.UpdateStatusRequest
import com.toyProject7.karrot.auction.AuctionBadPriceException
import com.toyProject7.karrot.auction.AuctionNotFoundException
import com.toyProject7.karrot.auction.AuctionOverException
import com.toyProject7.karrot.auction.AuctionPermissionDeniedException
import com.toyProject7.karrot.auction.AuctionTooFineUnitExceptions
import com.toyProject7.karrot.auction.AuctionTooLowPriceException
import com.toyProject7.karrot.auction.controller.Auction
import com.toyProject7.karrot.auction.controller.AuctionMessage
import com.toyProject7.karrot.auction.controller.PostAuctionRequest
Expand Down Expand Up @@ -32,15 +34,21 @@ class AuctionService(
@Transactional
fun updatePrice(auctionMessage: AuctionMessage): AuctionMessage {
val auctionEntity = auctionRepository.findByIdOrNull(auctionMessage.auctionId) ?: throw AuctionNotFoundException()
if (Instant.now().isAfter(auctionEntity.endTime)) {
throw AuctionOverException()
}
if (auctionEntity.currentPrice >= auctionMessage.price) {
throw AuctionBadPriceException()
throw AuctionTooLowPriceException()
}
if ((auctionMessage.price - auctionEntity.currentPrice) % (auctionEntity.startingPrice * 0.05).toInt() != 0) {
throw AuctionTooFineUnitExceptions()
}
val bidder = userService.getUserEntityByNickname(auctionMessage.senderNickname)

auctionEntity.currentPrice = auctionMessage.price
auctionEntity.bidder = bidder
if (ChronoUnit.MINUTES.between(auctionEntity.endTime, Instant.now()) <= 1) {
auctionEntity.endTime.plus(1, ChronoUnit.MINUTES)
auctionEntity.endTime = Instant.now().plus(1, ChronoUnit.MINUTES)
}

return auctionMessage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.toyProject7.karrot.chatRoom.controller

import com.toyProject7.karrot.article.controller.Article
import com.toyProject7.karrot.chatRoom.service.ChatRoomService
import com.toyProject7.karrot.user.AuthUser
import com.toyProject7.karrot.user.controller.User
Expand Down Expand Up @@ -54,6 +53,6 @@ data class CreateChatRoomRequest(
)

data class ChatRoomResponse(
val article: Article,
val chatRoom: ChatRoom,
val messages: List<ChatMessage>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class ChatRoomService(
)
val messages = chatMessageEntities.map { chatMessageEntity -> ChatMessage.fromEntity(chatMessageEntity) }
return ChatRoomResponse(
article = chatRoom.article,
chatRoom = chatRoom,
messages = messages,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,14 @@ class ProfileService(
nickname: String,
reviewId: Long,
): List<Review> {
return reviewService.getPreviousReviews(nickname, reviewId)
val userEntity = userService.getUserEntityByNickname(nickname)
val profileEntity = profileRepository.findByUserId(userEntity.id!!) ?: throw ProfileNotFoundException()

return profileEntity.reviews
.filter { it.id!! < reviewId }
.sortedByDescending { it.createdAt }
.take(10)
.map { Review.fromEntity(it) }
}

fun getItemCount(id: String): Int {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
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
import java.net.URLDecoder

@RestController
class ReviewController(
private val reviewService: ReviewService,
) {
@PostMapping("/api/{sellerNickname}/review")
@PostMapping("/api/review/post")
fun createReview(
@RequestBody request: ReviewCreateRequest,
@PathVariable sellerNickname: String,
@AuthUser user: User,
): ResponseEntity<ReviewCreateResponse> {
// Decode the sellerNickname
val decodedSellerNickname = URLDecoder.decode(sellerNickname, "UTF-8")

val review = reviewService.createReview(decodedSellerNickname, user.nickname, request.content, request.location)
val review = reviewService.createReview(request)
return ResponseEntity.status(201).body(review)
}
}

data class ReviewCreateRequest(
val content: String,
val location: String,
val isWritedByBuyer: Boolean,
val sellerId: String,
val buyerId: String,
)

typealias ReviewCreateResponse = Review
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package com.toyProject7.karrot.review.service
import com.toyProject7.karrot.profile.service.ProfileService
import com.toyProject7.karrot.review.ReviewContentLengthOutOfRangeException
import com.toyProject7.karrot.review.controller.Review
import com.toyProject7.karrot.review.controller.ReviewCreateRequest
import com.toyProject7.karrot.review.persistence.ReviewEntity
import com.toyProject7.karrot.review.persistence.ReviewRepository
import com.toyProject7.karrot.user.controller.User
import com.toyProject7.karrot.user.service.UserService
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -18,51 +18,36 @@ class ReviewService(
private val profileService: ProfileService,
) {
@Transactional
fun createReview(
sellerNickname: String,
buyerNickname: String,
content: String,
location: String,
): Review {
validateContent(content)
fun createReview(request: ReviewCreateRequest): Review {
validateContent(request.content)

val sellerEntity = userService.getUserEntityByNickname(sellerNickname)
val seller = User.fromEntity(sellerEntity)
val sellerProfileEntity = profileService.getProfileEntityByUserId(seller.id)
val sellerEntity = userService.getUserEntityById(request.sellerId)
val sellerProfileEntity = profileService.getProfileEntityByUserId(request.sellerId)

val buyerEntity = userService.getUserEntityByNickname(buyerNickname)
val buyer = User.fromEntity(buyerEntity)
val buyerProfileEntity = profileService.getProfileEntityByUserId(buyer.id)
val buyerEntity = userService.getUserEntityById(request.buyerId)
val buyerProfileEntity = profileService.getProfileEntityByUserId(request.buyerId)

val reviewEntity =
ReviewEntity(
seller = sellerEntity,
buyer = buyerEntity,
content = content,
location = location,
content = request.content,
location = request.location,
createdAt = Instant.now(),
updatedAt = Instant.now(),
).let {
reviewRepository.save(it)
}

sellerProfileEntity.reviews += reviewEntity
buyerProfileEntity.reviews += reviewEntity
if (request.isWritedByBuyer) {
sellerProfileEntity.reviews += reviewEntity
} else {
buyerProfileEntity.reviews += reviewEntity
}

return Review.fromEntity(reviewEntity)
}

@Transactional
fun getPreviousReviews(
nickname: String,
reviewId: Long,
): List<Review> {
return reviewRepository.findTop10BySellerNicknameOrBuyerNicknameAndIdBeforeOrderByCreatedAtDesc(nickname, nickname, reviewId).map {
reviewEntity ->
Review.fromEntity(reviewEntity)
}
}

private fun validateContent(content: String) {
if (content.isBlank()) {
throw ReviewContentLengthOutOfRangeException()
Expand Down

0 comments on commit 5f88e66

Please sign in to comment.