IUseCase
This is an interface to a Use Case implementation or otherwise known as a Domain Service
Domain services should not hold state (application services are not domain services, they are on the outer layer close to the UI layer, and can hold application/task state)
Domain services have very little behavior and only which does not fit cohesively in any domain model
Domain services sit in the core domain layer along with entities, value objects, aggregates and domain events, and expose domain models in their interfaces
import { User as UserAggregate } from '@modules/user';
import {
IUseCase,
DomainId,
Result,
UserNameValueObject,
ChangesObserver,
PasswordValueObject,
EmailValueObject,
BirthdayValueObject,
} from '@types-ddd';
export interface SignupDto {
email: string;
name: string;
password: string;
birthDay: Date;
}
export interface IUserRepo {
exists: ({ email: string }) => Promise<boolean>;
save: (user: UserAggregate) => Promise<void>;
}
export class SignupUseCase implements IUseCase<SignupDto, Result<void>> {
constructor(private readonly userRepository: IUserRepo) {}
async execute(dto: SignupDto): Promise<Result<void>> {
try {
const { name, password, email, birthDay } = dto;
const userAlreadyExists = await this.userRepository.exists({ email });
if (userAlreadyExists) {
return Result.fail('User already exists', 'CONFLICT');
}
const observer = ChangesObserver.init();
const nameOrError = UserNameValueObject.create(name);
const passwordOrError = PasswordValueObject.create(password);
const emailOrError = EmailValueObject.create(email);
const birthDayOrError = BirthdayValueObject.create(birthDay);
observer.add(nameOrError);
observer.add(passwordOrError);
observer.add(emailOrError);
observer.add(birthDayOrError);
const isAllValueObjectOk = observer.isAllResultsSuccess();
if (!isAllValueObjectOk) {
const message = observer.getResult().errorValue();
return Result.fail(message);
}
const userName = nameOrError.getResult();
const userPassword = passwordOrError.getResult();
const userEmail = emailOrError.getResult();
const userBirthDay = birthDayOrError.getResult();
userPassword.encrypt();
const userOrError = UserAggregate.create({
ID: DomainId.create(),
userName,
userPassword,
userEmail,
userBirthDay,
});
if (userOrError.isFailure) {
const message = userOrError.errorValue();
return Result.fail(message);
}
const user = userOrError.getResult();
await this.userRepository.save(user);
return Result.success();
} catch (err) {
return Result.fail('Error on SignupUseCase', 'INTERNAL_SERVER_ERROR');
}
}
}
Last updated
Was this helpful?