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

Issue# 98709 & 98710 POA Request List and Detail endpoints #19967

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

ojbucao
Copy link
Contributor

@ojbucao ojbucao commented Dec 19, 2024

This PR implements the list and detail endpoints of POA Request API:

Serializer:
• Created PowerOfAttorneyRequestSerializer and PowerOfAttorneyRequestResolutionSerializer to format the JSON output in JSON:API standard.
• Includes flattened resolution details
Controller:
• Added PowerOfAttorneyRequestsController with index and show actions.
Specs:
• Added request specs to verify:
• GET /power_of_attorney_requests returns a list of requests.
• GET /power_of_attorney_requests/:id returns the details of a specific request.
• Added serializer specs to ensure accurate formatting of response data:

- Implement PowerOfAttorneyRequestSerializer to handle resolution attributes:
  - Includes `id`, `type`, `created_at`, `reason`, and conditional `creator_id`
- Ensure safe handling of nil values with safe navigation (`&.`) and `try`
- Add RSpec tests to validate:
  - Resolution serialization for decisions, expirations, and declinations
  - Handling of `reason` and `creator_id` conditionally
  - Nil resolution scenarios
- Implement `PowerOfAttorneyRequestSerializer` to standardize JSON:API output
- Add request specs for controller endpoints (`index` and `show`)
- Add serializer specs to ensure proper formatting of resolution details
- Normalize response keys for consistency in test expectations
Copy link

github-actions bot commented Dec 19, 2024

1 Warning
⚠️ This PR changes 223 LoC (not counting whitespace/newlines).

In order to ensure each PR receives the proper attention it deserves, we recommend not exceeding
200. Expect some delays getting reviews.

File Summary

Files

  • modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/power_of_attorney_requests_controller.rb (+6/-41)

  • modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_resolution_serializer.rb (+19/-0)

  • modules/accredited_representative_portal/app/serializers/accredited_representative_portal/power_of_attorney_request_serializer.rb (+15/-0)

  • modules/accredited_representative_portal/spec/factories/power_of_attorney_decision.rb (+6/-0)

  • modules/accredited_representative_portal/spec/factories/power_of_attorney_request.rb (+3/-0)

  • modules/accredited_representative_portal/spec/factories/power_of_attorney_request_resolution.rb (+12/-4)

  • modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec.rb (+16/-27)

  • modules/accredited_representative_portal/spec/serializers/accredited_representative_portal/power_of_attorney_request_resolution_serializer_spec.rb (+34/-0)

  • modules/accredited_representative_portal/spec/serializers/accredited_representative_portal/power_of_attorney_request_serializer_spec.rb (+40/-0)

    Note: We exclude files matching the following when considering PR size:

    *.csv, *.json, *.tsv, *.txt, *.md, Gemfile.lock, app/swagger, modules/mobile/docs, spec/fixtures/, spec/support/vcr_cassettes/, modules/mobile/spec/support/vcr_cassettes/, db/seeds, modules/vaos/app/docs, modules/meb_api/app/docs, modules/appeals_api/app/swagger/, *.bru, *.pdf
    

Big PRs are difficult to review, often become stale, and cause delays.

Generated by 🚫 Danger

@ojbucao ojbucao changed the title POA Request API List and Show endpoints Issue# 98709 & 98710 POA Request List and Detail endpoints Dec 19, 2024
@ojbucao ojbucao requested review from chumpy and nihil2501 December 19, 2024 20:53
@ojbucao ojbucao force-pushed the art/98710/mvp-poa-reqs-api-2 branch 2 times, most recently from ecf8aa3 to fe03d67 Compare December 19, 2024 20:57
…h specs

- Implement `PowerOfAttorneyRequestSerializer` to handle serialization of power of attorney requests, including nested resolution data.
- Implement `PowerOfAttorneyRequestResolutionSerializer` to serialize resolution details, accommodating various resolution subtypes.
- Add comprehensive specs for both serializers to ensure accurate and dynamic handling of attributes.
- Adjust model factories accordingly
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.

Some changes to serializer definitions and queries.

def index
render json: POA_REQUEST_LIST_MOCK_DATA
poa_requests = PowerOfAttorneyRequest.includes(:resolution)
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 add .limit(100) just in case.

def index
render json: POA_REQUEST_LIST_MOCK_DATA
poa_requests = PowerOfAttorneyRequest.includes(:resolution)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is where we want to includes the rest of the object graph to not have N+1 query like the original proof of concept spec shows. So maybe this becomes includes(resolution: :resolving)?

end

def show
render json: POA_REQUEST_ITEM_MOCK_DATA
poa_request = PowerOfAttorneyRequest.includes(:resolution).find(params[:id])
Copy link
Contributor

Choose a reason for hiding this comment

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

This is where we want to includes the rest of the object graph to not have N+1 query like the original proof of concept spec shows. So maybe this becomes includes(resolution: :resolving)?

Comment on lines +9 to +11
attribute :created_at do |object|
object.created_at.iso8601
end
Copy link
Contributor

Choose a reason for hiding this comment

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

How was this getting serialized without the custom attribute?

Comment on lines +13 to +19
attribute :resolution do |object|
next nil if object.resolution.blank?

AccreditedRepresentativePortal::PowerOfAttorneyRequestResolutionSerializer.new(
object.resolution
).serializable_hash[:data][:attributes]
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use a relationship serializer? In fact it looks like we want to follow their example here for polymorphism:

class MovieSerializer
  include JSONAPI::Serializer

  has_many :actors, serializer: Proc.new do |record, params|
    if record.comedian?
      ComedianSerializer
    elsif params[:use_drama_serializer]
      DramaSerializer
    else
      ActorSerializer
    end
  end
end

Copy link
Contributor Author

@ojbucao ojbucao Dec 21, 2024

Choose a reason for hiding this comment

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

We can't control the structure that way. The result isn't flat like how we want it to be (they get placed under "relationships"). And there doesn't seem to be a way to override the default serialization when using relationships.

# frozen_string_literal: true

module AccreditedRepresentativePortal
class PowerOfAttorneyRequestResolutionSerializer
Copy link
Contributor

Choose a reason for hiding this comment

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

Follow the library's guide for polymorphic relationship instead.

object.resolving.type
end

attribute :reason
Copy link
Contributor

Choose a reason for hiding this comment

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

Reason will only need to be serialized on a declination in the decision serializer variant.

Comment on lines +23 to +25
attribute :created_at do |object|
object.created_at.iso8601
end
Copy link
Contributor

Choose a reason for hiding this comment

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

How was this serializing without the custom attribute?

Comment on lines +9 to +11
attribute :type do |object|
object.resolving_type.demodulize.underscore.split('_').last
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Once we have the polymorphic variants, each of them can hardcode this rather than manipulate the name of the Ruby class. In the end we should get: "type": "decision" and "type": "expiration".

@va-vfs-bot va-vfs-bot temporarily deployed to art/98710/mvp-poa-reqs-api-2/main/main December 20, 2024 17:30 Inactive
…ved query performance

- Updated `includes` to reference `resolving` instead of just `resolution`
- Added a limit of 100 records in the `index` action to optimize data retrieval
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants