Three editor-noise sources, three matching tame:
* Add `composite: true` to lib tsconfig.lib.json files (shared/ui,
shared/state, feature/auth) and let `nx sync` redirect consumer
references in apps/portal-{shell,admin}/tsconfig.app.json to point
at the .lib.json directly. Silences TS6306 ("Referenced project
must have setting composite: true") that the TS service raises on
the project references our Nx 22 lib generator emits.
* Add `ignoreDeprecations: "5.0"` on apps/portal-bff/tsconfig.{app,
spec}.json. Both inherit `moduleResolution: node` / `node10` which
TS 7.0 will remove; the diagnostic itself suggests the opt-out
knob. The TS 5.9 we run only accepts "5.0" as the value (the
warning text mentions "6.0" but TS rejects it). Migration to
nodenext/node16 is a separate chantier — too entangled with Nest
CJS semantics for a drive-by.
* Add a repo-level .axe-linter.yml that disables the `list` rule
globally. axe Linter (VS Code) doesn't understand Angular 17+
`@for` blocks and flags `@for (...) { <li>… }` as a non-<li>
child of <ul>/<ol>. Compiler erases the syntax at build time;
axe-playwright (ADR-0016) operates on the rendered DOM and is
unaffected.
Generate the four phase-4 libraries:
- libs/shared/tokens (project name shared-tokens) - plain TS lib via
@nx/js:library; will host the a11y design tokens (palette,
contrast tiers, spacing, motion) once Tailwind lands in phase 5;
consumable by both apps; tagged scope:shared, type:shared.
- libs/shared/util (shared-util) - plain TS lib for cross-cutting
utility code; tagged scope:shared, type:shared.
- libs/shared/ui (shared-ui) - Angular standalone library that will
host the spartan-ng components copy-pasted in phase 5; Angular-only
so tagged scope:portal-shell, type:shared. unitTestRunner=
vitest-analog because vitest-angular requires a buildable lib.
- libs/feature/auth (feature-auth) - placeholder Angular standalone
feature lib to demonstrate the type:feature pattern; tagged
scope:portal-shell, type:feature.
@nx/enforce-module-boundaries depConstraints replaced (root
eslint.config.mjs) with the rules from ADR-0003:
scope:portal-shell -> scope:portal-shell, scope:shared
scope:portal-bff -> scope:portal-bff, scope:shared
scope:shared -> scope:shared
type:app -> type:feature, type:shared
type:feature -> type:feature, type:shared
type:shared -> type:shared
This forbids portal-shell from importing portal-bff code (and vice
versa) and prevents shared libs from depending on feature libs.
Project names follow the convention of ADR-0003 (feature-<name> /
shared-<scope>) by passing --name explicitly to the generator; the Nx
22 default takes only the last directory segment.
Sanity check: pnpm nx run-many -t lint and -t test pass for the 8
projects (4 apps/e2e + 4 libs).
Side effects from the generators: tsconfig.base.json paths populated
with the lib import aliases; nx.json gains vite/playwright plugin
entries; .gitignore picks up vitest.config.*.timestamp* (Vitest temp
files); package.json gains @analogjs/vitest-angular and related
devDeps; pnpm-lock.yaml regenerated. Two eslint-disable comments in
portal-bff-e2e support files were trimmed by lint --fix - those files
already lint clean without the directive.