Skip to content

Commit 8397f42

Browse files
committed
Add Flipper for feature flag management
1 parent c37c535 commit 8397f42

8 files changed

Lines changed: 68 additions & 0 deletions

File tree

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,7 @@ gem "vite_rails", "~> 3.0"
103103
gem "inertia_rails-contrib", "~> 0.5.2"
104104

105105
gem "countries", "~> 8.1"
106+
107+
gem "flipper", "~> 1.3"
108+
gem "flipper-active_record", "~> 1.3"
109+
gem "flipper-ui", "~> 1.3"

Gemfile.lock

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,18 @@ GEM
167167
ffi (1.17.3-arm64-darwin)
168168
ffi (1.17.3-x86_64-linux-gnu)
169169
ffi (1.17.3-x86_64-linux-musl)
170+
flipper (1.4.0)
171+
concurrent-ruby (< 2)
172+
flipper-active_record (1.4.0)
173+
activerecord (>= 4.2, < 9)
174+
flipper (~> 1.4.0)
175+
flipper-ui (1.4.0)
176+
erubi (>= 1.0.0, < 2.0.0)
177+
flipper (~> 1.4.0)
178+
rack (>= 1.4, < 4)
179+
rack-protection (>= 1.5.3, < 5.0.0)
180+
rack-session (>= 1.0.2, < 3.0.0)
181+
sanitize (< 8)
170182
fugit (1.12.1)
171183
et-orbi (~> 1.4)
172184
raabro (~> 1.4)
@@ -324,6 +336,10 @@ GEM
324336
rack (3.2.4)
325337
rack-attack (6.8.0)
326338
rack (>= 1.0, < 4)
339+
rack-protection (4.2.1)
340+
base64 (>= 0.1.0)
341+
logger (>= 1.6.0)
342+
rack (>= 3.0.0, < 4)
327343
rack-proxy (0.7.7)
328344
rack
329345
rack-session (2.1.1)
@@ -414,6 +430,9 @@ GEM
414430
logger
415431
rubyzip (3.2.2)
416432
safely_block (0.5.0)
433+
sanitize (7.0.0)
434+
crass (~> 1.0.2)
435+
nokogiri (>= 1.16.8)
417436
securerandom (0.4.1)
418437
selenium-webdriver (4.40.0)
419438
base64 (~> 0.2)
@@ -536,6 +555,9 @@ DEPENDENCIES
536555
debug
537556
dotenv-rails
538557
faraday (~> 2.13)
558+
flipper (~> 1.3)
559+
flipper-active_record (~> 1.3)
560+
flipper-ui (~> 1.3)
539561
geocoder
540562
image_processing (~> 1.2)
541563
inertia_rails (~> 3.10)

app/controllers/application_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class ApplicationController < ActionController::Base
3838
inertia_share sign_out_path: -> { signout_path }
3939
inertia_share trial_session_path: -> { trial_session_path }
4040
inertia_share rsvp_path: -> { rsvp_path }
41+
inertia_share features: -> { # Feature flags for the frontend
42+
next {} unless current_user && !current_user.trial?
43+
{ collaborators: Flipper.enabled?(:collaborators, current_user) }
44+
}
4145
inertia_share has_unread_mail: -> { # Drives the envelope badge on the path page
4246
next false unless current_user && !current_user.trial?
4347
MailMessage.visible_to(current_user)
@@ -66,6 +70,11 @@ def track_page_view
6670
end
6771
end
6872

73+
def collaborators_enabled?
74+
current_user && Flipper.enabled?(:collaborators, current_user)
75+
end
76+
helper_method :collaborators_enabled? # Available in views/Inertia props
77+
6978
def user_not_authorized
7079
flash[:alert] = "You are not authorized to perform this action."
7180
redirect_back(fallback_location: root_path)

app/frontend/types/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export interface User {
1313

1414
export type FlashData = Record<string, string>
1515

16+
export interface Features {
17+
collaborators?: boolean
18+
}
19+
1620
export interface SharedProps {
1721
auth: { user: User | null }
1822
flash: FlashData

app/models/user.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
class User < ApplicationRecord
3333
include Discardable
3434
include PgSearch::Model
35+
include Flipper::Identifier # Enables per-user feature flags via Flipper
3536

3637
has_paper_trail
3738

config/initializers/flipper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
require "flipper/adapters/active_record"
2+
3+
Flipper.configure do |config|
4+
config.adapter { Flipper::Adapters::ActiveRecord.new }
5+
end

config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118

119119
constraints Constraints::AdminConstraint.new do
120120
mount MissionControl::Jobs::Engine, at: "/jobs"
121+
mount Flipper::UI.app(Flipper), at: "/flipper" # Feature flag dashboard — admin-only
121122

122123
namespace :admin do
123124
resources :projects, only: [ :index, :show ]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class CreateFlipperTables < ActiveRecord::Migration[8.1]
2+
def up
3+
create_table :flipper_features do |t|
4+
t.string :key, null: false
5+
t.timestamps null: false
6+
end
7+
add_index :flipper_features, :key, unique: true
8+
9+
create_table :flipper_gates do |t|
10+
t.string :feature_key, null: false
11+
t.string :key, null: false
12+
t.text :value
13+
t.timestamps null: false
14+
end
15+
add_index :flipper_gates, [ :feature_key, :key, :value ], unique: true, length: { value: 255 }
16+
end
17+
18+
def down
19+
drop_table :flipper_gates
20+
drop_table :flipper_features
21+
end
22+
end

0 commit comments

Comments
 (0)