Arquitectura

El servicio generado sigue una Arquitectura Hexagonal (Puertos y Adaptadores) combinada con principios de Domain-Driven Design.

Capas

Diagram
Capa Responsabilidad

Domain

Logica de negocio pura: aggregate roots, entidades, eventos de dominio e invariantes. Sin dependencias de framework.

Ports

Contratos (interfaces) que definen como el dominio interactua con el exterior. Se dividen en input ports (casos de uso) y output ports (persistencia, consultas, publicacion de eventos).

Services

Servicios de aplicacion que implementan los input ports y orquestan los output ports. No contienen logica de negocio.

Adapters

Implementaciones concretas que conectan los puertos con la tecnologia. Se dividen en inbound (controladores REST, listeners de eventos) y outbound (repositorios JPA, publicadores de eventos).

Reglas fundamentales:

  • El dominio nunca importa adaptadores ni servicios.

  • Los puertos son solo interfaces.

  • Los adaptadores no dependen entre si — solo de los puertos que implementan.

Commons

El paquete commons provee infraestructura compartida entre bounded contexts: entidades base, puertos de publicacion de eventos, el patron outbox/inbox y el manejo centralizado de excepciones.

Para los contratos de las tres clases base JPA que usan las entidades del dominio, ver Clases base JPA.

Mensajeria

El patron outbox/inbox vive en commons/messaging y commons/service, y respeta las reglas hexagonales del arquetipo:

  • Mensajes en el dominio: DomainEvent<T> y Command<T> son records inmutables, sin dependencias de framework. La regla ArchUnit domain_events_should_be_records verifica que los payloads bajo events/{dominio}/ sean records.

  • Ports como contratos puros: los publishers y registries (EventsPublisher, CommandPublisher, EventRegistry, CommandRegistry) y los handlers (DomainEventHandler<T>, CommandHandler<T>) son interfaces. La regla ports_should_be_interfaces lo refuerza, con @EventHandler y @CommandMapping declaradas como excepcion por ser meta-anotaciones.

  • Adapters aislados por direccion: los JPA adapters de las bandejas y los Spring publishers/listeners viven en commons/adapter/out/persistence, commons/adapter/out/spring y commons/adapter/in/listener/spring. Las reglas inbound_adapters_should_not_depend_on_outbound_adapters y su inversa impiden que cualquiera de los dos lados llame al otro directamente.

  • Servicios de orquestacion sin saltar capas: dispatchers (OutboxEventsDispatcher, InboxEventsProcessor, etc.) y handler dispatchers viven en commons/service y solo invocan ports, nunca adapters concretos. La regla general service_should_not_depend_on_adapters los cubre.

Para los contratos detallados del sistema, ver Referencia: Mensajeria. Para el razonamiento detras del diseno (por que outbox, por que cuatro bandejas, etc.), ver Decisiones de mensajeria.