| name | Backend Implementation |
| description | Backend development with Kotlin, Spring Boot, REST APIs. Use for backend, api, service, kotlin, rest tags. Provides validation commands, testing patterns, and blocker scenarios. |
| allowed-tools | Read, Write, Edit, Bash, Grep, Glob |
Backend Implementation Skill
Domain-specific guidance for backend API development, service implementation, and business logic.
When To Use This Skill
Load this Skill when task has tags:
backend,api,service,kotlin,restspring,spring-boot,controller,repository
Validation Commands
Run Tests
# Full test suite
./gradlew test
# Specific test class
./gradlew test --tests "UserServiceTest"
# Single test method
./gradlew test --tests "UserServiceTest.shouldCreateUser"
# With build
./gradlew clean test
Build Project
# Build JAR
./gradlew build
# Build without tests (for quick syntax check)
./gradlew build -x test
Run Application
# Local development
./gradlew bootRun
# With specific profile
./gradlew bootRun --args='--spring.profiles.active=dev'
Success Criteria (Before Completing Task)
✅ ALL tests MUST pass (0 failures, 0 errors) ✅ Build MUST succeed without compilation errors ✅ Code follows project conventions (existing patterns) ✅ API endpoints tested (integration tests) ✅ Error handling implemented (try-catch, validation)
Common Backend Tasks
REST API Endpoints
- Controller with request mapping
- Request/response DTOs
- Service layer business logic
- Repository integration
- Error handling (400, 401, 404, 500)
- Validation (@Valid annotations)
Service Implementation
- Business logic in service classes
- Transaction management (@Transactional)
- Error handling and exceptions
- Dependency injection (@Autowired, constructor injection)
Database Integration
- Repository interfaces (JPA, Exposed ORM)
- Entity mapping
- Query methods
- Transaction boundaries
Testing Principles for Backend
Use Real Infrastructure for Integration Tests
❌ AVOID mocking repositories in integration tests:
// BAD - Mocking repositories misses SQL errors, constraints
@Mock private lateinit var userRepository: UserRepository
when(userRepository.findById(any())).thenReturn(mockUser)
✅ USE real in-memory database:
// GOOD - Tests actual integration
@SpringBootTest
@Transactional // Auto-rollback after each test
class UserApiTest {
@Autowired private lateinit var userRepository: UserRepository
@Autowired private lateinit var userService: UserService
// Tests real database, serialization, constraints
}
Test Incrementally, Not in Batches
❌ Avoid: Write 200 lines code + 15 tests → run all → 12 failures → no idea which code caused which failure
✅ Do:
- Write basic implementation
- Write ONE happy path test
- Run ONLY that test:
./gradlew test --tests "ToolTest.shouldHandleBasicCase" - Fix until passes
- Add ONE edge case test
- Run ONLY that test
- Repeat
Benefits: Feedback in seconds, isolates root cause immediately.
Debug with Actual Output
When test fails:
- Read error message carefully - tells you what's wrong
- Print actual output:
println("Full response: $result") println("Response keys: ${result.jsonObject.keys}") - Verify assumptions about test data - count manually
- Fix root cause, not symptoms
Create Complete Test Entities
❌ BAD - Missing required fields:
val task = Task(
id = UUID.randomUUID(),
title = "Test Task",
status = TaskStatus.PENDING
// Missing: summary, priority, complexity, timestamps
)
taskRepository.create(task) // FAILS: NOT NULL constraint
✅ GOOD - Complete entity:
val task = Task(
id = UUID.randomUUID(),
title = "Test Task",
summary = "Test summary", // Required
status = TaskStatus.PENDING, // Required
priority = Priority.HIGH, // Required
complexity = 5, // Required
tags = listOf("test"),
projectId = testProjectId,
createdAt = Instant.now(), // Required
modifiedAt = Instant.now() // Required
)
How to find required fields: Check migration SQL or ORM model definition.
Common Blocker Scenarios
Blocker 1: Missing Database Schema
Issue: Tests expect column that doesn't exist
SQLSyntaxErrorException: Unknown column 'users.password_hash'
What to try:
- Check migration files - is column defined?
- Review prerequisite database tasks - marked complete but incomplete?
- Check if column was renamed
If blocked: Report to orchestrator - database task may need reopening
Blocker 2: NullPointerException in Service
Issue: NPE at runtime in service class
NullPointerException: Cannot invoke method on null object
What to try:
- Check dependency injection - is @Autowired present?
- Check constructor injection - all parameters provided?
- Check @Configuration on config class
- Check @Service or @Component on service class
- Add null safety (Kotlin: use
?operator, nullable types)
Common causes:
- Missing @Configuration annotation
- Spring not scanning package
- Circular dependency
Blocker 3: Integration Test Failures
Issue: Integration tests pass locally but fail in CI or for others
What to try:
- Check test isolation - are tests cleaning up state?
- Check @Transactional with rollback
- Check test order dependencies (tests should be independent)
- Check H2/in-memory DB configuration matches production DB type
- Check test data initialization
Blocker 4: Architectural Conflict
Issue: Task requirements conflict with existing architecture
Task requires middleware auth but project uses annotation-based security
What to try:
- Review existing patterns in codebase
- Check architecture documentation
- Look for similar implementations
If blocked: Report to orchestrator - may need architectural decision or task revision
Blocker 5: External Dependency Bug
Issue: Third-party library has known bug
JWT library v3.2.1 has refresh token bug - expires immediately
What to try:
- Check library changelog - is fix available in newer version?
- Search for known issues in library's issue tracker
- Try workaround if documented
If blocked: Report to orchestrator - may need to wait for library update or use alternative
Blocker Report Format
⚠️ BLOCKED - Requires Senior Engineer
Issue: [Specific problem - NPE at UserService.kt:42, missing column, etc.]
Attempted Fixes:
- [What you tried #1]
- [What you tried #2]
- [Why attempts didn't work]
Root Cause (if known): [Your analysis]
Partial Progress: [What work you DID complete]
Context for Senior Engineer:
- Error output: [Paste error]
- Test results: [Test failures]
- Related files: [Files involved]
Requires: [What needs to happen - Senior Engineer investigation, etc.]
Quick Reference
Spring Boot Patterns
Controller:
@RestController
@RequestMapping("/api/users")
class UserController(private val userService: UserService) {
@PostMapping
fun createUser(@Valid @RequestBody request: CreateUserRequest): User {
return userService.createUser(request)
}
@GetMapping("/{id}")
fun getUser(@PathVariable id: UUID): User {
return userService.findById(id)
?: throw NotFoundException("User not found")
}
}
Service:
@Service
@Transactional
class UserService(
private val userRepository: UserRepository,
private val passwordEncoder: PasswordEncoder
) {
fun createUser(request: CreateUserRequest): User {
val user = User(
email = request.email,
passwordHash = passwordEncoder.encode(request.password)
)
return userRepository.save(user)
}
}
Repository:
@Repository
interface UserRepository : JpaRepository<User, UUID> {
fun findByEmail(email: String): User?
}
Error Handling
@RestControllerAdvice
class GlobalExceptionHandler {
@ExceptionHandler(NotFoundException::class)
fun handleNotFound(ex: NotFoundException): ResponseEntity<ErrorResponse> {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(ErrorResponse(ex.message))
}
@ExceptionHandler(ValidationException::class)
fun handleValidation(ex: ValidationException): ResponseEntity<ErrorResponse> {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(ErrorResponse(ex.message))
}
}
Common Patterns to Follow
- Controller → Service → Repository layering
- Constructor injection over field injection
- @Transactional on service layer for database operations
- DTO pattern for request/response (don't expose entities)
- Exception handling with @RestControllerAdvice
- Validation with @Valid and constraint annotations
- Testing with real database for integration tests
What NOT to Do
❌ Don't mock repositories in integration tests ❌ Don't skip tests and mark task complete ❌ Don't expose entities directly in API responses ❌ Don't put business logic in controllers ❌ Don't forget @Transactional for database operations ❌ Don't hardcode configuration (use application.yml)
Focus Areas
When reading task sections, prioritize:
requirements- What API endpoints need to be builttechnical-approach- How to implement (patterns, libraries)implementation- Specific implementation detailstesting-strategy- How to test the implementation
Remember
- Run tests incrementally - one test at a time for fast feedback
- Use real infrastructure - in-memory database for integration tests
- Debug with actual output - print what you got, don't assume
- Report blockers promptly - don't wait, communicate to orchestrator
- Follow existing patterns - check codebase for similar implementations
- Complete test entities - all required fields must be populated
- Validation is mandatory - ALL tests must pass before completion
Additional Resources
For deeper patterns and examples, see:
- PATTERNS.md - Spring Security, REST API design patterns (load if needed)
- BLOCKERS.md - Detailed blocker scenarios with solutions (load if stuck)
- examples.md - Complete working examples (load if uncertain)