CLARIFICATION: There's a few articles around this point, I am trying to understand based on my use-case, what would you recommend as the AGGREGATE ROOT
Given a domain that allows creating new invoices with a constraint that each invoice must be unique (Identified by a code, set by the issuer's system, eg: INV-1021) per customer.
The issuer's system and how they generate those codes are completely outside of our scope, all we care about is that to make sure that when our system/domain persists an invoice it's unique in our system per customer, to avoid potential problems.
The solutions I currently have are:
- Invoice as an aggregate root: Create a repository implementation (Domain Service) that find an invoice by code and customerId and I could use this interface in my Domain as a business invariant check to the creation/registration behavior for a new Invoice Aggregate Root but since this might not be the responsibility of the Invoice AR, I could just move the behavior of creation to the domain service, without leaking logic outside of the Domain Layer.
- Company as an Aggregate Root: While searching for an answer I found this article and it made me think, it might make more sense to have Company as the AR and by loading the AR, it would be a simple memory check in the domain (I don't think it would be a problem from a performance standing point), but the problem is that the only Company behavior is invoice creation, but the rest of the domain logic is all executed on the invoice itself, so even though company is my scope (referencing the article) but it does not feel right and also I am not sure if it's worth the violations of having to manipulate the invoice via the Company AR all the time (99% of the logic of this domain) and not saving the Aggregate Root as whole because I will be interested in modifying the Invoice and not the Company.
- This function is not highly concurrent, however it's likely that a user make a mistake of uploading/registering the same invoice twice.
- I have read some comments that says that duplication is a database concern but I am not sure if that would be applicable here, since the uniqueness is a business constraint that's been mentioned several times by domain experts.
- Listing my options helped me feel that the first solution seems like the way to go, but being a DDD newbie, I am interested to hear the opinion of a more experienced person.