Skip to content

Configuration

Blue Dots follows strict configuration discipline: no domain- or environment-specific value is hardcoded. Values are read once at startup from a config loader or environment, with per-environment overrides.

ConcernSignals DPGAggregator DPG
Env var declarationspackages/config (Zod secrets.ts)config loader package
Per-env overridesconfig/env/{dev,staging,prod}.yamlconfig/env/{dev,staging,prod}.yaml
Schemas / formsnetwork + item schemas, schema registryconfig/schemas/aggregator/*.json (RJSF)
Local env.env (root or per-app .env.example)root .env (infra/env.template)

Two places must change together, or you’ll hit the classic “works locally, fails in pnpm dev:api” bug:

  1. The Zod schema in packages/config/src/secrets.ts — so validation passes.
  2. turbo.json’s globalPassThroughEnv — so the variable actually reaches filtered tasks.

Adding an environment variable (Aggregator)

Section titled “Adding an environment variable (Aggregator)”

Add it to the config loader’s schema. The aggregator web image deliberately takes no NEXT_PUBLIC_* build args (see the comment in apps/web/Dockerfile), so those values are read at runtime: an env change applies on a plain restart. make rebuild-web is for web code changes.

Registration and profile forms are schema-driven (RJSF in the Aggregator; item schemas in the Signals UI). Product and program teams can add or change fields by editing the JSON schemas — no application code change required. See Schema-Driven Model.

  • Local secrets live in .env files (the Aggregator’s make setup writes a chmod 600 root .env).
  • Never commit secrets. Production secrets are managed by your platform’s secret store (see the Signals repo docs/operations/secrets.md).