diff --git a/modules/claims_api/app/controllers/claims_api/v1/forms/power_of_attorney_controller.rb b/modules/claims_api/app/controllers/claims_api/v1/forms/power_of_attorney_controller.rb index d270784112f..be5eab5b701 100644 --- a/modules/claims_api/app/controllers/claims_api/v1/forms/power_of_attorney_controller.rb +++ b/modules/claims_api/app/controllers/claims_api/v1/forms/power_of_attorney_controller.rb @@ -73,7 +73,7 @@ def submit_form_2122 # rubocop:disable Metrics/MethodLength end claims_v1_logging('poa_submit', message: "poa_submit complete, poa: #{power_of_attorney&.id}") - render json: ClaimsApi::PowerOfAttorneySerializer.new(power_of_attorney) + render json: ClaimsApi::V1::PowerOfAttorneySerializer.new(power_of_attorney) end # PUT to upload a wet-signed 2122 form. @@ -96,7 +96,7 @@ def upload # If upload is successful, then the PoaUpater job is also called to update the code in BGS. ClaimsApi::PoaVBMSUploadJob.perform_async(@power_of_attorney.id, 'put') - render json: ClaimsApi::PowerOfAttorneySerializer.new(@power_of_attorney) + render json: ClaimsApi::V1::PowerOfAttorneySerializer.new(@power_of_attorney) end # GET the current status of a previous POA change request. @@ -105,7 +105,7 @@ def upload def status find_poa_by_id - render json: ClaimsApi::PowerOfAttorneySerializer.new(@power_of_attorney) + render json: ClaimsApi::V1::PowerOfAttorneySerializer.new(@power_of_attorney) end # GET current POA for a Veteran. diff --git a/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb b/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb index 554c5f9ce2b..52df9cd2f87 100644 --- a/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb +++ b/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb @@ -37,7 +37,7 @@ def status ) end - serialized_response = ClaimsApi::PowerOfAttorneySerializer.new(poa).serializable_hash + serialized_response = ClaimsApi::V2::PowerOfAttorneySerializer.new(poa).serializable_hash serialized_response[:data][:type] = serialized_response[:data][:type].to_s.camelize(:lower) render json: serialized_response.deep_transform_keys! { |key| key.to_s.camelize(:lower).to_sym } end diff --git a/modules/claims_api/app/models/claims_api/power_of_attorney.rb b/modules/claims_api/app/models/claims_api/power_of_attorney.rb index b98830d3197..e14157d0ebe 100644 --- a/modules/claims_api/app/models/claims_api/power_of_attorney.rb +++ b/modules/claims_api/app/models/claims_api/power_of_attorney.rb @@ -69,6 +69,42 @@ def set_md5 self.md5 = Digest::MD5.hexdigest form_data.merge(headers).to_json end + def processes + @processes ||= ClaimsApi::Process.where(processable: self) + .in_order_of(:step_type, ClaimsApi::Process::VALID_POA_STEP_TYPES).to_a + end + + def steps + ClaimsApi::Process::VALID_POA_STEP_TYPES.each do |step_type| + unless processes.any? { |p| p.step_type == step_type } + index = ClaimsApi::Process::VALID_POA_STEP_TYPES.index(step_type) + processes.insert(index, ClaimsApi::Process.new(step_type:, step_status: 'NOT_STARTED', processable: self)) + end + end + + processes.map do |p| + { + type: p.step_type, + status: p.step_status, + completed_at: p.completed_at, + next_step: p.next_step + } + end + end + + def errors + processes.map do |p| + error_message = p.error_messages.last + next unless error_message + + { + title: error_message['title'], + detail: error_message['detail'], + code: p.step_type + } + end.compact + end + def uploader @uploader ||= ClaimsApi::PowerOfAttorneyUploader.new(id) end diff --git a/modules/claims_api/app/serializers/claims_api/power_of_attorney_serializer.rb b/modules/claims_api/app/serializers/claims_api/power_of_attorney_serializer.rb deleted file mode 100644 index af2728c8e1a..00000000000 --- a/modules/claims_api/app/serializers/claims_api/power_of_attorney_serializer.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module ClaimsApi - class PowerOfAttorneySerializer - include JSONAPI::Serializer - - set_type :claims_api_power_of_attorneys - set_id :id - set_key_transform :underscore - - attributes :date_request_accepted, :previous_poa - - attribute :representative do |object| - object.representative.deep_transform_keys!(&:underscore) - end - - # "Uploaded" is an internal-only status indicating that the POA PDF - # was uploaded to VBMS, but we did not make it to updating BGS. - # For external consistency, return as "Updated" - attribute :status do |object| - if object[:status] == ClaimsApi::PowerOfAttorney::UPLOADED - ClaimsApi::PowerOfAttorney::UPDATED - else - object[:status] - end - end - end -end diff --git a/modules/claims_api/app/serializers/claims_api/v1/power_of_attorney_serializer.rb b/modules/claims_api/app/serializers/claims_api/v1/power_of_attorney_serializer.rb new file mode 100644 index 00000000000..e79ad7d0644 --- /dev/null +++ b/modules/claims_api/app/serializers/claims_api/v1/power_of_attorney_serializer.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module ClaimsApi + module V1 + class PowerOfAttorneySerializer + include JSONAPI::Serializer + + set_type :claims_api_power_of_attorneys + set_id :id + set_key_transform :underscore + + attributes :date_request_accepted, :previous_poa + + attribute :representative do |object| + object.representative.deep_transform_keys!(&:underscore) + end + + # "Uploaded" is an internal-only status indicating that the POA PDF + # was uploaded to VBMS, but we did not make it to updating BGS. + # For external consistency, return as "Updated" + attribute :status do |object| + if object[:status] == ClaimsApi::PowerOfAttorney::UPLOADED + ClaimsApi::PowerOfAttorney::UPDATED + else + object[:status] + end + end + end + end +end diff --git a/modules/claims_api/app/serializers/claims_api/v2/power_of_attorney_serializer.rb b/modules/claims_api/app/serializers/claims_api/v2/power_of_attorney_serializer.rb new file mode 100644 index 00000000000..7a4a796ad39 --- /dev/null +++ b/modules/claims_api/app/serializers/claims_api/v2/power_of_attorney_serializer.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module ClaimsApi + module V2 + class PowerOfAttorneySerializer + include JSONAPI::Serializer + + set_type :claims_api_power_of_attorneys + set_id :id + set_key_transform :underscore + + attributes :created_at + + attribute :representative do |object| + object.representative.deep_transform_keys!(&:underscore) + end + + # "Uploaded" is an internal-only status indicating that the POA PDF + # was uploaded to VBMS, but we did not make it to updating BGS. + # For external consistency, return as "Updated" + attribute :status do |object| + if object[:status] == ClaimsApi::PowerOfAttorney::UPLOADED + ClaimsApi::PowerOfAttorney::UPDATED + else + object[:status] + end + end + + attribute :errors + attribute :steps + + private + + def created_at + object.date_request_accepted + end + end + end +end diff --git a/modules/claims_api/app/sidekiq/claims_api/poa_updater.rb b/modules/claims_api/app/sidekiq/claims_api/poa_updater.rb index 01a2f30a7d1..bde62aa7d2e 100644 --- a/modules/claims_api/app/sidekiq/claims_api/poa_updater.rb +++ b/modules/claims_api/app/sidekiq/claims_api/poa_updater.rb @@ -21,23 +21,23 @@ def perform(power_of_attorney_id, rep_id = nil) # rubocop:disable Metrics/Method if response[:return_code] == 'BMOD0001' # Clear out the error message if there were previous failures poa_form.vbms_error_message = nil if poa_form.vbms_error_message.present? + poa_form.save + process.update!(step_status: 'SUCCESS', error_messages: []) ClaimsApi::Logger.log('poa', poa_id: poa_form.id, detail: 'BIRLS Success') ClaimsApi::VANotifyAcceptedJob.perform_async(poa_form.id, rep_id) if vanotify?(poa_form.auth_headers, rep_id) ClaimsApi::PoaVBMSUpdater.perform_async(poa_form.id) - - process.update!(step_status: 'SUCCESS') else poa_form.status = ClaimsApi::PowerOfAttorney::ERRORED poa_form.vbms_error_message = "BGS Error: update_birls_record failed with code #{response[:return_code]}" + poa_form.save + process.update!(step_status: 'FAILED', + error_messages: [{ title: 'BGS Error', + detail: poa_form.vbms_error_message }]) ClaimsApi::Logger.log('poa', poa_id: poa_form.id, detail: 'BIRLS Failed', error: response[:return_code]) - - process.update!(step_status: 'FAILED') end - - poa_form.save end private diff --git a/modules/claims_api/app/sidekiq/claims_api/poa_vbms_updater.rb b/modules/claims_api/app/sidekiq/claims_api/poa_vbms_updater.rb index 65d80b67b15..c7c9d58e370 100644 --- a/modules/claims_api/app/sidekiq/claims_api/poa_vbms_updater.rb +++ b/modules/claims_api/app/sidekiq/claims_api/poa_vbms_updater.rb @@ -27,14 +27,15 @@ def perform(power_of_attorney_id) # rubocop:disable Metrics/MethodLength if response[:return_code] == 'GUIE50000' poa_form.status = ClaimsApi::PowerOfAttorney::UPDATED - process.update!(step_status: 'SUCCESS') + process.update!(step_status: 'SUCCESS', error_messages: []) poa_form.vbms_error_message = nil if poa_form.vbms_error_message.present? ClaimsApi::Logger.log('poa_vbms_updater', poa_id: power_of_attorney_id, detail: 'VBMS Success') else poa_form.status = ClaimsApi::PowerOfAttorney::ERRORED - process.update!(step_status: 'FAILED') poa_form.vbms_error_message = 'update_poa_access failed with code ' \ "#{response[:return_code]}: #{response[:return_message]}" + process.update!(step_status: 'FAILED', error_messages: [{ title: 'BGS Error', + detail: poa_form.vbms_error_message }]) ClaimsApi::Logger.log('poa_vbms_updater', poa_id: power_of_attorney_id, detail: 'VBMS Failed', @@ -44,9 +45,11 @@ def perform(power_of_attorney_id) # rubocop:disable Metrics/MethodLength poa_form.save rescue BGS::ShareError => e poa_form.status = ClaimsApi::PowerOfAttorney::ERRORED - process.update!(step_status: 'FAILED') poa_form.vbms_error_message = e.respond_to?(:message) ? e.message : 'BGS::ShareError' poa_form.save + process.update!(step_status: 'FAILED', + error_messages: [{ title: 'BGS Error', + detail: poa_form.vbms_error_message }]) ClaimsApi::Logger.log('poa', poa_id: poa_form.id, detail: 'BGS Error', error: e) end diff --git a/modules/claims_api/app/sidekiq/claims_api/v2/poa_form_builder_job.rb b/modules/claims_api/app/sidekiq/claims_api/v2/poa_form_builder_job.rb index 8d4bd77d7de..286bcda3e22 100644 --- a/modules/claims_api/app/sidekiq/claims_api/v2/poa_form_builder_job.rb +++ b/modules/claims_api/app/sidekiq/claims_api/v2/poa_form_builder_job.rb @@ -41,13 +41,11 @@ def perform(power_of_attorney_id, form_number, rep_id, action) # rubocop:disable else ClaimsApi::PoaUpdater.perform_async(power_of_attorney.id, rep_id) end - process.update!(step_status: 'SUCCESS') + process.update!(step_status: 'SUCCESS', error_messages: []) rescue VBMS::Unknown - rescue_vbms_error(power_of_attorney) - process.update!(step_status: 'FAILED') + rescue_vbms_error(power_of_attorney, process:) rescue Errno::ENOENT - rescue_file_not_found(power_of_attorney) - process.update!(step_status: 'FAILED') + rescue_file_not_found(power_of_attorney, process:) end private diff --git a/modules/claims_api/app/sidekiq/claims_api/va_notify_accepted_job.rb b/modules/claims_api/app/sidekiq/claims_api/va_notify_accepted_job.rb index ae9ec91b2ab..9138a13b549 100644 --- a/modules/claims_api/app/sidekiq/claims_api/va_notify_accepted_job.rb +++ b/modules/claims_api/app/sidekiq/claims_api/va_notify_accepted_job.rb @@ -19,11 +19,10 @@ def perform(poa_id, rep_id) poa_code_from_form('2122a', poa) res = send_representative_notification(poa, rep) end - process.update!(step_status: 'SUCCESS') + process.update!(step_status: 'SUCCESS', error_messages: []) schedule_follow_up_check(res.id) if res.present? rescue => e - process.update!(step_status: 'FAILED') - handle_failure(poa_id, e) + handle_failure(poa_id, e, process) end # 2122a @@ -38,9 +37,11 @@ def send_organization_notification(poa, org) private - def handle_failure(poa_id, error) + def handle_failure(poa_id, error, process) job_name = 'ClaimsApi::VANotifyAcceptedJob' msg = "VA Notify email notification failed to send for #{poa_id} with error #{error}" + process.update!(step_status: 'FAILED', error_messages: [{ title: 'VA Notify Error', + detail: msg }]) slack_alert_on_failure(job_name, msg) ClaimsApi::Logger.log( diff --git a/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json b/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json index d03ea1dd17a..1ddbbf1f9b0 100644 --- a/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json +++ b/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json @@ -14202,14 +14202,40 @@ "id": "c00bed9d-9e1c-4fcf-9159-8928d77a2359", "type": "claimsApiPowerOfAttorneys", "attributes": { - "dateRequestAccepted": "2025-01-22", - "previousPoa": null, + "createdAt": "2025-01-23T01:08:50.089Z", "representative": { "serviceOrganization": { "poaCode": "074" } }, - "status": "pending" + "status": "pending", + "errors": [], + "steps": [ + { + "type": "PDF_SUBMISSION", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": "POA_UPDATE" + }, + { + "type": "POA_UPDATE", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": "POA_ACCESS_UPDATE" + }, + { + "type": "POA_ACCESS_UPDATE", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": "CLAIMANT_NOTIFICATION" + }, + { + "type": "CLAIMANT_NOTIFICATION", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": null + } + ] } } }, @@ -14241,7 +14267,7 @@ "additionalProperties": false, "required": [ "status", - "dateRequestAccepted", + "createdAt", "representative" ], "properties": { @@ -14255,11 +14281,75 @@ "errored" ] }, - "dateRequestAccepted": { + "createdAt": { "type": "string", "description": "Date request was first accepted", "format": "date" }, + "errors": { + "type": "array", + "description": "Error details if applicable", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "detail": { + "type": "string" + }, + "code": { + "type": "string", + "enum": [ + "PDF_SUBMISSION", + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + } + } + } + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "PDF_SUBMISSION", + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + }, + "status": { + "type": "string", + "enum": [ + "NOT_STARTED", + "IN_PROGRESS", + "SUCCESS", + "FAILED" + ] + }, + "completedAt": { + "type": "string", + "format": "date" + }, + "nextStep": { + "type": "string", + "enum": [ + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + } + } + } + }, "representative": { "type": "object", "additionalProperties": false, @@ -14281,11 +14371,6 @@ } } } - }, - "previousPoa": { - "type": "string", - "nullable": true, - "description": "Current or Previous Power of Attorney Code submitted for Veteran" } } } diff --git a/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json b/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json index e03ff977473..2595147f2de 100644 --- a/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json +++ b/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json @@ -12197,14 +12197,40 @@ "id": "38b49aa2-1163-4b42-9bc1-331a42404117", "type": "claimsApiPowerOfAttorneys", "attributes": { - "dateRequestAccepted": "2024-12-16", - "previousPoa": null, + "createdAt": "2025-01-23T01:09:57.718Z", "representative": { "serviceOrganization": { "poaCode": "074" } }, - "status": "pending" + "status": "pending", + "errors": [], + "steps": [ + { + "type": "PDF_SUBMISSION", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": "POA_UPDATE" + }, + { + "type": "POA_UPDATE", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": "POA_ACCESS_UPDATE" + }, + { + "type": "POA_ACCESS_UPDATE", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": "CLAIMANT_NOTIFICATION" + }, + { + "type": "CLAIMANT_NOTIFICATION", + "status": "NOT_STARTED", + "completedAt": null, + "nextStep": null + } + ] } } }, @@ -12236,7 +12262,7 @@ "additionalProperties": false, "required": [ "status", - "dateRequestAccepted", + "createdAt", "representative" ], "properties": { @@ -12250,11 +12276,75 @@ "errored" ] }, - "dateRequestAccepted": { + "createdAt": { "type": "string", "description": "Date request was first accepted", "format": "date" }, + "errors": { + "type": "array", + "description": "Error details if applicable", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "detail": { + "type": "string" + }, + "code": { + "type": "string", + "enum": [ + "PDF_SUBMISSION", + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + } + } + } + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "PDF_SUBMISSION", + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + }, + "status": { + "type": "string", + "enum": [ + "NOT_STARTED", + "IN_PROGRESS", + "SUCCESS", + "FAILED" + ] + }, + "completedAt": { + "type": "string", + "format": "date" + }, + "nextStep": { + "type": "string", + "enum": [ + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + } + } + } + }, "representative": { "type": "object", "additionalProperties": false, @@ -12276,11 +12366,6 @@ } } } - }, - "previousPoa": { - "type": "string", - "nullable": true, - "description": "Current or Previous Power of Attorney Code submitted for Veteran" } } } diff --git a/modules/claims_api/lib/claims_api/poa_vbms_sidekiq.rb b/modules/claims_api/lib/claims_api/poa_vbms_sidekiq.rb index 416b0dfefff..26f79e4e162 100644 --- a/modules/claims_api/lib/claims_api/poa_vbms_sidekiq.rb +++ b/modules/claims_api/lib/claims_api/poa_vbms_sidekiq.rb @@ -21,16 +21,28 @@ def upload_to_vbms(power_of_attorney, path) ) end - def rescue_file_not_found(power_of_attorney) + def rescue_file_not_found(power_of_attorney, process: nil) + error_message = 'File could not be retrieved from AWS' + power_of_attorney.update( status: ClaimsApi::PowerOfAttorney::ERRORED, - vbms_error_message: 'File could not be retrieved from AWS' + vbms_error_message: error_message ) + if process.present? + process.update!(step_status: 'FAILED', + error_messages: [{ title: 'VBMS Error', + detail: error_message }]) + end end - def rescue_vbms_error(power_of_attorney) + def rescue_vbms_error(power_of_attorney, process: nil) power_of_attorney.vbms_upload_failure_count = power_of_attorney.vbms_upload_failure_count + 1 power_of_attorney.vbms_error_message = 'An unknown error has occurred when uploading document' + if process.present? + process.update!(step_status: 'FAILED', + error_messages: [{ title: 'VBMS Error', + detail: power_of_attorney.vbms_error_message }]) + end if power_of_attorney.vbms_upload_failure_count < 5 self.class.perform_in(30.minutes, power_of_attorney.id) else diff --git a/modules/claims_api/spec/serializers/power_of_attorney_serializer_spec.rb b/modules/claims_api/spec/serializers/power_of_attorney_serializer_spec.rb index e4f26c9a1f2..808698dd5a7 100644 --- a/modules/claims_api/spec/serializers/power_of_attorney_serializer_spec.rb +++ b/modules/claims_api/spec/serializers/power_of_attorney_serializer_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe ClaimsApi::PowerOfAttorneySerializer, type: :serializer do +describe ClaimsApi::V1::PowerOfAttorneySerializer, type: :serializer do include SerializerSpecHelper subject { serialize(poa_submission, serializer_class: described_class) } diff --git a/modules/claims_api/spec/sidekiq/va_notify_accepted_job_spec.rb b/modules/claims_api/spec/sidekiq/va_notify_accepted_job_spec.rb index af84032ffba..67f012b1070 100644 --- a/modules/claims_api/spec/sidekiq/va_notify_accepted_job_spec.rb +++ b/modules/claims_api/spec/sidekiq/va_notify_accepted_job_spec.rb @@ -193,14 +193,16 @@ describe 'Va Notify Failure' do context 'when an error occurs' do - it 'calls handle_failure and updates the process' do + it 'calls the slack alert and updates the process' do instance = described_class.new error = StandardError.new('Some error') allow(instance).to receive(:skip_notification_email?).and_return(false) allow(instance).to receive(:organization_filing?).with(rep_poa.form_data).and_raise(error) - expect(instance).to receive(:handle_failure).with(rep_poa.id, error) - instance.perform(rep_poa.id, va_notify_rep) + expect(instance).to receive(:slack_alert_on_failure) + expect do + instance.perform(rep_poa.id, va_notify_rep) + end.to raise_error(error) process = ClaimsApi::Process.find_by(processable: rep_poa, step_type: 'CLAIMANT_NOTIFICATION') expect(process.step_status).to eq('FAILED') end diff --git a/spec/support/schemas/claims_api/v2/veterans/power_of_attorney/status.json b/spec/support/schemas/claims_api/v2/veterans/power_of_attorney/status.json index 3362bbf2353..dce46277228 100644 --- a/spec/support/schemas/claims_api/v2/veterans/power_of_attorney/status.json +++ b/spec/support/schemas/claims_api/v2/veterans/power_of_attorney/status.json @@ -18,7 +18,7 @@ "attributes": { "type": "object", "additionalProperties": false, - "required": ["status", "dateRequestAccepted", "representative"], + "required": ["status", "createdAt", "representative"], "properties": { "status": { "type": "string", @@ -30,11 +30,76 @@ "errored" ] }, - "dateRequestAccepted": { + "createdAt": { "type": "string", "description": "Date request was first accepted", "format": "date" }, + "errors": { + "type": "array", + "description": "Error details if applicable", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "detail": { + "type": "string" + }, + "code": { + "type": "string", + "enum": [ + "PDF_SUBMISSION", + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + } + } + } + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "PDF_SUBMISSION", + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION" + ] + }, + "status": { + "type": "string", + "enum": [ + "NOT_STARTED", + "IN_PROGRESS", + "SUCCESS", + "FAILED" + ] + }, + "completedAt": { + "type": ["string", "null"], + "format": "date" + }, + "nextStep": { + "type": ["string", "null"], + "enum": [ + "POA_UPDATE", + "POA_ACCESS_UPDATE", + "CLAIMANT_NOTIFICATION", + null + ] + } + } + } + }, "representative": { "type": "object", "additionalProperties": false, @@ -52,11 +117,6 @@ } } } - }, - "previousPoa": { - "type": "string", - "nullable": true, - "description": "Current or Previous Power of Attorney Code submitted for Veteran" } } }