feat(portal-shell): replace nx-welcome with real shell and home + budgets per ADR-0017 #74

Merged
julien merged 1 commits from feat/portal-shell/home-and-shell into main 2026-05-10 02:38:43 +02:00
Owner

Summary

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.

What lands

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. After page load, http://localhost:16686 should show one trace whose root span is the SPA document_load, with a child fetch span that has its own child HTTP GET /api/health BFF span.
  • 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 (per ADR-0012 phase 2).
  • nx-welcome.ts removed; app.ts no longer imports it.

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

Type Limit (raw) ADR-0017 (gzip)
initial 1 MB ≤ 300 KB
anyScript 300 KB ≤ 100 KB / chunk
anyComponentStyle 6 KB ≤ 6 KB
bundle "styles" 150 KB ≤ 150 KB

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

  • pnpm exec nx run-many -t lint test build → 8 projects green; 12 tests pass for portal-shell across 5 specs (App, Header, Footer, Home, AccessibilityStatement).
  • pnpm 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.
  • pnpm audit clean.

After ./infra/local/dev.sh up observability + pnpm nx serve portal-bff + pnpm nx serve portal-shell, opening http://localhost:4200 shows the new layout, the system-status widget connects to the BFF, and the corresponding trace appears in Jaeger.

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) — the hard-coded 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.

Test plan

  • CI green on this PR.
  • Local: home page renders, system-status widget transitions from "Checking the backend…" to the success state when the BFF is up; falls back to "Backend unreachable" with the BFF stopped.
  • /accessibility and /accessibilite render the matching language with <article lang="en|fr">.
  • Skip link reachable via Tab from address bar; clicking it focuses #main-content.
  • Production build size summary roughly matches the figures above (initial total ≈ 90 KB transfer).
## Summary 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. ## What lands **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. After page load, http://localhost:16686 should show one trace whose root span is the SPA `document_load`, with a child `fetch` span that has its own child `HTTP GET /api/health` BFF span. - `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 (per ADR-0012 phase 2). - `nx-welcome.ts` removed; `app.ts` no longer imports it. **Bundle budgets** (`apps/portal-shell/project.json`): | Type | Limit (raw) | ADR-0017 (gzip) | | ------------------- | ------------ | --------------- | | `initial` | 1 MB | ≤ 300 KB | | `anyScript` | 300 KB | ≤ 100 KB / chunk | | `anyComponentStyle` | 6 KB | ≤ 6 KB | | `bundle "styles"` | 150 KB | ≤ 150 KB | `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 - `pnpm exec nx run-many -t lint test build` → 8 projects green; **12 tests pass** for `portal-shell` across 5 specs (App, Header, Footer, Home, AccessibilityStatement). - `pnpm 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. - `pnpm audit` clean. After `./infra/local/dev.sh up observability` + `pnpm nx serve portal-bff` + `pnpm nx serve portal-shell`, opening http://localhost:4200 shows the new layout, the system-status widget connects to the BFF, and the corresponding trace appears in Jaeger. ## 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`) — the hard-coded `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. ## Test plan - [ ] CI green on this PR. - [ ] Local: home page renders, system-status widget transitions from "Checking the backend…" to the success state when the BFF is up; falls back to "Backend unreachable" with the BFF stopped. - [ ] `/accessibility` and `/accessibilite` render the matching language with `<article lang="en|fr">`. - [ ] Skip link reachable via Tab from address bar; clicking it focuses `#main-content`. - [ ] Production build size summary roughly matches the figures above (initial total ≈ 90 KB transfer).
julien added 1 commit 2026-05-10 02:38:06 +02:00
feat(portal-shell): replace nx-welcome with real shell and home + budgets per ADR-0017
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
781290800b
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.
julien merged commit 0d31937aeb into main 2026-05-10 02:38:43 +02:00
julien deleted branch feat/portal-shell/home-and-shell 2026-05-10 02:38:45 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#74