Class: Candid::PreEncounter::Patients::V1::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/candid/pre_encounter/patients/v_1/client.rb

Instance Method Summary collapse

Constructor Details

#initialize(client:, base_url: nil, environment: nil) ⇒ void

Parameters:



13
14
15
16
17
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 13

def initialize(client:, base_url: nil, environment: nil)
  @client = client
  @base_url = base_url
  @environment = environment
end

Instance Method Details

#create(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::Patient

Adds a patient. VersionConflictError is returned when the patient's external ID is already in use.

Parameters:

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

  • :skip_duplicate_check (Boolean, nil)

Returns:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 31

def create(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[skip_duplicate_check]
  query_params = {}
  query_params["skip_duplicate_check"] = params[:skip_duplicate_check] if params.key?(:skip_duplicate_check)
  params = params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "POST",
    path: "/patients/v1",
    query: query_params,
    body: Candid::PreEncounter::Patients::V1::Types::MutablePatient.new(params).to_h,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::Patient.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#create_with_mrn(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::Patient

Adds a patient and hydrates their MRN with a pre-existing MRN. Once this patient is created their MRN will not be editable. BadRequestError is returned when the MRN is greater than 20 characters. VersionConflictError is returned when the patient's external ID is already in use.

Parameters:

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

  • :skip_duplicate_check (Boolean, nil)

Returns:



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 74

def create_with_mrn(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[skip_duplicate_check]
  query_params = {}
  query_params["skip_duplicate_check"] = params[:skip_duplicate_check] if params.key?(:skip_duplicate_check)
  params = params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "POST",
    path: "/patients/v1/with_mrn",
    query: query_params,
    body: Candid::PreEncounter::Patients::V1::Types::MutablePatientWithMrn.new(params).to_h,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::Patient.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#deactivate(request_options: {}, **params) ⇒ untyped

Sets a patient as deactivated. The path must contain the most recent version plus 1 to prevent race conditions. Deactivating historic versions is not supported.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:

  • (untyped)

Raises:

  • (error_class)


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 437

def deactivate(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "DELETE",
    path: "/patients/v1/#{params[:id]}/#{params[:version]}",
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  return if code.between?(200, 299)

  error_class = Candid::Errors::ResponseError.subclass_for_code(code)
  raise error_class.new(response.body, code: code)
end

#get(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::Patient

Gets a patient.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 205

def get(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/#{params[:id]}",
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::Patient.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#get_by_mrn(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::Patient

Gets a patient by mrn.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

  • :mrn (String)

Returns:



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 239

def get_by_mrn(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/mrn/#{params[:mrn]}",
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::Patient.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#get_coverage_snapshot(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::PatientCoverageSnapshot

Gets a patient along with their coverages at a specific point in time. Note that the date passed in is only used to determine what the filing order was for that patient during that time. The actual data returned will always be the latest version of the patient and coverages.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 308

def get_coverage_snapshot(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[date]
  query_params = {}
  query_params["date"] = params[:date] if params.key?(:date)
  params = params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/#{params[:id]}/snapshot",
    query: query_params,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::PatientCoverageSnapshot.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#get_eligibility_timeline(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::EligibilityTimelinePage

Gets a patient's eligibility audit timeline, newest-first. Org-scoped and keyset-paginated.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 353

def get_eligibility_timeline(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[event_types coverage_id appointment_id page_token limit]
  query_params = {}
  query_params["event_types"] = params[:event_types] if params.key?(:event_types)
  query_params["coverage_id"] = params[:coverage_id] if params.key?(:coverage_id)
  query_params["appointment_id"] = params[:appointment_id] if params.key?(:appointment_id)
  query_params["page_token"] = params[:page_token] if params.key?(:page_token)
  query_params["limit"] = params[:limit] if params.key?(:limit)
  params = params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/#{params[:id]}/eligibility-timeline",
    query: query_params,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::EligibilityTimelinePage.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#get_history(request_options: {}, **params) ⇒ Array[Candid::PreEncounter::Patients::V1::Types::Patient]

Gets a patient along with it's full history. The return list is ordered by version ascending.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:

Raises:

  • (error_class)


273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 273

def get_history(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/#{params[:id]}/history",
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  return if code.between?(200, 299)

  error_class = Candid::Errors::ResponseError.subclass_for_code(code)
  raise error_class.new(response.body, code: code)
end

#get_multi(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::PatientPage

Searches for patients that match the query parameters.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 120

def get_multi(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[limit mrn page_token sort_field sort_direction redirect_to_primary]
  query_params = {}
  query_params["limit"] = params[:limit] if params.key?(:limit)
  query_params["mrn"] = params[:mrn] if params.key?(:mrn)
  query_params["page_token"] = params[:page_token] if params.key?(:page_token)
  query_params["sort_field"] = params[:sort_field] if params.key?(:sort_field)
  query_params["sort_direction"] = params[:sort_direction] if params.key?(:sort_direction)
  query_params["redirect_to_primary"] = params[:redirect_to_primary] if params.key?(:redirect_to_primary)
  params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/get_multi",
    query: query_params,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::PatientPage.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end

#reactivate(request_options: {}, **params) ⇒ untyped

Removes the deactivated flag for a patient. The path must contain the most recent version plus 1 to prevent race conditions. Reactivating historic versions is not supported.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:

  • (untyped)

Raises:

  • (error_class)


471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 471

def reactivate(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "PATCH",
    path: "/patients/v1/#{params[:id]}/#{params[:version]}",
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  return if code.between?(200, 299)

  error_class = Candid::Errors::ResponseError.subclass_for_code(code)
  raise error_class.new(response.body, code: code)
end

#scan(request_options: {}, **params) ⇒ Array[Candid::PreEncounter::Patients::V1::Types::Patient]

Scans up to 1000 patient updates. The since query parameter is inclusive, and the result list is ordered by updatedAt ascending.

Polling Pattern: To continuously poll for updates without gaps:

  1. Make your initial request with a since timestamp (e.g., since=2020-01-01T13:00:00.000Z)
  2. The API returns 100 by default and up to 1000 patient records, sorted by updated_at ascending
  3. Find the updated_at value from the last record in the response
  4. Use that updated_at value as the since parameter in your next request
  5. Repeat steps 2-4 to ingest updates until you receive an empty list

Important Notes:

  • The since parameter is inclusive, so you may receive the last record from the previous batch again (you can deduplicate by ID and version)
  • All patient records include updated_at, id, version, deactivated, and updating_user fields for tracking changes
  • Timestamps have millisecond resolution for precise ordering

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

  • :since (String)
  • :max_results (Integer, nil)

Returns:

Raises:

  • (error_class)


560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 560

def scan(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[since max_results]
  query_params = {}
  query_params["since"] = params[:since] if params.key?(:since)
  query_params["maxResults"] = params[:max_results] if params.key?(:max_results)
  params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/updates/scan",
    query: query_params,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  return if code.between?(200, 299)

  error_class = Candid::Errors::ResponseError.subclass_for_code(code)
  raise error_class.new(response.body, code: code)
end

#search(request_options: {}, **params) ⇒ Array[Candid::PreEncounter::Patients::V1::Types::Patient]

Returns a list of Patients based on the search criteria.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

  • :mrn (String, nil)
  • :similar_name_ordering (String, nil)

Returns:

Raises:

  • (error_class)


504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 504

def search(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[mrn similar_name_ordering]
  query_params = {}
  query_params["mrn"] = params[:mrn] if params.key?(:mrn)
  query_params["similar_name_ordering"] = params[:similar_name_ordering] if params.key?(:similar_name_ordering)
  params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1",
    query: query_params,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  return if code.between?(200, 299)

  error_class = Candid::Errors::ResponseError.subclass_for_code(code)
  raise error_class.new(response.body, code: code)
end

#search_providers(request_options: {}, **params) ⇒ Array[Candid::PreEncounter::Common::Types::ExternalProvider]

Searches for referring providers that match the query parameters. The search is case-insensitive, supports fuzzy matching, and matches against provider name and NPI. The search criteria must be an alphanumeric string, and the search is limited to the first 20 results.

Parameters:

  • request_options (Hash) (defaults to: {})
  • params (Hash)

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

  • :search_criteria (String)

Returns:

Raises:

  • (error_class)


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 167

def search_providers(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  query_param_names = %i[search_criteria]
  query_params = {}
  query_params["search_criteria"] = params[:search_criteria] if params.key?(:search_criteria)
  params.except(*query_param_names)

  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "GET",
    path: "/patients/v1/search_providers",
    query: query_params,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  return if code.between?(200, 299)

  error_class = Candid::Errors::ResponseError.subclass_for_code(code)
  raise error_class.new(response.body, code: code)
end

#update(request_options: {}, **params) ⇒ Candid::PreEncounter::Patients::V1::Types::Patient

Updates a patient. The path must contain the next version number to prevent race conditions. For example, if the current version of the patient is n, you will need to send a request to this endpoint with /{id}/n+1 to update the patient. Updating historic versions is not supported.

Parameters:

Options Hash (request_options:):

  • :base_url (String)
  • :additional_headers (Hash{String => Object})
  • :additional_query_parameters (Hash{String => Object})
  • :additional_body_parameters (Hash{String => Object})
  • :timeout_in_seconds (Integer)

Options Hash (**params):

Returns:



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/candid/pre_encounter/patients/v_1/client.rb', line 400

def update(request_options: {}, **params)
  params = Candid::Internal::Types::Utils.normalize_keys(params)
  request = Candid::Internal::JSON::Request.new(
    base_url: request_options[:base_url] || @base_url || @environment&.dig(:pre_encounter),
    method: "PUT",
    path: "/patients/v1/#{params[:id]}/#{params[:version]}",
    body: Candid::PreEncounter::Patients::V1::Types::MutablePatient.new(params).to_h,
    request_options: request_options
  )
  begin
    response = @client.send(request)
  rescue Net::HTTPRequestTimeout
    raise Candid::Errors::TimeoutError
  end
  code = response.code.to_i
  if code.between?(200, 299)
    Candid::PreEncounter::Patients::V1::Types::Patient.load(response.body)
  else
    error_class = Candid::Errors::ResponseError.subclass_for_code(code)
    raise error_class.new(response.body, code: code)
  end
end