Loading skill
Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Cursor rules for Kotlin development with Ktor integration.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 105% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 89% | 0% |
Cursor rules for Kotlin development with Ktor integration.
Synced from https://github.com/PatrickJS/awesome-cursorrules/tree/main/rules/kotlin-ktor-development-cursorrules-prompt-file.mdc.
src/main/kotlin/com/company/app/
├── common/ # Shared utilities, extensions
├── config/ # Application configuration, DI
└── features/
├── auth/ # Feature directory
│ ├── models/
│ ├── repositories/
│ ├── services/
│ └── routes/
└── users/ # Another feature
├── ...Test structure mirrors the feature-based organization:
src/test/kotlin/com/company/app/
├── common/
└── features/
├── auth/
│ ├── models/
│ ├── repositories/
│ ├── services/
│ └── routes/
└── users/
├── ...kotlininterface UserRepository { suspend fun findById(id: UUID): UserDTO? suspend fun create(user: CreateUserRequest): UserDTO suspend fun update(id: UUID, user: UpdateUserRequest): UserDTO? suspend fun delete(id: UUID): Boolean } class UserRepositoryImpl : UserRepository { override suspend fun findById(id: UUID): UserDTO? = withContext(Dispatchers.IO) { transaction { Users.select { Users.id eq id } .mapNotNull { it.toUserDTO() } .singleOrNull() } } // Other implementations... }
kotlininterface UserService { suspend fun getUserById(id: UUID): UserDTO suspend fun createUser(request: CreateUserRequest): UserDTO suspend fun updateUser(id: UUID, request: UpdateUserRequest): UserDTO suspend fun deleteUser(id: UUID) } class UserServiceImpl( private val userRepository: UserRepository ) : UserService { override suspend fun getUserById(id: UUID): UserDTO { return userRepository.findById(id) ?: throw ResourceNotFoundException("User", id.toString()) } // Other implementations... }
kotlinfun Application.configureUserRoutes(userService: UserService) { routing { route("/api/users") { get("/{id}") { val id = call.parameters["id"]?.let { UUID.fromString(it) } ?: throw ValidationException("Invalid ID format") val user = userService.getUserById(id) call.respond(ApiResponse("SUCCESS", "User retrieved", user)) } // Other routes... } } }
kotlinopen class ApplicationException( message: String, val statusCode: HttpStatusCode = HttpStatusCode.InternalServerError ) : RuntimeException(message) class ResourceNotFoundException(resource: String, id: String) : ApplicationException("$resource with ID $id not found", HttpStatusCode.NotFound) fun Application.configureExceptions() { install(StatusPages) { exception<ResourceNotFoundException> { call, cause -> call.respond(cause.statusCode, ApiResponse("ERROR", cause.message ?: "Resource not found")) } exception<Throwable> { call, cause -> call.respond(HttpStatusCode.InternalServerError, ApiResponse("ERROR", "An internal error occurred")) } } }
kotlinclass UserServiceTest : DescribeSpec({ describe("UserService") { val mockRepository = mockk<UserRepository>() val userService = UserServiceImpl(mockRepository) it("should return user when exists") { val userId = UUID.randomUUID() val user = UserDTO(userId.toString(), "Test User", "test@example.com") coEvery { mockRepository.findById(userId) } returns user val result = runBlocking { userService.getUserById(userId) } result shouldBe user } it("should throw exception when user not found") { val userId = UUID.randomUUID() coEvery { mockRepository.findById(userId) } returns null shouldThrow<ResourceNotFoundException> { runBlocking { userService.getUserById(userId) } } } } })
kotlinclass UserRoutesTest : FunSpec({ test("GET /api/users/{id} returns 200 when user exists") { val mockService = mockk<UserService>() val userId = UUID.randomUUID() val user = UserDTO(userId.toString(), "Test User", "test@example.com") coEvery { mockService.getUserById(userId) } returns user testApplication { application { configureRouting() configureDI { single { mockService } } } client.get("/api/users/$userId").apply { status shouldBe HttpStatusCode.OK bodyAsText().let { Json.decodeFromString<ApiResponse<UserDTO>>(it) }.data shouldBe user } } } })
kotlin// Type-safe configuration interface AppConfig { val database: DatabaseConfig val security: SecurityConfig } data class DatabaseConfig( val driver: String, val url: String, val user: String, val password: String ) // Access in application fun Application.configureDI() { val appConfig = HoconAppConfig(environment.config) install(Koin) { modules(module { single<AppConfig> { appConfig } single { appConfig.database } }) } }
kotlinfun Application.configureSecurity() { install(Authentication) { jwt("auth-jwt") { // JWT configuration } } install(DefaultHeaders) { header(HttpHeaders.XContentTypeOptions, "nosniff") header(HttpHeaders.XFrameOptions, "DENY") header(HttpHeaders.ContentSecurityPolicy, "default-src 'self'") header("Strict-Transport-Security", "max-age=31536000; includeSubDomains") } }
kotlinfun Application.configureMonitoring() { val startTime = System.currentTimeMillis() routing { get("/health") { call.respond(mapOf("status" to "UP", "uptime" to "${(System.currentTimeMillis() - startTime) / 1000}s")) } get("/metrics") { call.respond(prometheusRegistry.scrape()) } } install(MicrometerMetrics) { registry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT) meterBinders = listOf( JvmMemoryMetrics(), JvmGcMetrics(), ProcessorMetrics(), JvmThreadMetrics() ) } }
-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:MaxRAMPercentage=75.0Other measured skills in the registry, with their headline benchmark lift.