docs(decisions): add ADR-0018 — environment configuration strategy (#80)
CI / check (push) Successful in 1m36s
CI / commits (push) Has been skipped
CI / scan (push) Successful in 2m2s
CI / a11y (push) Successful in 1m36s
CI / perf (push) Successful in 3m33s

## Summary

Records the per-environment config strategy for both apps. ADR-only — no code changes; the implementation is anchored in §Confirmation against the next feature work that touches per-environment values.

## What lands

[**ADR-0018 — Environment configuration**](docs/decisions/0018-environment-configuration-strategy.md):

- **SPA**: Angular `environment.ts` + project.json `fileReplacements`. Build-time substitution; no runtime config fetch (rejected for the LCP/TTFB cost it would add and the deploy-time HTML rewrite that the alternatives need). Concretely cleans up the hard-coded URLs we left in `observability/tracing.ts` and `home-status.service.ts` ("hard-coded for v1 — env-config when it lands" comments).
- **BFF**: keep `process.env` + small per-key boot-time validators (the shape `apps/portal-bff/src/config/check-database-url.ts` already follows). `@nestjs/config` rejected as too heavy for the current key count; `zod` not justified yet.
- **Audit log connection**: formalises the `AUDIT_DATABASE_URL` split that ADR-0013 §"Wired as features land" already pointed at. When set, the `AuditModule` instantiates a second Prisma client with `audit_writer`-only credentials (defense in depth); when unset, the dev fallback (shared pool + `SET LOCAL ROLE audit_writer` per transaction) keeps working. A boot-time `UPDATE`-rejection self-test runs against the dedicated pool when configured — refuses to start if the pool can mutate the audit table.

The §Confirmation block cross-references the env-var-as-boot-gate items already pre-figured in ADR-0009 / ADR-0010 / ADR-0012 / ADR-0013 / ADR-0014, so the validator pattern is the single landing place when those features ship.

## What does NOT change in this PR

- No `apps/portal-shell/src/environments/*.ts` files yet — landed alongside the next feature that actually needs per-environment values.
- No `AUDIT_DATABASE_URL` validator in BFF — same; lands when the second pool is wired.
- No CLAUDE.md restructuring; just one extra bullet under the Architecture summary referencing ADR-0018.

## Doc updates

- `docs/decisions/README.md` index — new row for ADR-0018.
- `CLAUDE.md` Architecture summary — one-line reference to ADR-0018 between the perf-budget and local-quality-gates entries.

## Test plan

- [ ] CI green on this PR (`format:check`).
- [ ] ADR-0018 renders in the doc index with the right tags (`frontend`, `backend`, `infrastructure`, `process`) and 2026-05-10 date.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #80
This commit was merged in pull request #80.
This commit is contained in:
2026-05-10 04:58:02 +02:00
parent 4473b1d4a4
commit 4476cbb518
3 changed files with 209 additions and 19 deletions
+1
View File
@@ -46,6 +46,7 @@ The structural, security, observability, and quality choices are recorded as ADR
- **CI/CD:** **Gitea Actions** (level-2 implementation; will be superseded by a GitLab migration ADR within 6-18 months). Trunk-based with squash-merge, branch protection on `main`, all CI gates blocking. Thin YAML — orchestration logic lives in `package.json` scripts (`ci:check`, `ci:scan`, `ci:commits`) and Nx targets, runnable locally. Gates: format / lint / type-check / test / build / audit / secret-scan / commit-lint, plus `a11y` (per ADR-0016) and future `perf`. Self-hosted `act_runner` on-prem. Conventional Commits validated locally (hook) and in CI (defense in depth). Required reviewer count = 0 in v1, raised to ≥1 once a second contributor joins. Signed commits recommended, revisited at GitLab migration — see [ADR-0015](docs/decisions/0015-cicd-gitea-actions.md).
- **Accessibility:** **WCAG 2.2 AA baseline + targeted AAA** on criteria with high impact for APF's user base (1.4.6 Contrast Enhanced, 2.2.3 No Timing, 2.3.3 Animation, 3.1.5 Reading Level, 1.4.8 Visual Presentation, 2.4.9 Link Purpose, 3.3.5 Help). RGAA 4.1 alignment for French audit. UI stack: **Angular CDK + TailwindCSS** (spartan-ng _library_ deferred until it reaches 1.0.0; v1 components are written in-house in `libs/shared/ui/` on Angular CDK, applying the spartan-ng _philosophy_ of headless primitives + utility CSS + copy-paste). User-preferences panel (contrast / text size / motion / spacing / cognitive simplification / reading focus) persisted in session. Tooling: `@angular-eslint/template/*` lint, `@axe-core/playwright` e2e (blocking on critical/serious), token-contrast CI check, touch-target check (44×44 min). Manual testing cadence with APF's internal user panel before each major release. Public accessibility statement page at `/accessibility` and `/accessibilite` — see [ADR-0016](docs/decisions/0016-accessibility-baseline-wcag-aa-targeted-aaa.md).
- **Performance budgets:** Core Web Vitals at Google "Good" thresholds (LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1, TBT ≤ 200 ms, TTFB ≤ 800 ms), Lighthouse Performance ≥ 90 on critical routes. **Lighthouse CI** (`@lhci/cli`) runs in CI with median-of-3 mitigation, blocking on threshold breach. Angular bundle `budgets` (`type: "error"`): initial ≤ 300 KB gzip, lazy chunks ≤ 100 KB gzip. BFF p95/p99 SLOs per endpoint family observed via OTel (advisory in CI, alerting in prod). Weekly scheduled Lighthouse run on prod env. **a11y wins over perf** when they conflict — see [ADR-0017](docs/decisions/0017-performance-budgets-lighthouse-ci.md).
- **Environment configuration:** SPA per-environment values via Angular `environment.ts` + `fileReplacements` at build time (no runtime config-fetch). BFF reads `process.env` directly with small per-key boot-time validators (no `@nestjs/config` overhead at this scale). The audit log uses a separate `AUDIT_DATABASE_URL` connection pool in production (`audit_writer`-only login, defense in depth) and falls back to the shared pool + `SET LOCAL ROLE` in dev — see [ADR-0018](docs/decisions/0018-environment-configuration-strategy.md).
- **Local quality gates:** Husky + lint-staged + commitlint with Conventional Commits — see [ADR-0007](docs/decisions/0007-pre-commit-hooks-and-conventional-commits.md).
- **Runtime:** Node.js latest LTS major.