Skip to content

feat: scaffold CQRS sample with DDD and package-by-feature design (Helidon MP + MongoDB)#1

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/ensure-ddd-compliance
Draft

feat: scaffold CQRS sample with DDD and package-by-feature design (Helidon MP + MongoDB)#1
Copilot wants to merge 2 commits into
mainfrom
copilot/ensure-ddd-compliance

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 26, 2026

Repository contained only a README. This PR builds the full project from scratch, applying Domain-Driven Design and package-by-feature organization throughout.

Structure

Each bounded context owns its full vertical slice — no cross-feature leakage:

com.soujava.helidon.cqrs
├── shared/              ← CQRS bus abstractions (Command, Query, buses, AggregateRoot, DomainEvent)
└── order/               ← Order bounded context
    ├── api/             ← JAX-RS resource, request DTOs, DomainExceptionMapper
    ├── command/         ← CreateOrder / ConfirmOrder / CancelOrder + handlers
    ├── query/           ← FindOrderById / FindAllOrders + handlers, OrderView read model, OrderViewMapper
    ├── domain/          ← Order aggregate, OrderId / OrderStatus value objects, OrderItem, OrderRepository interface
    │   └── event/       ← OrderCreatedEvent, OrderConfirmedEvent, OrderCancelledEvent
    ├── infrastructure/  ← MongoClientProducer, MongoOrderRepository
    └── OrderHandlerRegistrar.java

DDD application

  • Order is the aggregate root — all invariants enforced internally, state changes only through named business methods (confirm(), cancel())
  • OrderId / OrderStatus are immutable value objects
  • Domain events (OrderCreatedEvent, etc.) are registered on the aggregate and collected via AggregateRoot
  • OrderRepository interface lives in the domain; MongoDB implementation lives in infrastructure — domain has zero persistence imports

CQRS wiring

Handlers register themselves at CDI startup via OrderHandlerRegistrar (@Observes @Initialized), keeping the CommandBus / QueryBus decoupled from any feature. OrderResource dispatches only through the bus interfaces — no domain logic in the API layer.

Key decisions

  • OrderViewMapper centralises aggregate → read model conversion, shared by both query handlers
  • DomainExceptionMapper (@Provider) maps IllegalArgumentException → 400, IllegalStateException → 409, logs unexpected errors server-side
  • OrderResource.createOrder() validates payload nulls before dispatch to give clean API errors
  • Config (mongodb.uri, mongodb.database, server.port) externalised via MicroProfile Config

Copilot AI and others added 2 commits April 25, 2026 06:13
…ing Helidon MP + MongoDB

Agent-Logs-Url: https://github.com/soujava/helidon-mongodb-cqrs/sessions/935ddb4c-bdbf-4d6d-9bba-2fe68b868911

Co-authored-by: otaviojava <863011+otaviojava@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants