From 12ba43096485d355afb45e94ccc409d10bf88f1c Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Thu, 7 Nov 2024 14:02:33 -0800 Subject: [PATCH 1/7] Extract shared code for appeal status updates - secondary form handling needs more work - TODO: shared examples for tests --- .../decision_review/hlr_status_updater_job.rb | 34 ++++++ .../decision_review/nod_status_updater_job.rb | 34 ++++++ .../saved_claim_hlr_status_updater_job.rb | 85 ------------- ...b.rb => saved_claim_status_updater_job.rb} | 82 ++++++++----- .../decision_review/sc_status_updater_job.rb | 115 ++++++++++++++++++ ...spec.rb => hlr_status_updater_job_spec.rb} | 2 +- ...spec.rb => nod_status_updater_job_spec.rb} | 2 +- ..._spec.rb => sc_status_updater_job_spec.rb} | 2 +- 8 files changed, 236 insertions(+), 120 deletions(-) create mode 100644 app/sidekiq/decision_review/hlr_status_updater_job.rb create mode 100644 app/sidekiq/decision_review/nod_status_updater_job.rb delete mode 100644 app/sidekiq/decision_review/saved_claim_hlr_status_updater_job.rb rename app/sidekiq/decision_review/{saved_claim_nod_status_updater_job.rb => saved_claim_status_updater_job.rb} (58%) create mode 100644 app/sidekiq/decision_review/sc_status_updater_job.rb rename spec/sidekiq/decision_review/{saved_claim_hlr_status_updater_job_spec.rb => hlr_status_updater_job_spec.rb} (98%) rename spec/sidekiq/decision_review/{saved_claim_nod_status_updater_job_spec.rb => nod_status_updater_job_spec.rb} (99%) rename spec/sidekiq/decision_review/{saved_claim_sc_status_updater_job_spec.rb => sc_status_updater_job_spec.rb} (99%) diff --git a/app/sidekiq/decision_review/hlr_status_updater_job.rb b/app/sidekiq/decision_review/hlr_status_updater_job.rb new file mode 100644 index 00000000000..a046ec704e9 --- /dev/null +++ b/app/sidekiq/decision_review/hlr_status_updater_job.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative 'saved_claim_status_updater_job' + +module DecisionReview + class HlrStatusUpdaterJob < SavedClaimStatusUpdaterJob + + private + + def records_to_update + @higher_level_reviews ||= ::SavedClaim::HigherLevelReview.where(delete_date: nil).order(created_at: :asc) + end + + def statsd_prefix + 'worker.decision_review.saved_claim_hlr_status_updater' + end + + def log_prefix + 'DecisionReview::SavedClaimHlrStatusUpdaterJob' + end + + def get_record_status(guid) + decision_review_service.get_higher_level_review(guid).body + end + + def get_evidence_uploads_statuses(_) + [] + end + + def enabled? + Flipper.enabled? :decision_review_saved_claim_hlr_status_updater_job_enabled + end + end +end diff --git a/app/sidekiq/decision_review/nod_status_updater_job.rb b/app/sidekiq/decision_review/nod_status_updater_job.rb new file mode 100644 index 00000000000..1cad7eb8f79 --- /dev/null +++ b/app/sidekiq/decision_review/nod_status_updater_job.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative 'saved_claim_status_updater_job' + +module DecisionReview + class NodStatusUpdaterJob < SavedClaimStatusUpdaterJob + + private + + def records_to_update + @notice_of_disagreements ||= ::SavedClaim::NoticeOfDisagreement.where(delete_date: nil).order(created_at: :asc) + end + + def statsd_prefix + 'worker.decision_review.saved_claim_nod_status_updater' + end + + def log_prefix + 'DecisionReview::SavedClaimNodStatusUpdaterJob' + end + + def get_record_status(guid) + decision_review_service.get_notice_of_disagreement(guid).body + end + + def get_evidence_status(guid) + decision_review_service.get_notice_of_disagreement_upload(guid:).body + end + + def enabled? + Flipper.enabled? :decision_review_saved_claim_nod_status_updater_job_enabled + end + end +end diff --git a/app/sidekiq/decision_review/saved_claim_hlr_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_hlr_status_updater_job.rb deleted file mode 100644 index 2dd25fe60b5..00000000000 --- a/app/sidekiq/decision_review/saved_claim_hlr_status_updater_job.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -require 'sidekiq' -require 'decision_review_v1/service' - -module DecisionReview - class SavedClaimHlrStatusUpdaterJob - include Sidekiq::Job - - # No need to retry since the schedule will run this every hour - sidekiq_options retry: false, unique_for: 30.minutes - - RETENTION_PERIOD = 59.days - - SUCCESSFUL_STATUS = %w[complete].freeze - - ERROR_STATUS = 'error' - - STATSD_KEY_PREFIX = 'worker.decision_review.saved_claim_hlr_status_updater' - - def perform - return unless enabled? && higher_level_reviews.present? - - StatsD.increment("#{STATSD_KEY_PREFIX}.processing_records", higher_level_reviews.size) - - higher_level_reviews.each do |hlr| - guid = hlr.guid - status, attributes = get_status_and_attributes(guid) - - timestamp = DateTime.now - params = { metadata: attributes.to_json, metadata_updated_at: timestamp } - - if SUCCESSFUL_STATUS.include? status - params[:delete_date] = timestamp + RETENTION_PERIOD - StatsD.increment("#{STATSD_KEY_PREFIX}.delete_date_update") - Rails.logger.info("#{self.class.name} updated delete_date", guid:) - else - handle_form_status_metrics_and_logging(hlr, status) - end - - hlr.update(params) - rescue => e - StatsD.increment("#{STATSD_KEY_PREFIX}.error") - Rails.logger.error('DecisionReview::SavedClaimHlrStatusUpdaterJob error', { guid:, message: e.message }) - end - - nil - end - - private - - def decision_review_service - @service ||= DecisionReviewV1::Service.new - end - - def higher_level_reviews - @higher_level_reviews ||= ::SavedClaim::HigherLevelReview.where(delete_date: nil).order(created_at: :asc) - end - - def get_status_and_attributes(guid) - response = decision_review_service.get_higher_level_review(guid).body - attributes = response.dig('data', 'attributes') - status = attributes['status'] - - [status, attributes] - end - - def handle_form_status_metrics_and_logging(hlr, status) - # Skip logging and statsd metrics when there is no status change - return if JSON.parse(hlr.metadata || '{}')['status'] == status - - if status == ERROR_STATUS - Rails.logger.info('DecisionReview::SavedClaimHlrStatusUpdaterJob form status error', guid: hlr.guid) - tags = ['service:higher-level-review', 'function: form submission to Lighthouse'] - StatsD.increment('silent_failure', tags:) - end - - StatsD.increment("#{STATSD_KEY_PREFIX}.status", tags: ["status:#{status}"]) - end - - def enabled? - Flipper.enabled? :decision_review_saved_claim_hlr_status_updater_job_enabled - end - end -end diff --git a/app/sidekiq/decision_review/saved_claim_nod_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb similarity index 58% rename from app/sidekiq/decision_review/saved_claim_nod_status_updater_job.rb rename to app/sidekiq/decision_review/saved_claim_status_updater_job.rb index 5aae21abb30..1c8803b8737 100644 --- a/app/sidekiq/decision_review/saved_claim_nod_status_updater_job.rb +++ b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb @@ -2,9 +2,11 @@ require 'sidekiq' require 'decision_review_v1/service' +require 'common/exceptions/not_implemented' + module DecisionReview - class SavedClaimNodStatusUpdaterJob + class SavedClaimStatusUpdaterJob include Sidekiq::Job # No need to retry since the schedule will run this every hour @@ -20,15 +22,14 @@ class SavedClaimNodStatusUpdaterJob ATTRIBUTES_TO_STORE = %w[status detail createDate updateDate].freeze - STATSD_KEY_PREFIX = 'worker.decision_review.saved_claim_nod_status_updater' - def perform - return unless enabled? && notice_of_disagreements.present? + return unless enabled? && records_to_update.present? + pp "Got in perform method" - StatsD.increment("#{STATSD_KEY_PREFIX}.processing_records", notice_of_disagreements.size) + StatsD.increment("#{statsd_prefix}.processing_records", records_to_update.size) - notice_of_disagreements.each do |nod| - guid = nod.guid + records_to_update.each do |record| + guid = record.guid status, attributes = get_status_and_attributes(guid) uploads_metadata = get_evidence_uploads_statuses(guid) @@ -36,17 +37,18 @@ def perform params = { metadata: attributes.merge(uploads: uploads_metadata).to_json, metadata_updated_at: timestamp } # only set delete date if attachments are all successful as well - if check_attachments_status(nod, uploads_metadata) && SUCCESSFUL_STATUS.include?(status) + if check_attachments_status(record, uploads_metadata) && SUCCESSFUL_STATUS.include?(status) params[:delete_date] = timestamp + RETENTION_PERIOD - StatsD.increment("#{STATSD_KEY_PREFIX}.delete_date_update") + StatsD.increment("#{statsd_prefix}.delete_date_update") else - handle_form_status_metrics_and_logging(nod, status) + handle_form_status_metrics_and_logging(record, status) end - nod.update(params) + record.update(params) rescue => e - StatsD.increment("#{STATSD_KEY_PREFIX}.error") - Rails.logger.error('DecisionReview::SavedClaimNodStatusUpdaterJob error', { guid:, message: e.message }) + pp "Got and error #{e.message}" + StatsD.increment("#{statsd_prefix}.error") + Rails.logger.error("#{log_prefix} error", { guid:, message: e.message }) end nil @@ -54,16 +56,36 @@ def perform private - def decision_review_service - @service ||= DecisionReviewV1::Service.new + def records_to_update + raise Common::Exceptions::NotImplemented + end + + def statsd_prefix + raise Common::Exceptions::NotImplemented + end + + def log_prefix + raise Common::Exceptions::NotImplemented + end + + def get_record_status(guid) + raise Common::Exceptions::NotImplemented end - def notice_of_disagreements - @notice_of_disagreements ||= ::SavedClaim::NoticeOfDisagreement.where(delete_date: nil).order(created_at: :asc) + def get_evidence_status(guid) + raise Common::Exceptions::NotImplemented + end + + def enabled? + raise Common::Exceptions::NotImplemented + end + + def decision_review_service + @service ||= DecisionReviewV1::Service.new end def get_status_and_attributes(guid) - response = decision_review_service.get_notice_of_disagreement(guid).body + response = get_record_status(guid) attributes = response.dig('data', 'attributes') status = attributes['status'] @@ -77,7 +99,7 @@ def get_evidence_uploads_statuses(submitted_appeal_uuid) &.pluck(:lighthouse_upload_id) || [] attachment_ids.each do |guid| - response = decision_review_service.get_notice_of_disagreement_upload(guid:).body + response = get_evidence_status(guid) attributes = response.dig('data', 'attributes').slice(*ATTRIBUTES_TO_STORE) result << attributes.merge('id' => guid) end @@ -85,23 +107,23 @@ def get_evidence_uploads_statuses(submitted_appeal_uuid) result end - def handle_form_status_metrics_and_logging(nod, status) + def handle_form_status_metrics_and_logging(record, status) # Skip logging and statsd metrics when there is no status change - return if JSON.parse(nod.metadata || '{}')['status'] == status + return if JSON.parse(record.metadata || '{}')['status'] == status if status == ERROR_STATUS - Rails.logger.info('DecisionReview::SavedClaimNodStatusUpdaterJob form status error', guid: nod.guid) + Rails.logger.info("#{log_prefix} form status error", guid: record.guid) tags = ['service:board-appeal', 'function: form submission to Lighthouse'] StatsD.increment('silent_failure', tags:) end - StatsD.increment("#{STATSD_KEY_PREFIX}.status", tags: ["status:#{status}"]) + StatsD.increment("#{statsd_prefix}.status", tags: ["status:#{status}"]) end - def check_attachments_status(nod, uploads_metadata) + def check_attachments_status(record, uploads_metadata) result = true - old_uploads_metadata = extract_uploads_metadata(nod.metadata) + old_uploads_metadata = extract_uploads_metadata(record.metadata) uploads_metadata.each do |upload| status = upload['status'] @@ -112,13 +134,13 @@ def check_attachments_status(nod, uploads_metadata) next if old_uploads_metadata.dig(upload_id, 'status') == status if status == ERROR_STATUS - Rails.logger.info('DecisionReview::SavedClaimNodStatusUpdaterJob evidence status error', - { guid: nod.guid, lighthouse_upload_id: upload_id, detail: upload['detail'] }) + Rails.logger.info("#{log_prefix} evidence status error", + { guid: record.guid, lighthouse_upload_id: upload_id, detail: upload['detail'] }) tags = ['service:board-appeal', 'function: evidence submission to Lighthouse'] StatsD.increment('silent_failure', tags:) end - StatsD.increment("#{STATSD_KEY_PREFIX}_upload.status", tags: ["status:#{status}"]) + StatsD.increment("#{statsd_prefix}_upload.status", tags: ["status:#{status}"]) end result @@ -129,9 +151,5 @@ def extract_uploads_metadata(metadata) JSON.parse(metadata).fetch('uploads', []).index_by { |upload| upload['id'] } end - - def enabled? - Flipper.enabled? :decision_review_saved_claim_nod_status_updater_job_enabled - end end end diff --git a/app/sidekiq/decision_review/sc_status_updater_job.rb b/app/sidekiq/decision_review/sc_status_updater_job.rb new file mode 100644 index 00000000000..4c14e5523be --- /dev/null +++ b/app/sidekiq/decision_review/sc_status_updater_job.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +require_relative 'saved_claim_status_updater_job' + +module DecisionReview + class ScStatusUpdaterJob < SavedClaimStatusUpdaterJob + + SECONDARY_FORM_ATTRIBUTES_TO_STORE = %w[status detail updated_at].freeze + + def perform + return unless enabled? && records_to_update.present? + + StatsD.increment("#{statsd_prefix}.processing_records", records_to_update.size) + + records_to_update.each do |sc| + status, attributes = get_status_and_attributes(sc.guid) + uploads_metadata = get_evidence_uploads_statuses(sc.guid) + secondary_forms_complete = get_and_update_secondary_form_statuses(sc.guid) + + timestamp = DateTime.now + params = { metadata: attributes.merge(uploads: uploads_metadata).to_json, metadata_updated_at: timestamp } + # only set delete date if attachments are all successful as well + if saved_claim_complete?(sc, status, uploads_metadata, secondary_forms_complete) + params[:delete_date] = timestamp + RETENTION_PERIOD + StatsD.increment("#{statsd_prefix}.delete_date_update") + else + handle_form_status_metrics_and_logging(sc, status) + end + + sc.update(params) + rescue => e + StatsD.increment("#{statsd_prefix}.error") + Rails.logger.error("#{log_prefix} error", { guid: sc.guid, message: e.message }) + end + + nil + end + + private + + def records_to_update + @supplemental_claims ||= ::SavedClaim::SupplementalClaim.where(delete_date: nil).order(created_at: :asc) + end + + def statsd_prefix + 'worker.decision_review.saved_claim_sc_status_updater' + end + + def log_prefix + 'DecisionReview::SavedClaimScStatusUpdaterJob' + end + + def get_record_status(guid) + decision_review_service.get_supplemental_claim(guid).body + end + + def get_evidence_status(uuid) + decision_review_service.get_supplemental_claim_upload(uuid:).body + end + + def benefits_intake_service + @intake_service ||= BenefitsIntake::Service.new + end + + def get_and_update_secondary_form_statuses(submitted_appeal_uuid) + all_complete = true + return all_complete unless Flipper.enabled?(:decision_review_track_4142_submissions) + + secondary_forms = AppealSubmission.find_by(submitted_appeal_uuid:)&.secondary_appeal_forms + secondary_forms = secondary_forms&.filter { |form| form.delete_date.nil? } || [] + + secondary_forms.each do |form| + response = benefits_intake_service.get_status(uuid: form.guid).body + attributes = response.dig('data', 'attributes').slice(*SECONDARY_FORM_ATTRIBUTES_TO_STORE) + all_complete = false unless UPLOAD_SUCCESSFUL_STATUS.include?(attributes['status']) + handle_secondary_form_status_metrics_and_logging(form, attributes['status']) + update_secondary_form_status(form, attributes) + end + + all_complete + end + + def handle_secondary_form_status_metrics_and_logging(form, status) + # Skip logging and statsd metrics when there is no status change + return if JSON.parse(form.status || '{}')['status'] == status + + if status == ERROR_STATUS + Rails.logger.info("#{log_prefix} secondary form status error", guid: form.guid) + tags = ['service:supplemental-claims-4142', 'function: PDF submission to Lighthouse'] + StatsD.increment('silent_failure', tags:) + end + + StatsD.increment("#{statsd_prefix}_secondary_form.status", tags: ["status:#{status}"]) + end + + def update_secondary_form_status(form, attributes) + status = attributes['status'] + if UPLOAD_SUCCESSFUL_STATUS.include?(status) + StatsD.increment("#{statsd_prefix}_secondary_form.delete_date_update") + delete_date = (Time.current + RETENTION_PERIOD) + else + delete_date = nil + end + form.update!(status: attributes.to_json, status_updated_at: Time.current, delete_date:) + end + + def saved_claim_complete?(sc, status, uploads_metadata, secondary_forms_complete) + check_attachments_status(sc, uploads_metadata) && secondary_forms_complete && SUCCESSFUL_STATUS.include?(status) + end + + def enabled? + Flipper.enabled? :decision_review_saved_claim_sc_status_updater_job_enabled + end + end +end diff --git a/spec/sidekiq/decision_review/saved_claim_hlr_status_updater_job_spec.rb b/spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb similarity index 98% rename from spec/sidekiq/decision_review/saved_claim_hlr_status_updater_job_spec.rb rename to spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb index 0d4f2b7292b..0a9241deafe 100644 --- a/spec/sidekiq/decision_review/saved_claim_hlr_status_updater_job_spec.rb +++ b/spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' require 'decision_review_v1/service' -RSpec.describe DecisionReview::SavedClaimHlrStatusUpdaterJob, type: :job do +RSpec.describe DecisionReview::HlrStatusUpdaterJob, type: :job do subject { described_class } let(:service) { instance_double(DecisionReviewV1::Service) } diff --git a/spec/sidekiq/decision_review/saved_claim_nod_status_updater_job_spec.rb b/spec/sidekiq/decision_review/nod_status_updater_job_spec.rb similarity index 99% rename from spec/sidekiq/decision_review/saved_claim_nod_status_updater_job_spec.rb rename to spec/sidekiq/decision_review/nod_status_updater_job_spec.rb index 04265f735b7..f7cfdde3760 100644 --- a/spec/sidekiq/decision_review/saved_claim_nod_status_updater_job_spec.rb +++ b/spec/sidekiq/decision_review/nod_status_updater_job_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' require 'decision_review_v1/service' -RSpec.describe DecisionReview::SavedClaimNodStatusUpdaterJob, type: :job do +RSpec.describe DecisionReview::NodStatusUpdaterJob, type: :job do subject { described_class } let(:service) { instance_double(DecisionReviewV1::Service) } diff --git a/spec/sidekiq/decision_review/saved_claim_sc_status_updater_job_spec.rb b/spec/sidekiq/decision_review/sc_status_updater_job_spec.rb similarity index 99% rename from spec/sidekiq/decision_review/saved_claim_sc_status_updater_job_spec.rb rename to spec/sidekiq/decision_review/sc_status_updater_job_spec.rb index 2b397b79346..20ba8f94b2a 100644 --- a/spec/sidekiq/decision_review/saved_claim_sc_status_updater_job_spec.rb +++ b/spec/sidekiq/decision_review/sc_status_updater_job_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' require 'decision_review_v1/service' -RSpec.describe DecisionReview::SavedClaimScStatusUpdaterJob, type: :job do +RSpec.describe DecisionReview::ScStatusUpdaterJob, type: :job do subject { described_class } let(:service) { instance_double(DecisionReviewV1::Service) } From ff5ca279c84fd244e78740c8d505eea92890bb49 Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Tue, 12 Nov 2024 12:36:31 -0800 Subject: [PATCH 2/7] Centralize handling of evidence and secondary forms --- .../decision_review/hlr_status_updater_job.rb | 9 +- .../decision_review/nod_status_updater_job.rb | 9 +- .../saved_claim_status_updater_job.rb | 69 ++++++++++++++-- .../decision_review/sc_status_updater_job.rb | 82 ++----------------- 4 files changed, 84 insertions(+), 85 deletions(-) diff --git a/app/sidekiq/decision_review/hlr_status_updater_job.rb b/app/sidekiq/decision_review/hlr_status_updater_job.rb index a046ec704e9..ffe5bdb9dc3 100644 --- a/app/sidekiq/decision_review/hlr_status_updater_job.rb +++ b/app/sidekiq/decision_review/hlr_status_updater_job.rb @@ -4,7 +4,6 @@ module DecisionReview class HlrStatusUpdaterJob < SavedClaimStatusUpdaterJob - private def records_to_update @@ -23,8 +22,12 @@ def get_record_status(guid) decision_review_service.get_higher_level_review(guid).body end - def get_evidence_uploads_statuses(_) - [] + def evidence? + false + end + + def secondary_forms? + false end def enabled? diff --git a/app/sidekiq/decision_review/nod_status_updater_job.rb b/app/sidekiq/decision_review/nod_status_updater_job.rb index 1cad7eb8f79..35236168a56 100644 --- a/app/sidekiq/decision_review/nod_status_updater_job.rb +++ b/app/sidekiq/decision_review/nod_status_updater_job.rb @@ -4,7 +4,6 @@ module DecisionReview class NodStatusUpdaterJob < SavedClaimStatusUpdaterJob - private def records_to_update @@ -27,6 +26,14 @@ def get_evidence_status(guid) decision_review_service.get_notice_of_disagreement_upload(guid:).body end + def evidence? + true + end + + def secondary_forms? + false + end + def enabled? Flipper.enabled? :decision_review_saved_claim_nod_status_updater_job_enabled end diff --git a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb index 1c8803b8737..1d0602cff92 100644 --- a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb +++ b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb @@ -4,7 +4,6 @@ require 'decision_review_v1/service' require 'common/exceptions/not_implemented' - module DecisionReview class SavedClaimStatusUpdaterJob include Sidekiq::Job @@ -22,9 +21,10 @@ class SavedClaimStatusUpdaterJob ATTRIBUTES_TO_STORE = %w[status detail createDate updateDate].freeze + SECONDARY_FORM_ATTRIBUTES_TO_STORE = %w[status detail updated_at].freeze + def perform return unless enabled? && records_to_update.present? - pp "Got in perform method" StatsD.increment("#{statsd_prefix}.processing_records", records_to_update.size) @@ -32,12 +32,13 @@ def perform guid = record.guid status, attributes = get_status_and_attributes(guid) uploads_metadata = get_evidence_uploads_statuses(guid) + secondary_forms_complete = get_and_update_secondary_form_statuses(guid) timestamp = DateTime.now params = { metadata: attributes.merge(uploads: uploads_metadata).to_json, metadata_updated_at: timestamp } # only set delete date if attachments are all successful as well - if check_attachments_status(record, uploads_metadata) && SUCCESSFUL_STATUS.include?(status) + if record_complete?(record, status, uploads_metadata, secondary_forms_complete) params[:delete_date] = timestamp + RETENTION_PERIOD StatsD.increment("#{statsd_prefix}.delete_date_update") else @@ -46,7 +47,6 @@ def perform record.update(params) rescue => e - pp "Got and error #{e.message}" StatsD.increment("#{statsd_prefix}.error") Rails.logger.error("#{log_prefix} error", { guid:, message: e.message }) end @@ -76,10 +76,18 @@ def get_evidence_status(guid) raise Common::Exceptions::NotImplemented end + def evidence? + raise Common::Exceptions::NotImplemented + end + + def secondary_forms? + raise Common::Exceptions::NotImplemented + end + def enabled? raise Common::Exceptions::NotImplemented end - + def decision_review_service @service ||= DecisionReviewV1::Service.new end @@ -93,6 +101,8 @@ def get_status_and_attributes(guid) end def get_evidence_uploads_statuses(submitted_appeal_uuid) + return [] unless evidence? + result = [] attachment_ids = AppealSubmission.find_by(submitted_appeal_uuid:)&.appeal_submission_uploads @@ -107,6 +117,26 @@ def get_evidence_uploads_statuses(submitted_appeal_uuid) result end + def get_and_update_secondary_form_statuses(submitted_appeal_uuid) + return true unless secondary_forms? + + all_complete = true + return all_complete unless Flipper.enabled?(:decision_review_track_4142_submissions) + + secondary_forms = AppealSubmission.find_by(submitted_appeal_uuid:)&.secondary_appeal_forms + secondary_forms = secondary_forms&.filter { |form| form.delete_date.nil? } || [] + + secondary_forms.each do |form| + response = benefits_intake_service.get_status(uuid: form.guid).body + attributes = response.dig('data', 'attributes').slice(*SECONDARY_FORM_ATTRIBUTES_TO_STORE) + all_complete = false unless UPLOAD_SUCCESSFUL_STATUS.include?(attributes['status']) + handle_secondary_form_status_metrics_and_logging(form, attributes['status']) + update_secondary_form_status(form, attributes) + end + + all_complete + end + def handle_form_status_metrics_and_logging(record, status) # Skip logging and statsd metrics when there is no status change return if JSON.parse(record.metadata || '{}')['status'] == status @@ -120,6 +150,30 @@ def handle_form_status_metrics_and_logging(record, status) StatsD.increment("#{statsd_prefix}.status", tags: ["status:#{status}"]) end + def handle_secondary_form_status_metrics_and_logging(form, status) + # Skip logging and statsd metrics when there is no status change + return if JSON.parse(form.status || '{}')['status'] == status + + if status == ERROR_STATUS + Rails.logger.info("#{log_prefix} secondary form status error", guid: form.guid) + tags = ['service:supplemental-claims-4142', 'function: PDF submission to Lighthouse'] + StatsD.increment('silent_failure', tags:) + end + + StatsD.increment("#{statsd_prefix}_secondary_form.status", tags: ["status:#{status}"]) + end + + def update_secondary_form_status(form, attributes) + status = attributes['status'] + if UPLOAD_SUCCESSFUL_STATUS.include?(status) + StatsD.increment("#{statsd_prefix}_secondary_form.delete_date_update") + delete_date = (Time.current + RETENTION_PERIOD) + else + delete_date = nil + end + form.update!(status: attributes.to_json, status_updated_at: Time.current, delete_date:) + end + def check_attachments_status(record, uploads_metadata) result = true @@ -146,6 +200,11 @@ def check_attachments_status(record, uploads_metadata) result end + def record_complete?(record, status, uploads_metadata, secondary_forms_complete) + check_attachments_status(record, + uploads_metadata) && secondary_forms_complete && SUCCESSFUL_STATUS.include?(status) + end + def extract_uploads_metadata(metadata) return {} if metadata.nil? diff --git a/app/sidekiq/decision_review/sc_status_updater_job.rb b/app/sidekiq/decision_review/sc_status_updater_job.rb index 4c14e5523be..049a9ea49f8 100644 --- a/app/sidekiq/decision_review/sc_status_updater_job.rb +++ b/app/sidekiq/decision_review/sc_status_updater_job.rb @@ -4,38 +4,6 @@ module DecisionReview class ScStatusUpdaterJob < SavedClaimStatusUpdaterJob - - SECONDARY_FORM_ATTRIBUTES_TO_STORE = %w[status detail updated_at].freeze - - def perform - return unless enabled? && records_to_update.present? - - StatsD.increment("#{statsd_prefix}.processing_records", records_to_update.size) - - records_to_update.each do |sc| - status, attributes = get_status_and_attributes(sc.guid) - uploads_metadata = get_evidence_uploads_statuses(sc.guid) - secondary_forms_complete = get_and_update_secondary_form_statuses(sc.guid) - - timestamp = DateTime.now - params = { metadata: attributes.merge(uploads: uploads_metadata).to_json, metadata_updated_at: timestamp } - # only set delete date if attachments are all successful as well - if saved_claim_complete?(sc, status, uploads_metadata, secondary_forms_complete) - params[:delete_date] = timestamp + RETENTION_PERIOD - StatsD.increment("#{statsd_prefix}.delete_date_update") - else - handle_form_status_metrics_and_logging(sc, status) - end - - sc.update(params) - rescue => e - StatsD.increment("#{statsd_prefix}.error") - Rails.logger.error("#{log_prefix} error", { guid: sc.guid, message: e.message }) - end - - nil - end - private def records_to_update @@ -58,54 +26,16 @@ def get_evidence_status(uuid) decision_review_service.get_supplemental_claim_upload(uuid:).body end - def benefits_intake_service - @intake_service ||= BenefitsIntake::Service.new - end - - def get_and_update_secondary_form_statuses(submitted_appeal_uuid) - all_complete = true - return all_complete unless Flipper.enabled?(:decision_review_track_4142_submissions) - - secondary_forms = AppealSubmission.find_by(submitted_appeal_uuid:)&.secondary_appeal_forms - secondary_forms = secondary_forms&.filter { |form| form.delete_date.nil? } || [] - - secondary_forms.each do |form| - response = benefits_intake_service.get_status(uuid: form.guid).body - attributes = response.dig('data', 'attributes').slice(*SECONDARY_FORM_ATTRIBUTES_TO_STORE) - all_complete = false unless UPLOAD_SUCCESSFUL_STATUS.include?(attributes['status']) - handle_secondary_form_status_metrics_and_logging(form, attributes['status']) - update_secondary_form_status(form, attributes) - end - - all_complete + def evidence? + true end - def handle_secondary_form_status_metrics_and_logging(form, status) - # Skip logging and statsd metrics when there is no status change - return if JSON.parse(form.status || '{}')['status'] == status - - if status == ERROR_STATUS - Rails.logger.info("#{log_prefix} secondary form status error", guid: form.guid) - tags = ['service:supplemental-claims-4142', 'function: PDF submission to Lighthouse'] - StatsD.increment('silent_failure', tags:) - end - - StatsD.increment("#{statsd_prefix}_secondary_form.status", tags: ["status:#{status}"]) - end - - def update_secondary_form_status(form, attributes) - status = attributes['status'] - if UPLOAD_SUCCESSFUL_STATUS.include?(status) - StatsD.increment("#{statsd_prefix}_secondary_form.delete_date_update") - delete_date = (Time.current + RETENTION_PERIOD) - else - delete_date = nil - end - form.update!(status: attributes.to_json, status_updated_at: Time.current, delete_date:) + def secondary_forms? + true end - def saved_claim_complete?(sc, status, uploads_metadata, secondary_forms_complete) - check_attachments_status(sc, uploads_metadata) && secondary_forms_complete && SUCCESSFUL_STATUS.include?(status) + def benefits_intake_service + @intake_service ||= BenefitsIntake::Service.new end def enabled? From 99cdb828d8cf8e8863075c48e2667818b2d1513a Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Tue, 12 Nov 2024 12:49:06 -0800 Subject: [PATCH 3/7] Use better associations --- .../saved_claim_status_updater_job.rb | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb index 1d0602cff92..5c34700d0e0 100644 --- a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb +++ b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb @@ -29,10 +29,9 @@ def perform StatsD.increment("#{statsd_prefix}.processing_records", records_to_update.size) records_to_update.each do |record| - guid = record.guid - status, attributes = get_status_and_attributes(guid) - uploads_metadata = get_evidence_uploads_statuses(guid) - secondary_forms_complete = get_and_update_secondary_form_statuses(guid) + status, attributes = get_status_and_attributes(record) + uploads_metadata = get_evidence_uploads_statuses(record) + secondary_forms_complete = get_and_update_secondary_form_statuses(record) timestamp = DateTime.now params = { metadata: attributes.merge(uploads: uploads_metadata).to_json, metadata_updated_at: timestamp } @@ -48,7 +47,7 @@ def perform record.update(params) rescue => e StatsD.increment("#{statsd_prefix}.error") - Rails.logger.error("#{log_prefix} error", { guid:, message: e.message }) + Rails.logger.error("#{log_prefix} error", { guid: record.guid, message: e.message }) end nil @@ -92,21 +91,21 @@ def decision_review_service @service ||= DecisionReviewV1::Service.new end - def get_status_and_attributes(guid) - response = get_record_status(guid) + def get_status_and_attributes(record) + response = get_record_status(record.guid) attributes = response.dig('data', 'attributes') status = attributes['status'] [status, attributes] end - def get_evidence_uploads_statuses(submitted_appeal_uuid) + def get_evidence_uploads_statuses(record) return [] unless evidence? result = [] - attachment_ids = AppealSubmission.find_by(submitted_appeal_uuid:)&.appeal_submission_uploads - &.pluck(:lighthouse_upload_id) || [] + attachment_ids = record.appeal_submission&.appeal_submission_uploads + &.pluck(:lighthouse_upload_id) || [] attachment_ids.each do |guid| response = get_evidence_status(guid) @@ -117,13 +116,13 @@ def get_evidence_uploads_statuses(submitted_appeal_uuid) result end - def get_and_update_secondary_form_statuses(submitted_appeal_uuid) + def get_and_update_secondary_form_statuses(record) return true unless secondary_forms? all_complete = true return all_complete unless Flipper.enabled?(:decision_review_track_4142_submissions) - secondary_forms = AppealSubmission.find_by(submitted_appeal_uuid:)&.secondary_appeal_forms + secondary_forms = record.appeal_submission&.secondary_appeal_forms secondary_forms = secondary_forms&.filter { |form| form.delete_date.nil? } || [] secondary_forms.each do |form| From f36c047e13569529801798a3a039ae67461262c5 Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Tue, 12 Nov 2024 13:27:27 -0800 Subject: [PATCH 4/7] Fix linting for placeholder method argument --- app/sidekiq/decision_review/saved_claim_status_updater_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb index 5c34700d0e0..0adaf1a5d91 100644 --- a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb +++ b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb @@ -67,11 +67,11 @@ def log_prefix raise Common::Exceptions::NotImplemented end - def get_record_status(guid) + def get_record_status(_guid) raise Common::Exceptions::NotImplemented end - def get_evidence_status(guid) + def get_evidence_status(_guid) raise Common::Exceptions::NotImplemented end From f07370300f244a8f1ed0653eb453c705a4462c78 Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Wed, 13 Nov 2024 11:45:51 -0800 Subject: [PATCH 5/7] Correct silent failure service tag - now depends on a method in each subclass of the status updater - add tests for correct statsd increment value --- app/sidekiq/decision_review/hlr_status_updater_job.rb | 4 ++++ app/sidekiq/decision_review/nod_status_updater_job.rb | 4 ++++ .../decision_review/saved_claim_status_updater_job.rb | 8 ++++++-- app/sidekiq/decision_review/sc_status_updater_job.rb | 4 ++++ .../decision_review/hlr_status_updater_job_spec.rb | 4 ++++ .../decision_review/nod_status_updater_job_spec.rb | 8 ++++++++ .../sidekiq/decision_review/sc_status_updater_job_spec.rb | 8 ++++++++ 7 files changed, 38 insertions(+), 2 deletions(-) diff --git a/app/sidekiq/decision_review/hlr_status_updater_job.rb b/app/sidekiq/decision_review/hlr_status_updater_job.rb index ffe5bdb9dc3..f568c8d4944 100644 --- a/app/sidekiq/decision_review/hlr_status_updater_job.rb +++ b/app/sidekiq/decision_review/hlr_status_updater_job.rb @@ -18,6 +18,10 @@ def log_prefix 'DecisionReview::SavedClaimHlrStatusUpdaterJob' end + def service_tag + 'service:higher-level-review' + end + def get_record_status(guid) decision_review_service.get_higher_level_review(guid).body end diff --git a/app/sidekiq/decision_review/nod_status_updater_job.rb b/app/sidekiq/decision_review/nod_status_updater_job.rb index 35236168a56..dce7e857bce 100644 --- a/app/sidekiq/decision_review/nod_status_updater_job.rb +++ b/app/sidekiq/decision_review/nod_status_updater_job.rb @@ -18,6 +18,10 @@ def log_prefix 'DecisionReview::SavedClaimNodStatusUpdaterJob' end + def service_tag + 'service:board-appeal' + end + def get_record_status(guid) decision_review_service.get_notice_of_disagreement(guid).body end diff --git a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb index 0adaf1a5d91..cdee234a9db 100644 --- a/app/sidekiq/decision_review/saved_claim_status_updater_job.rb +++ b/app/sidekiq/decision_review/saved_claim_status_updater_job.rb @@ -67,6 +67,10 @@ def log_prefix raise Common::Exceptions::NotImplemented end + def service_tag + raise Common::Exceptions::NotImplemented + end + def get_record_status(_guid) raise Common::Exceptions::NotImplemented end @@ -142,7 +146,7 @@ def handle_form_status_metrics_and_logging(record, status) if status == ERROR_STATUS Rails.logger.info("#{log_prefix} form status error", guid: record.guid) - tags = ['service:board-appeal', 'function: form submission to Lighthouse'] + tags = [service_tag, 'function: form submission to Lighthouse'] StatsD.increment('silent_failure', tags:) end @@ -189,7 +193,7 @@ def check_attachments_status(record, uploads_metadata) if status == ERROR_STATUS Rails.logger.info("#{log_prefix} evidence status error", { guid: record.guid, lighthouse_upload_id: upload_id, detail: upload['detail'] }) - tags = ['service:board-appeal', 'function: evidence submission to Lighthouse'] + tags = [service_tag, 'function: evidence submission to Lighthouse'] StatsD.increment('silent_failure', tags:) end diff --git a/app/sidekiq/decision_review/sc_status_updater_job.rb b/app/sidekiq/decision_review/sc_status_updater_job.rb index 049a9ea49f8..1c55781c030 100644 --- a/app/sidekiq/decision_review/sc_status_updater_job.rb +++ b/app/sidekiq/decision_review/sc_status_updater_job.rb @@ -18,6 +18,10 @@ def log_prefix 'DecisionReview::SavedClaimScStatusUpdaterJob' end + def service_tag + 'service:supplemental-claims' + end + def get_record_status(guid) decision_review_service.get_supplemental_claim(guid).body end diff --git a/spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb b/spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb index 0a9241deafe..5cfd31534ba 100644 --- a/spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb +++ b/spec/sidekiq/decision_review/hlr_status_updater_job_spec.rb @@ -125,6 +125,10 @@ .with('DecisionReview::SavedClaimHlrStatusUpdaterJob form status error', guid: guid1) expect(Rails.logger).to have_received(:info) .with('DecisionReview::SavedClaimHlrStatusUpdaterJob form status error', guid: guid2) + expect(StatsD).to have_received(:increment) + .with('silent_failure', tags: ['service:higher-level-review', + 'function: form submission to Lighthouse']) + .exactly(1).time end end end diff --git a/spec/sidekiq/decision_review/nod_status_updater_job_spec.rb b/spec/sidekiq/decision_review/nod_status_updater_job_spec.rb index f7cfdde3760..7c9b0713618 100644 --- a/spec/sidekiq/decision_review/nod_status_updater_job_spec.rb +++ b/spec/sidekiq/decision_review/nod_status_updater_job_spec.rb @@ -250,6 +250,10 @@ .with('DecisionReview::SavedClaimNodStatusUpdaterJob form status error', guid: guid1) expect(Rails.logger).to have_received(:info) .with('DecisionReview::SavedClaimNodStatusUpdaterJob form status error', guid: guid2) + expect(StatsD).to have_received(:increment) + .with('silent_failure', tags: ['service:board-appeal', + 'function: form submission to Lighthouse']) + .exactly(1).time end it 'does not increment metrics for unchanged evidence status' do @@ -285,6 +289,10 @@ expect(Rails.logger).to have_received(:info) .with('DecisionReview::SavedClaimNodStatusUpdaterJob evidence status error', guid: guid2, lighthouse_upload_id: upload_id2, detail: 'Invalid PDF') + expect(StatsD).to have_received(:increment) + .with('silent_failure', tags: ['service:board-appeal', + 'function: evidence submission to Lighthouse']) + .exactly(1).time end end diff --git a/spec/sidekiq/decision_review/sc_status_updater_job_spec.rb b/spec/sidekiq/decision_review/sc_status_updater_job_spec.rb index 20ba8f94b2a..e7e4cac27b3 100644 --- a/spec/sidekiq/decision_review/sc_status_updater_job_spec.rb +++ b/spec/sidekiq/decision_review/sc_status_updater_job_spec.rb @@ -413,6 +413,10 @@ .with('DecisionReview::SavedClaimScStatusUpdaterJob form status error', guid: guid1) expect(Rails.logger).to have_received(:info) .with('DecisionReview::SavedClaimScStatusUpdaterJob form status error', guid: guid2) + expect(StatsD).to have_received(:increment) + .with('silent_failure', tags: ['service:supplemental-claims', + 'function: form submission to Lighthouse']) + .exactly(1).time end it 'does not increment metrics for unchanged evidence status' do @@ -448,6 +452,10 @@ expect(Rails.logger).to have_received(:info) .with('DecisionReview::SavedClaimScStatusUpdaterJob evidence status error', guid: guid2, lighthouse_upload_id: upload_id2, detail: 'Invalid PDF') + expect(StatsD).to have_received(:increment) + .with('silent_failure', tags: ['service:supplemental-claims', + 'function: evidence submission to Lighthouse']) + .exactly(1).time end end From a5a60779a5adb07a4b6bfea906336122d37a51c7 Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Wed, 13 Nov 2024 13:27:11 -0800 Subject: [PATCH 6/7] Update job names in cron entries --- lib/periodic_jobs.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/periodic_jobs.rb b/lib/periodic_jobs.rb index 28c0ed6885f..dc0d3d993de 100644 --- a/lib/periodic_jobs.rb +++ b/lib/periodic_jobs.rb @@ -222,9 +222,9 @@ mgr.register('*/15 * * * *', 'IvcChampva::MissingFormStatusJob') # Hourly jobs that update DR SavedClaims with delete_date - mgr.register('20 * * * *', 'DecisionReview::SavedClaimHlrStatusUpdaterJob') - mgr.register('30 * * * *', 'DecisionReview::SavedClaimNodStatusUpdaterJob') - mgr.register('40 * * * *', 'DecisionReview::SavedClaimScStatusUpdaterJob') + mgr.register('20 * * * *', 'DecisionReview::HlrStatusUpdaterJob') + mgr.register('30 * * * *', 'DecisionReview::NodStatusUpdaterJob') + mgr.register('40 * * * *', 'DecisionReview::ScStatusUpdaterJob') # Clean SavedClaim records that are past delete date mgr.register('0 7 * * *', 'DecisionReview::DeleteSavedClaimRecordsJob') From 4f186479b58cb429bea3f6f3dd516ce68d767364 Mon Sep 17 00:00:00 2001 From: Molly Trombley-McCann Date: Fri, 15 Nov 2024 09:58:07 -0800 Subject: [PATCH 7/7] Delete old version of file - was renamed, but got resurrected during a merge --- .../saved_claim_sc_status_updater_job.rb | 186 ------------------ 1 file changed, 186 deletions(-) delete mode 100644 app/sidekiq/decision_review/saved_claim_sc_status_updater_job.rb diff --git a/app/sidekiq/decision_review/saved_claim_sc_status_updater_job.rb b/app/sidekiq/decision_review/saved_claim_sc_status_updater_job.rb deleted file mode 100644 index d78cf38d7fc..00000000000 --- a/app/sidekiq/decision_review/saved_claim_sc_status_updater_job.rb +++ /dev/null @@ -1,186 +0,0 @@ -# frozen_string_literal: true - -require 'sidekiq' -require 'decision_review_v1/service' - -module DecisionReview - class SavedClaimScStatusUpdaterJob - include Sidekiq::Job - - # No need to retry since the schedule will run this every hour - sidekiq_options retry: false, unique_for: 30.minutes - - RETENTION_PERIOD = 59.days - - SUCCESSFUL_STATUS = %w[complete].freeze - - ERROR_STATUS = 'error' - - UPLOAD_SUCCESSFUL_STATUS = %w[vbms].freeze - - ATTRIBUTES_TO_STORE = %w[status detail createDate updateDate].freeze - - SECONDARY_FORM_ATTRIBUTES_TO_STORE = %w[status detail updated_at].freeze - - STATSD_KEY_PREFIX = 'worker.decision_review.saved_claim_sc_status_updater' - - def perform - return unless enabled? && supplemental_claims.present? - - StatsD.increment("#{STATSD_KEY_PREFIX}.processing_records", supplemental_claims.size) - - supplemental_claims.each do |sc| - status, attributes = get_status_and_attributes(sc.guid) - uploads_metadata = get_evidence_uploads_statuses(sc) - secondary_forms_complete = get_and_update_secondary_form_statuses(sc) - - timestamp = DateTime.now - params = { metadata: attributes.merge(uploads: uploads_metadata).to_json, metadata_updated_at: timestamp } - # only set delete date if attachments are all successful as well - if saved_claim_complete?(sc, status, uploads_metadata, secondary_forms_complete) - params[:delete_date] = timestamp + RETENTION_PERIOD - StatsD.increment("#{STATSD_KEY_PREFIX}.delete_date_update") - else - handle_form_status_metrics_and_logging(sc, status) - end - - sc.update(params) - rescue => e - StatsD.increment("#{STATSD_KEY_PREFIX}.error") - Rails.logger.error('DecisionReview::SavedClaimScStatusUpdaterJob error', { guid: sc.guid, message: e.message }) - end - - nil - end - - private - - def decision_review_service - @service ||= DecisionReviewV1::Service.new - end - - def benefits_intake_service - @intake_service ||= BenefitsIntake::Service.new - end - - def supplemental_claims - @supplemental_claims ||= ::SavedClaim::SupplementalClaim.where(delete_date: nil).order(created_at: :asc) - end - - def get_status_and_attributes(guid) - response = decision_review_service.get_supplemental_claim(guid).body - attributes = response.dig('data', 'attributes') - status = attributes['status'] - - [status, attributes] - end - - def get_evidence_uploads_statuses(saved_claim) - result = [] - - attachment_ids = saved_claim.appeal_submission&.appeal_submission_uploads - &.pluck(:lighthouse_upload_id) || [] - - attachment_ids.each do |uuid| - response = decision_review_service.get_supplemental_claim_upload(uuid:).body - attributes = response.dig('data', 'attributes').slice(*ATTRIBUTES_TO_STORE) - result << attributes.merge('id' => uuid) - end - - result - end - - def get_and_update_secondary_form_statuses(saved_claim) - all_complete = true - return all_complete unless Flipper.enabled?(:decision_review_track_4142_submissions) - - secondary_forms = saved_claim.appeal_submission&.incomplete_secondary_appeal_forms || [] - - secondary_forms.each do |form| - response = benefits_intake_service.get_status(uuid: form.guid).body - attributes = response.dig('data', 'attributes').slice(*SECONDARY_FORM_ATTRIBUTES_TO_STORE) - all_complete = false unless UPLOAD_SUCCESSFUL_STATUS.include?(attributes['status']) - handle_secondary_form_status_metrics_and_logging(form, attributes['status']) - update_secondary_form_status(form, attributes) - end - - all_complete - end - - def handle_form_status_metrics_and_logging(sc, status) - # Skip logging and statsd metrics when there is no status change - return if JSON.parse(sc.metadata || '{}')['status'] == status - - if status == ERROR_STATUS - Rails.logger.info('DecisionReview::SavedClaimScStatusUpdaterJob form status error', guid: sc.guid) - tags = ['service:supplemental-claims', 'function: form submission to Lighthouse'] - StatsD.increment('silent_failure', tags:) - end - - StatsD.increment("#{STATSD_KEY_PREFIX}.status", tags: ["status:#{status}"]) - end - - def handle_secondary_form_status_metrics_and_logging(form, status) - # Skip logging and statsd metrics when there is no status change - return if JSON.parse(form.status || '{}')['status'] == status - - if status == ERROR_STATUS - Rails.logger.info('DecisionReview::SavedClaimScStatusUpdaterJob secondary form status error', guid: form.guid) - tags = ['service:supplemental-claims-4142', 'function: PDF submission to Lighthouse'] - StatsD.increment('silent_failure', tags:) - end - - StatsD.increment("#{STATSD_KEY_PREFIX}_secondary_form.status", tags: ["status:#{status}"]) - end - - def update_secondary_form_status(form, attributes) - status = attributes['status'] - if UPLOAD_SUCCESSFUL_STATUS.include?(status) - StatsD.increment("#{STATSD_KEY_PREFIX}_secondary_form.delete_date_update") - delete_date = (Time.current + RETENTION_PERIOD) - else - delete_date = nil - end - form.update!(status: attributes.to_json, status_updated_at: Time.current, delete_date:) - end - - def check_attachments_status(sc, uploads_metadata) - result = true - - old_uploads_metadata = extract_uploads_metadata(sc.metadata) - - uploads_metadata.each do |upload| - status = upload['status'] - upload_id = upload['id'] - result = false unless UPLOAD_SUCCESSFUL_STATUS.include? status - - # Skip logging and statsd metrics when there is no status change - next if old_uploads_metadata.dig(upload_id, 'status') == status - - if status == ERROR_STATUS - Rails.logger.info('DecisionReview::SavedClaimScStatusUpdaterJob evidence status error', - { guid: sc.guid, lighthouse_upload_id: upload_id, detail: upload['detail'] }) - tags = ['service:supplemental-claims', 'function: evidence submission to Lighthouse'] - StatsD.increment('silent_failure', tags:) - end - StatsD.increment("#{STATSD_KEY_PREFIX}_upload.status", tags: ["status:#{status}"]) - end - - result - end - - def saved_claim_complete?(sc, status, uploads_metadata, secondary_forms_complete) - check_attachments_status(sc, uploads_metadata) && secondary_forms_complete && SUCCESSFUL_STATUS.include?(status) - end - - def extract_uploads_metadata(metadata) - return {} if metadata.nil? - - JSON.parse(metadata).fetch('uploads', []).index_by { |upload| upload['id'] } - end - - def enabled? - Flipper.enabled? :decision_review_saved_claim_sc_status_updater_job_enabled - end - end -end