Claude-skill-registry kotlin-app-config
Sealed class configuration pattern for Kotlin applications with environment-specific settings
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/kotlin-app-config" ~/.claude/skills/majiayu000-claude-skill-registry-kotlin-app-config && rm -rf "$T"
manifest:
skills/data/kotlin-app-config/SKILL.mdsource content
Kotlin Application Configuration Skill
This skill provides patterns for type-safe environment configuration using Kotlin sealed classes.
Sealed Class Configuration Pattern
sealed class Environment( val name: String, val databaseUrl: String, val kafkaBrokers: String, val azureAdIssuer: String ) { data object Local : Environment( name = "local", databaseUrl = "jdbc:postgresql://localhost:5432/myapp", kafkaBrokers = "localhost:9092", azureAdIssuer = "http://localhost:8080/azuread" ) data class Dev( private val env: Map<String, String> ) : Environment( name = "dev", databaseUrl = env.getValue("DATABASE_URL"), kafkaBrokers = env.getValue("KAFKA_BROKERS"), azureAdIssuer = env.getValue("AZURE_OPENID_CONFIG_ISSUER") ) data class Prod( private val env: Map<String, String> ) : Environment( name = "prod", databaseUrl = env.getValue("DATABASE_URL"), kafkaBrokers = env.getValue("KAFKA_BROKERS"), azureAdIssuer = env.getValue("AZURE_OPENID_CONFIG_ISSUER") ) companion object { fun from(env: Map<String, String>): Environment { return when (env["Nais_CLUSTER_NAME"]) { "dev-gcp" -> Dev(env) "prod-gcp" -> Prod(env) else -> Local } } } }
Using Configuration
fun main() { val env = Environment.from(System.getenv()) val dataSource = createDataSource(env.databaseUrl) val kafkaProducer = createKafkaProducer(env.kafkaBrokers) logger.info("Starting application in ${env.name} environment") }
With Konfig Library
import com.natpryce.konfig.* data class AppConfig( val database: DatabaseConfig, val kafka: KafkaConfig, val azure: AzureConfig ) data class DatabaseConfig( val url: String,
Alternative: Sealed Interface Pattern (navikt/hotlibs)
Production pattern from navikt/hotlibs supporting multiple cluster types:
sealed interface Environment { val cluster: String val tier: Tier enum class Tier { TEST, LOCAL, DEV, PROD } companion object { private val all: List<Environment> = listOf( TestEnvironment, LocalEnvironment, GcpEnvironment.DEV, GcpEnvironment.PROD ) val current: Environment by lazy { val cluster = System.getenv("Nais_CLUSTER_NAME") all.find { it.cluster == cluster } ?: LocalEnvironment } } } sealed class DefaultEnvironment( override val cluster: String, override val tier: Environment.Tier ) : Environment object TestEnvironment : DefaultEnvironment("test", Environment.Tier.TEST) object LocalEnvironment : DefaultEnvironment("local", Environment.Tier.LOCAL) enum class GcpEnvironment( override val cluster: String, override val tier: Environment.Tier ) : Environment { DEV("dev-gcp", Environment.Tier.DEV), PROD("prod-gcp", Environment.Tier.PROD) }
data class DatabaseConfig( val url: String, val username: String, val password: String ) data class KafkaConfig( val brokers: String, val topic: String ) data class AzureConfig( val clientId: String, val issuer: String, val jwksUri: String ) fun loadConfig(): AppConfig { val config = ConfigurationProperties.systemProperties() overriding EnvironmentVariables() return AppConfig( database = DatabaseConfig( url = config[Key("database.url", stringType)], username = config[Key("database.username", stringType)], password = config[Key("database.password", stringType)] ), kafka = KafkaConfig( brokers = config[Key("kafka.brokers", stringType)], topic = config[Key("kafka.topic", stringType)] ), azure = AzureConfig( clientId = config[Key("azure.client.id", stringType)], issuer = config[Key("azure.issuer", stringType)], jwksUri = config[Key("azure.jwks.uri", stringType)] ) ) }
Benefits
- Type Safety: Compile-time validation of configuration
- Environment Separation: Clear boundaries between local/dev/prod
- Testability: Easy to create test configurations
- Documentation: Configuration structure is self-documenting