-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
98422: Port controller, model and monitor to module with mount for ne… (
#20283) * 98422: Port controller, model and monitor to module with mount for new engine and tests * 98422: Fix rubocop * 98422: Fix test * 98422: Add test coverage * 98422: Some tweaks to appease rubocop * 98422: 100% test coverage for saved_claims * 98422: Remove unnecessary require
- Loading branch information
Showing
8 changed files
with
933 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
modules/burials/app/controllers/burials/v0/claims_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'pension_burial/tag_sentry' | ||
require 'common/exceptions/validation_errors' | ||
|
||
module Burials | ||
module V0 | ||
class ClaimsController < ApplicationController | ||
skip_before_action(:authenticate) | ||
before_action :load_user, only: :create | ||
|
||
service_tag 'burial-application' | ||
|
||
def show | ||
claim = claim_class.find_by!(guid: params[:id]) | ||
render json: SavedClaimSerializer.new(claim) | ||
rescue ActiveRecord::RecordNotFound => e | ||
monitor.track_show404(params[:id], current_user, e) | ||
render(json: { error: e.to_s }, status: :not_found) | ||
rescue => e | ||
monitor.track_show_error(params[:id], current_user, e) | ||
raise e | ||
end | ||
|
||
def create | ||
PensionBurial::TagSentry.tag_sentry | ||
|
||
claim = claim_class.new(form: filtered_params[:form]) | ||
monitor.track_create_attempt(claim, current_user) | ||
|
||
in_progress_form = current_user ? InProgressForm.form_for_user(claim.form_id, current_user) : nil | ||
claim.form_start_date = in_progress_form.created_at if in_progress_form | ||
|
||
unless claim.save | ||
Sentry.set_tags(team: 'benefits-memorial-1') # tag sentry logs with team name | ||
monitor.track_create_validation_error(in_progress_form, claim, current_user) | ||
log_validation_error_to_metadata(in_progress_form, claim) | ||
raise Common::Exceptions::ValidationErrors, claim.errors | ||
end | ||
|
||
process_and_upload_to_lighthouse(in_progress_form, claim) | ||
|
||
monitor.track_create_success(in_progress_form, claim, current_user) | ||
|
||
clear_saved_form(claim.form_id) | ||
render json: SavedClaimSerializer.new(claim) | ||
rescue => e | ||
monitor.track_create_error(in_progress_form, claim, current_user, e) | ||
raise e | ||
end | ||
|
||
private | ||
|
||
# an identifier that matches the parameter that the form will be set as in the JSON submission. | ||
def short_name | ||
'burial_claim' | ||
end | ||
|
||
# a subclass of SavedClaim, runs json-schema validations and performs any storage and attachment processing | ||
def claim_class | ||
Burials::SavedClaim | ||
end | ||
|
||
def process_and_upload_to_lighthouse(in_progress_form, claim) | ||
claim.process_attachments! | ||
|
||
Lighthouse::SubmitBenefitsIntakeClaim.perform_async(claim.id) | ||
rescue => e | ||
monitor.track_process_attachment_error(in_progress_form, claim, current_user) | ||
raise e | ||
end | ||
|
||
# Filters out the parameters to form access. | ||
def filtered_params | ||
params.require(short_name.to_sym).permit(:form) | ||
end | ||
|
||
## | ||
# include validation error on in_progress_form metadata. | ||
# `noop` if in_progress_form is `blank?` | ||
# | ||
# @param in_progress_form [InProgressForm] | ||
# @param claim [Pensions::SavedClaim] | ||
# | ||
def log_validation_error_to_metadata(in_progress_form, claim) | ||
return if in_progress_form.blank? | ||
|
||
metadata = in_progress_form.metadata | ||
metadata['submission']['error_message'] = claim&.errors&.errors&.to_s | ||
in_progress_form.update(metadata:) | ||
end | ||
|
||
## | ||
# retreive a monitor for tracking | ||
# | ||
# @return [Burials::Monitor] | ||
# | ||
def monitor | ||
@monitor ||= Burials::Monitor.new | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'pension_burial/processing_office' | ||
|
||
module Burials | ||
class SavedClaim < ::SavedClaim | ||
FORM = '21P-530EZ' | ||
|
||
def process_attachments! | ||
refs = attachment_keys.map { |key| Array(open_struct_form.send(key)) }.flatten | ||
files = PersistentAttachment.where(guid: refs.map(&:confirmationCode)) | ||
files.find_each { |f| f.update(saved_claim_id: id) } | ||
end | ||
|
||
def regional_office | ||
PensionBurial::ProcessingOffice.address_for(open_struct_form.claimantAddress.postalCode) | ||
end | ||
|
||
def attachment_keys | ||
%i[transportationReceipts deathCertificate militarySeparationDocuments additionalEvidence].freeze | ||
end | ||
|
||
def email | ||
parsed_form['claimantEmail'] | ||
end | ||
|
||
def form_matches_schema | ||
return unless form_is_string | ||
|
||
JSON::Validator.fully_validate(VetsJsonSchema::SCHEMAS[form_id], parsed_form).each do |v| | ||
errors.add(:form, v.to_s) | ||
end | ||
end | ||
|
||
def process_pdf(pdf_path, timestamp = nil, form_id = nil) | ||
processed_pdf = PDFUtilities::DatestampPdf.new(pdf_path).run( | ||
text: 'Application Submitted on va.gov', | ||
x: 400, | ||
y: 675, | ||
text_only: true, # passing as text only because we override how the date is stamped in this instance | ||
timestamp:, | ||
page_number: 6, | ||
template: "lib/pdf_fill/forms/pdfs/#{form_id}.pdf", | ||
multistamp: true | ||
) | ||
renamed_path = "tmp/pdfs/#{form_id}_#{id}_final.pdf" | ||
File.rename(processed_pdf, renamed_path) # rename for vbms upload | ||
renamed_path # return the renamed path | ||
end | ||
|
||
def business_line | ||
'NCA' | ||
end | ||
|
||
## | ||
# utility function to retrieve claimant first name from form | ||
# | ||
# @return [String] the claimant first name | ||
# | ||
def veteran_first_name | ||
parsed_form.dig('veteranFullName', 'first') | ||
end | ||
|
||
def veteran_last_name | ||
parsed_form.dig('veteranFullName', 'last') | ||
end | ||
|
||
def claimaint_first_name | ||
parsed_form.dig('claimantFullName', 'first') | ||
end | ||
|
||
def benefits_claimed | ||
claimed = [] | ||
claimed << 'Burial Allowance' if parsed_form['burialAllowance'] | ||
claimed << 'Plot Allowance' if parsed_form['plotAllowance'] | ||
claimed << 'Transportation' if parsed_form['transportation'] | ||
claimed | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'burials/notification_email' | ||
require 'zero_silent_failures/monitor' | ||
|
||
module Burials | ||
## | ||
# Monitor functions for Rails logging and StatsD | ||
# | ||
class Monitor < ::ZeroSilentFailures::Monitor | ||
# statsd key for api | ||
CLAIM_STATS_KEY = 'api.burial_claim' | ||
|
||
# statsd key for sidekiq | ||
SUBMISSION_STATS_KEY = 'app.burial.submit_benefits_intake_claim' | ||
|
||
attr_reader :tags | ||
|
||
def initialize | ||
super('burial-application') | ||
|
||
@tags = ['form_id:21P-530EZ'] | ||
end | ||
|
||
## | ||
# log GET 404 from controller | ||
# @see BurialClaimsController | ||
# | ||
# @param confirmation_number [UUID] saved_claim guid | ||
# @param current_user [User] | ||
# @param e [ActiveRecord::RecordNotFound] | ||
# | ||
def track_show404(confirmation_number, current_user, e) | ||
additional_context = { | ||
confirmation_number:, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
message: e&.message, | ||
tags: | ||
} | ||
track_request('error', '21P-530EZ submission not found', CLAIM_STATS_KEY, | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log GET 500 from controller | ||
# @see BurialClaimsController | ||
# | ||
# @param confirmation_number [UUID] saved_claim guid | ||
# @param current_user [User] | ||
# @param e [Error] | ||
# | ||
def track_show_error(confirmation_number, current_user, e) | ||
additional_context = { | ||
confirmation_number:, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
message: e&.message, | ||
tags: | ||
} | ||
track_request('error', '21P-530EZ fetching submission failed', CLAIM_STATS_KEY, | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log POST processing started | ||
# @see BurialClaimsController | ||
# | ||
# @param claim [SavedClaim::Burial] | ||
# @param current_user [User] | ||
# | ||
def track_create_attempt(claim, current_user) | ||
additional_context = { | ||
confirmation_number: claim&.confirmation_number, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
tags: | ||
} | ||
track_request('info', '21P-530EZ submission to Sidekiq begun', "#{CLAIM_STATS_KEY}.attempt", | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log POST claim save validation error | ||
# @see BurialClaimsController | ||
# | ||
# @param in_progress_form [InProgressForm] | ||
# @param claim [SavedClaim::Burial] | ||
# @param current_user [User] | ||
# @param e [Error] | ||
# | ||
def track_create_validation_error(in_progress_form, claim, current_user) | ||
additional_context = { | ||
confirmation_number: claim&.confirmation_number, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
in_progress_form_id: in_progress_form&.id, | ||
errors: claim&.errors&.errors, | ||
tags: | ||
} | ||
track_request('error', '21P-530EZ submission validation error', "#{CLAIM_STATS_KEY}.validation_error", | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log POST processing failure | ||
# @see BurialClaimsController | ||
# | ||
# @param in_progress_form [InProgressForm] | ||
# @param claim [SavedClaim::Burial] | ||
# @param current_user [User] | ||
# @param e [Error] | ||
# | ||
def track_create_error(in_progress_form, claim, current_user, e = nil) | ||
additional_context = { | ||
confirmation_number: claim&.confirmation_number, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
in_progress_form_id: in_progress_form&.id, | ||
errors: claim&.errors&.errors, | ||
message: e&.message, | ||
tags: | ||
} | ||
track_request('error', '21P-530EZ submission to Sidekiq failed', "#{CLAIM_STATS_KEY}.failure", | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log POST processing success | ||
# @see BurialClaimsController | ||
# | ||
# @param in_progress_form [InProgressForm] | ||
# @param claim [SavedClaim::Burial] | ||
# @param current_user [User] | ||
# | ||
def track_create_success(in_progress_form, claim, current_user) | ||
additional_context = { | ||
confirmation_number: claim&.confirmation_number, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
in_progress_form_id: in_progress_form&.id, | ||
errors: claim&.errors&.errors, | ||
tags: | ||
} | ||
track_request('info', '21P-530EZ submission to Sidekiq success', "#{CLAIM_STATS_KEY}.success", | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log process_attachments! error | ||
# @see BurialClaimsController | ||
# | ||
# @param in_progress_form [InProgressForm] | ||
# @param claim [SavedClaim::Burial] | ||
# @param current_user [User] | ||
# | ||
def track_process_attachment_error(in_progress_form, claim, current_user) | ||
additional_context = { | ||
confirmation_number: claim&.confirmation_number, | ||
user_account_uuid: current_user&.user_account_uuid, | ||
in_progress_form_id: in_progress_form&.id, | ||
errors: claim&.errors&.errors, | ||
tags: | ||
} | ||
track_request('error', '21P-530EZ process attachment error', "#{CLAIM_STATS_KEY}.process_attachment_error", | ||
call_location: caller_locations.first, **additional_context) | ||
end | ||
|
||
## | ||
# log Sidkiq job exhaustion, complete failure after all retries | ||
# @see Lighthouse::SubmitBenefitsIntakeClaim | ||
# | ||
# @param msg [Hash] sidekiq exhaustion response | ||
# @param claim [SavedClaim::Burial] | ||
# | ||
def track_submission_exhaustion(msg, claim = nil) | ||
user_account_uuid = msg['args'].length <= 1 ? nil : msg['args'][1] | ||
additional_context = { | ||
confirmation_number: claim&.confirmation_number, | ||
user_account_uuid: user_account_uuid, | ||
form_id: claim&.form_id, | ||
claim_id: msg['args'].first, | ||
message: msg, | ||
tags: | ||
} | ||
call_location = caller_locations.first | ||
|
||
if claim | ||
Burials::NotificationEmail.new(claim.id).deliver(:error) | ||
log_silent_failure_avoided(additional_context, user_account_uuid, call_location:) | ||
else | ||
log_silent_failure(additional_context, user_account_uuid, call_location:) | ||
end | ||
|
||
track_request('error', 'Lighthouse::SubmitBenefitsIntakeClaim Burial 21P-530EZ submission to LH exhausted!', | ||
"#{SUBMISSION_STATS_KEY}.exhausted", call_location:, **additional_context) | ||
end | ||
end | ||
end |
Oops, something went wrong.