@h1dr0n/skill-pool 0.1.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.
Files changed (189) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +296 -0
  3. package/bin/cli.js +157 -0
  4. package/package.json +41 -0
  5. package/skills/api/agents/backend-specialist.md +69 -0
  6. package/skills/api/agents/database-optimizer.md +176 -0
  7. package/skills/api/manifest.yaml +20 -0
  8. package/skills/api/rules/auth-security.md +45 -0
  9. package/skills/api/skills/api-patterns/SKILL.md +81 -0
  10. package/skills/api/skills/api-patterns/api-style.md +42 -0
  11. package/skills/api/skills/api-patterns/auth.md +24 -0
  12. package/skills/api/skills/api-patterns/documentation.md +26 -0
  13. package/skills/api/skills/api-patterns/graphql.md +41 -0
  14. package/skills/api/skills/api-patterns/rate-limiting.md +31 -0
  15. package/skills/api/skills/api-patterns/response.md +37 -0
  16. package/skills/api/skills/api-patterns/rest.md +40 -0
  17. package/skills/api/skills/api-patterns/scripts/api_validator.py +211 -0
  18. package/skills/api/skills/api-patterns/security-testing.md +122 -0
  19. package/skills/api/skills/api-patterns/trpc.md +41 -0
  20. package/skills/api/skills/api-patterns/versioning.md +22 -0
  21. package/skills/api/skills/database-patterns.md +126 -0
  22. package/skills/api/skills/deployment-patterns.md +105 -0
  23. package/skills/api/skills/docker-patterns.md +135 -0
  24. package/skills/common/agents/code-reviewer.md +78 -0
  25. package/skills/common/agents/planner.md +80 -0
  26. package/skills/common/agents/security-reviewer.md +82 -0
  27. package/skills/common/agents/software-architect.md +81 -0
  28. package/skills/common/manifest.yaml +25 -0
  29. package/skills/common/rules/coding-style.md +39 -0
  30. package/skills/common/rules/git-workflow.md +33 -0
  31. package/skills/common/rules/security.md +25 -0
  32. package/skills/common/skills/architecture/SKILL.md +55 -0
  33. package/skills/common/skills/architecture/context-discovery.md +43 -0
  34. package/skills/common/skills/architecture/examples.md +94 -0
  35. package/skills/common/skills/architecture/pattern-selection.md +68 -0
  36. package/skills/common/skills/architecture/patterns-reference.md +50 -0
  37. package/skills/common/skills/architecture/trade-off-analysis.md +77 -0
  38. package/skills/common/skills/brainstorming/SKILL.md +163 -0
  39. package/skills/common/skills/brainstorming/dynamic-questioning.md +350 -0
  40. package/skills/common/skills/clean-code.md +99 -0
  41. package/skills/common/skills/code-review-checklist.md +86 -0
  42. package/skills/common/skills/plan-writing/SKILL.md +152 -0
  43. package/skills/common/skills/skill-feedback.md +94 -0
  44. package/skills/common/skills/tdd-workflow.md +130 -0
  45. package/skills/common/skills/verification-loop.md +112 -0
  46. package/skills/cpp/agents/cpp-build-resolver.md +90 -0
  47. package/skills/cpp/agents/cpp-reviewer.md +72 -0
  48. package/skills/cpp/manifest.yaml +15 -0
  49. package/skills/cpp/skills/cpp-coding-standards.md +722 -0
  50. package/skills/cpp/skills/cpp-testing.md +323 -0
  51. package/skills/devops/agents/devops-automator.md +376 -0
  52. package/skills/devops/agents/sre.md +90 -0
  53. package/skills/devops/manifest.yaml +20 -0
  54. package/skills/devops/skills/deployment-patterns.md +427 -0
  55. package/skills/devops/skills/deployment-procedures/SKILL.md +241 -0
  56. package/skills/devops/skills/docker-patterns.md +364 -0
  57. package/skills/devops/skills/e2e-testing.md +326 -0
  58. package/skills/devops/skills/github-ops.md +144 -0
  59. package/skills/django/manifest.yaml +16 -0
  60. package/skills/django/skills/django-patterns.md +734 -0
  61. package/skills/django/skills/django-security.md +593 -0
  62. package/skills/django/skills/django-tdd.md +729 -0
  63. package/skills/django/skills/django-verification.md +469 -0
  64. package/skills/dotnet/agents/csharp-reviewer.md +101 -0
  65. package/skills/dotnet/manifest.yaml +14 -0
  66. package/skills/dotnet/skills/csharp-testing.md +321 -0
  67. package/skills/dotnet/skills/dotnet-patterns.md +321 -0
  68. package/skills/go/agents/code-reviewer.md +76 -0
  69. package/skills/go/agents/go-build-resolver.md +94 -0
  70. package/skills/go/agents/go-reviewer.md +76 -0
  71. package/skills/go/manifest.yaml +17 -0
  72. package/skills/go/rules/go-style.md +55 -0
  73. package/skills/go/skills/golang-patterns.md +674 -0
  74. package/skills/go/skills/golang-testing.md +720 -0
  75. package/skills/java/agents/java-build-resolver.md +153 -0
  76. package/skills/java/agents/java-reviewer.md +92 -0
  77. package/skills/java/manifest.yaml +18 -0
  78. package/skills/java/skills/java-coding-standards.md +147 -0
  79. package/skills/java/skills/jpa-patterns.md +151 -0
  80. package/skills/java/skills/springboot-patterns.md +314 -0
  81. package/skills/java/skills/springboot-security.md +272 -0
  82. package/skills/kotlin/agents/kotlin-build-resolver.md +118 -0
  83. package/skills/kotlin/agents/kotlin-reviewer.md +159 -0
  84. package/skills/kotlin/manifest.yaml +17 -0
  85. package/skills/kotlin/skills/kotlin-coroutines-flows.md +284 -0
  86. package/skills/kotlin/skills/kotlin-patterns.md +711 -0
  87. package/skills/kotlin/skills/kotlin-testing.md +824 -0
  88. package/skills/laravel/manifest.yaml +15 -0
  89. package/skills/laravel/skills/laravel-patterns.md +409 -0
  90. package/skills/laravel/skills/laravel-security.md +279 -0
  91. package/skills/laravel/skills/laravel-tdd.md +277 -0
  92. package/skills/laravel/skills/laravel-verification.md +173 -0
  93. package/skills/mobile/agents/dart-build-resolver.md +201 -0
  94. package/skills/mobile/agents/flutter-reviewer.md +243 -0
  95. package/skills/mobile/manifest.yaml +19 -0
  96. package/skills/mobile/skills/android-clean-architecture.md +339 -0
  97. package/skills/mobile/skills/dart-flutter-patterns.md +563 -0
  98. package/skills/mobile/skills/swiftui-patterns.md +259 -0
  99. package/skills/nestjs/manifest.yaml +13 -0
  100. package/skills/nestjs/skills/nestjs-patterns.md +230 -0
  101. package/skills/perl/manifest.yaml +13 -0
  102. package/skills/perl/skills/perl-patterns.md +504 -0
  103. package/skills/perl/skills/perl-security.md +503 -0
  104. package/skills/perl/skills/perl-testing.md +475 -0
  105. package/skills/python/agents/python-reviewer.md +98 -0
  106. package/skills/python/manifest.yaml +18 -0
  107. package/skills/python/rules/python-style.md +69 -0
  108. package/skills/python/skills/python-patterns/SKILL.md +441 -0
  109. package/skills/python/skills/python-patterns.md +90 -0
  110. package/skills/python/skills/python-testing.md +81 -0
  111. package/skills/rust/agents/rust-build-resolver.md +148 -0
  112. package/skills/rust/agents/rust-reviewer.md +94 -0
  113. package/skills/rust/manifest.yaml +16 -0
  114. package/skills/rust/rules/rust-style.md +107 -0
  115. package/skills/rust/skills/rust-patterns.md +499 -0
  116. package/skills/rust/skills/rust-testing.md +500 -0
  117. package/skills/security/agents/accessibility-auditor.md +316 -0
  118. package/skills/security/agents/security-reviewer.md +108 -0
  119. package/skills/security/manifest.yaml +19 -0
  120. package/skills/security/skills/red-team-tactics/SKILL.md +199 -0
  121. package/skills/security/skills/security-bounty-hunter.md +99 -0
  122. package/skills/security/skills/security-review.md +495 -0
  123. package/skills/security/skills/security-scan.md +165 -0
  124. package/skills/security/skills/vulnerability-scanner/SKILL.md +276 -0
  125. package/skills/security/skills/vulnerability-scanner/checklists.md +121 -0
  126. package/skills/security/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  127. package/skills/swift/manifest.yaml +16 -0
  128. package/skills/swift/skills/swift-actor-persistence.md +142 -0
  129. package/skills/swift/skills/swift-concurrency.md +216 -0
  130. package/skills/swift/skills/swift-protocol-di-testing.md +190 -0
  131. package/skills/swift/skills/swiftui-patterns.md +259 -0
  132. package/skills/unity/agents/game-designer.md +167 -0
  133. package/skills/unity/agents/unity-architect.md +52 -0
  134. package/skills/unity/agents/unity-editor-tool-developer.md +310 -0
  135. package/skills/unity/agents/unity-multiplayer-engineer.md +321 -0
  136. package/skills/unity/agents/unity-shader-graph-artist.md +269 -0
  137. package/skills/unity/manifest.yaml +21 -0
  138. package/skills/unity/rules/csharp-patterns.md +48 -0
  139. package/skills/unity/rules/unity-specific.md +53 -0
  140. package/skills/unity/skills/systematic-debugging.md +92 -0
  141. package/skills/unity/skills/unity-architecture.md +173 -0
  142. package/skills/unreal/agents/level-designer.md +208 -0
  143. package/skills/unreal/agents/technical-artist.md +229 -0
  144. package/skills/unreal/agents/unreal-multiplayer-architect.md +313 -0
  145. package/skills/unreal/agents/unreal-systems-engineer.md +310 -0
  146. package/skills/unreal/agents/unreal-technical-artist.md +256 -0
  147. package/skills/unreal/agents/unreal-world-builder.md +273 -0
  148. package/skills/unreal/manifest.yaml +21 -0
  149. package/skills/unreal/skills/unreal-patterns.md +183 -0
  150. package/skills/web/agents/frontend-specialist.md +71 -0
  151. package/skills/web/agents/ui-designer.md +383 -0
  152. package/skills/web/agents/ux-architect.md +469 -0
  153. package/skills/web/manifest.yaml +22 -0
  154. package/skills/web/rules/accessibility.md +54 -0
  155. package/skills/web/rules/css-performance.md +52 -0
  156. package/skills/web/skills/e2e-testing.md +132 -0
  157. package/skills/web/skills/frontend-design/SKILL.md +452 -0
  158. package/skills/web/skills/frontend-design/animation-guide.md +331 -0
  159. package/skills/web/skills/frontend-design/color-system.md +311 -0
  160. package/skills/web/skills/frontend-design/decision-trees.md +418 -0
  161. package/skills/web/skills/frontend-design/motion-graphics.md +306 -0
  162. package/skills/web/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  163. package/skills/web/skills/frontend-design/scripts/ux_audit.py +722 -0
  164. package/skills/web/skills/frontend-design/typography-system.md +345 -0
  165. package/skills/web/skills/frontend-design/ux-psychology.md +1116 -0
  166. package/skills/web/skills/frontend-design/visual-effects.md +383 -0
  167. package/skills/web/skills/react-nextjs.md +135 -0
  168. package/skills/web/skills/tailwind-patterns/SKILL.md +269 -0
  169. package/src/adapters/antigravity.js +164 -0
  170. package/src/adapters/claude.js +188 -0
  171. package/src/adapters/cursor.js +161 -0
  172. package/src/adapters/index.js +67 -0
  173. package/src/adapters/windsurf.js +158 -0
  174. package/src/commands/add.js +266 -0
  175. package/src/commands/create.js +127 -0
  176. package/src/commands/diff.js +78 -0
  177. package/src/commands/info.js +88 -0
  178. package/src/commands/init.js +224 -0
  179. package/src/commands/install.js +90 -0
  180. package/src/commands/list.js +54 -0
  181. package/src/commands/remove.js +101 -0
  182. package/src/commands/targets.js +32 -0
  183. package/src/commands/update.js +57 -0
  184. package/src/core/manifest.js +57 -0
  185. package/src/core/plugins.js +86 -0
  186. package/src/core/resolver.js +84 -0
  187. package/src/core/tracker.js +49 -0
  188. package/src/utils/fs.js +80 -0
  189. package/src/utils/git.js +52 -0
@@ -0,0 +1,314 @@
1
+ ---
2
+ name: springboot-patterns
3
+ description: Spring Boot architecture patterns, REST API design, layered services, data access, caching, async processing, and logging. Use for Java Spring Boot backend work.
4
+ origin: ECC
5
+ ---
6
+
7
+ # Spring Boot Development Patterns
8
+
9
+ Spring Boot architecture and API patterns for scalable, production-grade services.
10
+
11
+ ## When to Activate
12
+
13
+ - Building REST APIs with Spring MVC or WebFlux
14
+ - Structuring controller → service → repository layers
15
+ - Configuring Spring Data JPA, caching, or async processing
16
+ - Adding validation, exception handling, or pagination
17
+ - Setting up profiles for dev/staging/production environments
18
+ - Implementing event-driven patterns with Spring Events or Kafka
19
+
20
+ ## REST API Structure
21
+
22
+ ```java
23
+ @RestController
24
+ @RequestMapping("/api/markets")
25
+ @Validated
26
+ class MarketController {
27
+ private final MarketService marketService;
28
+
29
+ MarketController(MarketService marketService) {
30
+ this.marketService = marketService;
31
+ }
32
+
33
+ @GetMapping
34
+ ResponseEntity<Page<MarketResponse>> list(
35
+ @RequestParam(defaultValue = "0") int page,
36
+ @RequestParam(defaultValue = "20") int size) {
37
+ Page<Market> markets = marketService.list(PageRequest.of(page, size));
38
+ return ResponseEntity.ok(markets.map(MarketResponse::from));
39
+ }
40
+
41
+ @PostMapping
42
+ ResponseEntity<MarketResponse> create(@Valid @RequestBody CreateMarketRequest request) {
43
+ Market market = marketService.create(request);
44
+ return ResponseEntity.status(HttpStatus.CREATED).body(MarketResponse.from(market));
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Repository Pattern (Spring Data JPA)
50
+
51
+ ```java
52
+ public interface MarketRepository extends JpaRepository<MarketEntity, Long> {
53
+ @Query("select m from MarketEntity m where m.status = :status order by m.volume desc")
54
+ List<MarketEntity> findActive(@Param("status") MarketStatus status, Pageable pageable);
55
+ }
56
+ ```
57
+
58
+ ## Service Layer with Transactions
59
+
60
+ ```java
61
+ @Service
62
+ public class MarketService {
63
+ private final MarketRepository repo;
64
+
65
+ public MarketService(MarketRepository repo) {
66
+ this.repo = repo;
67
+ }
68
+
69
+ @Transactional
70
+ public Market create(CreateMarketRequest request) {
71
+ MarketEntity entity = MarketEntity.from(request);
72
+ MarketEntity saved = repo.save(entity);
73
+ return Market.from(saved);
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## DTOs and Validation
79
+
80
+ ```java
81
+ public record CreateMarketRequest(
82
+ @NotBlank @Size(max = 200) String name,
83
+ @NotBlank @Size(max = 2000) String description,
84
+ @NotNull @FutureOrPresent Instant endDate,
85
+ @NotEmpty List<@NotBlank String> categories) {}
86
+
87
+ public record MarketResponse(Long id, String name, MarketStatus status) {
88
+ static MarketResponse from(Market market) {
89
+ return new MarketResponse(market.id(), market.name(), market.status());
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Exception Handling
95
+
96
+ ```java
97
+ @ControllerAdvice
98
+ class GlobalExceptionHandler {
99
+ @ExceptionHandler(MethodArgumentNotValidException.class)
100
+ ResponseEntity<ApiError> handleValidation(MethodArgumentNotValidException ex) {
101
+ String message = ex.getBindingResult().getFieldErrors().stream()
102
+ .map(e -> e.getField() + ": " + e.getDefaultMessage())
103
+ .collect(Collectors.joining(", "));
104
+ return ResponseEntity.badRequest().body(ApiError.validation(message));
105
+ }
106
+
107
+ @ExceptionHandler(AccessDeniedException.class)
108
+ ResponseEntity<ApiError> handleAccessDenied() {
109
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ApiError.of("Forbidden"));
110
+ }
111
+
112
+ @ExceptionHandler(Exception.class)
113
+ ResponseEntity<ApiError> handleGeneric(Exception ex) {
114
+ // Log unexpected errors with stack traces
115
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
116
+ .body(ApiError.of("Internal server error"));
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## Caching
122
+
123
+ Requires `@EnableCaching` on a configuration class.
124
+
125
+ ```java
126
+ @Service
127
+ public class MarketCacheService {
128
+ private final MarketRepository repo;
129
+
130
+ public MarketCacheService(MarketRepository repo) {
131
+ this.repo = repo;
132
+ }
133
+
134
+ @Cacheable(value = "market", key = "#id")
135
+ public Market getById(Long id) {
136
+ return repo.findById(id)
137
+ .map(Market::from)
138
+ .orElseThrow(() -> new EntityNotFoundException("Market not found"));
139
+ }
140
+
141
+ @CacheEvict(value = "market", key = "#id")
142
+ public void evict(Long id) {}
143
+ }
144
+ ```
145
+
146
+ ## Async Processing
147
+
148
+ Requires `@EnableAsync` on a configuration class.
149
+
150
+ ```java
151
+ @Service
152
+ public class NotificationService {
153
+ @Async
154
+ public CompletableFuture<Void> sendAsync(Notification notification) {
155
+ // send email/SMS
156
+ return CompletableFuture.completedFuture(null);
157
+ }
158
+ }
159
+ ```
160
+
161
+ ## Logging (SLF4J)
162
+
163
+ ```java
164
+ @Service
165
+ public class ReportService {
166
+ private static final Logger log = LoggerFactory.getLogger(ReportService.class);
167
+
168
+ public Report generate(Long marketId) {
169
+ log.info("generate_report marketId={}", marketId);
170
+ try {
171
+ // logic
172
+ } catch (Exception ex) {
173
+ log.error("generate_report_failed marketId={}", marketId, ex);
174
+ throw ex;
175
+ }
176
+ return new Report();
177
+ }
178
+ }
179
+ ```
180
+
181
+ ## Middleware / Filters
182
+
183
+ ```java
184
+ @Component
185
+ public class RequestLoggingFilter extends OncePerRequestFilter {
186
+ private static final Logger log = LoggerFactory.getLogger(RequestLoggingFilter.class);
187
+
188
+ @Override
189
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
190
+ FilterChain filterChain) throws ServletException, IOException {
191
+ long start = System.currentTimeMillis();
192
+ try {
193
+ filterChain.doFilter(request, response);
194
+ } finally {
195
+ long duration = System.currentTimeMillis() - start;
196
+ log.info("req method={} uri={} status={} durationMs={}",
197
+ request.getMethod(), request.getRequestURI(), response.getStatus(), duration);
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ ## Pagination and Sorting
204
+
205
+ ```java
206
+ PageRequest page = PageRequest.of(pageNumber, pageSize, Sort.by("createdAt").descending());
207
+ Page<Market> results = marketService.list(page);
208
+ ```
209
+
210
+ ## Error-Resilient External Calls
211
+
212
+ ```java
213
+ public <T> T withRetry(Supplier<T> supplier, int maxRetries) {
214
+ int attempts = 0;
215
+ while (true) {
216
+ try {
217
+ return supplier.get();
218
+ } catch (Exception ex) {
219
+ attempts++;
220
+ if (attempts >= maxRetries) {
221
+ throw ex;
222
+ }
223
+ try {
224
+ Thread.sleep((long) Math.pow(2, attempts) * 100L);
225
+ } catch (InterruptedException ie) {
226
+ Thread.currentThread().interrupt();
227
+ throw ex;
228
+ }
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ ## Rate Limiting (Filter + Bucket4j)
235
+
236
+ **Security Note**: The `X-Forwarded-For` header is untrusted by default because clients can spoof it.
237
+ Only use forwarded headers when:
238
+ 1. Your app is behind a trusted reverse proxy (nginx, AWS ALB, etc.)
239
+ 2. You have registered `ForwardedHeaderFilter` as a bean
240
+ 3. You have configured `server.forward-headers-strategy=NATIVE` or `FRAMEWORK` in application properties
241
+ 4. Your proxy is configured to overwrite (not append to) the `X-Forwarded-For` header
242
+
243
+ When `ForwardedHeaderFilter` is properly configured, `request.getRemoteAddr()` will automatically
244
+ return the correct client IP from the forwarded headers. Without this configuration, use
245
+ `request.getRemoteAddr()` directly—it returns the immediate connection IP, which is the only
246
+ trustworthy value.
247
+
248
+ ```java
249
+ @Component
250
+ public class RateLimitFilter extends OncePerRequestFilter {
251
+ private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
252
+
253
+ /*
254
+ * SECURITY: This filter uses request.getRemoteAddr() to identify clients for rate limiting.
255
+ *
256
+ * If your application is behind a reverse proxy (nginx, AWS ALB, etc.), you MUST configure
257
+ * Spring to handle forwarded headers properly for accurate client IP detection:
258
+ *
259
+ * 1. Set server.forward-headers-strategy=NATIVE (for cloud platforms) or FRAMEWORK in
260
+ * application.properties/yaml
261
+ * 2. If using FRAMEWORK strategy, register ForwardedHeaderFilter:
262
+ *
263
+ * @Bean
264
+ * ForwardedHeaderFilter forwardedHeaderFilter() {
265
+ * return new ForwardedHeaderFilter();
266
+ * }
267
+ *
268
+ * 3. Ensure your proxy overwrites (not appends) the X-Forwarded-For header to prevent spoofing
269
+ * 4. Configure server.tomcat.remoteip.trusted-proxies or equivalent for your container
270
+ *
271
+ * Without this configuration, request.getRemoteAddr() returns the proxy IP, not the client IP.
272
+ * Do NOT read X-Forwarded-For directly—it is trivially spoofable without trusted proxy handling.
273
+ */
274
+ @Override
275
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
276
+ FilterChain filterChain) throws ServletException, IOException {
277
+ // Use getRemoteAddr() which returns the correct client IP when ForwardedHeaderFilter
278
+ // is configured, or the direct connection IP otherwise. Never trust X-Forwarded-For
279
+ // headers directly without proper proxy configuration.
280
+ String clientIp = request.getRemoteAddr();
281
+
282
+ Bucket bucket = buckets.computeIfAbsent(clientIp,
283
+ k -> Bucket.builder()
284
+ .addLimit(Bandwidth.classic(100, Refill.greedy(100, Duration.ofMinutes(1))))
285
+ .build());
286
+
287
+ if (bucket.tryConsume(1)) {
288
+ filterChain.doFilter(request, response);
289
+ } else {
290
+ response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
291
+ }
292
+ }
293
+ }
294
+ ```
295
+
296
+ ## Background Jobs
297
+
298
+ Use Spring’s `@Scheduled` or integrate with queues (e.g., Kafka, SQS, RabbitMQ). Keep handlers idempotent and observable.
299
+
300
+ ## Observability
301
+
302
+ - Structured logging (JSON) via Logback encoder
303
+ - Metrics: Micrometer + Prometheus/OTel
304
+ - Tracing: Micrometer Tracing with OpenTelemetry or Brave backend
305
+
306
+ ## Production Defaults
307
+
308
+ - Prefer constructor injection, avoid field injection
309
+ - Enable `spring.mvc.problemdetails.enabled=true` for RFC 7807 errors (Spring Boot 3+)
310
+ - Configure HikariCP pool sizes for workload, set timeouts
311
+ - Use `@Transactional(readOnly = true)` for queries
312
+ - Enforce null-safety via `@NonNull` and `Optional` where appropriate
313
+
314
+ **Remember**: Keep controllers thin, services focused, repositories simple, and errors handled centrally. Optimize for maintainability and testability.
@@ -0,0 +1,272 @@
1
+ ---
2
+ name: springboot-security
3
+ description: Spring Security best practices for authn/authz, validation, CSRF, secrets, headers, rate limiting, and dependency security in Java Spring Boot services.
4
+ origin: ECC
5
+ ---
6
+
7
+ # Spring Boot Security Review
8
+
9
+ Use when adding auth, handling input, creating endpoints, or dealing with secrets.
10
+
11
+ ## When to Activate
12
+
13
+ - Adding authentication (JWT, OAuth2, session-based)
14
+ - Implementing authorization (@PreAuthorize, role-based access)
15
+ - Validating user input (Bean Validation, custom validators)
16
+ - Configuring CORS, CSRF, or security headers
17
+ - Managing secrets (Vault, environment variables)
18
+ - Adding rate limiting or brute-force protection
19
+ - Scanning dependencies for CVEs
20
+
21
+ ## Authentication
22
+
23
+ - Prefer stateless JWT or opaque tokens with revocation list
24
+ - Use `httpOnly`, `Secure`, `SameSite=Strict` cookies for sessions
25
+ - Validate tokens with `OncePerRequestFilter` or resource server
26
+
27
+ ```java
28
+ @Component
29
+ public class JwtAuthFilter extends OncePerRequestFilter {
30
+ private final JwtService jwtService;
31
+
32
+ public JwtAuthFilter(JwtService jwtService) {
33
+ this.jwtService = jwtService;
34
+ }
35
+
36
+ @Override
37
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
38
+ FilterChain chain) throws ServletException, IOException {
39
+ String header = request.getHeader(HttpHeaders.AUTHORIZATION);
40
+ if (header != null && header.startsWith("Bearer ")) {
41
+ String token = header.substring(7);
42
+ Authentication auth = jwtService.authenticate(token);
43
+ SecurityContextHolder.getContext().setAuthentication(auth);
44
+ }
45
+ chain.doFilter(request, response);
46
+ }
47
+ }
48
+ ```
49
+
50
+ ## Authorization
51
+
52
+ - Enable method security: `@EnableMethodSecurity`
53
+ - Use `@PreAuthorize("hasRole('ADMIN')")` or `@PreAuthorize("@authz.canEdit(#id)")`
54
+ - Deny by default; expose only required scopes
55
+
56
+ ```java
57
+ @RestController
58
+ @RequestMapping("/api/admin")
59
+ public class AdminController {
60
+
61
+ @PreAuthorize("hasRole('ADMIN')")
62
+ @GetMapping("/users")
63
+ public List<UserDto> listUsers() {
64
+ return userService.findAll();
65
+ }
66
+
67
+ @PreAuthorize("@authz.isOwner(#id, authentication)")
68
+ @DeleteMapping("/users/{id}")
69
+ public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
70
+ userService.delete(id);
71
+ return ResponseEntity.noContent().build();
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## Input Validation
77
+
78
+ - Use Bean Validation with `@Valid` on controllers
79
+ - Apply constraints on DTOs: `@NotBlank`, `@Email`, `@Size`, custom validators
80
+ - Sanitize any HTML with a whitelist before rendering
81
+
82
+ ```java
83
+ // BAD: No validation
84
+ @PostMapping("/users")
85
+ public User createUser(@RequestBody UserDto dto) {
86
+ return userService.create(dto);
87
+ }
88
+
89
+ // GOOD: Validated DTO
90
+ public record CreateUserDto(
91
+ @NotBlank @Size(max = 100) String name,
92
+ @NotBlank @Email String email,
93
+ @NotNull @Min(0) @Max(150) Integer age
94
+ ) {}
95
+
96
+ @PostMapping("/users")
97
+ public ResponseEntity<UserDto> createUser(@Valid @RequestBody CreateUserDto dto) {
98
+ return ResponseEntity.status(HttpStatus.CREATED)
99
+ .body(userService.create(dto));
100
+ }
101
+ ```
102
+
103
+ ## SQL Injection Prevention
104
+
105
+ - Use Spring Data repositories or parameterized queries
106
+ - For native queries, use `:param` bindings; never concatenate strings
107
+
108
+ ```java
109
+ // BAD: String concatenation in native query
110
+ @Query(value = "SELECT * FROM users WHERE name = '" + name + "'", nativeQuery = true)
111
+
112
+ // GOOD: Parameterized native query
113
+ @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
114
+ List<User> findByName(@Param("name") String name);
115
+
116
+ // GOOD: Spring Data derived query (auto-parameterized)
117
+ List<User> findByEmailAndActiveTrue(String email);
118
+ ```
119
+
120
+ ## Password Encoding
121
+
122
+ - Always hash passwords with BCrypt or Argon2 — never store plaintext
123
+ - Use `PasswordEncoder` bean, not manual hashing
124
+
125
+ ```java
126
+ @Bean
127
+ public PasswordEncoder passwordEncoder() {
128
+ return new BCryptPasswordEncoder(12); // cost factor 12
129
+ }
130
+
131
+ // In service
132
+ public User register(CreateUserDto dto) {
133
+ String hashedPassword = passwordEncoder.encode(dto.password());
134
+ return userRepository.save(new User(dto.email(), hashedPassword));
135
+ }
136
+ ```
137
+
138
+ ## CSRF Protection
139
+
140
+ - For browser session apps, keep CSRF enabled; include token in forms/headers
141
+ - For pure APIs with Bearer tokens, disable CSRF and rely on stateless auth
142
+
143
+ ```java
144
+ http
145
+ .csrf(csrf -> csrf.disable())
146
+ .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
147
+ ```
148
+
149
+ ## Secrets Management
150
+
151
+ - No secrets in source; load from env or vault
152
+ - Keep `application.yml` free of credentials; use placeholders
153
+ - Rotate tokens and DB credentials regularly
154
+
155
+ ```yaml
156
+ # BAD: Hardcoded in application.yml
157
+ spring:
158
+ datasource:
159
+ password: mySecretPassword123
160
+
161
+ # GOOD: Environment variable placeholder
162
+ spring:
163
+ datasource:
164
+ password: ${DB_PASSWORD}
165
+
166
+ # GOOD: Spring Cloud Vault integration
167
+ spring:
168
+ cloud:
169
+ vault:
170
+ uri: https://vault.example.com
171
+ token: ${VAULT_TOKEN}
172
+ ```
173
+
174
+ ## Security Headers
175
+
176
+ ```java
177
+ http
178
+ .headers(headers -> headers
179
+ .contentSecurityPolicy(csp -> csp
180
+ .policyDirectives("default-src 'self'"))
181
+ .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
182
+ .xssProtection(Customizer.withDefaults())
183
+ .referrerPolicy(rp -> rp.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER)));
184
+ ```
185
+
186
+ ## CORS Configuration
187
+
188
+ - Configure CORS at the security filter level, not per-controller
189
+ - Restrict allowed origins — never use `*` in production
190
+
191
+ ```java
192
+ @Bean
193
+ public CorsConfigurationSource corsConfigurationSource() {
194
+ CorsConfiguration config = new CorsConfiguration();
195
+ config.setAllowedOrigins(List.of("https://app.example.com"));
196
+ config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
197
+ config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
198
+ config.setAllowCredentials(true);
199
+ config.setMaxAge(3600L);
200
+
201
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
202
+ source.registerCorsConfiguration("/api/**", config);
203
+ return source;
204
+ }
205
+
206
+ // In SecurityFilterChain:
207
+ http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
208
+ ```
209
+
210
+ ## Rate Limiting
211
+
212
+ - Apply Bucket4j or gateway-level limits on expensive endpoints
213
+ - Log and alert on bursts; return 429 with retry hints
214
+
215
+ ```java
216
+ // Using Bucket4j for per-endpoint rate limiting
217
+ @Component
218
+ public class RateLimitFilter extends OncePerRequestFilter {
219
+ private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
220
+
221
+ private Bucket createBucket() {
222
+ return Bucket.builder()
223
+ .addLimit(Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1))))
224
+ .build();
225
+ }
226
+
227
+ @Override
228
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
229
+ FilterChain chain) throws ServletException, IOException {
230
+ String clientIp = request.getRemoteAddr();
231
+ Bucket bucket = buckets.computeIfAbsent(clientIp, k -> createBucket());
232
+
233
+ if (bucket.tryConsume(1)) {
234
+ chain.doFilter(request, response);
235
+ } else {
236
+ response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
237
+ response.getWriter().write("{\"error\": \"Rate limit exceeded\"}");
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ ## Dependency Security
244
+
245
+ - Run OWASP Dependency Check / Snyk in CI
246
+ - Keep Spring Boot and Spring Security on supported versions
247
+ - Fail builds on known CVEs
248
+
249
+ ## Logging and PII
250
+
251
+ - Never log secrets, tokens, passwords, or full PAN data
252
+ - Redact sensitive fields; use structured JSON logging
253
+
254
+ ## File Uploads
255
+
256
+ - Validate size, content type, and extension
257
+ - Store outside web root; scan if required
258
+
259
+ ## Checklist Before Release
260
+
261
+ - [ ] Auth tokens validated and expired correctly
262
+ - [ ] Authorization guards on every sensitive path
263
+ - [ ] All inputs validated and sanitized
264
+ - [ ] No string-concatenated SQL
265
+ - [ ] CSRF posture correct for app type
266
+ - [ ] Secrets externalized; none committed
267
+ - [ ] Security headers configured
268
+ - [ ] Rate limiting on APIs
269
+ - [ ] Dependencies scanned and up to date
270
+ - [ ] Logs free of sensitive data
271
+
272
+ **Remember**: Deny by default, validate inputs, least privilege, and secure-by-configuration first.
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: kotlin-build-resolver
3
+ description: Kotlin/Gradle build, compilation, and dependency error resolution specialist. Fixes build errors, Kotlin compiler errors, and Gradle issues with minimal changes. Use when Kotlin builds fail.
4
+ tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
5
+ model: sonnet
6
+ ---
7
+
8
+ # Kotlin Build Error Resolver
9
+
10
+ You are an expert Kotlin/Gradle build error resolution specialist. Your mission is to fix Kotlin build errors, Gradle configuration issues, and dependency resolution failures with **minimal, surgical changes**.
11
+
12
+ ## Core Responsibilities
13
+
14
+ 1. Diagnose Kotlin compilation errors
15
+ 2. Fix Gradle build configuration issues
16
+ 3. Resolve dependency conflicts and version mismatches
17
+ 4. Handle Kotlin compiler errors and warnings
18
+ 5. Fix detekt and ktlint violations
19
+
20
+ ## Diagnostic Commands
21
+
22
+ Run these in order:
23
+
24
+ ```bash
25
+ ./gradlew build 2>&1
26
+ ./gradlew detekt 2>&1 || echo "detekt not configured"
27
+ ./gradlew ktlintCheck 2>&1 || echo "ktlint not configured"
28
+ ./gradlew dependencies --configuration runtimeClasspath 2>&1 | head -100
29
+ ```
30
+
31
+ ## Resolution Workflow
32
+
33
+ ```text
34
+ 1. ./gradlew build -> Parse error message
35
+ 2. Read affected file -> Understand context
36
+ 3. Apply minimal fix -> Only what's needed
37
+ 4. ./gradlew build -> Verify fix
38
+ 5. ./gradlew test -> Ensure nothing broke
39
+ ```
40
+
41
+ ## Common Fix Patterns
42
+
43
+ | Error | Cause | Fix |
44
+ |-------|-------|-----|
45
+ | `Unresolved reference: X` | Missing import, typo, missing dependency | Add import or dependency |
46
+ | `Type mismatch: Required X, Found Y` | Wrong type, missing conversion | Add conversion or fix type |
47
+ | `None of the following candidates is applicable` | Wrong overload, wrong argument types | Fix argument types or add explicit cast |
48
+ | `Smart cast impossible` | Mutable property or concurrent access | Use local `val` copy or `let` |
49
+ | `'when' expression must be exhaustive` | Missing branch in sealed class `when` | Add missing branches or `else` |
50
+ | `Suspend function can only be called from coroutine` | Missing `suspend` or coroutine scope | Add `suspend` modifier or launch coroutine |
51
+ | `Cannot access 'X': it is internal in 'Y'` | Visibility issue | Change visibility or use public API |
52
+ | `Conflicting declarations` | Duplicate definitions | Remove duplicate or rename |
53
+ | `Could not resolve: group:artifact:version` | Missing repository or wrong version | Add repository or fix version |
54
+ | `Execution failed for task ':detekt'` | Code style violations | Fix detekt findings |
55
+
56
+ ## Gradle Troubleshooting
57
+
58
+ ```bash
59
+ # Check dependency tree for conflicts
60
+ ./gradlew dependencies --configuration runtimeClasspath
61
+
62
+ # Force refresh dependencies
63
+ ./gradlew build --refresh-dependencies
64
+
65
+ # Clear project-local Gradle build cache
66
+ ./gradlew clean && rm -rf .gradle/build-cache/
67
+
68
+ # Check Gradle version compatibility
69
+ ./gradlew --version
70
+
71
+ # Run with debug output
72
+ ./gradlew build --debug 2>&1 | tail -50
73
+
74
+ # Check for dependency conflicts
75
+ ./gradlew dependencyInsight --dependency <name> --configuration runtimeClasspath
76
+ ```
77
+
78
+ ## Kotlin Compiler Flags
79
+
80
+ ```kotlin
81
+ // build.gradle.kts - Common compiler options
82
+ kotlin {
83
+ compilerOptions {
84
+ freeCompilerArgs.add("-Xjsr305=strict") // Strict Java null safety
85
+ allWarningsAsErrors = true
86
+ }
87
+ }
88
+ ```
89
+
90
+ ## Key Principles
91
+
92
+ - **Surgical fixes only** -- don't refactor, just fix the error
93
+ - **Never** suppress warnings without explicit approval
94
+ - **Never** change function signatures unless necessary
95
+ - **Always** run `./gradlew build` after each fix to verify
96
+ - Fix root cause over suppressing symptoms
97
+ - Prefer adding missing imports over wildcard imports
98
+
99
+ ## Stop Conditions
100
+
101
+ Stop and report if:
102
+ - Same error persists after 3 fix attempts
103
+ - Fix introduces more errors than it resolves
104
+ - Error requires architectural changes beyond scope
105
+ - Missing external dependencies that need user decision
106
+
107
+ ## Output Format
108
+
109
+ ```text
110
+ [FIXED] src/main/kotlin/com/example/service/UserService.kt:42
111
+ Error: Unresolved reference: UserRepository
112
+ Fix: Added import com.example.repository.UserRepository
113
+ Remaining errors: 2
114
+ ```
115
+
116
+ Final: `Build Status: SUCCESS/FAILED | Errors Fixed: N | Files Modified: list`
117
+
118
+ For detailed Kotlin patterns and code examples, see `skill: kotlin-patterns`.