core/
├── dotCMS/ # Main backend Java code
│ └── src/main/java/com/ # Java source files
├── core-web/ # Frontend (Angular/Nx monorepo) → see core-web/CLAUDE.md
├── dotcms-integration/ # Integration tests
├── dotcms-postman/ # Postman API tests
├── bom/application/pom.xml # Dependency versions (ONLY place for versions)
├── parent/pom.xml # Plugin management
└── .github/workflows/ # CI/CD pipelines
# Build (choose based on scope)
./mvnw install -pl :dotcms-core -DskipTests # Simple core changes (~2-3 min)
./mvnw install -pl :dotcms-core --am -DskipTests # Core + dependencies (~3-5 min)
./mvnw clean install -DskipTests # Full rebuild (~8-15 min)
# Test (⚠️ NEVER run full integration suite — 60+ min)
./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTestClass # Specific class
./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTest#testMethod # Specific method
./mvnw verify -pl :dotcms-postman -Dpostman.test.skip=false -Dpostman.collections=all # Postman
# IDE Testing (fastest iteration)
just test-integration-ide # Start PostgreSQL + Elasticsearch + dotCMS
just test-integration-stop # Stop services when done
# Run
just dev-run # Start dotCMS in Docker with Glowroot
cd core-web && nx run dotcms-ui:serve # Frontend dev server onlyAll test modules need explicit
skip=falseflags or tests are silently skipped.
import com.dotmarketing.util.Config; // Config.getStringProperty("key", "default")
import com.dotmarketing.util.Logger; // Logger.info(this, "message")
import com.dotmarketing.util.UtilMethods; // UtilMethods.isSet(value)
UserAPI userAPI = APILocator.getUserAPI(); // Service access pattern- Config/Logger only: Never
System.out,System.getProperty, orSystem.getenv - Maven versions: Add to
bom/application/pom.xmlONLY, neverdotCMS/pom.xml - Java syntax: Java 11 compatible in core modules (Java 21 runtime, CLI exception)
- Security: No hardcoded secrets, validate all input, never log sensitive data
- REST @Schema: Must match actual return type — see REST API Guide
- Frontend: See core-web/CLAUDE.md for Angular/TypeScript standards
When editing ANY code, improve incrementally:
- Add missing generics:
List<String>notList - Replace legacy:
Logger.info()notSystem.out.println() - Modern Angular:
@ifnot*ngIf,input()not@Input() - Add missing annotations:
@Override,@Nullable
- Backend: Java 21 runtime, Java 11 syntax (core), Maven, Spring/CDI
- Frontend: Angular 19+, Nx, PrimeNG, Tailwind CSS, Jest/Spectator — core-web/CLAUDE.md
- Infrastructure: Docker, PostgreSQL, Elasticsearch, GitHub Actions
- Architecture Overview — System design, modules, patterns
- Git Workflows — Branch naming, PR process, conventional commits
- CI/CD Pipeline — Build process, testing, deployment
- Security Principles — Input validation, secrets, logging
- GitHub Issue Management — Issues, PRs, epics
- Rollback-Unsafe Change Categories — DB schema, ES mapping, API contract risks
- Java Standards — Coding patterns, immutables, exceptions, utilities
- REST API Patterns — JAX-RS, Swagger, @Schema rules
- Maven Build System — Dependency management
- Configuration Patterns — Config.getProperty() usage
- Database Patterns — DotConnect, transactions
- Health Monitoring — Health endpoints, log levels
- Angular Standards — Modern syntax, signals, components
- Testing Frontend — Spectator patterns, Jest config
- Component Architecture — Structure, organization
- Styling Standards — SCSS, BEM, Tailwind
- Backend Unit Tests — JUnit, integration patterns
- Integration Tests — API testing, database setup
- E2E Tests — Playwright, user workflows
- Docker Build Process — Container setup, optimization
- Use this guide for always-available context
- Load
/docs/files on-demand with Read tool - Use
/clearbetween different work contexts
- Project rules:
.cursor/rules/(.mdcfiles with globs); see.cursor/rules/README.md - Use
@docs/path/file.mdsyntax for detailed patterns - Domain-specific rules load by file pattern (Java, Angular, tests, docs)
- CLAUDE.md: Navigation hub + essential quick-reference only
/docs/: Full patterns by domain — single source of truth.cursor/rules/: Short reminders with globs, link to/docs/- When patterns are missing: update the relevant
/docs/{domain}/file, not this file