Best appoach to pre creation bus rules for aggregate

Hi, I’m trying to determine the best way to implement certain business rules. For most cases, In a command handler, I grab the aggregate in question by it’s id, then perform my checks, then failing or proceeding based on their outcome. But creation scenarios are a little different. Let’s say I have an event sourced Aggregate “User”:

So I have a CreateUserCommmand(id:String,email:String,…). So one of my business rules would be say ensuring that I can’t create a second user with the same email. Since I have no way to ‘search’ my aggregate repo for user, is it ‘ok’ to query the read model? I’m just asking as it’s a bit of a departure from most rules which act on the data in the aggregate instances. It’s also a bit sensitive to timing issues, if I’m using eventual consistency on the read model (I’m not, yet… lol) Any suggestions would be appreciated.

If I'm not mistaken this is what the DDD/CQRS posse would call a case
of set validation and the topic has been heavily discussed. Some sort
of query is more or less the only feasible solution here and then it
depends on how specialized/generalized you want query models to be. Do
you want one table of de-normalized data for every screen of your
application or more of a traditional model with a table/row per
aggregate-type/instance and then picking and choosing one ore several
columns from one or several tables when you want to build a view (or
something in between).

For this case I would probably create some sort of a query-model with
an entry for every username that is taken which is used solely for
this purpose. The second component is an interceptor that checks the
incoming create-commands against this query-model and rejects the
command if it contains a duplicate username. You can then choose,
depending on your requirements to update this model either on events
or commands. The first would probably give you a quicker response on
the create command but also a small window where duplicates might
arise and the second would give you a higher latency but also better

Hope this helps : )