Fix frontend documentation and Angular skill drift after the Angular 22 / TypeScript 6 upgrade
@oidacra is already working on this.
Since Aug 11, 2026.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Description
The Angular 21 → 22 / TypeScript 6 upgrade (#35930, delivered via PR #36838 and PR #36907) changed framework behavior and workspace tooling, but the frontend documentation was never updated to match. docs/frontend/ANGULAR_STANDARDS.md — described in its own header as "the single source of truth for Angular development in the dotCMS frontend" — now contains guidance that is factually wrong against origin/main.
The same drift extends to the sibling frontend docs, the root CLAUDE.md, and the angular-developer agent skill.
This is not cosmetic. Both developers and AI coding agents read these files as authoritative, so every stale rule actively produces incorrect code: the docs instruct yarn install in a pnpm-only workspace, they mandate an explicit OnPush line that Angular 22 made redundant, and the Angular skill ships an example that sets standalone: true — something ANGULAR_STANDARDS.md:16 explicitly forbids.
Verified drift in docs/frontend/ANGULAR_STANDARDS.md
Line numbers as of origin/main (d111b5d).
| Line | Doc currently says | Actual state |
|---|---|---|
| 3 | "Angular v20+" | Angular 22 |
| 6 | **Angular**: 22.0.7 |
22.1.0 — drifted within one patch release |
| 19, 32, 149 | "Always use OnPush change detection strategy" |
OnPush is the framework default since v22; ChangeDetectionStrategy.Eager (renamed from Default) is the opt-in mode and is used in 219 places. The doc never mentions Eager |
| 33 vs 111 | L33: "Prefer inline templates for small components" | L111: "Every component MUST have three separate files" and marks inline templates as forbidden. Direct self-contradiction — and the doc's own "Required" example at L215 uses an inline template |
| 151–179 | implements OnDestroy with a destroy$ Subject and takeUntil |
No mention of DestroyRef / takeUntilDestroyed() |
| 278–284 | Bare nx run … commands |
Nx is not installed globally; commands must be prefixed pnpm nx … |
| 287 | yarn install # NOT npm install |
packageManager is pnpm@10.17.1; only pnpm-lock.yaml exists in the repo |
| — | Nothing about TypeScript 6 | "ignoreDeprecations": "6.0" sits undocumented in core-web/tsconfig.base.json:18 |
Source for the change detection default: Angular — Advanced component configuration — "ChangeDetectionStrategy.OnPush is the default strategy (since v22)." This default flip is why PR #36907 had to add an explicit Eager to ~40 legacy components that had been relying on the old default.
The rest of the stack table (L7–L12) was verified correct: PrimeNG 21.1.3, NgRx Signals 21.1.1, Tailwind 4.1.17, Nx 23.1.1, TypeScript 6.0.3, Node 22.22.3.
Verified drift in sibling documentation
The workspace migrated from @ngneat/spectator to @openng/spectator@1.0.1. 528 source files import @openng; zero import @ngneat. Three docs still reference the old package:
| File | Stale references |
|---|---|
docs/frontend/TESTING_FRONTEND.md |
6 (lines 7, 14, 66, 67, 99, 304) |
docs/frontend/STATE_MANAGEMENT.md |
1 (line 238) |
docs/frontend/TESTING_REVIEW_RULES.md |
1 (line 7) |
Verified drift in CLAUDE.md
| File | Line | Issue |
|---|---|---|
CLAUDE.md (root) |
48 | cd core-web && yarn nx serve dotcms-ui # ... (use yarn nx, not nx) — must be pnpm nx |
CLAUDE.md (root) |
102 | **Frontend**: Angular 21+ — must be Angular 22+ |
core-web/CLAUDE.md |
— | Verified clean. Already uses pnpm and @openng/spectator, and carries no change detection guidance. No changes required |
Verified drift in the Angular skill
.agents/skills/angular-developer/, symlinked into .claude/skills/angular-developer. Added in #35237 and vendored from upstream: license: MIT, author: Copyright 2026 Google LLC, version: '1.0'. .claude/skills/CATALOG.md lists it under "External skills (symlinked, not governed here)".
| File | Line | Issue |
|---|---|---|
references/signal-forms.md |
556 | Sets standalone: true explicitly — contradicts the Angular default and ANGULAR_STANDARDS.md:16, which forbids it |
references/signal-forms.md |
559 | Sets changeDetection: ChangeDetectionStrategy.OnPush explicitly — redundant under the v22 default |
references/components.md |
115 | Standalone guidance still framed around "since Angular 19 / for older versions" |
SKILL.md |
16 | Instructs "run ng build to ensure there are no build errors … Do not skip this step". There is no angular.json in core-web; builds run through pnpm nx build |
SKILL.md |
25–42 | ng new / npx @angular/cli@latest new project-creation rules — not applicable inside an Nx monorepo |
references/cli.md |
21–75 | Assumes angular.json, ng serve / ng build / ng test, and Karma. The workspace uses nx.json and Jest 30.2.0 |
There are 15 ng CLI invocations across the skill. Because the skill is vendored and explicitly ungoverned, hand-editing it in place would silently fork it from upstream — the resolution needs to be a deliberate choice, captured in the criteria below.
The nx-* skills (nx-generate, nx-plugins, nx-run-tasks, nx-workspace) and link-workspace-packages were also checked: no yarn or @ngneat references. No changes required.
Acceptance Criteria
Change detection guidance (ANGULAR_STANDARDS.md)
- The doc states that
OnPushis the Angular framework default as of v22, and links to the official reference - The rule for new components is: do NOT set
changeDetectionin the@Componentdecorator — the default already isOnPush - The rule for legacy components is: components explicitly marked
ChangeDetectionStrategy.EagerkeepEager, and must NOT be converted toOnPushwhen the file is touched for unrelated work -
ChangeDetectionStrategy.Eageris documented as the opt-in eager mode renamed fromDefaultin v22, with a note that PR #36907 applied it to legacy components during the upgrade - The three existing directives to set
OnPushexplicitly (L19, L32, L149) are updated or removed; no remaining text instructs adding achangeDetectionline to a new component - The component example at L143–150 no longer carries a
changeDetection: ChangeDetectionStrategy.OnPushline
Version references (ANGULAR_STANDARDS.md)
- Hardcoded patch versions are removed from the Tech Stack Configuration block; versions are expressed as major-only (for example "Angular 22.x") with
core-web/package.jsonnamed as the source of truth - The header at L3 no longer says "Angular v20+"
- No version string in the file contradicts
core-web/package.jsononorigin/main
Commands and package manager
- Every command block in
ANGULAR_STANDARDS.mdusespnpm nx …; no barenx …invocations remain -
yarn installat L287 is replaced withpnpm install - Root
CLAUDE.md:48usespnpm nx serve dotcms-uiand the trailing parenthetical no longer says "use yarn nx, not nx" - Root
CLAUDE.md:102says Angular 22+ -
grep -rn "yarn " docs/frontend/ CLAUDE.mdreturns no results referring to the package manager
Spectator package rename
- All
@ngneat/spectatorreferences indocs/frontend/TESTING_FRONTEND.md,docs/frontend/STATE_MANAGEMENT.md, anddocs/frontend/TESTING_REVIEW_RULES.mdare updated to@openng/spectator -
grep -rn "@ngneat" docs/ CLAUDE.md core-web/CLAUDE.mdreturns no results
Internal consistency (ANGULAR_STANDARDS.md)
- The inline-template contradiction is resolved: L33 and the "File Structure Requirements" section at L108–138 state one consistent rule
- The "Standalone Component Pattern (Required)" example at L210–239 conforms to whichever rule is chosen — it currently uses an inline template while the doc forbids them
- The component example at L151–179 uses
DestroyRef/takeUntilDestroyed(), or explicitly documents why thedestroy$Subject pattern is still preferred in this codebase
TypeScript 6
- The doc notes the
"ignoreDeprecations": "6.0"flag incore-web/tsconfig.base.json, that it is transitional, and that new code must not rely on the deprecated APIs it unblocks
Angular skill (angular-developer)
- A decision is recorded on how to handle the vendored skill: re-sync from upstream if a v22-aware release exists, or add a thin dotCMS overlay — rather than silently hand-editing the vendored files into an undocumented fork
- Whichever route is taken, an Angular-coding agent working in this repo is told: do not set
standalone: true, do not setchangeDetectionon new components, build and test throughpnpm nxrather thanng, and use Jest with@openng/spectator - The two concrete contradictions at
references/signal-forms.md:556and:559no longer instruct agents to write code that violatesANGULAR_STANDARDS.md - The
ng build/ng new/ng testguidance is either scoped as not-applicable-here or replaced with thepnpm nxequivalents - If the vendored skill is edited in place, the divergence from upstream is documented inside the skill directory so a future re-sync does not silently revert it
- If an overlay skill is added, it is registered in
.claude/skills/CATALOG.mdand satisfies.claude/skills/skills.config.jsongovernance (dot-prefix,owner,status)
Verification
- Every claim remaining in the touched files is checked against
origin/main— no version, command, package name, or API reference contradicts the actual workspace - Internal relative links in the touched files still resolve
-
docs/frontend/ANGULAR_STANDARDS.mdcontains no rule that contradicts another rule in the same file
Priority
Low
Additional Context
Follow-up to #35930 (Migrate Angular 21 → Angular 22 (TypeScript 6) across the core-web Nx workspace), which is closed and shipped in release 26.08.07-01.
Out of scope, tracked separately:
- Code-level change detection cleanup. The 219
ChangeDetectionStrategy.Eageroccurrences stay as they are. Per the rule above they are deliberate, and reverting them would re-break what PR #36907 fixed. This issue only documents the policy. nx.json:20. The@nx/angular:componentgenerator is configured with"changeDetection": "OnPush", so newly generated components receive an explicitOnPushline that is now redundant under the v22 default. Removing it is a config change, not a docs change, and needs its own issue.ignoreDeprecationsremoval. Migrating the deprecated usages so the flag can be dropped fromtsconfig.base.jsonis code work; this issue only documents that the flag exists and is transitional.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.