A workflow in CYPEX is a state machine stored with your data model: named states, allowed transitions, and which roles may fire each transition. Once you enable enforcement, it is applied in the database — a CHECK constraint on the state column plus a trigger that rejects any transition you did not model, and checks the caller’s role against the transition’s permissions. The UI only offers what the database would accept anyway.
The walkthrough below builds a TODO list so you can see the full loop from schema → workflow → Application Designer. After creating your first application, use this pattern for any entity that needs controlled status changes.
Here’s some sample data:
BEGIN;
CREATE ROLE todo_owner LOGIN;
GRANT todo_owner TO authenticator;
CREATE SCHEMA todo AUTHORIZATION todo_owner;
CREATE TABLE todo.t_todo
(
id serial PRIMARY KEY,
tstamp date DEFAULT now(),
todo_item text NOT NULL,
status text
);
INSERT INTO todo.t_todo (tstamp, todo_item, status)
VALUES
('2021-03-04',' Do the laundry', 'created'),
('2021-03-06',' Cut the grass', 'accepted'),
('2021-03-09',' Eat a steak', 'success'),
('2021-03-12',' Slaughter a chicken', 'rejected');
COMMIT;
For the sake of simplicity, the TODO list consists of just one table. What is noteworthy here is the last column: The status informs us about the state of an object. A task might have succeeded, failed or it might have been rejected.
Workflows are created and configured on the Builder → Database page: open the table’s three-dot menu, choose Workflow, and pick the state column. See Understanding CYPEX workflows for the full editor reference.

Transitions are drawn by dragging an arrow from one state to the next.

With enforcement enabled, the table accepts only the transitions defined in the graph.
Finally, set the query permissions and generate the application from Builder → Applications:

The application is rendered normally. The interesting part is the status column: where the state column appears in a display context rather than as a form input, and the underlying query is updatable, CYPEX renders a state-change control listing the transitions available from the current state.
The control offers only the transitions you modelled, so a row in accepted can move to success or rejected and nowhere else. Whether the row can still be edited at all depends on the state’s Allow State Updates setting: without it, CYPEX records no self-transition, and with enforcement enabled the database rejects any update to a row in that state. Deleting a row likewise requires a transition to END.