Skip to content
AyoKoding

Overview

You have finished the by-example tracks for C4, DDD, Hexagonal Architecture, and Finite State Machines. You know what an aggregate is. You know what a port is. You know how to draw a Container diagram. You know how to model a state machine. Now the question is: how do they all wire together in a real production codebase that ships? This section answers that question through three parallel cases against the same shared Procure-to-Pay domain — so the only thing that changes between cases is the language and framework.

What "Case" Means Here

A case is a comprehensive worked treatment of the four architecture pattern families on a single coherent domain. Each case integrates:

  • C4 — how the service and its bounded contexts are drawn (Context, Container, Component)
  • DDD — how the business problem is carved into bounded contexts, aggregates, value objects, and domain events
  • Hexagonal Architecture — how source code is structured so the domain core never depends on infrastructure (ports, adapters, composition root)
  • FSM — how aggregate lifecycles move through their states (state types, transition functions, guards)

The cases here teach the wiring decisions — how these four families meet in code — not the families themselves. The four by-example tracks earlier in this section teach the families in isolation; the cases here show them composed.

What's in this section

Three production cases, all running against the hypothetical procurement-platform-be service (Purchase Requisitions → POs → Goods Receipt → Three-Way Matching → Payment):

All three cases share the same 27-guide numbering (beginner 1–6/7, intermediate 8–14/15, advanced 15/16–22, production 23–27) so cross-paradigm comparison is trivial: Guide 5's F# port definition versus Guide 5's Java interface definition versus Guide 5's Go interface definition is a single side-by-side read. Cross-language comparison within a paradigm is equally direct — Guide 5's F# type alias versus Guide 5's Clojure protocol or TypeScript function type surfaces how idiom shapes the same concept.

Prerequisites

Complete the four by-example tracks before starting either case:

The cases use terms like container, component, aggregate, port, adapter, bounded context, repository pattern, and state machine without redefinition. If any feel unfamiliar, finish the relevant prerequisite track first.

How the Four Families Compose

The four families operate at different levels and slot together as follows:

FamilyLevelQuestion Answered
C4ViewsHow do we draw the system?
DDDDomainHow do we carve the business problem?
HexStructureWhere does each piece of code live?
FSMBehaviorHow does an aggregate move through life?

The stack reads top-down. C4 describes any system independent of paradigm. DDD defines the units inside one C4 container. Hexagonal Architecture organizes the source tree implementing one DDD bounded context. FSM lives at the deepest layer, encoded inside an aggregate root, governing transitions that the application layer triggers through input ports.

C4 Container (one deployable service, e.g. procurement-platform-be)
    └── DDD bounded context (e.g. purchasing)
        └── Hexagonal hexagon (domain core + ports + adapters)
            └── DDD aggregate root (e.g. PurchaseOrder)
                └── FSM (PurchaseOrder lifecycle: draft → pending → approved → issued → ...)

Every guide in each case touches one or more of these layers explicitly.

Running Domain — Procure-to-Pay Procurement Platform

All three cases reason against the same hypothetical service: procurement-platform-be, the backend of a Procure-to-Pay (P2P) procurement platform.

Bounded contextAggregate rootResponsibility
purchasingPurchaseRequisition, PurchaseOrderRequisition lifecycle, approval routing, PO issuance
supplierSupplierVendor master, approval state, risk score
receivingGoodsReceiptNoteGoods receipt against PO, quantity verification
invoicingInvoiceInvoice registration, three-way matching (PO ↔ GRN ↔ Invoice)
paymentsPaymentPayment run scheduling, bank disbursement
murabaha-financeMurabahaContract (optional Sharia tier)Bank-purchased asset, markup contract, repayment schedule

Same contexts, same aggregates, same domain events, same ports, same state machines across all three cases — only the language and framework idioms differ.

Why Three Parallel Cases

Comparing the F# wiring of Guide 5 (a port as a function type alias) against the Java wiring of Guide 5 (a port as a nominal interface) against the Go wiring of Guide 5 (a port as a small structural interface satisfied implicitly) against the same business problem is the fastest way to internalise the structural decisions that hexagonal architecture, DDD, and the C4/FSM frames demand — regardless of which paradigm you ultimately ship with. Within each paradigm, additional language implementations (Clojure, TypeScript, and Haskell on the FP side; Kotlin, C#, and TypeScript on the OOP side; Rust on the Procedural side) show how the same structural decisions translate into different language idioms without changing the underlying wiring logic.

Last updated May 16, 2026

Command Palette

Search for a command to run...