import type { ITransactionManager } from "@erp/core/api"; import { UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import type { UpdateCustomerByIdRequestDTO } from "../../../common/dto"; import type { CustomerPatchProps } from "../../domain"; import type { IUpdateCustomerInputMapper } from "../mappers"; import type { ICustomerUpdater } from "../services"; import type { ICustomerFullReadModelAssembler } from "../services/assemblers"; import type { ICustomerFullSnapshotBuilder } from "../snapshot-builders"; type UpdateCustomerUseCaseInput = { companyId: UniqueID; customer_id: string; dto: UpdateCustomerByIdRequestDTO; }; export class UpdateCustomerUseCase { constructor( private readonly deps: { dtoMapper: IUpdateCustomerInputMapper; updater: ICustomerUpdater; fullReadModelAssembler: ICustomerFullReadModelAssembler; fullSnapshotBuilder: ICustomerFullSnapshotBuilder; transactionManager: ITransactionManager; } ) {} public execute(params: UpdateCustomerUseCaseInput) { const { companyId, customer_id, dto } = params; const idOrError = UniqueID.create(customer_id); if (idOrError.isFailure) { return Result.fail(idOrError.error); } const id = idOrError.data; // Mapear DTO → props de dominio const patchPropsResult = this.deps.dtoMapper.map(dto, { companyId }); if (patchPropsResult.isFailure) { return patchPropsResult; } const patchProps: CustomerPatchProps = patchPropsResult.data; return this.deps.transactionManager.complete(async (transaction: unknown) => { try { const updateResult = await this.deps.updater.update({ companyId, id, props: patchProps, transaction, }); if (updateResult.isFailure) { return Result.fail(updateResult.error); } const readModelResult = await this.deps.fullReadModelAssembler.assemble({ companyId, customer: updateResult.data, transaction, }); if (readModelResult.isFailure) { return Result.fail(readModelResult.error); } return Result.ok(this.deps.fullSnapshotBuilder.toOutput(readModelResult.data)); } catch (error: unknown) { return Result.fail(error as Error); } }); } }