0018. In-memory ticket store as transitional persistence

#Context

The OrderTicket aggregate (ADR 0017) needs persistence:

A durable persistence backend (Postgres / EventStore) is a non-trivial trajectory in itself: schema design, snapshot versus event-sourced layout, transactional boundaries that align with the command workflow, snapshotting policy. None of that is on the critical path for the current milestone (six strategies running end-to-end on a single host).

A precedent exists. Workflow_engine.In_memory_store has served the saga layer since Order_process_manager landed and is the canonical shape for transitional persistence in this codebase.

#Decision

Ship a Ticket_store.S hexagonal port with a single in-memory adapter, modelled on Workflow_engine.In_memory_store.

#Port

module type Ticket_store.S = sig
  type t

  val get        : t -> Ticket_id.t -> Order_ticket.t option
  val put        : t -> Order_ticket.t -> unit
  val all_open   : t -> Order_ticket.t list
  val active_count : t -> int
end

The port is the boundary every command workflow and query handler depends on. The composition root chooses the adapter.

#Adapter: In_memory_ticket_store

A Hashtbl keyed by Ticket_id.t plus a Mutex to serialise writes. all_open filters out terminal tickets. Concurrency semantics:

#Out of scope

#Migration path to a durable backend

When the durable backend lands:

  1. Add Persistence.Postgres_ticket_store (or similar) under execution_management/lib/infrastructure/persistence/.
  2. The composition root swaps the adapter argument; no workflow / query / domain code changes.
  3. Migration of in-flight tickets across the cutover is a one-shot replay against the new backend, fed from the bus's replayable IE stream (every aggregate event is already published).

The port surface is intentionally minimal so that this swap stays a configuration change.

#Mirror with ADR 0005

This decision mirrors the trajectory of the account-reservations ledger (ADR 0005): an in-memory ledger shipped first, with a durable backend planned along the same port. Two BCs, one pattern; durable persistence rolls out in a separate consistent trajectory rather than piecemeal per BC.

#Consequences

Easier:

Harder:

To watch for:

#References