Phase 1: CQRS, Clean Architecture & Event-Driven Foundation

Architecture Objective

Implementing a decoupled write and read model using MediatR alongside immutable event contracts ensures high scalability and testability for enterprise e-commerce pipelines.

1. Directory & Layer Separation

To prevent tight coupling, our microservice is broken down into four distinct layers following Clean Architecture principles:

OrderService/ 
├── OrderService.Domain/ # Core entities, value objects, domain events 
├── OrderService.Application/ # CQRS Handlers, DTOs, Validators (MediatR) 
├── OrderService.Infrastructure/# EF Core, LocalStack SNS/SQS publishers 
└── OrderService.API/ # Controllers / Endpoints (Presentation)

2. Event-Driven Flow Sequence

The following Mermaid diagram maps out how an incoming command triggers a state change, persisting the aggregate and broadcasting an integration event to the message broker.

sequenceDiagram

autonumber

actor Client
participant API as OrderService.API
participant Handler as CreateOrderCommandHandler
participant DB as Database / EF Core
participant Bus as LocalStack SNS/SQS

Client->>API: POST /api/orders (Command DTO)
API->>Handler: Send(CreateOrderCommand)
Handler->>DB: Save Order Aggregate
DB-->>Handler: Persistence Confirmed
Handler->>Bus: Publish(OrderPlacedEvent)
Bus-->>Handler: Acknowledged
Handler-->>API: Return OrderId Response
API-->>Client: 201 Created

Immutability Best Practice

Always define integration events as C# record types rather than mutable classes. This ensures thread safety and guarantees that event payloads cannot be modified unexpectedly after being dispatched to the message broker.