diff --git a/Gemfile b/Gemfile index 9eb64a26d..5ed2f2baa 100644 --- a/Gemfile +++ b/Gemfile @@ -52,6 +52,10 @@ gem "paper_trail-globalid" # Receive exceptions and configure alerts gem "sentry-rails" gem "sentry-ruby" +# Feature flagging +gem "flipper" +gem "flipper-active_record" +gem "flipper-ui" group :development, :test do # Check gems for known vulnerabilities diff --git a/Gemfile.lock b/Gemfile.lock index 384257f8c..a6b4496cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,7 +23,7 @@ GIT GIT remote: https://github.com/tagliala/activeadmin.git - revision: 871c6af8dec41f764a9f08bf04b5422971a23e32 + revision: 32995284eb1a54a570f025ab27b3bbca582c10ce branch: feature/railties-7 specs: activeadmin (2.10.1) @@ -111,8 +111,8 @@ GEM ruby2_keywords (>= 0.0.2, < 1.0) ast (2.4.2) aws-eventstream (1.2.0) - aws-partitions (1.562.0) - aws-sdk-core (3.127.0) + aws-partitions (1.563.0) + aws-sdk-core (3.128.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) @@ -173,6 +173,16 @@ GEM factory_bot (~> 6.2.0) railties (>= 5.0.0) ffi (1.15.5) + flipper (0.24.0) + flipper-active_record (0.24.0) + activerecord (>= 4.2, < 8) + flipper (~> 0.24.0) + flipper-ui (0.24.0) + erubi (>= 1.0.0, < 2.0.0) + flipper (~> 0.24.0) + rack (>= 1.4, < 3) + rack-protection (>= 1.5.3, < 2.2.0) + sanitize (< 7) formtastic (4.0.0) actionpack (>= 5.2.0) formtastic_i18n (0.7.0) @@ -292,6 +302,8 @@ GEM rack (2.2.3) rack-mini-profiler (2.3.4) rack (>= 1.2.0) + rack-protection (2.1.0) + rack rack-proxy (0.7.2) rack rack-test (1.1.0) @@ -377,7 +389,7 @@ GEM rubocop-rails (= 2.13.2) rubocop-rake (= 0.6.0) rubocop-rspec (= 2.7.0) - rubocop-performance (1.13.2) + rubocop-performance (1.13.3) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) rubocop-rails (2.13.2) @@ -391,6 +403,9 @@ GEM ruby-progressbar (1.11.0) ruby2_keywords (0.0.5) rubyzip (2.3.2) + sanitize (6.0.0) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) @@ -477,6 +492,9 @@ DEPENDENCIES devise! dotenv-rails factory_bot_rails + flipper + flipper-active_record + flipper-ui govuk-components govuk_design_system_formbuilder hotwire-rails diff --git a/app/views/case_logs/index.html.erb b/app/views/case_logs/index.html.erb index 02c7851ee..c54c9cd6f 100644 --- a/app/views/case_logs/index.html.erb +++ b/app/views/case_logs/index.html.erb @@ -6,7 +6,7 @@
<% if @case_logs.present? %> diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb new file mode 100644 index 000000000..7bd738858 --- /dev/null +++ b/config/initializers/flipper.rb @@ -0,0 +1,6 @@ +class CanAccessFlipperUI + def self.matches?(request) + current_user = request.env["warden"].user + current_user.present? && current_user.is_a?(AdminUser) + end +end diff --git a/config/routes.rb b/config/routes.rb index c9738f1e3..5652ab77c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,6 +26,10 @@ Rails.application.routes.draw do get "confirmations/reset", to: "auth/passwords#reset_confirmation" end + constraints CanAccessFlipperUI do + mount Flipper::UI.app(Flipper) => "/feature-flags" + end + get "/health", to: ->(_) { [204, {}, [nil]] } # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html diff --git a/db/migrate/20220307100023_create_flipper_tables.rb b/db/migrate/20220307100023_create_flipper_tables.rb new file mode 100644 index 000000000..1eae1b6d8 --- /dev/null +++ b/db/migrate/20220307100023_create_flipper_tables.rb @@ -0,0 +1,22 @@ +class CreateFlipperTables < ActiveRecord::Migration[7.0] + def self.up + create_table :flipper_features do |t| + t.string :key, null: false + t.timestamps null: false + end + add_index :flipper_features, :key, unique: true + + create_table :flipper_gates do |t| + t.string :feature_key, null: false + t.string :key, null: false + t.string :value + t.timestamps null: false + end + add_index :flipper_gates, %i[feature_key key value], unique: true + end + + def self.down + drop_table :flipper_gates + drop_table :flipper_features + end +end diff --git a/db/schema.rb b/db/schema.rb index dbebd8bcc..cd044fdbd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -45,32 +45,24 @@ ActiveRecord::Schema[7.0].define(version: 202202071123100) do t.datetime "updated_at", null: false t.string "tenant_code" t.integer "age1" - t.string "sex1" t.integer "ethnic" t.integer "national" t.integer "prevten" t.integer "ecstat1" t.integer "hhmemb" t.integer "age2" - t.string "sex2" t.integer "ecstat2" t.integer "age3" - t.string "sex3" t.integer "ecstat3" t.integer "age4" - t.string "sex4" t.integer "ecstat4" t.integer "age5" - t.string "sex5" t.integer "ecstat5" t.integer "age6" - t.string "sex6" t.integer "ecstat6" t.integer "age7" - t.string "sex7" t.integer "ecstat7" t.integer "age8" - t.string "sex8" t.integer "ecstat8" t.integer "homeless" t.integer "underoccupation_benefitcap" @@ -157,7 +149,6 @@ ActiveRecord::Schema[7.0].define(version: 202202071123100) do t.datetime "property_void_date", precision: nil t.bigint "owning_organisation_id" t.bigint "managing_organisation_id" - t.integer "renttype" t.integer "needstype" t.integer "lettype" t.integer "postcode_known" @@ -186,6 +177,26 @@ ActiveRecord::Schema[7.0].define(version: 202202071123100) do t.integer "previous_postcode_known" t.integer "previous_la_known" t.boolean "is_previous_la_inferred" + t.integer "letting_allocation_unknown" + t.integer "renttype" + t.string "sex1" + t.string "sex2" + t.string "sex3" + t.string "sex4" + t.string "sex5" + t.string "sex6" + t.string "sex7" + t.string "sex8" + t.integer "relat2" + t.integer "relat3" + t.integer "relat4" + t.integer "relat5" + t.integer "relat6" + t.integer "relat7" + t.integer "relat8" + t.integer "rent_type" + t.integer "has_benefits" + t.integer "renewal" t.integer "age1_known" t.integer "age2_known" t.integer "age3_known" @@ -196,7 +207,6 @@ ActiveRecord::Schema[7.0].define(version: 202202071123100) do t.integer "age8_known" t.integer "ethnic_group" t.string "ethnic_other" - t.integer "letting_allocation_unknown" t.integer "details_known_2" t.integer "details_known_3" t.integer "details_known_4" @@ -204,20 +214,26 @@ ActiveRecord::Schema[7.0].define(version: 202202071123100) do t.integer "details_known_6" t.integer "details_known_7" t.integer "details_known_8" - t.integer "relat2" - t.integer "relat3" - t.integer "relat4" - t.integer "relat5" - t.integer "relat6" - t.integer "relat7" - t.integer "relat8" - t.integer "rent_type" - t.integer "has_benefits" - t.integer "renewal" t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id" t.index ["owning_organisation_id"], name: "index_case_logs_on_owning_organisation_id" end + create_table "flipper_features", force: :cascade do |t| + t.string "key", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["key"], name: "index_flipper_features_on_key", unique: true + end + + create_table "flipper_gates", force: :cascade do |t| + t.string "feature_key", null: false + t.string "key", null: false + t.string "value" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["feature_key", "key", "value"], name: "index_flipper_gates_on_feature_key_and_key_and_value", unique: true + end + create_table "organisations", force: :cascade do |t| t.string "name" t.string "phone"