{"id":19946838,"url":"https://github.com/datainq/yfsm","last_synced_at":"2025-07-21T09:32:32.375Z","repository":{"id":57500427,"uuid":"212502416","full_name":"datainq/yfsm","owner":"datainq","description":"Yet (another) finite state machine in Go with Postgres for persistance ","archived":false,"fork":false,"pushed_at":"2019-10-03T08:51:23.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-01T14:17:35.548Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datainq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-03T05:19:44.000Z","updated_at":"2019-10-03T08:51:25.000Z","dependencies_parsed_at":"2022-08-31T00:22:28.243Z","dependency_job_id":null,"html_url":"https://github.com/datainq/yfsm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/datainq/yfsm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datainq%2Fyfsm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datainq%2Fyfsm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datainq%2Fyfsm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datainq%2Fyfsm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datainq","download_url":"https://codeload.github.com/datainq/yfsm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datainq%2Fyfsm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266276093,"owners_count":23903981,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T00:32:58.745Z","updated_at":"2025-07-21T09:32:32.344Z","avatar_url":"https://github.com/datainq.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# yfsm\n\nYet (another) Finite State Machine library.\n\nThe library was created for one the ecommerce projects in DataInq ecommerce lab.\n\nMain concepts are:\n - state\n - event\n\nThe graph of states and transitions can be described by tuples:\n`\u003cstate0, event, state1\u003e`.\n\nThe library has the capability of saving the state change history.\nYou should provide a `History` implementation.\n\n## Usage\n\n1. Create necessary tables in Postgre database.\n2. Populate tables with states and data.\n3. In your code, create a `Machine` instance with a `Type` object. You can use\n   `SqlType` with table name and state column provided.\n4. You can play with the states:\n\n```\nm := yfsm.NewMachine()\n```\n\n## Configuring state machine\n\n`state_machine` table contains all state machines you want to use. If you have\nmany object types you want to manage state, e.g. orders and warehouse\ncommodity transfer, you probably should create two separate machines:\n`order_state` and `parcel_state`.\n\n```\nINSERT INTO state_machine(id, name) VALUES (1, 'order_states');\n```\n\nYou must provide states:\n```\nINSERT INTO state_machine_state(id, state_machine_id, name, start, stop) VALUES\n(1, 1, 'CREATED', TRUE, FALSE),\n(2, 1, 'BUYER_DATA', FALSE, FALSE),\n(3, 1, 'PAYMENT', FALSE, FALSE),\n(4, 1, 'EXTERNAL_PAYMENT', FALSE, FALSE),\n(5, 1, 'WAITING_FOR_ACCEPT', FALSE, FALSE),\n(6, 1, 'COLLECT', FALSE, FALSE),\n(7, 1, 'SEND', FALSE, FALSE),\n(8, 1, 'ON_THE_WAY', FALSE, FALSE),\n(9, 1, 'DELIVERED', FALSE, FALSE),\n(10, 1, 'DONE', FALSE, TRUE),\n(11, 1, 'PAYMENT_FAIL', FALSE, TRUE),\n(12, 1, 'FAIL_TO_DELIVER', FALSE, TRUE),\n(13, 1, 'DECLINED', FALSE, TRUE),\n(14, 1, 'CANCELED', FALSE, TRUE);\n```\n\nHaving states (think about them as nodes in graph), one must define transitions\nbetween states. We have two concepts around that: `event` and `transition`.\nThe first can be though as a name e.g. `OK` may be an event, whereas transition\nis a tuple of `(fromState, event, toState)`. There may be multiple transitions\ndefined for same event.\n\nLet's define some events:\n```\nINSERT INTO state_machine_event(id, state_machine_id, name)\nVALUES\n(1, 1, 'OK'),\n(2, 1, 'FAIL'),\n(3, 1, 'RETRY');\n```\n\nThen we may define exact transitions we want to allow:\n```\nINSERT INTO state_machine_transition(\n    id,\n    state_machine_id,\n    state_machine_event_id,\n    from_state_id,\n    to_state_id\n) VALUES\n(1, 1, 1, 1, 2),  -- 'CREATED' - on 'OK' change to 'BUYER_DATA'\n(12, 1, 3, 11, 4);  -- 'DECLINED' - on 'RETRY' change to 'EXTERNAL_PAYMENT'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatainq%2Fyfsm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatainq%2Fyfsm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatainq%2Fyfsm/lists"}