Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter PoA index endpoint for pending/completed (#98714) #20081

Conversation

pixiitech
Copy link
Contributor

Summary

  • This work is behind a feature toggle (flipper): YES
  • Description Allow sending of status=Pending or status=Completed param to the power_of_attorney_requests endpoint to filter the list
  • (If bug, how to reproduce) feature
  • (What is the solution, why is this the solution?) Forward And Filter By Status In POA Request List Endpoint va.gov-team#98714
  • (Which team do you work for, does your team own the maintenance of this component?) ART, yes
  • (If introducing a flipper, what is the success criteria being targeted?) ??

Related issue(s)

Testing done

  • New code is covered by unit tests

  • Describe what the old behavior was prior to the change
    power_of_attorney_requests endpoint would return a list of all PoA request without filtering capability

  • Describe the steps required to verify your changes are working as expected. Exclusively stating 'Specs run' is NOT acceptable as appropriate testing
    Run rails accredited_representative_portal:seed in development
    accessing the power_of_attorney_requests endpoint with a logged in user with the ?status=Pending should yield 12 PoA requests
    accessing the power_of_attorney_requests endpoint with a logged in user with the ?status=Completed should yield 111 PoA requests

  • If this work is behind a flipper:

    • Tests need to be written for both the flipper on and flipper off scenarios. Docs.
    • What is the testing plan for rolling out the feature?
    • ?

Screenshots

Note: Optional

What areas of the site does it impact?

(Describe what parts of the site are impacted andifcode touched other areas)
Accredited Representative Portal

Acceptance criteria

  • I fixed|updated|added unit tests and integration tests for each feature (if applicable).
  • No error nor warning in the console.
  • Events are being sent to the appropriate logging solution
  • Documentation has been updated (link to documentation)
  • No sensitive information (i.e. PII/credentials/internal URLs/etc.) is captured in logging, hardcoded, or specs
  • Feature/bug has a monitor built into Datadog (if applicable)
  • If app impacted requires authentication, did you login to a local build and verify all authenticated routes work as expected
  • I added a screenshot of the developed feature

Requested Feedback

(OPTIONAL)What should the reviewers know in addition to the above. Is there anything specific you wish the reviewer to assist with. Do you have any concerns with this PR, why?

ojbucao and others added 27 commits December 30, 2024 17:07
2 Removed obsolete columns: city_bidx, state_bidx, zipcode_bidx
3 Added new columns: claimant_city_ciphertext, claimant_city_bidx,
  claimant_state_code_ciphertext, claimant_state_code_bidx,
  claimant_zip_code_ciphertext, claimant_zip_code_bidx
4 Added a new index for claimant_city_bidx, claimant_state_code_bidx,
  and claimant_zip_code_bidx
5 Added claimant_type column to ar_power_of_attorney_requests
@ojbucao ojbucao self-requested a review January 6, 2025 17:39
@@ -19,6 +19,9 @@ module ClaimantTypes
class_name: 'PowerOfAttorneyRequestResolution',
inverse_of: :power_of_attorney_request

has_many :resolutions,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we adding this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that the left_joins and joins I used in the scopes below work properly with ActiveRecord

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I found a better way. Thanks

@pixiitech pixiitech force-pushed the art/98714/filter-poa-list branch from fb7a44b to 7cb8c4e Compare January 9, 2025 20:12
@pixiitech pixiitech changed the base branch from art/poa-requests/decisions to art/serializers/tweak January 9, 2025 20:12
Copy link
Contributor

@nihil2501 nihil2501 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but I mention some things to solidify the code.

Comment on lines +34 to +35
scope :pending, -> { left_joins(:resolution).where(resolution: { resolving_type: nil }) }
scope :completed, -> { joins(:resolution) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These scopes will be a useful starting point. I suggest that we change the names to resolved and unresolved instead. In the future, product has the idea that our "Pending" tab should include resolved POA requests for which the effect of the resolution is still processing. Concretely, an accepted POA request will undergo a background process with an upstream Lighthouse API that modifies another database in order to "establish" the POA relationship, thereby granting the representative access to Veteran-centric operations in other software (called VBMS–Veteran Benefits Management System).

Our API can still expose the "Pending" and "Completed" concepts, but the implementation will notably match up to different concepts–"resolved" and "unresolved", and we will thereby be very clear on how the implementation will have to change in work that follows on shortly after.

@@ -31,6 +31,9 @@ module ClaimantTypes

delegate :poa_code, to: :accredited_individual

scope :pending, -> { left_joins(:resolution).where(resolution: { resolving_type: nil }) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id: nil seems less mysterious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the linter suggested where.missing(:resolution) ... looks like this is new for 7.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the linter suggested where.missing(:resolution) ... looks like this is new for 7.1

Oh that's great.

return poa_request_scope if params[:status].blank?
return poa_request_scope.none unless %w[pending completed].include?(params[:status]&.downcase)

poa_request_scope.send(params[:status].downcase)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't couple user input to the code we call like this. Logically equivalent to what we want, but we should choose a more appropriate expression of that logic.

Comment on lines +41 to +42
return poa_request_scope if params[:status].blank?
return poa_request_scope.none unless %w[pending completed].include?(params[:status]&.downcase)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's encode that our API will be kind to 3 values: (absent, pending, and completed), and throw a 400 otherwise. Being really strict with our client will let us keep things tight as we develop. I think we should put this exception rendering behavior as a rescue_from in our somewhat-shared PowerOfAttorneyRequests controller concern, which is where we are currently collecting that behavior so we can make a more principled choice later.

Let's also map from this user input to how we update our relation explicitly. I think the explicit matching should be a case statement that builds on the relation we're building: so we'd start building our relation as rel = poa_request_scope at top of the controller action, then the case branches will have rel = rel.resolved or rel = rel.unresolved or raise BadRequest with some message that the rescue_from could make use of.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And by absent I don't mean the string "absent", I mean the absence of any value.

poa_requests = poa_request_scope.includes(includes).limit(100)
poa_requests = filtered_poa_requests.includes(includes).limit(100)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's inline everything into the controller action rather than have a function extracted. This let's us wait until there is a compelling motivation for indirection and so we don't need to first unwind an existing indirection to achieve another.

@ojbucao ojbucao force-pushed the art/serializers/tweak branch 4 times, most recently from fbe92d7 to 43cacea Compare January 16, 2025 21:38
@ojbucao ojbucao deleted the branch department-of-veterans-affairs:art/serializers/tweak January 16, 2025 22:21
@ojbucao ojbucao closed this Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants