Integrate series-service microservice with API gateway routing, implement Series domain and point aggregation logic, and update frontend with SeriesViewModel, SeriesScreen, and dynamic state handling.

This commit is contained in:
2026-04-12 16:58:22 +02:00
parent 4ad9b274e8
commit 6e99bc97fd
20 changed files with 711 additions and 25 deletions
@@ -1,9 +1,10 @@
package at.mocode.results.service
import at.mocode.results.service.application.ResultsService
import at.mocode.results.service.domain.Ergebnis
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.*
@SpringBootApplication
class ResultsServiceApplication
@@ -13,7 +14,27 @@ fun main(args: Array<String>) {
}
@RestController
class ResultsController {
@RequestMapping("/api/v1/results")
class ResultsController(
private val service: ResultsService
) {
@GetMapping("/")
fun health(): String = "Results Service is running"
@GetMapping("/bewerb/{bewerbId}")
fun getForBewerb(@PathVariable bewerbId: String): List<Ergebnis> = service.getByBewerbId(bewerbId)
@PostMapping
fun save(@RequestBody ergebnis: Ergebnis): Ergebnis = service.saveErgebnis(ergebnis)
@PutMapping("/{id}")
fun update(@PathVariable id: String, @RequestBody ergebnis: Ergebnis): Ergebnis {
return service.saveErgebnis(ergebnis.copy(id = id))
}
@PostMapping("/bewerb/{bewerbId}/calculate")
fun calculate(@PathVariable bewerbId: String): List<Ergebnis> = service.calculatePlatzierung(bewerbId)
@GetMapping("/bewerb/{bewerbId}/pdf")
fun exportPdf(@PathVariable bewerbId: String): ByteArray = service.generatePdf(bewerbId)
}
@@ -0,0 +1,43 @@
package at.mocode.results.service.application
import at.mocode.results.service.domain.Ergebnis
import at.mocode.results.service.domain.ErgebnisStatus
import at.mocode.results.service.persistence.JpaErgebnisRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class ResultsService(
private val repository: JpaErgebnisRepository
) {
fun getByBewerbId(bewerbId: String): List<Ergebnis> = repository.findByBewerbId(bewerbId)
@Transactional
fun saveErgebnis(ergebnis: Ergebnis): Ergebnis = repository.save(ergebnis)
@Transactional
fun calculatePlatzierung(bewerbId: String): List<Ergebnis> {
val results = repository.findByBewerbId(bewerbId)
.filter { it.status == ErgebnisStatus.OK }
// Einfache Platzierungs-Logik: Höchste Wertnote zuerst (Standard Dressur/Stil)
// Bei gleicher Wertnote: Zeit als Tie-Breaker (Placeholder)
val sortedResults = results.sortedWith(
compareByDescending<Ergebnis> { it.wertnote ?: 0.0 }
.thenBy { it.zeit ?: 0.0 }
.thenByDescending { it.fehler ?: 0.0 }
)
val updatedResults = sortedResults.mapIndexed { index, ergebnis ->
ergebnis.copy(platzierung = index + 1)
}
return repository.saveAll(updatedResults)
}
fun generatePdf(bewerbId: String): ByteArray {
// Placeholder für PDF-Generierung
return "PDF Content for Bewerb $bewerbId".toByteArray()
}
}
@@ -0,0 +1,37 @@
package at.mocode.results.service.domain
import jakarta.persistence.*
import java.util.*
@Entity
@Table(name = "ergebnisse")
data class Ergebnis(
@Id
val id: String = UUID.randomUUID().toString(),
@Column(nullable = false)
val nennungId: String,
@Column(nullable = false)
val bewerbId: String,
@Column
val wertnote: Double? = null,
@Column
val zeit: Double? = null,
@Column
val fehler: Double? = null,
@Enumerated(EnumType.STRING)
@Column(nullable = false)
val status: ErgebnisStatus = ErgebnisStatus.OK,
@Column
val platzierung: Int? = null
)
enum class ErgebnisStatus {
OK, AUSGESCHIEDEN, VERZICHTET, DISQUALIFIZIERT, NICHT_GESTARTET
}
@@ -0,0 +1,10 @@
package at.mocode.results.service.persistence
import at.mocode.results.service.domain.Ergebnis
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface JpaErgebnisRepository : JpaRepository<Ergebnis, String> {
fun findByBewerbId(bewerbId: String): List<Ergebnis>
}