Skip to content

Commit

Permalink
97726: Add DR HLR V2 API endpoint (#19590)
Browse files Browse the repository at this point in the history
* 97726: Add DR HLR V2 API endpoint

* Update CODEOWNERS
  • Loading branch information
dfong-adh authored Nov 25, 2024
1 parent 5cf671e commit a0d9092
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ app/controllers/v1/sessions_controller.rb @department-of-veterans-affairs/octo-
app/controllers/v1/supplemental_claims_controller.rb @department-of-veterans-affairs/benefits-decision-reviews-be @department-of-veterans-affairs/backend-review-group
app/controllers/v1/supplemental_claims @department-of-veterans-affairs/benefits-decision-reviews-be @department-of-veterans-affairs/backend-review-group
app/controllers/v1/post911_gi_bill_statuses_controller.rb @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/govcio-vfep-codereviewers
app/controllers/v2/higher_level_reviews_controller.rb @department-of-veterans-affairs/benefits-decision-reviews-be @department-of-veterans-affairs/backend-review-group
app/mailers/application_mailer.rb @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
app/mailers/ch31_submissions_report_mailer.rb @department-of-veterans-affairs/benefits-non-disability @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
app/mailers/create_daily_spool_files_mailer.rb @department-of-veterans-affairs/my-education-benefits @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
Expand Down Expand Up @@ -1730,6 +1731,7 @@ spec/requests/v1/higher_level_reviews_spec.rb @department-of-veterans-affairs/b
spec/requests/v1/notice_of_disagreements_spec.rb @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-decision-reviews-be
spec/requests/v1/post911_gi_bill_status_spec.rb @department-of-veterans-affairs/govcio-vfep-codereviewers @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/requests/v1/supplemental_claims_spec.rb @department-of-veterans-affairs/backend-review-group @department-of-veterans-affairs/benefits-decision-reviews-be
spec/requests/v2/higher_level_reviews_spec.rb @department-of-veterans-affairs/benefits-decision-reviews-be @department-of-veterans-affairs/backend-review-group
spec/controllers/v1/decision_review_evidences_controller_spec.rb @department-of-veterans-affairs/benefits-decision-reviews-be @department-of-veterans-affairs/backend-review-group
spec/requests/va_profile @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group
spec/routing/v0/map_services_routing_spec.rb @department-of-veterans-affairs/octo-identity
Expand Down
64 changes: 64 additions & 0 deletions app/controllers/v2/higher_level_reviews_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

require 'decision_review/utilities/saved_claim/service'

module V2
class HigherLevelReviewsController < AppealsBaseControllerV1
include DecisionReview::SavedClaim::Service
service_tag 'higher-level-review'

def show
render json: decision_review_service.get_higher_level_review(params[:id]).body
rescue => e
log_exception_to_personal_information_log(
e, error_class: error_class(method: 'show', exception_class: e.class), id: params[:id]
)
raise
end

def create
hlr_response_body = decision_review_service
.create_higher_level_review(request_body: request_body_hash, user: @current_user,
version: 'V2')
.body
submitted_appeal_uuid = hlr_response_body.dig('data', 'id')
ActiveRecord::Base.transaction do
AppealSubmission.create!(user_uuid: @current_user.uuid, user_account: @current_user.user_account,
type_of_appeal: 'HLR', submitted_appeal_uuid:)

store_saved_claim(claim_class: SavedClaim::HigherLevelReview, form: request_body_hash.to_json,
guid: submitted_appeal_uuid)

# Clear in-progress form since submit was successful
InProgressForm.form_for_user('20-0996', current_user)&.destroy!
end
render json: hlr_response_body
rescue => e
::Rails.logger.error(
message: "Exception occurred while submitting Higher Level Review: #{e.message}",
backtrace: e.backtrace
)

handle_personal_info_error(e)
end

private

def error_class(method:, exception_class:)
"#{self.class.name}##{method} exception #{exception_class} (HLR_V2)"
end

def handle_personal_info_error(e)
request = begin
{ body: request_body_hash }
rescue
request_body_debug_data
end

log_exception_to_personal_information_log(
e, error_class: error_class(method: 'create', exception_class: e.class), request:
)
raise
end
end
end
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,10 @@
end
end

namespace :v2, defaults: { format: 'json' } do
resources :higher_level_reviews, only: %i[create show]
end

root 'v0/example#index', module: 'v0'

scope '/services' do
Expand Down
6 changes: 3 additions & 3 deletions lib/decision_review_v1/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ class Service < Common::Client::Base
# @param user [User] Veteran who the form is in regard to
# @return [Faraday::Response]
#
def create_higher_level_review(request_body:, user:)
def create_higher_level_review(request_body:, user:, version: 'V1')
with_monitoring_and_error_handling do
headers = create_higher_level_review_headers(user)
common_log_params = { key: :overall_claim_submission, form_id: '996', user_uuid: user.uuid,
downstream_system: 'Lighthouse' }
downstream_system: 'Lighthouse', params: { version: } }
begin
response = perform :post, 'higher_level_reviews', request_body, headers
log_formatted(**common_log_params.merge(is_success: true, status_code: response.status, body: '[Redacted]'))
Expand All @@ -48,7 +48,7 @@ def create_higher_level_review(request_body:, user:)
end
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)'
append_to_error_class: " (HLR_#{version}})"
response
end
end
Expand Down
6 changes: 4 additions & 2 deletions spec/requests/v1/higher_level_reviews_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
http: {
status_code: 200,
body: '[Redacted]'
}
},
version: 'V1'
}
end
let(:error_log_args) do
Expand All @@ -33,7 +34,8 @@
http: {
status_code: 422,
body: response_error_body
}
},
version: 'V1'
}
end

Expand Down
150 changes: 150 additions & 0 deletions spec/requests/v2/higher_level_reviews_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# frozen_string_literal: true

require 'rails_helper'
require 'support/controller_spec_helper'

RSpec.describe 'V2::HigherLevelReviews', type: :request do
let(:user) { build(:user, :loa3) }
let(:headers) { { 'CONTENT_TYPE' => 'application/json' } }
let(:success_log_args) do
{
message: 'Overall claim submission success!',
user_uuid: user.uuid,
action: 'Overall claim submission',
form_id: '996',
upstream_system: nil,
downstream_system: 'Lighthouse',
is_success: true,
http: {
status_code: 200,
body: '[Redacted]'
},
version: 'V2'
}
end
let(:error_log_args) do
{
message: 'Overall claim submission failure!',
user_uuid: user.uuid,
action: 'Overall claim submission',
form_id: '996',
upstream_system: nil,
downstream_system: 'Lighthouse',
is_success: false,
http: {
status_code: 422,
body: response_error_body
},
version: 'V2'
}
end

let(:response_error_body) do
{
'errors' => [{ 'title' => 'Missing required fields',
'detail' => 'One or more expected fields were not found',
'code' => '145',
'source' => { 'pointer' => '/' },
'status' => '422',
'meta' => { 'missing_fields' => %w[data included] } }]
}
end

let(:extra_error_log_message) do
'BackendServiceException: {:source=>"Common::Client::Errors::ClientError raised in DecisionReviewV1::Service", ' \
':code=>"DR_422"}'
end

before { sign_in_as(user) }

describe '#create' do
def personal_information_logs
PersonalInformationLog.where 'error_class like ?', 'V2::HigherLevelReviewsController#create exception % (HLR_V2)'
end

subject do
post '/v2/higher_level_reviews',
params: VetsJsonSchema::EXAMPLES.fetch('HLR-CREATE-REQUEST-BODY_V1').to_json,
headers:
end

it 'creates an HLR' do
VCR.use_cassette('decision_review/HLR-CREATE-RESPONSE-200_V1') do
# Create an InProgressForm
in_progress_form = create(:in_progress_form, user_uuid: user.uuid, form_id: '20-0996')
expect(in_progress_form).not_to be_nil

allow(Rails.logger).to receive(:info)
expect(Rails.logger).to receive(:info).with(success_log_args)
allow(StatsD).to receive(:increment)
expect(StatsD).to receive(:increment).with('decision_review.form_996.overall_claim_submission.success')

subject
expect(response).to be_successful
appeal_uuid = JSON.parse(response.body)['data']['id']
expect(AppealSubmission.where(submitted_appeal_uuid: appeal_uuid).first).to be_truthy
# InProgressForm should be destroyed after successful submission
in_progress_form = InProgressForm.find_by(user_uuid: user.uuid, form_id: '20-0996')
expect(in_progress_form).to be_nil
# SavedClaim should be created with request data
saved_claim = SavedClaim::HigherLevelReview.find_by(guid: appeal_uuid)
expect(saved_claim.form).to eq(VetsJsonSchema::EXAMPLES.fetch('HLR-CREATE-REQUEST-BODY_V1').to_json)
end
end

context 'when an error occurs with the api call' do
it 'adds to the PersonalInformationLog' do
VCR.use_cassette('decision_review/HLR-CREATE-RESPONSE-422_V1') do
expect(personal_information_logs.count).to be 0

allow(Rails.logger).to receive(:error)
expect(Rails.logger).to receive(:error).with(error_log_args)
expect(Rails.logger).to receive(:error).with(
message: "Exception occurred while submitting Higher Level Review: #{extra_error_log_message}",
backtrace: anything
)
expect(Rails.logger).to receive(:error).with(extra_error_log_message, anything)
allow(StatsD).to receive(:increment)
expect(StatsD).to receive(:increment).with('decision_review.form_996.overall_claim_submission.failure')

subject
expect(personal_information_logs.count).to be 1
pil = personal_information_logs.first
%w[
first_name last_name birls_id icn edipi mhv_correlation_id
participant_id vet360_id ssn assurance_level birth_date
].each { |key| expect(pil.data['user'][key]).to be_truthy }
%w[message backtrace key response_values original_status original_body]
.each { |key| expect(pil.data['error'][key]).to be_truthy }
expect(pil.data['additional_data']['request']['body']).not_to be_empty
end
end
end

context 'when an error occurs in the transaction' do
shared_examples 'rolledback transaction' do |model|
before do
allow_any_instance_of(model).to receive(:save!).and_raise(ActiveModel::Error) # stub a model error
end

it 'rollsback transaction' do
VCR.use_cassette('decision_review/HLR-CREATE-RESPONSE-200_V1') do
expect(subject).to eq 500

# check that transaction rolled back / records were not persisted
expect(AppealSubmission.count).to eq 0
expect(SavedClaim.count).to eq 0
end
end
end

context 'for AppealSubmission' do
it_behaves_like 'rolledback transaction', AppealSubmission
end

context 'for SavedClaim' do
it_behaves_like 'rolledback transaction', SavedClaim
end
end
end
end

0 comments on commit a0d9092

Please sign in to comment.