Files
mercadodevida/work/artifacts/F-004/architect.md
rikrdo 4851692031 feat(F-004): typed fail-fast config and feature flag module
- loadConfig: pure over env object, accumulates all problems, names var names only
- DATABASE_URL now required at startup; PORT/HOST/LOG_LEVEL/NODE_ENV/REDIS_URL defaulted
- flags module behind FeatureFlagProvider; unknown flags OFF; runtime setEnabled (no redeploy)
- buildApp decorates app.flags; server.ts fail-fast before app boot
- tests caught and fixed flag-store case-normalization bug before gates
- zero new dependencies; all gates approved; verify.sh green
2026-08-14 22:29:18 +02:00

1.7 KiB

Architect — F-004 Typed config and feature flags

done -> work/artifacts/F-004/architect.md

Deliverables

  • specs/F-004-config-flags/SPEC.md
  • specs/F-004-config-flags/DESIGN.md
  • specs/F-004-config-flags/TASKS.md
  • specs/F-004-config-flags/TESTS.md

Key decisions

  1. Config loader lives in infrastructure/config and is a pure function over an env object. No reads of process.env inside the loader → deterministic unit tests. It accumulates every problem and throws ONE ConfigError (fail fast AND clear). It names var NAMES only — never values — so secrets cannot leak into error messages.
  2. Feature flags are a real module (src/modules/flags) behind a FeatureFlagProvider interface with an in-memory store. Unknown flags default to OFF (fail-safe). setEnabled mutates live state → activation ≠ deployment, no redeploy.
  3. Inversion to keep the module clean: infrastructure/config parses FLAG_* into a plain record and the composition root hands it to the flags store. The flags module never imports config. The boundary checker enforces this.
  4. buildApp gains an optional flags dep, decorated onto the instance (app.flags), establishing the wiring point future risky routes will consume. Default: empty store → everything off.
  5. No new dependencies. Hand-rolled validation is small and boring.

Boundaries

  • flags module imports nothing outside its subtree (no shared needed). Config → flags only via composition root. server.ts pulls config + passes flags into buildApp.

Risks

  • server now requires DATABASE_URL to start (intentional fail-fast). Smoke/QA must pass it.
  • ConfigError must not echo values. Covered by name-only messages + test.