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
@@ -0,0 +1,41 @@
package at.mocode.series.service
import at.mocode.series.service.application.SeriesService
import at.mocode.series.service.domain.Serie
import at.mocode.series.service.domain.SeriePunkt
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.web.bind.annotation.*
@SpringBootApplication
class SeriesServiceApplication
fun main(args: Array<String>) {
runApplication<SeriesServiceApplication>(*args)
}
@RestController
@RequestMapping("/api/v1/series")
class SeriesController(
private val service: SeriesService
) {
@GetMapping("/")
fun health(): String = "Series Service is running"
@GetMapping
fun getAll(): List<Serie> = service.getAllSeries()
@GetMapping("/{id}")
fun getById(@PathVariable id: String): Serie? = service.getSeriesById(id)
@PostMapping
fun save(@RequestBody serie: Serie): Serie = service.saveSerie(serie)
@GetMapping("/{id}/stand")
fun getStand(@PathVariable id: String) = service.getStand(id)
@PostMapping("/{id}/punkte")
fun addPunkt(@PathVariable id: String, @RequestBody punkt: SeriePunkt): SeriePunkt {
return service.addPunkt(punkt.copy(serieId = id))
}
}
@@ -0,0 +1,36 @@
package at.mocode.series.service.application
import at.mocode.series.service.domain.Serie
import at.mocode.series.service.domain.SeriePunkt
import at.mocode.series.service.persistence.JpaSeriePunktRepository
import at.mocode.series.service.persistence.JpaSerieRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class SeriesService(
private val serieRepository: JpaSerieRepository,
private val punkteRepository: JpaSeriePunktRepository
) {
fun getAllSeries(): List<Serie> = serieRepository.findAll()
fun getSeriesById(id: String): Serie? = serieRepository.findById(id).orElse(null)
@Transactional
fun saveSerie(serie: Serie): Serie = serieRepository.save(serie)
fun getStand(serieId: String): Map<Pair<String, String>, Double> {
val punkte = punkteRepository.findBySerieId(serieId)
// Aggregation pro Paar (Reiter, Pferd)
return punkte.groupBy { it.reiterId to it.pferdId }
.mapValues { (_, v) -> v.sumOf { it.punkte } }
.toList()
.sortedByDescending { it.second }
.toMap()
}
@Transactional
fun addPunkt(punkt: SeriePunkt): SeriePunkt = punkteRepository.save(punkt)
}
@@ -0,0 +1,57 @@
package at.mocode.series.service.domain
import jakarta.persistence.*
import java.util.*
@Entity
@Table(name = "serien")
class Serie(
@Id
val id: String = UUID.randomUUID().toString(),
@Column(nullable = false)
val name: String,
@Column
val beschreibung: String? = null,
@Enumerated(EnumType.STRING)
@Column(nullable = false)
val reglementTyp: ReglementTyp = ReglementTyp.STREICHER_NORMAL,
@ElementCollection
@CollectionTable(name = "serie_bewerbe", joinColumns = [JoinColumn(name = "serie_id")])
@Column(name = "bewerb_id")
val bewerbIds: Set<String> = mutableSetOf()
)
enum class ReglementTyp {
STREICHER_NORMAL, // z.B. 4 von 6 Wertungen zählen
ALLES_ZAEHLT, // Alle Bewerbe zählen
MEISTERSCHAFT // Spezielle Gewichtung (z.B. Finale doppelt)
}
@Entity
@Table(name = "serie_punkte")
class SeriePunkt(
@Id
val id: String = UUID.randomUUID().toString(),
@Column(nullable = false)
val serieId: String,
@Column(nullable = false)
val reiterId: String,
@Column(nullable = false)
val pferdId: String,
@Column(nullable = false)
val bewerbId: String,
@Column(nullable = false)
val punkte: Double,
@Column(nullable = false)
val platzierung: Int
)
@@ -0,0 +1,14 @@
package at.mocode.series.service.persistence
import at.mocode.series.service.domain.Serie
import at.mocode.series.service.domain.SeriePunkt
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface JpaSerieRepository : JpaRepository<Serie, String>
@Repository
interface JpaSeriePunktRepository : JpaRepository<SeriePunkt, String> {
fun findBySerieId(serieId: String): List<SeriePunkt>
}