import { DuplicateEntityError } from "@erp/core/api"; import type { UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { Customer, type ICustomerCreateProps } from "../../domain"; import type { ICustomerRepository } from "../repositories"; import { CustomerNotExistsInCompanySpecification } from "../specs"; export interface ICustomerCreator { create(params: { companyId: UniqueID; id: UniqueID; props: ICustomerCreateProps; transaction?: unknown; }): Promise>; } type CustomerCreatorDeps = { repository: ICustomerRepository; }; export class CustomerCreator implements ICustomerCreator { private readonly repository: ICustomerRepository; constructor(deps: CustomerCreatorDeps) { this.repository = deps.repository; } async create(params: { companyId: UniqueID; id: UniqueID; props: ICustomerCreateProps; transaction?: unknown; }): Promise> { const { companyId, id, props, transaction } = params; // 1. Verificar unicidad const spec = new CustomerNotExistsInCompanySpecification( this.repository, companyId, transaction ); const isNew = await spec.isSatisfiedBy(id); if (!isNew) { return Result.fail(new DuplicateEntityError("Customer", "id", String(id))); } // 2. Crear agregado const createResult = Customer.create( { ...props, companyId, }, id ); if (createResult.isFailure) { return createResult; } const newCustomer = createResult.data; // 3. Persistir agregado const saveResult = await this.repository.create(newCustomer, transaction); if (saveResult.isFailure) { return Result.fail(saveResult.error); } return Result.ok(newCustomer); } }