Ctrl K
ComunidadGuías…

docs/preview-feature-flags.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Feature flags in preview environments

For implementation standards, Console rollouts, and self-hosted ENV configuration,
start with [Adding and operating feature flags](feature-flags.md).

Preview environments (`LIGHTDASH_MODE=pr`) enable most feature flags by default
and expose an API for toggling them, so QA can validate recent features without
a redeploy.

## Defaults

`PREVIEW_ENABLED_FEATURE_FLAGS` (`packages/common/src/featureFlags/previewFeatureFlags.ts`)
is every flag in `FeatureFlags` and `CommercialFeatureFlags` minus a short
exclusion list. New flags are therefore on in previews by default; add an
exclusion, with a reason, when that isn't safe. Flags are excluded when they:

- block or degrade every page (trial block/warning),
- change query or compile semantics, so QA results would mislead,
- change the signup flow (`new-onboarding` also needs SMTP for its email OTP,
  and the register page evaluates it anonymously so no override can undo it),
- are off pending a security review, or are deprecated,
- derive their value from instance configuration (`ai-copilot`,
  `enable-timezone-support`) — these are left to their
  config handler so a preview never advertises an unconfigured backend. To test
  AI copilot in a preview, configure a provider (`AI_COPILOT_ENABLED` plus
  credentials) rather than forcing the flag. PR previews read
  `AI_COPILOT_ENABLED`, `AI_DEFAULT_PROVIDER`, `ANTHROPIC_API_KEY`,
  `GEMINI_API_KEY`, and `OPENAI_API_KEY` from the Rainbow stored secrets
  (`rainbow.toml` `[secrets]`), so storing those once provisions Ask AI in
  every preview; leave them unset and the copilot stays off.

Flags that only gate UI can still be enabled while their backend is
unconfigured (for example email whitelabel needs a Postmark token, data apps
need an app runtime). Those surfaces render but won't work end to end.

This is controlled by `LIGHTDASH_PREVIEW_FEATURE_FLAGS_ENABLED`, which defaults
to `true` in PR mode. Set it to `false` for production-like flag resolution.

Rainbow previews run in PR mode too: `rainbow.toml`'s `[env]` table sets
`LIGHTDASH_MODE=pr`, and `packages/backend`'s `dev` script defers to a mode
already present in the environment (it defaults to `development` only when
nothing is set, so local development is unchanged). The table also sets this
variable outright. Anything touching that table or the services needs the
Rainbow base image recompiled before it takes effect.

## Managing flags at runtime

The management endpoints require an organization admin and only work when
`LIGHTDASH_PREVIEW_FEATURE_FLAGS_ENABLED` resolves to true — elsewhere they
return 404. Overrides are stored per organization in `feature_flag_overrides`.

```bash
# List every flag with its resolved value
curl -H "Authorization: ApiKey $LDPAT" "$SITE_URL/api/v2/feature-flag"

# Turn a flag off (or on) for the organization
curl -X POST -H "Authorization: ApiKey $LDPAT" -H 'Content-Type: application/json' \
  -d '{"enabled": false}' "$SITE_URL/api/v2/feature-flag/enable-data-apps"

# Drop the override and fall back to the environment default
curl -X DELETE -H "Authorization: ApiKey $LDPAT" \
  "$SITE_URL/api/v2/feature-flag/enable-data-apps"
```

Unknown flag ids are rejected, so a typo can't silently create a dead override.

## Resolution order

`FeatureFlagModel.get()` resolves in this order:

1. `LIGHTDASH_ENABLE_FEATURE_FLAGS` and `LIGHTDASH_DISABLE_FEATURE_FLAGS`. When
   only disable contains the flag, it is off regardless of stored overrides.
   When enable contains it (including when both lists do), proceed to the
   preview override check below before returning on.
2. In preview environments, a stored override for the user or organization,
   consulted only for flags the environment forces on.
3. `PREVIEW_ENABLED_FEATURE_FLAGS`, in preview environments.
4. Per-flag config handlers (for example `LIGHTDASH_ENABLE_TIMEZONE_SUPPORT`).
5. Database: user override, then organization override, then flag default.

The preview override check adds indexed lookups to the forced-on path. Ordinary
database-backed resolution also queries overrides outside preview environments.