Files
mercadodevida/work/artifacts/F-004/implementer.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

45 lines
2.3 KiB
Markdown

# Implementer — F-004 Typed config and feature flags
done -> work/artifacts/F-004/implementer.md
## Files created
- src/infrastructure/config/config.ts (loadConfig pure over env object; ConfigError accumulates all problems; names var names only)
- src/infrastructure/config/tests/config.test.ts (8 tests)
- src/modules/flags/domain/feature-flag-store.ts (FeatureFlagProvider + InMemoryFeatureFlagStore + createFlagStore)
- src/modules/flags/index.ts (module public API)
- src/modules/flags/tests/feature-flag-store.test.ts (5 tests)
- src/app/tests/config-flags.test.ts (2 composition tests: default OFF, runtime flip without redeploy)
## Files modified
- src/app/build-app.ts: optional flags dep; `app.flags` decorated on the instance (typed via module augmentation)
- src/infrastructure/http/server.ts: loadConfig fail-fast before anything starts; typed port/host/logLevel; flags seeded from FLAG_* env
- .env.example: REDIS_URL + FLAG_EXAMPLE_FEATURE example
- README.md: Configuration section
## API changes
- Server now REQUIRES DATABASE_URL at startup (fail-fast; intentional per spec).
## Bug found by tests during build (fixed before gates)
- Flag store constructor did not lowercase keys while isEnabled lowercased lookups -> case-insensitive seed test failed. Fixed by normalizing keys in the constructor. Regression test retained.
## Tests passed (evidence)
```
npm run lint -> OK
npm run lint:boundaries -> Boundary check OK: 22 file(s) checked (flags module imports nothing outside its subtree)
npm run typecheck -> exit 0
npm run build -> exit 0
npm test -> 9 files passed, 2 skipped (integration without DB); 38 passed | 6 skipped
npm run test:integration-> 2 files, 6 passed (no regression)
live smoke:
env -u DATABASE_URL node dist/.../server.js -> "Invalid configuration:\n- DATABASE_URL is required", exit 1 (AC1)
with DATABASE_URL + FLAG_EXAMPLE_FEATURE=true -> health=200, "HTTP server listening"
./scripts/verify.sh -> exit 0
```
## Known limitations
- No admin endpoint to flip flags yet (scope out); store API is runtime-mutable so the first consumer only adds transport.
- Flags live in memory: restart reseeds from env (documented as expected; persistence is a later ticket if needed).
## Follow-up work
- F-005 identity consumes config.databaseUrl through the pool and can guard risky paths via app.flags.