From team-of-agents
Use when implementing any feature or bugfix in a Kotlin/Spring Boot service — covers layer conventions, idioms, testing, and observability
npx claudepluginhub pranav8494/team-of-agentsThis skill uses the workspace's default tool permissions.
```
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Share bugs, ideas, or general feedback.
No new behaviour without a test that fails first, then passes.
Use this table to determine what to produce for each task type:
| User asks for | What to produce |
|---|---|
| New feature / endpoint | Clarify idempotency, consistency, and compliance requirements; propose data model and API contract first; search codebase for reuse candidates; implement thin controller → service → adapter/repository with validation at the controller boundary and domain exceptions mapped at the adapter boundary |
| Bug fix | Reproduce with a failing test first; identify whether the fault is in controller, service, adapter, or data layer; fix at the root cause and confirm the test passes |
| Data model / schema | Normalised table definitions, surrogate key choice, index plan for every query path, Flyway migration (forward-only, backward-compatible, zero-downtime), EXPLAIN ANALYZE for non-trivial queries |
| Code review | Per-layer feedback: constructor injection, resilience wrapping on external calls, @Transactional scope, BigDecimal for currency, idempotency of financial operations, PII/card data absent from logs, Flyway migration safety, index coverage, metrics on new external calls |
| API design | RESTful resource structure, HTTP status code table, Problem Details error shape (RFC 9457), OpenAPI (Springdoc) spec, Bean Validation placement |
| Testing | Unit test with @WebMvcTest + MockK/Mockito-Kotlin for controllers and services; Testcontainers integration test for repositories; WireMock for outbound HTTP; property-based tests for financial edge cases |
| Observability / metrics | Micrometer counter/timer with {org}.{domain}.{action} naming, result tag (success/failure), OkHttp metrics listener registration, KotlinLogging lambda form with correlation and entity IDs |
| Performance optimisation | Identify bottleneck with EXPLAIN ANALYZE or profiling; tune HikariCP pool size; introduce coroutine parallelism (async/awaitAll) for independent I/O; cache stable reads with @Cacheable |
| Security configuration | Spring Security JWT/OAuth2 resource server config in dedicated SecurityConfig, @PreAuthorize placement, secret storage guidance, fintech compliance checklist |
BigDecimal, never Double or FloatSERIALIZABLE for financial writes; understand the implications before defaulting to READ_COMMITTED@Transactional scope must not span external API calls — hold DB locks for DB work only@RestController + @RequestMapping@Autowired@RequestParam values inline at the parameter@ResponseStatus(HttpStatus.NO_CONTENT) on delete endpoints@Service annotation@Cacheable / @CacheEvict for cached reads of stable datarunBlocking(Dispatchers.IO) {
items.map { async { fetch(it) } }.awaitAll()
}
CoroutineScope(Dispatchers.IO).launch { try { ... } catch (e: Exception) { logger.error(e) { "..." } } }@Repository or @Component depending on roleOkHttpMetricsEventListener)runBlockingNotFoundExceptionTooManyRequestsExceptionForbiddenExceptiondata class for all DTOs and domain objects? for optional attributesemptyList()Extend a base HttpException with the appropriate HttpStatus:
class NotFoundException(override val message: String) :
HttpException(status = HttpStatus.NOT_FOUND, message = message)
data/model/exception/)object with extension functions on receiver types — not a Spring bean:
object DomainMapper {
fun ContentfulDto.toDomain(): DomainModel = ...
}
null when required data is absent; use mapNotNull at call sites@ConfigurationProperties(prefix = "...") on a data class with constructor defaultsSecurityConfig; use @PreAuthorize for method-level access control| Situation | Use |
|---|---|
| Null guard + use | x?.let { use(it) } |
| Null fallback | x ?: default |
| Transform + filter | mapNotNull, filter, map |
| Index by key | associateBy { it.id } |
| Group | groupBy { it.type } |
| Side effect on value | also { log(it) } |
| Enum with string ID | enum class X(val id: String) |
| Domain result type | sealed class Result<out T> — not nullable returns |
EXPLAIN ANALYZE before shipping any new querymaximumPoolSize, connectionTimeout) and monitor pool metricstype, title, status, detail@ExtendWith(SpringExtension::class)
@WebMvcTest(controllers = [MyController::class])
class MyControllerTest {
@Autowired private lateinit var mockMvc: MockMvc
@MockitoBean private lateinit var myService: MyService
@Test
fun `action should return expected result when condition`() { ... }
}
action should result when conditionwhenever(...).thenReturn(...), verify(service).method()verify(service, timeout(1000)).method()runTest { ... }@AfterEachwireMockServer.verify(putRequestedFor(urlEqualTo(...)))@Transactional rollback on DB integration tests to keep state cleanEvery public method: happy path + at least one error/edge case.
Counter.builder("{org}.{domain}.{action}")
.description("...")
.tags(Tags.of("result", result))
.register(meterRegistry)
{org}.{domain}.{action}result (success/failure)OkHttpMetricsEventListener)private val logger = KotlinLogging.logger {}
logger.info { "Message with $variable" }
logger.warn(ex) { "Failed to do X for id=$id" }
{ } — avoids string construction when log level is disabled@Autowired — primary constructor injection only@Transactional scope does not span external API callsBigDecimal; financial operations are idempotentKotlinLogging lambda form@ConfigurationProperties data classEnd every response with a confidence signal on its own line:
CONFIDENCE: [High|Medium|Low] — [one-line reason]
If the task is outside this skill's scope or you lack the information needed to proceed, return this instead of a confidence signal:
BLOCKED: [reason] — [what information would unblock this]
Do not guess or produce low-quality output to avoid returning BLOCKED. A precise BLOCKED is more useful than a low-confidence guess.