Files
apf_portal/docs/decisions
Julien Gautier 781290800b
CI / commits (pull_request) Successful in 1m18s
CI / scan (pull_request) Successful in 1m26s
CI / check (pull_request) Successful in 1m33s
CI / a11y (pull_request) Successful in 1m36s
CI / perf (pull_request) Successful in 4m5s
feat(portal-shell): replace nx-welcome with real shell and home + budgets per ADR-0017
Cuts the Nx scaffold's `NxWelcome` page (938 LOC of placeholder
markup) and lays down the actual portal layout — header, main,
footer landmarks plus a skip link — with a real home page and
the two RGAA-mandated accessibility statement routes. Bundle
budgets in `project.json` are tightened to match ADR-0017.

Layout shell (apps/portal-shell/src/app/):

- components/header/  — brand link + primary nav landmark stub
- components/footer/  — accessibility statement links (FR + EN)
                        + version badge
- app.html / app.scss — flex column with sticky footer + skip
                        link to #main-content (WCAG 2.4.1)

Pages:

- pages/home/         — welcome heading + "system status" widget
                        that fetches /api/health from the BFF.
                        Doubles as a smoke test of the full
                        SPA → BFF stack: CORS, OTel trace
                        propagation, Pino log correlation.
- pages/accessibility/ — single component, content selected by
                        route data (`lang: 'fr' | 'en'`). Mounted
                        at /accessibility (en) and /accessibilite
                        (fr). v1 carries placeholder copy
                        explicitly framed as "awaiting APF user
                        panel review" — RGAA + ADR-0016 require
                        the routes to exist; the substantive
                        statement (audit grid, gaps list,
                        remediation plan) lands separately.

Routing & wiring:

- app.routes.ts adds the three routes, all lazy-loaded.
- app.config.ts adds `provideHttpClient(withFetch())` so
  HttpClient delegates to the patched browser `fetch` and the
  W3C `traceparent` header propagates automatically (ADR-0012
  phase 2).
- nx-welcome.ts removed; app.ts no longer imports it.

Bundle budgets (apps/portal-shell/project.json):

- initial            ≤ 1 MB raw  (≈ 300 KB gzip target per ADR)
- anyScript          ≤ 300 KB raw (≈ 100 KB gzip per lazy chunk)
- anyComponentStyle  ≤ 6 KB raw  (5 KB warning floor)
- bundle "styles"    ≤ 150 KB raw

`maximumWarning == maximumError` so an overshoot fails the build
(matching `type: "error"` in spirit). Angular CLI compares raw
sizes; ADR-0017 §Confirmation is updated to record the gzip→raw
translation and the deferred follow-up that will add a CI check
on the actual gzipped transfer size (Angular has no native
gzip-mode budget).

Verified locally:
- `nx run-many -t lint test build` → 8 projects green, 12 tests
  pass for portal-shell across 5 specs.
- `nx build portal-shell --configuration=production` → initial
  bundle 326.99 KB raw / 89.82 KB transfer (gzip) — well under
  the ADR-0017 300 KB gzip target. Lazy chunks: home 2.66 KB,
  accessibility 2.90 KB.

Out of scope (separate PRs):

- Real RGAA audit content (APF user-panel review).
- Design tokens system in libs/shared/tokens.
- Reusable UI primitives in libs/shared/ui.
- User-preferences panel (ADR-0016 §"User-preferences panel").
- i18n machinery (@angular/localize) — for v1 the FR/EN copy is
  inlined and route-driven; real i18n is a separate ADR.
- env-config (Angular environment.ts) — DATABASE-of-the-front
  hard-coded URL `http://localhost:3000/api/health` will move
  there alongside the OTLP endpoint when the env-config PR
  lands.
- CI gzip-transfer-size assertion to complement the raw-size
  Angular budgets.
2026-05-10 02:35:27 +02:00
..

Architectural Decision Records

This project records architecturally-significant decisions as ADRs in the MADR 4.0.0 format. References: adr.github.io.

Why ADRs

ADRs capture the why behind a decision — context, drivers, options considered, trade-offs accepted — at the moment the decision is made. They make architecture reviewable, onboarding faster, and prevent the same debate from being re-litigated later.

Conventions

  • Format: MADR 4.0.0. Start from template.md.
  • Filename: NNNN-kebab-case-title.md, e.g. 0007-adopt-tailwind-for-design-tokens.md.
  • Numbering: globally sequential 4-digit prefix. Numbers never reset, never get reused — even when an ADR is superseded or deprecated.
  • Layout: flat folder. ADRs are not nested into category subfolders; topical organization happens via tags.
  • Tags: every ADR carries a tags: array in the MADR frontmatter, drawn from the tag vocabulary below. An ADR may carry several tags. Propose new tags (or renames) in the same PR that needs them; never invent ad-hoc tags inline.
  • Status lifecycle: proposedaccepted → optionally deprecated or superseded by [ADR-NNNN](NNNN-other.md). Update the YAML frontmatter; never delete an ADR.
  • Index maintenance: every ADR addition or status change must update the Index below in the same commit.

When to write an ADR

Write one whenever a development decision is non-trivial: tool or library choice, framework pattern, security control, perf budget, a11y target, naming convention, deprecation, breaking change, or any choice that future contributors would benefit from understanding the why of.

Tag vocabulary

The vocabulary below is the source of truth. It is intentionally coarse — propose extensions only when an existing tag genuinely doesn't fit, and avoid overly narrow tags.

Tag Scope
frontend UI, Angular, components, design system, client-side state
backend API, BFF, server-side services
security AuthN, AuthZ, sessions, CSP, dependency scanning, secret management
performance Perf budgets, caching, bundle size, Lighthouse
accessibility WCAG, a11y testing, keyboard, ARIA, contrast
infrastructure CI/CD, hosting, deployment, runtime
observability Logs, metrics, traces, correlation IDs, monitoring
data Persistence, schemas, migrations, data flow
process Team conventions, workflows, repo policy

Status: starter vocabulary, to be refined as ADRs accumulate. Update this table whenever a tag is added, renamed, or retired.

Index

ADRs are listed in numerical order. To slice by topic, filter on the Tags column.

# Title Status Tags Date
0001 Use ADRs to record architectural decisions accepted process 2026-04-29
0002 Adopt Nx monorepo with the apps preset accepted infrastructure, frontend, backend 2026-04-29
0003 Workspace and app naming convention accepted process 2026-04-29
0004 Frontend stack — Angular (latest LTS), standalone, zoneless, Signals, CSR-only, Vitest accepted frontend 2026-04-29
0005 Backend stack — NestJS over Express, Fastify, Hono accepted backend 2026-04-29
0006 Persistence — PostgreSQL with Prisma accepted data, backend 2026-04-29
0007 Pre-commit hooks and Conventional Commits accepted process 2026-04-29
0008 Identity model — multi-tenant Entra ID for workforce, dual-audience design for future External ID accepted security, data 2026-04-29
0009 Authentication flow — OIDC Authorization Code + PKCE via MSAL Node, BFF session pattern accepted security, backend 2026-04-29
0010 Session management — opaque session IDs in cookies, payload in self-hosted Redis with AES-GCM at rest accepted security, backend, infrastructure 2026-04-29
0011 MFA enforcement — Entra ID Conditional Access baseline, BFF claim sanity-check, step-up hooks designed-in accepted security 2026-04-29
0012 Observability — Pino structured logs + OpenTelemetry tracing, W3C Trace Context propagation, stdout + collector accepted observability, backend, frontend 2026-04-29
0013 Audit trail — separated append-only Postgres schema, decoupled from app logs accepted security, observability, data 2026-04-29
0014 Downstream API access — On-Behalf-Of pattern, unified DownstreamApiClient, audience-aware authorization accepted security, backend 2026-04-29
0015 CI/CD pipeline — Gitea Actions, trunk-based + squash-merge, thin YAML over portable scripts accepted infrastructure, process 2026-04-30
0016 Accessibility baseline — WCAG 2.2 AA + targeted AAA, Angular CDK + spartan-ng + Tailwind, APF panel testing accepted accessibility, frontend, process 2026-04-30
0017 Performance budgets — Core Web Vitals + Lighthouse CI gates, bundle budgets, BFF p95/p99 SLOs accepted performance, frontend, backend, process 2026-04-30