Class: BenefitsIntakeStatusJob
- Inherits:
-
Object
- Object
- BenefitsIntakeStatusJob
- Includes:
- Sidekiq::Job
- Defined in:
- app/sidekiq/benefits_intake_status_job.rb
Overview
Constant Summary collapse
- STATS_KEY =
'api.benefits_intake.submission_status'
- STALE_SLA =
Settings.lighthouse.benefits_intake.report.stale_sla || 10
- BATCH_SIZE =
Settings.lighthouse.benefits_intake.report.batch_size || 1000
Instance Attribute Summary collapse
-
#batch_size ⇒ Object
readonly
Returns the value of attribute batch_size.
Instance Method Summary collapse
- #batch_process(pending_form_submission_attempts) ⇒ Object private
-
#form_submission_attempts_hash ⇒ Object
private
rubocop:enable Metrics/MethodLength.
-
#handle_response(response) ⇒ Object
private
rubocop:disable Metrics/MethodLength.
-
#initialize(batch_size: BATCH_SIZE) ⇒ BenefitsIntakeStatusJob
constructor
A new instance of BenefitsIntakeStatusJob.
-
#log_result(result, form_id, uuid, time_to_transition = nil, error_message = nil) ⇒ Object
private
rubocop:enable Metrics/MethodLength.
-
#monitor_failure(form_id, saved_claim_id, bi_uuid) ⇒ Object
private
TODO: refactor - avoid require of module code, near duplication of process rubocop:disable Metrics/MethodLength.
- #perform ⇒ Object
Constructor Details
#initialize(batch_size: BATCH_SIZE) ⇒ BenefitsIntakeStatusJob
Returns a new instance of BenefitsIntakeStatusJob.
25 26 27 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 25 def initialize(batch_size: BATCH_SIZE) @batch_size = batch_size end |
Instance Attribute Details
#batch_size ⇒ Object (readonly)
Returns the value of attribute batch_size.
23 24 25 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 23 def batch_size @batch_size end |
Instance Method Details
#batch_process(pending_form_submission_attempts) ⇒ Object (private)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 38 def batch_process(pending_form_submission_attempts) total_handled = 0 intake_service = BenefitsIntake::Service.new pending_form_submission_attempts.each_slice(batch_size) do |batch| batch_uuids = batch.map(&:benefits_intake_uuid) response = intake_service.bulk_status(uuids: batch_uuids) # Log the entire response for debugging purposes Rails.logger.info("Received bulk status response: #{response.body}") raise response.body unless response.success? total_handled += handle_response(response) end [total_handled, true] rescue => e Rails.logger.error('Error processing Intake Status batch', class: self.class.name, message: e.) [total_handled, false] end |
#form_submission_attempts_hash ⇒ Object (private)
rubocop:enable Metrics/MethodLength
202 203 204 205 206 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 202 def form_submission_attempts_hash @_form_submission_attempts_hash ||= FormSubmissionAttempt .where(aasm_state: 'pending') .index_by(&:benefits_intake_uuid) end |
#handle_response(response) ⇒ Object (private)
rubocop:disable Metrics/MethodLength
61 62 63 64 65 66 67 68 69 70 71 72 73 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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 61 def handle_response(response) total_handled = 0 # Ensure response body contains data, and log the data for debugging if response.body['data'].blank? Rails.logger.error("Response data is blank or missing: #{response.body}") return total_handled end response.body['data']&.each do |submission| uuid = submission['id'] form_submission_attempt = form_submission_attempts_hash[uuid] form_submission = form_submission_attempt&.form_submission form_id = form_submission&.form_type saved_claim_id = form_submission&.saved_claim_id time_to_transition = (Time.zone.now - form_submission_attempt.created_at).truncate # https://developer.va.gov/explore/api/benefits-intake/docs status = submission.dig('attributes', 'status') # Log the status for debugging Rails.logger.info("Processing submission UUID: #{uuid}, Status: #{status}") lighthouse_updated_at = submission.dig('attributes', 'updated_at') if status == 'expired' # Expired - Indicate that documents were not successfully uploaded within the 15-minute window. = 'expired' form_submission_attempt.update(error_message:, lighthouse_updated_at:) form_submission_attempt.fail! log_result('failure', form_id, uuid, time_to_transition, ) monitor_failure(form_id, saved_claim_id, uuid) elsif status == 'error' # Error - Indicates that there was an error. Refer to the error code and detail for further information. = "#{submission.dig('attributes', 'code')}: #{submission.dig('attributes', 'detail')}" form_submission_attempt.update(error_message:, lighthouse_updated_at:) form_submission_attempt.fail! log_result('failure', form_id, uuid, time_to_transition, ) monitor_failure(form_id, saved_claim_id, uuid) elsif status == 'vbms' # submission was successfully uploaded into a Veteran's eFolder within VBMS form_submission_attempt.update(lighthouse_updated_at:) form_submission_attempt.vbms! log_result('success', form_id, uuid, time_to_transition) elsif time_to_transition > STALE_SLA.days # exceeds SLA (service level agreement) days for submission completion log_result('stale', form_id, uuid, time_to_transition) else # no change being tracked log_result('pending', form_id, uuid) Rails.logger.info( "Submission UUID: #{uuid} is still pending, status: #{status}, time to transition: #{time_to_transition}" ) end total_handled += 1 end total_handled end |
#log_result(result, form_id, uuid, time_to_transition = nil, error_message = nil) ⇒ Object (private)
rubocop:enable Metrics/MethodLength
122 123 124 125 126 127 128 129 130 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 122 def log_result(result, form_id, uuid, time_to_transition = nil, = nil) StatsD.increment("#{STATS_KEY}.#{form_id}.#{result}") StatsD.increment("#{STATS_KEY}.all_forms.#{result}") if result == 'failure' Rails.logger.error('BenefitsIntakeStatusJob', result:, form_id:, uuid:, time_to_transition:, error_message:) else Rails.logger.info('BenefitsIntakeStatusJob', result:, form_id:, uuid:, time_to_transition:) end end |
#monitor_failure(form_id, saved_claim_id, bi_uuid) ⇒ Object (private)
TODO: refactor - avoid require of module code, near duplication of process rubocop:disable Metrics/MethodLength
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 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 192 193 194 195 196 197 198 199 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 134 def monitor_failure(form_id, saved_claim_id, bi_uuid) context = { form_id: form_id, claim_id: saved_claim_id, benefits_intake_uuid: bi_uuid } call_location = caller_locations.first if %w[21P-530V2 21P-530].include?(form_id) claim = SavedClaim::Burial.find(saved_claim_id) if claim Burials::NotificationEmail.new(claim.id).deliver(:error) Burials::Monitor.new.log_silent_failure_avoided(context, nil, call_location:) else Burials::Monitor.new.log_silent_failure(context, nil, call_location:) end end if %w[21P-527EZ].include?(form_id) claim = Pensions::SavedClaim.find(saved_claim_id) if claim Pensions::NotificationEmail.new(claim.id).deliver(:error) Pensions::Monitor.new.log_silent_failure_avoided(context, nil, call_location:) else Pensions::Monitor.new.log_silent_failure(context, nil, call_location:) end end # Dependents if %w[686C-674].include?(form_id) claim = SavedClaim::DependencyClaim.find(saved_claim_id) email = if claim.present? claim.parsed_form.dig('dependents_application', 'veteran_contact_information', 'email_address') end if claim.present? && email.present? claim.send_failure_email(email) Dependents::Monitor.new.log_silent_failure_avoided(context, nil, call_location:) else Dependents::Monitor.new.log_silent_failure(context, nil, call_location:) end end # PCPG if %w[28-8832].include?(form_id) claim = SavedClaim::EducationCareerCounselingClaim.find(saved_claim_id) email = claim.parsed_form.dig('claimantInformation', 'emailAddress') if claim.present? if claim.present? && email.present? claim.send_failure_email(email) PCPG::Monitor.new.log_silent_failure_avoided(context, nil, call_location:) else PCPG::Monitor.new.log_silent_failure(ocntext, nil, call_location:) end end # VRE if %w[28-1900].include?(form_id) claim = SavedClaim::VeteranReadinessEmploymentClaim.find(saved_claim_id) email = claim.parsed_form['email'] if claim.present? if claim.present? && email.present? claim.send_failure_email(email) VRE::Monitor.new.log_silent_failure_avoided(context, nil, call_location:) else VRE::Monitor.new.log_silent_failure(context, nil, call_location:) end end end |
#perform ⇒ Object
29 30 31 32 33 34 |
# File 'app/sidekiq/benefits_intake_status_job.rb', line 29 def perform Rails.logger.info('BenefitsIntakeStatusJob started') pending_form_submission_attempts = FormSubmissionAttempt.where(aasm_state: 'pending') total_handled, result = batch_process(pending_form_submission_attempts) Rails.logger.info('BenefitsIntakeStatusJob ended', total_handled:) if result end |