agentic-team-templates 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/package.json +1 -1
- package/src/index.js +22 -2
- package/src/index.test.js +5 -0
- package/templates/cpp-expert/.cursorrules/concurrency.md +211 -0
- package/templates/cpp-expert/.cursorrules/error-handling.md +170 -0
- package/templates/cpp-expert/.cursorrules/memory-and-ownership.md +220 -0
- package/templates/cpp-expert/.cursorrules/modern-cpp.md +211 -0
- package/templates/cpp-expert/.cursorrules/overview.md +87 -0
- package/templates/cpp-expert/.cursorrules/performance.md +223 -0
- package/templates/cpp-expert/.cursorrules/testing.md +230 -0
- package/templates/cpp-expert/.cursorrules/tooling.md +312 -0
- package/templates/cpp-expert/CLAUDE.md +242 -0
- package/templates/csharp-expert/.cursorrules/aspnet-core.md +311 -0
- package/templates/csharp-expert/.cursorrules/async-patterns.md +206 -0
- package/templates/csharp-expert/.cursorrules/dependency-injection.md +206 -0
- package/templates/csharp-expert/.cursorrules/error-handling.md +235 -0
- package/templates/csharp-expert/.cursorrules/language-features.md +204 -0
- package/templates/csharp-expert/.cursorrules/overview.md +92 -0
- package/templates/csharp-expert/.cursorrules/performance.md +251 -0
- package/templates/csharp-expert/.cursorrules/testing.md +282 -0
- package/templates/csharp-expert/.cursorrules/tooling.md +254 -0
- package/templates/csharp-expert/CLAUDE.md +360 -0
- package/templates/java-expert/.cursorrules/concurrency.md +209 -0
- package/templates/java-expert/.cursorrules/error-handling.md +205 -0
- package/templates/java-expert/.cursorrules/modern-java.md +216 -0
- package/templates/java-expert/.cursorrules/overview.md +81 -0
- package/templates/java-expert/.cursorrules/performance.md +239 -0
- package/templates/java-expert/.cursorrules/persistence.md +262 -0
- package/templates/java-expert/.cursorrules/spring-boot.md +262 -0
- package/templates/java-expert/.cursorrules/testing.md +272 -0
- package/templates/java-expert/.cursorrules/tooling.md +301 -0
- package/templates/java-expert/CLAUDE.md +325 -0
- package/templates/javascript-expert/.cursorrules/overview.md +5 -3
- package/templates/javascript-expert/.cursorrules/typescript-deep-dive.md +348 -0
- package/templates/javascript-expert/CLAUDE.md +34 -3
- package/templates/kotlin-expert/.cursorrules/coroutines.md +237 -0
- package/templates/kotlin-expert/.cursorrules/error-handling.md +149 -0
- package/templates/kotlin-expert/.cursorrules/frameworks.md +227 -0
- package/templates/kotlin-expert/.cursorrules/language-features.md +231 -0
- package/templates/kotlin-expert/.cursorrules/overview.md +77 -0
- package/templates/kotlin-expert/.cursorrules/performance.md +185 -0
- package/templates/kotlin-expert/.cursorrules/testing.md +213 -0
- package/templates/kotlin-expert/.cursorrules/tooling.md +258 -0
- package/templates/kotlin-expert/CLAUDE.md +276 -0
- package/templates/swift-expert/.cursorrules/concurrency.md +230 -0
- package/templates/swift-expert/.cursorrules/error-handling.md +213 -0
- package/templates/swift-expert/.cursorrules/language-features.md +246 -0
- package/templates/swift-expert/.cursorrules/overview.md +88 -0
- package/templates/swift-expert/.cursorrules/performance.md +260 -0
- package/templates/swift-expert/.cursorrules/swiftui.md +260 -0
- package/templates/swift-expert/.cursorrules/testing.md +286 -0
- package/templates/swift-expert/.cursorrules/tooling.md +285 -0
- package/templates/swift-expert/CLAUDE.md +275 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Java Tooling and Build Systems
|
|
2
|
+
|
|
3
|
+
Maven or Gradle. Static analysis. CI/CD. Docker. The full production pipeline.
|
|
4
|
+
|
|
5
|
+
## Build Tools
|
|
6
|
+
|
|
7
|
+
### Maven
|
|
8
|
+
|
|
9
|
+
```xml
|
|
10
|
+
<!-- pom.xml essentials -->
|
|
11
|
+
<properties>
|
|
12
|
+
<java.version>21</java.version>
|
|
13
|
+
<maven.compiler.source>${java.version}</maven.compiler.source>
|
|
14
|
+
<maven.compiler.target>${java.version}</maven.compiler.target>
|
|
15
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
16
|
+
</properties>
|
|
17
|
+
|
|
18
|
+
<!-- Dependency management in parent POM -->
|
|
19
|
+
<dependencyManagement>
|
|
20
|
+
<dependencies>
|
|
21
|
+
<dependency>
|
|
22
|
+
<groupId>org.springframework.boot</groupId>
|
|
23
|
+
<artifactId>spring-boot-dependencies</artifactId>
|
|
24
|
+
<version>${spring-boot.version}</version>
|
|
25
|
+
<type>pom</type>
|
|
26
|
+
<scope>import</scope>
|
|
27
|
+
</dependency>
|
|
28
|
+
</dependencies>
|
|
29
|
+
</dependencyManagement>
|
|
30
|
+
|
|
31
|
+
<!-- Essential plugins -->
|
|
32
|
+
<build>
|
|
33
|
+
<plugins>
|
|
34
|
+
<plugin>
|
|
35
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
36
|
+
<artifactId>maven-compiler-plugin</artifactId>
|
|
37
|
+
<configuration>
|
|
38
|
+
<compilerArgs>
|
|
39
|
+
<arg>-Xlint:all</arg>
|
|
40
|
+
<arg>-Werror</arg>
|
|
41
|
+
</compilerArgs>
|
|
42
|
+
</configuration>
|
|
43
|
+
</plugin>
|
|
44
|
+
<plugin>
|
|
45
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
46
|
+
<artifactId>maven-surefire-plugin</artifactId>
|
|
47
|
+
<configuration>
|
|
48
|
+
<argLine>-XX:+EnableDynamicAgentLoading</argLine>
|
|
49
|
+
</configuration>
|
|
50
|
+
</plugin>
|
|
51
|
+
</plugins>
|
|
52
|
+
</build>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Gradle (Kotlin DSL)
|
|
56
|
+
|
|
57
|
+
```kotlin
|
|
58
|
+
// build.gradle.kts
|
|
59
|
+
plugins {
|
|
60
|
+
java
|
|
61
|
+
id("org.springframework.boot") version "3.4.0"
|
|
62
|
+
id("io.spring.dependency-management") version "1.1.6"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
java {
|
|
66
|
+
toolchain {
|
|
67
|
+
languageVersion = JavaLanguageVersion.of(21)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
tasks.withType<JavaCompile> {
|
|
72
|
+
options.compilerArgs.addAll(listOf("-Xlint:all", "-Werror"))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
dependencies {
|
|
76
|
+
implementation("org.springframework.boot:spring-boot-starter-web")
|
|
77
|
+
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
|
78
|
+
implementation("org.springframework.boot:spring-boot-starter-validation")
|
|
79
|
+
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
|
80
|
+
|
|
81
|
+
runtimeOnly("org.postgresql:postgresql")
|
|
82
|
+
runtimeOnly("org.flywaydb:flyway-database-postgresql")
|
|
83
|
+
|
|
84
|
+
compileOnly("org.projectlombok:lombok")
|
|
85
|
+
annotationProcessor("org.projectlombok:lombok")
|
|
86
|
+
|
|
87
|
+
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
|
88
|
+
testImplementation("org.testcontainers:postgresql")
|
|
89
|
+
testImplementation("org.testcontainers:junit-jupiter")
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
tasks.test {
|
|
93
|
+
useJUnitPlatform()
|
|
94
|
+
jvmArgs("-XX:+EnableDynamicAgentLoading")
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Essential Commands
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Maven
|
|
102
|
+
mvn clean verify # Full build + tests
|
|
103
|
+
mvn test # Unit tests only
|
|
104
|
+
mvn verify -Pintegration-tests # Integration tests
|
|
105
|
+
mvn dependency:tree # Dependency analysis
|
|
106
|
+
mvn versions:display-dependency-updates # Check for updates
|
|
107
|
+
mvn spotbugs:check # Static analysis
|
|
108
|
+
|
|
109
|
+
# Gradle
|
|
110
|
+
./gradlew clean build # Full build + tests
|
|
111
|
+
./gradlew test # Unit tests
|
|
112
|
+
./gradlew integrationTest # Integration tests
|
|
113
|
+
./gradlew dependencies # Dependency tree
|
|
114
|
+
./gradlew dependencyUpdates # Check for updates
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Static Analysis
|
|
118
|
+
|
|
119
|
+
### SpotBugs + ErrorProne
|
|
120
|
+
|
|
121
|
+
```xml
|
|
122
|
+
<!-- SpotBugs -->
|
|
123
|
+
<plugin>
|
|
124
|
+
<groupId>com.github.spotbugs</groupId>
|
|
125
|
+
<artifactId>spotbugs-maven-plugin</artifactId>
|
|
126
|
+
<configuration>
|
|
127
|
+
<effort>Max</effort>
|
|
128
|
+
<threshold>Low</threshold>
|
|
129
|
+
<failOnError>true</failOnError>
|
|
130
|
+
</configuration>
|
|
131
|
+
</plugin>
|
|
132
|
+
|
|
133
|
+
<!-- ErrorProne (compile-time bug detection) -->
|
|
134
|
+
<plugin>
|
|
135
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
136
|
+
<artifactId>maven-compiler-plugin</artifactId>
|
|
137
|
+
<configuration>
|
|
138
|
+
<annotationProcessorPaths>
|
|
139
|
+
<path>
|
|
140
|
+
<groupId>com.google.errorprone</groupId>
|
|
141
|
+
<artifactId>error_prone_core</artifactId>
|
|
142
|
+
<version>${errorprone.version}</version>
|
|
143
|
+
</path>
|
|
144
|
+
</annotationProcessorPaths>
|
|
145
|
+
<compilerArgs>
|
|
146
|
+
<arg>-XDcompilePolicy=simple</arg>
|
|
147
|
+
<arg>-Xplugin:ErrorProne</arg>
|
|
148
|
+
</compilerArgs>
|
|
149
|
+
</configuration>
|
|
150
|
+
</plugin>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Checkstyle
|
|
154
|
+
|
|
155
|
+
```xml
|
|
156
|
+
<plugin>
|
|
157
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
158
|
+
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
159
|
+
<configuration>
|
|
160
|
+
<configLocation>google_checks.xml</configLocation>
|
|
161
|
+
<failsOnError>true</failsOnError>
|
|
162
|
+
</configuration>
|
|
163
|
+
</plugin>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Docker
|
|
167
|
+
|
|
168
|
+
```dockerfile
|
|
169
|
+
# Multi-stage build
|
|
170
|
+
FROM eclipse-temurin:21-jdk-alpine AS build
|
|
171
|
+
WORKDIR /app
|
|
172
|
+
COPY pom.xml .
|
|
173
|
+
COPY src ./src
|
|
174
|
+
RUN --mount=type=cache,target=/root/.m2 \
|
|
175
|
+
mvn package -DskipTests -q
|
|
176
|
+
|
|
177
|
+
FROM eclipse-temurin:21-jre-alpine
|
|
178
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
179
|
+
USER appuser
|
|
180
|
+
WORKDIR /app
|
|
181
|
+
COPY --from=build /app/target/*.jar app.jar
|
|
182
|
+
EXPOSE 8080
|
|
183
|
+
|
|
184
|
+
# JVM tuning for containers
|
|
185
|
+
ENV JAVA_OPTS="-XX:+UseContainerSupport \
|
|
186
|
+
-XX:MaxRAMPercentage=75.0 \
|
|
187
|
+
-XX:+UseZGC \
|
|
188
|
+
-XX:+ZGenerational"
|
|
189
|
+
|
|
190
|
+
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## CI/CD (GitHub Actions)
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
name: CI
|
|
197
|
+
|
|
198
|
+
on:
|
|
199
|
+
push:
|
|
200
|
+
branches: [main]
|
|
201
|
+
pull_request:
|
|
202
|
+
branches: [main]
|
|
203
|
+
|
|
204
|
+
jobs:
|
|
205
|
+
build:
|
|
206
|
+
runs-on: ubuntu-latest
|
|
207
|
+
|
|
208
|
+
services:
|
|
209
|
+
postgres:
|
|
210
|
+
image: postgres:16-alpine
|
|
211
|
+
env:
|
|
212
|
+
POSTGRES_PASSWORD: test
|
|
213
|
+
POSTGRES_DB: testdb
|
|
214
|
+
ports:
|
|
215
|
+
- 5432:5432
|
|
216
|
+
|
|
217
|
+
steps:
|
|
218
|
+
- uses: actions/checkout@v4
|
|
219
|
+
|
|
220
|
+
- uses: actions/setup-java@v4
|
|
221
|
+
with:
|
|
222
|
+
distribution: temurin
|
|
223
|
+
java-version: 21
|
|
224
|
+
cache: maven
|
|
225
|
+
|
|
226
|
+
- name: Build and test
|
|
227
|
+
run: mvn clean verify -B
|
|
228
|
+
env:
|
|
229
|
+
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/testdb
|
|
230
|
+
SPRING_DATASOURCE_USERNAME: postgres
|
|
231
|
+
SPRING_DATASOURCE_PASSWORD: test
|
|
232
|
+
|
|
233
|
+
- name: Upload coverage
|
|
234
|
+
uses: codecov/codecov-action@v4
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Logging (SLF4J + Logback)
|
|
238
|
+
|
|
239
|
+
```java
|
|
240
|
+
// Always use SLF4J facade
|
|
241
|
+
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
|
|
242
|
+
// Or with Lombok: @Slf4j on the class
|
|
243
|
+
|
|
244
|
+
// Structured logging with parameters — never string concatenation
|
|
245
|
+
log.info("Order created orderId={} customerId={} itemCount={}",
|
|
246
|
+
order.getId(), order.getCustomerId(), order.getItems().size());
|
|
247
|
+
|
|
248
|
+
// MDC for request-scoped context
|
|
249
|
+
MDC.put("requestId", requestId);
|
|
250
|
+
MDC.put("userId", userId);
|
|
251
|
+
try {
|
|
252
|
+
// All log statements in this scope include requestId and userId
|
|
253
|
+
processOrder(order);
|
|
254
|
+
} finally {
|
|
255
|
+
MDC.clear();
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
```xml
|
|
260
|
+
<!-- logback-spring.xml for JSON output in production -->
|
|
261
|
+
<configuration>
|
|
262
|
+
<springProfile name="prod">
|
|
263
|
+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
|
264
|
+
<encoder class="net.logstash.logback.encoder.LogstashEncoder" />
|
|
265
|
+
</appender>
|
|
266
|
+
</springProfile>
|
|
267
|
+
|
|
268
|
+
<springProfile name="local">
|
|
269
|
+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
|
270
|
+
<encoder>
|
|
271
|
+
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
|
272
|
+
</encoder>
|
|
273
|
+
</appender>
|
|
274
|
+
</springProfile>
|
|
275
|
+
|
|
276
|
+
<root level="INFO">
|
|
277
|
+
<appender-ref ref="STDOUT" />
|
|
278
|
+
</root>
|
|
279
|
+
</configuration>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Anti-Patterns
|
|
283
|
+
|
|
284
|
+
```java
|
|
285
|
+
// Never: System.out.println for logging
|
|
286
|
+
System.out.println("Order created: " + order.getId());
|
|
287
|
+
// Use SLF4J logger
|
|
288
|
+
|
|
289
|
+
// Never: hardcoded versions scattered across modules
|
|
290
|
+
// Use dependencyManagement (Maven) or platform (Gradle)
|
|
291
|
+
|
|
292
|
+
// Never: fat JAR without layer optimization
|
|
293
|
+
// Use Spring Boot layered JARs for Docker cache efficiency
|
|
294
|
+
|
|
295
|
+
// Never: running as root in Docker containers
|
|
296
|
+
USER root // Security risk
|
|
297
|
+
// Use: non-root user (adduser)
|
|
298
|
+
|
|
299
|
+
// Never: skipping static analysis in CI
|
|
300
|
+
// SpotBugs, ErrorProne, and Checkstyle catch real bugs
|
|
301
|
+
```
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Java Expert Development Guide
|
|
2
|
+
|
|
3
|
+
Principal-level guidelines for Java engineering. Deep JVM knowledge, modern language features, and production-grade patterns.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This guide applies to:
|
|
10
|
+
- Web services and APIs (Spring Boot, Quarkus, Micronaut)
|
|
11
|
+
- Microservices and distributed systems
|
|
12
|
+
- Event-driven architectures (Kafka, RabbitMQ)
|
|
13
|
+
- Batch processing and data pipelines
|
|
14
|
+
- Libraries and Maven/Gradle artifacts
|
|
15
|
+
- Cloud-native applications (Kubernetes, GraalVM native images)
|
|
16
|
+
|
|
17
|
+
### Core Philosophy
|
|
18
|
+
|
|
19
|
+
Java's strength is its ecosystem maturity and runtime reliability. The best Java code is clear, testable, and boring.
|
|
20
|
+
|
|
21
|
+
- **Readability over cleverness.** A junior engineer should understand your code without a tutorial.
|
|
22
|
+
- **Immutability by default.** Records, `final` fields, unmodifiable collections. Mutation is the exception.
|
|
23
|
+
- **Composition over inheritance.** Interfaces, delegation, and dependency injection — not deep class hierarchies.
|
|
24
|
+
- **The JVM is your ally.** Understand garbage collection, JIT compilation, and memory model — don't fight them.
|
|
25
|
+
- **Fail fast, fail loud.** Validate at boundaries, throw meaningful exceptions, never swallow errors.
|
|
26
|
+
- **If you don't know, say so.** Admitting uncertainty is professional. Guessing at JVM behavior you haven't verified is not.
|
|
27
|
+
|
|
28
|
+
### Key Principles
|
|
29
|
+
|
|
30
|
+
1. **Modern Java Is Required** — Java 21+ features: records, sealed classes, pattern matching, virtual threads
|
|
31
|
+
2. **Null Is a Bug** — Use `Optional` for return types, `@Nullable`/`@NonNull` annotations, and validation at boundaries
|
|
32
|
+
3. **Dependency Injection Is the Architecture** — Constructor injection, interface segregation, Spring's application context
|
|
33
|
+
4. **Tests Are Documentation** — Descriptive names, Arrange-Act-Assert, behavior over implementation
|
|
34
|
+
5. **Observability Is Not Optional** — Structured logging, metrics, distributed tracing from day one
|
|
35
|
+
|
|
36
|
+
### Project Structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
project/
|
|
40
|
+
├── src/main/java/com/example/myapp/
|
|
41
|
+
│ ├── Application.java
|
|
42
|
+
│ ├── config/
|
|
43
|
+
│ ├── domain/
|
|
44
|
+
│ │ ├── model/
|
|
45
|
+
│ │ ├── service/
|
|
46
|
+
│ │ └── event/
|
|
47
|
+
│ ├── application/
|
|
48
|
+
│ │ ├── command/
|
|
49
|
+
│ │ ├── query/
|
|
50
|
+
│ │ └── port/
|
|
51
|
+
│ ├── infrastructure/
|
|
52
|
+
│ │ ├── persistence/
|
|
53
|
+
│ │ ├── messaging/
|
|
54
|
+
│ │ └── client/
|
|
55
|
+
│ └── api/
|
|
56
|
+
│ ├── controller/
|
|
57
|
+
│ ├── dto/
|
|
58
|
+
│ └── exception/
|
|
59
|
+
├── src/main/resources/
|
|
60
|
+
│ ├── application.yml
|
|
61
|
+
│ └── db/migration/
|
|
62
|
+
├── src/test/java/
|
|
63
|
+
├── pom.xml or build.gradle.kts
|
|
64
|
+
└── Dockerfile
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Modern Java
|
|
70
|
+
|
|
71
|
+
### Records
|
|
72
|
+
|
|
73
|
+
```java
|
|
74
|
+
public record CreateUserRequest(@NotBlank String name, @Email String email) {}
|
|
75
|
+
public record Money(BigDecimal amount, Currency currency) {
|
|
76
|
+
public Money {
|
|
77
|
+
if (amount.compareTo(BigDecimal.ZERO) < 0)
|
|
78
|
+
throw new IllegalArgumentException("Amount cannot be negative");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Sealed Classes
|
|
84
|
+
|
|
85
|
+
```java
|
|
86
|
+
public sealed interface PaymentResult
|
|
87
|
+
permits PaymentSuccess, PaymentFailure, PaymentPending {}
|
|
88
|
+
|
|
89
|
+
public String describe(PaymentResult result) {
|
|
90
|
+
return switch (result) {
|
|
91
|
+
case PaymentSuccess s -> "Paid: " + s.transactionId();
|
|
92
|
+
case PaymentFailure f -> "Failed: " + f.message();
|
|
93
|
+
case PaymentPending p -> "Pending: " + p.referenceId();
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Virtual Threads (Java 21+)
|
|
99
|
+
|
|
100
|
+
```java
|
|
101
|
+
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
|
102
|
+
var futures = tasks.stream()
|
|
103
|
+
.map(task -> executor.submit(() -> process(task)))
|
|
104
|
+
.toList();
|
|
105
|
+
}
|
|
106
|
+
// Don't pool them. Don't use synchronized for I/O. Use ReentrantLock instead.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Spring Boot
|
|
112
|
+
|
|
113
|
+
### Service Layer
|
|
114
|
+
|
|
115
|
+
```java
|
|
116
|
+
@Service
|
|
117
|
+
@RequiredArgsConstructor
|
|
118
|
+
@Transactional(readOnly = true)
|
|
119
|
+
public class OrderService {
|
|
120
|
+
private final OrderRepository orderRepository;
|
|
121
|
+
private final ApplicationEventPublisher eventPublisher;
|
|
122
|
+
|
|
123
|
+
@Transactional
|
|
124
|
+
public OrderResponse create(CreateOrderRequest request) {
|
|
125
|
+
var order = Order.create(request);
|
|
126
|
+
orderRepository.save(order);
|
|
127
|
+
eventPublisher.publishEvent(new OrderCreatedEvent(order.getId()));
|
|
128
|
+
return OrderResponse.from(order);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Exception Handling
|
|
134
|
+
|
|
135
|
+
```java
|
|
136
|
+
@RestControllerAdvice
|
|
137
|
+
public class GlobalExceptionHandler {
|
|
138
|
+
@ExceptionHandler(NotFoundException.class)
|
|
139
|
+
public ProblemDetail handleNotFound(NotFoundException ex) {
|
|
140
|
+
return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Configuration
|
|
146
|
+
|
|
147
|
+
```java
|
|
148
|
+
@Validated
|
|
149
|
+
@ConfigurationProperties(prefix = "app.orders")
|
|
150
|
+
public record OrderProperties(
|
|
151
|
+
@NotNull Duration processingTimeout,
|
|
152
|
+
@Min(1) int maxItemsPerOrder
|
|
153
|
+
) {}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Concurrency
|
|
159
|
+
|
|
160
|
+
### Rules
|
|
161
|
+
|
|
162
|
+
- Don't start threads you can't stop
|
|
163
|
+
- Prefer virtual threads for I/O, platform threads for CPU
|
|
164
|
+
- Use `ReentrantLock` over `synchronized` with virtual threads
|
|
165
|
+
- Always restore interrupt status in catch blocks
|
|
166
|
+
- Immutable objects are inherently thread-safe
|
|
167
|
+
|
|
168
|
+
### CompletableFuture
|
|
169
|
+
|
|
170
|
+
```java
|
|
171
|
+
var userFuture = CompletableFuture.supplyAsync(() -> userService.findById(userId));
|
|
172
|
+
var ordersFuture = CompletableFuture.supplyAsync(() -> orderService.recent(userId));
|
|
173
|
+
CompletableFuture.allOf(userFuture, ordersFuture)
|
|
174
|
+
.thenApply(v -> new Dashboard(userFuture.join(), ordersFuture.join()));
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Persistence
|
|
180
|
+
|
|
181
|
+
### JPA Best Practices
|
|
182
|
+
|
|
183
|
+
- Factory methods on entities, protected no-arg constructors for JPA
|
|
184
|
+
- `@Version` for optimistic locking
|
|
185
|
+
- JOIN FETCH or `@EntityGraph` to prevent N+1 queries
|
|
186
|
+
- DTO projections for read-only queries
|
|
187
|
+
- `spring.jpa.open-in-view=false` — always
|
|
188
|
+
|
|
189
|
+
### Transactions
|
|
190
|
+
|
|
191
|
+
```java
|
|
192
|
+
@Transactional(readOnly = true) // On the class for reads
|
|
193
|
+
public Optional<Order> findById(UUID id) { ... }
|
|
194
|
+
|
|
195
|
+
@Transactional // Override for writes
|
|
196
|
+
public Order create(CreateOrderRequest request) { ... }
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Migrations
|
|
200
|
+
|
|
201
|
+
Flyway or Liquibase. Every schema change is a versioned migration. No Hibernate auto-DDL in production.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Error Handling
|
|
206
|
+
|
|
207
|
+
### Two Approaches
|
|
208
|
+
|
|
209
|
+
1. **Exceptions** — Infrastructure failures, programming errors
|
|
210
|
+
2. **Result types** — Expected business failures (validation, conflicts)
|
|
211
|
+
|
|
212
|
+
### Guard Clauses
|
|
213
|
+
|
|
214
|
+
```java
|
|
215
|
+
Objects.requireNonNull(customerId, "customerId must not be null");
|
|
216
|
+
if (items.isEmpty()) throw new IllegalArgumentException("Order must have items");
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Logging
|
|
220
|
+
|
|
221
|
+
```java
|
|
222
|
+
log.error("Payment failed orderId={} amount={}: {}", orderId, amount, ex.getMessage(), ex);
|
|
223
|
+
// Parameters for structured logging. Exception as last arg for stack trace.
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Testing
|
|
229
|
+
|
|
230
|
+
### Framework Stack
|
|
231
|
+
|
|
232
|
+
| Tool | Purpose |
|
|
233
|
+
|------|---------|
|
|
234
|
+
| JUnit 5 | Test framework |
|
|
235
|
+
| AssertJ | Fluent assertions |
|
|
236
|
+
| Mockito | Mocking |
|
|
237
|
+
| Testcontainers | Real databases/services |
|
|
238
|
+
| WireMock | HTTP API mocking |
|
|
239
|
+
| ArchUnit | Architecture tests |
|
|
240
|
+
|
|
241
|
+
### Test Structure
|
|
242
|
+
|
|
243
|
+
```java
|
|
244
|
+
@Test
|
|
245
|
+
void create_withValidRequest_savesAndReturnsOrder() {
|
|
246
|
+
// Arrange
|
|
247
|
+
var request = new CreateOrderRequest("customer-1", List.of(item));
|
|
248
|
+
when(inventory.check("SKU-001", 2)).thenReturn(true);
|
|
249
|
+
// Act
|
|
250
|
+
var result = sut.create(request);
|
|
251
|
+
// Assert
|
|
252
|
+
assertThat(result.customerId()).isEqualTo("customer-1");
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Integration Tests
|
|
257
|
+
|
|
258
|
+
```java
|
|
259
|
+
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
|
260
|
+
@Testcontainers
|
|
261
|
+
class OrderControllerIT {
|
|
262
|
+
@Container
|
|
263
|
+
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Performance
|
|
270
|
+
|
|
271
|
+
### Profile First
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
java -XX:StartFlightRecording=filename=recording.jfr,duration=60s -jar app.jar
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Key Patterns
|
|
278
|
+
|
|
279
|
+
- Pre-size collections when capacity is known
|
|
280
|
+
- Use primitive streams to avoid autoboxing
|
|
281
|
+
- `StringBuilder` for complex string concatenation
|
|
282
|
+
- HikariCP pool sizing: `core_count * 2` connections
|
|
283
|
+
- Caffeine for in-process caching with eviction
|
|
284
|
+
- ZGC for ultra-low-latency requirements
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Tooling
|
|
289
|
+
|
|
290
|
+
### Essential Stack
|
|
291
|
+
|
|
292
|
+
| Tool | Purpose |
|
|
293
|
+
|------|---------|
|
|
294
|
+
| Maven/Gradle | Build system |
|
|
295
|
+
| SpotBugs | Bug detection |
|
|
296
|
+
| ErrorProne | Compile-time bug detection |
|
|
297
|
+
| Checkstyle | Code style enforcement |
|
|
298
|
+
| JFR + JMC | Production profiling |
|
|
299
|
+
| JMH | Micro-benchmarks |
|
|
300
|
+
| SLF4J + Logback | Logging |
|
|
301
|
+
|
|
302
|
+
### CI Essentials
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
mvn clean verify -B # Full build with tests
|
|
306
|
+
mvn spotbugs:check # Static analysis
|
|
307
|
+
mvn checkstyle:check # Code style
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Definition of Done
|
|
313
|
+
|
|
314
|
+
A Java feature is complete when:
|
|
315
|
+
|
|
316
|
+
- [ ] Code compiles with zero warnings (`-Xlint:all -Werror`)
|
|
317
|
+
- [ ] All tests pass (`mvn verify` or `gradle check`)
|
|
318
|
+
- [ ] No SpotBugs/ErrorProne findings
|
|
319
|
+
- [ ] No SonarQube code smells or security hotspots
|
|
320
|
+
- [ ] Null safety enforced (no raw `null` returns from public APIs)
|
|
321
|
+
- [ ] Javadoc on all public classes and methods
|
|
322
|
+
- [ ] Error paths are tested
|
|
323
|
+
- [ ] Thread safety verified for shared mutable state
|
|
324
|
+
- [ ] No `TODO` without an associated issue
|
|
325
|
+
- [ ] Code reviewed and approved
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# JavaScript Expert
|
|
1
|
+
# JavaScript & TypeScript Expert
|
|
2
2
|
|
|
3
|
-
Guidelines for principal-level JavaScript engineering across all runtimes, frameworks, and paradigms.
|
|
3
|
+
Guidelines for principal-level JavaScript and TypeScript engineering across all runtimes, frameworks, and paradigms.
|
|
4
|
+
|
|
5
|
+
**This template covers both JavaScript and TypeScript.** TypeScript is the default — all code is written in strict TypeScript. The advanced type system is covered in `typescript-deep-dive.md`.
|
|
4
6
|
|
|
5
7
|
## Scope
|
|
6
8
|
|
|
@@ -8,7 +10,7 @@ This ruleset applies to:
|
|
|
8
10
|
- Node.js services, CLIs, and tooling
|
|
9
11
|
- React, Vue, Angular, Svelte, and other UI frameworks
|
|
10
12
|
- Vanilla JavaScript and Web APIs
|
|
11
|
-
- TypeScript (strict mode, always)
|
|
13
|
+
- TypeScript (strict mode, always — see `typescript-deep-dive.md` for advanced patterns)
|
|
12
14
|
- Build tools, bundlers, and transpilers
|
|
13
15
|
- Testing at every level (unit, integration, E2E, performance)
|
|
14
16
|
|