(fix) Umbau zu SCS

**Backend:**
- Vervollständigen Sie alle Repository-Implementierungen
- Implementieren Sie die Authentifizierung und Autorisierung
- Fügen Sie Validierung für alle API-Endpunkte hinzu
This commit is contained in:
stefan
2025-07-19 18:31:32 +02:00
parent 8c1ddb6cb2
commit 83d0d81193
22 changed files with 134 additions and 152 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ Alle Endpunkte verwenden das gleiche Pattern:
```kotlin ```kotlin
// Validierung durchführen // Validierung durchführen
val validationErrors = ApiValidationUtils.validateXxx(...) val validationErrors = ApiValidationUtils.validateXxx('...')
if (!ApiValidationUtils.isValid(validationErrors)) { if (!ApiValidationUtils.isValid(validationErrors)) {
call.respond( call.respond(
@@ -39,4 +39,4 @@ fun Application.configureApiKeyAuth() {
/** /**
* Principal für die API-Key-Authentifizierung. * Principal für die API-Key-Authentifizierung.
*/ */
class ApiKeyPrincipal(val apiKey: String) : Principal class ApiKeyPrincipal(val apiKey: String)
@@ -3,8 +3,6 @@ package at.mocode.gateway.auth
import at.mocode.enums.BerechtigungE import at.mocode.enums.BerechtigungE
import at.mocode.members.domain.service.JwtService import at.mocode.members.domain.service.JwtService
import at.mocode.shared.config.AppConfig import at.mocode.shared.config.AppConfig
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@@ -47,7 +45,7 @@ fun Application.configureJwtAuth(jwtService: JwtService) {
/** /**
* Prüft, ob der aktuelle Benutzer die angegebene Berechtigung hat. * Prüft, ob der aktuelle Benutzer die angegebene Berechtigung hat.
* Muss innerhalb einer authenticate("jwt")-Block verwendet werden. * Muss innerhalb eines authenticate("jwt")-Block verwendet werden.
* *
* @param permission Die erforderliche Berechtigung * @param permission Die erforderliche Berechtigung
* @param onFailure Funktion, die bei fehlender Berechtigung aufgerufen wird * @param onFailure Funktion, die bei fehlender Berechtigung aufgerufen wird
@@ -64,9 +62,13 @@ suspend fun ApplicationCall.requirePermission(
return return
} }
val permissions = principal.getClaim("permissions", Array<String>::class) val permissions = principal.getClaim("permissions", Array<String>::class)?.mapNotNull {
?.map { try { BerechtigungE.valueOf(it) } catch (e: Exception) { null } } try {
?.filterNotNull() ?: emptyList() BerechtigungE.valueOf(it)
} catch (e: Exception) {
null
}
} ?: emptyList()
if (permissions.contains(permission) || permissions.contains(BerechtigungE.SYSTEM_ADMIN)) { if (permissions.contains(permission) || permissions.contains(BerechtigungE.SYSTEM_ADMIN)) {
onSuccess() onSuccess()
@@ -77,7 +79,7 @@ suspend fun ApplicationCall.requirePermission(
/** /**
* Prüft, ob der aktuelle Benutzer eine der angegebenen Berechtigungen hat. * Prüft, ob der aktuelle Benutzer eine der angegebenen Berechtigungen hat.
* Muss innerhalb einer authenticate("jwt")-Block verwendet werden. * Muss innerhalb eines authenticate("jwt")-Block verwendet werden.
* *
* @param permissions Die erforderlichen Berechtigungen (eine davon ist ausreichend) * @param permissions Die erforderlichen Berechtigungen (eine davon ist ausreichend)
* @param onFailure Funktion, die bei fehlender Berechtigung aufgerufen wird * @param onFailure Funktion, die bei fehlender Berechtigung aufgerufen wird
@@ -94,9 +96,13 @@ suspend fun ApplicationCall.requireAnyPermission(
return return
} }
val userPermissions = principal.getClaim("permissions", Array<String>::class) val userPermissions = principal.getClaim("permissions", Array<String>::class)?.mapNotNull {
?.map { try { BerechtigungE.valueOf(it) } catch (e: Exception) { null } } try {
?.filterNotNull() ?: emptyList() BerechtigungE.valueOf(it)
} catch (_: Exception) {
null
}
} ?: emptyList()
if (userPermissions.contains(BerechtigungE.SYSTEM_ADMIN) || if (userPermissions.contains(BerechtigungE.SYSTEM_ADMIN) ||
permissions.any { userPermissions.contains(it) }) { permissions.any { userPermissions.contains(it) }) {
@@ -5,7 +5,6 @@ import at.mocode.members.domain.service.AuthenticationService
import at.mocode.members.domain.service.JwtService import at.mocode.members.domain.service.JwtService
import at.mocode.validation.ApiValidationUtils import at.mocode.validation.ApiValidationUtils
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.* import io.ktor.server.auth.jwt.*
import io.ktor.server.request.* import io.ktor.server.request.*
@@ -1,21 +1,21 @@
package at.mocode.events.infrastructure.api package at.mocode.events.infrastructure.api
import at.mocode.dto.base.ApiResponse import at.mocode.dto.base.ApiResponse
import at.mocode.events.application.usecase.*
import at.mocode.events.domain.repository.VeranstaltungRepository
import at.mocode.enums.SparteE import at.mocode.enums.SparteE
import at.mocode.events.application.usecase.CreateVeranstaltungUseCase
import at.mocode.events.application.usecase.DeleteVeranstaltungUseCase
import at.mocode.events.application.usecase.GetVeranstaltungUseCase
import at.mocode.events.application.usecase.UpdateVeranstaltungUseCase
import at.mocode.events.domain.repository.VeranstaltungRepository
import at.mocode.serializers.UuidSerializer import at.mocode.serializers.UuidSerializer
import at.mocode.validation.ApiValidationUtils import at.mocode.validation.ApiValidationUtils
import at.mocode.validation.ValidationError
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom import com.benasher44.uuid.uuidFrom
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.* import io.ktor.server.request.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
/** /**
@@ -100,7 +100,7 @@ class VeranstaltungController(
} else { } else {
call.respond(HttpStatusCode.NotFound, ApiResponse.error<Any>("Event not found")) call.respond(HttpStatusCode.NotFound, ApiResponse.error<Any>("Event not found"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid event ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid event ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to retrieve event: ${e.message}")) call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to retrieve event: ${e.message}"))
@@ -228,7 +228,7 @@ class VeranstaltungController(
} }
call.respond(statusCode, ApiResponse.error<Any>(response.error?.message ?: "Failed to update event")) call.respond(statusCode, ApiResponse.error<Any>(response.error?.message ?: "Failed to update event"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid event ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid event ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid request data: ${e.message}")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid request data: ${e.message}"))
@@ -249,7 +249,7 @@ class VeranstaltungController(
val forceDelete = if (forceParam != null) { val forceDelete = if (forceParam != null) {
try { try {
forceParam.toBoolean() forceParam.toBoolean()
} catch (e: Exception) { } catch (_: Exception) {
return@delete call.respond( return@delete call.respond(
HttpStatusCode.BadRequest, HttpStatusCode.BadRequest,
ApiResponse.error<Any>("Invalid force parameter. Must be true or false") ApiResponse.error<Any>("Invalid force parameter. Must be true or false")
@@ -275,7 +275,7 @@ class VeranstaltungController(
} }
call.respond(statusCode, ApiResponse.error<Any>(response.error?.message ?: "Failed to delete event")) call.respond(statusCode, ApiResponse.error<Any>(response.error?.message ?: "Failed to delete event"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid event ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid event ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to delete event: ${e.message}")) call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to delete event: ${e.message}"))
@@ -3,7 +3,6 @@ package at.mocode.events.infrastructure.repository
import at.mocode.enums.SparteE 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.events.infrastructure.repository.VeranstaltungTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
@@ -143,7 +142,7 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
val sparten = if (spartenJson.isNotBlank()) { val sparten = if (spartenJson.isNotBlank()) {
try { try {
Json.decodeFromString<List<SparteE>>(spartenJson) Json.decodeFromString<List<SparteE>>(spartenJson)
} catch (e: Exception) { } catch (_: Exception) {
emptyList() emptyList()
} }
} else { } else {
@@ -1,21 +1,21 @@
package at.mocode.horses.infrastructure.api package at.mocode.horses.infrastructure.api
import at.mocode.horses.application.usecase.*
import at.mocode.horses.domain.repository.HorseRepository
import at.mocode.dto.base.BaseDto
import at.mocode.dto.base.ApiResponse import at.mocode.dto.base.ApiResponse
import at.mocode.enums.PferdeGeschlechtE import at.mocode.enums.PferdeGeschlechtE
import at.mocode.horses.application.usecase.CreateHorseUseCase
import at.mocode.horses.application.usecase.DeleteHorseUseCase
import at.mocode.horses.application.usecase.GetHorseUseCase
import at.mocode.horses.application.usecase.UpdateHorseUseCase
import at.mocode.horses.domain.repository.HorseRepository
import at.mocode.validation.ApiValidationUtils import at.mocode.validation.ApiValidationUtils
import at.mocode.validation.ValidationError
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom import com.benasher44.uuid.uuidFrom
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.* import io.ktor.server.request.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.Contextual import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
/** /**
* REST API controller for horse registry operations. * REST API controller for horse registry operations.
@@ -66,10 +66,10 @@ class HorseController(
val geschlecht = call.request.queryParameters["geschlecht"]?.let { val geschlecht = call.request.queryParameters["geschlecht"]?.let {
try { try {
PferdeGeschlechtE.valueOf(it) PferdeGeschlechtE.valueOf(it)
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
return@get call.respond( return@get call.respond(
HttpStatusCode.BadRequest, HttpStatusCode.BadRequest,
ApiResponse.error<Any>("Invalid geschlecht value. Valid values: ${PferdeGeschlechtE.values().joinToString(", ")}") ApiResponse.error<Any>("Invalid geschlecht value. Valid values: ${PferdeGeschlechtE.entries.joinToString(", ")}")
) )
} }
} }
@@ -101,7 +101,7 @@ class HorseController(
} else { } else {
call.respond(HttpStatusCode.NotFound, ApiResponse.error<Any>("Horse not found")) call.respond(HttpStatusCode.NotFound, ApiResponse.error<Any>("Horse not found"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to retrieve horse: ${e.message}")) call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to retrieve horse: ${e.message}"))
@@ -270,7 +270,7 @@ class HorseController(
} else { } else {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Update failed: ${response.errors.joinToString(", ")}")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Update failed: ${response.errors.joinToString(", ")}"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to update horse: ${e.message}")) call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to update horse: ${e.message}"))
@@ -296,7 +296,7 @@ class HorseController(
} else { } else {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Delete failed: ${response.errors.joinToString(", ")}")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Delete failed: ${response.errors.joinToString(", ")}"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to delete horse: ${e.message}")) call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to delete horse: ${e.message}"))
@@ -319,7 +319,7 @@ class HorseController(
} else { } else {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Soft delete failed: ${response.errors.joinToString(", ")}")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Soft delete failed: ${response.errors.joinToString(", ")}"))
} }
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format")) call.respond(HttpStatusCode.BadRequest, ApiResponse.error<Any>("Invalid horse ID format"))
} catch (e: Exception) { } catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to soft delete horse: ${e.message}")) call.respond(HttpStatusCode.InternalServerError, ApiResponse.error<Any>("Failed to soft delete horse: ${e.message}"))
@@ -3,12 +3,9 @@ package at.mocode.horses.infrastructure.repository
import at.mocode.enums.PferdeGeschlechtE import at.mocode.enums.PferdeGeschlechtE
import at.mocode.horses.domain.model.DomPferd import at.mocode.horses.domain.model.DomPferd
import at.mocode.horses.domain.repository.HorseRepository import at.mocode.horses.domain.repository.HorseRepository
import at.mocode.horses.infrastructure.repository.HorseTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
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.statements.UpdateBuilder import org.jetbrains.exposed.sql.statements.UpdateBuilder
@@ -1,16 +1,12 @@
package at.mocode.masterdata.infrastructure.api package at.mocode.masterdata.infrastructure.api
import at.mocode.dto.base.BaseDto
import at.mocode.dto.base.ApiResponse import at.mocode.dto.base.ApiResponse
import at.mocode.masterdata.application.usecase.CreateCountryUseCase import at.mocode.masterdata.application.usecase.CreateCountryUseCase
import at.mocode.masterdata.application.usecase.GetCountryUseCase import at.mocode.masterdata.application.usecase.GetCountryUseCase
import at.mocode.masterdata.domain.model.LandDefinition import at.mocode.masterdata.domain.model.LandDefinition
import at.mocode.validation.ApiValidationUtils import at.mocode.validation.ApiValidationUtils
import at.mocode.validation.ValidationError
import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom import com.benasher44.uuid.uuidFrom
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.* import io.ktor.server.request.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
@@ -95,7 +91,7 @@ class CountryController(
val orderBySortierung = if (orderBySortierungParam != null) { val orderBySortierung = if (orderBySortierungParam != null) {
try { try {
orderBySortierungParam.toBoolean() orderBySortierungParam.toBoolean()
} catch (e: Exception) { } catch (_: Exception) {
return@get call.respond( return@get call.respond(
HttpStatusCode.BadRequest, HttpStatusCode.BadRequest,
ApiResponse.error<List<CountryDto>>("Invalid orderBySortierung parameter. Must be true or false") ApiResponse.error<List<CountryDto>>("Invalid orderBySortierung parameter. Must be true or false")
@@ -1,6 +1,5 @@
package at.mocode.members.domain.repository package at.mocode.members.domain.repository
import at.mocode.members.domain.model.DomBerechtigung
import at.mocode.members.domain.model.DomRolleBerechtigung import at.mocode.members.domain.model.DomRolleBerechtigung
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
@@ -8,8 +8,6 @@ import kotlinx.datetime.Clock
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
/** /**
* Service für die Erstellung und Validierung von JWT-Tokens. * Service für die Erstellung und Validierung von JWT-Tokens.
@@ -114,7 +112,7 @@ actual class JwtService(private val userAuthorizationService: UserAuthorizationS
val permissions = payload.permissions.mapNotNull { permString -> val permissions = payload.permissions.mapNotNull { permString ->
try { try {
BerechtigungE.valueOf(permString) BerechtigungE.valueOf(permString)
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
null null
} }
} }
@@ -127,7 +125,7 @@ actual class JwtService(private val userAuthorizationService: UserAuthorizationS
issuedAt = Instant.fromEpochSeconds(payload.iat), issuedAt = Instant.fromEpochSeconds(payload.iat),
expiresAt = Instant.fromEpochSeconds(payload.exp) expiresAt = Instant.fromEpochSeconds(payload.exp)
) )
} catch (e: Exception) { } catch (_: Exception) {
null null
} }
} }
@@ -162,6 +160,6 @@ actual class JwtService(private val userAuthorizationService: UserAuthorizationS
bytes[i] = hexPair.toInt(16).toByte() bytes[i] = hexPair.toInt(16).toByte()
} }
return Uuid(bytes) return uuidOf(bytes)
} }
} }
@@ -78,17 +78,17 @@ class AuthenticationService(
* @return RegisterResult mit dem Ergebnis der Registrierung * @return RegisterResult mit dem Ergebnis der Registrierung
*/ */
suspend fun registerUser(username: String, email: String, password: String, personId: Uuid): RegisterResult { suspend fun registerUser(username: String, email: String, password: String, personId: Uuid): RegisterResult {
// Prüfen, ob Benutzername bereits existiert // Prüfen, ob der Benutzername bereits existiert
if (userRepository.findByUsername(username) != null) { if (userRepository.findByUsername(username) != null) {
return RegisterResult.Failure("Benutzername wird bereits verwendet") return RegisterResult.Failure("Benutzername wird bereits verwendet")
} }
// Prüfen, ob E-Mail bereits existiert // Prüfen, ob eine E-Mail bereits existiert
if (userRepository.findByEmail(email) != null) { if (userRepository.findByEmail(email) != null) {
return RegisterResult.Failure("E-Mail-Adresse wird bereits verwendet") return RegisterResult.Failure("E-Mail-Adresse wird bereits verwendet")
} }
// Prüfen, ob Person bereits einen Benutzer hat // Prüfen, ob eine Person bereits einen Benutzer hat
if (userRepository.findByPersonId(personId) != null) { if (userRepository.findByPersonId(personId) != null) {
return RegisterResult.Failure("Diese Person hat bereits einen Benutzeraccount") return RegisterResult.Failure("Diese Person hat bereits einen Benutzeraccount")
} }
@@ -71,7 +71,7 @@ actual class JwtService(private val userAuthorizationService: UserAuthorizationS
val permissions = permissionStrings.mapNotNull { permString -> val permissions = permissionStrings.mapNotNull { permString ->
try { try {
BerechtigungE.valueOf(permString) BerechtigungE.valueOf(permString)
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
null null
} }
} }
@@ -84,7 +84,7 @@ actual class JwtService(private val userAuthorizationService: UserAuthorizationS
issuedAt = Instant.fromEpochMilliseconds(jwt.issuedAt.time), issuedAt = Instant.fromEpochMilliseconds(jwt.issuedAt.time),
expiresAt = Instant.fromEpochMilliseconds(jwt.expiresAt.time) expiresAt = Instant.fromEpochMilliseconds(jwt.expiresAt.time)
) )
} catch (e: Exception) { } catch (_: Exception) {
null null
} }
} }
@@ -7,9 +7,9 @@ import at.mocode.members.infrastructure.table.BerechtigungTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime
import kotlinx.datetime.TimeZone
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
@@ -73,34 +73,34 @@ class BerechtigungRepositoryImpl : BerechtigungRepository {
} }
override suspend fun findById(berechtigungId: Uuid): DomBerechtigung? = DatabaseFactory.dbQuery { override suspend fun findById(berechtigungId: Uuid): DomBerechtigung? = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.id eq berechtigungId } BerechtigungTable.selectAll().where { BerechtigungTable.id eq berechtigungId }
.map(::rowToDomBerechtigung) .map(::rowToDomBerechtigung)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByTyp(berechtigungTyp: BerechtigungE): DomBerechtigung? = DatabaseFactory.dbQuery { override suspend fun findByTyp(berechtigungTyp: BerechtigungE): DomBerechtigung? = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.berechtigungTyp eq berechtigungTyp } BerechtigungTable.selectAll().where { BerechtigungTable.berechtigungTyp eq berechtigungTyp }
.map(::rowToDomBerechtigung) .map(::rowToDomBerechtigung)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByName(name: String): List<DomBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findByName(name: String): List<DomBerechtigung> = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.name like "%$name%" } BerechtigungTable.selectAll().where { BerechtigungTable.name like "%$name%" }
.map(::rowToDomBerechtigung) .map(::rowToDomBerechtigung)
} }
override suspend fun findByRessource(ressource: String): List<DomBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findByRessource(ressource: String): List<DomBerechtigung> = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.ressource eq ressource } BerechtigungTable.selectAll().where { BerechtigungTable.ressource eq ressource }
.map(::rowToDomBerechtigung) .map(::rowToDomBerechtigung)
} }
override suspend fun findByAktion(aktion: String): List<DomBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findByAktion(aktion: String): List<DomBerechtigung> = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.aktion eq aktion } BerechtigungTable.selectAll().where { BerechtigungTable.aktion eq aktion }
.map(::rowToDomBerechtigung) .map(::rowToDomBerechtigung)
} }
override suspend fun findAllActive(): List<DomBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findAllActive(): List<DomBerechtigung> = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.istAktiv eq true } BerechtigungTable.selectAll().where { BerechtigungTable.istAktiv eq true }
.map(::rowToDomBerechtigung) .map(::rowToDomBerechtigung)
} }
@@ -138,7 +138,7 @@ class BerechtigungRepositoryImpl : BerechtigungRepository {
} }
override suspend fun existsByTyp(berechtigungTyp: BerechtigungE): Boolean = DatabaseFactory.dbQuery { override suspend fun existsByTyp(berechtigungTyp: BerechtigungE): Boolean = DatabaseFactory.dbQuery {
BerechtigungTable.select { BerechtigungTable.berechtigungTyp eq berechtigungTyp } BerechtigungTable.selectAll().where { BerechtigungTable.berechtigungTyp eq berechtigungTyp }
.count() > 0 .count() > 0
} }
} }
@@ -2,7 +2,6 @@ package at.mocode.members.infrastructure.repository
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 at.mocode.members.infrastructure.repository.PersonTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
@@ -21,25 +20,25 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
class PersonRepositoryImpl : PersonRepository { class PersonRepositoryImpl : PersonRepository {
override suspend fun findById(id: Uuid): DomPerson? = DatabaseFactory.dbQuery { override suspend fun findById(id: Uuid): DomPerson? = DatabaseFactory.dbQuery {
PersonTable.select { PersonTable.id eq id } PersonTable.selectAll().where { PersonTable.id eq id }
.map { rowToDomPerson(it) } .map { rowToDomPerson(it) }
.singleOrNull() .singleOrNull()
} }
override suspend fun findByOepsSatzNr(oepsSatzNr: String): DomPerson? = DatabaseFactory.dbQuery { override suspend fun findByOepsSatzNr(oepsSatzNr: String): DomPerson? = DatabaseFactory.dbQuery {
PersonTable.select { PersonTable.oepsSatzNr eq oepsSatzNr } PersonTable.selectAll().where { PersonTable.oepsSatzNr eq oepsSatzNr }
.map { rowToDomPerson(it) } .map { rowToDomPerson(it) }
.singleOrNull() .singleOrNull()
} }
override suspend fun findByStammVereinId(vereinId: Uuid): List<DomPerson> = DatabaseFactory.dbQuery { override suspend fun findByStammVereinId(vereinId: Uuid): List<DomPerson> = DatabaseFactory.dbQuery {
PersonTable.select { PersonTable.stammVereinId eq vereinId } PersonTable.selectAll().where { PersonTable.stammVereinId eq vereinId }
.map { rowToDomPerson(it) } .map { rowToDomPerson(it) }
} }
override suspend fun findByName(searchTerm: String, limit: Int): List<DomPerson> = DatabaseFactory.dbQuery { override suspend fun findByName(searchTerm: String, limit: Int): List<DomPerson> = DatabaseFactory.dbQuery {
val searchPattern = "%$searchTerm%" val searchPattern = "%$searchTerm%"
PersonTable.select { PersonTable.selectAll().where {
(PersonTable.nachname like searchPattern) or (PersonTable.nachname like searchPattern) or
(PersonTable.vorname like searchPattern) (PersonTable.vorname like searchPattern)
} }
@@ -48,7 +47,7 @@ class PersonRepositoryImpl : PersonRepository {
} }
override suspend fun findAllActive(limit: Int, offset: Int): List<DomPerson> = DatabaseFactory.dbQuery { override suspend fun findAllActive(limit: Int, offset: Int): List<DomPerson> = DatabaseFactory.dbQuery {
PersonTable.select { PersonTable.istAktiv eq true } PersonTable.selectAll().where { PersonTable.istAktiv eq true }
.limit(limit, offset.toLong()) .limit(limit, offset.toLong())
.map { rowToDomPerson(it) } .map { rowToDomPerson(it) }
} }
@@ -58,7 +57,7 @@ class PersonRepositoryImpl : PersonRepository {
val existingPerson = findById(person.personId) val existingPerson = findById(person.personId)
if (existingPerson == null) { if (existingPerson == null) {
// Insert new person // Insert a new person
PersonTable.insert { stmt -> PersonTable.insert { stmt ->
stmt[PersonTable.id] = person.personId stmt[PersonTable.id] = person.personId
stmt[PersonTable.oepsSatzNr] = person.oepsSatzNr stmt[PersonTable.oepsSatzNr] = person.oepsSatzNr
@@ -128,12 +127,12 @@ class PersonRepositoryImpl : PersonRepository {
} }
override suspend fun existsByOepsSatzNr(oepsSatzNr: String): Boolean = DatabaseFactory.dbQuery { override suspend fun existsByOepsSatzNr(oepsSatzNr: String): Boolean = DatabaseFactory.dbQuery {
PersonTable.select { PersonTable.oepsSatzNr eq oepsSatzNr } PersonTable.selectAll().where { PersonTable.oepsSatzNr eq oepsSatzNr }
.count() > 0 .count() > 0
} }
override suspend fun countActive(): Long = DatabaseFactory.dbQuery { override suspend fun countActive(): Long = DatabaseFactory.dbQuery {
PersonTable.select { PersonTable.istAktiv eq true } PersonTable.selectAll().where { PersonTable.istAktiv eq true }
.count() .count()
} }
@@ -74,65 +74,62 @@ class PersonRolleRepositoryImpl : PersonRolleRepository {
} }
override suspend fun findById(personRolleId: Uuid): DomPersonRolle? = DatabaseFactory.dbQuery { override suspend fun findById(personRolleId: Uuid): DomPersonRolle? = DatabaseFactory.dbQuery {
PersonRolleTable.select { PersonRolleTable.id eq personRolleId } PersonRolleTable.selectAll().where { PersonRolleTable.id eq personRolleId }
.map(::rowToDomPersonRolle) .map(::rowToDomPersonRolle)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByPersonId(personId: Uuid, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery { override suspend fun findByPersonId(personId: Uuid, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery {
val query = if (nurAktive) { val query = if (nurAktive) {
PersonRolleTable.select { PersonRolleTable.selectAll()
(PersonRolleTable.personId eq personId) and (PersonRolleTable.istAktiv eq true) .where { (PersonRolleTable.personId eq personId) and (PersonRolleTable.istAktiv eq true) }
}
} else { } else {
PersonRolleTable.select { PersonRolleTable.personId eq personId } PersonRolleTable.selectAll().where { PersonRolleTable.personId eq personId }
} }
query.map(::rowToDomPersonRolle) query.map(::rowToDomPersonRolle)
} }
override suspend fun findByRolleId(rolleId: Uuid, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery { override suspend fun findByRolleId(rolleId: Uuid, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery {
val query = if (nurAktive) { val query = if (nurAktive) {
PersonRolleTable.select { PersonRolleTable.selectAll()
(PersonRolleTable.rolleId eq rolleId) and (PersonRolleTable.istAktiv eq true) .where { (PersonRolleTable.rolleId eq rolleId) and (PersonRolleTable.istAktiv eq true) }
}
} else { } else {
PersonRolleTable.select { PersonRolleTable.rolleId eq rolleId } PersonRolleTable.selectAll().where { PersonRolleTable.rolleId eq rolleId }
} }
query.map(::rowToDomPersonRolle) query.map(::rowToDomPersonRolle)
} }
override suspend fun findByVereinId(vereinId: Uuid, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery { override suspend fun findByVereinId(vereinId: Uuid, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery {
val query = if (nurAktive) { val query = if (nurAktive) {
PersonRolleTable.select { PersonRolleTable.selectAll()
(PersonRolleTable.vereinId eq vereinId) and (PersonRolleTable.istAktiv eq true) .where { (PersonRolleTable.vereinId eq vereinId) and (PersonRolleTable.istAktiv eq true) }
}
} else { } else {
PersonRolleTable.select { PersonRolleTable.vereinId eq vereinId } PersonRolleTable.selectAll().where { PersonRolleTable.vereinId eq vereinId }
} }
query.map(::rowToDomPersonRolle) query.map(::rowToDomPersonRolle)
} }
override suspend fun findByPersonAndRolle(personId: Uuid, rolleId: Uuid, vereinId: Uuid?): DomPersonRolle? = DatabaseFactory.dbQuery { override suspend fun findByPersonAndRolle(personId: Uuid, rolleId: Uuid, vereinId: Uuid?): DomPersonRolle? = DatabaseFactory.dbQuery {
val query = if (vereinId != null) { val query = if (vereinId != null) {
PersonRolleTable.select { PersonRolleTable.selectAll().where {
(PersonRolleTable.personId eq personId) and (PersonRolleTable.personId eq personId) and
(PersonRolleTable.rolleId eq rolleId) and (PersonRolleTable.rolleId eq rolleId) and
(PersonRolleTable.vereinId eq vereinId) (PersonRolleTable.vereinId eq vereinId)
} }
} else { } else {
PersonRolleTable.select { PersonRolleTable.selectAll().where {
(PersonRolleTable.personId eq personId) and (PersonRolleTable.personId eq personId) and
(PersonRolleTable.rolleId eq rolleId) and (PersonRolleTable.rolleId eq rolleId) and
PersonRolleTable.vereinId.isNull() PersonRolleTable.vereinId.isNull()
} }
} }
query.map(::rowToDomPersonRolle).singleOrNull() query.map(::rowToDomPersonRolle).singleOrNull()
} }
override suspend fun findValidAt(stichtag: LocalDate, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery { override suspend fun findValidAt(stichtag: LocalDate, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery {
val baseQuery = PersonRolleTable.select { val baseQuery = PersonRolleTable.selectAll().where {
(PersonRolleTable.gueltigVon lessEq stichtag) and (PersonRolleTable.gueltigVon lessEq stichtag) and
(PersonRolleTable.gueltigBis.isNull() or (PersonRolleTable.gueltigBis greaterEq stichtag)) (PersonRolleTable.gueltigBis.isNull() or (PersonRolleTable.gueltigBis greaterEq stichtag))
} }
val query = if (nurAktive) { val query = if (nurAktive) {
@@ -145,10 +142,10 @@ class PersonRolleRepositoryImpl : PersonRolleRepository {
} }
override suspend fun findByPersonValidAt(personId: Uuid, stichtag: LocalDate, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery { override suspend fun findByPersonValidAt(personId: Uuid, stichtag: LocalDate, nurAktive: Boolean): List<DomPersonRolle> = DatabaseFactory.dbQuery {
val baseQuery = PersonRolleTable.select { val baseQuery = PersonRolleTable.selectAll().where {
(PersonRolleTable.personId eq personId) and (PersonRolleTable.personId eq personId) and
(PersonRolleTable.gueltigVon lessEq stichtag) and (PersonRolleTable.gueltigVon lessEq stichtag) and
(PersonRolleTable.gueltigBis.isNull() or (PersonRolleTable.gueltigBis greaterEq stichtag)) (PersonRolleTable.gueltigBis.isNull() or (PersonRolleTable.gueltigBis greaterEq stichtag))
} }
val query = if (nurAktive) { val query = if (nurAktive) {
@@ -177,12 +174,12 @@ class PersonRolleRepositoryImpl : PersonRolleRepository {
override suspend fun hasPersonRolle(personId: Uuid, rolleId: Uuid, vereinId: Uuid?, stichtag: LocalDate?): Boolean = DatabaseFactory.dbQuery { override suspend fun hasPersonRolle(personId: Uuid, rolleId: Uuid, vereinId: Uuid?, stichtag: LocalDate?): Boolean = DatabaseFactory.dbQuery {
val checkDate = stichtag ?: Clock.System.todayIn(TimeZone.currentSystemDefault()) val checkDate = stichtag ?: Clock.System.todayIn(TimeZone.currentSystemDefault())
val baseQuery = PersonRolleTable.select { val baseQuery = PersonRolleTable.selectAll().where {
(PersonRolleTable.personId eq personId) and (PersonRolleTable.personId eq personId) and
(PersonRolleTable.rolleId eq rolleId) and (PersonRolleTable.rolleId eq rolleId) and
(PersonRolleTable.istAktiv eq true) and (PersonRolleTable.istAktiv eq true) and
(PersonRolleTable.gueltigVon lessEq checkDate) and (PersonRolleTable.gueltigVon lessEq checkDate) and
(PersonRolleTable.gueltigBis.isNull() or (PersonRolleTable.gueltigBis greaterEq checkDate)) (PersonRolleTable.gueltigBis.isNull() or (PersonRolleTable.gueltigBis greaterEq checkDate))
} }
val query = if (vereinId != null) { val query = if (vereinId != null) {
@@ -1,6 +1,5 @@
package at.mocode.members.infrastructure.repository package at.mocode.members.infrastructure.repository
import at.mocode.enums.BerechtigungE
import at.mocode.members.domain.model.DomBerechtigung import at.mocode.members.domain.model.DomBerechtigung
import at.mocode.members.domain.model.DomRolleBerechtigung import at.mocode.members.domain.model.DomRolleBerechtigung
import at.mocode.members.domain.repository.RolleBerechtigungRepository import at.mocode.members.domain.repository.RolleBerechtigungRepository
@@ -9,9 +8,9 @@ import at.mocode.members.infrastructure.table.RolleBerechtigungTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime
import kotlinx.datetime.TimeZone
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
@@ -91,41 +90,39 @@ class RolleBerechtigungRepositoryImpl : RolleBerechtigungRepository {
} }
override suspend fun findById(rolleBerechtigungId: Uuid): DomRolleBerechtigung? = DatabaseFactory.dbQuery { override suspend fun findById(rolleBerechtigungId: Uuid): DomRolleBerechtigung? = DatabaseFactory.dbQuery {
RolleBerechtigungTable.select { RolleBerechtigungTable.id eq rolleBerechtigungId } RolleBerechtigungTable.selectAll().where { RolleBerechtigungTable.id eq rolleBerechtigungId }
.map(::rowToDomRolleBerechtigung) .map(::rowToDomRolleBerechtigung)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByRolleId(rolleId: Uuid, nurAktive: Boolean): List<DomRolleBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findByRolleId(rolleId: Uuid, nurAktive: Boolean): List<DomRolleBerechtigung> = DatabaseFactory.dbQuery {
val query = if (nurAktive) { val query = if (nurAktive) {
RolleBerechtigungTable.select { RolleBerechtigungTable.selectAll()
(RolleBerechtigungTable.rolleId eq rolleId) and (RolleBerechtigungTable.istAktiv eq true) .where { (RolleBerechtigungTable.rolleId eq rolleId) and (RolleBerechtigungTable.istAktiv eq true) }
}
} else { } else {
RolleBerechtigungTable.select { RolleBerechtigungTable.rolleId eq rolleId } RolleBerechtigungTable.selectAll().where { RolleBerechtigungTable.rolleId eq rolleId }
} }
query.map(::rowToDomRolleBerechtigung) query.map(::rowToDomRolleBerechtigung)
} }
override suspend fun findByBerechtigungId(berechtigungId: Uuid, nurAktive: Boolean): List<DomRolleBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findByBerechtigungId(berechtigungId: Uuid, nurAktive: Boolean): List<DomRolleBerechtigung> = DatabaseFactory.dbQuery {
val query = if (nurAktive) { val query = if (nurAktive) {
RolleBerechtigungTable.select { RolleBerechtigungTable.selectAll()
(RolleBerechtigungTable.berechtigungId eq berechtigungId) and (RolleBerechtigungTable.istAktiv eq true) .where { (RolleBerechtigungTable.berechtigungId eq berechtigungId) and (RolleBerechtigungTable.istAktiv eq true) }
}
} else { } else {
RolleBerechtigungTable.select { RolleBerechtigungTable.berechtigungId eq berechtigungId } RolleBerechtigungTable.selectAll().where { RolleBerechtigungTable.berechtigungId eq berechtigungId }
} }
query.map(::rowToDomRolleBerechtigung) query.map(::rowToDomRolleBerechtigung)
} }
override suspend fun findByRolleAndBerechtigung(rolleId: Uuid, berechtigungId: Uuid): DomRolleBerechtigung? = DatabaseFactory.dbQuery { override suspend fun findByRolleAndBerechtigung(rolleId: Uuid, berechtigungId: Uuid): DomRolleBerechtigung? = DatabaseFactory.dbQuery {
RolleBerechtigungTable.select { RolleBerechtigungTable.selectAll()
(RolleBerechtigungTable.rolleId eq rolleId) and (RolleBerechtigungTable.berechtigungId eq berechtigungId) .where { (RolleBerechtigungTable.rolleId eq rolleId) and (RolleBerechtigungTable.berechtigungId eq berechtigungId) }
}.map(::rowToDomRolleBerechtigung).singleOrNull() .map(::rowToDomRolleBerechtigung).singleOrNull()
} }
override suspend fun findAllActive(): List<DomRolleBerechtigung> = DatabaseFactory.dbQuery { override suspend fun findAllActive(): List<DomRolleBerechtigung> = DatabaseFactory.dbQuery {
RolleBerechtigungTable.select { RolleBerechtigungTable.istAktiv eq true } RolleBerechtigungTable.selectAll().where { RolleBerechtigungTable.istAktiv eq true }
.map(::rowToDomRolleBerechtigung) .map(::rowToDomRolleBerechtigung)
} }
@@ -148,22 +145,22 @@ class RolleBerechtigungRepositoryImpl : RolleBerechtigungRepository {
} }
override suspend fun hasRolleBerechtigung(rolleId: Uuid, berechtigungId: Uuid): Boolean = DatabaseFactory.dbQuery { override suspend fun hasRolleBerechtigung(rolleId: Uuid, berechtigungId: Uuid): Boolean = DatabaseFactory.dbQuery {
RolleBerechtigungTable.select { RolleBerechtigungTable.selectAll().where {
(RolleBerechtigungTable.rolleId eq rolleId) and (RolleBerechtigungTable.rolleId eq rolleId) and
(RolleBerechtigungTable.berechtigungId eq berechtigungId) and (RolleBerechtigungTable.berechtigungId eq berechtigungId) and
(RolleBerechtigungTable.istAktiv eq true) (RolleBerechtigungTable.istAktiv eq true)
}.count() > 0 }.count() > 0
} }
override suspend fun assignBerechtigungToRolle(rolleId: Uuid, berechtigungId: Uuid, zugewiesenVon: Uuid?): DomRolleBerechtigung = DatabaseFactory.dbQuery { override suspend fun assignBerechtigungToRolle(rolleId: Uuid, berechtigungId: Uuid, zugewiesenVon: Uuid?): DomRolleBerechtigung = DatabaseFactory.dbQuery {
// Check if assignment already exists // Check if the assignment already exists
val existing = findByRolleAndBerechtigung(rolleId, berechtigungId) val existing = findByRolleAndBerechtigung(rolleId, berechtigungId)
if (existing != null) { if (existing != null) {
// Relationship already exists, return it // Relationship already exists, return it
return@dbQuery existing return@dbQuery existing
} }
// Create new assignment // Create a new assignment
val newAssignment = DomRolleBerechtigung( val newAssignment = DomRolleBerechtigung(
rolleId = rolleId, rolleId = rolleId,
berechtigungId = berechtigungId, berechtigungId = berechtigungId,
@@ -7,9 +7,9 @@ import at.mocode.members.infrastructure.table.RolleTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime
import kotlinx.datetime.TimeZone
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
@@ -67,24 +67,24 @@ class RolleRepositoryImpl : RolleRepository {
} }
override suspend fun findById(rolleId: Uuid): DomRolle? = DatabaseFactory.dbQuery { override suspend fun findById(rolleId: Uuid): DomRolle? = DatabaseFactory.dbQuery {
RolleTable.select { RolleTable.id eq rolleId } RolleTable.selectAll().where { RolleTable.id eq rolleId }
.map(::rowToDomRolle) .map(::rowToDomRolle)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByTyp(rolleTyp: RolleE): DomRolle? = DatabaseFactory.dbQuery { override suspend fun findByTyp(rolleTyp: RolleE): DomRolle? = DatabaseFactory.dbQuery {
RolleTable.select { RolleTable.rolleTyp eq rolleTyp } RolleTable.selectAll().where { RolleTable.rolleTyp eq rolleTyp }
.map(::rowToDomRolle) .map(::rowToDomRolle)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByName(name: String): List<DomRolle> = DatabaseFactory.dbQuery { override suspend fun findByName(name: String): List<DomRolle> = DatabaseFactory.dbQuery {
RolleTable.select { RolleTable.name like "%$name%" } RolleTable.selectAll().where { RolleTable.name like "%$name%" }
.map(::rowToDomRolle) .map(::rowToDomRolle)
} }
override suspend fun findAllActive(): List<DomRolle> = DatabaseFactory.dbQuery { override suspend fun findAllActive(): List<DomRolle> = DatabaseFactory.dbQuery {
RolleTable.select { RolleTable.istAktiv eq true } RolleTable.selectAll().where { RolleTable.istAktiv eq true }
.map(::rowToDomRolle) .map(::rowToDomRolle)
} }
@@ -122,7 +122,7 @@ class RolleRepositoryImpl : RolleRepository {
} }
override suspend fun existsByTyp(rolleTyp: RolleE): Boolean = DatabaseFactory.dbQuery { override suspend fun existsByTyp(rolleTyp: RolleE): Boolean = DatabaseFactory.dbQuery {
RolleTable.select { RolleTable.rolleTyp eq rolleTyp } RolleTable.selectAll().where { RolleTable.rolleTyp eq rolleTyp }
.count() > 0 .count() > 0
} }
} }
@@ -67,25 +67,25 @@ class UserRepositoryImpl : UserRepository {
} }
override suspend fun findById(userId: Uuid): DomUser? = DatabaseFactory.dbQuery { override suspend fun findById(userId: Uuid): DomUser? = DatabaseFactory.dbQuery {
UserTable.select { UserTable.id eq userId } UserTable.selectAll().where { UserTable.id eq userId }
.map(::rowToDomUser) .map(::rowToDomUser)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByUsername(username: String): DomUser? = DatabaseFactory.dbQuery { override suspend fun findByUsername(username: String): DomUser? = DatabaseFactory.dbQuery {
UserTable.select { UserTable.username eq username } UserTable.selectAll().where { UserTable.username eq username }
.map(::rowToDomUser) .map(::rowToDomUser)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByEmail(email: String): DomUser? = DatabaseFactory.dbQuery { override suspend fun findByEmail(email: String): DomUser? = DatabaseFactory.dbQuery {
UserTable.select { UserTable.email eq email } UserTable.selectAll().where { UserTable.email eq email }
.map(::rowToDomUser) .map(::rowToDomUser)
.singleOrNull() .singleOrNull()
} }
override suspend fun findByPersonId(personId: Uuid): DomUser? = DatabaseFactory.dbQuery { override suspend fun findByPersonId(personId: Uuid): DomUser? = DatabaseFactory.dbQuery {
UserTable.select { UserTable.personId eq personId } UserTable.selectAll().where { UserTable.personId eq personId }
.map(::rowToDomUser) .map(::rowToDomUser)
.singleOrNull() .singleOrNull()
} }
@@ -201,7 +201,7 @@ class UserRepositoryImpl : UserRepository {
} }
override suspend fun getActiveUsers(): List<DomUser> = DatabaseFactory.dbQuery { override suspend fun getActiveUsers(): List<DomUser> = DatabaseFactory.dbQuery {
UserTable.select { UserTable.isActive eq true } UserTable.selectAll().where { UserTable.isActive eq true }
.map(::rowToDomUser) .map(::rowToDomUser)
} }
} }
@@ -2,7 +2,6 @@ package at.mocode.members.infrastructure.repository
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 at.mocode.members.infrastructure.repository.VereinTable
import at.mocode.shared.database.DatabaseFactory import at.mocode.shared.database.DatabaseFactory
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
@@ -21,20 +20,20 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
class VereinRepositoryImpl : VereinRepository { class VereinRepositoryImpl : VereinRepository {
override suspend fun findById(id: Uuid): DomVerein? = DatabaseFactory.dbQuery { override suspend fun findById(id: Uuid): DomVerein? = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.id eq id } VereinTable.selectAll().where { VereinTable.id eq id }
.map { rowToDomVerein(it) } .map { rowToDomVerein(it) }
.singleOrNull() .singleOrNull()
} }
override suspend fun findByOepsVereinsNr(oepsVereinsNr: String): DomVerein? = DatabaseFactory.dbQuery { override suspend fun findByOepsVereinsNr(oepsVereinsNr: String): DomVerein? = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.oepsVereinsNr eq oepsVereinsNr } 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> = DatabaseFactory.dbQuery { override suspend fun findByName(searchTerm: String, limit: Int): List<DomVerein> = DatabaseFactory.dbQuery {
val searchPattern = "%$searchTerm%" val searchPattern = "%$searchTerm%"
VereinTable.select { VereinTable.selectAll().where {
(VereinTable.name like searchPattern) or (VereinTable.name like searchPattern) or
(VereinTable.kuerzel like searchPattern) (VereinTable.kuerzel like searchPattern)
} }
@@ -43,24 +42,24 @@ class VereinRepositoryImpl : VereinRepository {
} }
override suspend fun findByBundeslandId(bundeslandId: Uuid): List<DomVerein> = DatabaseFactory.dbQuery { override suspend fun findByBundeslandId(bundeslandId: Uuid): List<DomVerein> = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.bundeslandId eq bundeslandId } VereinTable.selectAll().where { VereinTable.bundeslandId eq bundeslandId }
.map { rowToDomVerein(it) } .map { rowToDomVerein(it) }
} }
override suspend fun findByLandId(landId: Uuid): List<DomVerein> = DatabaseFactory.dbQuery { override suspend fun findByLandId(landId: Uuid): List<DomVerein> = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.landId eq landId } VereinTable.selectAll().where { VereinTable.landId eq landId }
.map { rowToDomVerein(it) } .map { rowToDomVerein(it) }
} }
override suspend fun findAllActive(limit: Int, offset: Int): List<DomVerein> = DatabaseFactory.dbQuery { override suspend fun findAllActive(limit: Int, offset: Int): List<DomVerein> = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.istAktiv eq true } 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> = DatabaseFactory.dbQuery { override suspend fun findByLocation(searchTerm: String, limit: Int): List<DomVerein> = DatabaseFactory.dbQuery {
val searchPattern = "%$searchTerm%" val searchPattern = "%$searchTerm%"
VereinTable.select { VereinTable.selectAll().where {
(VereinTable.ort like searchPattern) or (VereinTable.ort like searchPattern) or
(VereinTable.plz like searchPattern) (VereinTable.plz like searchPattern)
} }
@@ -123,19 +122,17 @@ class VereinRepositoryImpl : VereinRepository {
} }
override suspend fun existsByOepsVereinsNr(oepsVereinsNr: String): Boolean = DatabaseFactory.dbQuery { override suspend fun existsByOepsVereinsNr(oepsVereinsNr: String): Boolean = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.oepsVereinsNr eq oepsVereinsNr } VereinTable.selectAll().where { VereinTable.oepsVereinsNr eq oepsVereinsNr }
.count() > 0 .count() > 0
} }
override suspend fun countActive(): Long = DatabaseFactory.dbQuery { override suspend fun countActive(): Long = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.istAktiv eq true } VereinTable.selectAll().where { VereinTable.istAktiv eq true }
.count() .count()
} }
override suspend fun countActiveByBundeslandId(bundeslandId: Uuid): Long = DatabaseFactory.dbQuery { override suspend fun countActiveByBundeslandId(bundeslandId: Uuid): Long = DatabaseFactory.dbQuery {
VereinTable.select { VereinTable.selectAll().where { (VereinTable.istAktiv eq true) and (VereinTable.bundeslandId eq bundeslandId) }.count()
(VereinTable.istAktiv eq true) and (VereinTable.bundeslandId eq bundeslandId)
}.count()
} }
/** /**
@@ -1,6 +1,5 @@
package at.mocode.members.infrastructure.table package at.mocode.members.infrastructure.table
import at.mocode.members.infrastructure.table.RolleTable
import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.kotlin.datetime.date import org.jetbrains.exposed.sql.kotlin.datetime.date
import org.jetbrains.exposed.sql.kotlin.datetime.timestamp import org.jetbrains.exposed.sql.kotlin.datetime.timestamp
@@ -1,6 +1,5 @@
package at.mocode.validation package at.mocode.validation
import at.mocode.dto.base.ApiResponse
import com.benasher44.uuid.Uuid import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom import com.benasher44.uuid.uuidFrom
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
@@ -19,7 +18,7 @@ object ApiValidationUtils {
return try { return try {
uuidFrom(uuidString) uuidFrom(uuidString)
} catch (e: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
null null
} }
} }
@@ -44,7 +43,7 @@ object ApiValidationUtils {
if (limitValue < 1 || limitValue > 1000) { if (limitValue < 1 || limitValue > 1000) {
errors.add(ValidationError("limit", "Limit must be between 1 and 1000", "INVALID_RANGE")) errors.add(ValidationError("limit", "Limit must be between 1 and 1000", "INVALID_RANGE"))
} }
} catch (e: NumberFormatException) { } catch (_: NumberFormatException) {
errors.add(ValidationError("limit", "Limit must be a valid integer", "INVALID_FORMAT")) errors.add(ValidationError("limit", "Limit must be a valid integer", "INVALID_FORMAT"))
} }
} }
@@ -56,7 +55,7 @@ object ApiValidationUtils {
if (offsetValue < 0) { if (offsetValue < 0) {
errors.add(ValidationError("offset", "Offset must be non-negative", "INVALID_RANGE")) errors.add(ValidationError("offset", "Offset must be non-negative", "INVALID_RANGE"))
} }
} catch (e: NumberFormatException) { } catch (_: NumberFormatException) {
errors.add(ValidationError("offset", "Offset must be a valid integer", "INVALID_FORMAT")) errors.add(ValidationError("offset", "Offset must be a valid integer", "INVALID_FORMAT"))
} }
} }
@@ -65,7 +64,7 @@ object ApiValidationUtils {
startDate?.let { dateStr -> startDate?.let { dateStr ->
try { try {
LocalDate.parse(dateStr) LocalDate.parse(dateStr)
} catch (e: Exception) { } catch (_: Exception) {
errors.add(ValidationError("startDate", "Invalid date format. Use YYYY-MM-DD", "INVALID_FORMAT")) errors.add(ValidationError("startDate", "Invalid date format. Use YYYY-MM-DD", "INVALID_FORMAT"))
} }
} }
@@ -73,7 +72,7 @@ object ApiValidationUtils {
endDate?.let { dateStr -> endDate?.let { dateStr ->
try { try {
LocalDate.parse(dateStr) LocalDate.parse(dateStr)
} catch (e: Exception) { } catch (_: Exception) {
errors.add(ValidationError("endDate", "Invalid date format. Use YYYY-MM-DD", "INVALID_FORMAT")) errors.add(ValidationError("endDate", "Invalid date format. Use YYYY-MM-DD", "INVALID_FORMAT"))
} }
} }