thenativeweb / node-cqrs-domain

Node-cqrs-domain is a node.js module based on nodeEventStore that. It can be very useful as domain component if you work with (d)ddd, cqrs, eventdenormalizer, host, etc.
http://cqrs.js.org/pages/domain.html
MIT License
269 stars 57 forks source link

Unique entity business rule #70

Closed gstrit closed 8 years ago

gstrit commented 8 years ago

Hi, I don't understand how to create a business rule which says : email adress is unique for all persons. I'm not able to access to the persons repository. Thanks

adrai commented 8 years ago

business rules only applies on 1 aggregate (so you may need a personS aggregate)

gstrit commented 8 years ago

I have to have a person and a persons aggregate ? I'm not sure to understand how it should work

adrai commented 8 years ago

no, just a persons aggregate

gstrit commented 8 years ago

OK but can I apply a command createOnePerson to the persons aggregate ? Thank you for your answers

adrai commented 8 years ago

Yes, an aggregate is not an object. it's a container for intensions.

gstrit commented 8 years ago

Ok I understand now how it should work but it doesn't work...

module.exports = require('cqrs-domain').definePreCondition({
    name: 'createPlayer',
    version: 0,
    description: 'unique email address'
}, function (data, agg) {
    var found = _.find(agg.get('players'), function (player) {
      return player.firstname === data.firstname;
    });
    if (found) {
      throw new Error('email already used');
    }
});

agg.get('players') is always empty.

adrai commented 8 years ago

how does your defineEvent file for playerCreated looks like?

gstrit commented 8 years ago
module.exports = require('cqrs-domain').defineEvent({
  name: 'playerCreated'
},
function (data, aggregate) {
    aggregate.get('players').push(data);
});
adrai commented 8 years ago

is that function called?

gstrit commented 8 years ago

yes it is

adrai commented 8 years ago

do you have this project hosted on github? can i look at it?

gstrit commented 8 years ago

https://github.com/gstrit/Test

adrai commented 8 years ago

You have to send all createPlayer commands with the same aggregateId

gstrit commented 8 years ago

In my domain, a player is an aggregate root not the collection. If I understand how it works, when a client send a command to update a player, he has to fill the id of the collection as the aggregateId and not the id of the player, right ?

adrai commented 8 years ago

no... to play a bit, just extend your commands with (cmd.payload.id = 'same aggregate Id for all commands';)

the id of your collection player should be passed in the payload like (cmd.payload.playerId = vm.id;)

gstrit commented 8 years ago

Ok thanks