Commit Graph

4 Commits

Author SHA1 Message Date
julien 0d31937aeb feat(portal-shell): replace nx-welcome with real shell and home + budgets per ADR-0017 (#74)
CI / check (push) Successful in 2m4s
CI / commits (push) Has been skipped
CI / scan (push) Successful in 2m6s
CI / a11y (push) Successful in 1m14s
CI / perf (push) Successful in 3m3s
## 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).

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #74
2026-05-10 02:38:42 +02:00
Julien Gautier bd8eefb44a chore: configure Tailwind 4 and align lib tsconfigs
Wire Tailwind CSS 4 in the portal-shell app per ADR-0016 (the future
host of spartan-ng components in libs/shared/ui will read from the
Tailwind tokens via the shared-tokens lib).

- pnpm add -D tailwindcss @tailwindcss/postcss postcss
- apps/portal-shell/postcss.config.js declares @tailwindcss/postcss
- apps/portal-shell/src/styles.scss renamed to styles.css and now
  contains a single @import 'tailwindcss' directive. Plain CSS for the
  global file avoids the Sass @import deprecation warning that fires
  when Tailwind directives sit inside SCSS. Component-level styles can
  still use SCSS.
- apps/portal-shell/project.json styles entry updated accordingly.

Side fix: align libs/shared/tokens and libs/shared/util tsconfigs from
module: commonjs to module: esnext. The Nx @nx/js:library --bundler=
tsc generator emits commonjs by default, but tsconfig.base.json
specifies moduleResolution: bundler, which TS only allows alongside
esnext or es2015+ modules. Without the alignment, those libs failed to
build (TS5095). All apps and libs now build green.

spartan-ng wiring is intentionally NOT in this commit. spartan-ng is
currently at 0.0.1-alpha.681 - clearly pre-1.0, which trips the
project rule against pre-1.0 dependencies. ADR-0016 chose spartan-ng
with the copy-paste mitigation, but the alpha state warrants an
explicit go/no-go decision before committing the workspace to it.
2026-04-30 17:50:35 +02:00
Julien Gautier cd1d482aa8 fix(portal-shell): make 'nx test' run once by default, add watch configuration
The Angular 21 unit-test builder (@angular/build:unit-test) defaults
to watch mode. Without an explicit option, 'pnpm nx test portal-shell'
hangs on 'Waiting for task' indefinitely - unsuitable for CI and
surprising for ad-hoc invocations.

Pin watch=false as the default in the target options. Add a 'watch'
configuration so developers who want continuous test running can opt
in with 'pnpm nx test portal-shell --configuration=watch'. portal-bff
uses Jest which defaults to no-watch and needs no change.
2026-04-30 16:44:33 +02:00
Julien Gautier bea5e1954f chore: generate portal-shell and portal-bff apps per ADR-0004 / ADR-0005
Add the @nx/angular, @nx/nest, @nx/vite, @nx/eslint plugins, then
generate the two apps. Adjust the empty-template tsconfig.base.json
to be Angular-compatible (drop project references and customConditions
that the empty-template defaults to but Angular doesn't support; keep
the strict-TS extensions from ADR-0004).

apps/portal-shell (Angular 21):
- standalone APIs, routing, SCSS, esbuild
- vitest-angular as unitTestRunner, playwright for e2e
- strict mode
- tags scope:portal-shell, type:app
- app.config.ts wired with provideZonelessChangeDetection() per
  ADR-0004 (Angular 21 + Nx 22 generates without zone.js by default)

apps/portal-bff (NestJS 11):
- Express adapter (default per ADR-0005)
- Jest as unitTestRunner
- tags scope:portal-bff, type:app
- main.ts wired with a global ValidationPipe configured
  whitelist + forbidNonWhitelisted + transform per ADR-0005
- Phase-2 security additions (helmet, CORS, sessions, CSRF, rate
  limit, auth guards, error filter) deferred to their respective
  ADRs - placeholder comment in main.ts

Workspace dependencies: class-validator + class-transformer added
(required by NestJS ValidationPipe at runtime). Nx-generated
.gitignore additions (.angular, __screenshots__) merged into ours.
.vscode/extensions.json and launch.json added by Nx are kept (do not
override our existing settings.json).
2026-04-30 16:12:42 +02:00