My system has the language of a "Contact" which is a sort of "ghost user" that we have some information on - it's validation rules are slim and it's state is largely contact information. We also have a concept of a "User" which is a fully-vetted and registered user. Think of a "User" as a fleshed out "Contact".
The lifecycle we are trying to capture is that a "Contact" will be replaced by a "User" once someone registers with that "Contact"s information.
We have other aggregate roots in the system that make reference to a "ContactId" pointing to the UUID of a "Contact". When that "Contact" registers, we'd like to use a new concept of a "User" to represent them in the domain and the "User" now has it's own "UserID" UUID.
- How can we keep relationships that still reference the "Contact" via a ContactID, to now reference the "User" via a UserID?
- Is there a fundamental problem with trying to transition my aggregate into another one?
- If so, how should I model this particular lifecycle of a "Contact" -> "Registered User"?
- If the answer is to merge the two ideas into a single aggregate root, how can I keep my domain objects being valid at all times, despite a "User" not being valid until this "Contact" actually registers?
As a side note, we are using CQRS/ES for the overall architecture.
Thanks!