This commit is contained in:
David Arranz 2024-06-17 22:58:08 +02:00
parent d405ce40d6
commit 7f363cd64a
14 changed files with 136 additions and 24 deletions

View File

@ -52,7 +52,7 @@ export class GetProfileUseCase
try {
await transaction.complete(async (t) => {
const dealerRepo = dealerRepoBuilder({ transaction: t });
profile = await dealerRepo.getById(userId);
profile = await dealerRepo.getByUserId(userId);
});
if (!profile) {
@ -67,8 +67,4 @@ export class GetProfileUseCase
);
}
}
private _getProfileRepository() {
return this._repositoryManager.getRepository<IProfileRepository>("Profile");
}
}

View File

@ -0,0 +1,74 @@
import {
IUseCase,
IUseCaseError,
IUseCaseRequest,
UseCaseError,
} from "@/contexts/common/application/useCases";
import { IRepositoryManager } from "@/contexts/common/domain";
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
import { Result, UniqueID } from "@shared/contexts";
import { IInfrastructureError } from "@/contexts/common/infrastructure";
import { IProfileRepository, Profile } from "../domain";
export interface IGetProfileUseCaseRequest extends IUseCaseRequest {
userId: UniqueID;
}
export type GetProfileResponseOrError =
| Result<never, IUseCaseError> // Misc errors (value objects)
| Result<Profile, never>; // Success!
export class GetProfileByUserIdUseCase
implements IUseCase<IGetProfileUseCaseRequest, Promise<GetProfileResponseOrError>>
{
private _adapter: ISequelizeAdapter;
private _repositoryManager: IRepositoryManager;
constructor(props: { adapter: ISequelizeAdapter; repositoryManager: IRepositoryManager }) {
this._adapter = props.adapter;
this._repositoryManager = props.repositoryManager;
}
private getRepositoryByName<T>(name: string) {
return this._repositoryManager.getRepository<T>(name);
}
async execute(request: IGetProfileUseCaseRequest): Promise<GetProfileResponseOrError> {
const { userId } = request;
// Validación de datos
// No hay en este caso
return await this._getProfileDealer(userId);
}
private async _getProfileDealer(userId: UniqueID) {
const transaction = this._adapter.startTransaction();
const dealerRepoBuilder = this.getRepositoryByName<IProfileRepository>("Profile");
let profile: Profile | null = null;
try {
await transaction.complete(async (t) => {
const dealerRepo = dealerRepoBuilder({ transaction: t });
profile = await dealerRepo.getById(userId);
});
if (!profile) {
return Result.fail(UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, "Profile not found"));
}
return Result.ok<Profile>(profile!);
} catch (error: unknown) {
const _error = error as IInfrastructureError;
return Result.fail(
UseCaseError.create(UseCaseError.REPOSITORY_ERROR, "Error al consultar el usuario", _error)
);
}
}
private _getProfileRepository() {
return this._repositoryManager.getRepository<IProfileRepository>("Profile");
}
}

View File

@ -11,7 +11,7 @@ import { DomainError, IUpdateProfile_Request_DTO, Result, UniqueID } from "@shar
import { IProfileRepository, Profile } from "../domain";
export interface IUpdateProfileUseCaseRequest extends IUseCaseRequest {
id: UniqueID;
userId: UniqueID;
profileDTO: IUpdateProfile_Request_DTO;
}
@ -31,20 +31,22 @@ export class UpdateProfileUseCase
}
async execute(request: IUpdateProfileUseCaseRequest): Promise<UpdateProfileResponseOrError> {
const { id, profileDTO } = request;
const { userId, profileDTO } = request;
const profileRepository = this._getProfileRepository();
// Comprobar que existe el profile
const idExists = await profileRepository().exists(id);
if (!idExists) {
const exitsOrError = await this._getProfileDealer(userId);
if (exitsOrError.isFailure) {
const message = `Profile not found`;
return Result.fail(
UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, message, {
path: "id",
path: "userId",
})
);
}
const oldProfile = exitsOrError.object;
// Crear perfil con datos actualizados
const profileOrError = Profile.create(
{
@ -54,7 +56,7 @@ export class UpdateProfileUseCase
defaultNotes: profileDTO.default_notes,
defaultQuoteValidity: profileDTO.default_quote_validity,
},
id
oldProfile.id
);
if (profileOrError.isFailure) {
@ -100,6 +102,31 @@ export class UpdateProfileUseCase
}
}
private async _getProfileDealer(userId: UniqueID) {
const transaction = this._adapter.startTransaction();
const dealerRepoBuilder = this._getProfileRepository();
let profile: Profile | null = null;
try {
await transaction.complete(async (t) => {
const dealerRepo = dealerRepoBuilder({ transaction: t });
profile = await dealerRepo.getByUserId(userId);
});
if (!profile) {
return Result.fail(UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, "Profile not found"));
}
return Result.ok<Profile>(profile!);
} catch (error: unknown) {
const _error = error as IInfrastructureError;
return Result.fail(
UseCaseError.create(UseCaseError.REPOSITORY_ERROR, "Error al consultar el usuario", _error)
);
}
}
private _getProfileRepository() {
return this._repositoryManager.getRepository<IProfileRepository>("Profile");
}

View File

@ -6,4 +6,6 @@ export interface IProfileRepository extends IRepository<any> {
exists(id: UniqueID): Promise<boolean>;
getById(id: UniqueID): Promise<Profile | null>;
update(profile: Profile): Promise<void>;
getByUserId(userId: UniqueID): Promise<Profile | null>;
}

View File

@ -37,7 +37,17 @@ export class ProfileRepository extends SequelizeRepository<Profile> implements I
// borrando y luego creando
// await this.removeById(user.id, true);
await this._save("Dealer_Model", profile.id, userData, {});
await this._save("Profile_Model", profile.id, userData, {});
}
public async getByUserId(userId: UniqueID): Promise<Profile | null> {
const rawDealer: any = await this._getBy("Profile_Model", "user_id", userId.toPrimitive());
if (!rawDealer === true) {
return null;
}
return this.mapper.mapToDomain(rawDealer);
}
}

View File

@ -9,7 +9,7 @@ export interface IGetProfilePresenter {
export const GetProfilePresenter: IGetProfilePresenter = {
map: (profile: Profile, context: IProfileContext): IGetProfileResponse_DTO => {
return {
id: profile.id.toString(),
dealer_id: profile.id.toString(),
contact_information: profile.contactInformation,
default_payment_method: profile.defaultPaymentMethod,
default_notes: profile.defaultNotes,

View File

@ -1,2 +1,2 @@
export * from "./getProfile";
//export * from "./updateProfile";
export * from "./updateProfile";

View File

@ -62,7 +62,7 @@ export class UpdateProfileController extends ExpressController {
// Llamar al caso de uso
const result = await this.useCase.execute({
id: user.id,
userId: user.id,
profileDTO,
});
@ -84,7 +84,7 @@ export class UpdateProfileController extends ExpressController {
switch (error.code) {
case UseCaseError.NOT_FOUND_ERROR:
errorMessage = "Profile has no associated profile";
errorMessage = "User has no associated profile";
infraError = InfrastructureError.create(
InfrastructureError.RESOURCE_NOT_FOUND_ERROR,

View File

@ -1,11 +1,11 @@
import { UpdateProfileUseCase } from "@/contexts/profile/application";
import { registerDealerRepository } from "@/contexts/sales/infrastructure/Dealer.repository";
import { IProfileContext } from "../../../Profile.context";
import { registerProfileRepository } from "../../../Profile.repository";
import { UpdateProfileController } from "./UpdateProfile.controller";
import { UpdateProfilePresenter } from "./presenter";
export const createUpdateProfileController = (context: IProfileContext) => {
registerDealerRepository(context);
registerProfileRepository(context);
return new UpdateProfileController(
{

View File

@ -9,7 +9,7 @@ export interface IUpdateProfilePresenter {
export const UpdateProfilePresenter: IUpdateProfilePresenter = {
map: (profile: Profile, context: IProfileContext): IUpdateProfileResponse_DTO => {
return {
id: profile.id.toString(),
dealer_id: profile.id.toString(),
contact_information: profile.contactInformation,
default_payment_method: profile.defaultPaymentMethod,
default_notes: profile.defaultNotes,

View File

@ -44,9 +44,9 @@ export default (sequelize: Sequelize) => {
timestamps: true,
//version: true,
createdAt: false,
createdAt: "created_at",
updatedAt: "updated_at",
deletedAt: false,
deletedAt: "deleted_at",
}
);

View File

@ -1,5 +1,8 @@
import { checkUser } from "@/contexts/auth";
import { createGetProfileController } from "@/contexts/profile/infrastructure";
import {
createGetProfileController,
createUpdateProfileController,
} from "@/contexts/profile/infrastructure";
import Express from "express";
export const profileRouter = (appRouter: Express.Router) => {

View File

@ -1,5 +1,5 @@
export interface IGetProfileResponse_DTO {
id: string;
dealer_id: string;
contact_information: string;
default_payment_method: string;
default_notes: string;

View File

@ -1,5 +1,5 @@
export interface IUpdateProfileResponse_DTO {
id: string;
dealer_id: string;
contact_information: string;
default_payment_method: string;
default_notes: string;