I'm currently developing message imap-based module in crm app and i'm trying to connect dots using ddd principals.
I've started with three main entities, all bound under Account Aggregate:
- Account - Email account. Has multiple Folders.
- Folder - Folder in email account (ex. Inbox, Sent, Draft). Has multiple Messages.
- Message - Email message.
In this case invariant is on the actual collections, mostly between Account and Folder:
- Account can't have two folders with the same name,
- Account can't have multiple special folders (like Inbox or Sent),
- Mailbox should have actual message count.
With this solution i ended with breaking rule of creating small aggregates. This also can cause performance issues. Almost every account has around six folders, that can contains thousands of messages. The amount of data loaded to memory. Then I tried to split it to two aggregates Account (with Folder as local entity) and Message. In this case I'm breaking rule of referencing local entity (Folder) to another aggregate (Message), because message is bounded to specific folder.
In the end I tried to split them all to separate aggregates. In that case, no aggregate rules are broken, but I'm breaking invariant between Account and Folder. As a result there is need of adding another layer of complexity using domain services and threat of most likely updating at least two aggregates in one transaction. Also this forces Folder, as it's entity between aggregates to become aggregate root while it never meant be one.
What is the best way to split this entities in this case?
[Edit] I added additional information based on comments.