Cerrada

Entry 004 - Auditoria Payment, Live Demo POS y capa de servicios

dddpaymentauditstate-machinetestingfrontendpreactlive-demo

Auditoria del contexto Payment

Se realizo una auditoria profunda del contexto Payment que revelo 11 problemas de diferente severidad. Esta iteracion los resuelve todos.

Estados terminales CANCELLED y FAILED

PaymentOrderStatus tenia CANCELLED y FAILED declarados pero nunca se usaban. Ahora tienen comportamiento real:

Ambos son estados terminales — una vez en CANCELLED o FAILED, no se aceptan mas pagos ni se puede transicionar a otro estado. El helper privado isTerminal() unifica esta validacion en addPayment(), registerPayment(), cancel() y markAsFailed().

Politica de reintentos en PaymentCommit

PaymentCommit ahora implementa la politica de reintentos como logica de aplicacion (no de dominio):

La constante MAX_FAILED_PAYMENTS = 3 vive en el use case, no en el agregado.

CancelPaymentOrder use case

Nuevo use case para cancelacion por el usuario:

Guardas de estado en Payment (entidad)

Payment.complete() y Payment.fail() ahora retornan Result y validan que el estado actual sea PENDING. Antes se podian llamar multiples veces o en orden incorrecto sin error.

PaymentOrder.registerPayment() propaga el Result de estas transiciones.

PaymentOrder.create() retorna Result

PaymentOrder.create() ahora valida totalAmount > 0 y retorna Result<InvalidPaymentError, PaymentOrder>. CreatePaymentOrder use case propaga este resultado.

Guarda de duplicados en CreatePaymentOrder

CreatePaymentOrder verifica que no exista una PaymentOrder para el mismo saleId antes de crear una nueva. Previene duplicados por eventos repetidos.

Validacion de monto en addPayment

addPayment() rechaza pagos con amount <= 0 retornando InvalidPaymentError.

Renombramiento del event handler

PaymentCompletedEventHandler renombrado a CreatePaymentOrderOnSaleReady — el nombre anterior era confuso porque sugeria que manejaba un evento de Payment completado, cuando en realidad reacciona a SalesReadyToPay.

Limpieza

Live Demo POS

Se implemento una seccion interactiva en /pos que permite ejecutar el flujo completo de una venta usando los bounded contexts reales del dominio.

Stack del frontend

Arquitectura: servicios en vez de bridge

Se descarto un bridge monolitico en favor de una capa de servicios distribuida por contexto:

Cada servicio encapsula dos responsabilidades: llamar los use cases del dominio y actualizar los stores de UI. Los componentes solo conocen servicios — no importan ni stores ni use cases directamente.

Stores (Nanostores)

Componentes Preact

Notificaciones (Toast)

Integradas en los servicios para feedback inmediato: exito al confirmar venta, error al agregar producto sin stock, pago completado con cambio, fallo definitivo del pago, etc. Tres tipos: success (verde), error (rojo), info (gris).

Pagina

La pagina pos.astro es un shell estatico con layout de 3 columnas. Los 3 paneles y el toast container son Preact islands con client:load. El catalogo se inicializa via <script> que llama CatalogService.init().

Acceso desde el home via boton “Live Demo” en el hero.

Test Results

Payment Audit (Iter 4)

Cancelacion, fallo por reintentos, guardas de estado terminal, validaciones

9 passed
Cancel payment order from PENDING transitions to CANCELLED
Cancel payment order from PARTIAL transitions to CANCELLED
Cannot add payment to a CANCELLED order
3 failed payments transitions order to FAILED
PaymentOrderFailed event cancels the Sale
Stock is restored after payment order fails definitively
Cannot add payment to a FAILED order
Cannot cancel a COMPLETED payment order
Payment with amount 0 is rejected