A saga in a table, because the alternative was a framework

A three-step process across two external systems, needing compensation when step two fails, and no appetite for a workflow engine.

CREATE TABLE checkout_sagas (
  id            BINARY(16) PRIMARY KEY,
  order_id      BIGINT UNSIGNED NOT NULL,
  state         ENUM('reserving','charging','confirming',
                     'done','compensating','failed') NOT NULL,
  attempts      TINYINT UNSIGNED NOT NULL DEFAULT 0,
  last_error    VARCHAR(512) NULL,
  updated_at    DATETIME(6) NOT NULL,
  KEY idx_stuck (state, updated_at)
) ENGINE=InnoDB;

A state machine in a table, advanced by a job per transition, covers this entirely — the index on state and update time is what makes a stuck saga findable, which is the operational requirement a workflow engine sells hardest. What we gave up is the visual designer and the retry semantics somebody else has debugged. For three steps that is the right trade; for thirty it would not be.