This implementation is without domain events, instead of events there are nested aggregates.
export class WarehouseEntity implements Attributes {
id: string;
name: string;
orders: OrderEntity[];
report?: ReportEntity; // nested aggregate
constructor(attributes: Attributes) {
this.id = attributes.id;
this.name = attributes.name;
this.orders = attributes.orders;
}
addOrder(order: OrderEntity) {
this.orders.push(order);
}
changeOrderStatusToValid(orderId: string, report: ReportEntity) {
const order = this.orders.find((el) => el.id === orderId);
order.changeStatus(true);
this.report = report;
}
}
If you are interested in the option with domain events, then follow the link
Domain model with a clean architecture with ports and adapters. It takes into account some tactical patterns from DDD.
![architecture schema](https://private-user-images.githubusercontent.com/44276887/297869254-0b862b4e-6d1e-4882-bb29-1653f296cd56.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTQ0NzQyOTcsIm5iZiI6MTcxNDQ3Mzk5NywicGF0aCI6Ii80NDI3Njg4Ny8yOTc4NjkyNTQtMGI4NjJiNGUtNmQxZS00ODgyLWJiMjktMTY1M2YyOTZjZDU2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA0MzAlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNDMwVDEwNDYzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBlMTQ1YTI2MTI5M2Y1NjZjNWJlNTNkNDYzNmRiNTZhNjZkZDY1Yjc5YzI2ZjQxNGQ2NmIyYzljNjA2NTc1ZjQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.pChVnbbxdmXskqUMDSv8O_SaCCnuoBZciYESKiFnZ3E)
npm install
# development
$ cp .env.example .env
$ npm run start:dev
# unit tests
$ npm run test
# arch tests
$ npm run test:arch
# test coverage
$ npm run test:cov