register user with id

This commit is contained in:
sbriat 2023-10-10 12:05:49 +02:00
parent 8e07b3b02a
commit 0937b70b48
7 changed files with 44 additions and 7 deletions

View File

@ -1,6 +1,7 @@
import { Command, CommandProps } from '@mobicoop/ddd-library';
export class CreateUserCommand extends Command {
readonly userId?: string;
readonly firstName?: string;
readonly lastName?: string;
readonly email?: string;
@ -8,6 +9,7 @@ export class CreateUserCommand extends Command {
constructor(props: CommandProps<CreateUserCommand>) {
super(props);
this.userId = props.userId;
this.firstName = props.firstName;
this.lastName = props.lastName;
this.email = props.email;

View File

@ -24,6 +24,7 @@ export class CreateUserService implements ICommandHandler {
async execute(command: CreateUserCommand): Promise<AggregateID> {
const user = UserEntity.create({
id: command.userId,
firstName: command.firstName,
lastName: command.lastName,
email: command.email,

View File

@ -9,7 +9,7 @@ export class UserEntity extends AggregateRoot<UserProps> {
protected readonly _id: AggregateID;
static create = (create: CreateUserProps): UserEntity => {
const id = v4();
const id = create.id ?? v4();
const props: UserProps = { ...create };
const user = new UserEntity({ id, props });

View File

@ -8,6 +8,7 @@ export interface UserProps {
// Properties that are needed for a User creation
export interface CreateUserProps {
id?: string;
firstName?: string;
lastName?: string;
email?: string;

View File

@ -24,10 +24,18 @@ export class CreateUserGrpcController {
constructor(private readonly commandBus: CommandBus) {}
@GrpcMethod('UserService', 'Create')
async create(data: CreateUserRequestDto): Promise<IdResponse> {
async create(
createUserRequestDto: CreateUserRequestDto,
): Promise<IdResponse> {
try {
const aggregateID: AggregateID = await this.commandBus.execute(
new CreateUserCommand(data),
new CreateUserCommand({
firstName: createUserRequestDto.firstName,
lastName: createUserRequestDto.lastName,
email: createUserRequestDto.email,
phone: createUserRequestDto.phone,
userId: createUserRequestDto.id,
}),
);
return new IdResponse(aggregateID);
} catch (error: any) {

View File

@ -1,13 +1,23 @@
import { IsEmail, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import {
IsEmail,
IsOptional,
IsPhoneNumber,
IsString,
IsUUID,
} from 'class-validator';
export class CreateUserRequestDto {
@IsString()
@IsUUID(4)
@IsOptional()
firstName: string;
id?: string;
@IsString()
@IsOptional()
lastName: string;
firstName?: string;
@IsString()
@IsOptional()
lastName?: string;
@IsEmail()
@IsOptional()

View File

@ -14,6 +14,14 @@ const createUserProps: CreateUserProps = {
phone: '+33611223344',
};
const createUserPropsWithId: CreateUserProps = {
id: '66378860-cb75-40de-b6eb-061faf923fee',
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@email.com',
phone: '+33611223344',
};
const updateUserProps: UpdateUserProps = {
firstName: 'Jane',
lastName: 'Dane',
@ -28,6 +36,13 @@ describe('User entity create', () => {
expect(userEntity.domainEvents.length).toBe(1);
expect(userEntity.domainEvents[0]).toBeInstanceOf(UserCreatedDomainEvent);
});
it('should create a new user entity with a given id', async () => {
const userEntity: UserEntity = UserEntity.create(createUserPropsWithId);
expect(userEntity.id).toBe('66378860-cb75-40de-b6eb-061faf923fee');
expect(userEntity.getProps().email).toBe('john.doe@email.com');
expect(userEntity.domainEvents.length).toBe(1);
expect(userEntity.domainEvents[0]).toBeInstanceOf(UserCreatedDomainEvent);
});
});
describe('User entity update', () => {