| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 1 | 22 | 23 | 2% |
| Commands | 0 | 3 | 23 | 0% |
| Section tags | 5 | 6 | 2 | 38% |
What each file covers
Sections
1 shared · 22 only in A · 23 only in B- − Project Structure
- − Environment Prerequisites
- − Build & Test Commands
- − Build (choose based on scope)
- − Test (⚠️ NEVER run full integration suite — 60+ min)
- − IDE Testing (fastest iteration)
- − Run
- − Essential Java Patterns
- − Critical Rules
- − OpenAPI / Swagger
- − Progressive Enhancement
- − Tech Stack
- − Documentation (Load On-Demand)
- − Core Architecture & Workflows
- − Backend Development (Java/Maven)
- − Frontend Development (Angular/TypeScript)
- − Testing
- − Infrastructure
- − Context Management
- − For Claude
- − For Cursor
- − Documentation Maintenance
- + Overview
- + MCP Servers
- + Essential Commands
- + Architecture
- + Where Code Goes
- + Code Placement Rules
- + Angular Rules (REQUIRED)
- + Modern Syntax — Always Use
- + Component Conventions
- + Form Markup
- + Portlet Development
- + Testing (Jest + Spectator)
- + Config
- + SignalStore Tests
- + Component Tests (with Mocked Store)
- + Dialog Tests
- + DotSiteComponent Mocking
- + Debounce / Timer Tests
- + Backend Integration
- + For Backend/Java Development
- + General Guidelines for working with Nx
- + Scaffolding & Generators
- + When to use nx_docs
- CLAUDE.md
Commands
0 shared · 3 only in A · 23 only in B- − just test-integration-ide
- − just test-integration-stop
- − just dev-run
- + pnpm nx serve dotcms-ui
- + pnpm nx build dotcms-ui
- + pnpm nx test {project}
- + pnpm nx test {project} --testPathPattern=
- + pnpm nx lint {project}
- + pnpm nx affected:test
- + pnpm run test:dotcms
- + pnpm run lint:dotcms
- + pnpm nx
- + jest.mock()
- + jest.fn().mockReturnValue(...)
- + jest.fn()
- + jest.mock('@dotcms/ui', ...)
- + jest.useFakeTimers()
- + jest.useRealTimers()
- + jest.advanceTimersByTime(300)
- + nx-workspace
- + nx run-many
- + nx affected
- + pnpm nx build
- + npm exec nx test
- + nx-generate
- + nx g @nx/react:app
Section tags
5 shared · 6 only in A · 2 only in B- − setup
- − build
- − types
- − git-pr
- − api
- − docs
- + testing-strategy
- + ui
- test
- code-style
- architecture
- do-not
- agent-behaviour
Line diff
dotCMS/core · CLAUDE.md
@@ −1 @@
1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Project Structure
6
7```
8core/
9├── dotCMS/ # Main backend Java code
10│ └── src/main/java/com/
11│ ├── dotcms/ # Modern domain-driven packages (prefer these)
12│ └── dotmarketing/ # Legacy packages (15+ yr old code, still active)
13├── core-web/ # Frontend (Angular/Nx monorepo) → see core-web/CLAUDE.md
14├── dotcms-integration/ # Integration tests
15├── dotcms-postman/ # Postman API tests
16├── bom/application/pom.xml # Dependency versions (ONLY place for versions)
17├── parent/pom.xml # Plugin management
18└── .github/workflows/ # CI/CD pipelines
19```
20
21## Environment Prerequisites
22
23```bash
24sdk env install # Java 25 via SDKMAN (.sdkmanrc) — build fails with wrong version
25nvm use # Node 22.22.3+ via nvm (.nvmrc) — frontend build fails with wrong version
26```
27
28## Build & Test Commands
29
30```bash
31# Build (choose based on scope)
32./mvnw install -pl :dotcms-core --am -DskipTests # Core + in-project deps (~2-3 min) ✅
33./mvnw install -pl :dotcms-core -DskipTests # ⚠️ Can fail: missing in-project deps
34./mvnw clean install -DskipTests # Full rebuild (~8-15 min)
35./mvnw clean install -DskipTests -Ddocker.skip # Full rebuild, skip Docker image
36
37# Test (⚠️ NEVER run full integration suite — 60+ min)
38./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTestClass # Specific class
39./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTest#testMethod # Specific method
40./mvnw verify -pl :dotcms-postman -Dpostman.test.skip=false -Dpostman.collections=all # Postman
41
42# IDE Testing (fastest iteration)
43just test-integration-ide # Start PostgreSQL + Elasticsearch + dotCMS
44just test-integration-stop # Stop services when done
45
46# Run
47just dev-run # Start dotCMS in Docker with Glowroot
48cd core-web && yarn nx serve dotcms-ui # Frontend dev server only (use yarn nx, not nx)
49```
50
51> All test modules need explicit `skip=false` flags or tests are silently skipped.
52
53## Essential Java Patterns
54
55```java
56import com.dotmarketing.util.Config; // Config.getStringProperty("key", "default")
57import com.dotmarketing.util.Logger; // Logger.info(this, "message")
58import com.dotmarketing.util.UtilMethods; // UtilMethods.isSet(value)
59UserAPI userAPI = APILocator.getUserAPI(); // Service access pattern
60```
61
62> **Batch permission filtering**: prefer `permissionAPI.filterCollection(Collection<P>, int, User, boolean)` over per-item `doesUserHavePermission` loops — one SQL round-trip vs N. See [Java Standards → Permission Checks](docs/backend/JAVA_STANDARDS.md#permission-checks--batch-vs-scalar).
63
64## Critical Rules
65
66- **Config/Logger only**: Never `System.out`, `System.getProperty`, or `System.getenv`
67- **Maven versions**: Add to `bom/application/pom.xml` ONLY, never `dotCMS/pom.xml`
68- **Java version**: Core modules compile to Java 25 by default (`dotcms.core.compiler.release`; override e.g. `-Ddotcms.core.compiler.release=11` for older bytecode). Java 25 runtime. CLI may target lower for portability.
69- **Security**: No hardcoded secrets, validate all input, never log sensitive data
70- **REST @Schema**: Must match actual return type — see [REST API Guide](dotCMS/src/main/java/com/dotcms/rest/CLAUDE.md)
71- **Frontend**: See [core-web/CLAUDE.md](core-web/CLAUDE.md) for Angular/TypeScript standards
72
73### OpenAPI / Swagger
74
75`openapi.yaml` is **auto-generated** by `swagger-maven-plugin` at compile phase — it writes directly to `src/main/webapp/WEB-INF/openapi/openapi.yaml`. The CI verifies the committed file matches what the build produces.
76
77- All description changes must go in Java `@Operation` / `@Parameter` annotations, not in the yaml directly
78- Regenerate after annotation changes: `./mvnw compile -pl :dotcms-core -DskipTests` (no Docker needed)
79- Commit the regenerated yaml alongside the Java changes
80
81### Progressive Enhancement
82
83When editing ANY code, improve incrementally:
84- Add missing generics: `List<String>` not `List`
85- Replace legacy: `Logger.info()` not `System.out.println()`
86- Modern Angular: `@if` not `*ngIf`, `input()` not `@Input()`
87- Add missing annotations: `@Override`, `@Nullable`
88
89## Tech Stack
90
91- **Backend**: Java 25 (runtime + core compile target, override-able), Maven, Spring/CDI
92- **Frontend**: Angular 21+, Nx, PrimeNG, Tailwind CSS, Jest/Spectator — [core-web/CLAUDE.md](core-web/CLAUDE.md)
93- **Infrastructure**: Docker, PostgreSQL, Elasticsearch, GitHub Actions
94
95## Documentation (Load On-Demand)
96
97### Core Architecture & Workflows
98- [Architecture Overview](docs/core/ARCHITECTURE_OVERVIEW.md) — System design, modules, patterns
99- [Git Workflows](docs/core/GIT_WORKFLOWS.md) — Branch naming, PR process, conventional commits
100- [CI/CD Pipeline](docs/core/CICD_PIPELINE.md) — Build process, testing, deployment
101- [Security Principles](docs/core/SECURITY_PRINCIPLES.md) — Input validation, secrets, logging
102- [GitHub Issue Management](docs/core/GITHUB_ISSUE_MANAGEMENT.md) — Issues, PRs, epics
103- [Rollback-Unsafe Change Categories](docs/core/ROLLBACK_UNSAFE_CATEGORIES.md) — DB schema, ES mapping, API contract risks
104
105### Backend Development (Java/Maven)
106- [Java Standards](docs/backend/JAVA_STANDARDS.md) — Coding patterns, immutables, exceptions, utilities
107- [REST API Patterns](docs/backend/REST_API_PATTERNS.md) — JAX-RS, Swagger, @Schema rules
108- [Maven Build System](docs/backend/MAVEN_BUILD_SYSTEM.md) — Dependency management
109- [Configuration Patterns](docs/backend/CONFIGURATION_PATTERNS.md) — Config.getProperty() usage
110- [Database Patterns](docs/backend/DATABASE_PATTERNS.md) — DotConnect, transactions
111- [Health Monitoring](docs/backend/HEALTH_MONITORING.md) — Health endpoints, log levels
112
113### Frontend Development (Angular/TypeScript)
114- [Angular Standards](docs/frontend/ANGULAR_STANDARDS.md) — Modern syntax, signals, components
115- [Testing Frontend](docs/frontend/TESTING_FRONTEND.md) — Spectator patterns, Jest config
116- [Component Architecture](docs/frontend/COMPONENT_ARCHITECTURE.md) — Structure, organization
117- [Styling Standards](docs/frontend/STYLING_STANDARDS.md) — SCSS, BEM, Tailwind
118
119### Testing
120- [Backend Unit Tests](docs/testing/BACKEND_UNIT_TESTS.md) — JUnit, integration patterns
121- [Integration Tests](docs/testing/INTEGRATION_TESTS.md) — API testing, database setup
122- [E2E Tests](docs/testing/E2E_TESTS.md) — Playwright, user workflows
123
124### Infrastructure
125- [Docker Build Process](docs/infrastructure/DOCKER_BUILD_PROCESS.md) — Container setup, optimization
126
127## Context Management
128
129### For Claude
130- Use this guide for always-available context
131- Load `/docs/` files on-demand with Read tool
132- Use `/clear` between different work contexts
133
134### For Cursor
135- Project rules: `.cursor/rules/` (`.mdc` files with globs); see `.cursor/rules/README.md`
136- Use `@docs/path/file.md` syntax for detailed patterns
137- Domain-specific rules load by file pattern (Java, Angular, tests, docs)
138
139## Documentation Maintenance
140
141- **CLAUDE.md**: Navigation hub + essential quick-reference only
142- **`/docs/`**: Full patterns by domain — single source of truth
143- **`.cursor/rules/`**: Short reminders with globs, link to `/docs/`
144- When patterns are missing: update the relevant `/docs/{domain}/` file, not this file
145
dotCMS/core · core-web/CLAUDE.md
@@ +1 @@
1# CLAUDE.md
2
3This file provides guidance to Claude Code when working with code in this repository.
4
5## Overview
6
7DotCMS Core-Web monorepo — Angular + Nx. Uses **pnpm** as package manager. Nx is not installed globally — always use `pnpm nx`.
8
9### MCP Servers
10
11Configured in `/.mcp.json`. Use these instead of guessing:
12
13- **`angular-cli`** — Angular best practices, documentation search, code examples. Use before writing Angular code.
14- **`primeng`** — PrimeNG component API, props, events, examples. Use when building UI.
15- **`chrome-devtools`** — Browser automation, screenshots, network debugging, performance tracing.
16
17## Essential Commands
18
19```bash
20pnpm nx serve dotcms-ui # Dev server (proxies /api/* to port 8080)
21pnpm nx build dotcms-ui # Build
22pnpm nx test {project} # Test specific project
23pnpm nx test {project} --testPathPattern= # Test specific file
24pnpm nx lint {project} # Lint
25pnpm nx affected:test # Test only changed projects
26pnpm run test:dotcms # Test all
27pnpm run lint:dotcms # Lint all
28```
29
30## Architecture
31
32### Where Code Goes
33
34```
35apps/dotcms-ui/ # Main admin UI application
36libs/portlets/ # Feature portlets (new portlets go HERE)
37libs/ui/ # Shared UI components (multi-portlet)
38libs/data-access/ # Shared services (multi-portlet)
39libs/dotcms-models/ # TypeScript interfaces and types
40libs/edit-content/ # Content editing library
41libs/block-editor/ # TipTap rich text editor
42libs/sdk/ # External SDKs (client, react, angular)
43```
44
45### Code Placement Rules
46
47```
48Is this component/service used by multiple portlets?
49├─ NO → libs/portlets/{feature}/
50└─ YES → Is it domain-agnostic?
51 ├─ YES (UI) → libs/ui/
52 ├─ YES (Service) → libs/data-access/
53 └─ NO → libs/portlets/shared/ or refactor
54```
55
56## Angular Rules (REQUIRED)
57
58### Modern Syntax — Always Use
59
60```typescript
61// Control flow
62@if (condition()) { <content /> } // NOT *ngIf
63@for (item of items(); track item.id) { } // NOT *ngFor
64
65// Inputs/Outputs
66data = input<string>(); // NOT @Input()
67onChange = output<string>(); // NOT @Output()
68
69// Testing selectors
70<button data-testid="submit-btn">Submit</button>
71spectator.query('[data-testid="submit-btn"]');
72spectator.setInput('prop', value); // ALWAYS use setInput
73```
74
75### Component Conventions
76
77- **Prefix**: All components use `dot-` prefix
78- **Standalone**: All new components must be standalone
79- **State**: Use NgRx signals (`@ngrx/signals`) for state management
80- **Styling**: Tailwind CSS + PrimeNG theme (PrimeFlex deprecated/removed — use Tailwind utilities instead)
81- **Testing**: Jest + Spectator, use `data-testid` for selectors
82- **Dialogs**: All dialogs must have `closable: true` and `closeOnEscape: true` to allow closing via X button and ESC key
83
84### Form Markup
85
86Always wrap form fields with this structure for consistent styling:
87
88```html
89<form class="form">
90 <div class="field">
91 <label for="name">Name</label>
92 <input pInputText id="name" />
93 </div>
94 <div class="field">
95 <label for="site">Site</label>
96 <p-select id="site" [options]="sites()" />
97 </div>
98</form>
99```
100
101## Portlet Development
102
103New portlets go in `libs/portlets/`. For full patterns, architecture, testing, and Nx generator setup:
104
105> **See [`libs/portlets/CLAUDE.md`](libs/portlets/CLAUDE.md)** — the complete portlet development guide with `dot-tags` as canonical reference.
106
107## Testing (Jest + Spectator)
108
109### Config
110
111- Use `dot-content-drive` portlet as reference for test config
112- `tsconfig.spec.json` tsconfig.spec.json must have "isolatedModules": true in compilerOptions
113- `tsconfig.json` — do NOT add `"strict": true` or `"module": "preserve"`
114- `tsconfig.spec.json` — keep minimal (only `module`, `target`, `types`)
115- Import `mockProvider` from `@openng/spectator/jest` (not `@openng/spectator`)
116
117### SignalStore Tests
118
119- Use `createServiceFactory` from Spectator
120- Call `spectator.flushEffects()` in `beforeEach` to trigger the `withHooks` `onInit` effect
121- Mock services with `mockProvider(Service, { method: jest.fn().mockReturnValue(of(...)) })`
122- Test error paths: mock service to `throwError(() => error)`, assert `httpErrorManager.handle` was called
123- For `jest.mock()` of utilities: place the mock **before** the import
124
125### Component Tests (with Mocked Store)
126
127- Use `createComponentFactory` from Spectator
128- Store goes in `componentProviders` (component-level injection), not `providers`
129- Mock all signal getters as `jest.fn().mockReturnValue(...)` and all methods as `jest.fn()`
130- PrimeNG button clicks: `spectator.query(byTestId('btn'))?.querySelector('button')` then `spectator.click(el)`
131
132### Dialog Tests
133
134- Mock `DialogService.open` to return `{ onClose: new Subject() }`, then emit a value and complete the subject
135- Two `describe` blocks for create/edit dialog: one with `DynamicDialogConfig.data: {}`, one with `data: { item }`
136- Test that dialogs are configured with `closable: true` and `closeOnEscape: true`
137
138### DotSiteComponent Mocking
139
140- Use `jest.mock('@dotcms/ui', ...)` with a stub implementing `ControlValueAccessor`
141- Add `CUSTOM_ELEMENTS_SCHEMA` when mocking complex child components
142
143### Debounce / Timer Tests
144
145- Use `jest.useFakeTimers()` in `beforeEach`, `jest.useRealTimers()` in `afterEach`
146- Advance with `jest.advanceTimersByTime(300)` to trigger debounced actions
147
148## Backend Integration
149
150- Dev proxy: `proxy-dev.conf.mjs` routes `/api/*` to port 8080
151- API services: `libs/data-access/` via `DotHttpService`
152- OpenAPI spec: Use `http://localhost:8080/api/openapi.json` (local dev instance), fallback to `https://demo.dotcms.com/api/openapi.json`. Fetch this to understand available endpoints, request/response schemas, and parameters before building API integrations.
153
154## For Backend/Java Development
155
156See **[../CLAUDE.md](../CLAUDE.md)** for Java, Maven, REST API, and Git workflow standards.
157
158<!-- nx configuration start-->
159<!-- Leave the start & end comments to automatically receive updates. -->
160
161## General Guidelines for working with Nx
162
163- For navigating/exploring the workspace, invoke the `nx-workspace` skill first - it has patterns for querying projects, targets, and dependencies
164- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
165- Prefix nx commands with the workspace's package manager (e.g., `pnpm nx build`, `npm exec nx test`) - avoids using globally installed CLI
166- You have access to the Nx MCP server and its tools, use them to help the user
167- For Nx plugin best practices, check `node_modules/@nx/<plugin>/PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable.
168- NEVER guess CLI flags - always check nx_docs or `--help` first when unsure
169
170## Scaffolding & Generators
171
172- For scaffolding tasks (creating apps, libs, project structure, setup), ALWAYS invoke the `nx-generate` skill FIRST before exploring or calling MCP tools
173
174## When to use nx_docs
175
176- USE for: advanced config options, unfamiliar flags, migration guides, plugin configuration, edge cases
177- DON'T USE for: basic generator syntax (`nx g @nx/react:app`), standard commands, things you already know
178- The `nx-generate` skill handles generator discovery internally - don't call nx_docs just to look up generator syntax
179
180<!-- nx configuration end-->
181
@@ −1 +1 @@
11 # CLAUDE.md
22
3−This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
3+This file provides guidance to Claude Code when working with code in this repository.
44
5−## Project Structure
5+## Overview
66
7+DotCMS Core-Web monorepo — Angular + Nx. Uses **pnpm** as package manager. Nx is not installed globally — always use `pnpm nx`.
8+
9+### MCP Servers
10+
11+Configured in `/.mcp.json`. Use these instead of guessing:
12+
13+- **`angular-cli`** — Angular best practices, documentation search, code examples. Use before writing Angular code.
14+- **`primeng`** — PrimeNG component API, props, events, examples. Use when building UI.
15+- **`chrome-devtools`** — Browser automation, screenshots, network debugging, performance tracing.
16+
17+## Essential Commands
18+
19+```bash
20+pnpm nx serve dotcms-ui # Dev server (proxies /api/* to port 8080)
21+pnpm nx build dotcms-ui # Build
22+pnpm nx test {project} # Test specific project
23+pnpm nx test {project} --testPathPattern= # Test specific file
24+pnpm nx lint {project} # Lint
25+pnpm nx affected:test # Test only changed projects
26+pnpm run test:dotcms # Test all
27+pnpm run lint:dotcms # Lint all
728 ```
8−core/
9−├── dotCMS/ # Main backend Java code
10−│ └── src/main/java/com/
11−│ ├── dotcms/ # Modern domain-driven packages (prefer these)
12−│ └── dotmarketing/ # Legacy packages (15+ yr old code, still active)
13−├── core-web/ # Frontend (Angular/Nx monorepo) → see core-web/CLAUDE.md
14−├── dotcms-integration/ # Integration tests
15−├── dotcms-postman/ # Postman API tests
16−├── bom/application/pom.xml # Dependency versions (ONLY place for versions)
17−├── parent/pom.xml # Plugin management
18−└── .github/workflows/ # CI/CD pipelines
29+
30+## Architecture
31+
32+### Where Code Goes
33+
1934 ```
35+apps/dotcms-ui/ # Main admin UI application
36+libs/portlets/ # Feature portlets (new portlets go HERE)
37+libs/ui/ # Shared UI components (multi-portlet)
38+libs/data-access/ # Shared services (multi-portlet)
39+libs/dotcms-models/ # TypeScript interfaces and types
40+libs/edit-content/ # Content editing library
41+libs/block-editor/ # TipTap rich text editor
42+libs/sdk/ # External SDKs (client, react, angular)
43+```
2044
21−## Environment Prerequisites
45+### Code Placement Rules
2246
23−```bash
24−sdk env install # Java 25 via SDKMAN (.sdkmanrc) — build fails with wrong version
25−nvm use # Node 22.22.3+ via nvm (.nvmrc) — frontend build fails with wrong version
2647 ```
48+Is this component/service used by multiple portlets?
49+├─ NO → libs/portlets/{feature}/
50+└─ YES → Is it domain-agnostic?
51+ ├─ YES (UI) → libs/ui/
52+ ├─ YES (Service) → libs/data-access/
53+ └─ NO → libs/portlets/shared/ or refactor
54+```
2755
28−## Build & Test Commands
56+## Angular Rules (REQUIRED)
2957
30−```bash
31−# Build (choose based on scope)
32−./mvnw install -pl :dotcms-core --am -DskipTests # Core + in-project deps (~2-3 min) ✅
33−./mvnw install -pl :dotcms-core -DskipTests # ⚠️ Can fail: missing in-project deps
34−./mvnw clean install -DskipTests # Full rebuild (~8-15 min)
35−./mvnw clean install -DskipTests -Ddocker.skip # Full rebuild, skip Docker image
58+### Modern Syntax — Always Use
3659
37−# Test (⚠️ NEVER run full integration suite — 60+ min)
38−./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTestClass # Specific class
39−./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTest#testMethod # Specific method
40−./mvnw verify -pl :dotcms-postman -Dpostman.test.skip=false -Dpostman.collections=all # Postman
60+```typescript
61+// Control flow
62+@if (condition()) { <content /> } // NOT *ngIf
63+@for (item of items(); track item.id) { } // NOT *ngFor
4164
42−# IDE Testing (fastest iteration)
43−just test-integration-ide # Start PostgreSQL + Elasticsearch + dotCMS
44−just test-integration-stop # Stop services when done
65+// Inputs/Outputs
66+data = input<string>(); // NOT @Input()
67+onChange = output<string>(); // NOT @Output()
4568
46−# Run
47−just dev-run # Start dotCMS in Docker with Glowroot
48−cd core-web && yarn nx serve dotcms-ui # Frontend dev server only (use yarn nx, not nx)
69+// Testing selectors
70+<button data-testid="submit-btn">Submit</button>
71+spectator.query('[data-testid="submit-btn"]');
72+spectator.setInput('prop', value); // ALWAYS use setInput
4973 ```
5074
51−> All test modules need explicit `skip=false` flags or tests are silently skipped.
75+### Component Conventions
5276
53−## Essential Java Patterns
77+- **Prefix**: All components use `dot-` prefix
78+- **Standalone**: All new components must be standalone
79+- **State**: Use NgRx signals (`@ngrx/signals`) for state management
80+- **Styling**: Tailwind CSS + PrimeNG theme (PrimeFlex deprecated/removed — use Tailwind utilities instead)
81+- **Testing**: Jest + Spectator, use `data-testid` for selectors
82+- **Dialogs**: All dialogs must have `closable: true` and `closeOnEscape: true` to allow closing via X button and ESC key
5483
55−```java
56−import com.dotmarketing.util.Config; // Config.getStringProperty("key", "default")
57−import com.dotmarketing.util.Logger; // Logger.info(this, "message")
58−import com.dotmarketing.util.UtilMethods; // UtilMethods.isSet(value)
59−UserAPI userAPI = APILocator.getUserAPI(); // Service access pattern
84+### Form Markup
85+
86+Always wrap form fields with this structure for consistent styling:
87+
88+```html
89+<form class="form">
90+ <div class="field">
91+ <label for="name">Name</label>
92+ <input pInputText id="name" />
93+ </div>
94+ <div class="field">
95+ <label for="site">Site</label>
96+ <p-select id="site" [options]="sites()" />
97+ </div>
98+</form>
6099 ```
61100
62−> **Batch permission filtering**: prefer `permissionAPI.filterCollection(Collection<P>, int, User, boolean)` over per-item `doesUserHavePermission` loops — one SQL round-trip vs N. See [Java Standards → Permission Checks](docs/backend/JAVA_STANDARDS.md#permission-checks--batch-vs-scalar).
101+## Portlet Development
63102
64−## Critical Rules
103+New portlets go in `libs/portlets/`. For full patterns, architecture, testing, and Nx generator setup:
65104
66−- **Config/Logger only**: Never `System.out`, `System.getProperty`, or `System.getenv`
67−- **Maven versions**: Add to `bom/application/pom.xml` ONLY, never `dotCMS/pom.xml`
68−- **Java version**: Core modules compile to Java 25 by default (`dotcms.core.compiler.release`; override e.g. `-Ddotcms.core.compiler.release=11` for older bytecode). Java 25 runtime. CLI may target lower for portability.
69−- **Security**: No hardcoded secrets, validate all input, never log sensitive data
70−- **REST @Schema**: Must match actual return type — see [REST API Guide](dotCMS/src/main/java/com/dotcms/rest/CLAUDE.md)
71−- **Frontend**: See [core-web/CLAUDE.md](core-web/CLAUDE.md) for Angular/TypeScript standards
105+> **See [`libs/portlets/CLAUDE.md`](libs/portlets/CLAUDE.md)** — the complete portlet development guide with `dot-tags` as canonical reference.
72106
73−### OpenAPI / Swagger
107+## Testing (Jest + Spectator)
74108
75−`openapi.yaml` is **auto-generated** by `swagger-maven-plugin` at compile phase — it writes directly to `src/main/webapp/WEB-INF/openapi/openapi.yaml`. The CI verifies the committed file matches what the build produces.
109+### Config
76110
77−- All description changes must go in Java `@Operation` / `@Parameter` annotations, not in the yaml directly
78−- Regenerate after annotation changes: `./mvnw compile -pl :dotcms-core -DskipTests` (no Docker needed)
79−- Commit the regenerated yaml alongside the Java changes
111+- Use `dot-content-drive` portlet as reference for test config
112+- `tsconfig.spec.json` tsconfig.spec.json must have "isolatedModules": true in compilerOptions
113+- `tsconfig.json` — do NOT add `"strict": true` or `"module": "preserve"`
114+- `tsconfig.spec.json` — keep minimal (only `module`, `target`, `types`)
115+- Import `mockProvider` from `@openng/spectator/jest` (not `@openng/spectator`)
80116
81−### Progressive Enhancement
117+### SignalStore Tests
82118
83−When editing ANY code, improve incrementally:
84−- Add missing generics: `List<String>` not `List`
85−- Replace legacy: `Logger.info()` not `System.out.println()`
86−- Modern Angular: `@if` not `*ngIf`, `input()` not `@Input()`
87−- Add missing annotations: `@Override`, `@Nullable`
119+- Use `createServiceFactory` from Spectator
120+- Call `spectator.flushEffects()` in `beforeEach` to trigger the `withHooks` `onInit` effect
121+- Mock services with `mockProvider(Service, { method: jest.fn().mockReturnValue(of(...)) })`
122+- Test error paths: mock service to `throwError(() => error)`, assert `httpErrorManager.handle` was called
123+- For `jest.mock()` of utilities: place the mock **before** the import
88124
89−## Tech Stack
125+### Component Tests (with Mocked Store)
90126
91−- **Backend**: Java 25 (runtime + core compile target, override-able), Maven, Spring/CDI
92−- **Frontend**: Angular 21+, Nx, PrimeNG, Tailwind CSS, Jest/Spectator — [core-web/CLAUDE.md](core-web/CLAUDE.md)
93−- **Infrastructure**: Docker, PostgreSQL, Elasticsearch, GitHub Actions
127+- Use `createComponentFactory` from Spectator
128+- Store goes in `componentProviders` (component-level injection), not `providers`
129+- Mock all signal getters as `jest.fn().mockReturnValue(...)` and all methods as `jest.fn()`
130+- PrimeNG button clicks: `spectator.query(byTestId('btn'))?.querySelector('button')` then `spectator.click(el)`
94131
95−## Documentation (Load On-Demand)
132+### Dialog Tests
96133
97−### Core Architecture & Workflows
98−- [Architecture Overview](docs/core/ARCHITECTURE_OVERVIEW.md) — System design, modules, patterns
99−- [Git Workflows](docs/core/GIT_WORKFLOWS.md) — Branch naming, PR process, conventional commits
100−- [CI/CD Pipeline](docs/core/CICD_PIPELINE.md) — Build process, testing, deployment
101−- [Security Principles](docs/core/SECURITY_PRINCIPLES.md) — Input validation, secrets, logging
102−- [GitHub Issue Management](docs/core/GITHUB_ISSUE_MANAGEMENT.md) — Issues, PRs, epics
103−- [Rollback-Unsafe Change Categories](docs/core/ROLLBACK_UNSAFE_CATEGORIES.md) — DB schema, ES mapping, API contract risks
134+- Mock `DialogService.open` to return `{ onClose: new Subject() }`, then emit a value and complete the subject
135+- Two `describe` blocks for create/edit dialog: one with `DynamicDialogConfig.data: {}`, one with `data: { item }`
136+- Test that dialogs are configured with `closable: true` and `closeOnEscape: true`
104137
105−### Backend Development (Java/Maven)
106−- [Java Standards](docs/backend/JAVA_STANDARDS.md) — Coding patterns, immutables, exceptions, utilities
107−- [REST API Patterns](docs/backend/REST_API_PATTERNS.md) — JAX-RS, Swagger, @Schema rules
108−- [Maven Build System](docs/backend/MAVEN_BUILD_SYSTEM.md) — Dependency management
109−- [Configuration Patterns](docs/backend/CONFIGURATION_PATTERNS.md) — Config.getProperty() usage
110−- [Database Patterns](docs/backend/DATABASE_PATTERNS.md) — DotConnect, transactions
111−- [Health Monitoring](docs/backend/HEALTH_MONITORING.md) — Health endpoints, log levels
138+### DotSiteComponent Mocking
112139
113−### Frontend Development (Angular/TypeScript)
114−- [Angular Standards](docs/frontend/ANGULAR_STANDARDS.md) — Modern syntax, signals, components
115−- [Testing Frontend](docs/frontend/TESTING_FRONTEND.md) — Spectator patterns, Jest config
116−- [Component Architecture](docs/frontend/COMPONENT_ARCHITECTURE.md) — Structure, organization
117−- [Styling Standards](docs/frontend/STYLING_STANDARDS.md) — SCSS, BEM, Tailwind
140+- Use `jest.mock('@dotcms/ui', ...)` with a stub implementing `ControlValueAccessor`
141+- Add `CUSTOM_ELEMENTS_SCHEMA` when mocking complex child components
118142
119−### Testing
120−- [Backend Unit Tests](docs/testing/BACKEND_UNIT_TESTS.md) — JUnit, integration patterns
121−- [Integration Tests](docs/testing/INTEGRATION_TESTS.md) — API testing, database setup
122−- [E2E Tests](docs/testing/E2E_TESTS.md) — Playwright, user workflows
143+### Debounce / Timer Tests
123144
124−### Infrastructure
125−- [Docker Build Process](docs/infrastructure/DOCKER_BUILD_PROCESS.md) — Container setup, optimization
145+- Use `jest.useFakeTimers()` in `beforeEach`, `jest.useRealTimers()` in `afterEach`
146+- Advance with `jest.advanceTimersByTime(300)` to trigger debounced actions
126147
127−## Context Management
148+## Backend Integration
128149
129−### For Claude
130−- Use this guide for always-available context
131−- Load `/docs/` files on-demand with Read tool
132−- Use `/clear` between different work contexts
150+- Dev proxy: `proxy-dev.conf.mjs` routes `/api/*` to port 8080
151+- API services: `libs/data-access/` via `DotHttpService`
152+- OpenAPI spec: Use `http://localhost:8080/api/openapi.json` (local dev instance), fallback to `https://demo.dotcms.com/api/openapi.json`. Fetch this to understand available endpoints, request/response schemas, and parameters before building API integrations.
133153
134−### For Cursor
135−- Project rules: `.cursor/rules/` (`.mdc` files with globs); see `.cursor/rules/README.md`
136−- Use `@docs/path/file.md` syntax for detailed patterns
137−- Domain-specific rules load by file pattern (Java, Angular, tests, docs)
154+## For Backend/Java Development
138155
139−## Documentation Maintenance
156+See **[../CLAUDE.md](../CLAUDE.md)** for Java, Maven, REST API, and Git workflow standards.
140157
141−- **CLAUDE.md**: Navigation hub + essential quick-reference only
142−- **`/docs/`**: Full patterns by domain — single source of truth
143−- **`.cursor/rules/`**: Short reminders with globs, link to `/docs/`
144−- When patterns are missing: update the relevant `/docs/{domain}/` file, not this file
158+<!-- nx configuration start-->
159+<!-- Leave the start & end comments to automatically receive updates. -->
160+
161+## General Guidelines for working with Nx
162+
163+- For navigating/exploring the workspace, invoke the `nx-workspace` skill first - it has patterns for querying projects, targets, and dependencies
164+- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
165+- Prefix nx commands with the workspace's package manager (e.g., `pnpm nx build`, `npm exec nx test`) - avoids using globally installed CLI
166+- You have access to the Nx MCP server and its tools, use them to help the user
167+- For Nx plugin best practices, check `node_modules/@nx/<plugin>/PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable.
168+- NEVER guess CLI flags - always check nx_docs or `--help` first when unsure
169+
170+## Scaffolding & Generators
171+
172+- For scaffolding tasks (creating apps, libs, project structure, setup), ALWAYS invoke the `nx-generate` skill FIRST before exploring or calling MCP tools
173+
174+## When to use nx_docs
175+
176+- USE for: advanced config options, unfamiliar flags, migration guides, plugin configuration, edge cases
177+- DON'T USE for: basic generator syntax (`nx g @nx/react:app`), standard commands, things you already know
178+- The `nx-generate` skill handles generator discovery internally - don't call nx_docs just to look up generator syntax
179+
180+<!-- nx configuration end-->
145181
