From 24018efe67efc232458939bfc4d7e7328b183374 Mon Sep 17 00:00:00 2001 From: ulfrxdev Date: Fri, 24 Apr 2026 18:22:08 +0200 Subject: [PATCH] feat(01-05): add HOCON config, Flyway migration dir, fail-loud Database.migrate - application.conf: HOCON with ktor.deployment.port (8080 + ${?PORT}) and database.url/user/password (localhost defaults + ${?DATABASE_URL/USER/PASSWORD}) - db/migration/.gitkeep: placeholder so classpath:db/migration resolves - Database.kt: object Database.migrate(app) reads HOCON config, runs Flyway with baselineOnMigrate + validateOnMigrate + cleanDisabled, throws IllegalStateException on any failure (D-16 fail-loud contract) - SLF4J (not Kermit); server logs url+user only, never password --- .../main/kotlin/dev/ulfrx/recipe/Database.kt | 31 +++++++++++++++++++ server/src/main/resources/application.conf | 18 +++++++++++ .../src/main/resources/db/migration/.gitkeep | 0 3 files changed, 49 insertions(+) create mode 100644 server/src/main/kotlin/dev/ulfrx/recipe/Database.kt create mode 100644 server/src/main/resources/application.conf create mode 100644 server/src/main/resources/db/migration/.gitkeep diff --git a/server/src/main/kotlin/dev/ulfrx/recipe/Database.kt b/server/src/main/kotlin/dev/ulfrx/recipe/Database.kt new file mode 100644 index 0000000..f7cde44 --- /dev/null +++ b/server/src/main/kotlin/dev/ulfrx/recipe/Database.kt @@ -0,0 +1,31 @@ +package dev.ulfrx.recipe + +import io.ktor.server.application.Application +import org.flywaydb.core.Flyway +import org.slf4j.LoggerFactory + +object Database { + private val log = LoggerFactory.getLogger(Database::class.java) + + fun migrate(app: Application) { + val url = app.environment.config.property("database.url").getString() + val user = app.environment.config.property("database.user").getString() + val password = app.environment.config.property("database.password").getString() + + log.info("Connecting to {} as {} and running Flyway migrations", url, user) + + runCatching { + Flyway.configure() + .dataSource(url, user, password) + .locations("classpath:db/migration") + .baselineOnMigrate(true) + .validateOnMigrate(true) + .cleanDisabled(true) + .load() + .migrate() + }.onFailure { ex -> + log.error("Flyway migration failed — cannot start server", ex) + throw IllegalStateException("Database unreachable or migration failed", ex) + } + } +} diff --git a/server/src/main/resources/application.conf b/server/src/main/resources/application.conf new file mode 100644 index 0000000..c82668d --- /dev/null +++ b/server/src/main/resources/application.conf @@ -0,0 +1,18 @@ +ktor { + deployment { + port = 8080 + port = ${?PORT} + } + application { + modules = [ dev.ulfrx.recipe.ApplicationKt.module ] + } +} + +database { + url = "jdbc:postgresql://localhost:5432/recipe" + url = ${?DATABASE_URL} + user = "recipe" + user = ${?DATABASE_USER} + password = "recipe" + password = ${?DATABASE_PASSWORD} +} diff --git a/server/src/main/resources/db/migration/.gitkeep b/server/src/main/resources/db/migration/.gitkeep new file mode 100644 index 0000000..e69de29