### feat: erweitere ZNS und SQLDelight-Integration
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled

- **SQLDelight:** Füge neue Queries (`countVereine`, `maxUpdated...`) zur SQLite-Datenbank hinzu und aktualisiere `DesktopMasterdataRepository`.
- **ZNS-Sync:** Passe `ZnsImportState` an, um Pferde- und Funktionärsdaten zu unterstützen.
- **Cloud-Sync:** Entferne redundante Auth-Header und setze Limits für Massensynchronisation auf 50.000 Datensätze.
- **Masterdata-Service:** Stabilisiere Consul Health-Checks und implementiere Limit-Beschränkungen auf Controller-Ebene.
This commit is contained in:
2026-04-22 14:14:33 +02:00
parent 98c241fc64
commit beb20e0cf7
16 changed files with 287 additions and 99 deletions
@@ -62,7 +62,7 @@ class FunktionaerController(private val funktionaerRepository: FunktionaerReposi
* GET /funktionaer — Alle Funktionäre (paginiert).
*/
get {
val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 100
val limit = (call.request.queryParameters["limit"]?.toIntOrNull() ?: 100).coerceAtMost(5000)
val offset = call.request.queryParameters["offset"]?.toIntOrNull() ?: 0
val results = funktionaerRepository.findAll(limit, offset)
@@ -62,11 +62,11 @@ class HorseController(private val horseRepository: HorseRepository) {
route("/horse") {
/**
* GET /horse — Alle Pferde (paginiert), optional gefiltert nach jahrgang.
* GET /horse — alle Pferde (paginiert), optional gefiltert nach Jahrgang.
*/
get {
val jahrgang = call.request.queryParameters["jahrgang"]?.toIntOrNull()
val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 100
val limit = (call.request.queryParameters["limit"]?.toIntOrNull() ?: 100).coerceAtMost(50000)
val offset = call.request.queryParameters["offset"]?.toIntOrNull() ?: 0
val results = when {
@@ -77,7 +77,7 @@ class HorseController(private val horseRepository: HorseRepository) {
}
/**
* GET /horse/search?q=... — Sucht Pferde nach Lebensnummer.
* GET /horse/search?q= … — Sucht Pferde nach Lebensnummer.
*/
get("/search") {
val query = call.request.queryParameters["q"] ?: ""
@@ -86,7 +86,7 @@ class HorseController(private val horseRepository: HorseRepository) {
}
/**
* GET /horse/{id} — Ruft ein spezifisches Pferd ab.
* GET /horse/{id} — ruft ein spezifisches Pferd ab.
*/
get("/{id}") {
val id = parseUuid(call.parameters["id"]) ?: return@get call.respond(HttpStatusCode.BadRequest)
@@ -104,7 +104,7 @@ class HorseController(private val horseRepository: HorseRepository) {
}
/**
* POST /horse — Erstellt ein neues Pferd.
* POST /horse — erstellt ein neues Pferd.
*/
post {
val req = call.receive<HorseCreateRequest>()
@@ -93,7 +93,7 @@ class ReiterController(private val reiterRepository: ReiterRepository) {
* GET /reiter — Alle Reiter (paginiert).
*/
get {
val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 100
val limit = (call.request.queryParameters["limit"]?.toIntOrNull() ?: 100).coerceAtMost(50000)
val offset = call.request.queryParameters["offset"]?.toIntOrNull() ?: 0
val results = reiterRepository.findAll(limit, offset)
@@ -76,11 +76,11 @@ class VereinController(private val vereinRepository: VereinRepository) {
route("/verein") {
/**
* GET /verein — Alle Vereine (paginiert), optional gefiltert nach verband/bundesland.
* GET /verein — alle Vereine (paginiert), optional gefiltert nach Verband/Bundesland.
*/
get {
val verband = call.request.queryParameters["verband"]
val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 100
val limit = (call.request.queryParameters["limit"]?.toIntOrNull() ?: 100).coerceAtMost(5000)
val offset = call.request.queryParameters["offset"]?.toIntOrNull() ?: 0
val results = if (verband != null) {
@@ -92,7 +92,7 @@ class VereinController(private val vereinRepository: VereinRepository) {
}
/**
* GET /verein/search?q=... — Sucht Vereine nach Name.
* GET /verein/search?q= … — Sucht Vereine nach Namen.
*/
get("/search") {
val query = call.request.queryParameters["q"] ?: ""
@@ -101,7 +101,7 @@ class VereinController(private val vereinRepository: VereinRepository) {
}
/**
* GET /verein/{id} — Ruft einen spezifischen Verein ab.
* GET /verein/{id} — ruft einen spezifischen Verein ab.
*/
get("/{id}") {
val id = parseUuid(call.parameters["id"]) ?: return@get call.respond(HttpStatusCode.BadRequest)
@@ -119,7 +119,7 @@ class VereinController(private val vereinRepository: VereinRepository) {
}
/**
* POST /verein — Erstellt einen neuen Verein.
* POST /verein — erstellt einen neuen Verein.
*/
post {
val req = call.receive<VereinCreateRequest>()
@@ -28,12 +28,15 @@ spring:
enabled: true
register: true
prefer-ip-address: true
health-check-path: /actuator/health
health-check-interval: 20s
health-check-port: ${MASTERDATA_SERVER_PORT:8086}
instance-id: ${spring.application.name}:${server.port}:${random.uuid}
health-check-path: /actuator/health/readiness
health-check-interval: 10s
health-check-timeout: 5s
health-check-port: 8086
health-check-critical-timeout: 2m
deregister-critical-service-after: 5m
instance-id: ${spring.application.name}:${random.uuid}
service-name: ${spring.application.name}
port: ${MASTERDATA_KTOR_PORT:8091}
port: 8091
#server:
# port: 8086 # Spring Boot Management Port (Actuator & Tomcat)