Feature Flag
Data Entity
Description
Defines an individual feature toggle for a specific organization, controlling which capabilities are visible (travel reimbursement, certifications, gamification, driver management). Includes an enabled state, optional minimum app version for phased rollout, and an optional activation date. Stored as entries within organisation_configuration JSONB and exposed as typed domain objects.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Surrogate identifier for the feature flag domain object. Generated client-side when deserializing JSONB entries; not persisted as a separate column. | PKrequiredunique |
flag_key |
enum |
Canonical identifier for the feature capability. Must match a constant defined in FeatureFlags (feature-flag-constants). Unique per organization. | required |
organization_id |
uuid |
Foreign key to the organisation whose configuration embeds this flag. Derived from the parent organisation_configuration row. | required |
enabled |
boolean |
Master switch for the feature. When false the feature is unconditionally suppressed regardless of rollout conditions. Defaults to false for all flags not explicitly configured. | required |
min_app_version |
string |
Minimum semantic app version (e.g. '2.4.0') required before the flag is evaluated as active. Supports phased rollout by excluding users on older app builds. Null means no version gate. | - |
activation_date |
datetime |
Optional UTC datetime after which the flag is eligible to activate. If set, the flag is suppressed until this timestamp is reached regardless of the enabled state. Null means immediately active once enabled. | - |
created_at |
datetime |
UTC timestamp when this flag entry was first added to the organisation's feature set. | required |
updated_at |
datetime |
UTC timestamp of the last change to any field on this flag entry. | required |
Database Indexes
idx_feature_flag_org_key
Columns: organization_id, flag_key
Enforces one entry per flag key per organization and supports O(1) flag lookup by org + key
idx_feature_flag_organization_id
Columns: organization_id
Supports loading all flags for a given organization in one query
idx_feature_flag_enabled
Columns: organization_id, enabled
Supports bulk queries for all enabled flags within an organization
idx_org_config_features_gin
Columns: features
GIN index on the JSONB features column of organisation_configuration for key-level containment queries
Validation Rules
flag_key_is_known_constant
error
Validation failed
min_app_version_semver
error
Validation failed
activation_date_is_utc_datetime
error
Validation failed
enabled_is_boolean
error
Validation failed
organization_id_references_existing_org
error
Validation failed
no_future_created_at
warning
Validation failed
Business Rules
rollout_condition_gate
A flag is only considered active when enabled=true AND (min_app_version is null OR current app version >= min_app_version) AND (activation_date is null OR now() >= activation_date). All three conditions must hold simultaneously.
default_disabled
Any flag key not explicitly present in an organization's features JSONB is treated as disabled. Absence equals false. This prevents accidental feature exposure during onboarding of new organizations.
unique_flag_key_per_org
Each flag_key may appear at most once per organization in the features JSONB. Duplicate entries are rejected at the repository layer before persisting.
known_flag_key_only
Only flag keys declared in FeatureFlags constants (feature-flag-constants) are valid. Unknown keys are rejected to prevent typos and orphaned configuration entries.
cache_ttl_invalidation
Resolved flag values are cached in memory with a TTL. Any admin write to a flag must invalidate the cache for the affected organization so UI components reflect the change within one session refresh cycle.
driver_flag_restricted_to_blindeforbundet
The driver_management flag is only meaningful for Blindeforbundet. Enabling it for other organizations has no product effect, but the system must not raise an error — feature gates simply have no child UI to render.
flag_inherited_by_tenant_context
When a user switches organization context the full flag map for the new organization must be loaded before the navigation shell renders. Feature gates must never evaluate stale flags from a previous organization context.
CRUD Operations
Storage Configuration
Entity Relationships
Organisation configuration embeds the features JSONB whose individual entries are logically represented as feature_flag domain objects