Development
This page collects design notes for developers maintaining or extending the platform, including how settings is organized, and how to decide where a new setting belongs.
Settings philosophy
Each component (backend and frontend) reads two kinds of settings:
Configuration describes what this deployment is: its name, its states, which GeoJSON files to load, which CSV schemas to expect, which indicator slugs to whitelist, whether the PDF report is enabled, which partners and resources to display.
Environment variables describe where this deployment is running right now: database credentials, Redis URL, secret key, allowed hosts, hostnames of downstream services, Sentry DSN, analytics IDs.
The configuration takes a different form per component:
The backend loads it from a TOML file (
config.toml). See Data Management API.The frontend receives it as a
configobject exported by its branding package. See Frontend.
The same configuration should be usable unchanged across production, staging, and local development for a given deployment. Only the environment differs between those.
Mixing the two makes it harder to reason about what changed between deployments, and to spin up new environments or promote builds across environments without re-editing files.
Deciding where a new setting belongs
Ask, in order:
Does the value change between staging and production of the same deployment? If yes,
→ Environment variableIs it a secret or credential?
→ Environment variableIs it tied to the infrastructure the code is running on (database, hostname, etc.)?
→ Environment variableDoes it describe the deployment itself — its data model, its states, its content, its feature flags?
→ Configuration
For concrete examples, see the existing settings already in place:
Configuration: Frontend, Data Management API.
Environment variables: Frontend, Data Management API.