
Kotlin Exposed Patterns
Stand up Kotlin backend data access with Exposed DSL or DAO, pooled connections, Flyway migrations, and repository boundaries.
Overview
kotlin-exposed-patterns is an agent skill for the Build phase that implements JetBrains Exposed ORM access with pooling, Flyway migrations, transactions, and repository boundaries in Kotlin.
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill kotlin-exposed-patternsWhat is this skill?
- Covers Exposed DSL select/where patterns and suspended newSuspendedTransaction usage
- Documents DAO entity lifecycle when that style fits your domain
- Shows HikariCP configuration via HikariConfig for production connection pooling
- Integrates Flyway for versioned SQL migrations at startup
- Promotes repository interfaces so business logic stays off raw table access and tests can use H2
- Documents both Exposed DSL and DAO query styles plus HikariCP and Flyway in one workflow
Adoption & trust: 4k installs on skills.sh; 210k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need a Kotlin backend data layer but the agent spits out raw JDBC or unstructured Exposed calls without pooling, migrations, or testable repositories.
Who is it for?
Solo builders shipping Kotlin API services who standardize on Exposed plus Flyway and want copy-paste-ready structural patterns.
Skip if: Greenfield projects committed to SQLDelight-only, JPA-only, or non-JVM stacks without Kotlin server code.
When should I use this skill?
Setting up database access with Exposed, writing DSL or DAO queries, configuring HikariCP, creating Flyway migrations, implementing repositories, or handling JSON columns.
What do I get? / Deliverables
You get pooled connections, migrated schema, transaction-wrapped queries, and repository-shaped APIs ready to plug into handlers or jobs.
- HikariCP pool configuration
- Flyway migration scripts and startup hook
- Repository interfaces with Exposed-backed implementations
Recommended Skills
Journey fit
ORM setup, pooling, and migrations belong to implementing the product backend before you ship schema changes to production. Database access layers, transactions, and repository interfaces are classic backend integration work in Kotlin services.
How it compares
Structured Exposed + Flyway + Hikari playbook for agents, not a hosted database MCP or ORM-agnostic query builder.
Common Questions / FAQ
Who is kotlin-exposed-patterns for?
Indie and solo developers building Kotlin JVM backends who use or plan to use JetBrains Exposed for PostgreSQL or similar databases.
When should I use kotlin-exposed-patterns?
During Build when setting up database access, writing Exposed DSL or DAO queries, configuring HikariCP, adding Flyway migrations, or implementing repositories.
Is kotlin-exposed-patterns safe to install?
Check the Security Audits panel on this Prism page; skills that touch DB credentials in examples still require you to manage secrets and connection strings in your environment.
SKILL.md
READMESKILL.md - Kotlin Exposed Patterns
# Kotlin Exposed Patterns Comprehensive patterns for database access with JetBrains Exposed ORM, including DSL queries, DAO, transactions, and production-ready configuration. ## When to Use - Setting up database access with Exposed - Writing SQL queries using Exposed DSL or DAO - Configuring connection pooling with HikariCP - Creating database migrations with Flyway - Implementing the repository pattern with Exposed - Handling JSON columns and complex queries ## How It Works Exposed provides two query styles: DSL for direct SQL-like expressions and DAO for entity lifecycle management. HikariCP manages a pool of reusable database connections configured via `HikariConfig`. Flyway runs versioned SQL migration scripts at startup to keep the schema in sync. All database operations run inside `newSuspendedTransaction` blocks for coroutine safety and atomicity. The repository pattern wraps Exposed queries behind an interface so business logic stays decoupled from the data layer and tests can use an in-memory H2 database. ## Examples ### DSL Query ```kotlin suspend fun findUserById(id: UUID): UserRow? = newSuspendedTransaction { UsersTable.selectAll() .where { UsersTable.id eq id } .map { it.toUser() } .singleOrNull() } ``` ### DAO Entity Usage ```kotlin suspend fun createUser(request: CreateUserRequest): User = newSuspendedTransaction { UserEntity.new { name = request.name email = request.email role = request.role }.toModel() } ``` ### HikariCP Configuration ```kotlin val hikariConfig = HikariConfig().apply { driverClassName = config.driver jdbcUrl = config.url username = config.username password = config.password maximumPoolSize = config.maxPoolSize isAutoCommit = false transactionIsolation = "TRANSACTION_READ_COMMITTED" validate() } ``` ## Database Setup ### HikariCP Connection Pooling ```kotlin // DatabaseFactory.kt object DatabaseFactory { fun create(config: DatabaseConfig): Database { val hikariConfig = HikariConfig().apply { driverClassName = config.driver jdbcUrl = config.url username = config.username password = config.password maximumPoolSize = config.maxPoolSize isAutoCommit = false transactionIsolation = "TRANSACTION_READ_COMMITTED" validate() } return Database.connect(HikariDataSource(hikariConfig)) } } data class DatabaseConfig( val url: String, val driver: String = "org.postgresql.Driver", val username: String = "", val password: String = "", val maxPoolSize: Int = 10, ) ``` ### Flyway Migrations ```kotlin // FlywayMigration.kt fun runMigrations(config: DatabaseConfig) { Flyway.configure() .dataSource(config.url, config.username, config.password) .locations("classpath:db/migration") .baselineOnMigrate(true) .load() .migrate() } // Application startup fun Application.module() { val config = DatabaseConfig( url = environment.config.property("database.url").getString(), username = environment.config.property("database.username").getString(), password = environment.config.property("database.password").getString(), ) runMigrations(config) val database = DatabaseFactory.create(config) // ... } ``` ### Migration Files ```sql -- src/main/resources/db/migration/V1__create_users.sql CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(100) NOT NULL, email VARCHAR(255) NOT NULL UNIQUE, role VARCHAR(20) NOT NULL DEFAULT 'USER', metadata JSONB, created_at TIMESTAMPTZ NOT NUL