Skip to content

Commit 489dc67

Browse files
committed
Added initial state of the unpeeled onion as the preparation for slimming it down.
1 parent b228890 commit 489dc67

34 files changed

+1054
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { getApplication } from '#core/api';
2+
import { MongoClient } from 'mongodb';
3+
import registerHandlers from './application/shoppingCarts';
4+
import controllers from './controllers';
5+
6+
const initApp = (mongo: MongoClient) => {
7+
registerHandlers(mongo);
8+
return getApplication(...controllers);
9+
};
10+
11+
export default initApp;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { CommandHandler } from '#core/commands';
2+
import { EventBus } from '#core/events';
3+
import { ShoppingCartRepository } from 'src/unpeeled/ecommerce/infrastructure/shoppingCarts/shoppingCartRepository';
4+
import { AddProductItemToShoppingCart } from '../commands/shoppingCarts/addProductItemToShoppingCart';
5+
import { ShoppingCartMapper } from '../mappers/shoppingCartMapper';
6+
7+
export class AddProductItemToShoppingCartHandler
8+
implements CommandHandler<AddProductItemToShoppingCart>
9+
{
10+
constructor(
11+
private repository: ShoppingCartRepository,
12+
private mapper: ShoppingCartMapper,
13+
private eventBus: EventBus
14+
) {}
15+
16+
async handle(command: AddProductItemToShoppingCart): Promise<void> {
17+
const model = await this.repository.find(command.shoppingCartId);
18+
19+
if (model === null) {
20+
throw Error(`Shopping cart with id ${command.shoppingCartId} not found!`);
21+
}
22+
23+
const aggregate = this.mapper.toAggregate(model);
24+
aggregate.addProductItem(command.productItem);
25+
26+
await this.repository.add(this.mapper.toModel(aggregate));
27+
28+
for (const event of aggregate.dequeueUncomittedEvents()) {
29+
await this.eventBus.publish(event);
30+
}
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { CommandHandler } from '#core/commands';
2+
import { EventBus } from '#core/events';
3+
import { ShoppingCartRepository } from 'src/unpeeled/ecommerce/infrastructure/shoppingCarts/shoppingCartRepository';
4+
import { ConfirmShoppingCart } from '../commands/shoppingCarts/confirmShoppingCart';
5+
import { ShoppingCartMapper } from '../mappers/shoppingCartMapper';
6+
7+
export class ConfirmShoppingCartHandler
8+
implements CommandHandler<ConfirmShoppingCart>
9+
{
10+
constructor(
11+
private repository: ShoppingCartRepository,
12+
private mapper: ShoppingCartMapper,
13+
private eventBus: EventBus
14+
) {}
15+
16+
async handle(command: ConfirmShoppingCart): Promise<void> {
17+
const model = await this.repository.find(command.shoppingCartId);
18+
19+
if (model === null) {
20+
throw Error(`Shopping cart with id ${command.shoppingCartId} not found!`);
21+
}
22+
23+
const aggregate = this.mapper.toAggregate(model);
24+
aggregate.confirm();
25+
26+
await this.repository.add(this.mapper.toModel(aggregate));
27+
28+
for (const event of aggregate.dequeueUncomittedEvents()) {
29+
await this.eventBus.publish(event);
30+
}
31+
}
32+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { CommandHandler } from '#core/commands';
2+
import { OpenShoppingCart } from '../commands/shoppingCarts/openShoppingCart';
3+
import { ShoppingCart } from 'src/unpeeled/ecommerce/domain/shoppingCarts';
4+
import { ShoppingCartRepository } from 'src/unpeeled/ecommerce/infrastructure/shoppingCarts/shoppingCartRepository';
5+
import { ShoppingCartMapper } from '../mappers/shoppingCartMapper';
6+
import { EventBus } from '#core/events';
7+
8+
export class OpenShoppingCartHandler
9+
implements CommandHandler<OpenShoppingCart>
10+
{
11+
constructor(
12+
private repository: ShoppingCartRepository,
13+
private mapper: ShoppingCartMapper,
14+
private eventBus: EventBus
15+
) {}
16+
17+
async handle(command: OpenShoppingCart): Promise<void> {
18+
const aggregate = ShoppingCart.open(
19+
command.shoppingCartId,
20+
command.customerId
21+
);
22+
23+
await this.repository.add(this.mapper.toModel(aggregate));
24+
25+
for (const event of aggregate.dequeueUncomittedEvents()) {
26+
await this.eventBus.publish(event);
27+
}
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { CommandHandler } from '#core/commands';
2+
import { EventBus } from '#core/events';
3+
import { ShoppingCartRepository } from 'src/unpeeled/ecommerce/infrastructure/shoppingCarts/shoppingCartRepository';
4+
import { RemoveProductItemFromShoppingCart } from '../commands/shoppingCarts/removeProductItemFromShoppingCart';
5+
import { ShoppingCartMapper } from '../mappers/shoppingCartMapper';
6+
7+
export class RemoveProductItemFromShoppingCartHandler
8+
implements CommandHandler<RemoveProductItemFromShoppingCart>
9+
{
10+
constructor(
11+
private repository: ShoppingCartRepository,
12+
private mapper: ShoppingCartMapper,
13+
private eventBus: EventBus
14+
) {}
15+
16+
async handle(command: RemoveProductItemFromShoppingCart): Promise<void> {
17+
const model = await this.repository.find(command.shoppingCartId);
18+
19+
if (model === null) {
20+
throw Error(`Shopping cart with id ${command.shoppingCartId} not found!`);
21+
}
22+
23+
const aggregate = this.mapper.toAggregate(model);
24+
aggregate.removeProductItem(command.productItem);
25+
26+
await this.repository.add(this.mapper.toModel(aggregate));
27+
28+
for (const event of aggregate.dequeueUncomittedEvents()) {
29+
await this.eventBus.publish(event);
30+
}
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Command } from '#core/commands';
2+
import { ProductItem } from 'src/unpeeled/ecommerce/common/shoppingCarts/productItem';
3+
4+
export class AddProductItemToShoppingCart extends Command {
5+
constructor(
6+
public readonly shoppingCartId: string,
7+
public readonly productItem: ProductItem
8+
) {
9+
super();
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Command } from '#core/commands';
2+
3+
export class ConfirmShoppingCart extends Command {
4+
constructor(public readonly shoppingCartId: string) {
5+
super();
6+
}
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Command } from '#core/commands';
2+
3+
export class OpenShoppingCart extends Command {
4+
constructor(
5+
public readonly shoppingCartId: string,
6+
public readonly customerId: string
7+
) {
8+
super();
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Command } from '#core/commands';
2+
import { ProductItem } from 'src/unpeeled/ecommerce/common/shoppingCarts/productItem';
3+
4+
export class RemoveProductItemFromShoppingCart extends Command {
5+
constructor(
6+
public readonly shoppingCartId: string,
7+
public readonly productItem: ProductItem
8+
) {
9+
super();
10+
}
11+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { MongoClient } from 'mongodb';
2+
import { registerCommandHandler } from '#core/commands';
3+
import { registerQueryHandler } from '#core/queries';
4+
import { OpenShoppingCart } from 'src/unpeeled/ecommerce/application/shoppingCarts/commands/shoppingCarts/openShoppingCart';
5+
import { GetShoppingCartById } from 'src/unpeeled/ecommerce/application/shoppingCarts/queries/getShoppingCartById';
6+
import { AddProductItemToShoppingCart } from 'src/unpeeled/ecommerce/application/shoppingCarts/commands/shoppingCarts/addProductItemToShoppingCart';
7+
import { RemoveProductItemFromShoppingCart } from './commands/shoppingCarts/removeProductItemFromShoppingCart';
8+
import { ShoppingCartMapper } from './mappers/shoppingCartMapper';
9+
import { OpenShoppingCartHandler } from './commandHandlers/openShoppingCartHandler';
10+
import { AddProductItemToShoppingCartHandler } from './commandHandlers/addProductToShoppingCartHandler';
11+
import { RemoveProductItemFromShoppingCartHandler } from './commandHandlers/removeProductFromShoppingCartHandler';
12+
import { GetShoppingCartByIdHandler } from './queryHandlers/getShoppingCartByIdQueryHandler';
13+
import { MongoDBShoppingCartRepository } from 'src/unpeeled/ecommerce/infrastructure/shoppingCarts/shoppingCartRepository';
14+
import { ConfirmShoppingCart } from './commands/shoppingCarts/confirmShoppingCart';
15+
import { ConfirmShoppingCartHandler } from './commandHandlers/confirmShoppingCart';
16+
import { GetCustomerShoppingHistory } from './queries/getCustomerShoppingHistory';
17+
import { GetCustomerShoppingHistoryHandler } from './queryHandlers/getCustomerShoppingHistoryHandler';
18+
import { CustomerShoppingHistoryMapper } from './mappers/customerShoppingHistoryMapper';
19+
import { EventBusFactory } from '#core/events';
20+
21+
const registerHandlers = (mongo: MongoClient) => {
22+
const repository = new MongoDBShoppingCartRepository(mongo);
23+
const eventBus = EventBusFactory();
24+
25+
const shoppingCartMapper = new ShoppingCartMapper();
26+
const shoppingHistoryMapper = new CustomerShoppingHistoryMapper();
27+
28+
registerCommandHandler(
29+
OpenShoppingCart,
30+
new OpenShoppingCartHandler(repository, shoppingCartMapper, eventBus)
31+
);
32+
registerCommandHandler(
33+
AddProductItemToShoppingCart,
34+
new AddProductItemToShoppingCartHandler(
35+
repository,
36+
shoppingCartMapper,
37+
eventBus
38+
)
39+
);
40+
registerCommandHandler(
41+
RemoveProductItemFromShoppingCart,
42+
new RemoveProductItemFromShoppingCartHandler(
43+
repository,
44+
shoppingCartMapper,
45+
eventBus
46+
)
47+
);
48+
registerCommandHandler(
49+
ConfirmShoppingCart,
50+
new ConfirmShoppingCartHandler(repository, shoppingCartMapper, eventBus)
51+
);
52+
registerQueryHandler(
53+
GetShoppingCartById,
54+
new GetShoppingCartByIdHandler(repository)
55+
);
56+
registerQueryHandler(
57+
GetCustomerShoppingHistory,
58+
new GetCustomerShoppingHistoryHandler(repository, shoppingHistoryMapper)
59+
);
60+
};
61+
62+
export default registerHandlers;

0 commit comments

Comments
 (0)