vortex-ruby-sdk 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18819ec338fa097c24046e0a535a98483acbe55e0163fe6e6db86d0160334a1b
4
- data.tar.gz: 1cdbc41d41372b4658ef5a38db7ee6cbda22f5c63227738bd8ac79140215af43
3
+ metadata.gz: e7f6c2f423b5aa8099f7ccce759daaf6dcdd114c6052f1ffb9d9f5072d505916
4
+ data.tar.gz: 46755e0df9a92907219042a2f2373f6f067aa46f57a1409159cc215ae14823f3
5
5
  SHA512:
6
- metadata.gz: 950cf7e0435224d9e7aa534d94b3999ed72f823b2211eb368a332de4fe683f8c0998bbde59a445571b5b7fb81cc5de60036944c7944a124f4933ea0aae41a698
7
- data.tar.gz: 561c091c7232a282cbe854dacdc3d2e3eaac70fb28a7b6c08dee852d4b7466d56f2fe4c07e7834cfe1e23c2802786c5019d6cf514f720ac3341fa5827085fa92
6
+ metadata.gz: 55c8a0671bcad40614d75363ef1b0aaf7b2323f47e9dd717940f59fd026b449c64d79b6c7b9bbed6493199c4c3d1beaac97c3e728409407339bb41363c93b1f9
7
+ data.tar.gz: fcce54f801ef8115f7567cded83704409fb8436f34056aa296c77210099e0519dd59d8b51f29ff8eb05669acefb088e5cdf4a8a7f2603033f84de1767192b025
data/README.md CHANGED
@@ -5,6 +5,8 @@ A Ruby SDK for the Vortex invitation system, providing seamless integration with
5
5
  ## Features
6
6
 
7
7
  - **JWT Generation**: Identical algorithm to other SDKs for complete compatibility
8
+ - **Simplified JWT Format**: New streamlined payload with `userEmail` and `adminScopes`
9
+ - **Backward Compatible**: Legacy JWT format still supported
8
10
  - **Complete API Coverage**: All invitation management operations
9
11
  - **Framework Integration**: Built-in Rails and Sinatra helpers
10
12
  - **Same Route Structure**: Ensures React provider compatibility
@@ -39,13 +41,15 @@ require 'vortex'
39
41
  # Initialize the client
40
42
  client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
41
43
 
42
- # Generate JWT for a user
43
- jwt = client.generate_jwt(
44
- user_id: 'user123',
45
- identifiers: [{ type: 'email', value: 'user@example.com' }],
46
- groups: [{ id: 'team1', type: 'team', name: 'Engineering' }],
47
- role: 'admin'
48
- )
44
+ # Create a user object
45
+ user = {
46
+ id: 'user-123',
47
+ email: 'user@example.com',
48
+ admin_scopes: ['autojoin'] # Optional - included as adminScopes array in JWT
49
+ }
50
+
51
+ # Generate JWT
52
+ jwt = client.generate_jwt(user: user)
49
53
 
50
54
  # Get invitations by target
51
55
  invitations = client.get_invitations_by_target('email', 'user@example.com')
@@ -57,6 +61,22 @@ client.accept_invitations(['inv1', 'inv2'], { type: 'email', value: 'user@exampl
57
61
  group_invitations = client.get_invitations_by_group('team', 'team1')
58
62
  ```
59
63
 
64
+ ### Generate JWT with Additional Properties
65
+
66
+ ```ruby
67
+ user = {
68
+ id: 'user-123',
69
+ email: 'user@example.com'
70
+ }
71
+
72
+ extra = {
73
+ role: 'admin',
74
+ department: 'Engineering'
75
+ }
76
+
77
+ jwt = client.generate_jwt(user: user, extra: extra)
78
+ ```
79
+
60
80
  ## Rails Integration
61
81
 
62
82
  Create a controller with Vortex routes:
@@ -70,13 +90,13 @@ class VortexController < ApplicationController
70
90
 
71
91
  def authenticate_vortex_user
72
92
  # Return user data hash or nil
93
+ admin_scopes = []
94
+ admin_scopes << 'autojoin' if current_user.admin?
95
+
73
96
  {
74
- user_id: current_user.id,
75
- identifiers: [{ type: 'email', value: current_user.email }],
76
- groups: current_user.teams.map { |team|
77
- { id: team.id, type: 'team', name: team.name }
78
- },
79
- role: current_user.role
97
+ id: current_user.id,
98
+ email: current_user.email,
99
+ admin_scopes: admin_scopes
80
100
  }
81
101
  end
82
102
 
@@ -86,7 +106,7 @@ class VortexController < ApplicationController
86
106
  when 'JWT', 'GET_INVITATIONS'
87
107
  true
88
108
  when 'REVOKE_INVITATION'
89
- user[:role] == 'admin'
109
+ user[:admin_scopes]&.include?('autojoin')
90
110
  else
91
111
  false
92
112
  end
@@ -134,10 +154,9 @@ class MyApp < Sinatra::Base
134
154
  return nil unless user_id
135
155
 
136
156
  {
137
- user_id: user_id,
138
- identifiers: [{ type: 'email', value: 'user@example.com' }],
139
- groups: [{ id: 'team1', type: 'team', name: 'Engineering' }],
140
- role: 'user'
157
+ id: user_id,
158
+ email: 'user@example.com',
159
+ admin_scopes: [] # Optional
141
160
  }
142
161
  end
143
162
 
@@ -153,9 +172,13 @@ end
153
172
  All methods match the functionality of other Vortex SDKs:
154
173
 
155
174
  ### JWT Generation
156
- - `generate_jwt(user_id:, identifiers:, groups:, role: nil)` - Generate JWT token
175
+
176
+ - `generate_jwt(user:, extra: nil)` - Generate JWT token
177
+ - `user`: Hash with `:id`, `:email`, and optional `:admin_scopes` array
178
+ - `extra`: Optional hash with additional properties to include in JWT payload
157
179
 
158
180
  ### Invitation Management
181
+
159
182
  - `get_invitations_by_target(target_type, target_value)` - Get invitations by target
160
183
  - `get_invitation(invitation_id)` - Get specific invitation
161
184
  - `revoke_invitation(invitation_id)` - Revoke invitation
@@ -177,13 +200,33 @@ The SDK provides these routes (same as other SDKs for React provider compatibili
177
200
  - `DELETE /api/vortex/invitations/by-group/:type/:id`
178
201
  - `POST /api/vortex/invitations/:id/reinvite`
179
202
 
203
+ ## JWT Payload Structure
204
+
205
+ The SDK generates JWTs with the following payload structure:
206
+
207
+ ```ruby
208
+ {
209
+ userId: 'user-123',
210
+ userEmail: 'user@example.com',
211
+ adminScopes: ['autojoin'], # Full array included if admin_scopes provided
212
+ expires: 1234567890
213
+ }
214
+ ```
215
+
216
+ Additional properties from the `extra` parameter are merged into the payload.
217
+
180
218
  ## Error Handling
181
219
 
182
220
  All methods raise `Vortex::VortexError` on failures:
183
221
 
184
222
  ```ruby
185
223
  begin
186
- jwt = client.generate_jwt(user_data)
224
+ jwt = client.generate_jwt(
225
+ user: {
226
+ id: 'user-123',
227
+ email: 'user@example.com'
228
+ }
229
+ )
187
230
  rescue Vortex::VortexError => e
188
231
  logger.error "Vortex error: #{e.message}"
189
232
  end
@@ -201,4 +244,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/vortex
201
244
 
202
245
  ## License
203
246
 
204
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
247
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -13,29 +13,35 @@ require 'vortex'
13
13
  API_KEY = ENV['VORTEX_API_KEY'] || 'your-api-key-here'
14
14
  client = Vortex::Client.new(API_KEY)
15
15
 
16
- # Example user data - same structure as other SDKs
17
- user_data = {
18
- user_id: 'user123',
19
- identifiers: [
20
- { type: 'email', value: 'user@example.com' }
21
- ],
22
- groups: [
23
- { id: 'team1', type: 'team', name: 'Engineering Team' },
24
- { id: 'dept1', type: 'department', name: 'Product Development' }
25
- ],
26
- role: 'admin'
16
+ # Example user data
17
+ user = {
18
+ id: 'user123',
19
+ email: 'user@example.com',
20
+ admin_scopes: ['autojoin'] # Optional - included as adminScopes array in JWT
21
+ }
22
+
23
+ # Additional properties (optional)
24
+ extra = {
25
+ role: 'admin',
26
+ department: 'Engineering'
27
27
  }
28
28
 
29
29
  begin
30
30
  puts "=== Vortex Ruby SDK Example ==="
31
31
  puts
32
32
 
33
- # 1. Generate JWT
33
+ # 1. Generate JWT for user
34
34
  puts "1. Generating JWT for user..."
35
- jwt = client.generate_jwt(**user_data)
35
+ jwt = client.generate_jwt(user: user)
36
36
  puts "JWT generated: #{jwt[0..50]}..."
37
37
  puts
38
38
 
39
+ # 1b. Generate JWT with additional properties
40
+ puts "1b. Generating JWT with additional properties..."
41
+ jwt_with_extra = client.generate_jwt(user: user, extra: extra)
42
+ puts "JWT with extra generated: #{jwt_with_extra[0..50]}..."
43
+ puts
44
+
39
45
  # 2. Get invitations by target
40
46
  puts "2. Getting invitations by email target..."
41
47
  invitations = client.get_invitations_by_target('email', 'user@example.com')
@@ -32,16 +32,15 @@ class VortexController < ActionController::Base
32
32
  user_id = session[:user_id] || request.headers['X-User-ID']
33
33
  return nil unless user_id
34
34
 
35
- # Return user data in the format expected by Vortex
35
+ # Build admin_scopes array
36
+ admin_scopes = []
37
+ admin_scopes << 'autojoin' if session[:user_role] == 'admin'
38
+
39
+ # Return user data
36
40
  {
37
- user_id: user_id,
38
- identifiers: [
39
- { type: 'email', value: session[:user_email] || 'user@example.com' }
40
- ],
41
- groups: [
42
- { id: 'team1', type: 'team', name: 'Engineering' }
43
- ],
44
- role: session[:user_role] || 'user'
41
+ id: user_id,
42
+ email: session[:user_email] || 'user@example.com',
43
+ admin_scopes: admin_scopes
45
44
  }
46
45
  end
47
46
 
@@ -56,9 +55,9 @@ class VortexController < ActionController::Base
56
55
  when 'ACCEPT_INVITATIONS'
57
56
  true # Everyone can accept invitations
58
57
  when 'REVOKE_INVITATION', 'DELETE_GROUP_INVITATIONS'
59
- user[:role] == 'admin' # Only admins can delete
58
+ user[:admin_scopes]&.include?('autojoin') # Only admins can delete
60
59
  when 'GET_GROUP_INVITATIONS', 'REINVITE'
61
- user[:role] == 'admin' # Only admins can manage groups
60
+ user[:admin_scopes]&.include?('autojoin') # Only admins can manage groups
62
61
  else
63
62
  false
64
63
  end
@@ -25,16 +25,15 @@ class VortexSinatraApp < Sinatra::Base
25
25
  user_id = request.env['HTTP_X_USER_ID'] || 'demo-user'
26
26
  return nil unless user_id
27
27
 
28
- # Return user data in the format expected by Vortex
28
+ # Build admin_scopes array
29
+ admin_scopes = []
30
+ admin_scopes << 'autojoin' if request.env['HTTP_X_USER_ROLE'] == 'admin'
31
+
32
+ # Return user data
29
33
  {
30
- user_id: user_id,
31
- identifiers: [
32
- { type: 'email', value: request.env['HTTP_X_USER_EMAIL'] || 'demo@example.com' }
33
- ],
34
- groups: [
35
- { id: 'team1', type: 'team', name: 'Engineering' }
36
- ],
37
- role: request.env['HTTP_X_USER_ROLE'] || 'user'
34
+ id: user_id,
35
+ email: request.env['HTTP_X_USER_EMAIL'] || 'demo@example.com',
36
+ admin_scopes: admin_scopes
38
37
  }
39
38
  end
40
39
 
@@ -48,9 +47,9 @@ class VortexSinatraApp < Sinatra::Base
48
47
  when 'ACCEPT_INVITATIONS'
49
48
  true # Everyone can accept invitations
50
49
  when 'REVOKE_INVITATION', 'DELETE_GROUP_INVITATIONS'
51
- user[:role] == 'admin' # Only admins can delete
50
+ user[:admin_scopes]&.include?('autojoin') # Only admins can delete
52
51
  when 'GET_GROUP_INVITATIONS', 'REINVITE'
53
- user[:role] == 'admin' # Only admins can manage groups
52
+ user[:admin_scopes]&.include?('autojoin') # Only admins can manage groups
54
53
  else
55
54
  false
56
55
  end
data/lib/vortex/client.rb CHANGED
@@ -23,18 +23,31 @@ module Vortex
23
23
  @connection = build_connection
24
24
  end
25
25
 
26
- # Generate a JWT for the given user data
26
+ # Generate a JWT token for a user
27
27
  #
28
- # This uses the exact same algorithm as the Node.js SDK to ensure
29
- # complete compatibility across all platforms.
30
- #
31
- # @param user_id [String] Unique identifier for the user
32
- # @param identifiers [Array<Hash>] Array of identifier hashes with :type and :value
33
- # @param groups [Array<Hash>] Array of group hashes with :id, :type, and :name
34
- # @param role [String, nil] Optional user role
28
+ # @param params [Hash] JWT parameters with :user (required) and optional :attributes
35
29
  # @return [String] JWT token
36
30
  # @raise [VortexError] If API key is invalid or JWT generation fails
37
- def generate_jwt(user_id:, identifiers:, groups:, role: nil)
31
+ #
32
+ # @example Simple usage
33
+ # client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
34
+ # jwt = client.generate_jwt({
35
+ # user: {
36
+ # id: 'user-123',
37
+ # email: 'user@example.com',
38
+ # admin_scopes: ['autojoin']
39
+ # }
40
+ # })
41
+ #
42
+ # @example With additional attributes
43
+ # jwt = client.generate_jwt({
44
+ # user: { id: 'user-123', email: 'user@example.com' },
45
+ # attributes: { role: 'admin', department: 'Engineering' }
46
+ # })
47
+ def generate_jwt(params)
48
+ user = params[:user]
49
+ attributes = params[:attributes]
50
+
38
51
  # Parse API key - same format as Node.js SDK
39
52
  prefix, encoded_id, key = @api_key.split('.')
40
53
 
@@ -52,7 +65,7 @@ module Vortex
52
65
  # Step 1: Derive signing key from API key + ID (same as Node.js)
53
66
  signing_key = OpenSSL::HMAC.digest('sha256', key, id)
54
67
 
55
- # Step 2: Build header + payload (same structure as Node.js)
68
+ # Step 2: Build header + payload
56
69
  header = {
57
70
  iat: Time.now.to_i,
58
71
  alg: 'HS256',
@@ -60,14 +73,23 @@ module Vortex
60
73
  kid: id
61
74
  }
62
75
 
76
+ # Build payload - start with required fields
63
77
  payload = {
64
- userId: user_id,
65
- groups: groups,
66
- role: role,
67
- expires: expires,
68
- identifiers: identifiers
78
+ userId: user[:id],
79
+ userEmail: user[:email],
80
+ expires: expires
69
81
  }
70
82
 
83
+ # Add adminScopes if present
84
+ if user[:admin_scopes]
85
+ payload[:adminScopes] = user[:admin_scopes]
86
+ end
87
+
88
+ # Add any additional properties from attributes
89
+ if attributes && !attributes.empty?
90
+ payload.merge!(attributes)
91
+ end
92
+
71
93
  # Step 3: Base64URL encode (same as Node.js)
72
94
  header_b64 = base64url_encode(JSON.generate(header))
73
95
  payload_b64 = base64url_encode(JSON.generate(payload))
@@ -81,6 +103,8 @@ module Vortex
81
103
  raise VortexError, "JWT generation failed: #{e.message}"
82
104
  end
83
105
 
106
+ public
107
+
84
108
  # Get invitations by target
85
109
  #
86
110
  # @param target_type [String] Type of target (email, sms)
data/lib/vortex/rails.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'logger'
3
4
  require 'vortex/client'
4
5
  require 'vortex/error'
5
6
 
@@ -28,6 +29,17 @@ module Vortex
28
29
  # @vortex_client ||= Vortex::Client.new(ENV['VORTEX_API_KEY'])
29
30
  # end
30
31
  # end
32
+ #
33
+ # Configure logging:
34
+ # Vortex::Rails.logger = MyLogger.new
35
+ class << self
36
+ attr_writer :logger
37
+
38
+ def logger
39
+ @logger ||= defined?(::Rails) ? ::Rails.logger : Logger.new(nil)
40
+ end
41
+ end
42
+
31
43
  module Controller
32
44
  extend ActiveSupport::Concern
33
45
 
@@ -39,28 +51,54 @@ module Vortex
39
51
  # Generate JWT for authenticated user
40
52
  # POST /api/vortex/jwt
41
53
  def generate_jwt
54
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#generate_jwt invoked")
55
+
42
56
  user = authenticate_vortex_user
43
57
  return render_unauthorized('Authentication required') unless user
44
58
 
45
59
  unless authorize_vortex_operation('JWT', user)
60
+ Vortex::Rails.logger.warn("Vortex JWT authorization failed for user #{user[:user_id]}")
46
61
  return render_forbidden('Not authorized to generate JWT')
47
62
  end
48
63
 
49
- jwt = vortex_client.generate_jwt(
50
- user_id: user[:user_id],
51
- identifiers: user[:identifiers],
52
- groups: user[:groups],
53
- role: user[:role]
54
- )
64
+ # Extract email from identifiers for the user hash
65
+ email = user[:identifiers]&.find { |i| i[:type] == 'email' }&.dig(:value)
66
+
67
+ # Build the JWT
68
+ jwt_params = {
69
+ user: {
70
+ id: user[:user_id],
71
+ email: email
72
+ }
73
+ }
55
74
 
75
+ # Add adminScopes if present
76
+ if user[:admin_scopes]&.any?
77
+ jwt_params[:user][:admin_scopes] = user[:admin_scopes]
78
+ end
79
+
80
+ # Add attributes if present
81
+ if user[:attributes]
82
+ jwt_params[:attributes] = user[:attributes]
83
+ end
84
+
85
+ jwt = vortex_client.generate_jwt(jwt_params)
86
+
87
+ Vortex::Rails.logger.debug("Vortex JWT generated successfully for user #{user[:user_id]}")
56
88
  render json: { jwt: jwt }
57
89
  rescue Vortex::VortexError => e
90
+ Vortex::Rails.logger.error("Vortex error generating JWT: #{e.message}")
58
91
  render_server_error("Failed to generate JWT: #{e.message}")
92
+ rescue StandardError => e
93
+ Vortex::Rails.logger.error("Unexpected error generating JWT: #{e.class} - #{e.message}")
94
+ render_server_error("Unexpected error: #{e.message}")
59
95
  end
60
96
 
61
97
  # Get invitations by target
62
98
  # GET /api/vortex/invitations?targetType=email&targetValue=user@example.com
63
99
  def get_invitations_by_target
100
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#get_invitations_by_target invoked")
101
+
64
102
  user = authenticate_vortex_user
65
103
  return render_unauthorized('Authentication required') unless user
66
104
 
@@ -82,6 +120,8 @@ module Vortex
82
120
  # Get specific invitation by ID
83
121
  # GET /api/vortex/invitations/:invitation_id
84
122
  def get_invitation
123
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#get_invitation invoked")
124
+
85
125
  user = authenticate_vortex_user
86
126
  return render_unauthorized('Authentication required') unless user
87
127
 
@@ -99,6 +139,8 @@ module Vortex
99
139
  # Revoke (delete) invitation
100
140
  # DELETE /api/vortex/invitations/:invitation_id
101
141
  def revoke_invitation
142
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#revoke_invitation invoked")
143
+
102
144
  user = authenticate_vortex_user
103
145
  return render_unauthorized('Authentication required') unless user
104
146
 
@@ -116,6 +158,8 @@ module Vortex
116
158
  # Accept invitations
117
159
  # POST /api/vortex/invitations/accept
118
160
  def accept_invitations
161
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#accept_invitations invoked")
162
+
119
163
  user = authenticate_vortex_user
120
164
  return render_unauthorized('Authentication required') unless user
121
165
 
@@ -139,6 +183,8 @@ module Vortex
139
183
  # Get invitations by group
140
184
  # GET /api/vortex/invitations/by-group/:group_type/:group_id
141
185
  def get_invitations_by_group
186
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#get_invitations_by_group invoked")
187
+
142
188
  user = authenticate_vortex_user
143
189
  return render_unauthorized('Authentication required') unless user
144
190
 
@@ -158,6 +204,8 @@ module Vortex
158
204
  # Delete invitations by group
159
205
  # DELETE /api/vortex/invitations/by-group/:group_type/:group_id
160
206
  def delete_invitations_by_group
207
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#delete_invitations_by_group invoked")
208
+
161
209
  user = authenticate_vortex_user
162
210
  return render_unauthorized('Authentication required') unless user
163
211
 
@@ -177,6 +225,8 @@ module Vortex
177
225
  # Reinvite user
178
226
  # POST /api/vortex/invitations/:invitation_id/reinvite
179
227
  def reinvite
228
+ Vortex::Rails.logger.debug("Vortex::Rails::Controller#reinvite invoked")
229
+
180
230
  user = authenticate_vortex_user
181
231
  return render_unauthorized('Authentication required') unless user
182
232
 
@@ -228,7 +278,6 @@ module Vortex
228
278
  end
229
279
 
230
280
  def handle_vortex_error(error)
231
- Rails.logger.error("Vortex error: #{error.message}")
232
281
  render_server_error(error.message)
233
282
  end
234
283
  end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vortex
4
+ # Type documentation for Vortex SDK responses
5
+ # Ruby uses dynamic typing with Hashes, but this documents the expected structure
6
+ module Types
7
+ # Group structure for JWT generation (input)
8
+ # @example
9
+ # {
10
+ # type: 'workspace',
11
+ # id: 'workspace-123', # Legacy field (deprecated, use groupId)
12
+ # groupId: 'workspace-123', # Preferred field
13
+ # name: 'My Workspace'
14
+ # }
15
+ GROUP_INPUT = {
16
+ type: String, # Required: Group type (e.g., "workspace", "team")
17
+ id: String, # Optional: Legacy field (deprecated, use groupId)
18
+ groupId: String, # Optional: Preferred - Customer's group ID
19
+ name: String # Required: Group name
20
+ }.freeze
21
+
22
+ # InvitationGroup structure from API responses
23
+ # This matches the MemberGroups table structure from the API
24
+ # @example
25
+ # {
26
+ # id: '550e8400-e29b-41d4-a716-446655440000',
27
+ # accountId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
28
+ # groupId: 'workspace-123',
29
+ # type: 'workspace',
30
+ # name: 'My Workspace',
31
+ # createdAt: '2025-01-27T12:00:00.000Z'
32
+ # }
33
+ INVITATION_GROUP = {
34
+ id: String, # Vortex internal UUID
35
+ accountId: String, # Vortex account ID
36
+ groupId: String, # Customer's group ID (the ID they provided to Vortex)
37
+ type: String, # Group type (e.g., "workspace", "team")
38
+ name: String, # Group name
39
+ createdAt: String # ISO 8601 timestamp when the group was created
40
+ }.freeze
41
+
42
+ # Invitation structure from API responses
43
+ # @example
44
+ # {
45
+ # id: '550e8400-e29b-41d4-a716-446655440000',
46
+ # accountId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
47
+ # groups: [INVITATION_GROUP, ...],
48
+ # # ... other fields
49
+ # }
50
+ INVITATION = {
51
+ id: String,
52
+ accountId: String,
53
+ clickThroughs: Integer,
54
+ configurationAttributes: Hash,
55
+ attributes: Hash,
56
+ createdAt: String,
57
+ deactivated: :boolean,
58
+ deliveryCount: Integer,
59
+ deliveryTypes: Array, # of String
60
+ foreignCreatorId: String,
61
+ invitationType: String,
62
+ modifiedAt: String,
63
+ status: String,
64
+ target: Array, # of { type: String, value: String }
65
+ views: Integer,
66
+ widgetConfigurationId: String,
67
+ projectId: String,
68
+ groups: Array, # of INVITATION_GROUP structures
69
+ accepts: Array, # of acceptance structures
70
+ expired: :boolean,
71
+ expires: String # ISO 8601 timestamp (optional)
72
+ }.freeze
73
+ end
74
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vortex
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vortex-ruby-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vortex Software
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-17 00:00:00.000000000 Z
11
+ date: 2025-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -156,6 +156,7 @@ files:
156
156
  - lib/vortex/error.rb
157
157
  - lib/vortex/rails.rb
158
158
  - lib/vortex/sinatra.rb
159
+ - lib/vortex/types.rb
159
160
  - lib/vortex/version.rb
160
161
  - vortex-ruby-sdk.gemspec
161
162
  homepage: https://github.com/vortexsoftware/vortex-ruby-sdk
@@ -166,7 +167,7 @@ metadata:
166
167
  homepage_uri: https://github.com/vortexsoftware/vortex-ruby-sdk
167
168
  source_code_uri: https://github.com/vortexsoftware/vortex-ruby-sdk
168
169
  changelog_uri: https://github.com/vortexsoftware/vortex-ruby-sdk/blob/main/CHANGELOG.md
169
- post_install_message:
170
+ post_install_message:
170
171
  rdoc_options: []
171
172
  require_paths:
172
173
  - lib
@@ -181,8 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
182
  - !ruby/object:Gem::Version
182
183
  version: '0'
183
184
  requirements: []
184
- rubygems_version: 3.3.5
185
- signing_key:
185
+ rubygems_version: 3.4.19
186
+ signing_key:
186
187
  specification_version: 4
187
188
  summary: Ruby SDK for Vortex invitation system
188
189
  test_files: []