diff --git a/docs/developer/adding-feature-flags.md b/docs/developer/adding-feature-flags.md index 99cede39e..dd97c7497 100644 --- a/docs/developer/adding-feature-flags.md +++ b/docs/developer/adding-feature-flags.md @@ -9,16 +9,12 @@ We use [django-waffle](https://waffle.readthedocs.io/en/stable/) for our feature 3. Click `Add waffle flag`. 4. Add the model as you would normally. Refer to waffle's documentation [regarding attributes](https://waffle.readthedocs.io/en/stable/types/flag.html#flag-attributes) for more information on them. -## Adding feature flags when migrations are ran -Given that we store waffle flags as a predefined list, this means that we need to create a new migration file when we want to add a set of feature flags programatically this way. Note that if `WAFFLE_CREATE_MISSING_FLAGS` is set to True, you may not need this step. - -Follow these steps to achieve this: -1. Navigate to `registrar/models/waffle_flag.py`. -2. Modify the `get_default_waffle_flags` and add the desired name of your feature flag to the `default_flags` array. -3. Navigate to `registrar/migrationdata`. -4. Copy the migration named `0091_create_waffle_flags_v01`. -5. Rename the copied migration to match the increment. For instance, if `0091_create_waffle_flags_v01` exists, you will rename your migration to `0091_create_waffle_flags_v02`. -6. Modify the migration dependency to match the last migration in the stack. +### Enabling the profile_feature flag +1. On the app, navigate to `\admin`. +2. Under models, click `Waffle flags`. +3. Click the `profile_feature` record. This should exist by default, if not - create one with that name. +4. (Important) Set the field `Everyone` to `Unknown`. This field overrides all other settings when set to anything else. +5. Configure the settings as you see fit. ## Using feature flags as boolean values Waffle [provides a boolean](https://waffle.readthedocs.io/en/stable/usage/views.html) called `flag_is_active` that you can use as you otherwise would a boolean. This boolean requires a request object and the flag name. diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 2df448d8c..ff56f24ea 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -325,7 +325,7 @@ SERVER_EMAIL = "root@get.gov" # region: Waffle feature flags-----------------------------------------------------------### # If Waffle encounters a reference to a flag that is not in the database, should Waffle create the flag? -WAFFLE_CREATE_MISSING_FLAGS = False +WAFFLE_CREATE_MISSING_FLAGS = True # The model that will be used to keep track of flags. Extends AbstractUserFlag. # Used to replace the default flag class (for customization purposes). diff --git a/src/registrar/migrations/0091_create_waffle_flags_v01.py b/src/registrar/migrations/0091_create_waffle_flags_v01.py deleted file mode 100644 index ca7fcb751..000000000 --- a/src/registrar/migrations/0091_create_waffle_flags_v01.py +++ /dev/null @@ -1,45 +0,0 @@ -# This migration creates default WaffleFlag objects for our DB. -# Whenever you add to the `create_waffle_flags` function, increment/copy this -# migration by one - -from django.db import migrations -from registrar.models import WaffleFlag -from typing import Any - - -# For linting: RunPython expects a function reference, -# so let's give it one -def create_flags(apps, schema_editor): - """ - Populates pre-existing flags we wish to associate. - Only generates a flag name and a note, but no other data is loaded at this point. - """ - - # This is a bit of a hack to get around "apps" not knowing what the concept of a constant is - default_flags = WaffleFlag.get_default_waffle_flags() - WaffleFlag.create_waffle_flags_for_migrations(apps, default_flags) - - -def delete_flags(apps, schema_editor): - """ - Deletes all prexisting flags. - Does not delete flags not defined in this scope (user generated). - """ - - # This is a bit of a hack to get around "apps" not knowing what the concept of a constant is - default_flags = WaffleFlag.get_default_waffle_flags() - WaffleFlag.delete_waffle_flags_for_migrations(apps, default_flags) - - -class Migration(migrations.Migration): - dependencies = [ - ("registrar", "0090_waffleflag"), - ] - - operations = [ - migrations.RunPython( - code=create_flags, - reverse_code=delete_flags, - atomic=True, - ), - ] diff --git a/src/registrar/models/waffle_flag.py b/src/registrar/models/waffle_flag.py index 6d2b3a9a8..d185c2a82 100644 --- a/src/registrar/models/waffle_flag.py +++ b/src/registrar/models/waffle_flag.py @@ -17,51 +17,3 @@ class WaffleFlag(AbstractUserFlag): verbose_name = "waffle flag" verbose_name_plural = "Waffle flags" - - @staticmethod - def get_default_waffle_flags(): - """ - Defines which waffle flags should be created at startup. - - Add to this function if you want to add another flag that is generated at startup. - When you do so, you will need to add a new instance of `0091_create_waffle_flags_v{version_number}` - in registrar/migrations for that change to update automatically on migrate. - """ - default_flags = [ - # flag_name, flag_note - ("profile_feature", "Used for profiles"), - ("dns_hosting_feature", "Used for dns hosting"), - ] - return default_flags - - @staticmethod - def create_waffle_flags_for_migrations(apps, default_waffle_flags): - """ - Creates a list of flags for our migrations. - """ - logger.info("Creating default waffle flags...") - WaffleFlag = apps.get_model("registrar", "WaffleFlag") - # Flags can be changed through django admin if necessary. - for flag_name, flag_note in default_waffle_flags: - try: - WaffleFlag.objects.update_or_create( - name=flag_name, - # Booleans like superusers or is_staff can be set here, if needed. - defaults={"note": flag_note}, - ) - except Exception as e: - logger.error(f"An error occurred when attempting to add or update flag {flag_name}: {e}") - - @staticmethod - def delete_waffle_flags_for_migrations(apps, default_waffle_flags): - """ - Delete a list of flags for our migrations (the reverse_code operation). - """ - logger.info("Deleting default waffle flags...") - WaffleFlag = apps.get_model("registrar", "WaffleFlag") - existing_flags = WaffleFlag.objects.filter(name__in=default_waffle_flags) - for flag in existing_flags: - try: - WaffleFlag.objects.get(name=flag.name).delete() - except Exception as e: - logger.error(f"An error occurred when attempting to delete flag {flag.name}: {e}")