Skip to content

Instantly share code, notes, and snippets.

@rinotc
Last active March 12, 2023 15:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rinotc/53838bb7e90b4b8553f9ecfb6a0af69f to your computer and use it in GitHub Desktop.
Save rinotc/53838bb7e90b4b8553f9ecfb6a0af69f to your computer and use it in GitHub Desktop.
class ChangeEmailUseCase @Inject() (
userEmailUniqueChecker: UserEmailUniqueChecker,
userRepository: UserRepository
) {
import ChangeEmailOutput._
override def handle(input: ChangeEmailInput): ChangeEmailOutput = {
val result = for {
user <- userRepository.findById(input.userId).toRight(NotFoundUser(input.userId))
emailIsUniqueMessage <- userEmailUniqueChecker.check(input.email).left.map { _ => EmailIsNotUnique(input.email) }
} yield {
val emailUpdatedUser = user.changeEmail(emailIsUniqueMessage)
userRepository.update(emailUpdatedUser)
Success(emailUpdatedUser)
}
result.merge
}
}
trait UserEmailUniqueChecker extends DomainService {
import UserEmailUniqueChecker._
/**
* メールアドレスがユニークなものであるか調べる
*
* @param email
* 調べるメールアドレス
* @return
* 引数のメールアドレスがまだDBに同じものが存在せず、ユニークである時、[[Right]]で[[EmailIsUnique]]メッセージを返す
*/
def check(email: EmailAddress): Either[Because, EmailIsUnique] =
Either.cond(isNotExist(email), new EmailIsUnique(email), EmailAlreadyExist)
/**
* 引数のメールアドレスを持つユーザーがまだDB上に存在しない
* @param email
* メールアドレス
* @return
* 存在する時: `false`, 存在しない時: `true`
*/
protected def isNotExist(email: EmailAddress): Boolean
}
object UserEmailUniqueChecker {
/**
* メールアドレスがユニークであることを示すメッセージ
*/
final class EmailIsUnique private[unique] (val email: EmailAddress)
/** 失敗理由 **/
sealed trait Because
/** メールアドレスがすでに使われていた **/
case object EmailAlreadyExist extends Because
}
final class User private (
val id: UserId,
val name: Option[String],
val email: EmailAddress
) extends Entity[UserId]
with Aggregate {
/**
* メールアドレスを変更する
* @param message
* 変更しようとしているメールアドレスがユニークであることを示すメッセージ
*/
def changeEmail(message: EmailIsUnique): User = copy(email = message.email)
private def copy(
id: UserId = this.id,
name: Option[String] = this.name,
email: EmailAddress = this.email,
avatarUrl: Option[Url] = this.avatarUrl
) =
new User(id, name, email, avatarUrl)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment