forked from Sairyss/domain-driven-hexagon
-
Notifications
You must be signed in to change notification settings - Fork 1
/
create-user.service.ts
49 lines (44 loc) · 1.87 KB
/
create-user.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { ID } from '@libs/ddd/domain/value-objects/id.value-object';
import { UserRepositoryPort } from '@modules/user/database/user.repository.port';
import { Address } from '@modules/user/domain/value-objects/address.value-object';
import { Email } from '@modules/user/domain/value-objects/email.value-object';
import { UnitOfWork } from '@src/infrastructure/database/unit-of-work/unit-of-work';
import { CommandHandler } from '@nestjs/cqrs';
import { CommandHandlerBase } from '@src/libs/ddd/domain/base-classes/command-handler.base';
import { Err, Ok, Result } from 'oxide.ts/dist';
import { CreateUserCommand } from './create-user.command';
import { UserEntity } from '../../domain/entities/user.entity';
import { UserAlreadyExistsError } from '../../errors/user.errors';
@CommandHandler(CreateUserCommand)
export class CreateUserService extends CommandHandlerBase {
constructor(protected readonly unitOfWork: UnitOfWork) {
super(unitOfWork);
}
async handle(
command: CreateUserCommand,
): Promise<Result<ID, UserAlreadyExistsError>> {
/* Use a repository provided by UnitOfWork to include everything
(including changes caused by Domain Events) into one
atomic database transaction */
const userRepo: UserRepositoryPort = this.unitOfWork.getUserRepository(
command.correlationId,
);
// user uniqueness guard
if (await userRepo.exists(command.email)) {
/** Returning an Error instead of throwing it
* so a controller can handle it explicitly */
return Err(new UserAlreadyExistsError());
}
const user = UserEntity.create({
email: new Email(command.email),
address: new Address({
country: command.country,
postalCode: command.postalCode,
street: command.street,
}),
});
user.someBusinessLogic();
const created = await userRepo.save(user);
return Ok(created.id);
}
}