Commit Graph

2 Commits

Author SHA1 Message Date
Julien Gautier 47277114da feat(portal-shell): i18n string sweep — mark UI strings + FR translations
CI / commits (pull_request) Successful in 2m12s
CI / scan (pull_request) Successful in 2m13s
CI / check (pull_request) Successful in 2m22s
CI / a11y (pull_request) Successful in 2m13s
CI / perf (pull_request) Successful in 5m27s
Continue ADR-0019 implementation. Mark every UI string surfaced by
the shell with `i18n="@@id"` (templates) or `$localize` (TypeScript)
and populate `messages.fr.xlf` with French translations. 43 trans-
units total: skip-link, header, sidebar, theme switcher, footer,
home page, route titles.

What's marked:

- `app.html` skip-link.
- `header.html` brand wordmark, search label + placeholder, action
  buttons (notifications / help / settings), user-menu placeholder.
- `sidebar.ts` MENU data (group + item labels) and a computed aria-
  label for the toggle button (Expand / Collapse).
- `sidebar.html` aside / sections / role / collapse strings.
- `theme-switcher.ts` MODE_OPTIONS labels + computed trigger aria
  ("Theme: <mode> (open menu)" with a named placeholder).
- `theme-switcher.html` menu aria-label.
- `footer.html` aria-labels + copyright. The two accessibility-page
  link labels stay bilingual on purpose (one per language, each
  carrying its `lang` attribute) — the dual-link pattern goes away
  in the upcoming route-fusion PR.
- `home.html` welcome heading + intro + status widget labels.
- `app.routes.ts` browser tab titles. The `/accessibility` and
  `/accessibilite` routes share one title key; the route-fusion PR
  will collapse them to a single localised route.

Tooling:

- Add `"@angular/localize"` to the `types` array in both
  `tsconfig.app.json` and `tsconfig.spec.json` so TypeScript
  resolves the `$localize` global.

Translation choices worth flagging:

- Wordmark: "APF Portal" → "Portail APF" (consistent with the route
  title key).
- "System" theme mode → "Système".
- "Anonymous" role → "Anonyme"; "Role:" → "Rôle :" (French uses a
  non-breaking-space before the colon — typographic convention,
  preserved in the XLIFF target).

Verification:

- Production build emits both locales (`dist/.../{en,fr}/`).
  Spot-checked the FR bundle: no leftover English source text on
  any of the swept strings, route titles, or the home page intro.
- Initial bundle: 129 kB gzip per locale (vs 122 kB before).
  +7 kB gzip absorbs the i18n marker metadata + the FR translation
  data embedded in the FR bundle. Well under the 300 KB budget.
- 36 / 36 specs unchanged (they run in the source locale, so the
  English assertions still match).

Out of scope (each its own follow-up PR):

- Locale switcher in the footer + `__Host-portal_locale` cookie +
  smart `/` redirect.
- Collapse `/accessibility` + `/accessibilite` into one localised
  route.
- CI gate that fails the build on a missing translation.
2026-05-11 19:46:13 +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