lib_fsm is not maintained anymore at Netwo but its maintainer continue to work on it [here](https://github.com/FGRibreau/lib_fsm/)
[x] User-defined state support: let your user specify their own state machine while still ensuring consistency
[x] Multi-tenant: each row/column from your table can reference a state in another state machine
[x] Historical support: successful state changes are recorded
[x] Complete API
[x] Fully tested
[x] Visual graph generation
A finite state machine has states, events and transitions.
A state machine can go from one state to another state through a transition.
State change is triggered with an event.
A transition is a tuple of a start (previous) state, the event that will trigger the transition and a next state.
An abstract state machine describe a state machine, its (abstract) state and (abstract) transition.
A state machine is an instance of an abstract state machine and points to an abstract state, thus an abstract state machine.
A consistent naming convention is essential to build a futur-proof project.
Use shared SQL convention as well as an SQL linter.
-
must be a verb
-
verb tense must be either at the simple past (+ed) or at present progressive (+ing)
-
lower-case
-
snake_case if multiple words (e.g.
locked_out)
Examples: opened, loading, loaded, recorded, closed, locked, dumped, shipped, finished, running, failed, entered, enabled, disabled, approved, published, archived, activated, pending, pending_renewal, expired, ordered, canceled, returned, refunded, checked_out
A trigger on every tables that listen to the table state column and that have a custom type like lib_fsm.state_machine to know it must be monitored.
-
Cons:
-
Custom types in PostgreSQL requires a C extension
-
C extensions are not supported in PostgreSQL managed environments
-
Rejected.
The previous idea but instead of a custom type, we rely on a composite type (last_state, abstract_machine__id).
-
Pros:
-
Easier to maintain
-
Does not need column names convention
-
-
Cons:
-
No foreign key on abstract_machine__id (ensure referential integrity with a trigger)
-
No foreign key on abstract_machine__id (ensuring referential integrity with a trigger would require a schema introspection to retrieve all columns of type lib_fsm.state_machine.abstract_machine\__id === old.abstract_machine__id)
-
Rejected.
Externalize each machine current states to an independent table.
Each state is linked to a finite state machine (see abstract state machine).
-
Pros:
-
The table schema explicitly states that one of more columns are each linked to their state machine
-
Supports multiple state (e.g. a contract might two columns, a
signed_statusand awriting_status)
-
-
Cons:
-
Looking at a table, you don’t know the value of the current state (e.g. a contract status attribute). It requires an extra join.
-
-
❏ add support for versioning
-
❏ add support for transition
properties -
❏ add support for transition
triggers: 0-N triggers, what events should automatically trigger the transition -
❏ add support for transition
conditions: 0-N (cf: ui-predicate), requires implementinglib_rule_enginefirst -
❏ add support for transition
pre_conditions: 0-N, these pre-conditions are run before displaying available events from 'from_state' post_actions (0-N, what to do once we switched toto_state) ⇐ WONT_IMPLEMENT
Code is written following standard SQL-convention.