alumni_lookup

Feature Flags Guide

This document describes our feature flag strategy for safely developing and deploying new features.


Why Feature Flags?

Feature flags allow us to:


When to Use Feature Flags

✅ Use Feature Flags For:

❌ Don’t Need Feature Flags For:


Implementation Pattern

1. Define the Flag

Add flags to environment configuration:

# config/environments/development.rb
config.x.features.champion_portal = true  # Enable for local dev

# config/environments/staging.rb
config.x.features.champion_portal = true  # Enable for testing

# config/environments/production.rb
config.x.features.champion_portal = false  # Disable until ready

2. Create a Helper Method

Add to ApplicationController for easy access:

# app/controllers/application_controller.rb
helper_method :feature_enabled?

def feature_enabled?(feature_name)
  Rails.application.config.x.features.send(feature_name)
rescue NoMethodError
  false
end

3. Use in Controllers

class AlumniNetwork::PortalController < AlumniNetwork::BaseController
  before_action :require_portal_access

  private

  def require_portal_access
    unless feature_enabled?(:champion_portal)
      redirect_to root_path, alert: "This feature is not yet available."
    end
  end
end

4. Use in Views

<% if feature_enabled?(:champion_portal) %>
  <%= link_to "My Portal", champions_portal_path %>
<% end %>

5. Use in Routes (Optional)

For completely hiding routes:

# config/routes.rb
if Rails.application.config.x.features.champion_portal
  namespace :alumni_network do
    resource :portal, only: [:show]
  end
end

⚠️ Note: Route-level flags require app restart. Controller-level checks are preferred for flexibility.


Current Feature Flags

Env-var flags (config.x.features, feature_enabled?)

Flag Description Dev Staging Production
champion_portal New Alumni Portal (replaces signup flow)

DB-backed portal flags (Phase 20, Cp::FeatureFlag, cp_feature_enabled?)

Staff-toggleable at /alumni_network/feature_flags (portal_admin) — instant, no deploy/restart. Govern the belmontalum.com portal only (nothing touches the alumnichampions.com signup). Flags hide champion-facing surfaces; all data, jobs, and Champion Admin management stay live, so a feature re-enables with no rebuild.

Flag (key) Gates Default: Dev/Staging Default: Prod
news Community news blocks, news index/detail, likes, news submission flow
photos Community album carousels, album index/detail
events Dashboard events sidebar, community upcoming-events, event index/detail, RSVP, event submission flow
champion_role Roles microsite + Champion Info, role cards, dashboard role ideas, role-quiz wizard actions, champion nudge, and role badges portal-wide
your_impact Your Impact dashboard sidebar card

Resolution order (Cp::FeatureFlag.enabled?(:news)): ENV["FEATURE_NEWS"] ("true"/"false") → cached DB enabled column → false. The ENV override is an emergency kill-switch; day-to-day toggling is via the admin UI.

Usage:

# Controller (Cp:: namespace)
before_action -> { require_feature!(:news) }, only: [:index, :show]  # OFF → redirect to dashboard

# View / controller
cp_feature_enabled?(:news)          # helper
Cp::FeatureFlag.enabled?(:news)     # model-level

Rows arrive via the migration data-insert (or db/seeds.rb for schema:load), enabled: !Rails.env.production?. Each environment has its own DB, so the boolean is naturally per-environment. Tests: fixtures test/fixtures/cp/feature_flags.yml (all on); disable one explicitly to exercise an OFF path.


Environment Variable Overrides

All feature flags support ENV variable overrides for quick enable/disable without deploying:

# Pattern used in all environments:
config.x.features.champion_portal = ENV.fetch('FEATURE_CHAMPION_PORTAL', '<default>') == 'true'

Quick Toggle Commands

# Enable on staging (instant, no deploy needed)
heroku config:set FEATURE_CHAMPION_PORTAL=true -a alumni-lookup-staging

# Enable on production
heroku config:set FEATURE_CHAMPION_PORTAL=true -a alumni-lookup

# Disable (emergency rollback)
heroku config:set FEATURE_CHAMPION_PORTAL=false -a alumni-lookup

# Check current value
heroku config:get FEATURE_CHAMPION_PORTAL -a alumni-lookup

# Remove override (use code default)
heroku config:unset FEATURE_CHAMPION_PORTAL -a alumni-lookup

Default Values by Environment

Environment Default Override With
Development true FEATURE_CHAMPION_PORTAL=false
Test true (in test setup)
Staging false FEATURE_CHAMPION_PORTAL=true
Production false FEATURE_CHAMPION_PORTAL=true

Feature Flag Lifecycle

  1. Create — Add flag (default OFF in production)
  2. Develop — Build feature behind flag
  3. Test — Enable in staging, verify
  4. Launch — Enable in production
  5. Cleanup — Remove flag and conditionals once stable (usually 1-2 weeks after launch)

Cleanup Checklist

When removing a feature flag:


Best Practices

  1. Keep flags short-lived — Remove within 2 weeks of full launch
  2. Name clearly — Use descriptive names like champion_portal, not new_feature
  3. Document in this file — Add to the Current Feature Flags table
  4. Test both states — Ensure app works with flag ON and OFF
  5. Don’t nest flags — Avoid if flag_a && flag_b complexity