Feature flag catalogue

The vocabulary is src/app/shared/feature-flags/feature-flags.const.ts. Fourteen flags. Mechanics — the three layers, their precedence and the four application methods — are in feature flags.

Catalogue

Flag Gates Checked in

SUPPLIER_ACCOUNT_HEALTH

Amazon account-health data on the supplier header, and the health tab.

suppliers/supplier/supplier-box-header/supplier-box-header-old/supplier-box-header.component.ts (isEnabled)

TASKS_MID_VER_SIMPLE_QUERY

A simpler task query/transition path in the task list and counters.

crm-tools/tasks/task-list/task-list/transition/task-list-transition.component.ts, shared/task-count-badge/task-count-badge.component.ts

UNDERWRITING_TRACKER

The UW Tracker sidebar item, and an underwriting-tracker link on the marketplace form.

shared/sidenav/sidenav-menu/sidenav-menu.component.html, marketplaces/marketplace/marketplace.component.html (both *appEnabledByFeatureFlag)

BANK_CATEGORIES

The bank transactions categories underwriting tab (ExternalReports.BANK_CATEGORIES, PL-BT).

suppliers/supplier/supplier-underwriting/supplier-underwriting.component.ts

EVA_ONBOARDING_SUMMARY

The EVA-rendered onboarding summary instead of the Angular one.

suppliers/supplier/supplier-onboarding/supplier-onboarding-details/supplier-onboarding-details.component.ts

ACCESS_ONBOARDING_PREDICTIONS

The onboarding ML-prediction underwriting tab (BR-AC-ON).

supplier-underwriting.component.ts

ACCESS_DAILY_PREDICTIONS

The daily ML-prediction underwriting tab (BR-AC-DL).

supplier-underwriting.component.ts

TWO_FA

Supplier two-factor management on the General tab.

suppliers/supplier/supplier-general/supplier-general.component.html (*appEnabledByFeatureFlag)

UNDERWRITING_CHECK_TOOLS_BEFORE_APPROVING

Requires UW tool results before an underwriting approval is allowed.

suppliers/supplier/supplier-underwriting/underwriting-initial/underwriting-initial-footer/underwriting-initial-footer.component.ts

PYB_DOCUMENTS

Routes document handling to the pybDocumentsApiUrl backend. The most widely checked flag.

shared/apps-document/apps-document.service.ts, crm-tools/files/file-upload/file-upload.component.ts, crm-tools/comments/comment-list/comment-list.component.ts, crm-tools/shared/item-with-attachment.component.ts, crm-tools/shared/b2b-preview/…, suppliers/supplier/kyc-documentation/kyc-documentation.component.ts

EVA_SUPPLIER_MENU

The EVA-rendered supplier header/menu.

suppliers/supplier/supplier-box-header/eva/supplier-box-header-eva.component.ts

CHECK_VPN

Starts VpnTesterService — a 30-second OPTIONS probe that toasts when off-VPN.

src/app/app.component.ts (in the constructor)

DELETE_SUPPLIER

Supplier account deletion on the General tab.

suppliers/supplier/supplier-general/supplier-general.component.html (*appEnabledByFeatureFlag)

CARD_MANAGEMENT_AIRWALLEX

The Airwallex card programme — provider choice and card list.

suppliers/supplier/choose-card-type/choose-card-type.component.ts, suppliers/supplier/supplier-payment/supplier-payment-list/supplier-payment-list.component.ts

Route-level flag gating

Only two routes use FeatureFlagGuard (which redirects to /404 when the flag is off), and both take the flag from route data:

Route Guard

/suppliers/:supplierKey/new-underwriting

canLoad/canActivate: [FeatureFlagGuard]

/suppliers/:supplierKey/underwriting/documentation

canLoad/canActivate: [FeatureFlagGuard]

Every other flag hides UI without blocking the route. FeatureFlagsGeneralGuard — which is on nearly every route — only initialises flags and always resolves true. So a flag-hidden feature’s URL usually still renders. The UNDERWRITING_TRACKER menu item disappears but /underwriting/tracker still loads the EVA frame.

Flags checked outside the enum

Two related mechanisms use flag-shaped strings that are not FEATURE_FLAGS members:

String Detail

'🎪'

FeatureFlagsEvaService.ALWAYS_ON_FLAGS — an emoji sentinel forced to true for EVA and unioned into EVA’s fetched flag set. Intentional. See DEV Admin.

NEW_SEARCH_ENGINE

Exported from search-engine.service.ts as a flag name, but the check is short-circuited to if (1 === 1). Dead.

Storage keys

Key Layer

environment.featureFlags

Build. Comma-separated, no spaces. Empty in both .cfg templates.

Global setting FEATURE_FLAGS_IA

Environment-wide, config_value = { flags: 'A,B,C', lastChange: <ms> }.

Global setting FEATURE_FLAGS_EVA

Same, for EVA.

sessionStorage['FeatureExecFlags']

Per-tab overrides for this app, as [{ FLAG: boolean }, …].

sessionStorage['FeatureExecFlagsLastChange']

Override timestamp; compared against the global setting’s lastChange.

sessionStorage['FeatureExecFlagsEva'] / …LastChangeEva

The EVA equivalents.

Precedence reminder

exec = globalSettings                       ← seeds the set (NOT build flags)
     + session overrides (true)             ← only if newer than the setting's lastChange
     − session overrides (false)

isEnabled() reads build flags + session storage, and is only correct after initFF() has run — which FeatureFlagsGeneralGuard does on every guarded navigation.

Consequences that cause confusion:

  • A flag in the build but absent from FEATURE_FLAGS_IA resolves to off.

  • Saving to global settings invalidates everyone’s session overrides.

  • A flag typo in the environment string is silent — the cast to FEATURE_FLAGS[] is unchecked.

  • A leading comma (',A,B') clears the whole list.

Full analysis: feature flags.

Managing flags

/admin/feature-flags (needs DEV) shows one table per environment (IA, EVA) with three independent columns per flag — build, globalSettings, exec — and can toggle a session override, clear overrides, persist the set to global settings, or share a configuration by URL.

In non-production the resolved table is printed to the console once per page load by FeatureFlagsGeneralGuard.

See DEV Admin.

Adding a flag

  1. Add the member to FEATURE_FLAGS in feature-flags.const.ts.

  2. Apply it — isEnabled, *appEnabledByFeatureFlag, or FeatureFlagGuard with data.enabledByFeatureFlag.

  3. If it gates a menu item, wrap the item and decide whether the route should also be blocked.

  4. Enable it per environment at /admin/feature-flags → save to global settings.

  5. Add a row to this page.