From dd3f53c2b14ecd61abc596ab3e6336913b9d94f3 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 29 Mar 2026 21:00:07 +0200 Subject: [PATCH] . --- .../aggregates/issued-invoice.aggregate.ts | 26 +++++++++++++------ .../aggregates/proforma.aggregate.ts | 10 +++++++ .../domain/aggregates/customer.aggregate.ts | 10 +++++++ modules/customers/src/api/index.ts | 21 ++++++--------- .../express/customers.routes.ts | 11 +++++--- modules/factuges/src/api/index.ts | 2 +- 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts b/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts index 86b8da0b..44ee0f11 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts @@ -96,14 +96,10 @@ export class IssuedInvoice } static create(props: IIssuedInvoiceCreateProps, id?: UniqueID): Result { - if (!props.recipient) { - return Result.fail( - new DomainValidationError( - "MISSING_RECIPIENT", - "recipient", - "Issued invoice requires recipient" - ) - ); + const validationResult = IssuedInvoice.validateCreateProps(props); + + if (validationResult.isFailure) { + return Result.fail(validationResult.error); } const internalItems = IssuedInvoiceItems.create({ @@ -132,6 +128,20 @@ export class IssuedInvoice return Result.ok(issuedInvoice); } + private static validateCreateProps(props: IIssuedInvoiceCreateProps): Result { + if (!props.recipient) { + return Result.fail( + new DomainValidationError( + "MISSING_RECIPIENT", + "recipient", + "Issued invoice requires recipient" + ) + ); + } + + return Result.ok(); + } + // Rehidratación desde persistencia static rehydrate( props: InternalIssuedInvoiceProps, diff --git a/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts b/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts index b1786f27..769fd88e 100644 --- a/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts +++ b/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts @@ -116,6 +116,12 @@ export class Proforma extends AggregateRoot implements IP // Creación funcional static create(props: IProformaCreateProps, id?: UniqueID): Result { + const validationResult = Proforma.validateCreateProps(props); + + if (validationResult.isFailure) { + return Result.fail(validationResult.error); + } + const internalItems = ProformaItems.create({ items: [], languageCode: props.languageCode, @@ -141,6 +147,10 @@ export class Proforma extends AggregateRoot implements IP return Result.ok(proforma); } + private static validateCreateProps(props: IProformaCreateProps): Result { + return Result.ok(); + } + // Rehidratación desde persistencia static rehydrate(props: InternalProformaProps, items: ProformaItems, id: UniqueID): Proforma { return new Proforma(props, items, id); diff --git a/modules/customers/src/api/domain/aggregates/customer.aggregate.ts b/modules/customers/src/api/domain/aggregates/customer.aggregate.ts index f433318c..6eff0bff 100644 --- a/modules/customers/src/api/domain/aggregates/customer.aggregate.ts +++ b/modules/customers/src/api/domain/aggregates/customer.aggregate.ts @@ -99,6 +99,12 @@ type CustomerInternalProps = Omit implements ICustomer { static create(props: ICustomerCreateProps, id?: UniqueID): Result { + const validationResult = Customer.validateCreateProps(props); + + if (validationResult.isFailure) { + return Result.fail(validationResult.error); + } + const { address, defaultTaxes, ...internalProps } = props; const postalAddressResult = PostalAddress.create(address); @@ -132,6 +138,10 @@ export class Customer extends AggregateRoot implements IC return Result.ok(contact); } + private static validateCreateProps(props: ICustomerCreateProps): Result { + return Result.ok(); + } + // Rehidratación desde persistencia static rehydrate(props: CustomerInternalProps, id: UniqueID): Customer { return new Customer(props, id); diff --git a/modules/customers/src/api/index.ts b/modules/customers/src/api/index.ts index 19f6780b..90c5d699 100644 --- a/modules/customers/src/api/index.ts +++ b/modules/customers/src/api/index.ts @@ -1,16 +1,11 @@ import type { IModuleServer } from "@erp/core/api"; -import { type CustomerPublicServices, customersRouter, models } from "./infrastructure"; -import { - type CustomersInternalDeps, - buildCustomerPublicServices, - buildCustomersDependencies, -} from "./infrastructure/di"; +import type { ICustomerPublicServices } from "./application"; +import { customersRouter, models } from "./infrastructure"; +import { buildCustomerPublicServices, buildCustomersDependencies } from "./infrastructure/di"; export * from "./infrastructure/sequelize"; -export type { CustomerPublicServices }; - export const customersAPIModule: IModuleServer = { name: "customers", version: "1.0.0", @@ -30,7 +25,10 @@ export const customersAPIModule: IModuleServer = { const internal = buildCustomersDependencies(params); // 2) Servicios públicos (Application Services) - const customersServices: CustomerPublicServices = buildCustomerPublicServices(params, internal); + const customersServices: ICustomerPublicServices = buildCustomerPublicServices( + params, + internal + ); logger.info("🚀 Customers module dependencies registered", { label: this.name, @@ -60,11 +58,8 @@ export const customersAPIModule: IModuleServer = { async start(params) { const { app, baseRoutePath, logger, getInternal } = params; - // Recuperamos el dominio interno del módulo - const customersInternalDeps = getInternal("customers"); - // Registro de rutas HTTP - customersRouter(params, customersInternalDeps); + customersRouter(params); logger.info("🚀 Customers module started", { label: this.name, diff --git a/modules/customers/src/api/infrastructure/express/customers.routes.ts b/modules/customers/src/api/infrastructure/express/customers.routes.ts index b581bba0..c10224d0 100644 --- a/modules/customers/src/api/infrastructure/express/customers.routes.ts +++ b/modules/customers/src/api/infrastructure/express/customers.routes.ts @@ -1,5 +1,5 @@ import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth/api"; -import { type ModuleParams, type RequestWithAuth, validateRequest } from "@erp/core/api"; +import { type RequestWithAuth, type StartParams, validateRequest } from "@erp/core/api"; import { type NextFunction, type Request, type Response, Router } from "express"; import { @@ -18,11 +18,16 @@ import { UpdateCustomerController, } from "./controllers"; -export const customersRouter = (params: ModuleParams, deps: CustomersInternalDeps) => { - const { app, config } = params; +export const customersRouter = (params: StartParams) => { + const { app, config, getInternal } = params; + + // Recuperamos el dominio interno del módulo + const deps = getInternal("customers"); const router: Router = Router({ mergeParams: true }); + // ---------------------------------------------- + // 🔐 Autenticación + Tenancy para TODO el router if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") { router.use( diff --git a/modules/factuges/src/api/index.ts b/modules/factuges/src/api/index.ts index 1152df4c..e76ae8b0 100644 --- a/modules/factuges/src/api/index.ts +++ b/modules/factuges/src/api/index.ts @@ -46,7 +46,7 @@ export const factugesAPIModule: IModuleServer = { * - NO construye dominio */ async start(params) { - const { app, baseRoutePath, logger, getInternal, getService, listServices } = params; + const { logger } = params; // Registro de rutas HTTP factugesRouter(params);