flowable 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowableClient
4
+ module Resources
5
+ class ProcessDefinitions < Base
6
+ BASE_PATH = 'service/repository/process-definitions'
7
+
8
+ # List all process definitions
9
+ # @param options [Hash] Query parameters
10
+ # @option options [String] :key Filter by key
11
+ # @option options [String] :keyLike Filter by key pattern
12
+ # @option options [String] :name Filter by name
13
+ # @option options [String] :nameLike Filter by name pattern
14
+ # @option options [Integer] :version Filter by version
15
+ # @option options [String] :deploymentId Filter by deployment
16
+ # @option options [Boolean] :latest Only return latest versions
17
+ # @option options [Boolean] :suspended Filter by suspension state
18
+ # @option options [String] :tenantId Filter by tenant
19
+ # @return [Hash] Paginated list of process definitions
20
+ def list(**options)
21
+ params = paginate_params(options)
22
+ %i[key keyLike name nameLike resourceName resourceNameLike
23
+ category categoryLike categoryNotEquals deploymentId
24
+ startableByUser tenantId tenantIdLike].each do |key|
25
+ params[key] = options[key] if options[key]
26
+ end
27
+ params[:version] = options[:version] if options[:version]
28
+ params[:latest] = options[:latest] if options.key?(:latest)
29
+ params[:suspended] = options[:suspended] if options.key?(:suspended)
30
+ params[:withoutTenantId] = options[:withoutTenantId] if options.key?(:withoutTenantId)
31
+
32
+ client.get(BASE_PATH, params)
33
+ end
34
+
35
+ # Get a specific process definition
36
+ # @param process_definition_id [String] The process definition ID
37
+ # @return [Hash] Process definition details
38
+ def get(process_definition_id)
39
+ client.get("#{BASE_PATH}/#{process_definition_id}")
40
+ end
41
+
42
+ # Get process definition by key (returns latest version)
43
+ # @param key [String] The process definition key
44
+ # @param tenant_id [String] Optional tenant ID
45
+ # @return [Hash] Process definition details
46
+ def get_by_key(key, tenant_id: nil)
47
+ params = { key: key, latest: true }
48
+ params[:tenantId] = tenant_id if tenant_id
49
+
50
+ result = client.get(BASE_PATH, params)
51
+ result['data']&.first
52
+ end
53
+
54
+ # Update the category of a process definition
55
+ # @param process_definition_id [String] The process definition ID
56
+ # @param category [String] The new category
57
+ # @return [Hash] Updated process definition
58
+ def update_category(process_definition_id, category)
59
+ client.put("#{BASE_PATH}/#{process_definition_id}", { category: category })
60
+ end
61
+
62
+ # Suspend a process definition
63
+ # @param process_definition_id [String] The process definition ID
64
+ # @param include_instances [Boolean] Also suspend running instances
65
+ # @param date [String] Effective date (ISO-8601)
66
+ # @return [Hash] Updated process definition
67
+ def suspend(process_definition_id, include_instances: false, date: nil)
68
+ body = { action: 'suspend', includeProcessInstances: include_instances }
69
+ body[:date] = date if date
70
+ client.put("#{BASE_PATH}/#{process_definition_id}", body)
71
+ end
72
+
73
+ # Activate a process definition
74
+ # @param process_definition_id [String] The process definition ID
75
+ # @param include_instances [Boolean] Also activate suspended instances
76
+ # @param date [String] Effective date (ISO-8601)
77
+ # @return [Hash] Updated process definition
78
+ def activate(process_definition_id, include_instances: false, date: nil)
79
+ body = { action: 'activate', includeProcessInstances: include_instances }
80
+ body[:date] = date if date
81
+ client.put("#{BASE_PATH}/#{process_definition_id}", body)
82
+ end
83
+
84
+ # Get the BPMN XML content of a process definition
85
+ # @param process_definition_id [String] The process definition ID
86
+ # @return [String] BPMN XML content
87
+ def resource_data(process_definition_id)
88
+ client.get("#{BASE_PATH}/#{process_definition_id}/resourcedata")
89
+ end
90
+
91
+ alias resource_content resource_data
92
+
93
+ # Get the BPMN model as JSON
94
+ # @param process_definition_id [String] The process definition ID
95
+ # @return [Hash] BPMN model structure
96
+ def model(process_definition_id)
97
+ client.get("#{BASE_PATH}/#{process_definition_id}/model")
98
+ end
99
+
100
+ # Get process diagram image (PNG)
101
+ # @param process_definition_id [String] The process definition ID
102
+ # @return [String] Binary image data
103
+ def diagram(process_definition_id)
104
+ client.get("#{BASE_PATH}/#{process_definition_id}/image")
105
+ end
106
+
107
+ alias image diagram
108
+
109
+ # Get all candidate starters for a process definition
110
+ # @param process_definition_id [String] The process definition ID
111
+ # @return [Array<Hash>] List of identity links
112
+ def identity_links(process_definition_id)
113
+ client.get("#{BASE_PATH}/#{process_definition_id}/identitylinks")
114
+ end
115
+
116
+ # Add a candidate starter (user) to a process definition
117
+ # @param process_definition_id [String] The process definition ID
118
+ # @param user_id [String] The user ID
119
+ # @return [Hash] Created identity link
120
+ def add_candidate_user(process_definition_id, user_id)
121
+ client.post("#{BASE_PATH}/#{process_definition_id}/identitylinks", { user: user_id })
122
+ end
123
+
124
+ # Add a candidate starter (group) to a process definition
125
+ # @param process_definition_id [String] The process definition ID
126
+ # @param group_id [String] The group ID
127
+ # @return [Hash] Created identity link
128
+ def add_candidate_group(process_definition_id, group_id)
129
+ client.post("#{BASE_PATH}/#{process_definition_id}/identitylinks", { group: group_id })
130
+ end
131
+
132
+ # Remove a candidate starter from a process definition
133
+ # @param process_definition_id [String] The process definition ID
134
+ # @param family [String] 'users' or 'groups'
135
+ # @param identity_id [String] The user or group ID
136
+ # @return [Boolean] true if successful
137
+ def remove_candidate(process_definition_id, family, identity_id)
138
+ client.delete("#{BASE_PATH}/#{process_definition_id}/identitylinks/#{family}/#{identity_id}")
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowableClient
4
+ module Resources
5
+ class ProcessInstances < Base
6
+ BASE_PATH = 'service/runtime/process-instances'
7
+
8
+ # List all process instances
9
+ # @param options [Hash] Query parameters
10
+ # @option options [String] :id Filter by instance ID
11
+ # @option options [String] :processDefinitionKey Filter by definition key
12
+ # @option options [String] :processDefinitionId Filter by definition ID
13
+ # @option options [String] :businessKey Filter by business key
14
+ # @option options [String] :involvedUser Filter by involved user
15
+ # @option options [Boolean] :suspended Filter suspended instances
16
+ # @option options [String] :tenantId Filter by tenant
17
+ # @return [Hash] Paginated list of process instances
18
+ def list(**options)
19
+ params = paginate_params(options)
20
+ %i[id processDefinitionKey processDefinitionId businessKey
21
+ involvedUser superProcessInstanceId tenantId tenantIdLike].each do |key|
22
+ params[key] = options[key] if options[key]
23
+ end
24
+ params[:suspended] = options[:suspended] if options.key?(:suspended)
25
+ params[:withoutTenantId] = options[:withoutTenantId] if options.key?(:withoutTenantId)
26
+ params[:includeProcessVariables] = options[:includeProcessVariables] if options.key?(:includeProcessVariables)
27
+
28
+ client.get(BASE_PATH, params)
29
+ end
30
+
31
+ # Get a specific process instance
32
+ # @param process_instance_id [String] The process instance ID
33
+ # @return [Hash] Process instance details
34
+ def get(process_instance_id)
35
+ client.get("#{BASE_PATH}/#{process_instance_id}")
36
+ end
37
+
38
+ # Start a new process instance by process definition ID
39
+ # @param process_definition_id [String] The process definition ID
40
+ # @param variables [Hash] Optional variables (name => value)
41
+ # @param business_key [String] Optional business key
42
+ # @param return_variables [Boolean] Return variables in response
43
+ # @return [Hash] Created process instance
44
+ def start_by_id(process_definition_id, variables: {}, business_key: nil, return_variables: false)
45
+ body = { processDefinitionId: process_definition_id }
46
+ body[:businessKey] = business_key if business_key
47
+ body[:variables] = build_variables_array(variables) unless variables.empty?
48
+ body[:returnVariables] = return_variables if return_variables
49
+
50
+ client.post(BASE_PATH, body)
51
+ end
52
+
53
+ # Start a new process instance by process definition key
54
+ # @param process_definition_key [String] The process definition key
55
+ # @param variables [Hash] Optional variables (name => value)
56
+ # @param business_key [String] Optional business key
57
+ # @param tenant_id [String] Optional tenant ID
58
+ # @param return_variables [Boolean] Return variables in response
59
+ # @return [Hash] Created process instance
60
+ def start_by_key(process_definition_key, variables: {}, business_key: nil, tenant_id: nil,
61
+ return_variables: false)
62
+ body = { processDefinitionKey: process_definition_key }
63
+ body[:businessKey] = business_key if business_key
64
+ body[:tenantId] = tenant_id if tenant_id
65
+ body[:variables] = build_variables_array(variables) unless variables.empty?
66
+ body[:returnVariables] = return_variables if return_variables
67
+
68
+ client.post(BASE_PATH, body)
69
+ end
70
+
71
+ # Delete a process instance
72
+ # @param process_instance_id [String] The process instance ID
73
+ # @param delete_reason [String] Reason for deletion
74
+ # @return [Boolean] true if successful
75
+ def delete(process_instance_id, delete_reason: nil)
76
+ params = {}
77
+ params[:deleteReason] = delete_reason if delete_reason
78
+ client.delete("#{BASE_PATH}/#{process_instance_id}", params)
79
+ end
80
+
81
+ # Suspend a process instance
82
+ # @param process_instance_id [String] The process instance ID
83
+ # @return [Hash] Updated process instance
84
+ def suspend(process_instance_id)
85
+ client.put("#{BASE_PATH}/#{process_instance_id}", { action: 'suspend' })
86
+ end
87
+
88
+ # Activate a suspended process instance
89
+ # @param process_instance_id [String] The process instance ID
90
+ # @return [Hash] Updated process instance
91
+ def activate(process_instance_id)
92
+ client.put("#{BASE_PATH}/#{process_instance_id}", { action: 'activate' })
93
+ end
94
+
95
+ # Query process instances with complex filters
96
+ # @param query [Hash] Query body with filters and variable conditions
97
+ # @return [Hash] Paginated list of process instances
98
+ def query(query)
99
+ client.post('service/query/process-instances', query)
100
+ end
101
+
102
+ # Get the diagram/image for a process instance
103
+ # @param process_instance_id [String] The process instance ID
104
+ # @return [String] Binary image data
105
+ def diagram(process_instance_id)
106
+ client.get("#{BASE_PATH}/#{process_instance_id}/diagram")
107
+ end
108
+
109
+ # --- Identity Links ---
110
+
111
+ # Get involved people for a process instance
112
+ # @param process_instance_id [String] The process instance ID
113
+ # @return [Array<Hash>] List of identity links
114
+ def identity_links(process_instance_id)
115
+ client.get("#{BASE_PATH}/#{process_instance_id}/identitylinks")
116
+ end
117
+
118
+ # Add an involved user to a process instance
119
+ # @param process_instance_id [String] The process instance ID
120
+ # @param user_id [String] The user ID
121
+ # @param type [String] Type of involvement (e.g., 'participant')
122
+ # @return [Hash] Created identity link
123
+ def add_involved_user(process_instance_id, user_id, type: 'participant')
124
+ client.post(
125
+ "#{BASE_PATH}/#{process_instance_id}/identitylinks",
126
+ { userId: user_id, type: type }
127
+ )
128
+ end
129
+
130
+ # Remove an involved user from a process instance
131
+ # @param process_instance_id [String] The process instance ID
132
+ # @param user_id [String] The user ID
133
+ # @param type [String] Type of involvement
134
+ # @return [Boolean] true if successful
135
+ def remove_involved_user(process_instance_id, user_id, type)
136
+ client.delete("#{BASE_PATH}/#{process_instance_id}/identitylinks/users/#{user_id}/#{type}")
137
+ end
138
+
139
+ # --- Variables ---
140
+
141
+ # Get all variables for a process instance
142
+ # @param process_instance_id [String] The process instance ID
143
+ # @return [Array<Hash>] List of variables
144
+ def variables(process_instance_id)
145
+ client.get("#{BASE_PATH}/#{process_instance_id}/variables")
146
+ end
147
+
148
+ # Get a specific variable from a process instance
149
+ # @param process_instance_id [String] The process instance ID
150
+ # @param variable_name [String] The variable name
151
+ # @return [Hash] Variable details
152
+ def variable(process_instance_id, variable_name)
153
+ client.get("#{BASE_PATH}/#{process_instance_id}/variables/#{variable_name}")
154
+ end
155
+
156
+ # Create variables on a process instance (fails if exists)
157
+ # @param process_instance_id [String] The process instance ID
158
+ # @param variables [Hash] Variables to create (name => value)
159
+ # @return [Array<Hash>] Created variables
160
+ def create_variables(process_instance_id, variables)
161
+ client.post(
162
+ "#{BASE_PATH}/#{process_instance_id}/variables",
163
+ build_variables_array(variables)
164
+ )
165
+ end
166
+
167
+ # Create or update variables on a process instance
168
+ # @param process_instance_id [String] The process instance ID
169
+ # @param variables [Hash] Variables to set (name => value)
170
+ # @return [Array<Hash>] Updated variables
171
+ def set_variables(process_instance_id, variables)
172
+ client.put(
173
+ "#{BASE_PATH}/#{process_instance_id}/variables",
174
+ build_variables_array(variables)
175
+ )
176
+ end
177
+
178
+ # Update a single variable on a process instance
179
+ # @param process_instance_id [String] The process instance ID
180
+ # @param name [String] Variable name
181
+ # @param value [Object] Variable value
182
+ # @param type [String] Optional explicit type
183
+ # @return [Hash] Updated variable
184
+ def update_variable(process_instance_id, name, value, type: nil)
185
+ body = { name: name, value: value }
186
+ body[:type] = type || infer_type(value)
187
+
188
+ client.put("#{BASE_PATH}/#{process_instance_id}/variables/#{name}", body)
189
+ end
190
+
191
+ # Delete a variable from a process instance
192
+ # @param process_instance_id [String] The process instance ID
193
+ # @param variable_name [String] The variable name
194
+ # @return [Boolean] true if successful
195
+ def delete_variable(process_instance_id, variable_name)
196
+ client.delete("#{BASE_PATH}/#{process_instance_id}/variables/#{variable_name}")
197
+ end
198
+ end
199
+ end
200
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flowable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jakub Polak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-12-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: A comprehensive Ruby client for interacting with Flowable CMMN and BPMN
28
+ engines via REST API. Supports deployments, case/process definitions, instances,
29
+ tasks, variables, history, and more.
30
+ email:
31
+ - jakub.polak.vz@gmail.com
32
+ executables:
33
+ - flowable
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - CHANGELOG.md
38
+ - LICENSE
39
+ - README.md
40
+ - bin/flowable
41
+ - lib/flowable.rb
42
+ - lib/flowable/flowable.rb
43
+ - lib/flowable/resources/base.rb
44
+ - lib/flowable/resources/bpmn_deployments.rb
45
+ - lib/flowable/resources/bpmn_history.rb
46
+ - lib/flowable/resources/case_definitions.rb
47
+ - lib/flowable/resources/case_instances.rb
48
+ - lib/flowable/resources/deployments.rb
49
+ - lib/flowable/resources/executions.rb
50
+ - lib/flowable/resources/history.rb
51
+ - lib/flowable/resources/plan_item_instances.rb
52
+ - lib/flowable/resources/process_definitions.rb
53
+ - lib/flowable/resources/process_instances.rb
54
+ - lib/flowable/resources/tasks.rb
55
+ - lib/flowable/version.rb
56
+ - lib/flowable/workflow.rb
57
+ - lib/flowable_client/resources/bpmn_history.rb
58
+ - lib/flowable_client/resources/process_definitions.rb
59
+ - lib/flowable_client/resources/process_instances.rb
60
+ homepage: https://github.com/kupolak/flowable
61
+ licenses:
62
+ - MIT
63
+ metadata:
64
+ homepage_uri: https://github.com/kupolak/flowable
65
+ source_code_uri: https://github.com/kupolak/flowable
66
+ changelog_uri: https://github.com/kupolak/flowable/blob/main/CHANGELOG.md
67
+ documentation_uri: https://github.com/kupolak/flowable#readme
68
+ bug_tracker_uri: https://github.com/kupolak/flowable/issues
69
+ rubygems_mfa_required: 'true'
70
+ post_install_message: |
71
+ Thank you for installing flowable!
72
+
73
+ Quick start:
74
+ require 'flowable'
75
+ client = Flowable::Client.new(
76
+ host: 'localhost',
77
+ port: 8080,
78
+ username: 'rest-admin',
79
+ password: 'test'
80
+ )
81
+
82
+ CLI usage:
83
+ flowable --help
84
+
85
+ Documentation: https://github.com/kupolak/flowable
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: 3.1.0
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.5.22
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Ruby client for Flowable CMMN and BPMN REST API
104
+ test_files: []