A state machine turns a plain status field into a guided workflow: an instance can only move between states along the transitions you define, and each move can run checks or follow-up steps before it's confirmed. This walkthrough builds a complete example — an Expense Report that flows Draft → Submitted → Approved or Rejected → Paid — so you can see how every piece fits together.

You'll combine building blocks Yellow already provides:

  • an enumeration whose items are the states,
  • a State Machine constraint that says "this model's status lives in this property and uses this enumeration",
  • transition records that define the allowed moves, and
  • a reference constraint so the status field shows as a dropdown.

What you'll build

Piece Purpose
ExpenseReport model The thing that has a workflow — Title, Amount, Submitter, and a State property.
ExpenseReportStatus enumeration The set of states: Draft, Submitted, Approved, Rejected, Paid.
State Machine constraint Binds the State property of ExpenseReport to the ExpenseReportStatus enumeration.
Transitions The allowed moves between states.
RejectionInfo model Extra data captured when a report is rejected.

Step 1 — Create the status enumeration

Create an enumeration named ExpenseReportStatus and add one item per state. Give each item a Name (shown to users) and an Id (a number you choose, used for ordering):

Item Id
Draft 1
Submitted 2
Approved 3
Rejected 4
Paid 5

Result: an enumeration with five items, listed in Id order.

Step 2 — Create the ExpenseReport model

Create a model named ExpenseReport with these properties:

Property Type What it does
Title Text A short title for the report.
Amount Number The total amount.
Submitter Text Who submitted it.
State Reference Holds the current state — it points at an item of ExpenseReportStatus.

The State property is the one the workflow moves; the other three are ordinary fields.

Step 3 — Make State a dropdown

Add a reference constraint on the State property so it only accepts the statuses:

  • Target Model: EnumerationItem
  • Enumeration: ExpenseReportStatus
  • Required: yes

Result: when you edit an expense report, State shows as a dropdown of the five statuses instead of a free reference picker.

Step 4 — Declare the state machine

Add a State Machine constraint with:

  • Model: ExpenseReport
  • Property: State
  • State Machine: ExpenseReportStatus

This tells Yellow that ExpenseReport has a workflow and which property holds its status.

Step 5 — Define the transitions

Create one transition per allowed move. Each transition names the State Machine, an Initial State, a Final State, and a Direct setting. Some also point at an Additional Info model for extra data.

From To Direct Additional Info
Draft Submitted Yes
Submitted Approved No
Submitted Rejected No RejectionInfo
Approved Paid No

For the Reject transition, first create a small RejectionInfo model with Reason (Text) and Rejected By (Text). Whoever rejects a report fills these in.

Direct vs. non-direct moves

The Direct setting decides how a move is applied:

  • Direct = Yes — the move happens immediately when you save. Draft → Submitted is direct: submitting is always allowed, so the state changes right away.
  • Direct = No — the move is recorded as a request and applied afterwards, once Yellow has run the model's validations and any follow-up steps. Submitted → Approved is non-direct: approval can depend on rules, so it's checked before the state changes.

A non-direct move that can't be completed comes back with the reason, and the state stays where it was.

Using it

Open an expense report in Draft and look for the Save & transition menu next to Save. It lists only the states you can reach from the current one — from Draft you'll see Submitted.

  1. Pick Submitted. Because that move is direct, the report changes to Submitted as soon as it saves.
  2. From Submitted, pick Approved or Rejected. These are non-direct: Yellow records the request and resolves it, then updates the state if the rules pass.
  3. Choosing Rejected first opens a small form — the RejectionInfo fields — so you can capture the reason. Fill it in and confirm.

The State field is read-only in the editor on purpose: the only way to change it is through a transition, which keeps the workflow's rules in force.

Where to find it

The status enumeration and its items live in the Enumerations area. The model, its State property, and both constraints are edited in the model editor. Transitions are ordinary instances of the StateMachineTransition model, so you create and edit them just like any other data.

  • Enumerations — the states are an enumeration's items.
  • Constraints — the reference and State Machine constraints used here.
  • Property types — references and the other property types.