From 78666cf14fd609765463e85a9d36d9e32f2aec10 Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 8 Jan 2025 11:15:37 +0000 Subject: [PATCH 1/2] Add feature flag to toggle autocomplete This adds a feature flag to disable autocomplete in case of unforeseen problems by returning an empty set of completion results in the response. This is controlled by the env var `ENABLE_AUTOCOMPLETE`, and will allow us to consolidate the logic behind disabling autocomplete in a single place instead of having it scattered across several apps (as the component will not render completions if no results are returned). --- app/controllers/autocompletes_controller.rb | 8 +++++++- config/application.rb | 6 ++++++ spec/requests/autocomplete_request_spec.rb | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/controllers/autocompletes_controller.rb b/app/controllers/autocompletes_controller.rb index 156b6e4..21458fa 100644 --- a/app/controllers/autocompletes_controller.rb +++ b/app/controllers/autocompletes_controller.rb @@ -1,10 +1,16 @@ class AutocompletesController < ApplicationController def show - render json: DiscoveryEngine::Autocomplete::Complete.new(query).completion_result + render json: completion_result end private + def completion_result + return CompletionResult.new(suggestions: []) unless Rails.configuration.enable_autocomplete + + DiscoveryEngine::Autocomplete::Complete.new(query).completion_result + end + def query params[:q] end diff --git a/config/application.rb b/config/application.rb index 272479c..e08e72e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -40,5 +40,11 @@ class Application < Rails::Application ## currently only using a single instance (the Publishing "shared" Redis). If we ever need to ## use multiple Redis instances, this is the only place that needs updating. config.redlock_redis_instances = [config.redis_url] + + # Feature flags + def self.feature_flag(name, default: false) + ActiveModel::Type::Boolean.new.cast(ENV.fetch(name, default)) + end + config.enable_autocomplete = feature_flag("ENABLE_AUTOCOMPLETE", default: true) end end diff --git a/spec/requests/autocomplete_request_spec.rb b/spec/requests/autocomplete_request_spec.rb index ce6c0ee..1278233 100644 --- a/spec/requests/autocomplete_request_spec.rb +++ b/spec/requests/autocomplete_request_spec.rb @@ -17,4 +17,19 @@ }) end end + + context "when autocomplete is disabled through the feature flag" do + before do + allow(Rails.configuration).to receive(:enable_autocomplete).and_return(false) + end + + it "returns empty suggestions" do + get "/autocomplete.json?q=foo" + + expect(response).to have_http_status(:ok) + expect(JSON.parse(response.body)).to eq({ + "suggestions" => [], + }) + end + end end From cf044a3eef0990592ce44bee826d5153d1dc6ce4 Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Thu, 9 Jan 2025 12:12:48 +0000 Subject: [PATCH 2/2] Add/migrate autocomplete documentation (denylist, feature flag) --- docs/search_autocomplete.md | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 docs/search_autocomplete.md diff --git a/docs/search_autocomplete.md b/docs/search_autocomplete.md new file mode 100644 index 0000000..0ea2783 --- /dev/null +++ b/docs/search_autocomplete.md @@ -0,0 +1,56 @@ +# Search autocomplete +We use Vertex AI Search's [built-in autocomplete functionality][vais-ac] to provide our users with +helpful suggestions to complete their query as they type in search fields. + +Search API v2 provides an API to return suggestions, which the [`search_with_autocomplete` +component][component] in frontend rendering apps accesses through a [proxy endpoint][ff-proxy] on +Finder Frontend. Other internal clients and the GOV.UK app may access it directly or through an API +gateway. + +## Update denylist +We use a denylist to avoid the autocomplete returning suggestions that are not suitable or helpful. + +Updating this list currently requires a manual process until we complete the work to automate it: + +1. In a text editor create a new empty file, save this file as `denylist.jsonl` ([JSON Lines + format][jsonl]) +1. Access [the denylist spreadsheet][denylist] and apply the desired changes to the appropriate tab +1. Copy and paste the contents from the "denylist" column **from each of the several tabs** into + your created `denylist.jsonl` file + +Then for each GOV.UK environment of integration, staging and production: + +1. Log into [Google Cloud][gcp] and access the `Search API V2 ` project +1. Access "Cloud Storage" > "Buckets" and find the `search-api-v2-_vais_artifacts` + bucket +1. Upload the `denylist.jsonl` file to the bucket, replacing the existing file +1. Leave Google Cloud and open your terminal +1. [Log into][kube-auth] the appropriate environment for Kubernetes +1. Run the `rake autocomplete:update_denylist` [rake task][rake-task] for `search-api-v2` to import the file + +If there are problems updating the denylist we can consider [disabling the autocomplete +feature](#disable-search-autocomplete) temporarily to provide time to resolve the problem. + +## Disable search autocomplete +If poor suggestions are shown to users that cannot be mitigated through the denylist, or there is a +problem updating the denylist, or autocomplete needs to be turned off for another reason, the +`ENABLE_AUTOCOMPLETE` feature flag environment variable for Search API v2 can be turned off. + +This will cause an empty array of suggestions to be returned to all clients (web or otherwise). + +1. Open the appropriate `values-.yaml` file from GOV.UK Helm Charts, for example + [values-production.yaml][] +1. Set `ENABLE_AUTOCOMPLETE` in `extraEnv` to `false` +1. Open a PR to apply the change +1. Once merged, a new deployment will be created for Search API v2 and no suggestions will be + returned + +[component]: https://components.publishing.service.gov.uk/component-guide/search_with_autocomplete +[denylist]: https://docs.google.com/spreadsheets/d/1aA2JapqNt0nu-MiFraP7p9flSDvNQCm0QvSZi2Unw48 +[ff-proxy]: https://github.com/alphagov/finder-frontend/blob/main/app/controllers/api/autocompletes_controller.rb +[gcp]: https://docs.publishing.service.gov.uk/manual/google-cloud-platform-gcp.html#gcp-access +[jsonl]: https://jsonlines.org/ +[kube-auth]: https://docs.publishing.service.gov.uk/kubernetes/cheatsheet.html#prerequisites +[rake-task]: https://docs.publishing.service.gov.uk/manual/running-rake-tasks.html#run-a-rake-task-on-eks +[vais-ac]: https://cloud.google.com/generative-ai-app-builder/docs/configure-autocomplete +[values-production.yaml]: https://github.com/alphagov/govuk-helm-charts/blob/main/charts/app-config/values-production.yaml