-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkotlin-spring.mdc
More file actions
100 lines (74 loc) · 7.14 KB
/
Copy pathkotlin-spring.mdc
File metadata and controls
100 lines (74 loc) · 7.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
---
description: Kotlin Spring Boot rules — constructor injection, DTOs, null safety, @Valid on inputs.
globs: ""
alwaysApply: true
---
## Dependency Injection
- Use constructor injection exclusively. Never use @Autowired field injection. Every Spring bean must declare dependencies as constructor parameters with final modifiers.
- All constructor parameters must be annotated with @Autowired or use Kotlin's val with Spring's implicit constructor injection. No bare parameters.
- Never inject ApplicationContext, BeanFactory, or ObjectProvider. If you need dynamic bean lookup, create a dedicated factory bean with explicit methods.
- Circular dependencies are a hard failure. Restructure immediately. Never use @Lazy to hide circular dependencies.
## Request/Response Handling
- Every @RequestMapping method parameter of type object must have @Valid annotation. No exceptions. Primitive types and Strings are exempt.
- Never return JPA entities directly from @RestController methods. Create a DTO class in src/main/kotlin/com/[company]/[project]/dto/ with the exact name [EntityName]Response.
- All request DTOs must be in src/main/kotlin/com/[company]/[project]/dto/ with the exact name [EntityName]Request.
- Response DTOs must have @JsonProperty annotations for any field that differs from camelCase naming. Never rely on implicit serialization.
## Null Safety
- Never use the !! operator outside of test files. Use .let{}, .also{}, or explicit null checks with if statements.
- All Optional returns from repository methods must be handled with .orElseThrow { EntityNotFoundException(...) } or .orElse(null) with immediate null check.
- Nullable types must be declared explicitly with ? in the type signature. Never use @Nullable without the ? operator.
- Data class properties that can be null must have default values of null. Never leave nullable properties uninitialized.
## Entity and JPA
- All JPA entities must be in src/main/kotlin/com/[company]/[project]/entity/ and named with Entity suffix: UserEntity, OrderEntity.
- Entity classes must be data classes with val properties only. No var properties. Use @Column(updatable=false) for immutable fields.
- Never use @ManyToMany relationships. Use an explicit join entity instead with @OneToMany and @ManyToOne.
- All @OneToMany relationships must have cascade=CascadeType.NONE explicitly set. Never use cascade=CascadeType.ALL.
- Entity constructors must have all parameters with default values of null for optional fields. No-arg constructor must exist (use @NoArgsConstructor).
- Never use @Transactional on entity classes or repositories. Use it only on @Service classes.
## Service Layer
- All business logic must be in @Service classes in src/main/kotlin/com/[company]/[project]/service/ named [EntityName]Service.
- Every public method in a @Service must have @Transactional(readOnly=true) or @Transactional(readOnly=false). Explicit is required.
- Service methods that modify data must return the modified entity or a response DTO, never void.
- Service methods must not catch exceptions. Let them propagate to @ControllerAdvice. Never swallow exceptions with try/catch in services.
## Controller Layer
- All controllers must be in src/main/kotlin/com/[company]/[project]/controller/ and named [EntityName]Controller.
- Every @RestController must have a @ControllerAdvice companion in src/main/kotlin/com/[company]/[project]/exception/ named [EntityName]ExceptionHandler.
- HTTP status codes must be explicit: use ResponseEntity.ok(), ResponseEntity.created(), ResponseEntity.noContent(). Never return raw objects.
- All @PathVariable parameters must have @Valid if they are objects. Primitive path variables are exempt.
## Error Handling
- Create a sealed class AppException in src/main/kotlin/com/[company]/[project]/exception/AppException.kt with subclasses: EntityNotFoundException, ValidationException, UnauthorizedException, ConflictException.
- Every catch block must specify the exact exception type. Never use catch (e: Exception) or catch (e: Throwable).
- All exceptions must include a structured error code string: throw EntityNotFoundException("USER_NOT_FOUND", "User with id $id not found").
- @ControllerAdvice methods must return ErrorResponse data class with fields: code: String, message: String, timestamp: Long, path: String.
- Never log and rethrow the same exception. Either log it or throw it, not both.
## Validation
- All validation annotations (@NotNull, @NotBlank, @Email, @Min, @Max) must be on DTO request classes only, never on entities.
- Custom validators must be in src/main/kotlin/com/[company]/[project]/validation/ and implement ConstraintValidator<Annotation, Type>.
- Validation error messages must be in src/main/resources/messages.properties with keys like validation.user.email.invalid.
- Never validate in the service layer. Validation must happen at the @RestController boundary via @Valid.
## Security
- Never hardcode secrets, API keys, or database credentials. All must come from environment variables via @Value("${property.name}") or @ConfigurationProperties.
- All @RequestMapping methods that modify data (POST, PUT, DELETE, PATCH) must have @PreAuthorize("hasRole('ROLE_NAME')") or @PreAuthorize("hasAuthority('PERMISSION')").
- Never trust user input. All string inputs must be trimmed and validated for length: @NotBlank @Size(min=1, max=255).
- SQL queries must use parameterized queries only. Never concatenate strings into @Query. Use :paramName syntax.
## Testing
- All tests must be in src/test/kotlin/com/[company]/[project]/ mirroring the src/main structure.
- Service tests must be named [EntityName]ServiceTest and use @ExtendWith(MockitoExtension::class).
- Controller tests must be named [EntityName]ControllerTest and use @WebMvcTest(controllers=[EntityNameController::class]).
- Every test must have exactly one @Test method with a descriptive name: testFindByIdReturnsUserWhenExists(), testCreateThrowsValidationExceptionWhenEmailInvalid().
- Mock repositories in service tests with @MockBean. Never use real database connections in unit tests.
- Integration tests must be in src/test/kotlin/com/[company]/[project]/integration/ and use @SpringBootTest with @Testcontainers for database.
## File and Package Structure
- Package names must be lowercase: com.company.project.controller, com.company.project.service, com.company.project.entity.
- File names must match class names exactly: UserService.kt, UserEntity.kt, UserController.kt.
- No wildcard imports. Every import must be explicit.
- Maximum file size is 500 lines. Split larger files immediately.
## Logging
- Use SLF4J with Logback. Inject logger as: private val logger = LoggerFactory.getLogger(this::class.java).
- Never use println() or System.out.println(). All output must go through logger.
- Log levels: debug for entry/exit, info for business events, warn for recoverable errors, error for exceptions with stack traces.
- Never log sensitive data: passwords, tokens, SSNs, credit cards. Use logger.debug("User login: {}", userId) not username.
---
> Source: [Codelibrium](https://codelibrium.com) — the marketplace for AI behaviour files.
> Browse multiple rulesets at [codelibrium.com](https://codelibrium.com) or install via CLI:
> `npx codelibrium-cli install <ruleset-name>`