This commit is contained in:
David Arranz 2025-02-21 11:06:27 +01:00
parent 085a390aa6
commit 829c839f9b
36 changed files with 211 additions and 237 deletions

View File

@ -1,5 +1,6 @@
import { Maybe, Result, ValueObject } from "@common/domain";
import { Maybe, Result } from "@common/helpers";
import { z } from "zod";
import { ValueObject } from "./value-object";
interface EmailAddressProps {
value: string;
@ -47,4 +48,8 @@ export class EmailAddress extends ValueObject<EmailAddressProps> {
getValue(): string {
return this.props.value;
}
toString(): string {
return this.getValue();
}
}

View File

@ -1,5 +1,6 @@
import { Maybe, Result, ValueObject } from "@common/domain";
import { Maybe, Result } from "@common/helpers";
import { z } from "zod";
import { ValueObject } from "./value-object";
interface NameProps {
value: string;

View File

@ -1,5 +1,6 @@
import { Maybe, Result, ValueObject } from "@common/domain";
import { Maybe, Result } from "@common/helpers";
import { z } from "zod";
import { ValueObject } from "./value-object";
interface SlugProps {
value: string;
@ -35,7 +36,7 @@ export class Slug extends ValueObject<SlugProps> {
return Result.ok(Maybe.None<Slug>());
}
return Slug.create(value!).map((value) => Maybe.Some(value));
return Slug.create(value!).map((value: Slug) => Maybe.Some(value));
}
getValue(): string {

View File

@ -1,4 +1,4 @@
import { Result } from "@common/domain";
import { Result } from "@common/helpers";
import { ITransactionManager } from "@common/infrastructure/database";
import { User } from "@contexts/auth/domain";
import { IUserService } from "@contexts/auth/domain/services";

View File

@ -1,6 +1,8 @@
import { AggregateRoot, Result, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { AggregateRoot, EmailAddress, UniqueID } from "@common/domain";
import { UserAuthenticatedEvent } from "../events";
import { EmailAddress, HashPassword, PlainPassword, Username } from "../value-objects";
import { HashPassword, PlainPassword, Username } from "../value-objects";
export interface IAuthenticatedUserProps {
username: Username;
@ -12,6 +14,7 @@ export interface IAuthenticatedUserProps {
export interface IAuthenticatedUser {
username: Username;
email: EmailAddress;
hashPassword: HashPassword;
accessToken: string;
refreshToken: string;
@ -67,6 +70,10 @@ export class AuthenticatedUser
return this.props.email;
}
get hashPassword(): HashPassword {
return this.props.hashPassword;
}
get isUser(): boolean {
return this.hasRole("user");
}
@ -79,14 +86,6 @@ export class AuthenticatedUser
* 🔹 Devuelve una representación lista para persistencia
*/
toPersistenceData(): any {
return {
id: this.id.toString(),
username: this.props.username.toString(),
email: this.props.email.toString(),
hash_password: this.props.hashPassword.toString(),
roles: this.props.roles.map((role) => role.toString()),
access_token: this.accessToken,
refresh_token: this.refreshToken,
};
return;
}
}

View File

@ -1,4 +1,5 @@
import { AggregateRoot, Result, UniqueID } from "@common/domain";
import { AggregateRoot, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
export interface IRoleProps {}

View File

@ -1,4 +1,5 @@
import { AggregateRoot, EmailAddress, Result, UniqueID } from "@common/domain";
import { AggregateRoot, EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { UserAuthenticatedEvent } from "../events";
import { Username } from "../value-objects";
@ -14,11 +15,11 @@ export interface IUser {
isUser: boolean;
isAdmin: boolean;
isActive: boolean;
hasRole(role: string): boolean;
hasRoles(roles: string[]): boolean;
getRoles(): string[];
toPersistenceData(): any;
}
export class User extends AggregateRoot<IUserProps> implements IUser {
@ -60,15 +61,7 @@ export class User extends AggregateRoot<IUserProps> implements IUser {
return this.hasRole("admin");
}
/**
* 🔹 Devuelve una representación lista para persistencia
*/
toPersistenceData(): any {
return {
id: this.id.toString(),
username: this.props.username.toString(),
email: this.props.email.toString(),
roles: this.props.roles.map((role) => role.toString()),
};
get isActive(): boolean {
return true;
}
}

View File

@ -1,5 +1,5 @@
import { DomainEntity, Result, UniqueID } from "@common/domain";
import { EmailAddress } from "../value-objects";
import { DomainEntity, EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
export interface IJWTPayloadProps {
tabId: UniqueID;
@ -23,10 +23,6 @@ export interface IJWTPayload {
export class JWTPayload extends DomainEntity<IJWTPayloadProps> implements IJWTPayload {
static create(props: IJWTPayloadProps): Result<JWTPayload, Error> {
if (props.email.isEmpty()) {
return Result.fail(new Error("Email is required"));
}
return Result.ok(new JWTPayload(props));
}
@ -42,10 +38,6 @@ export class JWTPayload extends DomainEntity<IJWTPayloadProps> implements IJWTPa
return Result.fail(result.error);
}
if (emailOrError.data.isEmpty()) {
return Result.fail(new Error("Email is required"));
}
return JWTPayload.create({
email: emailOrError.data,
userId: userIdOrError.data,

View File

@ -1,5 +1,6 @@
import { DomainEntity, Result, UniqueID } from "@common/domain";
import { EmailAddress, PlainPassword } from "../value-objects";
import { DomainEntity, EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { PlainPassword } from "../value-objects";
export interface ILoginDataProps {
email: EmailAddress;
@ -36,10 +37,6 @@ export class LoginData extends DomainEntity<ILoginDataProps> implements ILoginDa
return Result.fail(result.error);
}
if (emailOrError.data.isEmpty()) {
return Result.fail(new Error("Email is required"));
}
return LoginData.create({
email: emailOrError.data,
plainPassword: plainPasswordOrError.data,

View File

@ -1,5 +1,5 @@
import { DomainEntity, Result, UniqueID } from "@common/domain";
import { EmailAddress } from "../value-objects";
import { DomainEntity, EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
export interface ILogoutDataProps {
email: EmailAddress;
@ -32,10 +32,6 @@ export class LogoutData extends DomainEntity<ILogoutDataProps> implements ILogou
return Result.fail(result.error);
}
if (emailOrError.data.isEmpty()) {
return Result.fail(new Error("Email is required"));
}
return LogoutData.create({
email: emailOrError.data,
tabId: tabIdOrError.data,

View File

@ -1,5 +1,6 @@
import { DomainEntity, Result } from "@common/domain";
import { EmailAddress, HashPassword, Username } from "../value-objects";
import { DomainEntity, EmailAddress } from "@common/domain";
import { Result } from "@common/helpers";
import { HashPassword, Username } from "../value-objects";
export interface IRegisterDataProps {
username: Username;
@ -37,9 +38,6 @@ export class RegisterData extends DomainEntity<IRegisterDataProps> implements IR
return Result.fail(result.error);
}
if (emailOrError.data.isEmpty()) {
return Result.fail(new Error("Email is required"));
}
return RegisterData.create({
username: userNameOrError.data,
email: emailOrError.data,

View File

@ -1,4 +1,5 @@
import { DomainEntity, Result, UniqueID } from "@common/domain";
import { DomainEntity, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
export interface ITabContextProps {
tabId: UniqueID;
@ -14,8 +15,6 @@ export interface ITabContextPrimitives {
export interface ITabContext {
tabId: UniqueID;
userId: UniqueID;
toPersistenceData(): any;
}
export class TabContext extends DomainEntity<ITabContextProps> implements ITabContext {
@ -47,12 +46,4 @@ export class TabContext extends DomainEntity<ITabContextProps> implements ITabCo
get userId(): UniqueID {
return this.props.userId;
}
toPersistenceData(): ITabContextPrimitives {
return {
id: this.id.toString(),
tab_id: this.tabId.toString(),
user_id: this.userId.toString(),
};
}
}

View File

@ -1,6 +1,8 @@
import { Result } from "@common/domain";
import { Result } from "@common/helpers";
import { EmailAddress } from "@common/domain";
import { AuthenticatedUser } from "../aggregates";
import { EmailAddress, Username } from "../value-objects";
import { Username } from "../value-objects";
export interface IAuthenticatedUserRepository {
getUserByEmail(email: EmailAddress, transaction?: any): Promise<Result<AuthenticatedUser, Error>>;

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { Transaction } from "sequelize";
import { TabContext } from "../entities";

View File

@ -1,9 +1,9 @@
import { Result, UniqueID } from "@common/domain";
import { EmailAddress, UniqueID } from "@common/domain";
import { Collection, Result } from "@common/helpers";
import { User } from "../aggregates";
import { EmailAddress } from "../value-objects";
export interface IUserRepository {
findAll(transaction?: any): Promise<Result<User[], Error>>;
findAll(transaction?: any): Promise<Result<Collection<User>, Error>>;
findById(id: UniqueID, transaction?: any): Promise<Result<User, Error>>;
findByEmail(email: EmailAddress, transaction?: any): Promise<Result<User, Error>>;
}

View File

@ -1,7 +1,7 @@
import { Result } from "@common/domain";
import { EmailAddress } from "@common/domain";
import { Result } from "@common/helpers";
import {
AuthenticatedUser,
EmailAddress,
IJWTPayload,
LoginData,
LogoutData,

View File

@ -1,15 +1,9 @@
import { Result, UniqueID } from "@common/domain";
import {
AuthenticatedUser,
EmailAddress,
IAuthenticatedUserRepository,
IJWTPayload,
JWTPayload,
LoginData,
RegisterData,
TabContext,
Token,
} from "..";
import { EmailAddress } from "@common/domain";
import { Result } from "@common/helpers";
import { AuthenticatedUser, IJWTPayload, LoginData, RegisterData, TabContext, Token } from "..";
import { UniqueID } from "@common/domain";
import { IAuthenticatedUserRepository, JWTPayload } from "..";
import { JwtHelper } from "../../infraestructure/passport/jwt.helper";
import { ITabContextRepository } from "../repositories/tab-context-repository.interface";
import { IAuthService } from "./auth-service.interface";
@ -101,11 +95,6 @@ export class AuthService implements IAuthService {
let result: any;
const { email, plainPassword, tabId } = loginData;
// Verificar que el tab ID está definido
if (!tabId.isDefined()) {
return Result.fail(new Error("Invalid tab id"));
}
// 🔹 Verificar si el usuario existe en la base de datos
result = await this.authUserRepo.getUserByEmail(email, transaction);
if (result.isFailure) {
@ -171,11 +160,6 @@ export class AuthService implements IAuthService {
): Promise<Result<void, Error>> {
const { email, tabId } = params;
// Verificar que el tab ID está definido
if (!tabId.isDefined()) {
return Result.fail(new Error("Invalid tab id"));
}
// 🔹 Verificar si el usuario existe en la base de datos
const userResult = await this.authUserRepo.getUserByEmail(email, transaction);
if (userResult.isFailure) {

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { TabContext } from "../entities";
export interface ITabContextService {

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { TabContext } from "../entities";
import { ITabContextRepository } from "../repositories";
import { ITabContextService } from "./tab-context-service.interface";

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { User } from "../aggregates";
export interface IUserService {

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { IUserRepository, User } from "..";
import { IUserService } from "./user-service.interface";
@ -12,7 +13,7 @@ export class UserService implements IUserService {
}
// Solo devolver usuarios activos
const activeUsers = usersOrError.data.filter((user) => user /*.isActive*/);
const activeUsers = usersOrError.data.filter((user) => user.isActive);
return Result.ok(activeUsers);
}

View File

@ -1,14 +1,19 @@
import { Result, ValueObject } from "@common/domain";
import { ValueObject } from "@common/domain";
import { Result } from "@common/helpers";
import { z } from "zod";
const RoleSchema = z.enum(["Admin", "User", "Manager", "Editor"]);
export class UserRoles extends ValueObject<string[]> {
interface UserRolesProps {
value: string[];
}
export class UserRoles extends ValueObject<UserRolesProps> {
static create(roles: string[]): Result<UserRoles, Error> {
const result = UserRoles.validate(roles);
return result.success
? Result.ok(new UserRoles(result.data))
? Result.ok(new UserRoles({ value: result.data }))
: Result.fail(new Error("Invalid user roles"));
}
@ -17,6 +22,10 @@ export class UserRoles extends ValueObject<string[]> {
}
hasRole(role: string): boolean {
return this.props.includes(role);
return this.props.value.includes(role);
}
getValue() {
return this.props.value;
}
}

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@common/domain";
import { ValueObject } from "@common/domain";
import { Result } from "@common/helpers";
import bcrypt from "bcrypt";
import { z } from "zod";

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@common/domain";
import { ValueObject } from "@common/domain";
import { Result } from "@common/helpers";
import { z } from "zod";
interface PlainPasswordProps {

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@common/domain";
import { ValueObject } from "@common/domain";
import { Result } from "@common/helpers";
import { z } from "zod";
interface TokenProps {

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@common/domain";
import { ValueObject } from "@common/domain";
import { Result } from "@common/helpers";
import { z } from "zod";
interface UsernameProps {

View File

@ -1,26 +1,25 @@
import { EmailAddress, Result, UniqueID } from "@common/domain";
import { EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "@common/infrastructure";
import { AuthenticatedUser, HashPassword, Username } from "@contexts/auth/domain";
import { AuthUserModel } from "../sequelize";
import { AuthUserCreationAttributes, AuthUserModel } from "../sequelize";
export interface IAuthenticatedUserMapper {
toDomain(entity: AuthUserModel): Result<AuthenticatedUser, Error>;
toPersistence(aggregate: AuthenticatedUser): AuthUserModel;
}
class AuthenticatedUserMapper implements IAuthenticatedUserMapper {
/**
* 🔹 Convierte una entidad de la base de datos en un agregado de dominio `AuthenticatedUser`
*/
toDomain(entity: AuthUserModel): Result<AuthenticatedUser, Error> {
if (!entity) {
return Result.fail(new Error("Entity not found"));
}
export interface IAuthenticatedUserMapper
extends ISequelizeMapper<AuthUserModel, AuthUserCreationAttributes, AuthenticatedUser> {}
export class AuthenticatedUserMapper
extends SequelizeMapper<AuthUserModel, AuthUserCreationAttributes, AuthenticatedUser>
implements IAuthenticatedUserMapper
{
public mapToDomain(
source: AuthUserModel,
params?: MapperParamsType
): Result<AuthenticatedUser, Error> {
// Crear Value Objects asegurando que sean válidos
const uniqueIdResult = UniqueID.create(entity.id);
const usernameResult = Username.create(entity.username);
const passwordHashResult = HashPassword.createFromHash(entity.hash_password);
const emailResult = EmailAddress.create(entity.email);
const uniqueIdResult = UniqueID.create(source.id);
const usernameResult = Username.create(source.username);
const passwordHashResult = HashPassword.createFromHash(source.hash_password);
const emailResult = EmailAddress.create(source.email);
// Validar que no haya errores en la creación de los Value Objects
const okOrError = Result.combine([
@ -39,17 +38,25 @@ class AuthenticatedUserMapper implements IAuthenticatedUserMapper {
username: usernameResult.data!,
email: emailResult.data!,
hashPassword: passwordHashResult.data!,
roles: entity.roles || [],
roles: source.roles || [],
},
uniqueIdResult.data!
);
}
/**
* 🔹 Convierte un agregado `AuthenticatedUser` en un objeto listo para persistencia
*/
toPersistence(authenticatedUser: AuthenticatedUser): AuthUserModel {
return authenticatedUser.toPersistenceData();
public mapToPersistence(
source: AuthenticatedUser,
params?: MapperParamsType
): Result<AuthUserCreationAttributes, Error> {
return Result.ok({
id: source.id.toString(),
username: source.username.toString(),
email: source.email.toString(),
hash_password: source.hashPassword.toString(),
roles: source.getRoles().map((role) => role.toString()),
//access_token: source.accessToken,
//refresh_token: source.refreshToken,
});
}
}

View File

@ -1,22 +1,24 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "@common/infrastructure";
import { TabContext } from "@contexts/auth/domain";
import { TabContextModel } from "../sequelize";
import { TabContextCreationAttributes, TabContextModel } from "../sequelize";
export interface ITabContextMapper {
toDomain(entity: TabContextModel): Result<TabContext, Error>;
toPersistence(aggregate: TabContext): TabContextModel;
}
class TabContextMapper implements ITabContextMapper {
toDomain(entity: TabContextModel): Result<TabContext, Error> {
if (!entity) {
return Result.fail(new Error("Entity not found"));
}
export interface ITabContextMapper
extends ISequelizeMapper<TabContextModel, TabContextCreationAttributes, TabContext> {}
export class TabContextMapper
extends SequelizeMapper<TabContextModel, TabContextCreationAttributes, TabContext>
implements ITabContextMapper
{
public mapToDomain(
source: TabContextModel,
params?: MapperParamsType
): Result<TabContext, Error> {
// Crear Value Objects asegurando que sean válidos
const uniqueIdResult = UniqueID.create(entity.id);
const tabIdResult = UniqueID.create(entity.tab_id);
const userIdResult = UniqueID.create(entity.user_id);
const uniqueIdResult = UniqueID.create(source.id);
const tabIdResult = UniqueID.create(source.tab_id);
const userIdResult = UniqueID.create(source.user_id);
//const companyIdResult = UniqueID.create(entity.company_id, false);
//const brachIdResult = UniqueID.create(entity.branch_id, false);
@ -44,8 +46,15 @@ class TabContextMapper implements ITabContextMapper {
);
}
toPersistence(tabContext: TabContext): TabContextModel {
return tabContext.toPersistenceData();
public mapToPersistence(
source: TabContext,
params?: MapperParamsType
): Result<TabContextCreationAttributes, Error> {
return Result.ok({
id: source.id.toString(),
tab_id: source.tabId.toString(),
user_id: source.userId.toString(),
});
}
}

View File

@ -1,28 +1,24 @@
import { EmailAddress, Result, UniqueID } from "@common/domain";
import { EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import {
ISequelizeMapper,
MapperParamsType,
SequelizeMapper,
} from "@common/infrastructure/sequelize/sequelize-mapper";
import { User, Username } from "@contexts/auth/domain";
import { UserModel } from "../sequelize";
import { UserCreationAttributes, UserModel } from "../sequelize";
export interface IUserMapper {
toDomain(entity: UserModel): Result<User, Error>;
toDomainArray(entities: UserModel[]): Result<User[], Error>;
toPersistence(aggregate: User): UserModel;
toPersistenceArray(users: User[]): UserModel[];
}
class UserMapper implements IUserMapper {
/**
* 🔹 Convierte una entidad de la base de datos en un agregado de dominio `User`
*/
toDomain(entity: UserModel): Result<User, Error> {
if (!entity) {
return Result.fail(new Error("Entity not found"));
}
export interface IUserMapper extends ISequelizeMapper<UserModel, UserCreationAttributes, User> {}
class UserMapper
extends SequelizeMapper<UserModel, UserCreationAttributes, User>
implements IUserMapper
{
public mapToDomain(source: UserModel, params?: MapperParamsType): Result<User, Error> {
// Crear Value Objects asegurando que sean válidos
const uniqueIdResult = UniqueID.create(entity.id);
const usernameResult = Username.create(entity.username);
const emailResult = EmailAddress.create(entity.email);
const uniqueIdResult = UniqueID.create(source.id);
const usernameResult = Username.create(source.username);
const emailResult = EmailAddress.create(source.email);
// Validar que no haya errores en la creación de los Value Objects
const okOrError = Result.combine([uniqueIdResult, usernameResult, emailResult]);
@ -42,41 +38,16 @@ class UserMapper implements IUserMapper {
);
}
/**
* 🔹 Convierte un array de entidades de la base de datos en un array de agregados de dominio `User`
*/
toDomainArray(entities: UserModel[]): Result<User[], Error> {
if (!Array.isArray(entities) || entities.length === 0) {
return Result.fail(new Error("Entities array is empty or invalid"));
}
const usersResults = entities.map(this.toDomain);
const okOrError = Result.combine(usersResults);
if (okOrError.isFailure) {
return Result.fail(okOrError.error);
}
const result = usersResults.map((result) => result.data!);
return Result.ok(result);
}
/**
* 🔹 Convierte un agregado `User` en un objeto listo para persistencia
*/
toPersistence(user: User): UserModel {
return user.toPersistenceData();
}
/**
* 🔹 Convierte un array de agregados `User` en un array de objetos listos para persistencia
*/
toPersistenceArray(users: User[]): UserModel[] {
if (!Array.isArray(users) || users.length === 0) {
return [];
}
return users.map(this.toPersistence);
public mapToPersistence(
source: User,
params?: MapperParamsType
): Result<UserCreationAttributes, Error> {
return Result.ok({
id: source.id.toString(),
username: source.username.toString(),
email: source.email.toString(),
//roles: source.getRoles().map((role) => role.toString()),
});
}
}

View File

@ -1,9 +1,10 @@
import { NextFunction, Response } from "express";
import { Result, UniqueID } from "@common/domain";
import { EmailAddress, UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { ITransactionManager } from "@common/infrastructure/database";
import { logger } from "@common/infrastructure/logger";
import { EmailAddress, TabContext } from "@contexts/auth/domain";
import { TabContext } from "@contexts/auth/domain";
import { IAuthService, ITabContextService } from "@contexts/auth/domain/services";
import passport from "passport";
import { ExtractJwt, Strategy as JwtStrategy } from "passport-jwt";

View File

@ -1,11 +1,7 @@
import { Result } from "@common/domain";
import { EmailAddress } from "@common/domain";
import { Result } from "@common/helpers";
import { SequelizeRepository } from "@common/infrastructure";
import {
AuthenticatedUser,
EmailAddress,
IAuthenticatedUserRepository,
Username,
} from "@contexts/auth/domain";
import { AuthenticatedUser, IAuthenticatedUserRepository, Username } from "@contexts/auth/domain";
import { Transaction } from "sequelize";
import { authenticatedUserMapper, IAuthenticatedUserMapper } from "../mappers";
import { AuthUserModel } from "./auth-user.model";
@ -75,7 +71,7 @@ class AuthenticatedUserRepository
return Result.fail(new Error("User with email not exists"));
}
return this._mapper.toDomain(rawUser);
return this._mapper.mapToDomain(rawUser);
} catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper);
}
@ -86,8 +82,8 @@ class AuthenticatedUserRepository
transaction?: Transaction
): Promise<Result<void, Error>> {
try {
const persistenceData = this._mapper.toPersistence(user);
await AuthUserModel.create(persistenceData, { transaction });
const persistenceData = this._mapper.mapToPersistence(user);
await AuthUserModel.create(persistenceData.data, { transaction });
return Result.ok();
} catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper);

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@common/domain";
import { UniqueID } from "@common/domain";
import { Result } from "@common/helpers";
import { SequelizeRepository } from "@common/infrastructure";
import { ITabContextRepository, TabContext } from "@contexts/auth/domain/";
import { Op, Transaction } from "sequelize";
@ -44,7 +45,7 @@ class TabContextRepository
return Result.fail(new Error("Tab context not exists"));
}
return this._mapper.toDomain(rawContext);
return this._mapper.mapToDomain(rawContext);
} catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper);
}
@ -78,17 +79,17 @@ class TabContextRepository
): Promise<Result<void, Error>> {
try {
const { userId, tabId } = context;
const data = this._mapper.toPersistence(context);
const persistenceData = this._mapper.mapToPersistence(context);
// Si existe el contexto de ese tabId, lo actualizo.
if (await this._exists(TabContextModel, "tab_id", tabId.toString())) {
await TabContextModel.update(data, {
await TabContextModel.update(persistenceData.data, {
where: { [Op.and]: [{ tab_id: tabId.toString() }, { user_id: userId.toString() }] },
transaction,
});
} else {
await TabContextModel.create(data, {
await TabContextModel.create(persistenceData.data, {
include: [{ all: true }],
transaction,
});

View File

@ -1,4 +1,5 @@
import { EmailAddress, Result, UniqueID } from "@common/domain";
import { EmailAddress, UniqueID } from "@common/domain";
import { Collection, Result } from "@common/helpers";
import { SequelizeRepository } from "@common/infrastructure";
import { IUserRepository, User } from "@contexts/auth/domain";
import { Transaction } from "sequelize";
@ -24,7 +25,7 @@ class UserRepository extends SequelizeRepository<User> implements IUserRepositor
this._mapper = mapper;
}
async findAll(transaction?: Transaction): Promise<Result<User[], Error>> {
async findAll(transaction?: Transaction): Promise<Result<Collection<User>, Error>> {
try {
const rawUsers: any = await this._findAll(UserModel, {}, transaction);
@ -32,7 +33,7 @@ class UserRepository extends SequelizeRepository<User> implements IUserRepositor
return Result.fail(new Error("User with email not exists"));
}
return this._mapper.toDomainArray(rawUsers);
return this._mapper.mapArrayToDomain(rawUsers);
} catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper);
}
@ -46,7 +47,7 @@ class UserRepository extends SequelizeRepository<User> implements IUserRepositor
return Result.fail(new Error(`User with id ${id.toString()} not exists`));
}
return this._mapper.toDomain(rawUser);
return this._mapper.mapToDomain(rawUser);
} catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper);
}
@ -60,7 +61,7 @@ class UserRepository extends SequelizeRepository<User> implements IUserRepositor
return Result.fail(new Error(`User with email ${email.toString()} not exists`));
}
return this._mapper.toDomain(rawUser);
return this._mapper.mapToDomain(rawUser);
} catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper);
}

View File

@ -1,3 +1,4 @@
import { ensureString } from "@common/helpers";
import { User } from "@contexts/auth/domain";
import { IListUsersResponseDTO } from "../../dto";
@ -8,8 +9,8 @@ export interface IListUsersPresenter {
export const listUsersPresenter: IListUsersPresenter = {
toDTO: (users: User[]): IListUsersResponseDTO[] =>
users.map((user) => ({
id: user.id.toString(),
email: user.email.toString(),
username: user.username.toString(),
id: ensureString(user.id.toString()),
email: ensureString(user.email.toString()),
username: ensureString(user.username.toString()),
})),
};

View File

@ -27,9 +27,18 @@ export const loginPresenter: ILoginPresenter = {
tokens: { accessToken, refreshToken },
} = data;
const userData = user.toPersistenceData();
const userData = {
id: user.id.toString(),
username: user.username.toString(),
email: user.email.toString(),
//roles: user.getRoles().map((role) => role.toString()),
};
const tabContextData = tabContext.toPersistenceData();
const tabContextData = {
id: tabContext.id.toString(),
tab_id: tabContext.tabId.toString(),
user_id: tabContext.userId.toString(),
};
return {
user: {

View File

@ -1,5 +1,5 @@
import { validateRequestDTO } from "@common/presentation";
import { checkTabContext, checkUserIsAdmin } from "@contexts/auth/infraestructure";
import { checkTabContext } from "@contexts/auth/infraestructure";
import { listUsersController, ListUsersSchema } from "@contexts/auth/presentation";
import { NextFunction, Request, Response, Router } from "express";
@ -10,7 +10,7 @@ export const userRouter = (appRouter: Router) => {
"/",
validateRequestDTO(ListUsersSchema),
checkTabContext,
checkUserIsAdmin,
//checkUserIsAdmin,
(req: Request, res: Response, next: NextFunction) => {
listUsersController().execute(req, res, next);
}