trustid_sdk 0.2.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.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +80 -0
  3. data/lib/trustid_sdk/client.rb +21 -0
  4. data/lib/trustid_sdk/concerns/attribute_resolution.rb +19 -0
  5. data/lib/trustid_sdk/concerns/has_nested_models.rb +179 -0
  6. data/lib/trustid_sdk/config.rb +45 -0
  7. data/lib/trustid_sdk/errors.rb +23 -0
  8. data/lib/trustid_sdk/models/access_lock.rb +28 -0
  9. data/lib/trustid_sdk/models/advanced_query_arguments.rb +78 -0
  10. data/lib/trustid_sdk/models/application_flexible_field.rb +34 -0
  11. data/lib/trustid_sdk/models/application_flexible_field_attribute.rb +75 -0
  12. data/lib/trustid_sdk/models/application_flexible_field_list.rb +79 -0
  13. data/lib/trustid_sdk/models/application_flexible_field_value.rb +79 -0
  14. data/lib/trustid_sdk/models/base_model.rb +53 -0
  15. data/lib/trustid_sdk/models/branch.rb +34 -0
  16. data/lib/trustid_sdk/models/callback_info.rb +33 -0
  17. data/lib/trustid_sdk/models/callback_state.rb +46 -0
  18. data/lib/trustid_sdk/models/chargeable_status.rb +31 -0
  19. data/lib/trustid_sdk/models/configuration.rb +78 -0
  20. data/lib/trustid_sdk/models/container.rb +254 -0
  21. data/lib/trustid_sdk/models/custom_field.rb +29 -0
  22. data/lib/trustid_sdk/models/dbs_check_initiation.rb +14 -0
  23. data/lib/trustid_sdk/models/dbs_form.rb +108 -0
  24. data/lib/trustid_sdk/models/digital_identification_scheme.rb +43 -0
  25. data/lib/trustid_sdk/models/document.rb +646 -0
  26. data/lib/trustid_sdk/models/document_configuration.rb +21 -0
  27. data/lib/trustid_sdk/models/document_container_field.rb +31 -0
  28. data/lib/trustid_sdk/models/document_container_validation.rb +45 -0
  29. data/lib/trustid_sdk/models/document_container_validation_outcome.rb +58 -0
  30. data/lib/trustid_sdk/models/document_feature_feedback.rb +24 -0
  31. data/lib/trustid_sdk/models/document_feedback.rb +35 -0
  32. data/lib/trustid_sdk/models/document_field.rb +48 -0
  33. data/lib/trustid_sdk/models/document_field_data_type.rb +22 -0
  34. data/lib/trustid_sdk/models/document_field_source.rb +34 -0
  35. data/lib/trustid_sdk/models/document_sorting_column.rb +27 -0
  36. data/lib/trustid_sdk/models/document_source.rb +29 -0
  37. data/lib/trustid_sdk/models/document_status.rb +34 -0
  38. data/lib/trustid_sdk/models/document_storage_type.rb +32 -0
  39. data/lib/trustid_sdk/models/document_type.rb +46 -0
  40. data/lib/trustid_sdk/models/document_type_charge_status.rb +37 -0
  41. data/lib/trustid_sdk/models/document_validation.rb +45 -0
  42. data/lib/trustid_sdk/models/document_validation_result.rb +60 -0
  43. data/lib/trustid_sdk/models/established_document_data.rb +20 -0
  44. data/lib/trustid_sdk/models/external_service_data.rb +29 -0
  45. data/lib/trustid_sdk/models/filter_date_option.rb +36 -0
  46. data/lib/trustid_sdk/models/flexible_field_data_type.rb +39 -0
  47. data/lib/trustid_sdk/models/flexible_field_search_specification.rb +50 -0
  48. data/lib/trustid_sdk/models/flexible_field_specification_search_operator.rb +30 -0
  49. data/lib/trustid_sdk/models/gender.rb +31 -0
  50. data/lib/trustid_sdk/models/guest_link_response.rb +38 -0
  51. data/lib/trustid_sdk/models/image.rb +101 -0
  52. data/lib/trustid_sdk/models/image_orientation.rb +52 -0
  53. data/lib/trustid_sdk/models/image_type.rb +89 -0
  54. data/lib/trustid_sdk/models/kdb_country.rb +37 -0
  55. data/lib/trustid_sdk/models/kdb_document_number.rb +37 -0
  56. data/lib/trustid_sdk/models/kdb_document_sub_type.rb +28 -0
  57. data/lib/trustid_sdk/models/kdb_feature_type.rb +45 -0
  58. data/lib/trustid_sdk/models/liveness_result_type.rb +55 -0
  59. data/lib/trustid_sdk/models/mrz_query_option.rb +35 -0
  60. data/lib/trustid_sdk/models/ocr_coordinates.rb +19 -0
  61. data/lib/trustid_sdk/models/ocr_field.rb +78 -0
  62. data/lib/trustid_sdk/models/ocr_field_data.rb +28 -0
  63. data/lib/trustid_sdk/models/organisation.rb +19 -0
  64. data/lib/trustid_sdk/models/overall_status.rb +39 -0
  65. data/lib/trustid_sdk/models/pdf.rb +17 -0
  66. data/lib/trustid_sdk/models/referral_history_record.rb +68 -0
  67. data/lib/trustid_sdk/models/referral_type.rb +27 -0
  68. data/lib/trustid_sdk/models/remaining_credits.rb +16 -0
  69. data/lib/trustid_sdk/models/report.rb +17 -0
  70. data/lib/trustid_sdk/models/review_application_state.rb +33 -0
  71. data/lib/trustid_sdk/models/sorting_direction.rb +28 -0
  72. data/lib/trustid_sdk/models/user.rb +41 -0
  73. data/lib/trustid_sdk/models/user_archive_visibility.rb +28 -0
  74. data/lib/trustid_sdk/models/user_reference.rb +16 -0
  75. data/lib/trustid_sdk/models/webhook_callback.rb +129 -0
  76. data/lib/trustid_sdk/models/webhook_data.rb +272 -0
  77. data/lib/trustid_sdk/models/webhook_response.rb +89 -0
  78. data/lib/trustid_sdk/models/workflow_storage_item.rb +52 -0
  79. data/lib/trustid_sdk/models/workflow_type.rb +31 -0
  80. data/lib/trustid_sdk/request.rb +116 -0
  81. data/lib/trustid_sdk/services/authentication.rb +23 -0
  82. data/lib/trustid_sdk/services/containers.rb +20 -0
  83. data/lib/trustid_sdk/services/documents.rb +23 -0
  84. data/lib/trustid_sdk/services/guest_links.rb +19 -0
  85. data/lib/trustid_sdk/services/images.rb +21 -0
  86. data/lib/trustid_sdk/services/reports.rb +79 -0
  87. data/lib/trustid_sdk/services/webhook_parser.rb +220 -0
  88. data/lib/trustid_sdk/version.rb +5 -0
  89. data/lib/trustid_sdk.rb +23 -0
  90. metadata +186 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 301c57a0d10d984e3596a83163bac369d92daee4cc785a90553c0f6d958f3be7
4
+ data.tar.gz: 87e4f7fa237313d37ecc7b640239bebfe9353355e4e3f7e5cd338364637baf07
5
+ SHA512:
6
+ metadata.gz: '09df2387ca97b8753e74c36fe72fddd3cb929bd1e02114e89151cb278e68471157e03d506d72c7ec4b23329c9446f2045f84117067ee5c7f81f6c6de7b22de4b'
7
+ data.tar.gz: c493a5aea56b14f9d85dfd30b6f11e8026bc82f976e524824977263e42da19fc738e224fb1dd92ee352b9ba825f95a7fa9e2245ded1e003041a2895c2982285e
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # TrustID SDK
2
+
3
+ A modular Ruby SDK for interacting with the TrustID API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install trustid_sdk
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ ### Production Mode
14
+ ```ruby
15
+ TrustID.configure do |config|
16
+ config.username = ENV["TRUSTID_USERNAME"]
17
+ config.password = ENV["TRUSTID_PASSWORD"]
18
+ config.api_key = ENV["TRUSTID_API_KEY"]
19
+ # Optional: Override default production URL
20
+ # config.server_url = "https://custom-production-url.com"
21
+ end
22
+ ```
23
+
24
+ ### Sandbox Mode
25
+ ```ruby
26
+ TrustID.configure do |config|
27
+ config.username = ENV["TRUSTID_USERNAME"]
28
+ config.password = ENV["TRUSTID_PASSWORD"]
29
+ config.api_key = ENV["TRUSTID_API_KEY"]
30
+ config.sandbox_mode = true
31
+ # Optional: Override default sandbox URL
32
+ # config.server_url = "https://custom-sandbox-url.com"
33
+ end
34
+ ```
35
+
36
+ ### Device ID
37
+
38
+ `device_id` can be a string or a proc (or any object that responds to `call`). When it is a proc, it is invoked each time the SDK needs the device ID (e.g. for requests and reports), and the returned value is used.
39
+
40
+ This is particularly useful for **parallel usage**: if you run multiple clients or workers, each needs a distinct device ID and session. If you reuse the same device ID, the next login for that device invalidates the previous session. Setting `device_id` to a proc that returns a new value per client (e.g. `-> { "prefix-#{SecureRandom.uuid}" }`) ensures each logical “device” gets a unique ID and its own session.
41
+
42
+ ```ruby
43
+ require 'securerandom'
44
+
45
+ TrustID.configure do |config|
46
+ config.username = ENV["TRUSTID_USERNAME"]
47
+ config.password = ENV["TRUSTID_PASSWORD"]
48
+ config.api_key = ENV["TRUSTID_API_KEY"]
49
+ # Unique device ID per client/worker so each has its own session
50
+ config.device_id = -> { "worker-#{SecureRandom.uuid}" }
51
+ end
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ ```ruby
57
+ client = TrustID::Client.new
58
+
59
+ TrustID::Services::GuestLinks.create(email: "jane@example.com", name: "Jane Example")
60
+ TrustID::Services::Containers.retrieve(container_id: "abc123")
61
+ TrustID::Services::Documents.retrieve(container_id: "abc123", document_id: "doc456")
62
+ image_data = TrustID::Services::Images.retrieve(image_id: "img789")
63
+
64
+ # Export PDF report (recommended - uses POST with JSON, more secure)
65
+ pdf = TrustID::Services::Reports.find_report(container_id: "abc123")
66
+
67
+ # Download PDF using GET request
68
+ pdf = TrustID::Services::Reports.find_pdf(container_id: "abc123")
69
+
70
+ # Generate a download link URL for embedding in HTML
71
+ download_url = TrustID::Services::Reports.download_link(container_id: "abc123")
72
+ # Use in HTML: <a href="#{download_url}" download>Download PDF</a>
73
+ ```
74
+
75
+ ## Development
76
+
77
+ ```bash
78
+ bundle install
79
+ rspec
80
+ ```
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ class Client
5
+ attr_reader :server_url
6
+ attr_accessor :session_id
7
+
8
+ def initialize
9
+ config = TrustID.config
10
+ @device_id = config.device_id
11
+ @server_url = config.server_url
12
+ TrustID.client = self
13
+ Services::Authentication.new(config.username, config.password).login
14
+ end
15
+
16
+ def device_id
17
+ value = @device_id
18
+ value.respond_to?(:call) ? value.call : value
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ module AttributeResolution
5
+ private
6
+
7
+ def resolve_enum(value, enum_module)
8
+ return nil if value.nil?
9
+
10
+ enum_module.respond_to?(:name_for) ? enum_module.name_for(value) : value
11
+ end
12
+
13
+ def resolve_model(value, klass)
14
+ return klass.new({}) if value.nil?
15
+
16
+ value.is_a?(klass) ? value : klass.new(value)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ # HasNestedModels is a concern that allows models to define nested models
5
+ # with support for single objects or arrays. It provides methods to define
6
+ # nested models, handle attribute extraction, and create instances from hashes.
7
+ module HasNestedModels
8
+ def self.included(base)
9
+ base.extend(ClassMethods)
10
+ base.include(ActiveModel::Model) unless base.include?(ActiveModel::Model)
11
+ base.include(ActiveModel::Attributes) unless base.include?(ActiveModel::Attributes)
12
+ end
13
+
14
+ # ClassMethods module to define nested models
15
+ module ClassMethods
16
+ # Register a nested model (single object or array)
17
+ def nested_model(attr, klass, array: false, keys: nil)
18
+ keys ||= infer_keys(attr, klass)
19
+ nested_model_definitions[attr.to_s] = {
20
+ klass: klass,
21
+ array: array,
22
+ keys: keys
23
+ }
24
+ define_nested_model_accessors(attr)
25
+ end
26
+
27
+ def nested_model_definitions
28
+ @nested_model_definitions ||= {}
29
+ end
30
+
31
+ # Helper method to extract attributes with multiple potential keys
32
+ def extract_attribute(attrs, *keys)
33
+ keys.each do |key|
34
+ if attrs.key?(key)
35
+ value = attrs.delete(key)
36
+ return value unless value.nil?
37
+ end
38
+ end
39
+ nil
40
+ end
41
+
42
+ # Helper to create model instance from hash
43
+ def create_nested_instance(klass, data)
44
+ return nil if data.nil?
45
+ return data if data.is_a?(klass)
46
+
47
+ klass.respond_to?(:from_hash) ? klass.from_hash(data) : klass.new(data)
48
+ end
49
+
50
+ private
51
+
52
+ def define_nested_model_accessors(attr)
53
+ define_method(attr) { instance_variable_get("@#{attr}") }
54
+ define_method("#{attr}=") do |value|
55
+ config = self.class.nested_model_definitions[attr.to_s]
56
+ processed = self.class.process_nested_value(config, value)
57
+ instance_variable_set("@#{attr}", processed)
58
+ end
59
+ end
60
+
61
+ def process_nested_value(config, value)
62
+ if config[:array]
63
+ Array(value).map { |item| create_nested_instance(config[:klass], item) }.compact
64
+ else
65
+ create_nested_instance(config[:klass], value)
66
+ end
67
+ end
68
+ public :process_nested_value
69
+
70
+ def infer_keys(attr, klass)
71
+ attr_str = attr.to_s
72
+ attr_sym = attr.to_sym
73
+ camel = attr_str.camelize
74
+ camel_sym = camel.to_sym
75
+ klass_str = klass.name.split('::').last
76
+ [
77
+ attr_str, camel, attr_sym, camel_sym,
78
+ klass_str, klass_str.underscore, klass_str.to_sym, klass_str.underscore.to_sym
79
+ ].uniq
80
+ end
81
+ end
82
+
83
+ def initialize(attrs = {})
84
+ # Normalize input hash - convert all keys to strings for consistent lookup
85
+ attrs = attrs.transform_keys(&:to_s) if attrs.is_a?(Hash)
86
+
87
+ # Extract nested model data and assign to normalized keys
88
+ nested_values = {}
89
+ self.class.nested_model_definitions.each do |attr, config|
90
+ value = nil
91
+ config[:keys].each do |key|
92
+ key_str = key.to_s
93
+ if attrs.key?(key_str)
94
+ value = attrs.delete(key_str)
95
+ break if value
96
+ end
97
+ end
98
+ attrs[attr.to_s] = value if value
99
+ nested_values[attr] = value if value
100
+ end
101
+
102
+ # Initialize with normalized attributes
103
+ super
104
+
105
+ # Always call the setter for each nested attribute to ensure type conversion
106
+ nested_values.each do |attr, value|
107
+ next if value.nil?
108
+
109
+ send("#{attr}=", value)
110
+ end
111
+ end
112
+
113
+ def assign_attributes(new_attributes)
114
+ return unless new_attributes
115
+
116
+ # Handle nested attributes first
117
+ nested_attrs = {}
118
+ self.class.nested_model_definitions.each do |attr, config|
119
+ config[:keys].each do |key|
120
+ next unless new_attributes.key?(key.to_s) || new_attributes.key?(key.to_sym)
121
+
122
+ value = new_attributes.delete(key.to_s) || new_attributes.delete(key.to_sym)
123
+ nested_attrs[attr] = value unless value.nil?
124
+ break
125
+ end
126
+ end
127
+
128
+ # Update nested models
129
+ nested_attrs.each do |attr, value|
130
+ send("#{attr}=", value)
131
+ end
132
+
133
+ # Handle remaining attributes
134
+ super
135
+ end
136
+
137
+ def process_nested_models
138
+ return unless defined?(@nested_data) && @nested_data.is_a?(Hash)
139
+
140
+ self.class.nested_model_definitions.each do |attr, config|
141
+ next unless @nested_data[attr]
142
+
143
+ value = @nested_data[attr]
144
+ processed_value = if config[:array]
145
+ value.map { |item| self.class.create_nested_instance(config[:klass], item) }.compact
146
+ else
147
+ self.class.create_nested_instance(config[:klass], value)
148
+ end
149
+
150
+ instance_variable_set("@#{attr}", processed_value)
151
+ define_accessors(attr)
152
+ end
153
+ end
154
+
155
+ protected
156
+
157
+ def define_accessors(attr_name)
158
+ unless respond_to?(attr_name)
159
+ define_singleton_method(attr_name) do
160
+ instance_variable_get("@#{attr_name}")
161
+ end
162
+ end
163
+
164
+ return if respond_to?("#{attr_name}=")
165
+
166
+ define_singleton_method("#{attr_name}=") do |value|
167
+ config = self.class.nested_model_definitions[attr_name]
168
+
169
+ processed = if config[:array]
170
+ Array(value).map { |item| self.class.create_nested_instance(config[:klass], item) }.compact
171
+ else
172
+ self.class.create_nested_instance(config[:klass], value)
173
+ end
174
+
175
+ instance_variable_set("@#{attr_name}", processed)
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Main module for TrustID SDK functionality
4
+ module TrustID
5
+ # Configuration class for TrustID SDK settings
6
+ class Config
7
+ attr_accessor :username, :password, :device_id, :api_key
8
+
9
+ def initialize
10
+ @sandbox_mode = false
11
+ @api_header_key = 'Tid-Api-Key'
12
+ end
13
+
14
+ def sandbox_mode=(mode)
15
+ @sandbox_mode = mode
16
+ # Set default server URL based on mode if not explicitly set
17
+ @server_url = default_server_url if @server_url.nil?
18
+ end
19
+
20
+ attr_reader :api_header_key, :sandbox_mode
21
+ attr_writer :server_url
22
+
23
+ def server_url
24
+ @server_url ||= default_server_url
25
+ end
26
+
27
+ def debug_mode=(debug_mode = false)
28
+ TrustID.debug_mode = debug_mode
29
+ end
30
+
31
+ private
32
+
33
+ def default_server_url
34
+ @sandbox_mode ? 'https://sandbox.trustid.co.uk' : 'https://cloud.trustid.co.uk'
35
+ end
36
+ end
37
+
38
+ def self.config
39
+ @config ||= Config.new
40
+ end
41
+
42
+ def self.configure
43
+ yield(config)
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ module Errors
5
+ class ClientError < StandardError; end
6
+
7
+ class APIError < StandardError
8
+ attr_reader :response
9
+
10
+ def initialize(response)
11
+ @message = response['Message']
12
+ @response = response
13
+ super(@message)
14
+ end
15
+ end
16
+
17
+ class AuthenticationError < APIError; end
18
+ class BadRequestError < APIError; end
19
+ class UnauthorizedError < APIError; end
20
+ class ForbiddenError < APIError; end
21
+ class NotFoundError < APIError; end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ # Represents locking information for shared resources on TrustID Cloud.
5
+ #
6
+ # Fields as per TrustID API documentation:
7
+ # anonymous_session_id [String]: SHA256 hash of session id.
8
+ # locked [Boolean]: Whether the resource is locked.
9
+ # timestamp [DateTime]: ISO8601 datetime of the lock.
10
+ # user_display [String]: Display name of the user holding the lock.
11
+ # user_id [String]: ID of the user holding the lock.
12
+ # user [User, nil]: User model (resolved if present).
13
+ #
14
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/AccessLock.html
15
+ class AccessLock < BaseModel
16
+ attribute :anonymous_session_id, :string
17
+ attribute :locked, :boolean
18
+ attribute :timestamp, :datetime
19
+ attribute :user_display, :string
20
+ attribute :user_id, :string
21
+ attr_reader :user
22
+
23
+ def initialize(attributes = {})
24
+ super
25
+ @user = resolve_model(attributes[:user], TrustID::User)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model'
4
+ require_relative '../concerns/attribute_resolution'
5
+
6
+ module TrustID
7
+ # Represents advanced query arguments for searching documents and applications in the TrustID API.
8
+ #
9
+ # Fields as per TrustID API documentation:
10
+ # status [Integer]: Status code to filter by.
11
+ # audited [Boolean]: Whether the record is audited.
12
+ # mrz_corrected [Boolean]: Whether the MRZ was corrected.
13
+ # min_age_failed [Integer]: Minimum age failure filter.
14
+ # max_age_failed [Integer]: Maximum age failure filter.
15
+ # quick_query [String]: Quick search string.
16
+ # firstname [String]: First name filter.
17
+ # lastname [String]: Last name filter.
18
+ # nationality_code [String]: Nationality code filter.
19
+ # issuing_country_code [String]: Issuing country code filter.
20
+ # document_number [String]: Document number filter.
21
+ # passport_number [String]: Passport number filter.
22
+ # visa_number [String]: Visa number filter.
23
+ # identity_card_number [String]: Identity card number filter.
24
+ # driving_license_number [String]: Driving license number filter.
25
+ # document_type [Integer]: Document type filter.
26
+ # personal_number [String]: Personal number filter.
27
+ # expiry_date [Date]: Expiry date filter.
28
+ # date_of_birth [Date]: Date of birth filter.
29
+ # scanned_by [String]: Scanned by user filter.
30
+ # audited_by [String]: Audited by user filter.
31
+ # branch_name [String]: Branch name filter.
32
+ # gender [Gender, nil]: Gender filter (enum).
33
+ # mrz_query_option [MrzQueryOption, nil]: MRZ query option (enum).
34
+ # filter_expiry_date_option [FilterDateOption, nil]: Expiry date filter option (enum).
35
+ # filter_date_of_birth_date_option [FilterDateOption, nil]: Date of birth filter option (enum).
36
+ # custom_fields [Array<CustomField>]: Custom field filters.
37
+ #
38
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/AdvancedQueryArguments.html
39
+ class AdvancedQueryArguments < BaseModel
40
+ # Simple attributes
41
+ attribute :status, :integer
42
+ attribute :audited, :boolean
43
+ attribute :mrz_corrected, :boolean
44
+ attribute :min_age_failed, :integer
45
+ attribute :max_age_failed, :integer
46
+ attribute :quick_query, :string
47
+ attribute :firstname, :string
48
+ attribute :lastname, :string
49
+ attribute :nationality_code, :string
50
+ attribute :issuing_country_code, :string
51
+ attribute :document_number, :string
52
+ attribute :passport_number, :string
53
+ attribute :visa_number, :string
54
+ attribute :identity_card_number, :string
55
+ attribute :driving_license_number, :string
56
+ attribute :document_type, :integer
57
+ attribute :personal_number, :string
58
+ attribute :expiry_date, :date
59
+ attribute :date_of_birth, :date
60
+ attribute :scanned_by, :string
61
+ attribute :audited_by, :string
62
+ attribute :branch_name, :string
63
+
64
+ # Expose nested/enum attributes as readers
65
+ attr_reader :gender, :mrz_query_option, :filter_expiry_date_option, :filter_date_of_birth_date_option,
66
+ :custom_fields
67
+
68
+ def initialize(attributes = {})
69
+ super
70
+ @gender = resolve_enum(attributes[:gender], TrustID::Gender)
71
+ @mrz_query_option = resolve_enum(attributes[:mrz_query_option], TrustID::MrzQueryOption)
72
+ @filter_expiry_date_option = resolve_enum(attributes[:filter_expiry_date_option], TrustID::FilterDateOption)
73
+ @filter_date_of_birth_date_option = resolve_enum(attributes[:filter_date_of_birth_date_option],
74
+ TrustID::FilterDateOption)
75
+ @custom_fields = Array(attributes[:custom_fields]).map { |cf| resolve_model(cf, TrustID::CustomField) }
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ # ApplicationFlexibleField
5
+ #
6
+ # Enum representing the types of flexible fields that can be associated with an application.
7
+ #
8
+ # Enum values:
9
+ # NEW_APPLICATION_FIELD (1) - New application field.
10
+ # NEW_QUEUED_APPLICATION_FIELD (2) - New queued application field.
11
+ # POPULATE_QUEUED_APPLICATION_FIELD (4) - Populate queued application field.
12
+ # NEW_GUEST_LINK_FIELD (256) - New guest link field.
13
+ #
14
+ # Use as: ApplicationFlexibleField::NEW_APPLICATION_FIELD, etc.
15
+ #
16
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/ApplicationFlexibleField.html
17
+ class ApplicationFlexibleField
18
+ NEW_APPLICATION_FIELD = 1
19
+ NEW_QUEUED_APPLICATION_FIELD = 2
20
+ POPULATE_QUEUED_APPLICATION_FIELD = 4
21
+ NEW_GUEST_LINK_FIELD = 256
22
+
23
+ NAMES = {
24
+ NEW_APPLICATION_FIELD => 'NewApplicationField',
25
+ NEW_QUEUED_APPLICATION_FIELD => 'NewQueuedApplicationField',
26
+ POPULATE_QUEUED_APPLICATION_FIELD => 'PopulateQueuedApplicationField',
27
+ NEW_GUEST_LINK_FIELD => 'NewGuestLinkField'
28
+ }.freeze
29
+
30
+ def self.name_for(code)
31
+ NAMES[code]
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ # Represents a template for an application-level custom field (flexible field attribute).
5
+ # Application flexible fields are associated with document containers.
6
+ #
7
+ # Fields as per TrustID API documentation:
8
+ # branch_id [String]: The branch that applies to this field.
9
+ # creation_date [DateTime]: When this field was created.
10
+ # data_range [String]: Comma-separated list of possible values if enum.
11
+ # data_type [Integer]: See FlexibleFieldDataType.
12
+ # default_value [String]: The default value for this field.
13
+ # display_name [String]: Display name for the field.
14
+ # entity_id [String]: The entity ID associated with this field.
15
+ # field_order_index [Integer]: Order in which field is presented.
16
+ # flags [Integer]: Flags associated with this field.
17
+ # flexible_field_id [String]: Unique identifier shared between all versions.
18
+ # help_text [String]: Help information for the user.
19
+ # id [String]: Unique version identifier.
20
+ # is_active [Boolean]: True if this is the active version.
21
+ # is_enabled [Boolean]: True if the field is enabled.
22
+ # is_global [Boolean]: True if the field is global.
23
+ # is_validation_field [Boolean]: True if validated against pass/warn/fail.
24
+ # last_modifield [DateTime]: When this field was last modified.
25
+ # mandatory [Boolean]: True if this field is mandatory.
26
+ # name [String]: Internal name.
27
+ # validation_fail_value [String]: Value considered a fail.
28
+ # validation_pass_value [String]: Value considered a pass.
29
+ # validation_warning_value [String]: Value considered a warning.
30
+ #
31
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/ApplicationFlexibleFieldAttribute.html
32
+ class ApplicationFlexibleFieldAttribute < BaseModel
33
+ # Explicitly define all attributes found in the API response
34
+ attribute :branch_id, :string
35
+ attribute :creation_date, :datetime
36
+ attribute :data_range, :string
37
+ attribute :data_type, :integer
38
+ attribute :default_value, :string
39
+ attribute :display_name, :string
40
+ attribute :entity_id, :string
41
+ attribute :field_order_index, :integer
42
+ attribute :flags, :integer
43
+ attribute :flexible_field_id, :string
44
+ attribute :help_text, :string
45
+ attribute :id, :string
46
+ attribute :is_active, :boolean
47
+ attribute :is_enabled, :boolean
48
+ attribute :is_global, :boolean
49
+ attribute :is_validation_field, :boolean
50
+ attribute :last_modifield, :datetime
51
+ attribute :mandatory, :boolean
52
+ attribute :name, :string
53
+ attribute :validation_fail_value, :string
54
+ attribute :validation_pass_value, :string
55
+ attribute :validation_warning_value, :string
56
+
57
+ def initialize(attributes = {})
58
+ # Normalize keys to handle API response format
59
+ attributes = normalize_keys(attributes)
60
+ super
61
+ end
62
+
63
+ private
64
+
65
+ # Helper method to normalize keys to lowercase symbols
66
+ def normalize_keys(hash)
67
+ result = {}
68
+ hash.each do |key, value|
69
+ key_str = key.to_s.underscore.downcase
70
+ result[key_str.to_sym] = value
71
+ end
72
+ result
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'application_flexible_field_attribute'
4
+ require_relative 'application_flexible_field_value'
5
+
6
+ module TrustID
7
+ # ApplicationFlexibleFieldList
8
+ #
9
+ # Represents a single pair of (attribute, value) for a custom application field.
10
+ #
11
+ # This is a value object that wraps a single pair, not a true list or collection.
12
+ #
13
+ # Fields:
14
+ # attribute - ApplicationFlexibleFieldAttribute: The type/metadata for the custom field.
15
+ # value - ApplicationFlexibleFieldValue: The value for the custom field.
16
+ #
17
+ # When initialized, this model expects a hash with either:
18
+ # - keys :m_Item1 and :m_Item2 (as returned by the TrustID API), or
19
+ # - keys :attribute and :value (for internal use).
20
+ #
21
+ # The model will resolve and wrap the attribute and value using their respective models.
22
+ #
23
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/ApplicationFlexibleFieldList.html
24
+ class ApplicationFlexibleFieldList < BaseModel
25
+ attr_reader :attribute, :value
26
+
27
+ attribute :m_item1 # For API compatibility
28
+ attribute :m_item2 # For API compatibility
29
+
30
+ def initialize(attributes = {})
31
+ # Normalize attribute keys
32
+ attributes = normalize_keys(attributes)
33
+
34
+ # Extract attribute and value data
35
+ @attribute_data = attributes.delete(:m_item1) || attributes.delete('m_item1') ||
36
+ attributes.delete(:attribute) || attributes.delete('attribute')
37
+ @value_data = attributes.delete(:m_item2) || attributes.delete('m_item2') ||
38
+ attributes.delete(:value) || attributes.delete('value')
39
+
40
+ # Initialize with remaining attributes
41
+ super
42
+
43
+ # Process nested models
44
+ process_nested_models
45
+ end
46
+
47
+ def process_nested_models
48
+ self.attribute = @attribute_data if @attribute_data
49
+ self.value = @value_data if @value_data
50
+ end
51
+
52
+ def attribute=(data)
53
+ @attribute = if data.is_a?(TrustID::ApplicationFlexibleFieldAttribute)
54
+ data
55
+ else
56
+ TrustID::ApplicationFlexibleFieldAttribute.from_hash(data)
57
+ end
58
+ end
59
+
60
+ def value=(data)
61
+ @value = if data.is_a?(TrustID::ApplicationFlexibleFieldValue)
62
+ data
63
+ else
64
+ TrustID::ApplicationFlexibleFieldValue.from_hash(data)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def normalize_keys(hash)
71
+ result = {}
72
+ hash.each do |key, value|
73
+ normalized_key = key.to_s.downcase.to_sym
74
+ result[normalized_key] = value
75
+ end
76
+ result
77
+ end
78
+ end
79
+ end