Order Processing Workflow

A production-quality example demonstrating how functional patterns solve real business problems.


Overview

The Order Processing Workflow is a comprehensive e-commerce example that processes customer orders through multiple stages: validation, inventory reservation, payment processing, shipment creation, and notification. It showcases how Higher-Kinded-J patterns handle complexity without sacrificing readability.

┌─────────────────────────────────────────────────────────────────────────┐
│                        ORDER PROCESSING PIPELINE                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Request ──▶ Validate ──▶ Customer ──▶ Inventory ──▶ Discount          │
│                  │            │            │            │               │
│                  ▼            ▼            ▼            ▼               │
│              Address?     Exists?      In Stock?    Valid Code?         │
│              Postcode?    Eligible?    Reserved?    Loyalty Tier?       │
│                                                                         │
│   ──▶ Payment ──▶ Shipment ──▶ Notification ──▶ Result                  │
│          │           │             │                                    │
│          ▼           ▼             ▼                                    │
│       Approved?   Created?     Sent?                                    │
│       Funds?      Carrier?     (non-critical)                           │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Key Patterns Demonstrated

Typed Error Hierarchies

Domain errors modelled as a sealed interface hierarchy for exhaustive pattern matching:

public sealed interface OrderError {
    record ValidationError(String field, String message) implements OrderError {}
    record CustomerNotFound(CustomerId id) implements OrderError {}
    record InsufficientInventory(ProductId id, int requested, int available) implements OrderError {}
    record PaymentDeclined(String reason) implements OrderError {}
    record ShipmentFailed(String carrier, String reason) implements OrderError {}
}

ForPath Comprehensions

Clean, readable workflow composition with ForPath:

public EitherPath<OrderError, OrderResult> processOrder(OrderRequest request) {
    return ForPath.forPath(validateRequest(request))
        .bind(validated -> lookupCustomer(validated.customerId()))
        .bind((validated, customer) -> reserveInventory(validated.lines()))
        .bind((validated, customer, reservation) ->
            applyDiscounts(validated, customer))
        .bind((validated, customer, reservation, discount) ->
            processPayment(customer, discount.finalAmount()))
        .bind((validated, customer, reservation, discount, payment) ->
            createShipment(validated, reservation))
        .map((validated, customer, reservation, discount, payment, shipment) ->
            new OrderResult(validated.orderId(), shipment, payment));
}

Resilience Patterns

Built-in retry policies and timeouts for external service calls:

private EitherPath<OrderError, PaymentConfirmation> processPaymentWithRetry(
        Customer customer, Money amount) {
    return Path.io(() -> paymentService.charge(customer, amount))
        .retry(RetryPolicy.exponentialBackoff(3, Duration.ofMillis(100)))
        .timeout(Duration.ofSeconds(5))
        .mapError(e -> new PaymentDeclined(e.getMessage()));
}

Focus DSL Integration

Immutable state updates using generated lenses:

// Update nested order status
Order updated = OrderFocus.status().set(order, OrderStatus.CONFIRMED);

// Modify all line item quantities
Order adjusted = OrderFocus.lines()
    .traverseEach()
    .compose(OrderLineFocus.quantity())
    .modify(order, qty -> qty + 1);

Source Files

FileDescriptionRun Command
OrderWorkflowDemo.javaMain demo runner./gradlew :hkj-examples:run -PmainClass=org.higherkindedj.example.order.runner.OrderWorkflowDemo
EnhancedOrderWorkflowDemo.javaDemo with concurrency./gradlew :hkj-examples:run -PmainClass=org.higherkindedj.example.order.runner.EnhancedOrderWorkflowDemo
OrderWorkflow.javaCore workflowView source
ConfigurableOrderWorkflow.javaFeature flags and resilienceView source
EnhancedOrderWorkflow.javaVTask concurrency patternsView source

Domain Model

FileDescription
OrderError.javaSealed error hierarchy
OrderRequest.javaInput request model
ValidatedOrder.javaPost-validation model
OrderResult.javaWorkflow result

Services

FileDescription
CustomerService.javaCustomer lookup
InventoryService.javaStock reservation
PaymentService.javaPayment processing
ShippingService.javaShipment creation

Extended Workflows

FileDescription
PartialFulfilmentWorkflow.javaHandling partial inventory
SplitShipmentWorkflow.javaMulti-warehouse shipping
OrderCancellationWorkflow.javaCancellation with rollback

Project Structure

hkj-examples/src/main/java/org/higherkindedj/example/order/
├── config/
│   └── WorkflowConfig.java        # Feature flags and configuration
├── context/
│   └── OrderContext.java          # Execution context
├── error/
│   └── OrderError.java            # Sealed error hierarchy
├── model/
│   ├── OrderRequest.java          # Input models
│   ├── ValidatedOrder.java        # Domain models
│   ├── OrderResult.java           # Result types
│   └── value/                     # Value objects (Money, OrderId, etc.)
├── resilience/
│   ├── Resilience.java            # Retry utilities
│   └── RetryPolicy.java           # Policy definitions
├── runner/
│   ├── OrderWorkflowDemo.java     # Main runner
│   └── EnhancedOrderWorkflowDemo.java
├── service/
│   ├── CustomerService.java       # Service interfaces
│   ├── InventoryService.java
│   └── impl/                      # In-memory implementations
└── workflow/
    ├── OrderWorkflow.java         # Core workflow
    ├── ConfigurableOrderWorkflow.java
    ├── EnhancedOrderWorkflow.java
    └── FocusDSLExamples.java      # Focus DSL usage


Next: Draughts Game