DEV Admin
What it is
A developer console reachable only with the DEV permission. Two screens:
-
Feature flags — inspect and switch flags at runtime, for both this application and EVA, and persist a flag set to global settings.
-
QA — an EVA-hosted QA surface.
Where it lives
| Concern | Location |
|---|---|
Routes |
|
Components |
|
Services |
|
Model |
|
Access
The /admin route is the only one in the application using an allow clause with
only:
{
path: 'admin',
canActivate: [RouteAccessResolver, FeatureFlagsGeneralGuard, NgxPermissionsGuard],
data: { permissions: { only: USER_PERMISSION.DEV, redirectTo: '/' } },
children: [ /* base → feature-flags | qa | ** → /admin/feature-flags */ ],
}
The sidebar mirrors it with ngxPermissionsOnly="userPermission.DEV". dev_support is
a separate permission and does *not grant access here.
The feature-flag console
AdminFeatureFlagsComponent shows one table per environment:
readonly ENV_CONFIG = [
{ env: FEATURE_FLAGS_ENV.IA, title: 'Internal Admin' },
{ env: FEATURE_FLAGS_ENV.EVA, title: 'Eva' },
];
Each row is a FeatureFlagEntity with three independent booleans:
| Column | Meaning |
|---|---|
|
The flag was baked into the bundle at build time
( |
|
The flag is present in the global-settings record for this environment
( |
|
The effective value right now for this browser session, after session overrides. |
Seeing all three side by side is the point: it makes "why is this flag on here but not for my colleague" answerable at a glance. The precedence rules are in feature flags.
What the console can do
| Operation | Effect |
|---|---|
Toggle a flag |
|
Clear session overrides |
|
Persist to global settings |
|
Refetch global settings |
|
Share a configuration |
The component injects |
|
"Persist to global settings" is not a developer-local action. It rewrites the environment-wide flag record and takes effect for other users on their next flag initialisation. On a shared environment, prefer session overrides. |
Driving EVA’s flags
The interesting part of this screen is that it manages another application’s flags.
AdminFeatureFlagsComponent embeds an EvaComponent (@ViewChild('appEva')) and
registers it with the services (setAppEva(component)). Then:
Internal Admin EVA (iframe)
───────────────────────────────────────────── ────────────────────────
FeatureFlagsEvaService.initFF(available, build)
├─ read FEATURE_FLAGS_EVA from global settings
├─ read session overrides (FeatureExecFlagsEva)
├─ recalculate exec set
└─ storeAndSend(flags)
└─ appEva.sendMessage().sendUpdatedConfig(evaFlags)
── GENERAL__CONFIG_RESPONSE ──► applies flag set
◄── GENERAL__CONFIG_REQUEST ── EVA asks for config
◄── GENERAL__CONFIG_UPDATE ── EVA reports its own flags
FEATURE_FLAGS__RESET ─────────────────────────► EVA clears overrides
FeatureFlagsEvaService keeps EVA’s session overrides under separate keys —
FeatureExecFlagsEva and FeatureExecFlagsLastChangeEva — so the two applications'
overrides never collide.
It also enforces an always-on list:
private readonly ALWAYS_ON_FLAGS = ['🎪'];
Any flag named in ALWAYS_ON_FLAGS is forced to true in storeAndSend and unioned
into the fetched global-settings set. The single entry is an emoji — a deliberate
sentinel that EVA recognises and that cannot collide with a real flag name.
CommunicationService.featureFlagsFromEva$ is the inbound channel for EVA’s own
available-flag list, so the console can render EVA’s rows without hardcoding them.
The QA screen
AdminQaComponent is minimal — a component with a single @ViewChild('appEva') and a
template embedding EVA. Like the underwriting tracker, the content is EVA’s; this route
exists to host it behind the DEV permission. See
underwriting tracker for the same pattern.
Non-production console output
Separately from this screen, FeatureFlagsGeneralGuard prints the resolved flag table
to the browser console on the first guarded navigation when
environment.production is false:
[Feature Flags] Current Functionality Status:
SUPPLIER_ACCOUNT_HEALTH: Enabled
TASKS_MID_VER_SIMPLE_QUERY: Disabled
…
It is printed once per page load (guarded by a displayed flag). That is often faster
than opening /admin/feature-flags.
Other developer affordances
| Tool | Detail |
|---|---|
Redux DevTools |
|
Store debugger |
|
Request ring buffer |
|
Error-handling playground |
|
Version banner |
|
VPN tester |
|
Gotchas
| Issue | Detail |
|---|---|
|
Two similar-looking permissions; only |
Persisting affects everyone |
|
Session vs global storage |
Session overrides live in |
The emoji flag is real |
|
|
|
The |
|