Skip to content

Commit

Permalink
Api-v0.0.4-4
Browse files Browse the repository at this point in the history
  • Loading branch information
kdomo authored Jul 19, 2023
2 parents 55e0112 + 2577294 commit 15eb066
Show file tree
Hide file tree
Showing 30 changed files with 426 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.depromeet.whatnow.api.notification.controller

import com.depromeet.whatnow.api.notification.dto.NotificationResponse
import com.depromeet.whatnow.api.notification.usecase.NotificationReadUseCase
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.security.SecurityRequirement
import io.swagger.v3.oas.annotations.tags.Tag
import org.springdoc.api.annotations.ParameterObject
import org.springframework.data.domain.Pageable
import org.springframework.data.web.PageableDefault
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@Tag(name = "8. [알림]")
@RequestMapping("/v1/notifications")
@SecurityRequirement(name = "access-token")
class NotificationController(
val notificationReadUseCase: NotificationReadUseCase,
) {
@Operation(summary = "자신의 알림 조회")
@GetMapping
fun getMyNotifications(
@ParameterObject @PageableDefault
pageable: Pageable,
): NotificationResponse {
return notificationReadUseCase.execute(pageable)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.notification.domain.EndSharingNotification
import com.depromeet.whatnow.domains.notification.domain.NotificationType
import java.time.LocalDateTime

class EndSharingNotificationResponse(
val promiseId: Long,
override val createdAt: LocalDateTime,
) : NotificationAbstract(NotificationType.START_SHARING, createdAt) {
companion object {
fun from(notification: EndSharingNotification): EndSharingNotificationResponse {
return EndSharingNotificationResponse(
notification.promiseId,
notification.createdAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.notification.domain.ImageNotification
import com.depromeet.whatnow.domains.notification.domain.NotificationType
import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType
import java.time.LocalDateTime

class ImageNotificationResponse(
val senderUserPromiseUserType: PromiseUserType,
val senderUserId: Long,
val promiseId: Long,
val imageKey: String,
override val createdAt: LocalDateTime,
) : NotificationAbstract(NotificationType.IMAGE, createdAt) {
companion object {
fun from(notification: ImageNotification): ImageNotificationResponse {
return ImageNotificationResponse(
notification.senderUserPromiseUserType,
notification.senderUserId,
notification.promiseId,
notification.imageKey,
notification.createdAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.interaction.domain.InteractionType
import com.depromeet.whatnow.domains.notification.domain.InteractionAttainmentNotification
import com.depromeet.whatnow.domains.notification.domain.NotificationType
import java.time.LocalDateTime

class InteractionAttainmentNotificationResponse(
val promiseId: Long,
val senderUserId: Long,
val interactionType: InteractionType,
override val createdAt: LocalDateTime,
) : NotificationAbstract(NotificationType.INTERACTION_ATTAINMENT, createdAt) {
companion object {
fun from(notification: InteractionAttainmentNotification): InteractionAttainmentNotificationResponse {
return InteractionAttainmentNotificationResponse(
notification.promiseId,
notification.senderUserId,
notification.interactionType,
notification.createdAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.interaction.domain.InteractionType
import com.depromeet.whatnow.domains.notification.domain.InteractionNotification
import com.depromeet.whatnow.domains.notification.domain.NotificationType
import java.time.LocalDateTime

class InteractionNotificationResponse(
val promiseId: Long,
val senderUserId: Long,
val interactionType: InteractionType,
override val createdAt: LocalDateTime,
) : NotificationAbstract(NotificationType.INTERACTION, createdAt) {
companion object {
fun from(notification: InteractionNotification): InteractionNotificationResponse {
return InteractionNotificationResponse(
notification.promiseId,
notification.senderUserId,
notification.interactionType,
notification.createdAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.notification.domain.NotificationType
import java.time.LocalDateTime

abstract class NotificationAbstract(
val notificationType: NotificationType,
open val createdAt: LocalDateTime,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.depromeet.whatnow.api.notification.dto

import java.time.LocalDate

data class NotificationResponse(
val notifications: Map<LocalDate, List<NotificationAbstract>>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.notification.domain.NotificationType
import com.depromeet.whatnow.domains.notification.domain.StartSharingNotification
import java.time.LocalDateTime

class StartSharingNotificationResponse(
val promiseId: Long,
override val createdAt: LocalDateTime,
) : NotificationAbstract(NotificationType.START_SHARING, createdAt) {
companion object {
fun from(notification: StartSharingNotification): StartSharingNotificationResponse {
return StartSharingNotificationResponse(
notification.promiseId,
notification.createdAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.depromeet.whatnow.api.notification.dto

import com.depromeet.whatnow.domains.notification.domain.NotificationType
import com.depromeet.whatnow.domains.notification.domain.TimeOverNotification
import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType
import java.time.LocalDateTime

class TimeOverNotificationResponse(
val promiseId: Long,
val promiseUserType: PromiseUserType,
override val createdAt: LocalDateTime,
) : NotificationAbstract(NotificationType.TIMEOVER, createdAt) {
companion object {
fun from(notification: TimeOverNotification): TimeOverNotificationResponse {
return TimeOverNotificationResponse(
notification.promiseId,
notification.promiseUserType,
notification.createdAt,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.depromeet.whatnow.api.notification.usecase

import com.depromeet.whatnow.annotation.UseCase
import com.depromeet.whatnow.api.notification.dto.EndSharingNotificationResponse
import com.depromeet.whatnow.api.notification.dto.ImageNotificationResponse
import com.depromeet.whatnow.api.notification.dto.InteractionAttainmentNotificationResponse
import com.depromeet.whatnow.api.notification.dto.InteractionNotificationResponse
import com.depromeet.whatnow.api.notification.dto.NotificationResponse
import com.depromeet.whatnow.api.notification.dto.StartSharingNotificationResponse
import com.depromeet.whatnow.api.notification.dto.TimeOverNotificationResponse
import com.depromeet.whatnow.config.security.SecurityUtils
import com.depromeet.whatnow.domains.notification.domain.EndSharingNotification
import com.depromeet.whatnow.domains.notification.domain.ImageNotification
import com.depromeet.whatnow.domains.notification.domain.InteractionAttainmentNotification
import com.depromeet.whatnow.domains.notification.domain.InteractionNotification
import com.depromeet.whatnow.domains.notification.domain.StartSharingNotification
import com.depromeet.whatnow.domains.notification.domain.TimeOverNotification
import com.depromeet.whatnow.domains.notification.exception.UnknownNotificationTypeException
import com.depromeet.whatnow.domains.notification.service.NotificationDomainService
import org.springframework.data.domain.Pageable

@UseCase
class NotificationReadUseCase(
val notificationDomainService: NotificationDomainService,
) {
fun execute(pageable: Pageable): NotificationResponse {
val userId = SecurityUtils.currentUserId
val notifications = notificationDomainService.getMyNotifications(userId, pageable)
.map { notification ->
when (notification) {
is ImageNotification -> {
ImageNotificationResponse.from(notification)
}
is InteractionNotification -> {
InteractionNotificationResponse.from(notification)
}
is InteractionAttainmentNotification -> {
InteractionAttainmentNotificationResponse.from(notification)
}
is StartSharingNotification -> {
StartSharingNotificationResponse.from(notification)
}
is EndSharingNotification -> {
EndSharingNotificationResponse.from(notification)
}
is TimeOverNotification -> {
TimeOverNotificationResponse.from(notification)
}
else -> throw UnknownNotificationTypeException.EXCEPTION
}
}
.groupBy { it.createdAt.toLocalDate() }

return NotificationResponse(notifications)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PromiseUserController(
}

@Operation(summary = "약속 id로 약속 유저(promiseUser) 조회", description = "약속ID 로 약속 유저를 조회합니다.")
@GetMapping("/promises/{promiseId}/users")
@GetMapping("/promises/{promise-id}/users")
fun getPromiseUser(@PathVariable("promise-id") promiseId: Long): List<PromiseUserDto> {
return promiseUserReadUseCase.findByPromiseId(promiseId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.depromeet.whatnow.domains.notification.adapter
import com.depromeet.whatnow.annotation.Adapter
import com.depromeet.whatnow.domains.notification.domain.Notification
import com.depromeet.whatnow.domains.notification.repository.NotificationRepository
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice

@Adapter
class NotificationAdapter(
Expand All @@ -11,4 +13,8 @@ class NotificationAdapter(
fun save(notification: Notification): Notification {
return notificationRepository.save(notification)
}

fun getMyNotifications(userId: Long, pageable: Pageable): Slice<Notification> {
return notificationRepository.findAllByTargetUserIdOrderByCreatedAtDesc(userId, pageable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.depromeet.whatnow.domains.notification.domain
import com.depromeet.whatnow.domains.interaction.domain.InteractionType
import javax.persistence.DiscriminatorValue
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated

@Entity
@DiscriminatorValue("INTERACTION_ATTAINMENT")
Expand All @@ -11,6 +13,7 @@ class InteractionAttainmentNotification(

var senderUserId: Long,

@Enumerated(EnumType.STRING)
var interactionType: InteractionType,

override var targetUserId: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.depromeet.whatnow.domains.notification.domain
import com.depromeet.whatnow.domains.interaction.domain.InteractionType
import javax.persistence.DiscriminatorValue
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated

@Entity
@DiscriminatorValue("INTERACTION")
Expand All @@ -11,6 +13,7 @@ class InteractionNotification(

var senderUserId: Long,

@Enumerated(EnumType.STRING)
var interactionType: InteractionType,

override var targetUserId: Long,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.depromeet.whatnow.domains.notification.exception

import com.depromeet.whatnow.annotation.ExplainError
import com.depromeet.whatnow.consts.BAD_REQUEST
import com.depromeet.whatnow.dto.ErrorReason
import com.depromeet.whatnow.exception.BaseErrorCode
import java.util.*

enum class NotificationErrorCode(val status: Int, val code: String, val reason: String) : BaseErrorCode {

@ExplainError("알수 없는 알림 유형 일 경우")
UNKNOWN_NOTIFICATION_TYPE(BAD_REQUEST, "NOTIFICATION_400_1", "알수 없는 알림 유형 입니다."),
;

override val errorReason: ErrorReason
get() {
return ErrorReason(status, code, reason)
}

override val explainError: String
get() {
val field = this.javaClass.getField(name)
val annotation = field.getAnnotation(ExplainError::class.java)
return if (Objects.nonNull(annotation)) annotation.value else reason
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.depromeet.whatnow.domains.notification.exception

import com.depromeet.whatnow.exception.WhatnowCodeException

class UnknownNotificationTypeException : WhatnowCodeException(
NotificationErrorCode.UNKNOWN_NOTIFICATION_TYPE,
) {
companion object {
val EXCEPTION: WhatnowCodeException = UnknownNotificationTypeException()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.depromeet.whatnow.domains.notification.repository

import com.depromeet.whatnow.domains.notification.domain.Notification
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
import org.springframework.data.jpa.repository.JpaRepository

interface NotificationRepository : JpaRepository<Notification, Long>
interface NotificationRepository : JpaRepository<Notification, Long> {
fun findAllByTargetUserIdOrderByCreatedAtDesc(targetUserId: Long, pageable: Pageable): Slice<Notification>
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import com.depromeet.whatnow.domains.notification.domain.EndSharingNotification
import com.depromeet.whatnow.domains.notification.domain.ImageNotification
import com.depromeet.whatnow.domains.notification.domain.InteractionAttainmentNotification
import com.depromeet.whatnow.domains.notification.domain.InteractionNotification
import com.depromeet.whatnow.domains.notification.domain.Notification
import com.depromeet.whatnow.domains.notification.domain.StartSharingNotification
import com.depromeet.whatnow.domains.notification.domain.TimeOverNotification
import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

Expand Down Expand Up @@ -45,4 +48,9 @@ class NotificationDomainService(
fun saveForInteractionAttainment(promiseId: Long, senderUserId: Long, interactionType: InteractionType, targetUserId: Long) {
notificationAdapter.save(InteractionAttainmentNotification(promiseId, senderUserId, interactionType, targetUserId))
}

@Transactional(readOnly = true)
fun getMyNotifications(userId: Long, pageable: Pageable): Slice<Notification> {
return notificationAdapter.getMyNotifications(userId, pageable)
}
}
Loading

0 comments on commit 15eb066

Please sign in to comment.