From a5bf1864ec179439b1fb5e335b31e2840e6d0afa Mon Sep 17 00:00:00 2001 From: Matt Gardner Date: Wed, 12 Feb 2025 15:33:27 -0500 Subject: [PATCH] FFS-2336: First sketch of multi-provider search (#442) * First sketch of multi-provider search * Refactor Provider Search Service * Keyed by symbol * Basic test * Extract provider result into response objects * Add terraform configuration * Resolve conflicts * Lint infra --- app/.env | 1 + .../cbv/employer_searches_controller.rb | 15 +++---- .../models/response_objects/search_result.rb | 27 ++++++++++++ app/app/services/argyle_service.rb | 43 +++++++++++++++++++ app/app/services/provider_search_service.rb | 28 ++++++++++++ .../cbv/employer_searches/_employer.html.erb | 12 +++--- app/config/client-agency-config.yml | 6 +++ app/db/schema.rb | 2 +- app/lib/client_agency_config.rb | 2 + app/spec/lib/site_config_spec.rb | 6 ++- .../services/provider_search_service_spec.rb | 33 ++++++++++++++ .../env-config/environment-variables.tf | 23 +++++++++- 12 files changed, 178 insertions(+), 20 deletions(-) create mode 100644 app/app/models/response_objects/search_result.rb create mode 100644 app/app/services/argyle_service.rb create mode 100644 app/app/services/provider_search_service.rb create mode 100644 app/spec/services/provider_search_service_spec.rb diff --git a/app/.env b/app/.env index 8aeb4beda..2f0287d07 100644 --- a/app/.env +++ b/app/.env @@ -15,3 +15,4 @@ MA_WEEKLY_REPORT_RECIPIENTS=test@email.com ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=primary ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=deterministic ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=derivationsalt +SUPPORTED_PROVIDERS=pinwheel diff --git a/app/app/controllers/cbv/employer_searches_controller.rb b/app/app/controllers/cbv/employer_searches_controller.rb index c90041177..6943b3006 100644 --- a/app/app/controllers/cbv/employer_searches_controller.rb +++ b/app/app/controllers/cbv/employer_searches_controller.rb @@ -6,7 +6,7 @@ class Cbv::EmployerSearchesController < Cbv::BaseController def show @query = search_params[:query] - @employers = @query.blank? ? [] : fetch_employers(@query) + @employers = @query.blank? ? [] : provider_search(@query) @has_pinwheel_account = @cbv_flow.pinwheel_accounts.any? @selected_tab = search_params[:type] || "payroll" @@ -20,17 +20,12 @@ def show private - def search_params - params.slice(:query, :type) + def provider_search(query = "") + ProviderSearchService.new(@cbv_flow.client_agency_id).search(query) end - def fetch_employers(query = "") - request_params = { - q: query, - supported_jobs: [ "paystubs" ] - } - - pinwheel.fetch_items(request_params)["data"] + def search_params + params.slice(:query, :type) end def track_clicked_popular_payroll_providers_event diff --git a/app/app/models/response_objects/search_result.rb b/app/app/models/response_objects/search_result.rb new file mode 100644 index 000000000..6638e7046 --- /dev/null +++ b/app/app/models/response_objects/search_result.rb @@ -0,0 +1,27 @@ +module ResponseObjects + SearchResult = Struct.new(:provider_name, :provider_options, :name, :logo_url, keyword_init: true) do + def self.from_pinwheel(response_body) + new( + provider_name: :pinwheel, + provider_options: { + response_type: response_body["response_type"], + provider_id: response_body["id"] + }, + name: response_body["name"], + logo_url: response_body["logo_url"] + ) + end + + def self.from_argyle(response_body) + new( + provider_name: :argyle, + provider_options: { + response_type: response_body["kind"], + provider_id: response_body["id"] + }, + name: response_body["name"], + logo_url: response_body["logo_url"] + ) + end + end +end diff --git a/app/app/services/argyle_service.rb b/app/app/services/argyle_service.rb new file mode 100644 index 000000000..f582e5b99 --- /dev/null +++ b/app/app/services/argyle_service.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "faraday" + +class ArgyleService + ENVIRONMENTS = { + sandbox: { + base_url: "https://api-sandbox.argyle.com/v2", + api_key_id: ENV["ARGYLE_API_TOKEN_SANDBOX_ID"], + api_key_secret: ENV["ARGYLE_API_TOKEN_SANDBOX_SECRET"] + } + } + + def initialize(environment, api_key_id = nil, api_key_secret = nil) + @api_key_id = api_key_id || ENVIRONMENTS.fetch(environment.to_sym)[:api_key_id] + @api_key_secret = api_key_secret || ENVIRONMENTS.fetch(environment.to_sym)[:api_key_secret] + @environment = ENVIRONMENTS.fetch(environment.to_sym) { |env| raise KeyError.new("ArgyleService unknown environment: #{env}") } + + client_options = { + request: { + open_timeout: 5, + timeout: 5, + params_encoder: Faraday::FlatParamsEncoder + }, + url: @environment[:base_url] + } + @http = Faraday.new(client_options) do |conn| + conn.set_basic_auth @api_key_id, @api_key_secret + conn.response :raise_error + conn.response :json, content_type: "application/json" + conn.response :logger, + Rails.logger, + headers: true, + bodies: true, + log_level: :debug + end + end + + # Fetch all Argyle items + def items(query = nil) + @http.get("items", { q: query }).body + end +end diff --git a/app/app/services/provider_search_service.rb b/app/app/services/provider_search_service.rb new file mode 100644 index 000000000..a898ee106 --- /dev/null +++ b/app/app/services/provider_search_service.rb @@ -0,0 +1,28 @@ +class ProviderSearchService + SUPPORTED_PROVIDERS = (ENV["SUPPORTED_PROVIDERS"] || "pinwheel")&.split(",")&.map(&:to_sym) + + def initialize(client_agency_id) + @client_agency_config = site_config[client_agency_id] + end + + def search(query = "") + SUPPORTED_PROVIDERS.map do |provider| + case provider + when :pinwheel + PinwheelService.new(@client_agency_config.pinwheel_environment).fetch_items(q: query)["data"].map do |result| + ResponseObjects::SearchResult.from_pinwheel(result) + end + when :argyle + ArgyleService.new(@client_agency_config.argyle_environment).items(query)["results"].map do |result| + ResponseObjects::SearchResult.from_argyle(result) + end + end + end.flatten + end + + private + + def site_config + Rails.application.config.client_agencies + end +end diff --git a/app/app/views/cbv/employer_searches/_employer.html.erb b/app/app/views/cbv/employer_searches/_employer.html.erb index f21d5b7d1..70e0ae4fe 100644 --- a/app/app/views/cbv/employer_searches/_employer.html.erb +++ b/app/app/views/cbv/employer_searches/_employer.html.erb @@ -9,13 +9,13 @@
-

<%= employer["name"] %>

+

<%= employer.name %>