RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Copilot instructions/dotCMS/core

Copilot instructions

.github/copilot-instructions.md
Copilot instructions

Quality

84/100

Scores the file, not the repository.

Length

3,341 words

134 headings · 33 code blocks

Repository

949

— · pushed 0 days ago

Last changed

today

First indexed 3 days ago.
dotCMS/core/.github/copilot-instructions.mdRawGitHub
1# Copilot Coding Agent Instructions for dotCMS Core
2 
3> **Purpose**: This file provides essential information for AI coding agents working with the dotCMS repository. It contains critical patterns, common errors, and workflows to work efficiently.
4 
5## Repository Overview
6 
7dotCMS is a **Universal Content Management System** - a large-scale enterprise Java/Angular CMS with:
8- **Maven multi-module project** (~30+ modules) for backend
9- **Nx monorepo** for Angular frontend applications and libraries
10- **Mature codebase** with 15+ years of history (mix of modern and legacy patterns)
11 
12**Tech Stack:**
13- **Backend**: Java 21 runtime (Java 11 syntax for core), Maven 3.9+, JAX-RS REST APIs
14- **Frontend**: Angular 20+, TypeScript 5.6+, Nx 20.5+, PrimeNG 17.18+
15- **Infrastructure**: Docker, PostgreSQL, Elasticsearch, Tomcat 9
16- **Testing**: JUnit 5, Jest, Spectator, Playwright, Postman
17 
18**Key Characteristics:**
19- Monolithic architecture with modular design
20- Heavy use of dependency injection (CDI/Guice)
21- Immutable objects pattern (Immutables library)
22- RESTful APIs with OpenAPI/Swagger documentation
23- Reactive patterns with signals in frontend
24 
25## Environment Requirements
26 
27**CRITICAL: Build will fail without correct versions**
28 
29| Tool | Version | Installation | Verification |
30|------|---------|--------------|--------------|
31| Java | 21.0.8+ | `sdk env install` (SDKMAN) | `java -version` |
32| Node.js | 22.22.3+ | `nvm use` (from `.nvmrc`) | `node --version` |
33| Maven | 3.9+ | Wrapper included (`./mvnw`) | `./mvnw --version` |
34| Docker | Latest | [Docker Desktop](https://www.docker.com/products/docker-desktop) | `docker --version` |
35 
36**Common Setup Error #1 - Wrong Java Version:**
37```bash
38# Error: "Building this project requires JDK version 21 or higher"
39# Solution: Install Java 21 with SDKMAN
40sdk env install # Uses .sdkmanrc file
41sdk use java 21.0.8-ms
42```
43 
44## Build Commands (Choose the Right One!)
45 
46**⚠️ CRITICAL**: Build times vary significantly (2-15 min). Choose based on your changes.
47 
48### Quick Reference
49```bash
50# ❌ WRONG - Missing dependencies
51./mvnw install -pl :dotcms-core -DskipTests
52# Error: "Cannot resolve in-project dependency: com.dotcms:dotcms-core-web"
53 
54# ✅ CORRECT - For simple backend changes (~2-3 min)
55./mvnw install -pl :dotcms-core --am -DskipTests
56# The --am flag builds required dependencies
57 
58# ✅ Full build without Docker (~5-8 min)
59./mvnw clean install -DskipTests -Ddocker.skip
60 
61# ✅ Full build with Docker image (~8-15 min)
62./mvnw clean install -DskipTests
63```
64 
65### Using Just Commands (Optional)
66```bash
67# Just provides shorter aliases for common tasks
68brew install just # Install once
69
70just build-quicker # Same as: ./mvnw install -pl :dotcms-core --am -DskipTests
71just build # Same as: ./mvnw clean install -DskipTests
72just build-no-docker # Same as: ./mvnw clean install -DskipTests -Ddocker.skip
73```
74 
75## Testing Commands
76 
77**⚠️ CRITICAL: Never run full integration suite (60+ min). Always target specific tests.**
78 
79### Backend Testing Strategy
80 
81**Common Test Error - Tests Silently Skipped:**
82```bash
83# ❌ WRONG - Tests are skipped by default!
84./mvnw verify -pl :dotcms-integration
85# No error, but tests don't run
86 
87# ✅ CORRECT - Explicit flag required
88./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTest
89```
90 
91**Recommended Testing Workflow:**
92 
93```bash
94# 1. Specific integration test class (~2-10 min) - RECOMMENDED
95./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=ContentTypeAPIImplTest
96 
97# 2. Specific test method (~30 sec - 2 min)
98./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTest#testMethod
99 
100# 3. IDE debugging workflow (FASTEST iteration)
101just test-integration-ide # Start services (PostgreSQL + Elasticsearch + dotCMS)
102# → Run/debug individual tests in your IDE (10-30 sec per test)
103just test-integration-stop # Clean up when done
104 
105# 4. JVM unit tests only (~30 sec)
106./mvnw test -pl :dotcms-core
107 
108# 5. Postman API tests (specific collection)
109./mvnw verify -pl :dotcms-postman -Dpostman.test.skip=false -Dpostman.collections=ai
110just test-postman ai # Shorter command
111 
112# ⚠️ NEVER DO THIS during development (60+ min):
113./mvnw verify -Dcoreit.test.skip=false # Runs ALL integration tests
114```
115 
116### Frontend Testing Commands
117```bash
118cd core-web
119 
120# Install dependencies first
121pnpm install # Required before first test
122 
123# Run specific component tests (RECOMMENDED)
124nx run dotcms-ui:test --testNamePattern="ContentTypeComponent"
125 
126# Run all tests in a file
127nx run dotcms-ui:test --testPathPattern="dot-edit-content"
128 
129# Run all unit tests
130nx run dotcms-ui:test
131 
132# Test only affected by your changes
133nx affected -t test --exclude='tag:skip:test'
134 
135# Lint code
136nx run dotcms-ui:lint --fix
137 
138# Development server (separate from backend)
139nx run dotcms-ui:serve # Available at http://localhost:4200
140```
141 
142## Project Structure
143 
144```
145core/
146├── dotCMS/ # Main backend Java code
147│ ├── src/main/java/com/ # Java source files
148│ │ ├── dotcms/ # Modern domain-driven packages
149│ │ └── dotmarketing/ # Legacy packages
150│ └── src/main/webapp/ # JSP views, static assets
151├── core-web/ # Frontend (Angular/Nx monorepo)
152│ ├── apps/ # Applications
153│ │ ├── dotcms-ui/ # Main admin UI
154│ │ ├── dotcms-block-editor/ # Block editor app
155│ │ └── dotcms-binary-field-builder/
156│ └── libs/ # Shared libraries
157│ ├── sdk/ # External SDKs (client, react, angular)
158│ ├── data-access/ # API services
159│ ├── ui/ # Shared UI components
160│ ├── portlets/ # Feature modules
161│ └── dotcms-models/ # TypeScript interfaces
162├── dotcms-integration/ # Integration tests
163├── dotcms-postman/ # Postman API tests
164├── test-karate/ # Karate API tests
165├── e2e/ # E2E tests (Playwright)
166├── bom/ # Bill of Materials
167│ └── application/pom.xml # ⚠️ DEPENDENCY VERSIONS GO HERE
168├── parent/pom.xml # Plugin management
169├── pom.xml # Root aggregator POM
170├── justfile # Task runner commands
171└── .github/workflows/ # CI/CD pipelines
172 ├── cicd_1-pr.yml # PR builds
173 ├── cicd_2-merge-queue.yml # Merge queue
174 ├── cicd_3-trunk.yml # Trunk builds
175 └── cicd_4-nightly.yml # Nightly builds
176```
177 
178## Critical Patterns (Always Follow)
179 
180### Maven Dependency Management
181 
182**⚠️ CRITICAL RULE: Add dependency versions ONLY to `bom/application/pom.xml`**
183 
184```xml
185<!-- ❌ WRONG - Adding version to module POM -->
186<!-- In dotCMS/pom.xml -->
187<dependency>
188 <groupId>com.example</groupId>
189 <artifactId>my-library</artifactId>
190 <version>1.2.3</version> <!-- NO! This will cause conflicts -->
191</dependency>
192 
193<!-- ✅ CORRECT - Version in BOM, no version in module -->
194<!-- Step 1: In bom/application/pom.xml -->
195<properties>
196 <my-library.version>1.2.3</my-library.version>
197</properties>
198<dependencyManagement>
199 <dependencies>
200 <dependency>
201 <groupId>com.example</groupId>
202 <artifactId>my-library</artifactId>
203 <version>${my-library.version}</version>
204 </dependency>
205 </dependencies>
206</dependencyManagement>
207 
208<!-- Step 2: In dotCMS/pom.xml or other module -->
209<dependency>
210 <groupId>com.example</groupId>
211 <artifactId>my-library</artifactId>
212 <!-- NO version here - inherited from BOM -->
213</dependency>
214```
215 
216**Why**: Centralized version management prevents conflicts across 30+ modules.
217 
218### Java Coding Patterns
219 
220**ALWAYS use these dotCMS utility classes (not standard Java equivalents):**
221 
222```java
223// ✅ Configuration - Use Config class (NOT System.getProperty)
224import com.dotmarketing.util.Config;
225String value = Config.getStringProperty("key", "default");
226boolean enabled = Config.getBooleanProperty("feature.enabled", false);
227int timeout = Config.getIntProperty("timeout.seconds", 30);
228 
229// ✅ Logging - Use Logger class (NOT System.out or Log4j directly)
230import com.dotmarketing.util.Logger;
231Logger.info(this, "Operation completed successfully");
232Logger.error(this, "Error occurred: " + e.getMessage(), e);
233Logger.debug(this, () -> "Expensive string: " + computeExpensiveString());
234 
235// ✅ Services - Use APILocator (NOT direct instantiation)
236import com.dotcms.api.system.APILocator;
237ContentletAPI contentletAPI = APILocator.getContentletAPI();
238UserAPI userAPI = APILocator.getUserAPI();
239PermissionAPI permissionAPI = APILocator.getPermissionAPI();
240 
241// ✅ Null checking - Use UtilMethods (NOT manual null checks)
242import com.dotmarketing.util.UtilMethods;
243if (UtilMethods.isSet(myString)) { // Checks null, empty, "null" string
244 processString(myString);
245}
246 
247// Safe supplier pattern for nested null checks
248String value = UtilMethods.isSet(() -> complex.getObject().getValue())
249 ? complex.getObject().getValue()
250 : "default";
251 
252// ✅ Collections - Use CollectionsUtils
253import com.dotcms.util.CollectionsUtils;
254List<String> list = CollectionsUtils.list("item1", "item2");
255Map<String, Object> map = CollectionsUtils.map("key1", "value1", "key2", "value2");
256```
257 
258### Immutable Objects Pattern
259 
260**Use Immutables library for data objects:**
261 
262```java
263import org.immutables.value.Value;
264import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
265import com.fasterxml.jackson.databind.annotation.JsonSerialize;
266 
267@Value.Immutable
268@JsonSerialize(as = ImmutableMyEntity.class)
269@JsonDeserialize(as = ImmutableMyEntity.class)
270public abstract class MyEntity {
271 public abstract String name();
272 public abstract Optional<String> description();
273
274 @Value.Default
275 public boolean enabled() { return true; }
276
277 // Builder convenience method
278 public static Builder builder() {
279 return ImmutableMyEntity.builder();
280 }
281}
282 
283// ⚠️ IMPORTANT: Run ./mvnw compile after creating @Value.Immutable classes
284// The annotation processor generates ImmutableMyEntity at compile time
285 
286// Usage:
287MyEntity entity = MyEntity.builder()
288 .name("test")
289 .description("optional description")
290 .enabled(false)
291 .build();
292```
293 
294### REST API Patterns (JAX-RS)
295 
296**Complete REST endpoint pattern with OpenAPI documentation:**
297 
298```java
299import javax.ws.rs.*;
300import javax.ws.rs.core.*;
301import io.swagger.v3.oas.annotations.*;
302import io.swagger.v3.oas.annotations.media.*;
303import io.swagger.v3.oas.annotations.parameters.*;
304import io.swagger.v3.oas.annotations.responses.*;
305import io.swagger.v3.oas.annotations.tags.Tag;
306import com.dotcms.rest.WebResource;
307import com.dotcms.rest.annotation.NoCache;
308 
309@Path("/v1/resource")
310@Tag(name = "Resource", description = "Resource operations")
311public class ResourceEndpoint {
312 private final WebResource webResource = new WebResource();
313
314 @GET
315 @Path("/{id}")
316 @Operation(
317 summary = "Get by ID",
318 description = "Retrieves a resource by its identifier"
319 )
320 @ApiResponse(
321 responseCode = "200",
322 description = "Resource found",
323 content = @Content(
324 mediaType = MediaType.APPLICATION_JSON,
325 schema = @Schema(implementation = ResponseEntityResourceView.class)
326 )
327 )
328 @ApiResponse(responseCode = "404", description = "Resource not found")
329 @ApiResponse(responseCode = "401", description = "Unauthorized")
330 @Produces(MediaType.APPLICATION_JSON)
331 @NoCache
332 public Response getById(
333 @Context HttpServletRequest request,
334 @Context HttpServletResponse response,
335 @Parameter(description = "Resource ID", required = true)
336 @PathParam("id") String id) {
337
338 // ALWAYS initialize request context for authentication/permissions
339 InitDataObject initData = webResource.init(request, response, true);
340 User user = initData.getUser();
341
342 // Business logic here
343 Resource resource = resourceAPI.findById(id, user);
344
345 return Response.ok(new ResponseEntityResourceView(resource)).build();
346 }
347}
348```
349 
350**⚠️ CRITICAL: OpenAPI Documentation Rules**
351- ALWAYS add `@Tag` at class level
352- ALWAYS add `@Operation` to every endpoint
353- ALWAYS add `@ApiResponse` for 200 and error codes
354- ALWAYS specify `@Schema(implementation = SpecificView.class)` - NEVER use generic `ResponseEntityView.class`
355- For path parameters: Use `@PathParam` with matching `@Path` placeholder
356- For query parameters: Use `@QueryParam` (e.g., `?filter=value`)
357- ALWAYS add `@NoCache` for REST endpoints that return dynamic data
358 
359### Angular/Frontend Patterns
360 
361**Modern Angular syntax (REQUIRED - no legacy patterns):**
362 
363```typescript
364// ✅ CORRECT: Modern control flow (Angular 19+)
365@if (condition()) {
366 <div>Content</div>
367}
368@for (item of items(); track item.id) {
369 <div>{{ item.name }}</div>
370}
371 
372// ❌ WRONG: Legacy structural directives
373<div *ngIf="condition">Content</div>
374<div *ngFor="let item of items">{{ item.name }}</div>
375 
376// ✅ CORRECT: Modern inputs/outputs (signals)
377export class MyComponent {
378 data = input<string>(); // NOT @Input()
379 onChange = output<string>(); // NOT @Output()
380
381 // Computed values
382 displayValue = computed(() => this.data().toUpperCase());
383}
384 
385// ✅ CORRECT: Testing with Spectator
386describe('MyComponent', () => {
387 let spectator: Spectator<MyComponent>;
388
389 beforeEach(() => {
390 spectator = createComponentFactory({
391 component: MyComponent
392 })();
393 });
394
395 it('should update on input change', () => {
396 // ✅ ALWAYS use spectator.setInput()
397 spectator.setInput('data', 'test value');
398 spectator.detectChanges();
399
400 // ✅ ALWAYS use data-testid for selectors
401 const button = spectator.query('[data-testid="submit-button"]');
402 expect(button).toBeVisible();
403
404 // ✅ Test user interactions
405 spectator.click('[data-testid="submit-button"]');
406 expect(spectator.query('[data-testid="success-message"]')).toExist();
407 });
408});
409 
410// ❌ WRONG: Direct property access in tests
411spectator.component.data = 'value'; // NO! Use setInput()
412```
413 
414## Security Guidelines
415 
416**⚠️ CRITICAL: Security violations are unacceptable and will fail code review.**
417 
418### Never Do These (Security Violations)
419 
420```java
421// ❌ NEVER: Hardcoded secrets or credentials
422String apiKey = "sk-1234567890"; // SECURITY VIOLATION
423String password = "admin123"; // SECURITY VIOLATION
424 
425// ❌ NEVER: Direct input injection without validation
426String sql = "SELECT * FROM users WHERE name = '" + userInput + "'"; // SQL INJECTION
427 
428// ❌ NEVER: Exposing sensitive data in logs
429Logger.info(this, "Password: " + password); // SECURITY VIOLATION
430Logger.info(this, "API Key: " + apiKey); // SECURITY VIOLATION
431 
432// ❌ NEVER: Using System.out/err for any output
433System.out.println("Debug info"); // Use Logger instead
434```
435 
436### Always Do These (Security Best Practices)
437 
438```java
439// ✅ ALWAYS: Validate and sanitize user input
440import com.dotmarketing.util.UtilMethods;
441 
442public void processInput(String userInput) {
443 // Null/empty check
444 if (!UtilMethods.isSet(userInput)) {
445 throw new DotDataException("Input cannot be empty");
446 }
447
448 // Format validation (whitelist approach)
449 if (!userInput.matches("^[a-zA-Z0-9\\s\\-_\\.]+$")) {
450 Logger.warn(this, "Invalid input format attempted");
451 throw new DotSecurityException("Invalid input format");
452 }
453
454 // Length validation
455 if (userInput.length() > 255) {
456 throw new DotDataException("Input exceeds maximum length");
457 }
458
459 // Process validated input
460 processValidatedInput(userInput);
461}
462 
463// ✅ ALWAYS: Use Config for sensitive properties
464String apiKey = Config.getStringProperty("external.api.key", "");
465if (!UtilMethods.isSet(apiKey)) {
466 throw new DotDataException("API key not configured");
467}
468 
469// ✅ ALWAYS: Use proper exception handling
470try {
471 riskyOperation();
472 Logger.info(this, "Operation completed successfully");
473} catch (SQLException e) {
474 Logger.error(this, "Database operation failed", e);
475 throw new DotDataException("Failed to process request", e);
476} catch (Exception e) {
477 Logger.error(this, "Unexpected error", e);
478 throw new DotRuntimeException("System error occurred", e);
479}
480 
481// ✅ ALWAYS: Log safely (no sensitive data)
482Logger.info(this, "User authenticated: " + user.getUserId()); // Log ID, not password
483Logger.debug(this, () -> "Processing " + items.size() + " items"); // Lazy evaluation
484```
485 
486## Common Issues and Solutions
487 
488### Issue #1: Build Fails - Wrong Java Version
489 
490**Error:**
491```
492[ERROR] Rule 1: org.apache.maven.enforcer.rules.version.RequireJavaVersion failed
493[ERROR] Building this project requires JDK version 21 or higher
494```
495 
496**Solution:**
497```bash
498# Check current version
499java -version
500 
501# Install Java 21 with SDKMAN
502sdk env install # Uses .sdkmanrc file
503sdk use java 21.0.8-ms
504 
505# Verify
506java -version # Should show 21.0.8
507```
508 
509### Issue #2: Build Fails - Missing Dependencies
510 
511**Error:**
512```
513[ERROR] Failed to calculate checksums for dotcms-core:
514Cannot resolve in-project dependency: com.dotcms:dotcms-core-web:war:1.0.0-SNAPSHOT
515```
516 
517**Solution:**
518```bash
519# ❌ WRONG - Missing --am flag
520./mvnw install -pl :dotcms-core -DskipTests
521 
522# ✅ CORRECT - Include dependencies with --am flag
523./mvnw install -pl :dotcms-core --am -DskipTests
524```
525 
526### Issue #3: Tests Are Silently Skipped
527 
528**Symptom:** Test command succeeds but no tests run.
529 
530**Solution:**
531```bash
532# Tests are skipped by default. Add explicit flags:
533-Dcoreit.test.skip=false # For integration tests
534-Dpostman.test.skip=false # For Postman tests
535-Dkarate.test.skip=false # For Karate tests
536 
537# Example:
538./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false
539```
540 
541### Issue #4: Frontend Build Fails - Node Version
542 
543**Error:**
544```
545error @angular/compiler-cli@19.2.15: The engine "node" is incompatible
546```
547 
548**Solution:**
549```bash
550# Check required version
551cat .nvmrc # Shows: v22.22.3
552 
553# Install and use correct version
554nvm install 22.22.3
555nvm use 22.22.3
556 
557# Verify
558node --version # Should show v22.22.3
559```
560 
561### Issue #5: Frontend Build Fails - Puppeteer ARM64
562 
563**Error (on Apple M1/M2 Macs):**
564```
565[ERROR] The chromium binary is not available for arm64
566```
567 
568**Solution:**
569```bash
570# Install Chromium for ARM64
571brew install chromium
572 
573# Set environment variables (add to .zshrc or .bashrc)
574export PUPPETEER_EXECUTABLE_PATH=$(which chromium)
575export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
576 
577# Reload shell
578source ~/.zshrc
579 
580# Reinstall dependencies
581cd core-web && pnpm install
582```
583 
584### Issue #6: Dependency Version Conflict
585 
586**Error:**
587```
588[ERROR] Dependency convergence error for com.example:library:jar
589```
590 
591**Solution:**
592```bash
593# Check dependency tree
594./mvnw dependency:tree -pl :dotcms-core | grep &quot;library&quot;
595 
596# Add version to BOM (NOT module POM!)
597# Edit bom/application/pom.xml:
598&lt;properties&gt;
599 &lt;library.version&gt;1.2.3&lt;/library.version&gt;
600&lt;/properties&gt;
601&lt;dependencyManagement&gt;
602 &lt;dependencies&gt;
603 &lt;dependency&gt;
604 &lt;groupId&gt;com.example&lt;/groupId&gt;
605 &lt;artifactId&gt;library&lt;/artifactId&gt;
606 &lt;version&gt;${library.version}&lt;/version&gt;
607 &lt;/dependency&gt;
608 &lt;/dependencies&gt;
609&lt;/dependencyManagement&gt;
610```
611 
612### Issue #7: Docker Build Fails
613 
614**Error:** Docker image build fails or times out.
615 
616**Solution:**
617```bash
618# Skip Docker build during development
619./mvnw clean install -DskipTests -Ddocker.skip
620 
621# Or use Just command
622just build-no-docker
623```
624 
625### Issue #8: "Cannot Find Symbol" After Adding @Value.Immutable
626 
627**Error:**
628```
629[ERROR] cannot find symbol: class ImmutableMyEntity
630```
631 
632**Solution:**
633```bash
634# Immutables are generated at compile time
635# Run compile phase to generate classes
636./mvnw compile -pl :dotcms-core
637 
638# Then continue with your build
639./mvnw install -pl :dotcms-core --am -DskipTests
640```
641 
642## CI/CD and Validation
643 
644### What Triggers CI Builds
645 
646**File patterns that trigger builds** (from `.github/filters.yaml`):
647 
648- **Backend Changes**: `dotCMS/**`, `bom/**`, `parent/**`, `pom.xml`, `dotcms-integration/**`
649- **Frontend Changes**: `core-web/**`, `dotCMS/src/main/webapp/html/**/*.{css,js}`
650- **CLI Changes**: `tools/dotcms-cli/**`
651- **Full Build Trigger**: `.sdkmanrc`, `.nvmrc`, workflow files
652 
653### CI Workflows
654 
655| Workflow | Trigger | Purpose |
656|----------|---------|---------|
657| `cicd_1-pr.yml` | Pull request | PR validation |
658| `cicd_2-merge-queue.yml` | Merge queue | Pre-merge validation |
659| `cicd_3-trunk.yml` | Push to main | Trunk integration |
660| `cicd_4-nightly.yml` | Schedule (nightly) | Full test suite |
661 
662### Pre-Commit Checklist
663 
664Before committing code, ensure:
665 
6661. ✅ **Build succeeds**: `./mvnw install -pl :dotcms-core --am -DskipTests`
6672. ✅ **Tests pass**: Run relevant tests for your changes (specific test classes)
6683. ✅ **No hardcoded secrets**: Check for API keys, passwords, credentials
6694. ✅ **Dependency versions in BOM**: Check `bom/application/pom.xml`
6705. ✅ **OpenAPI annotations**: REST endpoints have complete `@Operation` and `@ApiResponse`
6716. ✅ **Security validation**: Input validation, no SQL injection risks
6727. ✅ **Logging uses Logger**: No `System.out.println()`
673 
674## Development Workflows
675 
676### Workflow #1: Simple Backend Code Change
677 
678```bash
679# 1. Make code changes in dotCMS/src/main/java/
680 
681# 2. Build with dependencies (~2-3 min)
682./mvnw install -pl :dotcms-core --am -DskipTests
683 
684# 3. Run specific test (~2-10 min)
685./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MyTest
686 
687# 4. Commit changes
688git add .
689git commit -m &quot;feat: add new feature&quot;
690```
691 
692### Workflow #2: Adding New REST Endpoint
693 
694```bash
695# 1. Create endpoint class in dotCMS/src/main/java/com/dotcms/rest/api/v1/
696 
697# 2. Add complete OpenAPI documentation
698# - @Tag at class level
699# - @Operation for each method
700# - @ApiResponse with specific @Schema
701 
702# 3. Build
703./mvnw install -pl :dotcms-core --am -DskipTests
704 
705# 4. Test endpoint with Postman or curl
706curl -X GET http://localhost:8080/api/v1/myresource/123
707 
708# 5. Run Postman API tests
709./mvnw verify -pl :dotcms-postman -Dpostman.test.skip=false -Dpostman.collections=all
710```
711 
712### Workflow #3: Frontend Component Development
713 
714```bash
715# 1. Navigate to frontend
716cd core-web
717 
718# 2. Install dependencies (first time only)
719pnpm install
720 
721# 3. Start development server
722nx serve dotcms-ui
723# Available at http://localhost:4200
724 
725# 4. Make changes in apps/dotcms-ui/src/ or libs/
726 
727# 5. Run component tests
728nx run dotcms-ui:test --testNamePattern=&quot;MyComponent&quot;
729 
730# 6. Lint and fix
731nx run dotcms-ui:lint --fix
732 
733# 7. Build for production
734nx build dotcms-ui
735```
736 
737### Workflow #4: IDE Integration Test Debugging
738 
739```bash
740# 1. Build the project once
741./mvnw clean install -DskipTests
742 
743# 2. Start integration test services
744just test-integration-ide
745# This starts PostgreSQL, Elasticsearch, and dotCMS
746 
747# 3. In your IDE (IntelliJ/Eclipse):
748# - Navigate to test class in dotcms-integration/
749# - Set breakpoints
750# - Right-click test method → Debug
751# - Tests run in ~10-30 seconds
752 
753# 4. Make code changes, rebuild
754./mvnw install -pl :dotcms-core --am -DskipTests
755 
756# 5. Re-run test in IDE (no need to restart services)
757 
758# 6. Stop services when done
759just test-integration-stop
760```
761 
762### Workflow #5: Adding New Maven Dependency
763 
764```bash
765# 1. Add version to bom/application/pom.xml
766&lt;properties&gt;
767 &lt;my-library.version&gt;1.2.3&lt;/my-library.version&gt;
768&lt;/properties&gt;
769&lt;dependencyManagement&gt;
770 &lt;dependencies&gt;
771 &lt;dependency&gt;
772 &lt;groupId&gt;com.example&lt;/groupId&gt;
773 &lt;artifactId&gt;my-library&lt;/artifactId&gt;
774 &lt;version&gt;${my-library.version}&lt;/version&gt;
775 &lt;/dependency&gt;
776 &lt;/dependencies&gt;
777&lt;/dependencyManagement&gt;
778 
779# 2. Add dependency to module (NO version)
780# In dotCMS/pom.xml or other module
781&lt;dependency&gt;
782 &lt;groupId&gt;com.example&lt;/groupId&gt;
783 &lt;artifactId&gt;my-library&lt;/artifactId&gt;
784&lt;/dependency&gt;
785 
786# 3. Build to verify
787./mvnw install -pl :dotcms-core --am -DskipTests
788 
789# 4. Check for conflicts
790./mvnw dependency:tree -pl :dotcms-core | grep &quot;my-library&quot;
791```
792 
793## Key Files Reference
794 
795### Essential Files for Development
796 
797| File | Purpose | When to Edit |
798|------|---------|--------------|
799| `bom/application/pom.xml` | Dependency versions | Adding/updating dependencies |
800| `parent/pom.xml` | Plugin configuration | Changing build plugins |
801| `pom.xml` | Root aggregator | Adding new modules |
802| `justfile` | Task shortcuts | Creating new commands |
803| `.sdkmanrc` | Java version | Never (managed by team) |
804| `.nvmrc` | Node version | Never (managed by team) |
805| `.github/filters.yaml` | CI triggers | Rarely (CI team) |
806| `.github/workflows/` | CI/CD pipelines | Rarely (CI team) |
807 
808### Configuration Files
809 
810| File | Purpose |
811|------|---------|
812| `dotCMS/src/main/resources/dotcms-config-default.properties` | Default configuration |
813| `dotCMS/src/main/webapp/WEB-INF/web.xml` | Web application descriptor |
814| `core-web/nx.json` | Nx workspace configuration |
815| `core-web/tsconfig.base.json` | TypeScript compiler options |
816| `core-web/package.json` | Frontend dependencies |
817 
818### Where to Find Code
819 
820| Feature | Location |
821|---------|----------|
822| REST APIs | `dotCMS/src/main/java/com/dotcms/rest/api/` |
823| Contentlet API | `dotCMS/src/main/java/com/dotcms/contenttype/` |
824| Workflow | `dotCMS/src/main/java/com/dotcms/workflow/` |
825| Storage | `dotCMS/src/main/java/com/dotcms/storage/` |
826| Integrations | `dotCMS/src/main/java/com/dotcms/integrations/` |
827| Util classes | `dotCMS/src/main/java/com/dotmarketing/util/` |
828| Frontend UI | `core-web/apps/dotcms-ui/` |
829| Shared components | `core-web/libs/ui/` |
830| SDKs | `core-web/libs/sdk/` |
831| Data services | `core-web/libs/data-access/` |
832 
833## Additional Resources
834 
835### Documentation
836- **Full Development Guide**: [`CLAUDE.md`](/CLAUDE.md) - Comprehensive patterns and examples
837- **Backend Onboarding**: [`dotBackendOnboarding.md`](/dotBackendOnboarding.md) - Setup and build guide
838- **Frontend Onboarding**: [`dotFrontendOnboarding.md`](/dotFrontendOnboarding.md) - Angular/Nx guide
839- **Core Web Guide**: [`core-web/CLAUDE.md`](/core-web/CLAUDE.md) - Frontend architecture
840- **Detailed Docs**: [`docs/`](/docs/) - Organized by domain (backend, frontend, testing, etc.)
841 
842### Quick Links
843- [Justfile Commands](/justfile) - All available `just` shortcuts
844- [GitHub Actions Workflows](/.github/workflows/) - CI/CD pipeline definitions
845- [Contributing Guidelines](/CONTRIBUTING.md) - How to contribute
846- [Security Policy](/SECURITY.md) - Security reporting
847 
848---
849 
850## Summary Checklist
851 
852When working with dotCMS:
853 
854### Backend (Java/Maven)
855- ✅ Use Java 21 (`sdk env install`)
856- ✅ Add versions to `bom/application/pom.xml` ONLY
857- ✅ Use `Config`, `Logger`, `APILocator`, `UtilMethods`
858- ✅ Build with `./mvnw install -pl :dotcms-core --am -DskipTests`
859- ✅ Test specific classes: `-Dit.test=MyTest`
860- ✅ Complete OpenAPI docs for REST endpoints
861 
862### Frontend (Angular/TypeScript)
863- ✅ Use Node 22.22.3+ (`nvm use`)
864- ✅ Modern syntax: `@if`, `@for`, `input()`, `output()`
865- ✅ Test with Spectator: `spectator.setInput()`, `data-testid`
866- ✅ Build with `nx run dotcms-ui:build`
867 
868### Security & Quality
869- ❌ No hardcoded secrets or passwords
870- ❌ No `System.out.println()` - use `Logger`
871- ❌ No SQL injection - validate all input
872- ✅ Validate user input with regex whitelist
873- ✅ Use parameterized queries
874- ✅ Log safely (no sensitive data)
875 
876### Testing
877- ❌ Never run full test suite during development (60+ min)
878- ✅ Target specific test classes (~2-10 min)
879- ✅ Use IDE debugging with `just test-integration-ide`
880- ✅ Add test flags: `-Dcoreit.test.skip=false`
881 
882---
883 
884**Trust these instructions.** They are based on real build attempts and cover common issues. For questions not covered here, search the codebase or refer to [CLAUDE.md](/CLAUDE.md) for comprehensive guidance.
885 

Commands it names

  • just build-quicker
  • just build
  • just build-no-docker
  • just test-integration-ide
  • just test-integration-stop
  • just test-postman ai
  • pnpm install
  • nx run dotcms-ui:test --testNamePattern="ContentTypeComponent"
  • nx run dotcms-ui:test --testPathPattern="dot-edit-content"
  • nx run dotcms-ui:test
  • nx affected -t test --exclude='tag:skip:test'
  • nx run dotcms-ui:lint --fix
  • nx run dotcms-ui:serve
  • node --version
  • git add .
  • git commit -m "feat: add new feature"
  • nx serve dotcms-ui
  • nx run dotcms-ui:test --testNamePattern="MyComponent"
  • nx build dotcms-ui
  • docker --version
  • just
  • nx run dotcms-ui:build

Sections

  • Copilot Coding Agent Instructions for dotCMS Core
  • Repository Overview
  • Environment Requirements
  • Error: "Building this project requires JDK version 21 or higher"
  • Solution: Install Java 21 with SDKMAN
  • Build Commands (Choose the Right One!)
  • Quick Reference
  • ❌ WRONG - Missing dependencies
  • Error: "Cannot resolve in-project dependency: com.dotcms:dotcms-core-web"
  • ✅ CORRECT - For simple backend changes (~2-3 min)
  • The --am flag builds required dependencies
  • ✅ Full build without Docker (~5-8 min)
  • ✅ Full build with Docker image (~8-15 min)
  • Using Just Commands (Optional)
  • Just provides shorter aliases for common tasks
  • Testing Commands
  • Backend Testing Strategy
  • ❌ WRONG - Tests are skipped by default!
  • No error, but tests don't run
  • ✅ CORRECT - Explicit flag required
  • 1. Specific integration test class (~2-10 min) - RECOMMENDED
  • 2. Specific test method (~30 sec - 2 min)
  • 3. IDE debugging workflow (FASTEST iteration)
  • → Run/debug individual tests in your IDE (10-30 sec per test)
  • 4. JVM unit tests only (~30 sec)
  • 5. Postman API tests (specific collection)
  • ⚠️ NEVER DO THIS during development (60+ min):
  • Frontend Testing Commands
  • Install dependencies first
  • Run specific component tests (RECOMMENDED)
  • Run all tests in a file
  • Run all unit tests
  • Test only affected by your changes
  • Lint code
  • Development server (separate from backend)
  • Project Structure
  • Critical Patterns (Always Follow)
  • Maven Dependency Management
  • Java Coding Patterns
  • Immutable Objects Pattern
  • REST API Patterns (JAX-RS)
  • Angular/Frontend Patterns
  • Security Guidelines
  • Never Do These (Security Violations)
  • Always Do These (Security Best Practices)
  • Common Issues and Solutions
  • Issue #1: Build Fails - Wrong Java Version
  • Check current version
  • Install Java 21 with SDKMAN
  • Verify
  • Issue #2: Build Fails - Missing Dependencies
  • ❌ WRONG - Missing --am flag
  • ✅ CORRECT - Include dependencies with --am flag
  • Issue #3: Tests Are Silently Skipped
  • Tests are skipped by default. Add explicit flags:
  • Example:
  • Issue #4: Frontend Build Fails - Node Version
  • Check required version
  • Install and use correct version
  • Verify

What it covers

setupbuildtestlint-formatcode-stylearchitecturetesting-strategygit-prsecuritydependenciesapiuideploymentdo-notagent-behaviour

Stack — with the evidence

java

(1.00)

node

(1.00)

angular

(0.70)

jest

(0.70)

pytest

(0.70)

eslint

(0.70)

vercel

(0.70)

typescript

(0.60)

github-actions

(0.60)

monorepo

(0.50)

javascript

(0.50)

python

(0.50)

Format

Copilot instructions

Two layers: one always-on repo file, plus optional glob-scoped instruction files. Lives under .github/ rather than the repo root, which is the tell that it is aimed at the GitHub platform surface as much as the editor.

What the corpus says about it

Repository

Owner
dotCMS
Language
—
License
—
Archived
no

All configs in this repo

Also in dotCMS/core

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
dotCMS/corecore-web/apps/dotcms-ui-e2e/AGENTS.md · 949AGENTS.mdtypescriptjava+10setupstylearchtesting-strategy+278/1003 days ago
dotCMS/corecore-web/apps/mcp-server/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9setupbuildtestlint-format+589/1003 days ago
dotCMS/core.cursor/rules/doc-updates.mdc · 949Cursor rulesjavanode+9docs30/1003 days ago
dotCMS/core.cursor/rules/dotcms-guide.mdc · 949Cursor rulesjavanode+9archdo-notdocs69/1003 days ago
dotCMS/core.cursor/rules/e2e-rules.mdc · 949Cursor rulesjavanode+9setupteststylearch+589/1003 days ago
dotCMS/core.cursor/rules/frontend-context.mdc · 949Cursor rulesjavanode+10teststyledocs78/1003 days ago
dotCMS/core.cursor/rules/java-context.mdc · 949Cursor rulesjavanode+9buildstyle44/1003 days ago
dotCMS/core.cursor/rules/test-context.mdc · 949Cursor rulesjavanode+9testtesting-strategy54/1003 days ago
dotCMS/core.github/instructions/frontend.instructions.md · 949Copilot instructionsjavanode+10testlint-formatstylearch+369/1003 days ago
dotCMS/coreCLAUDE.md · 949CLAUDE.mdjavanode+9setupbuildteststyle+799/100today
dotCMS/corecore-web/AGENTS.md · 949AGENTS.mdjavanode+13style63/1003 days ago
dotCMS/corecore-web/CLAUDE.md · 949CLAUDE.mdjavanode+13teststylearchtesting-strategy+3100/1003 days ago
dotCMS/corecore-web/apps/dotcms-ui/AGENTS.md · 949AGENTS.mdtypescriptjava+9buildteststyledependencies+394/1003 days ago
dotCMS/corecore-web/libs/block-editor/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9archdo-not69/1003 days ago
dotCMS/corecore-web/libs/new-block-editor/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9lint-formatstyledo-notagent-behaviour61/1003 days ago
dotCMS/corecore-web/libs/portlets/CLAUDE.md · 949CLAUDE.mdjavanode+9setupteststyleui+177/1003 days ago
dotCMS/corecore-web/libs/portlets/edit-ema/portlet/src/lib/store/CLAUDE.md · 949CLAUDE.mdjavanode+9teststylearchtypes+265/1003 days ago
dotCMS/corecore-web/libs/sdk/client/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9setupbuildtestlint-format+997/1003 days ago
dotCMS/corecore-web/libs/sdk/react/CLAUDE.md · 949CLAUDE.mdtypescriptjava+10setupbuildtestlint-format+997/1003 days ago
dotCMS/coredotCMS/src/main/java/com/dotcms/rest/CLAUDE.md · 949CLAUDE.mdjavanode+9typesdatabaseapido-not+157/1003 days ago
Diff against core-web/apps/dotcms-ui-e2e/AGENTS.md Diff against core-web/apps/mcp-server/CLAUDE.md Diff against .cursor/rules/doc-updates.mdc Diff against .cursor/rules/dotcms-guide.mdc Diff against .cursor/rules/e2e-rules.mdc Diff against .cursor/rules/frontend-context.mdc Diff against .cursor/rules/java-context.mdc Diff against .cursor/rules/test-context.mdc Diff against .github/instructions/frontend.instructions.md Diff against CLAUDE.md Diff against core-web/AGENTS.md Diff against core-web/CLAUDE.md Diff against core-web/apps/dotcms-ui/AGENTS.md Diff against core-web/libs/block-editor/CLAUDE.md Diff against core-web/libs/new-block-editor/CLAUDE.md Diff against core-web/libs/portlets/CLAUDE.md Diff against core-web/libs/portlets/edit-ema/portlet/src/lib/store/CLAUDE.md Diff against core-web/libs/sdk/client/CLAUDE.md Diff against core-web/libs/sdk/react/CLAUDE.md Diff against dotCMS/src/main/java/com/dotcms/rest/CLAUDE.md

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
chihebnabil/lovable-boilerplate.github/instructions/global.instructions.md · 63Copilot instructionstypescriptreact+7buildlint-formatstylearch+4100/1003 days ago
HerringtonDarkholme/megarepo.github/copilot-instructions.md · 17Copilot instructionsnodejavascriptsetupbuildtestlint-format+7100/1003 days ago
louislam/uptime-kuma.github/copilot-instructions.md · 90kCopilot instructionstypescriptjavascript+10setupbuildtestlint-format+9100/1003 days ago
JCodesMore/ai-website-cloner-template.github/copilot-instructions.md · 31kCopilot instructionstypescriptnode+7buildlint-formatstylearch+397/1002 days ago
bagisto/bagisto.github/copilot-instructions.md · 28kCopilot instructionsphplaravel+8setupbuildteststyle+597/1003 days ago
darkmatter/nixmac.github/copilot-instructions.md · 24Copilot instructionstypescriptrust+14setupbuildtestlint-format+896/1003 days ago
nerolis-lab/nerolis-lab.github/copilot-instructions.md · 32Copilot instructionstypescriptnode+8setupbuildtestlint-format+1196/1003 days ago
thangaram611/second-brain.github/copilot-instructions.md · 0Copilot instructionstypescriptnode+12setupteststylearch+496/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack