import { Password } from "@/contexts/common/domain"; import { AggregateRoot, Email, IDomainError, Language, Name, Result, UniqueID, handleDomainError, } from "@shared/contexts"; import { UserHasName } from "./User.specifications"; import { UserRole } from "./UserRole"; export interface IUserProps { name: Name; email: Email; password: Password; roles: UserRole[]; language: Language; } //type ISecuredUserProps = ; export interface IUser { id: UniqueID; name: Name; email: Email; password: Password; language: Language; isUser: boolean; isAdmin: boolean; } export class User extends AggregateRoot implements IUser { static readonly ERROR_USER_WITHOUT_NAME = "ERROR_USER_WITHOUT_NAME"; public static create(props: IUserProps, id?: UniqueID): Result { const user = new User(props, id); // Reglas de negocio / validaciones const isValidUser = new UserHasName().isSatisfiedBy(user); if (!isValidUser) { return Result.fail(handleDomainError(User.ERROR_USER_WITHOUT_NAME)); } return Result.ok(user); } public static async hashPassword(password): Promise { return Password.hashPassword(password); } private roles: UserRole[]; constructor(props: IUserProps, id?: UniqueID) { const { roles } = props; super(props, id); this.roles = roles; } get name(): Name { return this.props.name; } get email(): Email { return this.props.email; } get password(): Password { return this.props.password; } get language(): Language { return this.props.language; } get isUser(): boolean { return this.hasRole(UserRole.ROLE_USER); } get isAdmin(): boolean { return this.hasRole(UserRole.ROLE_ADMIN); } public hasRole(role: UserRole): boolean { return this.roles.some((r) => r.equals(role)); } public getRoles(): UserRole[] { return this.roles; } public addRole(role: UserRole): void { if (!this.roles.some((r) => r.equals(role))) { this.roles.push(role); } } public removeRole(role: UserRole): void { this.roles = this.roles.filter((r) => !r.equals(role)); } }