Modeling the user registration process

Guillaume Bilodeau <[email protected]>
Newsgroups gmane.comp.programming.domain-driven-design
Message-ID <CAOr8G3Mt61fFQdQ14UHX6ZDmNghDYbNbBCTaCc7YPfNmpKXSnw@mail.gmail.com>
Hi all,

I'm looking for some basic feedback on the very standard user registration
process. Here we go.

Domain
======
. In order to access some restricted features of the application, a person
needs to create an account for the application.
. During this registration process, the person enters his full name, his
email address, a password of his choice and, optionally, a profile photo.
  A thumbnail of the profile photo must be presented to other users in
various situations.
. At this point, the person cannot yet log in using his email address and
password.
. The person's email address must then be verified. A random alphanumeric
token is generated and sent to the person's email address, along with an
application URL.
. The person then opens this application URL and enters the given token.
  In case of a match, the person's email is considered verified and his
account is activated.
  The person can now login with his email address and password.

Design
======
The following packages, classes and resources have been created. Interfaces
are marked by (I), classes by (C), enums by (E) and files by (F).

com.company.project.commons.media
(I) ThumbnailProducer
(C) AwtThumbnailProducer

com.company.project.application.user
(I) UserAccountService
(C) UserAccountServiceImpl

com.company.project.application.user.verification
(C) EmailVerificationTokenMailer
(C) MailingTokenEmailVerificationStrategy
(I) TokenBasedEmailVerificationStrategy
(F) registration_html_en.template
(F) registration_text_en.template

com.company.project.domain.token
(C) InvalidTokenException
(C) RandomAlphanumericTokenFactory
(C) Token
(I) TokenFactory
(I) TokenRepository
(E) TokenType

com.company.project.domain.user
(I) ProfilePhotoRepository
(C) ProfilePhotoThumbnailProducer
(C) UserAccount
(C) UserAccountBuilder
(C) UserAccountRegistrationRequest
(C) UserAccountRegistrationService
(I) UserAccountRepository
(E) UserAccountStatus

com.company.project.infrastructure.persistence
(C) DelegatingProfilePhotoRepository
(I) MediaStorage

com.company.project.infrastructure.persistence.filesystem
(C) LocalFileSystemMediaStorage

com.company.project.infrastructure.persistence.jpa
(C) JpaTokenRepository
(C) JpaUserAccountRepository

com.company.project.web.user
(C) UserAccountRegistrationController
(C) UserAccountEmailVerificationController

Technical constraints
=====================
This application is developed using a common Java stack: Spring MVC, Spring
IoC, Spring Security, JPA / Hibernate with a relational Postgres database.
Profile photos are to be stored on a locally accessible network area
storage.

Explanations
============
. UserAccountService/Impl is an application service that manages everything
related to user management.
. UserAccount is a domain entity.
. UserAccountRegistrationRequest is a (mutable) value object that
represents the registration request.
. UserAccountBuilder is a domain service that builds a UserAccount from
this UserAccountRegistrationRequest.
. UserAccountRepository is a domain repository that manages UserAccount
persistence. Its implementing JpaUserAccountRepository is an infrastructure
service.
. There is no ProfilePhoto domain object.
. ProfilePhotoRepository is a domain repository that manages profile photo
persistence and lookup. Its implementing DelegatingProfilePhotoRepository
is an infrastructure service.
  DelegatingProfilePhotoRepository delegates these operations to
MediaStorage and its implementing LocalFileSystemMediaStorage. Methods deal
in byte[] and URLs.
. ProfilePhotoThumbnailProducer is a domain service that produces
thumbnails of a given profile photo's byte[] using a ThumbnailProducer and
its implementing AwtThumbnailProducer.
. UserAccount maintains references to his full-size and thumbnail-sized
profile photos using URLs produced by the ProfilePhotoRepository.
. UserAccountRegistrationService is a domain service that manages the
registration process. Invoked by UserAccountServiceImpl.
. Token is a domain entity. Token has a UserAccount owner; UserAccount has
no knowledge of the tokens he owns.
. TokenFactory is a domain factory. It produces Token instances.
RandomAlphanumericTokenFactory is a TokenFactory that uses a random
algorithm to achieve this.
. TokenRepository is a domain repository that manages Token persistence.
Its implementing JpaTokenRepository is an infrastructure service.
. TokenBasedEmailVerificationStrategy is an application service that
manages email verification. MailingTokenBasedEmailVerification implements
this interface by
  producing a Token, assigning it to its UserAccount owner, and sending it
to the owner through the EmailVerificationTokenMailer. It also verifies the
later-submitted Token.
. EmailVerificationTokenMailer produces the email message using the
registration_html_en.template and registration_text_en.template templates.
It then sends them using the JavaMail API.

Questions
=========
I think that this is an adequate model. However, I would like some feedback.

1. Should there be a UserAccount entity at all? Or just a User / Person /
Party / Actor entity?
2. How does the packaging look like?
3. Am I completely lost when it comes to distinguishing application vs
domain vs infrastructure services?
4. What does the (Delegating)ProfilePhotoRepository to
(LocalFileSystem)MediaStorage strategy look like?
5. Should there be a ProfilePhoto domain object?
6. Is MailingTokenBasedEmailVerification really an application service? Or
should it be considered a domain service?
7. Is EmailVerificationTokenMailer an application, domain or service or
infrastructure service? It looks like an application process, but it speaks
of domain entities and integrates
   with the mailing infrastructure. Not clear to me what this is. I
consider the JavaMail API to be the infrastructure service here.

Any feedback would be greatly appreciated :)

Thanks a bunch!
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.