FactuGES_ERP/modules/customers/src/api/application/use-cases/update-customer.use-case.ts
2026-06-25 13:49:59 +02:00

76 lines
2.3 KiB
TypeScript

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);
}
});
}
}