defmodule DaProductApp.FeatureFlags do @moduledoc """ Feature flag system for gradual migration and A/B testing. This module provides a centralized way to enable/disable features during development and production deployments, supporting the gradual migration strategy. """ @doc """ Check if a feature flag is enabled. Priority order: 1. Environment variables (FEATURE_=true/false) 2. Application config 3. Database settings (when implemented) 4. Default value """ def enabled?(flag_name, default \\ false) do flag_name |> to_string() |> String.upcase() |> check_feature_flag(default) end @doc """ Enable a feature flag programmatically. Useful for testing and dynamic feature control. """ def enable(flag_name) do Application.put_env(:da_product_app, :feature_flags, Keyword.put(get_feature_flags(), flag_name, true) ) end @doc """ Disable a feature flag programmatically. """ def disable(flag_name) do Application.put_env(:da_product_app, :feature_flags, Keyword.put(get_feature_flags(), flag_name, false) ) end @doc """ Get all currently configured feature flags. """ def list_flags do get_feature_flags() end # Available feature flags for our gradual migration @available_flags %{ # Data source flags use_database_settings: false, use_database_international_payments: false, use_database_settlements: false, # Performance flags use_redis_caching: false, enable_transaction_type_filtering: true, # Audit and logging flags enable_api_request_logging: true, enable_response_logging: true, enable_log_viewer: false, # Fallback and reliability flags enable_database_fallback: true, enable_file_logging_on_db_failure: true, # UI and monitoring flags show_real_time_metrics: false, enable_advanced_monitoring: false } @doc """ Get default configuration for all available flags. """ def default_flags, do: @available_flags # Private functions defp check_feature_flag(flag_name, default) do # 1. Check environment variable first case System.get_env("FEATURE_#{flag_name}") do "true" -> true "false" -> false nil -> # 2. Check application config case get_feature_flags()[String.to_atom(String.downcase(flag_name))] do nil -> default value -> value end _ -> default end end defp get_feature_flags do Application.get_env(:da_product_app, :feature_flags, []) end end