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

Al/appeals 45664 #23279

Open
wants to merge 21 commits into
base: feature/APPEALS-45267
Choose a base branch
from
Open

Al/appeals 45664 #23279

wants to merge 21 commits into from

Conversation

pamatyatake2
Copy link
Contributor

@pamatyatake2 pamatyatake2 commented Oct 18, 2024

Resolves APPEALS-45664

Description

Please explain the changes you made here.

  1. Added new saved_searches_controller.rb and its actions. index, show, delete and create.
  2. Added test for the controller -> saved_searches_controller_spec.rb
  3. Added Serializer for saved_search
  4. Added two scopes in model to get the data from the backend.
  5. added a method to validate if its a VHA_ADMIN
  6. Added template files for index and show.

Acceptance Criteria

  • Code compiles correctly
  • Handle saving of new saved search 
  • Handle deletion of saved search 
  • Validation to ensure user can only delete their own Saved Search, not other users'
  • Make index to return all Saved Searches 
  • Make action to return saved searches for a specific user 
  • Need validation to ensure User is a VHA admin

Testing Plan

In Ruby Console:

FactoryBot.create_list(:saved_search, 10)

user = User.find_by_css_id("VHAADMIN")
# use VHAADMIN as a user when getting the set-cookie from the browser or 
# change VHAADMIN to any VHA admin that you use
FactoryBot.create_list(:saved_search, 5, user: user)
  1. Go to Jira Issue/Test Plan Link or list them below
  2. You can use postman to test the functionality.
  3. login to postman, copy set-cookie from the browser and paste it in POSTMAN.
  4. access -> GET: localhost:3000/saved_searches.json -> this should return all the saved search for all user.
  5. GET: localhost:3000/saved_searches/:id -> this should only return single saved search based on the id.
  6. POST: localhost:3000/saved_searches/ -> this should create a new saved search
  7. DELETE: localhost:3000/saved_searches/:id. > Thi should delete a saved search for that user.

Tester can use Postman using this link with pre-saved URL endpoint criteria to ease help with testing.

In order to make an API call tester needs to capture _caseflow_session from the Chrome browser after logging in through the frontend with the type of user they want to test the endpoint with e.g vha admin
Screenshot_2024-05-08_16-37-49

  • For feature branches merging into main: Was this deployed to UAT?

Frontend

User Facing Changes

  • Screenshots of UI changes added to PR & Original Issue
BEFORE AFTER

Storybook Story

For Frontend (Presentation) Components

  • Add a Storybook file alongside the component file (e.g. create MyComponent.stories.js alongside MyComponent.jsx)
  • Give it a title that reflects the component's location within the overall Caseflow hierarchy
  • Write a separate story (within the same file) for each discrete variation of the component

Backend

Database Changes

Only for Schema Changes

  • Add typical timestamps (created_at, updated_at) for new tables
  • Update column comments; include a "PII" prefix to indicate definite or potential PII data content
  • Have your migration classes inherit from Caseflow::Migration, especially when adding indexes (use add_safe_index) (see Writing DB migrations)
  • Verify that migrate:rollback works as desired (change supported functions)
  • Perform query profiling (eyeball Rails log, check bullet and fasterer output)
  • For queries using raw sql was an explain plan run by System Team
  • Add appropriate indexes (especially for foreign keys, polymorphic columns, unique constraints, and Rails scopes)
  • Run make check-fks; add any missing foreign keys or add to config/initializers/immigrant.rb (see Record associations and Foreign Keys)
  • Add belongs_to for associations to enable the schema diagrams to be automatically updated
  • Document any non-obvious semantics or logic useful for interpreting database data at Caseflow Data Model and Dictionary

Integrations: Adding endpoints for external APIs

  • Check that Caseflow's external API code for the endpoint matches the code in the relevant integration repo
    • Request: Service name, method name, input field names
    • Response: Check expected data structure
    • Check that calls are wrapped in MetricService record block
  • Check that all configuration is coming from ENV variables
    • Listed all new ENV variables in description
    • Worked with or notified System Team that new ENV variables need to be set
  • Update Fakes
  • For feature branches: Was this tested in Caseflow UAT

Best practices

Code Documentation Updates

  • Add or update code comments at the top of the class, module, and/or component.

Tests

Test Coverage

Did you include any test coverage for your code? Check below:

  • RSpec
  • Jest
  • Other

Code Climate

Your code does not add any new code climate offenses? If so why?

  • No new code climate issues added

Monitoring, Logging, Auditing, Error, and Exception Handling Checklist

Monitoring

  • Are performance metrics (e.g., response time, throughput) being tracked?
  • Are key application components monitored (e.g., database, cache, queues)?
  • Is there a system in place for setting up alerts based on performance thresholds?

Logging

  • Are logs being produced at appropriate log levels (debug, info, warn, error, fatal)?
  • Are logs structured (e.g., using log tags) for easier querying and analysis?
  • Are sensitive data (e.g., passwords, tokens) redacted or omitted from logs?
  • Is log retention and rotation configured correctly?
  • Are logs being forwarded to a centralized logging system if needed?

Auditing

  • Are user actions being logged for audit purposes?
  • Are changes to critical data being tracked ?
  • Are logs being securely stored and protected from tampering or exposing protected data?

Error Handling

  • Are errors being caught and handled gracefully?
  • Are appropriate error messages being displayed to users?
  • Are critical errors being reported to an error tracking system (e.g., Sentry, ELK)?
  • Are unhandled exceptions being caught at the application level ?

Exception Handling

  • Are custom exceptions defined and used where appropriate?
  • Is exception handling consistent throughout the codebase?
  • Are exceptions logged with relevant context and stack trace information?
  • Are exceptions being grouped and categorized for easier analysis and resolution?

Copy link

codeclimate bot commented Oct 18, 2024

Code Climate has analyzed commit 010e3c8 and detected 0 issues on this pull request.

View more on Code Climate.

@pamatyatake2 pamatyatake2 added Stakeholder: VHA Functionality associated with Veterans Health Administration workflows/feature requests ruby Pull requests that update Ruby code ART: VHA Saved Search - Reassign cases to camo Team: Titan A development team for the VHA business line labels Oct 23, 2024
@almorbah almorbah marked this pull request as ready for review October 24, 2024 14:02
@TylerBroyles TylerBroyles changed the base branch from main to feature/APPEALS-45267 October 24, 2024 14:39
Copy link
Contributor

@TylerBroyles TylerBroyles 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. I left a lot of comments around around naming conventions and small things like that so if you have any questions let me know.

@@ -18,19 +18,19 @@ const SavedSearches = () => {

const ALL_TABS = [
{
key: 'my_saved_searches',
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't bother doing any minor tweaks to the javascript files in this PR that really only affect mocked data. Let's just keep it all backend.

Copy link
Contributor

Choose a reason for hiding this comment

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

@pamatyatake2 let revert this change here

app/controllers/saved_searches_controller.rb Outdated Show resolved Hide resolved
app/models/saved_search.rb Outdated Show resolved Hide resolved
app/models/saved_search.rb Outdated Show resolved Hide resolved
@@ -7,6 +7,10 @@ class SavedSearch < CaseflowRecord
validates :description, presence: true, length: { maximum: 1000 }
validate :saved_search_limit

scope :all_saved_searches, -> { order(created_at: :desc) }

scope :my_saved_searches, ->(user) { where(user_id: user).order(created_at: :desc) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Active record is smart enough to realize that user_id is a foreign key and automatically transform user -> user.id, but I think it's probably better to make it more explicit in the scope. You can also chain scopes and if you keep the other scope you should chain it here instead of repeating .order(created_at: :desc). This is also why I don't think the name makes much sense when you look at it written out like this.

Suggested change
scope :my_saved_searches, ->(user) { where(user_id: user).order(created_at: :desc) }
scope :my_saved_searches, ->(user) { where(user: user).all_saved_searches }

app/controllers/saved_searches_controller.rb Outdated Show resolved Hide resolved
app/controllers/saved_searches_controller.rb Outdated Show resolved Hide resolved
app/controllers/saved_searches_controller.rb Outdated Show resolved Hide resolved
app/views/saved_searches/index.html.erb Show resolved Hide resolved
app/controllers/saved_searches_controller.rb Outdated Show resolved Hide resolved
brandondorner
brandondorner previously approved these changes Oct 25, 2024
Copy link
Contributor

@TylerBroyles TylerBroyles 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 overall. I noticed a couple of small things around the index/show html methods and some cleanup that we might want to address.

@@ -7,6 +7,9 @@ class SavedSearch < CaseflowRecord
validates :description, presence: true, length: { maximum: 1000 }
validate :saved_search_limit

# Ex:- scope :active, -> {where(:active => true)}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Ex:- scope :active, -> {where(:active => true)}

attribute :userCssId do |object|
object.user.css_id
end
attribute :userFullName do |object|
Copy link
Contributor

Choose a reason for hiding this comment

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

These will error if there is no user. I would group them up as a user attribute. It would be similar to how the task serializer handles it's assigned to relationship. It's just an example so that the frontend redux store will be able to look for user attributes like this savedSearch.user.cssId

  # Example assigned_to from task serializer
  attribute :assigned_to do |object|
    assignee = object.try(:unscoped_assigned_to)

    {
      css_id: assignee.try(:css_id),
      full_name: assignee.try(:full_name),
      is_organization: assignee.is_a?(Organization),
      name: assignee.is_a?(Organization) ? assignee.name : assignee.css_id,
      status: assignee.try(:status),
      type: assignee.class.name,
      id: assignee.id
    }
  end

private

def organization
@organization ||= BusinessLine.find_by(url: params[:decision_review_business_line_slug])
Copy link
Contributor

Choose a reason for hiding this comment

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

The decision_review_business_line_slug is not included in any of your routes so it's not going to know what this :decision_review_business_line_slug param is. It would have to be using the :business_line_slug param from the routes.
Something like this might work

@organization ||= Organization.find_by(url: params[:business_line_slug] || params[:organization_slug])

app/views/saved_searches/index.html.erb Show resolved Hide resolved
app/views/saved_searches/show.html.erb Show resolved Hide resolved
# frozen_string_literal: true

describe SavedSearchesController, :postgres, type: :controller do
let(:user) { create(:user, :vha_admin_user, :with_saved_search_reports) }
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the :vha_admin_user trait already creates adds the user to the VhaBusienssLine so you probably don't have to add it later non_comp_org.add_user(user)

let(:non_comp_org) { VhaBusinessLine.singleton }

let(:default_user) { create(:user) }
let(:vha_business_line) { VhaBusinessLine.singleton }
Copy link
Contributor

Choose a reason for hiding this comment

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

vha_business_line and non_comp_org can probably be combined into one variable since they are doing the same thing.

}
end

context "VHA user creating saved search" do
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
context "VHA user creating saved search" do
context "VHA admin user creating saved search" do

end
end

context "VHA user saved search not exists" do
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
context "VHA user saved search not exists" do
context "VHA admin user saved search not exists" do

config/routes.rb Outdated
@@ -308,6 +308,7 @@
get '/remands(/*path)', to: redirect('/supplemental_claims/%{path}')

resources :decision_reviews, param: :business_line_slug do
resources :saved_searches, only: [:index, :create, :destroy, :show]
Copy link
Contributor

Choose a reason for hiding this comment

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

This still does not match the current SavedSearches page url which is /decision_reviews/business_line_slug/report/searches. This route would match /decision_reviews/business_line_slug/searches. Is that the intention?

Copy link
Contributor

@TylerBroyles TylerBroyles left a comment

Choose a reason for hiding this comment

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

I noticed one last thing, but that should be it.

class SavedSearchSerializer
include FastJsonapi::ObjectSerializer

attribute :name
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably also need to serialize the id since that will be what we are sending back to the backend when we are deleting a saved search.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ART: VHA ruby Pull requests that update Ruby code Saved Search - Reassign cases to camo Stakeholder: VHA Functionality associated with Veterans Health Administration workflows/feature requests Team: Titan A development team for the VHA business line
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants