department-of-veterans-affairs / va.gov-cms

Editor-centered management for Veteran-centered content.
https://prod.cms.va.gov
GNU General Public License v2.0
97 stars 69 forks source link

SPIKE: Become familiar with the facility locator data architecture #12990

Closed kmariepat-cityfriends closed 1 year ago

kmariepat-cityfriends commented 1 year ago

Background

Refer to this card: https://app.zenhub.com/workspaces/sitewide-facilities-639f5253e4b702a32376339e/issues/gh/department-of-veterans-affairs/va.gov-cms/12984

Acceptance Criteria

kmariepat-cityfriends commented 1 year ago

Dave C. brought up existing documentation that Lance completed within the facility locator GitHub repo https://github.com/department-of-veterans-affairs/va.gov-team/tree/master/products/facilities/facility-locator/engineering, this should be reviewed on the spike

jilladams commented 1 year ago

From 1:1 discussion with Max:

maxx1128 commented 1 year ago

I am catching up after last week and am adding relevant notes here as I go over the repo again.

The documentation points to controllers/v1/facilities/va_controller.rb for the facilities data endpoint, but the code that sorts out those responses is in lib/lighthouse/facilities/. These are the files that take in the responses from the Lighthouse Facilities API, sort out the properties into the right format, and add extra properties like min and max time for nearby ones. So I anticipate that most of the changes we make for the facility locator front-end would be here.

maxx1128 commented 1 year ago

Changes in the data attributes would likely be in app/serializers/lighthouse/facilities/facility_serializer.rb. This is the file in charge of formatting all the data into a predictable, functional format. Plus it defines the basic facility attributes, so changes in those would likely need to be reflected here too.

maxx1128 commented 1 year ago

lib/facilities/ files are ones that are not Ruby on Rails specific and are mostly static Facilities data or base configuration. It's unlikely these will ever be changed for our changes. But if there are ever vague or weird errors with the API requests, it's worth checking if the files here are related to them.

maxx1128 commented 1 year ago

For general Ruby knowledge that would help with navigating vets-api, I would recommend these Github documents on some Ruby fundamentals, Methods, and Structs. This is also a helpful introduction to object-oriented programming and Ruby.

For general Ruby on Rails knowledge sharing, I think the most important part of navigating the codebase and finding needed functionality is the folder structure. All the below files are in the app/ folder with a fast breakdown of each.

Info on other (custom) Rails patterns can be found here.

maxx1128 commented 1 year ago

This is a small overview of some of the other important folders in the Rails app, outside of the app/ folder.

jilladams commented 1 year ago

@maxx1128 https://github.com/department-of-veterans-affairs/va.gov-team/blob/master/products/facilities/facility-locator/engineering/README.md. FYI

And https://github.com/department-of-veterans-affairs/va.gov-team/tree/master/products/facilities/facility-locator/data

maxx1128 commented 1 year ago

From what I'm reading and re-reading in these documents, the basic data architecture and setup is mostly lining up with what I see in the code. For a facility locator data request, the process basically goes like this:

I don't see the PPMS coming into play at any point in this process, which may be the one difference I see between the code and a few of the documents. But otherwise it looks accurate.

The data architecture of each piece of facility data is as follows:

# "access" is initially under the "wait_times" attribute
attribute :access, Object

attribute :active_status, String
attribute :address, Object
attribute :classification, String
attribute :detailed_services, Object
attribute :distance, Float
attribute :facility_type, String

# This is the first part of the "id" attribute, before the "_" symbol
attribute :facility_type_prefix, String

# "feedback" is initially under the "satisfaction" attribute
attribute :feedback, Object

attribute :hours, Object
attribute :id, String
attribute :lat, Float
attribute :long, Float
attribute :mobile, Boolean
attribute :name, String
attribute :operating_status, Object
attribute :operational_hours_special_instructions, String
attribute :phone, Object
attribute :services, Object
attribute :type, String

# This is the second part of the "id" attribute, after the "_" symbol
attribute :unique_id, String

attribute :visn, String
attribute :website, String

The attributes that are Object have nested attributes within them, but they're not specified within the code.

maxx1128 commented 1 year ago

I've been looking more into the PPMS code and it looks like it lines up with this documentation about the endpoints it hits. This is a dev-focused overview of what files are hit when making a PPMS API request.

  1. The request starts when it hits the controller modules/facilities_api/app/controllers/facilities_api/v1/ccp_controller.rb.
    • There's another at modules/mobile/app/controllers/mobile/v0/community_care_providers_controller.rb but that looks like it's no longer use since it's with the older API version.
    • The controller handles requests for these four types of facilities data: urgent care, provider, pharmacy, and specialities. This lines up with the documentation.
  2. All of the above four data requests go to modules/facilities_api/app/services/facilities_api/v1/ppms/client.rb. This is what starts the process of making the API request and returning it in workable data.
  3. In modules/facilities_api/app/services/facilities_api/v1/ppms/client.rb, there is a different method for each of the four request types. Each one references a different endpoint PPMS URL to get the needed data (listed as private methods in the class).
    • This service pulls in configuration data from modules/facilities_api/app/services/facilities_api/v1/ppms/configuration.rb, which has the code that makes the actual HTTP connection to the API endpoint in the connection method.
      • It uses the Faraday gem for making the request and getting the response
      • modules/facilities_api/app/services/facilities_api/v1/ppms/middleware/ppms_parser.rb parses the raw API response
    • This file holds details on the request parameters, like pagination, search radius, and the number of results.
  4. When the API response has been completed and initially parsed, it is then passed to modules/facilities_api/app/services/facilities_api/v1/ppms/response.rb. This file converts the response into a data model, which holds information on all the attributes each one has.
    • All of the four data types are passed to the same model file: modules/facilities_api/app/models/facilities_api/v1/ppms/provider.rb. The exception is again specialities, which instead uses modules/facilities_api/app/models/facilities_api/v1/ppms/specialty.rb. These data files are in charge of managing how the response data is handled by other Ruby code (data types, data defined through separate methods, cleaning up data, and see all the basic attributes). Information on PPMS data structures can be found in these two files.
    • This response file also does the actual pagination based on past parameters. This is with the will_paginate ruby gem, which is designed for these kind of ActiveRecord data objects.
      1. These ActiveRecord data objects then come back to modules/facilities_api/app/controllers/facilities_api/v1/ccp_controller.rb, finished and in a Ruby-friendly form. They are all piped through modules/facilities_api/app/serializers/facilities_api/v1/ppms/provider_serializer.rb - the exception is specialties, which go through modules/facilities_api/app/serializers/facilities_api/v1/ppms/specialty_serializer.rb. These convert the data into a JSON format, which is what is ultimately given to whoever is making the API request.
    • The serializer makes sure any nested objects in the data are converted to JSON properly. This also handles renaming them and saving values under multiple names. Additional information on PPMS data structures can be found in these two files.
maxx1128 commented 1 year ago

This is the data architecture for the different PPMS data types.

Urgent Care, Providers, and Pharmacies

# modules/facilities_api/app/serializers/facilities_api/v1/ppms/provider_serializer.rb

attribute :accNewPatients

attribute :address # the below four attributes are only included if they all exist. Otherwise it's only the address
    :street
    :city
    :state
    :zip

attribute :caresitePhone
attribute :email
attribute :fax
attribute :gender
attribute :lat, :latitude
attribute :long, :longitude
attribute :name
attribute :phone, :mainPhone
attribute :posCodes # if there are multiple, it only shows the first
attribute :prefContact, :contactMethod
attribute :uniqueId, :providerIdentifier

Specialties

# modules/facilities_api/app/serializers/facilities_api/v1/ppms/specialty_serializer.rb

attribute :specialityCode # is the unique ID
attribute :classification
attribute :grouping
attribute :name
attribute :specialization
attribute :specialityCode
attribute :specialityDescription
eselkin commented 1 year ago

Just some related info, to install currently on a mac from a fresh homebrew with new rvm

brew install shared-mime-info
# not full postgresql install, just the lib
brew install libpq 
# because libpq by itself links not in a normal location for gem/ruby
gem install pg -- --with-pg-config=/opt/homebrew/opt/libpq/bin/pg_config 
bundle install

You can run the system pretty easily with

make up

This startup starts redis/postgres DBs and the vets-api You have to do a

make build
or 
make rebuild

prior to make up

Can't currently get LIGHTHOUSE_API_KEY