Class: DecisionReviewV1::Service

Inherits:
Common::Client::Base show all
Includes:
Common::Client::Concerns::Monitoring, Appeals::LoggingUtils, Appeals::SupplementalClaimServices, SentryLogging
Defined in:
lib/decision_review_v1/service.rb

Overview

Proxy Service for the Lighthouse Decision Reviews API.

Constant Summary collapse

STATSD_KEY_PREFIX =
'api.decision_review'
ZIP_REGEX =
/^\d{5}(-\d{4})?$/
NO_ZIP_PLACEHOLDER =
'00000'

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Appeals::LoggingUtils

#benchmark_to_log_data_hash, #log_formatted, #parse_form412_response_to_log_msg, #parse_lighthouse_response_to_log_msg, #run_and_benchmark_if_enabled

Methods included from Appeals::SupplementalClaimServices

#create_supplemental_claim, #get_supplemental_claim, #get_supplemental_claim_contestable_issues, #get_supplemental_claim_upload, #get_supplemental_claim_upload_url, #process_form4142_submission, #put_supplemental_claim_upload, #queue_form4142, #queue_submit_evidence_uploads

Methods included from Appeals::Helpers

#create_supplemental_claims_headers, #get_and_rejigger_required_info, #middle_initial, #payload_encrypted_string

Methods included from Common::Client::Concerns::Monitoring

#with_monitoring

Methods included from SentryLogging

#log_exception_to_sentry, #log_message_to_sentry, #non_nil_hash?, #normalize_level, #rails_logger

Methods inherited from Common::Client::Base

configuration, #raise_backend_exception

Class Method Details

.file_upload_metadata(user, backup_zip = nil) ⇒ Object



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/decision_review_v1/service.rb', line 284

def self.(user, backup_zip = nil)
  original_zip = user.postal_code.to_s
  backup_zip_from_frontend = backup_zip.to_s
  zip = if original_zip =~ ZIP_REGEX
          original_zip
        elsif backup_zip_from_frontend =~ ZIP_REGEX
          backup_zip_from_frontend
        else
          NO_ZIP_PLACEHOLDER
        end
  {
    'veteranFirstName' => transliterate_name(user.first_name),
    'veteranLastName' => transliterate_name(user.last_name),
    'zipCode' => zip,
    'fileNumber' => user.ssn.to_s.strip,
    'source' => 'va.gov',
    'businessLine' => 'BVA'
  }.to_json
end

.transliterate_name(str) ⇒ Object

upstream requirements ^[a-zA-Z-/s]1,50$ Cannot be missing or empty or longer than 50 characters. Only upper/lower case letters, hyphens(-), spaces and forward-slash(/) allowed



111
112
113
# File 'lib/decision_review_v1/service.rb', line 111

def self.transliterate_name(str)
  I18n.transliterate(str.to_s).gsub(%r{[^a-zA-Z\-/\s]}, '').strip.first(50)
end

Instance Method Details

#create_higher_level_review(request_body:, user:) ⇒ Faraday::Response

Create a Higher-Level Review

Parameters:

  • request_body (JSON)

    JSON serialized version of a Higher-Level Review Form (20-0996)

  • user (User)

    Veteran who the form is in regard to

Returns:

  • (Faraday::Response)


37
38
39
40
41
42
43
44
45
46
# File 'lib/decision_review_v1/service.rb', line 37

def create_higher_level_review(request_body:, user:)
  with_monitoring_and_error_handling do
    headers = create_higher_level_review_headers(user)
    response = perform :post, 'higher_level_reviews', request_body, headers
    raise_schema_error_unless_200_status response.status
    validate_against_schema json: response.body, schema: HLR_CREATE_RESPONSE_SCHEMA,
                            append_to_error_class: ' (HLR_V1)'
    response
  end
end

#create_notice_of_disagreement(request_body:, user:) ⇒ Faraday::Response

Create a Notice of Disagreement

Parameters:

  • request_body (JSON)

    JSON serialized version of a Notice of Disagreement Form (10182)

  • user (User)

    Veteran who the form is in regard to

Returns:

  • (Faraday::Response)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/decision_review_v1/service.rb', line 122

def create_notice_of_disagreement(request_body:, user:) # rubocop:disable Metrics/MethodLength
  with_monitoring_and_error_handling do
    headers = create_notice_of_disagreement_headers(user)
    common_log_params = {
      key: :overall_claim_submission,
      form_id: '10182',
      user_uuid: user.uuid,
      downstream_system: 'Lighthouse'
    }
    begin
      response = perform :post, 'notice_of_disagreements', request_body, headers
      log_formatted(**common_log_params.merge(is_success: true, status_code: response.status, body: '[Redacted]'))
    rescue => e
      log_formatted(**common_log_params.merge(is_success: false, response_error: e))
      raise e
    end
    raise_schema_error_unless_200_status response.status
    validate_against_schema(
      json: response.body, schema: NOD_CREATE_RESPONSE_SCHEMA, append_to_error_class: ' (NOD_V1)'
    )
    response
  end
end

#get_higher_level_review(uuid) ⇒ Faraday::Response

Retrieve a Higher-Level Review

Parameters:

  • uuid (uuid)

    A Higher-Level Review’s UUID (included in a create_higher_level_review response)

Returns:

  • (Faraday::Response)


54
55
56
57
58
59
60
61
62
# File 'lib/decision_review_v1/service.rb', line 54

def get_higher_level_review(uuid)
  with_monitoring_and_error_handling do
    response = perform :get, "higher_level_reviews/#{uuid}", nil
    raise_schema_error_unless_200_status response.status
    validate_against_schema json: response.body, schema: HLR_SHOW_RESPONSE_SCHEMA,
                            append_to_error_class: ' (HLR_V1)'
    response
  end
end

#get_higher_level_review_contestable_issues(user:, benefit_type:) ⇒ Faraday::Response

Get Contestable Issues for a Higher-Level Review

Parameters:

  • user (User)

    Veteran who the form is in regard to

  • benefit_type (String)

    Type of benefit the decision review is for

Returns:

  • (Faraday::Response)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/decision_review_v1/service.rb', line 71

def get_higher_level_review_contestable_issues(user:, benefit_type:)
  with_monitoring_and_error_handling do
    path = "contestable_issues/higher_level_reviews?benefit_type=#{benefit_type}"
    headers = get_contestable_issues_headers(user)
    response = perform :get, path, nil, headers
    raise_schema_error_unless_200_status response.status
    validate_against_schema(
      json: response.body,
      schema: GET_CONTESTABLE_ISSUES_RESPONSE_SCHEMA,
      append_to_error_class: ' (HLR_V1)'
    )
    response
  end
end

#get_legacy_appeals(user:) ⇒ Faraday::Response

Get Legacy Appeals for either a Higher-Level Review or a Supplemental Claim

Parameters:

  • user (User)

    Veteran who the form is in regard to

Returns:

  • (Faraday::Response)


92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/decision_review_v1/service.rb', line 92

def get_legacy_appeals(user:)
  with_monitoring_and_error_handling do
    path = 'legacy_appeals'
    headers = get_legacy_appeals_headers(user)
    response = perform :get, path, nil, headers
    raise_schema_error_unless_200_status response.status
    validate_against_schema(
      json: response.body,
      schema: GET_LEGACY_APPEALS_RESPONSE_SCHEMA,
      append_to_error_class: ' (DECISION_REVIEW_V1)'
    )
    response
  end
end

#get_notice_of_disagreement(uuid) ⇒ Faraday::Response

Retrieve a Notice of Disagreement

Parameters:

  • uuid (uuid)

    A Notice of Disagreement’s UUID (included in a create_notice_of_disagreement response)

Returns:

  • (Faraday::Response)


152
153
154
155
156
157
158
159
160
161
# File 'lib/decision_review_v1/service.rb', line 152

def get_notice_of_disagreement(uuid)
  with_monitoring_and_error_handling do
    response = perform :get, "notice_of_disagreements/#{uuid}", nil
    raise_schema_error_unless_200_status response.status
    validate_against_schema(
      json: response.body, schema: NOD_SHOW_RESPONSE_SCHEMA, append_to_error_class: ' (NOD_V1)'
    )
    response
  end
end

#get_notice_of_disagreement_contestable_issues(user:) ⇒ Faraday::Response

Get Contestable Issues for a Notice of Disagreement

Parameters:

  • user (User)

    Veteran who the form is in regard to

Returns:

  • (Faraday::Response)


169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/decision_review_v1/service.rb', line 169

def get_notice_of_disagreement_contestable_issues(user:)
  with_monitoring_and_error_handling do
    path = 'contestable_issues/notice_of_disagreements'
    headers = get_contestable_issues_headers(user)
    response = perform :get, path, nil, headers
    raise_schema_error_unless_200_status response.status
    validate_against_schema(
      json: response.body,
      schema: GET_CONTESTABLE_ISSUES_RESPONSE_SCHEMA,
      append_to_error_class: ' (NOD_V1)'
    )
    response
  end
end

#get_notice_of_disagreement_upload(guid:) ⇒ Faraday::Response

Returns all of the data associated with a specific Notice of Disagreement Evidence Submission.

Parameters:

  • guid (uuid)

    the uuid returned from get_notice_of_disagreement_upload_url

Returns:

  • (Faraday::Response)


278
279
280
281
282
# File 'lib/decision_review_v1/service.rb', line 278

def get_notice_of_disagreement_upload(guid:)
  with_monitoring_and_error_handling do
    perform :get, "notice_of_disagreements/evidence_submissions/#{guid}", nil
  end
end

#get_notice_of_disagreement_upload_url(nod_uuid:, file_number:, user_uuid: nil, appeal_submission_upload_id: nil) ⇒ Faraday::Response

Get the url to upload supporting evidence for a Notice of Disagreement

Parameters:

  • nod_uuid (uuid)

    The uuid of the submited Notice of Disagreement

  • file_number (Integer)

    The file number or ssn

Returns:

  • (Faraday::Response)


191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/decision_review_v1/service.rb', line 191

def get_notice_of_disagreement_upload_url(nod_uuid:, file_number:, user_uuid: nil, appeal_submission_upload_id: nil) # rubocop:disable Metrics/MethodLength
  with_monitoring_and_error_handling do
    headers = { 'X-VA-File-Number' => file_number.to_s.strip.presence }
    common_log_params = {
      key: :get_lighthouse_evidence_upload_url,
      form_id: '10182',
      user_uuid:,
      upstream_system: 'Lighthouse',
      downstream_system: 'Lighthouse',
      params: {
        nod_uuid:,
        appeal_submission_upload_id:
      }
    }
    begin
      response = perform :post, 'notice_of_disagreements/evidence_submissions', { nod_uuid: }, headers
      log_formatted(**common_log_params.merge(is_success: true, status_code: response.status, body: response.body))
      response
    rescue => e
      # We can freely log Lighthouse's error responses because they do not include PII or PHI.
      # See https://developer.va.gov/explore/api/decision-reviews/docs?version=v2
      log_formatted(**common_log_params.merge(is_success: false, response_error: e))
      raise e
    end
  end
end

#put_notice_of_disagreement_upload(upload_url:, file_upload:, metadata_string:, user_uuid: nil, appeal_submission_upload_id: nil) ⇒ Faraday::Response

Upload supporting evidence for a Notice of Disagreement

rubocop:disable Metrics/MethodLength

Parameters:

  • upload_url (String)

    The url for the document to be uploaded

  • file_path (String)

    The file path for the document to be uploaded

  • metadata_string (Hash)

    additional data

Returns:

  • (Faraday::Response)


228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/decision_review_v1/service.rb', line 228

def put_notice_of_disagreement_upload(upload_url:, file_upload:, metadata_string:, user_uuid: nil, appeal_submission_upload_id: nil) # rubocop:disable Layout/LineLength
  content_tmpfile = Tempfile.new(file_upload.filename, encoding: file_upload.read.encoding)
  content_tmpfile.write(file_upload.read)
  content_tmpfile.rewind

  json_tmpfile = Tempfile.new('metadata.json', encoding: 'utf-8')
  json_tmpfile.write()
  json_tmpfile.rewind

  params = { metadata: Faraday::UploadIO.new(json_tmpfile.path, Mime[:json].to_s, 'metadata.json'),
             content: Faraday::UploadIO.new(content_tmpfile.path, Mime[:pdf].to_s, file_upload.filename) }

  # when we upgrade to Faraday >1.0
  # params = { metadata: Faraday::FilePart.new(json_tmpfile, Mime[:json].to_s, 'metadata.json'),
  #            content: Faraday::FilePart.new(content_tmpfile, Mime[:pdf].to_s, file_upload.filename) }
  common_log_params = {
    key: :evidence_upload_to_lighthouse,
    form_id: '10182',
    user_uuid:,
    downstream_system: 'Lighthouse',
    params: {
      upload_url:,
      appeal_submission_upload_id:
    }
  }
  with_monitoring_and_error_handling do
    response = perform :put, upload_url, params, { 'Content-Type' => 'multipart/form-data' }
    log_formatted(**common_log_params.merge(is_success: true, status_code: response.status, body: '[Redacted]'))
    response
  rescue => e
    # We can freely log Lighthouse's error responses because they do not include PII or PHI.
    # See https://developer.va.gov/explore/api/decision-reviews/docs?version=v2
    log_formatted(**common_log_params.merge(is_success: false, response_error: e))
    raise e
  end
ensure
  content_tmpfile.close
  content_tmpfile.unlink
  json_tmpfile.close
  json_tmpfile.unlink
end