.
This commit is contained in:
parent
e350e65f37
commit
c040a247e7
@ -57,7 +57,7 @@ export class Password extends StringValueObject {
|
|||||||
return Result.ok(new Password(validationResult.object));
|
return Result.ok(new Password(validationResult.object));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async createFromPlainTextPassword(
|
public static createFromPlainTextPassword(
|
||||||
value: UndefinedOr<string>,
|
value: UndefinedOr<string>,
|
||||||
options: IPasswordOptions = {},
|
options: IPasswordOptions = {},
|
||||||
) {
|
) {
|
||||||
@ -79,7 +79,7 @@ export class Password extends StringValueObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Result.ok(
|
return Result.ok(
|
||||||
new Password(await Password.hashPassword(validationResult.object)),
|
new Password(Password.hashPassword(validationResult.object)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -126,14 +126,14 @@ export abstract class SequelizeRepository<T> implements IRepository<T> {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const _model = this.adapter.getModel(modelName);
|
const _model = this.adapter.getModel(modelName);
|
||||||
|
|
||||||
if (await this._exists(modelName, "id", id.toString())) {
|
if (await this._exists(modelName, "id", id.toPrimitive())) {
|
||||||
await _model.update(
|
await _model.update(
|
||||||
{
|
{
|
||||||
...data,
|
...data,
|
||||||
id: undefined,
|
id: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
where: { id: id.toString() },
|
where: { id: id.toPrimitive() },
|
||||||
transaction: this.transaction,
|
transaction: this.transaction,
|
||||||
...params,
|
...params,
|
||||||
},
|
},
|
||||||
@ -142,7 +142,7 @@ export abstract class SequelizeRepository<T> implements IRepository<T> {
|
|||||||
await _model.create(
|
await _model.create(
|
||||||
{
|
{
|
||||||
...data,
|
...data,
|
||||||
id: id.toString(),
|
id: id.toPrimitive(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
include: [{ all: true }],
|
include: [{ all: true }],
|
||||||
@ -163,7 +163,7 @@ export abstract class SequelizeRepository<T> implements IRepository<T> {
|
|||||||
|
|
||||||
await model.destroy({
|
await model.destroy({
|
||||||
where: {
|
where: {
|
||||||
id: id.toString(),
|
id: id.toPrimitive(),
|
||||||
},
|
},
|
||||||
transaction: this.transaction,
|
transaction: this.transaction,
|
||||||
force,
|
force,
|
||||||
@ -192,7 +192,7 @@ export abstract class SequelizeRepository<T> implements IRepository<T> {
|
|||||||
modelName: string,
|
modelName: string,
|
||||||
ids: UniqueID[] | string[]
|
ids: UniqueID[] | string[]
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const _ids = ids.map((id: UniqueID | string) => id.toString());
|
const _ids = ids.map((id: UniqueID | string) => id.toPrimitive());
|
||||||
|
|
||||||
const destroyedRows: Promise<number> = await this.adapter.models[
|
const destroyedRows: Promise<number> = await this.adapter.models[
|
||||||
modelName
|
modelName
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import {
|
|||||||
IUseCaseError,
|
IUseCaseError,
|
||||||
UseCaseError,
|
UseCaseError,
|
||||||
} from "@/contexts/common/application";
|
} from "@/contexts/common/application";
|
||||||
import { IRepositoryManager } from "@/contexts/common/domain";
|
import { IRepositoryManager, Password } from "@/contexts/common/domain";
|
||||||
import { IInfrastructureError } from "@/contexts/common/infrastructure";
|
import { IInfrastructureError } from "@/contexts/common/infrastructure";
|
||||||
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
||||||
import {
|
import {
|
||||||
@ -12,14 +12,13 @@ import {
|
|||||||
ICreateUser_Request_DTO,
|
ICreateUser_Request_DTO,
|
||||||
IDomainError,
|
IDomainError,
|
||||||
Name,
|
Name,
|
||||||
Password,
|
|
||||||
Result,
|
Result,
|
||||||
UniqueID,
|
UniqueID,
|
||||||
ensureEmailIsValid,
|
ensureEmailIsValid,
|
||||||
ensureIdIsValid,
|
ensureIdIsValid,
|
||||||
|
ensureNameIsValid,
|
||||||
} from "@shared/contexts";
|
} from "@shared/contexts";
|
||||||
import { IUserRepository, User } from "../domain";
|
import { IUserRepository, User } from "../domain";
|
||||||
import { existsUserByEmail, existsUserByID } from "./userServices";
|
|
||||||
|
|
||||||
export type CreateUserResponseOrError =
|
export type CreateUserResponseOrError =
|
||||||
| Result<never, IUseCaseError> // Misc errors (value objects)
|
| Result<never, IUseCaseError> // Misc errors (value objects)
|
||||||
@ -41,15 +40,12 @@ export class CreateUserUseCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
async execute(request: ICreateUser_Request_DTO) {
|
async execute(request: ICreateUser_Request_DTO) {
|
||||||
const { id, email } = request;
|
const { id, name, email } = request;
|
||||||
|
|
||||||
const userRepository = this._getUserRepository();
|
|
||||||
|
|
||||||
// Validaciones de datos
|
// Validaciones de datos
|
||||||
|
const idOrError = ensureIdIsValid(id);
|
||||||
const userIdOrError = ensureIdIsValid(id);
|
if (idOrError.isFailure) {
|
||||||
if (userIdOrError.isFailure) {
|
const message = idOrError.error.message; //`User ID ${userDTO.id} is not valid`;
|
||||||
const message = userIdOrError.error.message; //`User ID ${userDTO.id} is not valid`;
|
|
||||||
return Result.fail(
|
return Result.fail(
|
||||||
UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message, [
|
UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message, [
|
||||||
{ path: "id" },
|
{ path: "id" },
|
||||||
@ -57,13 +53,32 @@ export class CreateUserUseCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const idExists = await existsUserByID(
|
const nameOrError = ensureNameIsValid(name);
|
||||||
userIdOrError.object,
|
if (nameOrError.isFailure) {
|
||||||
this._adapter,
|
const message = nameOrError.error.message; //`User ID ${userDTO.id} is not valid`;
|
||||||
userRepository,
|
return Result.fail(
|
||||||
);
|
UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message, [
|
||||||
|
{ path: "name" },
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const emailOrError = ensureEmailIsValid(email);
|
||||||
|
if (emailOrError.isFailure) {
|
||||||
|
const message = emailOrError.error.message;
|
||||||
|
return Result.fail(
|
||||||
|
UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message, [
|
||||||
|
{ path: "email" },
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comprobar que no existe un usuario previo con esos datos
|
||||||
|
const userRepository = this._getUserRepository();
|
||||||
|
|
||||||
|
const idExists = await userRepository().existsUserWithId(idOrError.object);
|
||||||
if (idExists) {
|
if (idExists) {
|
||||||
const message = `Another user with ID ${id} exists`;
|
const message = `Another user with same ID exists`;
|
||||||
return Result.fail(
|
return Result.fail(
|
||||||
UseCaseError.create(UseCaseError.RESOURCE_ALREADY_EXITS, message, {
|
UseCaseError.create(UseCaseError.RESOURCE_ALREADY_EXITS, message, {
|
||||||
path: "id",
|
path: "id",
|
||||||
@ -71,38 +86,33 @@ export class CreateUserUseCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const emailOrError = ensureEmailIsValid(email);
|
const nameExists = await userRepository().existsUserWithName(
|
||||||
if (emailOrError.isFailure) {
|
nameOrError.object,
|
||||||
|
);
|
||||||
|
if (nameExists) {
|
||||||
|
const message = `Another user with same name exists`;
|
||||||
return Result.fail(
|
return Result.fail(
|
||||||
UseCaseError.create(
|
UseCaseError.create(UseCaseError.RESOURCE_ALREADY_EXITS, message, {
|
||||||
UseCaseError.INVALID_INPUT_DATA,
|
path: "name",
|
||||||
"Email or password is not valid",
|
}),
|
||||||
emailOrError.error,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const emailExists = await existsUserByEmail(
|
const emailExists = await userRepository().existsUserWithEmail(
|
||||||
emailOrError.object,
|
emailOrError.object,
|
||||||
this._adapter,
|
|
||||||
userRepository,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (emailExists) {
|
if (emailExists) {
|
||||||
|
const message = `Another user with same email exists`;
|
||||||
return Result.fail(
|
return Result.fail(
|
||||||
UseCaseError.create(
|
UseCaseError.create(UseCaseError.RESOURCE_ALREADY_EXITS, message, {
|
||||||
UseCaseError.RESOURCE_ALREADY_EXITS,
|
path: "email",
|
||||||
`Another user with email ${email} exists`,
|
}),
|
||||||
{ path: "email" },
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crear user
|
// Crear user
|
||||||
const userOrError = this._tryCreateUserInstance(
|
const userOrError = this._tryCreateUserInstance(request, idOrError.object);
|
||||||
request,
|
|
||||||
userIdOrError.object,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (userOrError.isFailure) {
|
if (userOrError.isFailure) {
|
||||||
const { error: domainError } = userOrError;
|
const { error: domainError } = userOrError;
|
||||||
@ -180,7 +190,9 @@ export class CreateUserUseCase
|
|||||||
return Result.fail(emailOrError.error);
|
return Result.fail(emailOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const passwordOrError = Password.createFromPlainText(userDTO.password);
|
const passwordOrError = Password.createFromPlainTextPassword(
|
||||||
|
userDTO.password,
|
||||||
|
);
|
||||||
if (passwordOrError.isFailure) {
|
if (passwordOrError.isFailure) {
|
||||||
return Result.fail(passwordOrError.error);
|
return Result.fail(passwordOrError.error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
import { IRepository } from "@/contexts/common/domain";
|
import { IRepository } from "@/contexts/common/domain";
|
||||||
import { Email, ICollection, IQueryCriteria, UniqueID } from "@shared/contexts";
|
import {
|
||||||
|
Email,
|
||||||
|
ICollection,
|
||||||
|
IQueryCriteria,
|
||||||
|
Name,
|
||||||
|
UniqueID,
|
||||||
|
} from "@shared/contexts";
|
||||||
import { User } from "../entities";
|
import { User } from "../entities";
|
||||||
|
|
||||||
export interface IUserRepository extends IRepository<any> {
|
export interface IUserRepository extends IRepository<any> {
|
||||||
@ -13,5 +19,6 @@ export interface IUserRepository extends IRepository<any> {
|
|||||||
removeById(id: UniqueID): Promise<void>;
|
removeById(id: UniqueID): Promise<void>;
|
||||||
|
|
||||||
existsUserWithId(id: UniqueID): Promise<boolean>;
|
existsUserWithId(id: UniqueID): Promise<boolean>;
|
||||||
|
existsUserWithName(name: Name): Promise<boolean>;
|
||||||
existsUserWithEmail(email: Email): Promise<boolean>;
|
existsUserWithEmail(email: Email): Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,13 @@ import {
|
|||||||
ISequelizeAdapter,
|
ISequelizeAdapter,
|
||||||
SequelizeRepository,
|
SequelizeRepository,
|
||||||
} from "@/contexts/common/infrastructure/sequelize";
|
} from "@/contexts/common/infrastructure/sequelize";
|
||||||
import { Email, ICollection, IQueryCriteria, UniqueID } from "@shared/contexts";
|
import {
|
||||||
|
Email,
|
||||||
|
ICollection,
|
||||||
|
IQueryCriteria,
|
||||||
|
Name,
|
||||||
|
UniqueID,
|
||||||
|
} from "@shared/contexts";
|
||||||
import { Transaction } from "sequelize";
|
import { Transaction } from "sequelize";
|
||||||
import { User } from "../domain";
|
import { User } from "../domain";
|
||||||
import { IUserRepository } from "../domain/repository";
|
import { IUserRepository } from "../domain/repository";
|
||||||
@ -40,7 +46,6 @@ export class UserRepository
|
|||||||
|
|
||||||
// borrando y luego creando
|
// borrando y luego creando
|
||||||
await this.removeById(user.id, true);
|
await this.removeById(user.id, true);
|
||||||
|
|
||||||
await this._save("User_Model", user.id, userData, {});
|
await this._save("User_Model", user.id, userData, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +92,15 @@ export class UserRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async existsUserWithId(id: UniqueID): Promise<boolean> {
|
public async existsUserWithId(id: UniqueID): Promise<boolean> {
|
||||||
return this._exists("User_Model", "id", id.toString());
|
return this._exists("User_Model", "id", id.toPrimitive());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async existsUserWithName(name: Name): Promise<boolean> {
|
||||||
|
return this._exists("User_Model", "name", name.toPrimitive());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async existsUserWithEmail(email: Email): Promise<boolean> {
|
public async existsUserWithEmail(email: Email): Promise<boolean> {
|
||||||
return this._exists("User_Model", "email", email.toString());
|
return this._exists("User_Model", "email", email.toPrimitive());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user