-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feature: game comment * feature: game sort by rating
- Loading branch information
1 parent
7ade030
commit 5d917c5
Showing
25 changed files
with
618 additions
and
32 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
...ion/src/main/kotlin/tw/waterballsa/gaas/application/repositories/GameCommentRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package tw.waterballsa.gaas.application.repositories | ||
|
||
import tw.waterballsa.gaas.domain.GameComment | ||
import tw.waterballsa.gaas.domain.GameRegistration | ||
import tw.waterballsa.gaas.domain.User | ||
|
||
interface GameCommentRepository { | ||
fun commentGame(gameComment: GameComment) | ||
fun updateGameComment(gameComment: GameComment) | ||
fun findByGameIdAndUserId(gameId: GameRegistration.Id, userId: User.Id): GameComment? | ||
} |
66 changes: 66 additions & 0 deletions
66
application/src/main/kotlin/tw/waterballsa/gaas/application/usecases/CommentGameUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package tw.waterballsa.gaas.application.usecases | ||
|
||
import tw.waterballsa.gaas.application.eventbus.EventBus | ||
import tw.waterballsa.gaas.application.repositories.GameCommentRepository | ||
import tw.waterballsa.gaas.application.repositories.UserRepository | ||
import tw.waterballsa.gaas.domain.GameComment | ||
import tw.waterballsa.gaas.domain.GameRegistration | ||
import tw.waterballsa.gaas.domain.User | ||
import tw.waterballsa.gaas.events.CommentGameEvent | ||
import tw.waterballsa.gaas.exceptions.NotFoundException.Companion.notFound | ||
import tw.waterballsa.gaas.exceptions.PlatformException | ||
import tw.waterballsa.gaas.exceptions.enums.PlatformError | ||
import javax.inject.Named | ||
|
||
@Named | ||
class CommentGameUseCase( | ||
private val userRepository: UserRepository, | ||
private val gameRatingRepository: GameCommentRepository, | ||
private val eventBus: EventBus, | ||
) { | ||
|
||
fun execute(request: Request) { | ||
val commentUser = getCommentUser(request.identityProviderId) | ||
val gameId = GameRegistration.Id(request.gameId) | ||
val userId = commentUser.id!! | ||
|
||
validateCommentEligibility(commentUser, gameId) | ||
createGameComment(gameId, userId, request.rating, request.comment) | ||
eventBus.broadcast(CommentGameEvent(gameId, userId, request.rating.toLong(), 1)) | ||
} | ||
|
||
private fun getCommentUser(identityProviderId: String): User { | ||
return userRepository.findByIdentity(identityProviderId) | ||
?: throw notFound(PlatformError.USER_NOT_FOUND, User::class).message() | ||
} | ||
|
||
private fun validateCommentEligibility(user: User, gameId: GameRegistration.Id) { | ||
user.validateGamePlayed(gameId) | ||
validateNoExistingRating(gameId, user.id!!) | ||
} | ||
|
||
private fun createGameComment(gameId: GameRegistration.Id, userId: User.Id, rating: Int, comment: String) { | ||
val newRating = GameComment(gameId, userId, rating, comment) | ||
gameRatingRepository.commentGame(newRating) | ||
} | ||
|
||
private fun User.validateGamePlayed(gameId: GameRegistration.Id) { | ||
val playedGamesIds = playedGamesIds ?: emptySet() | ||
if (gameId !in playedGamesIds) { | ||
throw PlatformException(PlatformError.GAME_NOT_PLAYED, "Must play game before comment.") | ||
} | ||
} | ||
|
||
private fun validateNoExistingRating(gameId: GameRegistration.Id, userId: User.Id) { | ||
if (gameRatingRepository.findByGameIdAndUserId(gameId, userId) != null) { | ||
throw PlatformException(PlatformError.GAME_COMMENT_DUPLICATED, "Game already commented.") | ||
} | ||
} | ||
|
||
data class Request( | ||
val identityProviderId: String, | ||
val gameId: String, | ||
val rating: Int, | ||
val comment: String, | ||
) | ||
} |
52 changes: 52 additions & 0 deletions
52
...tion/src/main/kotlin/tw/waterballsa/gaas/application/usecases/UpdateGameCommentUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package tw.waterballsa.gaas.application.usecases | ||
|
||
import tw.waterballsa.gaas.application.eventbus.EventBus | ||
import tw.waterballsa.gaas.application.repositories.GameCommentRepository | ||
import tw.waterballsa.gaas.application.repositories.UserRepository | ||
import tw.waterballsa.gaas.domain.GameComment | ||
import tw.waterballsa.gaas.domain.GameRegistration | ||
import tw.waterballsa.gaas.domain.User | ||
import tw.waterballsa.gaas.events.CommentGameEvent | ||
import tw.waterballsa.gaas.exceptions.NotFoundException.Companion.notFound | ||
import tw.waterballsa.gaas.exceptions.enums.PlatformError | ||
import java.time.Instant | ||
import javax.inject.Named | ||
|
||
@Named | ||
class UpdateGameCommentUseCase( | ||
private val userRepository: UserRepository, | ||
private val gameRatingRepository: GameCommentRepository, | ||
private val eventBus: EventBus, | ||
) { | ||
|
||
fun execute(request: Request) { | ||
val commentUser = getCommentUser(request.identityProviderId) | ||
val gameId = GameRegistration.Id(request.gameId) | ||
val userId = commentUser.id!! | ||
|
||
val gameComment = gameRatingRepository.findByGameIdAndUserId(gameId, userId) | ||
?: throw notFound(PlatformError.GAME_COMMENT_NOT_FOUND, GameComment::class).message() | ||
val originRating = gameComment.rating | ||
|
||
gameComment.apply { | ||
rating = request.rating | ||
comment = request.comment | ||
lastUpdatedTime = Instant.now() | ||
} | ||
|
||
gameRatingRepository.updateGameComment(gameComment) | ||
eventBus.broadcast(CommentGameEvent(gameId, userId, originRating - request.rating.toLong(), 0)) | ||
} | ||
|
||
private fun getCommentUser(identityProviderId: String): User { | ||
return userRepository.findByIdentity(identityProviderId) | ||
?: throw notFound(PlatformError.USER_NOT_FOUND, User::class).message() | ||
} | ||
|
||
data class Request( | ||
val identityProviderId: String, | ||
val gameId: String, | ||
val rating: Int, | ||
val comment: String, | ||
) | ||
} |
19 changes: 19 additions & 0 deletions
19
domain/src/main/kotlin/tw/waterballsa/gaas/domain/GameComment.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package tw.waterballsa.gaas.domain | ||
|
||
import java.time.Instant | ||
|
||
class GameComment( | ||
val id: Id? = null, | ||
val gameId: GameRegistration.Id, | ||
val userId: User.Id, | ||
var rating: Int, | ||
var comment: String, | ||
var lastUpdatedTime: Instant, | ||
val createdTime: Instant, | ||
) { | ||
constructor(gameId: GameRegistration.Id, userId: User.Id, rating: Int, comment: String) : | ||
this(null, gameId, userId, rating, comment, Instant.now(), Instant.now()) | ||
|
||
@JvmInline | ||
value class Id(val value: String) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
domain/src/main/kotlin/tw/waterballsa/gaas/events/CommentGameEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package tw.waterballsa.gaas.events | ||
|
||
import tw.waterballsa.gaas.domain.GameRegistration | ||
import tw.waterballsa.gaas.domain.User | ||
|
||
data class CommentGameEvent( | ||
val gameId: GameRegistration.Id, | ||
val userId: User.Id, | ||
val incrementRating: Long, | ||
val incrementNumberOfComments: Long, | ||
) : DomainEvent() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
spring/src/main/kotlin/tw/waterballsa/gaas/spring/controllers/GameCommentController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package tw.waterballsa.gaas.spring.controllers | ||
|
||
import org.springframework.security.core.annotation.AuthenticationPrincipal | ||
import org.springframework.security.oauth2.jwt.Jwt | ||
import org.springframework.web.bind.annotation.* | ||
import tw.waterballsa.gaas.application.usecases.CommentGameUseCase | ||
import tw.waterballsa.gaas.application.usecases.UpdateGameCommentUseCase | ||
import tw.waterballsa.gaas.exceptions.PlatformException | ||
import tw.waterballsa.gaas.exceptions.enums.PlatformError.JWT_ERROR | ||
import tw.waterballsa.gaas.spring.controllers.viewmodel.PlatformViewModel | ||
|
||
@RestController | ||
@RequestMapping("/comments") | ||
class GameCommentController( | ||
private val commentGameUserCase: CommentGameUseCase, | ||
private val updateGameCommentUseCase: UpdateGameCommentUseCase, | ||
) { | ||
|
||
@PostMapping | ||
fun commentGame( | ||
@AuthenticationPrincipal jwt: Jwt, | ||
@RequestBody request: CommentGameRequest | ||
): PlatformViewModel { | ||
commentGameUserCase.execute( | ||
CommentGameUseCase.Request( | ||
jwt.identityProviderId, | ||
request.gameId, | ||
request.rating, | ||
request.comment | ||
) | ||
) | ||
return PlatformViewModel.success() | ||
} | ||
|
||
|
||
@PostMapping("/games/{gameId}") | ||
fun updateGameComment( | ||
@AuthenticationPrincipal jwt: Jwt, | ||
@PathVariable gameId: String, | ||
@RequestBody request: UpdateGameCommentRequest | ||
): PlatformViewModel { | ||
updateGameCommentUseCase.execute( | ||
UpdateGameCommentUseCase.Request( | ||
jwt.identityProviderId, | ||
gameId, | ||
request.rating, | ||
request.comment, | ||
) | ||
) | ||
return PlatformViewModel.success() | ||
} | ||
|
||
|
||
data class CommentGameRequest( | ||
val gameId: String, | ||
val rating: Int, | ||
val comment: String, | ||
) | ||
|
||
data class UpdateGameCommentRequest( | ||
val rating: Int, | ||
val comment: String, | ||
) | ||
} | ||
|
||
private val Jwt.identityProviderId: String | ||
get() = subject ?: throw PlatformException(JWT_ERROR, "identityProviderId should exist.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
spring/src/main/kotlin/tw/waterballsa/gaas/spring/eventbus/CommentGameEventListener.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package tw.waterballsa.gaas.spring.eventbus | ||
|
||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.stereotype.Component | ||
import tw.waterballsa.gaas.events.CommentGameEvent | ||
import tw.waterballsa.gaas.spring.repositories.dao.GameRegistrationDAO | ||
import kotlin.reflect.KClass | ||
|
||
@Component | ||
class CommentGameEventListener( | ||
override val eventType: KClass<CommentGameEvent>, | ||
private val gameRegistrationDAO: GameRegistrationDAO, | ||
) : EventListener<CommentGameEvent> { | ||
|
||
@Autowired | ||
constructor(gameRegistrationDAO: GameRegistrationDAO): this(CommentGameEvent::class, gameRegistrationDAO) | ||
|
||
override fun onEvents(events: List<CommentGameEvent>) { | ||
events.forEach { | ||
gameRegistrationDAO.incrementTotalRatingAndNumberOfCommentsById( | ||
it.gameId.value, it.incrementRating, it.incrementNumberOfComments | ||
) | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...ng/src/main/kotlin/tw/waterballsa/gaas/spring/repositories/SpringGameCommentRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package tw.waterballsa.gaas.spring.repositories | ||
|
||
import org.springframework.stereotype.Component | ||
import tw.waterballsa.gaas.application.repositories.GameCommentRepository | ||
import tw.waterballsa.gaas.domain.GameComment | ||
import tw.waterballsa.gaas.domain.GameRegistration | ||
import tw.waterballsa.gaas.domain.User | ||
import tw.waterballsa.gaas.spring.repositories.dao.GameCommentDAO | ||
import tw.waterballsa.gaas.spring.repositories.data.toData | ||
|
||
@Component | ||
class SpringGameCommentRepository( | ||
private val gameCommentDAO: GameCommentDAO, | ||
): GameCommentRepository { | ||
override fun commentGame(gameComment: GameComment) { | ||
gameCommentDAO.save(gameComment.toData()).toDomain() | ||
} | ||
|
||
override fun updateGameComment(gameComment: GameComment) { | ||
gameCommentDAO.save(gameComment.toData()).toDomain() | ||
} | ||
|
||
override fun findByGameIdAndUserId(gameId: GameRegistration.Id, userId: User.Id): GameComment? { | ||
return gameCommentDAO.findByGameIdAndUserId(gameId.value, userId.value)?.toDomain() | ||
} | ||
} |
Oops, something went wrong.