diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 67a9686cabf..ddde7a275f1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -842,6 +842,7 @@ lib/benefits_intake_service @department-of-veterans-affairs/benefits-dependents- lib/bgs @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/bid @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/bip_claims @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group +lib/burials @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/carma @department-of-veterans-affairs/vfs-10-10 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/caseflow @department-of-veterans-affairs/lighthouse-banana-peels @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/central_mail @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group @@ -1384,6 +1385,7 @@ spec/lib/bgs @department-of-veterans-affairs/benefits-dependents-management @dep spec/lib/bid @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/bip_claims @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/breakers @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group +spec/lib/burials @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/carma @department-of-veterans-affairs/vfs-10-10 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/caseflow @department-of-veterans-affairs/lighthouse-banana-peels @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/central_mail @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group diff --git a/app/controllers/v0/burial_claims_controller.rb b/app/controllers/v0/burial_claims_controller.rb index 5e3b70df986..132bddd4b01 100644 --- a/app/controllers/v0/burial_claims_controller.rb +++ b/app/controllers/v0/burial_claims_controller.rb @@ -1,52 +1,61 @@ # frozen_string_literal: true require 'pension_burial/tag_sentry' +require 'burials/monitor' module V0 class BurialClaimsController < ClaimsBaseController service_tag 'burial-application' def show - submission_attempt = determine_submission_attempt + claim = claim_class.find_by!(guid: params[:id]) + form_submission = claim&.form_submissions&.last + submission_attempt = form_submission&.form_submission_attempts&.last if submission_attempt state = submission_attempt.aasm_state == 'failure' ? 'failure' : 'success' render(json: { data: { attributes: { state: } } }) elsif central_mail_submission render json: CentralMailSubmissionSerializer.new(central_mail_submission) - else - Rails.logger.error("ActiveRecord::RecordNotFound: Claim submission not found for claim_id: #{params[:id]}") - render(json: { data: { attributes: { state: 'not found' } } }, status: :not_found) end + rescue ActiveRecord::RecordNotFound => e + monitor.track_show404(params[:id], current_user, e) + render(json: { data: { attributes: { state: 'not found' } } }, status: :not_found) rescue => e - Rails.logger.error(e.to_s) + monitor.track_show_error(params[:id], current_user, e) render(json: { data: { attributes: { state: 'error processing request' } } }, status: :unprocessable_entity) end def create PensionBurial::TagSentry.tag_sentry - claim = if Flipper.enabled?(:va_burial_v2) - # cannot parse a nil form, to pass unit tests do a check for form presence - form = filtered_params[:form] - claim_class.new(form:, formV2: form.present? ? JSON.parse(form)['formV2'] : nil) - else - claim_class.new(form: filtered_params[:form]) - end - - unless claim.save - StatsD.increment("#{stats_key}.failure") - Sentry.set_tags(team: 'benefits-memorial-1') # tag sentry logs with team name - Rails.logger.error('Burial claim was not saved', { error_messages: claim.errors, - user_uuid: current_user&.uuid, - in_progress_form_id: in_progress_form&.id }) - raise Common::Exceptions::ValidationErrors, claim - end + claim = create_claim + monitor.track_create_attempt(claim, current_user) + + track_claim_save_failure(claim) unless claim.save + # this method also calls claim.process_attachments! claim.submit_to_structured_data_services! Rails.logger.info "ClaimID=#{claim.confirmation_number} Form=#{claim.form_id}" + + 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 + 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 + + def create_claim + if Flipper.enabled?(:va_burial_v2) + form = filtered_params[:form] + claim_class.new(form:, formV2: form.present? ? JSON.parse(form)['formV2'] : nil) + else + claim_class.new(form: filtered_params[:form]) + end end def short_name @@ -59,12 +68,6 @@ def claim_class private - def determine_submission_attempt - claim = claim_class.find_by(guid: params[:id]) - form_submission = claim&.form_submissions&.last - form_submission&.form_submission_attempts&.last - end - def central_mail_submission CentralMailSubmission.joins(:central_mail_claim).find_by(saved_claims: { guid: params[:id] }) end @@ -72,5 +75,39 @@ def central_mail_submission def in_progress_form current_user ? InProgressForm.form_for_user(claim.form_id, current_user) : nil end + + def track_claim_save_failure(claim) + StatsD.increment("#{stats_key}.failure") + Sentry.set_tags(team: 'benefits-memorial-1') # tag sentry logs with team name + Rails.logger.error('Burial claim was not saved', { error_messages: claim.errors, + user_uuid: current_user&.uuid, + in_progress_form_id: in_progress_form&.id }) + log_validation_error_to_metadata(in_progress_form, claim) + raise Common::Exceptions::ValidationErrors, claim + 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 diff --git a/lib/burials/monitor.rb b/lib/burials/monitor.rb new file mode 100644 index 00000000000..66d1436b735 --- /dev/null +++ b/lib/burials/monitor.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +module Burials + ## + # Monitor functions for Rails logging and StatsD + # + class Monitor + CLAIM_STATS_KEY = 'api.burial_claim' + + ## + # 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) + Rails.logger.error('21P-530EZ submission not found', + { confirmation_number:, user_uuid: current_user&.uuid, message: e&.message }) + 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) + Rails.logger.error('21P-530EZ fetching submission failed', + { confirmation_number:, user_uuid: current_user&.uuid, message: e&.message }) + end + + ## + # log POST processing started + # @see BurialClaimsController + # + # @param claim [Pension::SavedClaim] + # @param current_user [User] + # + def track_create_attempt(claim, current_user) + StatsD.increment("#{CLAIM_STATS_KEY}.attempt") + Rails.logger.info('21P-530EZ submission to Sidekiq begun', + { confirmation_number: claim&.confirmation_number, user_uuid: current_user&.uuid }) + 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) + StatsD.increment("#{CLAIM_STATS_KEY}.failure") + Rails.logger.error('21P-530EZ submission to Sidekiq failed', + { confirmation_number: claim&.confirmation_number, user_uuid: current_user&.uuid, + in_progress_form_id: in_progress_form&.id, errors: claim&.errors&.errors, + message: e&.message }) + 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) + StatsD.increment("#{CLAIM_STATS_KEY}.success") + if claim.form_start_date + claim_duration = claim.created_at - claim.form_start_date + tags = ["form_id:#{claim.form_id}"] + StatsD.measure('saved_claim.time-to-file', claim_duration, tags:) + end + context = { + confirmation_number: claim&.confirmation_number, + user_uuid: current_user&.uuid, + in_progress_form_id: in_progress_form&.id + } + Rails.logger.info('21P-530EZ submission to Sidekiq success', context) + end + end +end diff --git a/modules/claims_api/lib/bgs_service/local_bgs.rb b/modules/claims_api/lib/bgs_service/local_bgs.rb index ed982050e53..b29ea73d914 100644 --- a/modules/claims_api/lib/bgs_service/local_bgs.rb +++ b/modules/claims_api/lib/bgs_service/local_bgs.rb @@ -437,6 +437,10 @@ def jrn private + def builder_to_xml(builder) + builder.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION) + end + def transform_keys(hash_or_array) transformer = lambda do |object| case object diff --git a/modules/claims_api/lib/bgs_service/person_web_service.rb b/modules/claims_api/lib/bgs_service/person_web_service.rb index 1fde82af939..b108d4c70c9 100644 --- a/modules/claims_api/lib/bgs_service/person_web_service.rb +++ b/modules/claims_api/lib/bgs_service/person_web_service.rb @@ -7,15 +7,33 @@ def bean_name end def find_dependents_by_ptcpnt_id(id) - body = Nokogiri::XML::DocumentFragment.parse <<~EOXML - - EOXML - - { ptcpntId: id }.each do |k, v| - body.xpath("./*[local-name()='#{k}']").first.content = v + builder = Nokogiri::XML::Builder.new do + ptcpntId id end + body = builder_to_xml(builder) + make_request(endpoint: bean_name, action: 'findDependentsByPtcpntId', body:, key: 'DependentDTO') end + + # ptcpntIdA is the veteranʼs or dependentʼs participant id + # ptcpntIdB is the poaʼs participant id + def manage_ptcpnt_rlnshp_poa(options = {}) + builder = Nokogiri::XML::Builder.new do + PtcpntRlnshpDTO do + authznChangeClmantAddrsInd 'Y' if options[:authzn_change_clmant_addrs_ind].present? + authznPoaAccessInd 'Y' if options[:authzn_poa_access_ind].present? + compId do + ptcpntIdA options[:ptcpnt_id_a] + ptcpntIdB options[:ptcpnt_id_b] + end + statusTypeCd options[:status_type_cd] || 'CURR' + end + end + + body = builder_to_xml(builder) + + make_request(endpoint: bean_name, action: 'managePtcpntRlnshpPoa', body:, key: 'PtcpntRlnshpDTO') + end end end diff --git a/modules/claims_api/lib/claims_api/error/soap_error_handler.rb b/modules/claims_api/lib/claims_api/error/soap_error_handler.rb index aa5c0870722..88aa92e1da7 100644 --- a/modules/claims_api/lib/claims_api/error/soap_error_handler.rb +++ b/modules/claims_api/lib/claims_api/error/soap_error_handler.rb @@ -35,6 +35,10 @@ def get_exception raise ::Common::Exceptions::UnprocessableEntity.new( detail: 'Please try again after checking your input values.' ) + elsif participant_has_open_claims? + raise ::Common::Exceptions::ServiceError.new( + detail: 'PtcpntIdA has open claims.' + ) else soap_logging('500') raise ::Common::Exceptions::ServiceError.new(detail: 'An external server is experiencing difficulty.') @@ -64,6 +68,13 @@ def unprocessable? has_errors end + def participant_has_open_claims? + has_error = @fault_string.include?('PtcpntIdA has open claims') + soap_logging('422') if has_error + + has_error + end + def soap_logging(status_code) ClaimsApi::Logger.log('soap_error_handler', detail: "Returning #{status_code} via local_bgs & soap_error_handler, " \ diff --git a/modules/claims_api/spec/lib/claims_api/person_web_service_spec.rb b/modules/claims_api/spec/lib/claims_api/person_web_service_spec.rb index a04895d4839..a6e2e7ea249 100644 --- a/modules/claims_api/spec/lib/claims_api/person_web_service_spec.rb +++ b/modules/claims_api/spec/lib/claims_api/person_web_service_spec.rb @@ -6,35 +6,79 @@ describe ClaimsApi::PersonWebService do subject { described_class.new external_uid: 'xUid', external_key: 'xKey' } - describe '#find_dependents_by_ptcpnt_id with one dependent' do - it 'responds as expected' do - VCR.use_cassette('claims_api/bgs/person_web_service/find_dependents_by_ptcpnt_id_one_dependent') do - result = subject.find_dependents_by_ptcpnt_id(600052699) # rubocop:disable Style/NumericLiterals - expect(result).to be_a Hash - expect(result[:dependent][:first_nm]).to eq 'MARGIE' - expect(result[:number_of_records]).to eq '1' + describe '#find_dependents_by_ptcpnt_id' do + context 'with a participant that has one dependent' do + it 'responds with one dependent' do + VCR.use_cassette('claims_api/bgs/person_web_service/find_dependents_by_ptcpnt_id_one_dependent') do + result = subject.find_dependents_by_ptcpnt_id('600052699') + expect(result).to be_a Hash + expect(result[:dependent][:first_nm]).to eq 'MARGIE' + expect(result[:number_of_records]).to eq '1' + end end end - end - describe '#find_dependents_by_ptcpnt_id with two dependents' do - it 'responds as expected' do - VCR.use_cassette('claims_api/bgs/person_web_service/find_dependents_by_ptcpnt_id_two_dependents') do - result = subject.find_dependents_by_ptcpnt_id(600049324) # rubocop:disable Style/NumericLiterals - expect(result).to be_a Hash - expect(result[:dependent].size).to eq 2 - expect(result[:dependent].first[:first_nm]).to eq 'MARK' - expect(result[:number_of_records]).to eq '2' + context 'with a participant that has two dependents' do + it 'responds with two dependents' do + VCR.use_cassette('claims_api/bgs/person_web_service/find_dependents_by_ptcpnt_id_two_dependents') do + # integers should work too + result = subject.find_dependents_by_ptcpnt_id(600049324) # rubocop:disable Style/NumericLiterals + expect(result).to be_a Hash + expect(result[:dependent]).to be_an Array + expect(result[:dependent].size).to eq 2 + expect(result[:dependent].first[:first_nm]).to eq 'MARK' + expect(result[:number_of_records]).to eq '2' + end + end + end + + context 'with a participant that has no dependents' do + it 'responds as expected' do + VCR.use_cassette('claims_api/bgs/person_web_service/find_dependents_by_ptcpnt_id_no_dependents') do + result = subject.find_dependents_by_ptcpnt_id(123) + expect(result).to be_a Hash + expect(result[:number_of_records]).to eq '0' + end end end end - describe '#find_dependents_by_ptcpnt_id with no dependents' do - it 'responds as expected' do - VCR.use_cassette('claims_api/bgs/person_web_service/find_dependents_by_ptcpnt_id_no_dependents') do - result = subject.find_dependents_by_ptcpnt_id(123) - expect(result).to be_a Hash - expect(result[:number_of_records]).to eq '0' + describe '#manage_ptcpnt_rlnshp_poa' do + context 'when participant A (the veteran or dependent) has no open claims' do + let(:ptcpnt_id_a) { '601163580' } + let(:ptcpnt_id_b) { '46004' } + + it 'assigns the POA to the participant' do + VCR.use_cassette('claims_api/bgs/person_web_service/manage_ptcpnt_rlnshp_poa_no_open_claims') do + options = { + ptcpnt_id_a:, + ptcpnt_id_b: + } + result = subject.manage_ptcpnt_rlnshp_poa(options) + + expect(result).to be_a Hash + expect(result[:authzn_poa_access_ind]).to eq 'Y' + expect(result[:comp_id][:ptcpnt_id_a]).to eq ptcpnt_id_a + expect(result[:comp_id][:ptcpnt_id_b]).to eq ptcpnt_id_b + expect(result[:comp_id][:ptcpnt_rlnshp_type_nm]).to eq 'Power of Attorney For' + end + end + end + + context 'when participant A (the veteran or dependent) has open claims' do + it 'returns an error' do + VCR.use_cassette('claims_api/bgs/person_web_service/manage_ptcpnt_rlnshp_poa_with_open_claims') do + options = { + ptcpnt_id_a: '600052700', + ptcpnt_id_b: '46004' + } + + expect do + subject.manage_ptcpnt_rlnshp_poa(options) + end.to raise_error(Common::Exceptions::ServiceError) { |error| + expect(error.errors.first.detail).to eq 'PtcpntIdA has open claims.' + } + end end end end diff --git a/modules/mobile/app/controllers/mobile/v0/claims_and_appeals_controller.rb b/modules/mobile/app/controllers/mobile/v0/claims_and_appeals_controller.rb index 9f672583f14..b64bfe1738c 100644 --- a/modules/mobile/app/controllers/mobile/v0/claims_and_appeals_controller.rb +++ b/modules/mobile/app/controllers/mobile/v0/claims_and_appeals_controller.rb @@ -62,7 +62,15 @@ def get_claim def get_appeal appeal = evss_claims_proxy.get_appeal(params[:id]) - appeal = appeal_adapter.parse(appeal) if Flipper.enabled?(:mobile_appeal_model, @current_user) + begin + appeal = appeal_adapter.parse(appeal) if Flipper.enabled?(:mobile_appeal_model, @current_user) + rescue => e + PersonalInformationLog.create!( + data: { appeal:, error: e.message }, + error_class: 'MobileAppealModelValidationError' + ) + end + render json: Mobile::V0::AppealSerializer.new(appeal) end diff --git a/modules/mobile/app/models/mobile/v0/appeals/appeal.rb b/modules/mobile/app/models/mobile/v0/appeals/appeal.rb index fa45e241788..e88682f7004 100644 --- a/modules/mobile/app/models/mobile/v0/appeals/appeal.rb +++ b/modules/mobile/app/models/mobile/v0/appeals/appeal.rb @@ -5,6 +5,9 @@ module Mobile module V0 module Appeals + # This model is derived from the following docs: https://developer.va.gov/explore/api/appeals-status/docs?version=current + # We do not use the endpoint that these docs are for but instead share the same upstream service. + # The endpoint does not change the data in anyway so the docs should still be accurate. class Appeal < Common::Resource AOJ_TYPES = Types::String.enum( 'vba', @@ -28,6 +31,7 @@ class Appeal < Common::Resource 'medical', 'burial', 'bva', + 'fiduciary', 'other', 'multiple' ) @@ -43,7 +47,9 @@ class Appeal < Common::Resource 'decision_soon', 'blocked_by_vso', 'scheduled_dro_hearing', - 'dro_hearing_no_show' + 'dro_hearing_no_show', + 'evidentiary_period', + 'ama_post_decision' ) EVENT_TYPES = Types::String.enum( @@ -70,9 +76,19 @@ class Appeal < Common::Resource 'ramp_notice', 'transcript', 'remand_return', - 'dro_hearing_held', - 'dro_hearing_cancelled', - 'dro_hearing_no_show' + 'ama_nod', + 'docket_change', + 'distributed_to_vlj', + 'bva_decision_effectuation', + 'dta_decision', + 'sc_request', + 'sc_decision', + 'sc_other_close', + 'hlr_request', + 'hlr_decision', + 'hlr_dta_error', + 'hlr_other_close', + 'statutory_opt_in' ) LAST_ACTION_TYPES = Types::String.enum( @@ -106,26 +122,53 @@ class Appeal < Common::Resource 'other_close', 'remand_ssoc', 'remand', - 'merged' + 'merged', + 'evidentiary_period', + 'ama_remand', + 'post_bva_dta_decision', + 'bva_decision_effectuation', + 'sc_received', + 'sc_decision', + 'sc_closed', + 'hlr_received', + 'hlr_dta_error', + 'hlr_decision', + 'hlr_closed', + 'statutory_opt_in' + ) + + APPEAL_TYPES = Types::String.enum( + 'legacyAppeal', + 'appeal', + 'supplementalClaim', + 'higherLevelReview' ) attribute :id, Types::String attribute :appealIds, Types::Array.of(Types::String) + attribute :updated, Types::DateTime attribute :active, Types::Bool - attribute :alerts, Types::Array do - attribute :type, ALERT_TYPES - attribute :details, Types::Hash - end - attribute :aod, Types::Bool.optional + attribute :incompleteHistory, Types::Bool attribute :aoj, AOJ_TYPES + attribute :programArea, PROGRAM_AREA_TYPES attribute :description, Types::String - attribute :docket, Docket.optional - attribute :events, Types::Array do - attribute :type, EVENT_TYPES - attribute :date, Types::Date + attribute :type, APPEAL_TYPES + attribute :aod, Types::Bool.optional + attribute :location, LOCATION_TYPES + attribute :status do + attribute :type, STATUS_TYPES + attribute :details do + attribute? :lastSocDate, Types::Date + attribute? :certificationTimeliness, Types::Array.of(Integer) + attribute? :ssocTimeliness, Types::Array.of(Integer) + attribute? :decisionTimeliness, Types::Array.of(Integer) + attribute? :remandTimeliness, Types::Array.of(Integer) + attribute? :socTimeliness, Types::Array.of(Integer) + attribute? :remandSsocTimeliness, Types::Array.of(Integer) + attribute? :returnTimeliness, Types::Array.of(Integer) + end end - attribute :evidence, Types::Array.of(Evidence).optional - attribute :incompleteHistory, Types::Bool + attribute :docket, Docket.optional attribute :issues, Types::Array do attribute :active, Types::Bool attribute :lastAction, LAST_ACTION_TYPES.optional @@ -133,14 +176,15 @@ class Appeal < Common::Resource attribute :diagnosticCode, Types::String.optional attribute :date, Types::Date end - attribute :location, LOCATION_TYPES - attribute :programArea, PROGRAM_AREA_TYPES - attribute :status do - attribute :type, STATUS_TYPES + attribute :alerts, Types::Array do + attribute :type, ALERT_TYPES attribute :details, Types::Hash end - attribute :type, Types::String - attribute :updated, Types::DateTime + attribute :events, Types::Array do + attribute :type, EVENT_TYPES + attribute :date, Types::Date + end + attribute :evidence, Types::Array.of(Evidence).optional end end end diff --git a/modules/mobile/app/models/mobile/v0/appeals/status_detail.rb b/modules/mobile/app/models/mobile/v0/appeals/status_detail.rb new file mode 100644 index 00000000000..d027f9237ec --- /dev/null +++ b/modules/mobile/app/models/mobile/v0/appeals/status_detail.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'common/models/resource' + +module Mobile + module V0 + module Appeals + class StatusDetail < Common::Resource + attribute :lastSocDate, Types::Date.optional + attribute :certificationTimeliness, Types::Array.of(Integer).optional + attribute :ssocTimeliness, Types::Array.of(Integer).optional + attribute :decisionTimeliness, Types::Array.of(Integer).optional + attribute :remandTimeliness, Types::Array.of(Integer).optional + attribute :socTimeliness, Types::Array.of(Integer).optional + attribute :remandSsocTimeliness, Types::Array.of(Integer).optional + attribute :returnTimeliness, Types::Array.of(Integer).optional + end + end + end +end diff --git a/modules/mobile/docs/index.html b/modules/mobile/docs/index.html index bd3a64fc24d..8299ecb43bf 100755 --- a/modules/mobile/docs/index.html +++ b/modules/mobile/docs/index.html @@ -2256,7 +2256,7 @@

Request samples

Content type
application/json
{
  • "environment": "dev",
  • "buildNumber": "10",
  • "os": "android"
}

Response samples

Content type
application/json
{}

/v0/appeal/{id}

Returns info on all user's claims and appeals for mobile overview page

+

Request samples

Content type
application/json
{
  • "environment": "dev",
  • "buildNumber": "10",
  • "os": "android"
}

Response samples

Content type
application/json
{}

/v0/appeal/{id}

Returns info on all user's claims and appeals for mobile overview page. Should be identical to the following docs https://developer.va.gov/explore/api/appeals-status/docs?version=current

Authorizations:
Bearer
path Parameters
id
required
string

Appeal Id

header Parameters
X-Key-Inflection
string
Default: snake
Enum: "camel" "snake"

Allows the API to return camelCase keys rather than snake_case

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}