Files
apf_portal/apps/portal-shell/project.json
T
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

99 lines
2.5 KiB
JSON

{
"name": "portal-shell",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"prefix": "app",
"sourceRoot": "apps/portal-shell/src",
"tags": ["scope:portal-shell", "type:app"],
"targets": {
"build": {
"executor": "@angular/build:application",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/portal-shell",
"browser": "apps/portal-shell/src/main.ts",
"tsConfig": "apps/portal-shell/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "apps/portal-shell/public"
}
],
"styles": ["apps/portal-shell/src/styles.css"]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "1mb",
"maximumError": "1mb"
},
{
"type": "anyScript",
"maximumWarning": "300kb",
"maximumError": "300kb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "5kb",
"maximumError": "6kb"
},
{
"type": "bundle",
"name": "styles",
"maximumWarning": "150kb",
"maximumError": "150kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"continuous": true,
"executor": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "portal-shell:build:production"
},
"development": {
"buildTarget": "portal-shell:build:development"
}
},
"defaultConfiguration": "development"
},
"lint": {
"executor": "@nx/eslint:lint"
},
"test": {
"executor": "@angular/build:unit-test",
"options": {
"watch": false
},
"configurations": {
"watch": {
"watch": true
}
}
},
"serve-static": {
"continuous": true,
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "portal-shell:build",
"port": 4200,
"staticFilePath": "dist/apps/portal-shell/browser",
"spa": true
}
}
}
}