(fix) Konfiguration-Setup Umbau zu SCS
This commit is contained in:
@@ -0,0 +1,173 @@
|
|||||||
|
# Konfigurationsmanagement
|
||||||
|
|
||||||
|
Dieses Dokument beschreibt, wie die Konfiguration des Meldestelle-Projekts verwaltet wird.
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Das Projekt verwendet einen mehrschichtigen Konfigurationsansatz, um verschiedene Umgebungen (Entwicklung, Test, Staging, Produktion) zu unterstützen. Die Konfiguration kann über folgende Quellen bereitgestellt werden:
|
||||||
|
|
||||||
|
1. Umgebungsvariablen (höchste Priorität)
|
||||||
|
2. Umgebungsspezifische Konfigurationsdateien (.properties)
|
||||||
|
3. Basis-Konfigurationsdatei (application.properties)
|
||||||
|
4. Standardwerte im Code (niedrigste Priorität)
|
||||||
|
|
||||||
|
## Konfigurationsquellen
|
||||||
|
|
||||||
|
### Umgebungsvariablen
|
||||||
|
|
||||||
|
Umgebungsvariablen haben die höchste Priorität und überschreiben alle anderen Konfigurationen. Sie werden typischerweise verwendet, um sensible Informationen wie Passwörter oder umgebungsspezifische Werte zu setzen.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
```bash
|
||||||
|
# Umgebung festlegen
|
||||||
|
export APP_ENV=PRODUCTION
|
||||||
|
|
||||||
|
# Datenbank-Konfiguration
|
||||||
|
export DB_HOST=db.example.com
|
||||||
|
export DB_PORT=5432
|
||||||
|
export DB_NAME=meldestelle_db
|
||||||
|
export DB_USER=db_user
|
||||||
|
export DB_PASSWORD=secret_password
|
||||||
|
|
||||||
|
# Server-Konfiguration
|
||||||
|
export API_PORT=8081
|
||||||
|
```
|
||||||
|
|
||||||
|
### Konfigurationsdateien
|
||||||
|
|
||||||
|
Das Projekt verwendet .properties-Dateien im `/config`-Verzeichnis. Die folgenden Dateien werden geladen (in dieser Reihenfolge):
|
||||||
|
|
||||||
|
1. `application.properties` - Basiseinstellungen für alle Umgebungen
|
||||||
|
2. Umgebungsspezifische Datei - abhängig von `APP_ENV`:
|
||||||
|
- `application-dev.properties` - Entwicklungsumgebung (Standard)
|
||||||
|
- `application-test.properties` - Testumgebung
|
||||||
|
- `application-staging.properties` - Staging-Umgebung
|
||||||
|
- `application-prod.properties` - Produktionsumgebung
|
||||||
|
|
||||||
|
## Umgebungen
|
||||||
|
|
||||||
|
Das Projekt unterstützt folgende Umgebungen:
|
||||||
|
|
||||||
|
| Umgebung | Beschreibung | Typische Verwendung |
|
||||||
|
|----------|-------------|--------------------|
|
||||||
|
| DEVELOPMENT | Lokale Entwicklungsumgebung | Lokale Entwicklung, Debug-Modus aktiv |
|
||||||
|
| TEST | Testumgebung | Automatisierte Tests, Integrationstests |
|
||||||
|
| STAGING | Vorabproduktionsumgebung | Manuelle Tests, UAT, Demos |
|
||||||
|
| PRODUCTION | Produktionsumgebung | Live-System |
|
||||||
|
|
||||||
|
Die aktuelle Umgebung wird über die Umgebungsvariable `APP_ENV` festgelegt. Wenn diese Variable nicht gesetzt ist, wird standardmäßig `DEVELOPMENT` verwendet.
|
||||||
|
|
||||||
|
## Konfigurationsstruktur
|
||||||
|
|
||||||
|
Die Konfiguration ist in mehrere Kategorien unterteilt:
|
||||||
|
|
||||||
|
### AppInfo
|
||||||
|
|
||||||
|
Allgemeine Anwendungsinformationen:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
app.name=Meldestelle
|
||||||
|
app.version=1.0.0
|
||||||
|
app.description=Pferdesport Meldestelle System
|
||||||
|
```
|
||||||
|
|
||||||
|
### Server
|
||||||
|
|
||||||
|
Server-Konfiguration:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
server.port=8081
|
||||||
|
server.host=0.0.0.0
|
||||||
|
server.workers=4
|
||||||
|
server.cors.enabled=true
|
||||||
|
server.cors.allowedOrigins=*
|
||||||
|
```
|
||||||
|
|
||||||
|
### Datenbank
|
||||||
|
|
||||||
|
Datenbank-Konfiguration:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
database.host=localhost
|
||||||
|
database.port=5432
|
||||||
|
database.name=meldestelle_db
|
||||||
|
database.username=meldestelle_user
|
||||||
|
database.password=secure_password_change_me
|
||||||
|
database.maxPoolSize=10
|
||||||
|
database.autoMigrate=true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sicherheit
|
||||||
|
|
||||||
|
Sicherheitseinstellungen (JWT, etc.):
|
||||||
|
|
||||||
|
```properties
|
||||||
|
security.jwt.secret=your-secret-key
|
||||||
|
security.jwt.issuer=meldestelle-api
|
||||||
|
security.jwt.audience=meldestelle-clients
|
||||||
|
security.jwt.realm=meldestelle
|
||||||
|
security.jwt.expirationInMinutes=1440
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
Logging-Konfiguration:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
logging.level=INFO
|
||||||
|
logging.requests=true
|
||||||
|
logging.responses=false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verwendung im Code
|
||||||
|
|
||||||
|
Die Konfiguration wird über die zentrale `AppConfig`-Klasse bereitgestellt:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import at.mocode.shared.config.AppConfig
|
||||||
|
|
||||||
|
// Verwendung der Konfiguration
|
||||||
|
fun example() {
|
||||||
|
// Umgebung prüfen
|
||||||
|
if (AppConfig.environment.isDevelopment()) {
|
||||||
|
println("Debug-Modus aktiv")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server-Port abrufen
|
||||||
|
val port = AppConfig.server.port
|
||||||
|
|
||||||
|
// Datenbank-Konfiguration
|
||||||
|
val dbConfig = AppConfig.database
|
||||||
|
|
||||||
|
// JWT-Secret
|
||||||
|
val jwtSecret = AppConfig.security.jwt.secret
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Konfiguration für Docker
|
||||||
|
|
||||||
|
Bei Verwendung von Docker werden Umgebungsvariablen in der `.env`-Datei und im `docker-compose.yml` definiert:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
environment:
|
||||||
|
- APP_ENV=PRODUCTION
|
||||||
|
- DB_HOST=db
|
||||||
|
- DB_PORT=5432
|
||||||
|
- DB_NAME=${POSTGRES_DB}
|
||||||
|
- DB_USER=${POSTGRES_USER}
|
||||||
|
- DB_PASSWORD=${POSTGRES_PASSWORD}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Beste Praktiken
|
||||||
|
|
||||||
|
1. **Sensible Daten**: Speichern Sie niemals sensible Daten wie Passwörter oder API-Schlüssel direkt in Konfigurationsdateien, die in die Versionskontrolle eingecheckt werden. Verwenden Sie stattdessen Umgebungsvariablen.
|
||||||
|
|
||||||
|
2. **Umgebungsspezifische Konfiguration**: Verwenden Sie umgebungsspezifische Konfigurationsdateien nur für Werte, die sich zwischen den Umgebungen unterscheiden.
|
||||||
|
|
||||||
|
3. **Standardwerte**: Geben Sie für alle Konfigurationsparameter sinnvolle Standardwerte an, damit die Anwendung auch funktioniert, wenn nicht alle Konfigurationen explizit gesetzt sind.
|
||||||
|
|
||||||
|
4. **Validierung**: Validieren Sie kritische Konfigurationen beim Anwendungsstart, um Fehler frühzeitig zu erkennen.
|
||||||
|
|
||||||
|
5. **Dokumentation**: Halten Sie die Dokumentation der Konfigurationsparameter aktuell, damit neue Teammitglieder die Anwendung leicht konfigurieren können.
|
||||||
@@ -1,38 +1,30 @@
|
|||||||
package at.mocode.gateway
|
package at.mocode.gateway
|
||||||
|
|
||||||
import at.mocode.gateway.config.MigrationSetup
|
import at.mocode.gateway.config.MigrationSetup
|
||||||
|
import at.mocode.shared.config.AppConfig
|
||||||
import at.mocode.shared.database.DatabaseConfig
|
import at.mocode.shared.database.DatabaseConfig
|
||||||
import at.mocode.shared.database.DatabaseFactory
|
import at.mocode.shared.database.DatabaseFactory
|
||||||
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.engine.*
|
import io.ktor.server.engine.*
|
||||||
import io.ktor.server.netty.*
|
import io.ktor.server.netty.*
|
||||||
import io.ktor.server.plugins.contentnegotiation.*
|
import io.ktor.server.plugins.contentnegotiation.*
|
||||||
import io.ktor.serialization.kotlinx.json.*
|
|
||||||
import io.ktor.server.routing.*
|
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
// Konfiguration laden (wird automatisch beim ersten Zugriff auf AppConfig initialisiert)
|
||||||
|
val config = AppConfig
|
||||||
|
|
||||||
// Datenbank initialisieren
|
// Datenbank initialisieren
|
||||||
val databaseConfig = DatabaseConfig.fromEnv()
|
DatabaseFactory.init(config.database)
|
||||||
DatabaseFactory.init(databaseConfig)
|
|
||||||
|
|
||||||
// Migrationen ausführen
|
// Migrationen ausführen
|
||||||
MigrationSetup.runMigrations()
|
MigrationSetup.runMigrations()
|
||||||
|
|
||||||
// Server starten
|
// Server starten
|
||||||
embeddedServer(Netty, port = System.getenv("API_PORT")?.toIntOrNull() ?: 8081) {
|
embeddedServer(Netty, port = config.server.port, host = config.server.host) {
|
||||||
configureApplication()
|
module()
|
||||||
}.start(wait = true)
|
}.start(wait = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Application.configureApplication() {
|
|
||||||
install(ContentNegotiation) {
|
|
||||||
json()
|
|
||||||
}
|
|
||||||
|
|
||||||
routing {
|
|
||||||
get("/health") {
|
|
||||||
call.respond(mapOf("status" to "OK"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package at.mocode.gateway
|
||||||
|
|
||||||
|
import at.mocode.shared.config.AppConfig
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
|
import io.ktor.server.application.*
|
||||||
|
import io.ktor.server.plugins.calllogging.*
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.*
|
||||||
|
import io.ktor.server.plugins.cors.routing.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
|
fun Application.module() {
|
||||||
|
val config = AppConfig
|
||||||
|
|
||||||
|
// ContentNegotiation installieren
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CORS installieren, wenn aktiviert
|
||||||
|
if (config.server.cors.enabled) {
|
||||||
|
install(CORS) {
|
||||||
|
if (config.server.cors.allowedOrigins.contains("*")) {
|
||||||
|
anyHost()
|
||||||
|
} else {
|
||||||
|
config.server.cors.allowedOrigins.forEach { allowHost(it, schemes = listOf("http", "https")) }
|
||||||
|
}
|
||||||
|
allowHeader(HttpHeaders.ContentType)
|
||||||
|
allowHeader(HttpHeaders.Authorization)
|
||||||
|
allowMethod(HttpMethod.Options)
|
||||||
|
allowMethod(HttpMethod.Get)
|
||||||
|
allowMethod(HttpMethod.Post)
|
||||||
|
allowMethod(HttpMethod.Put)
|
||||||
|
allowMethod(HttpMethod.Delete)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call-Logging installieren
|
||||||
|
if (config.logging.logRequests) {
|
||||||
|
install(CallLogging)
|
||||||
|
}
|
||||||
|
|
||||||
|
routing {
|
||||||
|
// Hauptrouten
|
||||||
|
get("/") {
|
||||||
|
call.respondText(
|
||||||
|
"${config.appInfo.name} API v${config.appInfo.version} (${config.environment})",
|
||||||
|
ContentType.Text.Plain
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Entwicklungsumgebung spezifische Konfiguration
|
||||||
|
|
||||||
|
# Server-Einstellungen
|
||||||
|
server.port=8081
|
||||||
|
|
||||||
|
# Datenbank-Einstellungen
|
||||||
|
database.host=localhost
|
||||||
|
database.port=5432
|
||||||
|
|
||||||
|
# Logging-Einstellungen
|
||||||
|
logging.level=DEBUG
|
||||||
|
logging.requests=true
|
||||||
|
logging.responses=true
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Produktionsumgebung spezifische Konfiguration
|
||||||
|
|
||||||
|
# Server-Einstellungen
|
||||||
|
server.port=8081
|
||||||
|
server.workers=4
|
||||||
|
server.cors.allowedOrigins=https://meldestelle.at,https://app.meldestelle.at
|
||||||
|
|
||||||
|
# Datenbank-Einstellungen
|
||||||
|
database.host=db
|
||||||
|
database.port=5432
|
||||||
|
database.maxPoolSize=20
|
||||||
|
|
||||||
|
# Logging-Einstellungen
|
||||||
|
logging.level=INFO
|
||||||
|
logging.requests=true
|
||||||
|
logging.responses=false
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Staging-Umgebung spezifische Konfiguration
|
||||||
|
|
||||||
|
# Server-Einstellungen
|
||||||
|
server.port=8081
|
||||||
|
server.workers=2
|
||||||
|
server.cors.allowedOrigins=https://staging.meldestelle.at
|
||||||
|
|
||||||
|
# Datenbank-Einstellungen
|
||||||
|
database.host=db
|
||||||
|
database.port=5432
|
||||||
|
database.name=meldestelle_staging_db
|
||||||
|
|
||||||
|
# Logging-Einstellungen
|
||||||
|
logging.level=INFO
|
||||||
|
logging.requests=true
|
||||||
|
logging.responses=false
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Testumgebung spezifische Konfiguration
|
||||||
|
|
||||||
|
# Server-Einstellungen
|
||||||
|
server.port=8082
|
||||||
|
|
||||||
|
# Datenbank-Einstellungen
|
||||||
|
database.host=localhost
|
||||||
|
database.port=5432
|
||||||
|
database.name=meldestelle_test_db
|
||||||
|
|
||||||
|
# Logging-Einstellungen
|
||||||
|
logging.level=DEBUG
|
||||||
|
logging.requests=true
|
||||||
|
logging.responses=true
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Allgemeine Anwendungseinstellungen
|
||||||
|
app.name=Meldestelle
|
||||||
|
app.version=1.0.0
|
||||||
|
app.description=Pferdesport Meldestelle System
|
||||||
|
|
||||||
|
# Server-Einstellungen
|
||||||
|
server.port=8081
|
||||||
|
server.host=0.0.0.0
|
||||||
|
server.workers=4
|
||||||
|
server.cors.enabled=true
|
||||||
|
server.cors.allowedOrigins=*
|
||||||
|
|
||||||
|
# Datenbank-Einstellungen
|
||||||
|
database.host=localhost
|
||||||
|
database.port=5432
|
||||||
|
database.name=meldestelle_db
|
||||||
|
database.username=meldestelle_user
|
||||||
|
database.password=secure_password_change_me
|
||||||
|
database.maxPoolSize=10
|
||||||
|
database.autoMigrate=true
|
||||||
|
|
||||||
|
# Sicherheits-Einstellungen
|
||||||
|
security.jwt.secret=default-jwt-secret-key-please-change-in-production
|
||||||
|
security.jwt.issuer=meldestelle-api
|
||||||
|
security.jwt.audience=meldestelle-clients
|
||||||
|
security.jwt.realm=meldestelle
|
||||||
|
security.jwt.expirationInMinutes=1440
|
||||||
|
|
||||||
|
# Logging-Einstellungen
|
||||||
|
logging.level=INFO
|
||||||
|
logging.requests=true
|
||||||
|
logging.responses=false
|
||||||
+14
-14
@@ -1,16 +1,14 @@
|
|||||||
package at.mocode.events.infrastructure.repository
|
package at.mocode.events.infrastructure.repository
|
||||||
|
|
||||||
|
import at.mocode.enums.SparteE
|
||||||
import at.mocode.events.domain.model.Veranstaltung
|
import at.mocode.events.domain.model.Veranstaltung
|
||||||
import at.mocode.events.domain.repository.VeranstaltungRepository
|
import at.mocode.events.domain.repository.VeranstaltungRepository
|
||||||
import at.mocode.enums.SparteE
|
|
||||||
import com.benasher44.uuid.Uuid
|
import com.benasher44.uuid.Uuid
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.LocalDate
|
import kotlinx.datetime.LocalDate
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
|
||||||
import org.jetbrains.exposed.sql.statements.UpdateBuilder
|
import org.jetbrains.exposed.sql.statements.UpdateBuilder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,21 +20,21 @@ import org.jetbrains.exposed.sql.statements.UpdateBuilder
|
|||||||
class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
||||||
|
|
||||||
override suspend fun findById(id: Uuid): Veranstaltung? {
|
override suspend fun findById(id: Uuid): Veranstaltung? {
|
||||||
return VeranstaltungTable.select { VeranstaltungTable.id eq id }
|
return VeranstaltungTable.selectAll().where { VeranstaltungTable.id eq id }
|
||||||
.map { rowToVeranstaltung(it) }
|
.map { rowToVeranstaltung(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByName(searchTerm: String, limit: Int): List<Veranstaltung> {
|
override suspend fun findByName(searchTerm: String, limit: Int): List<Veranstaltung> {
|
||||||
val searchPattern = "%$searchTerm%"
|
val searchPattern = "%$searchTerm%"
|
||||||
return VeranstaltungTable.select { VeranstaltungTable.name like searchPattern }
|
return VeranstaltungTable.selectAll().where { VeranstaltungTable.name like searchPattern }
|
||||||
.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
|
.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.map { rowToVeranstaltung(it) }
|
.map { rowToVeranstaltung(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): List<Veranstaltung> {
|
override suspend fun findByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): List<Veranstaltung> {
|
||||||
val query = VeranstaltungTable.select { VeranstaltungTable.veranstalterVereinId eq vereinId }
|
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.veranstalterVereinId eq vereinId }
|
||||||
|
|
||||||
return if (activeOnly) {
|
return if (activeOnly) {
|
||||||
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
||||||
@@ -47,9 +45,9 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByDateRange(startDate: LocalDate, endDate: LocalDate, activeOnly: Boolean): List<Veranstaltung> {
|
override suspend fun findByDateRange(startDate: LocalDate, endDate: LocalDate, activeOnly: Boolean): List<Veranstaltung> {
|
||||||
val query = VeranstaltungTable.select {
|
val query = VeranstaltungTable.selectAll().where {
|
||||||
(VeranstaltungTable.startDatum greaterEq startDate) and
|
(VeranstaltungTable.startDatum greaterEq startDate) and
|
||||||
(VeranstaltungTable.endDatum lessEq endDate)
|
(VeranstaltungTable.endDatum lessEq endDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (activeOnly) {
|
return if (activeOnly) {
|
||||||
@@ -61,7 +59,7 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByStartDate(date: LocalDate, activeOnly: Boolean): List<Veranstaltung> {
|
override suspend fun findByStartDate(date: LocalDate, activeOnly: Boolean): List<Veranstaltung> {
|
||||||
val query = VeranstaltungTable.select { VeranstaltungTable.startDatum eq date }
|
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.startDatum eq date }
|
||||||
|
|
||||||
return if (activeOnly) {
|
return if (activeOnly) {
|
||||||
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
||||||
@@ -72,14 +70,14 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findAllActive(limit: Int, offset: Int): List<Veranstaltung> {
|
override suspend fun findAllActive(limit: Int, offset: Int): List<Veranstaltung> {
|
||||||
return VeranstaltungTable.select { VeranstaltungTable.istAktiv eq true }
|
return VeranstaltungTable.selectAll().where { VeranstaltungTable.istAktiv eq true }
|
||||||
.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
|
.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
|
||||||
.limit(limit, offset.toLong())
|
.limit(limit, offset.toLong())
|
||||||
.map { rowToVeranstaltung(it) }
|
.map { rowToVeranstaltung(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findPublicEvents(activeOnly: Boolean): List<Veranstaltung> {
|
override suspend fun findPublicEvents(activeOnly: Boolean): List<Veranstaltung> {
|
||||||
val query = VeranstaltungTable.select { VeranstaltungTable.istOeffentlich eq true }
|
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.istOeffentlich eq true }
|
||||||
|
|
||||||
return if (activeOnly) {
|
return if (activeOnly) {
|
||||||
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
||||||
@@ -94,7 +92,9 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
|||||||
val updatedVeranstaltung = veranstaltung.copy(updatedAt = now)
|
val updatedVeranstaltung = veranstaltung.copy(updatedAt = now)
|
||||||
|
|
||||||
// Check if record exists
|
// Check if record exists
|
||||||
val existingRecord = VeranstaltungTable.select { VeranstaltungTable.id eq veranstaltung.veranstaltungId }.singleOrNull()
|
val existingRecord = VeranstaltungTable.selectAll()
|
||||||
|
.where { VeranstaltungTable.id eq veranstaltung.veranstaltungId }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
return if (existingRecord != null) {
|
return if (existingRecord != null) {
|
||||||
// Update existing record
|
// Update existing record
|
||||||
@@ -118,12 +118,12 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countActive(): Long {
|
override suspend fun countActive(): Long {
|
||||||
return VeranstaltungTable.select { VeranstaltungTable.istAktiv eq true }
|
return VeranstaltungTable.selectAll().where { VeranstaltungTable.istAktiv eq true }
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): Long {
|
override suspend fun countByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): Long {
|
||||||
val query = VeranstaltungTable.select { VeranstaltungTable.veranstalterVereinId eq vereinId }
|
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.veranstalterVereinId eq vereinId }
|
||||||
|
|
||||||
return if (activeOnly) {
|
return if (activeOnly) {
|
||||||
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
query.andWhere { VeranstaltungTable.istAktiv eq true }
|
||||||
|
|||||||
+4
-4
@@ -41,7 +41,7 @@ class HorseRepositoryImpl : HorseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByOepsNummer(oepsNummer: String): DomPferd? {
|
override suspend fun findByOepsNummer(oepsNummer: String): DomPferd? {
|
||||||
return HorseTable.select { HorseTable.oepsNummer eq oepsNummer }
|
return HorseTable.selectAll().where { HorseTable.oepsNummer eq oepsNummer }
|
||||||
.map { rowToDomPferd(it) }
|
.map { rowToDomPferd(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
@@ -224,17 +224,17 @@ class HorseRepositoryImpl : HorseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun existsByFeiNummer(feiNummer: String): Boolean {
|
override suspend fun existsByFeiNummer(feiNummer: String): Boolean {
|
||||||
return HorseTable.select { HorseTable.feiNummer eq feiNummer }
|
return HorseTable.selectAll().where { HorseTable.feiNummer eq feiNummer }
|
||||||
.count() > 0
|
.count() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countActive(): Long {
|
override suspend fun countActive(): Long {
|
||||||
return HorseTable.select { HorseTable.istAktiv eq true }
|
return HorseTable.selectAll().where { HorseTable.istAktiv eq true }
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countByOwnerId(ownerId: Uuid, activeOnly: Boolean): Long {
|
override suspend fun countByOwnerId(ownerId: Uuid, activeOnly: Boolean): Long {
|
||||||
val query = HorseTable.select { HorseTable.besitzerId eq ownerId }
|
val query = HorseTable.selectAll().where { HorseTable.besitzerId eq ownerId }
|
||||||
|
|
||||||
return if (activeOnly) {
|
return if (activeOnly) {
|
||||||
query.andWhere { HorseTable.istAktiv eq true }
|
query.andWhere { HorseTable.istAktiv eq true }
|
||||||
|
|||||||
+13
-19
@@ -6,8 +6,6 @@ import com.benasher44.uuid.Uuid
|
|||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
|
||||||
import org.jetbrains.exposed.sql.SortOrder
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PostgreSQL implementation of LandRepository using Exposed ORM.
|
* PostgreSQL implementation of LandRepository using Exposed ORM.
|
||||||
@@ -18,29 +16,29 @@ import org.jetbrains.exposed.sql.SortOrder
|
|||||||
class LandRepositoryImpl : LandRepository {
|
class LandRepositoryImpl : LandRepository {
|
||||||
|
|
||||||
override suspend fun findById(id: Uuid): LandDefinition? {
|
override suspend fun findById(id: Uuid): LandDefinition? {
|
||||||
return LandTable.select { LandTable.id eq id }
|
return LandTable.selectAll().where { LandTable.id eq id }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.toLandDefinition()
|
?.toLandDefinition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByIsoAlpha2Code(isoAlpha2Code: String): LandDefinition? {
|
override suspend fun findByIsoAlpha2Code(isoAlpha2Code: String): LandDefinition? {
|
||||||
return LandTable.select { LandTable.isoAlpha2Code eq isoAlpha2Code }
|
return LandTable.selectAll().where { LandTable.isoAlpha2Code eq isoAlpha2Code }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.toLandDefinition()
|
?.toLandDefinition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByIsoAlpha3Code(isoAlpha3Code: String): LandDefinition? {
|
override suspend fun findByIsoAlpha3Code(isoAlpha3Code: String): LandDefinition? {
|
||||||
return LandTable.select { LandTable.isoAlpha3Code eq isoAlpha3Code }
|
return LandTable.selectAll().where { LandTable.isoAlpha3Code eq isoAlpha3Code }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.toLandDefinition()
|
?.toLandDefinition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByName(searchTerm: String, limit: Int): List<LandDefinition> {
|
override suspend fun findByName(searchTerm: String, limit: Int): List<LandDefinition> {
|
||||||
val searchPattern = "%$searchTerm%"
|
val searchPattern = "%$searchTerm%"
|
||||||
return LandTable.select {
|
return LandTable.selectAll().where {
|
||||||
(LandTable.nameGerman like searchPattern) or
|
(LandTable.nameGerman like searchPattern) or
|
||||||
(LandTable.nameEnglish like searchPattern) or
|
(LandTable.nameEnglish like searchPattern) or
|
||||||
(LandTable.nameLocal like searchPattern)
|
(LandTable.nameLocal like searchPattern)
|
||||||
}
|
}
|
||||||
.orderBy(LandTable.sortierReihenfolge)
|
.orderBy(LandTable.sortierReihenfolge)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
@@ -48,7 +46,7 @@ class LandRepositoryImpl : LandRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findAllActive(orderBySortierung: Boolean): List<LandDefinition> {
|
override suspend fun findAllActive(orderBySortierung: Boolean): List<LandDefinition> {
|
||||||
val query = LandTable.select { LandTable.isActive eq true }
|
val query = LandTable.selectAll().where { LandTable.isActive eq true }
|
||||||
|
|
||||||
return if (orderBySortierung) {
|
return if (orderBySortierung) {
|
||||||
query.orderBy(LandTable.sortierReihenfolge to SortOrder.ASC, LandTable.nameGerman to SortOrder.ASC)
|
query.orderBy(LandTable.sortierReihenfolge to SortOrder.ASC, LandTable.nameGerman to SortOrder.ASC)
|
||||||
@@ -58,17 +56,13 @@ class LandRepositoryImpl : LandRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findEuMembers(): List<LandDefinition> {
|
override suspend fun findEuMembers(): List<LandDefinition> {
|
||||||
return LandTable.select {
|
return LandTable.selectAll().where { (LandTable.isActive eq true) and (LandTable.isEuMember eq true) }
|
||||||
(LandTable.isActive eq true) and (LandTable.isEuMember eq true)
|
|
||||||
}
|
|
||||||
.orderBy(LandTable.sortierReihenfolge to SortOrder.ASC, LandTable.nameGerman to SortOrder.ASC)
|
.orderBy(LandTable.sortierReihenfolge to SortOrder.ASC, LandTable.nameGerman to SortOrder.ASC)
|
||||||
.map { it.toLandDefinition() }
|
.map { it.toLandDefinition() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findEwrMembers(): List<LandDefinition> {
|
override suspend fun findEwrMembers(): List<LandDefinition> {
|
||||||
return LandTable.select {
|
return LandTable.selectAll().where { (LandTable.isActive eq true) and (LandTable.isEwrMember eq true) }
|
||||||
(LandTable.isActive eq true) and (LandTable.isEwrMember eq true)
|
|
||||||
}
|
|
||||||
.orderBy(LandTable.sortierReihenfolge to SortOrder.ASC, LandTable.nameGerman to SortOrder.ASC)
|
.orderBy(LandTable.sortierReihenfolge to SortOrder.ASC, LandTable.nameGerman to SortOrder.ASC)
|
||||||
.map { it.toLandDefinition() }
|
.map { it.toLandDefinition() }
|
||||||
}
|
}
|
||||||
@@ -77,7 +71,7 @@ class LandRepositoryImpl : LandRepository {
|
|||||||
val now = Clock.System.now()
|
val now = Clock.System.now()
|
||||||
|
|
||||||
// Check if record exists
|
// Check if record exists
|
||||||
val existingRecord = LandTable.select { LandTable.id eq land.landId }.singleOrNull()
|
val existingRecord = LandTable.selectAll().where { LandTable.id eq land.landId }.singleOrNull()
|
||||||
|
|
||||||
return if (existingRecord != null) {
|
return if (existingRecord != null) {
|
||||||
// Update existing record
|
// Update existing record
|
||||||
@@ -126,17 +120,17 @@ class LandRepositoryImpl : LandRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun existsByIsoAlpha2Code(isoAlpha2Code: String): Boolean {
|
override suspend fun existsByIsoAlpha2Code(isoAlpha2Code: String): Boolean {
|
||||||
return LandTable.select { LandTable.isoAlpha2Code eq isoAlpha2Code }
|
return LandTable.selectAll().where { LandTable.isoAlpha2Code eq isoAlpha2Code }
|
||||||
.count() > 0
|
.count() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun existsByIsoAlpha3Code(isoAlpha3Code: String): Boolean {
|
override suspend fun existsByIsoAlpha3Code(isoAlpha3Code: String): Boolean {
|
||||||
return LandTable.select { LandTable.isoAlpha3Code eq isoAlpha3Code }
|
return LandTable.selectAll().where { LandTable.isoAlpha3Code eq isoAlpha3Code }
|
||||||
.count() > 0
|
.count() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countActive(): Long {
|
override suspend fun countActive(): Long {
|
||||||
return LandTable.select { LandTable.isActive eq true }.count()
|
return LandTable.selectAll().where { LandTable.isActive eq true }.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -129,7 +129,7 @@ class UserAuthorizationService(
|
|||||||
for (roleType in roles) {
|
for (roleType in roles) {
|
||||||
// Find the role by type
|
// Find the role by type
|
||||||
val rolle = rolleRepository.findByTyp(roleType)
|
val rolle = rolleRepository.findByTyp(roleType)
|
||||||
if (rolle != null && rolle.rolleId != null) {
|
if (rolle != null) {
|
||||||
// Get role permissions
|
// Get role permissions
|
||||||
val rolleBerechtigungen = rolleBerechtigungRepository.findByRolleId(rolle.rolleId)
|
val rolleBerechtigungen = rolleBerechtigungRepository.findByRolleId(rolle.rolleId)
|
||||||
.filter { it.istAktiv }
|
.filter { it.istAktiv }
|
||||||
|
|||||||
+12
-16
@@ -1,20 +1,16 @@
|
|||||||
package at.mocode.members.infrastructure.repository
|
package at.mocode.members.infrastructure.repository
|
||||||
|
|
||||||
|
// Import table definition and extension functions
|
||||||
import at.mocode.enums.BerechtigungE
|
import at.mocode.enums.BerechtigungE
|
||||||
import at.mocode.members.domain.model.DomBerechtigung
|
import at.mocode.members.domain.model.DomBerechtigung
|
||||||
import at.mocode.members.domain.repository.BerechtigungRepository
|
import at.mocode.members.domain.repository.BerechtigungRepository
|
||||||
import com.benasher44.uuid.Uuid
|
import com.benasher44.uuid.Uuid
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.toKotlinInstant
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import org.jetbrains.exposed.sql.*
|
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
// Import table definition and extension functions
|
import org.jetbrains.exposed.sql.update
|
||||||
import at.mocode.members.infrastructure.repository.BerechtigungTable
|
|
||||||
import at.mocode.members.infrastructure.repository.insertOrUpdate
|
|
||||||
import at.mocode.members.infrastructure.repository.toLocalDateTime
|
|
||||||
import at.mocode.members.infrastructure.repository.toInstant
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposed-based implementation of BerechtigungRepository.
|
* Exposed-based implementation of BerechtigungRepository.
|
||||||
@@ -45,35 +41,35 @@ class BerechtigungRepositoryImpl : BerechtigungRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findById(berechtigungId: Uuid): DomBerechtigung? {
|
override suspend fun findById(berechtigungId: Uuid): DomBerechtigung? {
|
||||||
return BerechtigungTable.select { BerechtigungTable.id eq berechtigungId }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.id eq berechtigungId }
|
||||||
.map { rowToDomBerechtigung(it) }
|
.map { rowToDomBerechtigung(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByTyp(berechtigungTyp: BerechtigungE): DomBerechtigung? {
|
override suspend fun findByTyp(berechtigungTyp: BerechtigungE): DomBerechtigung? {
|
||||||
return BerechtigungTable.select { BerechtigungTable.berechtigungTyp eq berechtigungTyp }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.berechtigungTyp eq berechtigungTyp }
|
||||||
.map { rowToDomBerechtigung(it) }
|
.map { rowToDomBerechtigung(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByName(name: String): List<DomBerechtigung> {
|
override suspend fun findByName(name: String): List<DomBerechtigung> {
|
||||||
val searchPattern = "%$name%"
|
val searchPattern = "%$name%"
|
||||||
return BerechtigungTable.select { BerechtigungTable.name like searchPattern }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.name like searchPattern }
|
||||||
.map { rowToDomBerechtigung(it) }
|
.map { rowToDomBerechtigung(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByRessource(ressource: String): List<DomBerechtigung> {
|
override suspend fun findByRessource(ressource: String): List<DomBerechtigung> {
|
||||||
return BerechtigungTable.select { BerechtigungTable.ressource eq ressource }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.ressource eq ressource }
|
||||||
.map { rowToDomBerechtigung(it) }
|
.map { rowToDomBerechtigung(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByAktion(aktion: String): List<DomBerechtigung> {
|
override suspend fun findByAktion(aktion: String): List<DomBerechtigung> {
|
||||||
return BerechtigungTable.select { BerechtigungTable.aktion eq aktion }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.aktion eq aktion }
|
||||||
.map { rowToDomBerechtigung(it) }
|
.map { rowToDomBerechtigung(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findAllActive(): List<DomBerechtigung> {
|
override suspend fun findAllActive(): List<DomBerechtigung> {
|
||||||
return BerechtigungTable.select { BerechtigungTable.istAktiv eq true }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.istAktiv eq true }
|
||||||
.map { rowToDomBerechtigung(it) }
|
.map { rowToDomBerechtigung(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +99,7 @@ class BerechtigungRepositoryImpl : BerechtigungRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun existsByTyp(berechtigungTyp: BerechtigungE): Boolean {
|
override suspend fun existsByTyp(berechtigungTyp: BerechtigungE): Boolean {
|
||||||
return BerechtigungTable.select { BerechtigungTable.berechtigungTyp eq berechtigungTyp }
|
return BerechtigungTable.selectAll().where { BerechtigungTable.berechtigungTyp eq berechtigungTyp }
|
||||||
.count() > 0
|
.count() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-18
@@ -1,20 +1,15 @@
|
|||||||
package at.mocode.members.infrastructure.repository
|
package at.mocode.members.infrastructure.repository
|
||||||
|
|
||||||
|
// Import table definition and extension functions
|
||||||
import at.mocode.members.domain.model.DomPerson
|
import at.mocode.members.domain.model.DomPerson
|
||||||
import at.mocode.members.domain.repository.PersonRepository
|
import at.mocode.members.domain.repository.PersonRepository
|
||||||
import com.benasher44.uuid.Uuid
|
import com.benasher44.uuid.Uuid
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.toKotlinInstant
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import kotlinx.datetime.toKotlinLocalDate
|
|
||||||
import org.jetbrains.exposed.sql.*
|
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
|
import org.jetbrains.exposed.sql.or
|
||||||
// Import table definition and extension functions
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import at.mocode.members.infrastructure.repository.PersonTable
|
|
||||||
import at.mocode.members.infrastructure.repository.insertOrUpdate
|
|
||||||
import at.mocode.members.infrastructure.repository.toLocalDateTime
|
|
||||||
import at.mocode.members.infrastructure.repository.toInstant
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposed-based implementation of PersonRepository.
|
* Exposed-based implementation of PersonRepository.
|
||||||
@@ -25,34 +20,34 @@ import at.mocode.members.infrastructure.repository.toInstant
|
|||||||
class PersonRepositoryImpl : PersonRepository {
|
class PersonRepositoryImpl : PersonRepository {
|
||||||
|
|
||||||
override suspend fun findById(id: Uuid): DomPerson? {
|
override suspend fun findById(id: Uuid): DomPerson? {
|
||||||
return PersonTable.select { PersonTable.id eq id }
|
return PersonTable.selectAll().where { PersonTable.id eq id }
|
||||||
.map { rowToDomPerson(it) }
|
.map { rowToDomPerson(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByOepsSatzNr(oepsSatzNr: String): DomPerson? {
|
override suspend fun findByOepsSatzNr(oepsSatzNr: String): DomPerson? {
|
||||||
return PersonTable.select { PersonTable.oepsSatzNr eq oepsSatzNr }
|
return PersonTable.selectAll().where { PersonTable.oepsSatzNr eq oepsSatzNr }
|
||||||
.map { rowToDomPerson(it) }
|
.map { rowToDomPerson(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByStammVereinId(vereinId: Uuid): List<DomPerson> {
|
override suspend fun findByStammVereinId(vereinId: Uuid): List<DomPerson> {
|
||||||
return PersonTable.select { PersonTable.stammVereinId eq vereinId }
|
return PersonTable.selectAll().where { PersonTable.stammVereinId eq vereinId }
|
||||||
.map { rowToDomPerson(it) }
|
.map { rowToDomPerson(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByName(searchTerm: String, limit: Int): List<DomPerson> {
|
override suspend fun findByName(searchTerm: String, limit: Int): List<DomPerson> {
|
||||||
val searchPattern = "%$searchTerm%"
|
val searchPattern = "%$searchTerm%"
|
||||||
return PersonTable.select {
|
return PersonTable.selectAll().where {
|
||||||
(PersonTable.nachname like searchPattern) or
|
(PersonTable.nachname like searchPattern) or
|
||||||
(PersonTable.vorname like searchPattern)
|
(PersonTable.vorname like searchPattern)
|
||||||
}
|
}
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.map { rowToDomPerson(it) }
|
.map { rowToDomPerson(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findAllActive(limit: Int, offset: Int): List<DomPerson> {
|
override suspend fun findAllActive(limit: Int, offset: Int): List<DomPerson> {
|
||||||
return PersonTable.select { PersonTable.istAktiv eq true }
|
return PersonTable.selectAll().where { PersonTable.istAktiv eq true }
|
||||||
.limit(limit, offset.toLong())
|
.limit(limit, offset.toLong())
|
||||||
.map { rowToDomPerson(it) }
|
.map { rowToDomPerson(it) }
|
||||||
}
|
}
|
||||||
@@ -100,12 +95,12 @@ class PersonRepositoryImpl : PersonRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun existsByOepsSatzNr(oepsSatzNr: String): Boolean {
|
override suspend fun existsByOepsSatzNr(oepsSatzNr: String): Boolean {
|
||||||
return PersonTable.select { PersonTable.oepsSatzNr eq oepsSatzNr }
|
return PersonTable.selectAll().where { PersonTable.oepsSatzNr eq oepsSatzNr }
|
||||||
.count() > 0
|
.count() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countActive(): Long {
|
override suspend fun countActive(): Long {
|
||||||
return PersonTable.select { PersonTable.istAktiv eq true }
|
return PersonTable.selectAll().where { PersonTable.istAktiv eq true }
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-22
@@ -1,19 +1,12 @@
|
|||||||
package at.mocode.members.infrastructure.repository
|
package at.mocode.members.infrastructure.repository
|
||||||
|
|
||||||
|
// Import table definition and extension functions
|
||||||
import at.mocode.members.domain.model.DomVerein
|
import at.mocode.members.domain.model.DomVerein
|
||||||
import at.mocode.members.domain.repository.VereinRepository
|
import at.mocode.members.domain.repository.VereinRepository
|
||||||
import com.benasher44.uuid.Uuid
|
import com.benasher44.uuid.Uuid
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.toKotlinInstant
|
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
|
||||||
|
|
||||||
// Import table definition and extension functions
|
|
||||||
import at.mocode.members.infrastructure.repository.VereinTable
|
|
||||||
import at.mocode.members.infrastructure.repository.insertOrUpdate
|
|
||||||
import at.mocode.members.infrastructure.repository.toLocalDateTime
|
|
||||||
import at.mocode.members.infrastructure.repository.toInstant
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposed-based implementation of VereinRepository.
|
* Exposed-based implementation of VereinRepository.
|
||||||
@@ -24,48 +17,48 @@ import at.mocode.members.infrastructure.repository.toInstant
|
|||||||
class VereinRepositoryImpl : VereinRepository {
|
class VereinRepositoryImpl : VereinRepository {
|
||||||
|
|
||||||
override suspend fun findById(id: Uuid): DomVerein? {
|
override suspend fun findById(id: Uuid): DomVerein? {
|
||||||
return VereinTable.select { VereinTable.id eq id }
|
return VereinTable.selectAll().where { VereinTable.id eq id }
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByOepsVereinsNr(oepsVereinsNr: String): DomVerein? {
|
override suspend fun findByOepsVereinsNr(oepsVereinsNr: String): DomVerein? {
|
||||||
return VereinTable.select { VereinTable.oepsVereinsNr eq oepsVereinsNr }
|
return VereinTable.selectAll().where { VereinTable.oepsVereinsNr eq oepsVereinsNr }
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByName(searchTerm: String, limit: Int): List<DomVerein> {
|
override suspend fun findByName(searchTerm: String, limit: Int): List<DomVerein> {
|
||||||
val searchPattern = "%$searchTerm%"
|
val searchPattern = "%$searchTerm%"
|
||||||
return VereinTable.select {
|
return VereinTable.selectAll().where {
|
||||||
(VereinTable.name like searchPattern) or
|
(VereinTable.name like searchPattern) or
|
||||||
(VereinTable.kuerzel like searchPattern)
|
(VereinTable.kuerzel like searchPattern)
|
||||||
}
|
}
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByBundeslandId(bundeslandId: Uuid): List<DomVerein> {
|
override suspend fun findByBundeslandId(bundeslandId: Uuid): List<DomVerein> {
|
||||||
return VereinTable.select { VereinTable.bundeslandId eq bundeslandId }
|
return VereinTable.selectAll().where { VereinTable.bundeslandId eq bundeslandId }
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByLandId(landId: Uuid): List<DomVerein> {
|
override suspend fun findByLandId(landId: Uuid): List<DomVerein> {
|
||||||
return VereinTable.select { VereinTable.landId eq landId }
|
return VereinTable.selectAll().where { VereinTable.landId eq landId }
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findAllActive(limit: Int, offset: Int): List<DomVerein> {
|
override suspend fun findAllActive(limit: Int, offset: Int): List<DomVerein> {
|
||||||
return VereinTable.select { VereinTable.istAktiv eq true }
|
return VereinTable.selectAll().where { VereinTable.istAktiv eq true }
|
||||||
.limit(limit, offset.toLong())
|
.limit(limit, offset.toLong())
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByLocation(searchTerm: String, limit: Int): List<DomVerein> {
|
override suspend fun findByLocation(searchTerm: String, limit: Int): List<DomVerein> {
|
||||||
val searchPattern = "%$searchTerm%"
|
val searchPattern = "%$searchTerm%"
|
||||||
return VereinTable.select {
|
return VereinTable.selectAll().where {
|
||||||
(VereinTable.ort like searchPattern) or
|
(VereinTable.ort like searchPattern) or
|
||||||
(VereinTable.plz like searchPattern)
|
(VereinTable.plz like searchPattern)
|
||||||
}
|
}
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.map { rowToDomVerein(it) }
|
.map { rowToDomVerein(it) }
|
||||||
@@ -104,19 +97,18 @@ class VereinRepositoryImpl : VereinRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun existsByOepsVereinsNr(oepsVereinsNr: String): Boolean {
|
override suspend fun existsByOepsVereinsNr(oepsVereinsNr: String): Boolean {
|
||||||
return VereinTable.select { VereinTable.oepsVereinsNr eq oepsVereinsNr }
|
return VereinTable.selectAll().where { VereinTable.oepsVereinsNr eq oepsVereinsNr }
|
||||||
.count() > 0
|
.count() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countActive(): Long {
|
override suspend fun countActive(): Long {
|
||||||
return VereinTable.select { VereinTable.istAktiv eq true }
|
return VereinTable.selectAll().where { VereinTable.istAktiv eq true }
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun countActiveByBundeslandId(bundeslandId: Uuid): Long {
|
override suspend fun countActiveByBundeslandId(bundeslandId: Uuid): Long {
|
||||||
return VereinTable.select {
|
return VereinTable.selectAll()
|
||||||
(VereinTable.istAktiv eq true) and (VereinTable.bundeslandId eq bundeslandId)
|
.where { (VereinTable.istAktiv eq true) and (VereinTable.bundeslandId eq bundeslandId) }
|
||||||
}
|
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package at.mocode.shared.config
|
||||||
|
|
||||||
|
import at.mocode.shared.database.DatabaseConfig
|
||||||
|
import java.io.File
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zentrale Konfigurationsverwaltung für die Anwendung.
|
||||||
|
* Lädt Konfigurationen aus verschiedenen Quellen (Umgebungsvariablen, Property-Dateien).
|
||||||
|
*/
|
||||||
|
object AppConfig {
|
||||||
|
// Aktuelle Umgebung
|
||||||
|
val environment: AppEnvironment = AppEnvironment.current()
|
||||||
|
|
||||||
|
// Anwendungs-Informationen
|
||||||
|
val appInfo = AppInfoConfig()
|
||||||
|
|
||||||
|
// Server-Konfiguration
|
||||||
|
val server = ServerConfig()
|
||||||
|
|
||||||
|
// Sicherheits-Konfiguration
|
||||||
|
val security = SecurityConfig()
|
||||||
|
|
||||||
|
// Logging-Konfiguration
|
||||||
|
val logging = LoggingConfig()
|
||||||
|
|
||||||
|
// Datenbank-Konfiguration (wird nach dem Laden der Properties initialisiert)
|
||||||
|
val database: DatabaseConfig
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Lade Umgebungsspezifische Properties
|
||||||
|
val props = loadProperties()
|
||||||
|
|
||||||
|
// Konfiguriere Komponenten mit Properties
|
||||||
|
appInfo.configure(props)
|
||||||
|
server.configure(props)
|
||||||
|
security.configure(props)
|
||||||
|
logging.configure(props)
|
||||||
|
|
||||||
|
// Datenbank-Konfiguration mit Properties initialisieren
|
||||||
|
database = DatabaseConfig.fromEnv(props)
|
||||||
|
|
||||||
|
// Log Konfigurationsinformationen
|
||||||
|
if (!AppEnvironment.isProduction()) {
|
||||||
|
println("=== Anwendungskonfiguration ===")
|
||||||
|
println("Umgebung: $environment")
|
||||||
|
println("App: ${appInfo.name} v${appInfo.version}")
|
||||||
|
println("Server: Port ${server.port}, ${server.workers} Worker")
|
||||||
|
println("Datenbank: ${database.jdbcUrl}")
|
||||||
|
println("===============================\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt die Properties für die aktuelle Umgebung.
|
||||||
|
*/
|
||||||
|
private fun loadProperties(): Properties {
|
||||||
|
val props = Properties()
|
||||||
|
|
||||||
|
// Lade Basis-Properties
|
||||||
|
loadPropertiesFile("application.properties", props)
|
||||||
|
|
||||||
|
// Lade umgebungsspezifische Properties
|
||||||
|
val envFile = when (environment) {
|
||||||
|
AppEnvironment.DEVELOPMENT -> "application-dev.properties"
|
||||||
|
AppEnvironment.TEST -> "application-test.properties"
|
||||||
|
AppEnvironment.STAGING -> "application-staging.properties"
|
||||||
|
AppEnvironment.PRODUCTION -> "application-prod.properties"
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPropertiesFile(envFile, props)
|
||||||
|
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt eine Property-Datei, wenn sie existiert.
|
||||||
|
*/
|
||||||
|
private fun loadPropertiesFile(filename: String, props: Properties) {
|
||||||
|
val resourceStream = javaClass.classLoader.getResourceAsStream(filename)
|
||||||
|
if (resourceStream != null) {
|
||||||
|
props.load(resourceStream)
|
||||||
|
resourceStream.close()
|
||||||
|
} else {
|
||||||
|
// Versuche aus dem Dateisystem zu laden
|
||||||
|
val file = File("config/$filename")
|
||||||
|
if (file.exists()) {
|
||||||
|
file.inputStream().use { props.load(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt den Wert einer Property zurück, wobei die Priorität wie folgt ist:
|
||||||
|
* 1. Umgebungsvariable
|
||||||
|
* 2. Property aus Datei
|
||||||
|
* 3. Standardwert
|
||||||
|
*/
|
||||||
|
fun getProperty(key: String, defaultValue: String? = null): String? {
|
||||||
|
val envKey = key.replace('.', '_').uppercase()
|
||||||
|
return System.getenv(envKey) ?: defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konfiguration für Anwendungsinformationen.
|
||||||
|
*/
|
||||||
|
class AppInfoConfig {
|
||||||
|
var name: String = "Meldestelle"
|
||||||
|
var version: String = "1.0.0"
|
||||||
|
var description: String = "Pferdesport Meldestelle System"
|
||||||
|
|
||||||
|
fun configure(props: Properties) {
|
||||||
|
name = props.getProperty("app.name", name)
|
||||||
|
version = props.getProperty("app.version", version)
|
||||||
|
description = props.getProperty("app.description", description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konfiguration für den Server.
|
||||||
|
*/
|
||||||
|
class ServerConfig {
|
||||||
|
var port: Int = System.getenv("API_PORT")?.toIntOrNull() ?: 8081
|
||||||
|
var host: String = System.getenv("API_HOST") ?: "0.0.0.0"
|
||||||
|
var workers: Int = Runtime.getRuntime().availableProcessors()
|
||||||
|
var cors: CorsConfig = CorsConfig()
|
||||||
|
|
||||||
|
fun configure(props: Properties) {
|
||||||
|
port = props.getProperty("server.port")?.toIntOrNull() ?: port
|
||||||
|
host = props.getProperty("server.host") ?: host
|
||||||
|
workers = props.getProperty("server.workers")?.toIntOrNull() ?: workers
|
||||||
|
|
||||||
|
// CORS Konfiguration
|
||||||
|
cors.enabled = props.getProperty("server.cors.enabled")?.toBoolean() ?: cors.enabled
|
||||||
|
props.getProperty("server.cors.allowedOrigins")?.split(",")?.map { it.trim() }?.let {
|
||||||
|
cors.allowedOrigins = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CorsConfig {
|
||||||
|
var enabled: Boolean = true
|
||||||
|
var allowedOrigins: List<String> = listOf("*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konfiguration für die Sicherheit.
|
||||||
|
*/
|
||||||
|
class SecurityConfig {
|
||||||
|
var jwt = JwtConfig()
|
||||||
|
|
||||||
|
fun configure(props: Properties) {
|
||||||
|
// JWT Konfiguration
|
||||||
|
jwt.secret = System.getenv("JWT_SECRET") ?: props.getProperty("security.jwt.secret") ?: jwt.secret
|
||||||
|
jwt.issuer = System.getenv("JWT_ISSUER") ?: props.getProperty("security.jwt.issuer") ?: jwt.issuer
|
||||||
|
jwt.audience = System.getenv("JWT_AUDIENCE") ?: props.getProperty("security.jwt.audience") ?: jwt.audience
|
||||||
|
jwt.realm = System.getenv("JWT_REALM") ?: props.getProperty("security.jwt.realm") ?: jwt.realm
|
||||||
|
|
||||||
|
props.getProperty("security.jwt.expirationInMinutes")?.toLongOrNull()?.let {
|
||||||
|
jwt.expirationInMinutes = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JwtConfig {
|
||||||
|
var secret: String = "default-jwt-secret-key-please-change-in-production"
|
||||||
|
var issuer: String = "meldestelle-api"
|
||||||
|
var audience: String = "meldestelle-clients"
|
||||||
|
var realm: String = "meldestelle"
|
||||||
|
var expirationInMinutes: Long = 60 * 24 // 24 Stunden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konfiguration für das Logging.
|
||||||
|
*/
|
||||||
|
class LoggingConfig {
|
||||||
|
var level: String = if (AppEnvironment.isProduction()) "INFO" else "DEBUG"
|
||||||
|
var logRequests: Boolean = true
|
||||||
|
var logResponses: Boolean = !AppEnvironment.isProduction()
|
||||||
|
|
||||||
|
fun configure(props: Properties) {
|
||||||
|
level = props.getProperty("logging.level") ?: level
|
||||||
|
logRequests = props.getProperty("logging.requests")?.toBoolean() ?: logRequests
|
||||||
|
logResponses = props.getProperty("logging.responses")?.toBoolean() ?: logResponses
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package at.mocode.shared.config
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aufzählung der verschiedenen Anwendungsumgebungen.
|
||||||
|
*/
|
||||||
|
enum class AppEnvironment {
|
||||||
|
DEVELOPMENT, // Lokale Entwicklungsumgebung
|
||||||
|
TEST, // Testumgebung (CI/CD, Integrationstests)
|
||||||
|
STAGING, // Vorabproduktionsumgebung
|
||||||
|
PRODUCTION; // Produktionsumgebung
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Ermittelt die aktuelle Umgebung basierend auf der APP_ENV Umgebungsvariable.
|
||||||
|
*
|
||||||
|
* @return Die aktuelle Umgebung (Standardmäßig DEVELOPMENT wenn nicht definiert)
|
||||||
|
*/
|
||||||
|
fun current(): AppEnvironment {
|
||||||
|
val envName = System.getenv("APP_ENV")?.uppercase() ?: "DEVELOPMENT"
|
||||||
|
return try {
|
||||||
|
valueOf(envName)
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
println("Warnung: Unbekannte Umgebung '$envName', verwende DEVELOPMENT")
|
||||||
|
DEVELOPMENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob die aktuelle Umgebung die Entwicklungsumgebung ist.
|
||||||
|
*/
|
||||||
|
fun isDevelopment() = current() == DEVELOPMENT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob die aktuelle Umgebung die Testumgebung ist.
|
||||||
|
*/
|
||||||
|
fun isTest() = current() == TEST
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob die aktuelle Umgebung die Staging-Umgebung ist.
|
||||||
|
*/
|
||||||
|
fun isStaging() = current() == STAGING
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob die aktuelle Umgebung die Produktionsumgebung ist.
|
||||||
|
*/
|
||||||
|
fun isProduction() = current() == PRODUCTION
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,32 +1,45 @@
|
|||||||
package at.mocode.shared.database
|
package at.mocode.shared.database
|
||||||
|
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Konfiguration für die Datenbankverbindung.
|
* Konfiguration für die Datenbankverbindung.
|
||||||
* Parameter werden aus Umgebungsvariablen gelesen oder Standardwerte verwendet.
|
* Parameter werden aus Umgebungsvariablen oder Property-Dateien gelesen.
|
||||||
*/
|
*/
|
||||||
data class DatabaseConfig(
|
data class DatabaseConfig(
|
||||||
val jdbcUrl: String,
|
val jdbcUrl: String,
|
||||||
val username: String,
|
val username: String,
|
||||||
val password: String,
|
val password: String,
|
||||||
val driverClassName: String = "org.postgresql.Driver",
|
val driverClassName: String = "org.postgresql.Driver",
|
||||||
val maxPoolSize: Int = 10
|
val maxPoolSize: Int = 10,
|
||||||
|
val autoMigrate: Boolean = true
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Erstellt eine Datenbank-Konfiguration aus Umgebungsvariablen.
|
* Erstellt eine Datenbank-Konfiguration aus Umgebungsvariablen und Properties.
|
||||||
* Wenn keine Umgebungsvariablen gefunden werden, werden Standardwerte für die Entwicklung verwendet.
|
* Wenn keine Umgebungsvariablen gefunden werden, werden Standardwerte für die Entwicklung verwendet.
|
||||||
*/
|
*/
|
||||||
fun fromEnv(): DatabaseConfig {
|
fun fromEnv(props: Properties = Properties()): DatabaseConfig {
|
||||||
val host = System.getenv("DB_HOST") ?: "localhost"
|
// Priorität: Umgebungsvariablen > Properties > Standardwerte
|
||||||
val port = System.getenv("DB_PORT") ?: "5432"
|
val host = System.getenv("DB_HOST") ?: props.getProperty("database.host") ?: "localhost"
|
||||||
val database = System.getenv("DB_NAME") ?: "meldestelle_db"
|
val port = System.getenv("DB_PORT") ?: props.getProperty("database.port") ?: "5432"
|
||||||
val username = System.getenv("DB_USER") ?: "meldestelle_user"
|
val database = System.getenv("DB_NAME") ?: props.getProperty("database.name") ?: "meldestelle_db"
|
||||||
val password = System.getenv("DB_PASSWORD") ?: "secure_password_change_me"
|
val username = System.getenv("DB_USER") ?: props.getProperty("database.username") ?: "meldestelle_user"
|
||||||
|
val password = System.getenv("DB_PASSWORD") ?: props.getProperty("database.password") ?: "secure_password_change_me"
|
||||||
|
val maxPoolSize = System.getenv("DB_MAX_POOL_SIZE")?.toIntOrNull()
|
||||||
|
?: props.getProperty("database.maxPoolSize")?.toIntOrNull()
|
||||||
|
?: 10
|
||||||
|
val autoMigrate = System.getenv("DB_AUTO_MIGRATE")?.toBoolean()
|
||||||
|
?: props.getProperty("database.autoMigrate")?.toBoolean()
|
||||||
|
?: true
|
||||||
|
|
||||||
return DatabaseConfig(
|
return DatabaseConfig(
|
||||||
jdbcUrl = "jdbc:postgresql://$host:$port/$database",
|
jdbcUrl = "jdbc:postgresql://$host:$port/$database",
|
||||||
username = username,
|
username = username,
|
||||||
password = password
|
password = password,
|
||||||
|
driverClassName = "org.postgresql.Driver",
|
||||||
|
maxPoolSize = maxPoolSize,
|
||||||
|
autoMigrate = autoMigrate
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user