Platform Configuration, Properties & Feature Flags — How it works
Overview
The platform-config engine manages two kinds of configuration:
- Feature flags — the switches that turn platform behaviour on or off per deployment, tenant, or facility, resolved by layering scoped overrides on a global default, with an audit trail.
- Global properties (CONF-001) — operational key-value settings a deployment tunes without a code change: the facility's currency, a retention window, an integration endpoint. A flag answers is this behaviour on?; a property answers what value does it use?
Data model & ownership
| Table | Purpose |
|---|---|
feature_flag | The flag and its global default. |
feature_flag_scope | The scope kind (e.g. tenant/facility) an override targets. |
feature_flag_override | A scoped value that overrides the default. |
feature_flag_audit | Append-only change history. |
global_property | One scoped key-value setting: property_name, property_value, and the two nullable scope arms tenant_id / facility_id. |
Key rules & invariants
- Effective value = the most specific matching override, else the global default.
- Security-sensitive flags default to the safe value (off); changes are audited.
Global properties (CONF-001)
- Scope lives in the two arms, not in the name. Both null = a platform row;
tenant_idset = a tenant row; both set = a facility row. The name stays identical across scopes. - A name may exist once per scope, enforced by a partial unique index on
(property_name, COALESCE(tenant_id, nil), COALESCE(facility_id, nil))wherevoided = false. Creating a second row at the same scope is refused; creating one at a different scope is how an override is expressed. - Reads resolve facility → tenant → platform. A facility inherits every setting it has not overridden, so removing a facility row uncovers the tenant or platform value rather than deleting the setting.
- The scope arms are stamped from the session's signed claims, never from the payload — the
platform-wide tenant/facility rule. A client picks a scope level (
PLATFORM,TENANT,FACILITY); the server supplies the ids. - The name is the row's identity. An update changes value and description only; a different name or scope is a different row.
Registered property names
| Name | Consumer | Meaning |
|---|---|---|
billing.default_currency | Billing / charge master (FE-127) | ISO-4217 code new priced records default to. The currency symbol is never stored — it derives from the code on the client, so a symbol can never disagree with the code it labels. |
API
See the API Reference. Endpoint groups under /api/v1/platformconfig: feature
flags, scopes, overrides, and the resolved effective flag for a context; plus properties
(GET visible rows, POST at a scope, PUT value/description, DELETE) and
properties/resolve?name=…, which answers with the value that applies to the caller's scope.
Permissions: platformconfig.property.read / .write / .delete. The admin screen is gated by
route key admin.platform.properties.
Configuration & feature flags
Flags are the feature itself; specific flags (e.g. pii.encryption.enabled, OPA enablement) are
documented on their operations pages.
Related features
- Consumed by the Access control decision pipeline and any engine gating optional behaviour.