Files
apf_portal/apps/portal-admin/project.json
T
Julien Gautier 8dd235e44f
CI / check (pull_request) Successful in 4m8s
CI / commits (pull_request) Successful in 4m12s
CI / scan (pull_request) Successful in 5m6s
CI / a11y (pull_request) Successful in 1m47s
CI / perf (pull_request) Successful in 6m21s
feat(spa): proxy /api in dev-server, relative bffApiBaseUrl
Make the SPAs reach the BFF same-origin via the Angular dev-server's
proxy, so the dockerised dev mode (ADR-0030) works when the SPA is
accessed from a remote browser (e.g. http://<vm-ip>:4200/) — and CORS
is bypassed in dev altogether.

- New proxy.conf.js per SPA: /api -> ${BFF_TARGET:-http://localhost:3000}
  (JS form so the env var can swap the target at startup without a
  rebuild).
- project.json serve.options.proxyConfig wired in for both apps.
- environment.ts (shell + admin) bffApiBaseUrl: 'http://localhost:3000/api'
  -> '/api'. Production siblings can still set an absolute origin if
  the SPA and BFF live on different hosts; tracing.ts resolves either
  form against window.location.origin.
- tracing.ts: new URL(env, window.location.origin) — relative bases no
  longer throw, absolute bases keep their own origin.
- dev.compose.yml: BFF_TARGET=http://portal-bff:3000 on portal-shell
  and portal-admin so the proxy hits the BFF container by Compose DNS.
  Native nx serve leaves it unset and falls back to localhost.

OTel exporter URL and cross-SPA links remain absolute — same remote-
browser issue, but not blocking the 'Backend unreachable' path this
PR targets. Out of scope here, follow-up if needed.

Stacked on top of feat/dockerised-dev-mode.
2026-06-01 11:16:05 +02:00

125 lines
3.2 KiB
JSON

{
"name": "portal-admin",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"prefix": "app",
"sourceRoot": "apps/portal-admin/src",
"tags": ["scope:portal-admin", "type:app"],
"i18n": {
"sourceLocale": {
"code": "en",
"baseHref": "/en/"
},
"locales": {
"fr": {
"translation": "apps/portal-admin/src/locale/messages.fr.xlf",
"baseHref": "/fr/"
}
}
},
"targets": {
"build": {
"executor": "@angular/build:application",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/portal-admin",
"browser": "apps/portal-admin/src/main.ts",
"polyfills": ["@angular/localize/init"],
"tsConfig": "apps/portal-admin/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "apps/portal-admin/public"
}
],
"styles": ["apps/portal-admin/src/styles.css"]
},
"configurations": {
"production": {
"localize": ["en", "fr"],
"i18nMissingTranslation": "error",
"budgets": [
{
"type": "initial",
"maximumWarning": "1.5mb",
"maximumError": "1.5mb"
},
{
"type": "anyScript",
"maximumWarning": "500kb",
"maximumError": "500kb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "8kb"
},
{
"type": "bundle",
"name": "styles",
"maximumWarning": "150kb",
"maximumError": "150kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"extract-i18n": {
"executor": "@angular/build:extract-i18n",
"options": {
"buildTarget": "portal-admin:build",
"outputPath": "apps/portal-admin/src/locale",
"outFile": "messages.xlf"
}
},
"serve": {
"continuous": true,
"executor": "@angular/build:dev-server",
"options": {
"port": 4300,
"proxyConfig": "apps/portal-admin/proxy.conf.js"
},
"configurations": {
"production": {
"buildTarget": "portal-admin:build:production"
},
"development": {
"buildTarget": "portal-admin: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-admin:build",
"port": 4300,
"staticFilePath": "dist/apps/portal-admin/browser"
}
}
}
}