Skip to content

Commit

Permalink
Merge pull request #20354 from department-of-veterans-affairs/uat/APP…
Browse files Browse the repository at this point in the history
…EALS-28087

Eli/APPEALS-28088_APPEALS-28090 (#19726)
  • Loading branch information
mikefinneran authored Dec 27, 2023
2 parents e96ea61 + 4571ecf commit 5e5cfe0
Show file tree
Hide file tree
Showing 38 changed files with 2,886 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Makefile.example
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ reset-dbs: ## Resets Caseflow and ETL database schemas
seed-vbms-ext-claim: ## Seed only vbms_ext_claim
bundle exec rake db:seed:vbms_ext_claim

seed-ama-intake: ## Seeds scenarios for the AMA Intake API
bundle exec rake db:seed:ama_intake

seed-dbs: ## Seed all databases
bundle exec rake local:vacols:seed
bundle exec rake spec:setup_vacols
Expand Down
533 changes: 533 additions & 0 deletions app/controllers/api/docs/v3/ama_issues.yaml

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions app/controllers/api/docs/v3/docs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,14 @@ def decision_reviews
swagger = YAML.safe_load(File.read("app/controllers/api/docs/v3/decision_reviews.yaml"))
render json: swagger
end

def ama_issues
swagger = YAML.safe_load(File.read("app/controllers/api/docs/v3/ama_issues.yaml"))
render json: swagger
end

def vacols_issues
swagger = YAML.safe_load(File.read("app/controllers/api/docs/v3/vacols_issues.yaml"))
render json: swagger
end
end
268 changes: 268 additions & 0 deletions app/controllers/api/docs/v3/vacols_issues.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
openapi: 3.0.3
info:
title: VACOLS Issues
description: >+
The VACOLS Issues API allows you to interact with a veteran’s VACOLS Issues. This API provides all VACOLS Issues per Veteran File Number.
For more information on the Legacy Appeal process, including Legacy Issues, please see [this informative page on VA.gov](https://www.va.gov/decision-reviews/legacy-appeals/).
## Technical Summary
The VACOLS Issues API interacts with VA's internal system, called Caseflow, that manages all benefit appeals.
* The VACOLS API accepts the veteran file number identification that is supplied in the request header.
* The VACOLS Issue request will be validated to ensure the Veteran information matches VA records and that the appeal information sent is valid.
* Detailed error messages will be returned to help your application provide meaningful information to the Veteran attempting to make the VACOLS Issue request.
* The VACOLS Issues are paginated in the response. The page paramenter must be a integer greater than or equal to 1. 0 and negative numbers are defaulted to page 1.
## Authorization
API requests are authorized through a token, provided in an HTTP header.
Example _curl_ (assuming you're running Caseflow locally, and the `api_v3` feature toggle has been enabled):
```
curl -v -H 'Authorization: Token {{YourApiKeyHere}}'\
'http://localhost:3000/api/v3/issues/vacols/find_by_veteran/?page=2'
```
version: 3.0.0
servers:
- url: '{{CaseflowInstance}}/api/v3/issues/vacols'
paths:
/api/v3/issues/vacols/find_by_veteran:
get:
tags:
- VACOLS Issues
parameters:
- in: query
name: page
schema:
type: integer
description: The page of request issues for the supplied veteran. Positive greater than 0. 0 or negative numbers are defaulted to 1.
summary: Retrieve all VACOLS issues from Veteran.
description: >+
Will return a paginated response of VACOLS Issues for the Veteran.
responses:
'200':
description: 200 OK
content:
application/vnd.api+json:
examples:
veteran_returned_1_page:
value:
page: 1
total_number_of_pages: 1
total_vacols_issues_for_vet: 6
max_vacols_issues_per_page: 10
veteran_participant_id: '1826209'
veteran_file_number: '872958715'
vacols_issues:
- id: '2760964'
notice_of_disagreement_date: '2019-03-09T00:00:00.000Z'
legacy_appeal_status: Remand
legacy_appeal_soc_date: '2019-12-25T00:00:00.000Z'
legacy_appeal_ssoc_dates:
- '2023-01-31T00:00:00.000Z'
legacy_appeal_eligible_for_opt_in: false
legacy_appeal_eligible_for_soc_opt_in_with_exemption: true
vacols_id: '2760964'
vacols_sequence_id: 1
eligible_for_soc_opt_in: true
eligible_for_soc_opt_in_with_exemption: true
description: Service connection, pancreatitis
disposition: remanded
close_date: '2023-06-16T00:00:00.000Z'
note: Itaque adipisci aut ullam voluptas recusandae possimus facilis.
- id: LEGACYID
notice_of_disagreement_date: '2022-09-18T00:00:00.000Z'
legacy_appeal_status: Advance
legacy_appeal_soc_date: '2023-03-18T00:00:00.000Z'
legacy_appeal_ssoc_dates: []
legacy_appeal_eligible_for_opt_in: false
legacy_appeal_eligible_for_soc_opt_in_with_exemption: true
vacols_id: LEGACYID
vacols_sequence_id: 1
eligible_for_soc_opt_in: true
eligible_for_soc_opt_in_with_exemption: true
description: New and material evidence to reopen claim for service connection, ankylosing spondylitis
disposition: null
close_date: null
note: null
- id: LEGACYID
notice_of_disagreement_date: '2022-09-18T00:00:00.000Z'
legacy_appeal_status: Advance
legacy_appeal_soc_date: '2023-03-18T00:00:00.000Z'
legacy_appeal_ssoc_dates: []
legacy_appeal_eligible_for_opt_in: false
legacy_appeal_eligible_for_soc_opt_in_with_exemption: true
vacols_id: LEGACYID
vacols_sequence_id: 2
eligible_for_soc_opt_in: true
eligible_for_soc_opt_in_with_exemption: true
description: New and material evidence to reopen claim for service connection, spinal fusion
disposition: null
close_date: null
note: null
- id: LEGACYID
notice_of_disagreement_date: '2022-09-18T00:00:00.000Z'
legacy_appeal_status: Advance
legacy_appeal_soc_date: '2023-03-18T00:00:00.000Z'
legacy_appeal_ssoc_dates: []
legacy_appeal_eligible_for_opt_in: false
legacy_appeal_eligible_for_soc_opt_in_with_exemption: true
vacols_id: LEGACYID
vacols_sequence_id: 3
eligible_for_soc_opt_in: true
eligible_for_soc_opt_in_with_exemption: true
description: New and material evidence to reopen claim for service connection, degenerative arthritis of the spine
disposition: null
close_date: null
note: null
- id: LEGACYID
notice_of_disagreement_date: '2022-09-18T00:00:00.000Z'
legacy_appeal_status: Advance
legacy_appeal_soc_date: '2023-03-18T00:00:00.000Z'
legacy_appeal_ssoc_dates: []
legacy_appeal_eligible_for_opt_in: false
legacy_appeal_eligible_for_soc_opt_in_with_exemption: true
vacols_id: LEGACYID
vacols_sequence_id: 4
eligible_for_soc_opt_in: true
eligible_for_soc_opt_in_with_exemption: true
description: New and material evidence to reopen claim for service connection, intervertebral disc syndrome
disposition: null
close_date: null
note: null
- id: LEGACYID
notice_of_disagreement_date: '2022-09-18T00:00:00.000Z'
legacy_appeal_status: Advance
legacy_appeal_soc_date: '2023-03-18T00:00:00.000Z'
legacy_appeal_ssoc_dates: []
legacy_appeal_eligible_for_opt_in: false
legacy_appeal_eligible_for_soc_opt_in_with_exemption: true
vacols_id: LEGACYID
vacols_sequence_id: 5
eligible_for_soc_opt_in: true
eligible_for_soc_opt_in_with_exemption: true
description: New and material evidence to reopen claim for service connection, ankylosis of hip
disposition: null
close_date: null
note: null
'401':
description: 401 Unauthorized
content:
application/vnd.api+json:
examples:
invalid_api_key:
value:
status: unauthorized
missing_api_key:
value:
status: unauthorized
'404':
description: 404 Veteran not found
content:
application/vnd.api+json:
examples:
not_implemented:
value:
errors:
- status: 404
code: "veteran_not_found"
detail: "No Veteran found for the given identifier."
'500':
description: 500 Unexpected Error
content:
application/vnd.api+json:
examples:
not_implemented:
value:
errors:
- status: 500
code: "Unknown error occured"
detail: "Message: There was a server error. Use the error uuid to submit a support ticket: {id}"
'501':
description: 501 Not Implemented
content:
application/vnd.api+json:
examples:
not_implemented:
value:
-
status: 501
title: "Not Implemented"
detail: "This endpoint is not yet supported."
components:
schemas:
VeteranParticipantId:
type: string
Errors:
type: array
items:
type: object
properties:
status:
type: string
code:
type: string
title:
type: string
VacolsIssue:
description:Issues that are attached to a Legacy Appeal within VACOLS. There can be multiple VACOLS Issues attached to a Legacy Appeal. VACOLS Issues are eligible for AMA if they meet the Legacy Issue opt-in eligibility requirements
type: object
properties:
data:
type: object
properties:
id:
type: integer
description: "The unique identifier for an issue"
notice_of_disagreement_date:
type: datetime
description: "Receipt date of the appeal form. Used to determine which VACOLS issues are within the timeliness window to be appealed. Only VACOLS issues decided prior to the receipt date will show up as contestable issues."
legacy_appeal_status:
type: boolean
description: "Indicates the status of the Legacy Appeal."
legacy_appeal_soc_date:
type: datetime
description: "Date/Time Statement of the Case Issued"
legacy_appeal_ssoc_dates:
type: array
description: "Date/Time Supplemental Statement of the Cases Issued"
legacy_appeal_eligible_for_opt_in:
type: boolean
description: "Indicates whether a Legacy Appeal is eligible to withdraw matching issues from the Legacy process."
legacy_appeal_eligible_for_soc_opt_in_with_exemption:
type: boolean
description: "Indicates whether a Legacy Appeal is eligible to withdraw matching issues from the Legacy process due to an exemption."
vacols_id:
type: varchar
description: "The VACOLS ID (primary key) of the Legacy appeal that the VACOLS issue is part of."
vacols_sequence_id:
type: integer
description: "The sequence ID of the VACOLS issue on the legacy appeal. The vacols_id and vacols_sequence_id form a composite key to identify a specific VACOLS issue."
issue_eligible_for_soc_opt_in:
type: boolean
description: "Indicates whether a VACOLS Issue is eligible to withdraw matching issues from the Legacy process."
issue_eligible_for_soc_opt_in_with_exemption:
type: boolean
description: "Indicates whether a VACOLS Issue is eligible to withdraw matching issues from the Legacy process due to an exemption."
issue_close_date:
type: datetime
description: "The date the VACOLS issue received a disposition."
issue_description:
type: varchar
description: "The description for the VACOLS issue."
issue_disposition:
type: varchar
description: "The disposition for each issue on the Legacy appeal. There are fourteen dispositions in total: some controlled by BVA and others controlled by the field."
issue_note:
type: text
description: "Notes added to the VACOLS Issue. This may be used to capture handwritten notes on the form, New Material or other comments."
13 changes: 13 additions & 0 deletions app/controllers/api/v3/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ def status_from_errors(errors)
end
end

rescue_from StandardError do |error|
Raven.capture_exception(error, extra: raven_extra_context)

render json: {
"errors": [
"status": "500",
"title": "Unknown error occured",
"detail": "Message: There was a server error. "\
"Use the error uuid to submit a support ticket: #{Raven.last_event_id}"
]
}, status: :internal_server_error
end

protect_from_forgery with: :null_session

def render_errors(errors)
Expand Down
59 changes: 59 additions & 0 deletions app/controllers/api/v3/issues/ama/veterans_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

# :reek:InstanceVariableAssumption
class Api::V3::Issues::Ama::VeteransController < Api::V3::BaseController
include ApiV3FeatureToggleConcern

before_action do
api_released?(:api_v3_ama_issues)
end

def show
veteran = find_veteran
page = init_page
per_page = init_per
if veteran
MetricsService.record("Retrieving AMA Request Issues for Veteran: #{veteran.participant_id}",
service: "AMA Request Issue endpoint",
name: "VeteransController.show") do
render_request_issues(Api::V3::Issues::Ama::VbmsAmaDtoBuilder.new(veteran, page, per_page).hash_response)
end
end
end

private

def init_page
page = ActiveRecord::Base.sanitize_sql(params[:page].to_i) if params[:page]
# Disallow page(0) or negative. Page(0) == page(1) in kaminari. This is to avoid confusion.
if page.nil? || page <= 0
page = 1
end
page
end

# :reek:FeatureEnvy
def init_per
per = ActiveRecord::Base.sanitize_sql(params[:per_page].to_i) if params[:per_page]
if per.nil? || per <= 0 || per > RequestIssue::DEFAULT_UPPER_BOUND_PER_PAGE
per = [RequestIssue.default_per_page, RequestIssue::DEFAULT_UPPER_BOUND_PER_PAGE].min
end
per
end

def find_veteran
begin
Veteran.find_by!(participant_id: params[:participant_id])
rescue ActiveRecord::RecordNotFound
render_errors(
status: 404,
code: :veteran_not_found,
title: "No Veteran found for the given identifier."
) && return
end
end

def render_request_issues(request_issues)
render json: request_issues.to_json
end
end
Loading

0 comments on commit 5e5cfe0

Please sign in to comment.