Extend Bewerb DTOs and APIs: add comprehensive properties, mapping functions, and RichterEinsatz support, and align backend and frontend implementations.
This commit is contained in:
+139
-5
@@ -2,20 +2,149 @@
|
|||||||
|
|
||||||
package at.mocode.entries.service.bewerbe
|
package at.mocode.entries.service.bewerbe
|
||||||
|
|
||||||
|
import at.mocode.core.domain.model.AbteilungsTeilungsTypE
|
||||||
|
import at.mocode.core.domain.model.BeginnZeitTypE
|
||||||
|
import at.mocode.entries.domain.model.RichterEinsatz
|
||||||
|
import kotlinx.datetime.LocalDate
|
||||||
|
import kotlinx.datetime.LocalTime
|
||||||
import org.springframework.http.HttpStatus
|
import org.springframework.http.HttpStatus
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import kotlin.uuid.Uuid
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
|
// --- DTOs ---
|
||||||
|
data class RichterEinsatzDto(
|
||||||
|
val funktionaerId: String,
|
||||||
|
val position: String,
|
||||||
|
)
|
||||||
|
|
||||||
data class CreateBewerbRequest(
|
data class CreateBewerbRequest(
|
||||||
|
// Basis
|
||||||
val klasse: String,
|
val klasse: String,
|
||||||
val hoeheCm: Int? = null,
|
val hoeheCm: Int? = null,
|
||||||
val bezeichnung: String,
|
val bezeichnung: String,
|
||||||
|
|
||||||
|
// Abteilungs-Konfiguration
|
||||||
|
val teilungsTyp: AbteilungsTeilungsTypE? = null,
|
||||||
|
|
||||||
|
// Text & Details
|
||||||
|
val beschreibung: String? = null,
|
||||||
|
val aufgabe: String? = null,
|
||||||
|
val aufgabenNummer: String? = null,
|
||||||
|
val paraGrade: String? = null,
|
||||||
|
|
||||||
|
// Ort & Funktionäre
|
||||||
|
val austragungsplatzId: String? = null,
|
||||||
|
val richterEinsaetze: List<RichterEinsatzDto> = emptyList(),
|
||||||
|
|
||||||
|
// Zeitplan
|
||||||
|
val geplantesDatum: LocalDate? = null,
|
||||||
|
val beginnZeitTyp: BeginnZeitTypE? = null,
|
||||||
|
val beginnZeit: LocalTime? = null,
|
||||||
|
val reitdauerMinuten: Int? = null,
|
||||||
|
val umbauMinuten: Int? = null,
|
||||||
|
val besichtigungMinuten: Int? = null,
|
||||||
|
val stechenGeplant: Boolean = false,
|
||||||
|
|
||||||
|
// Finanzen
|
||||||
|
val startgeldCent: Long? = null,
|
||||||
|
val geldpreisAusbezahlt: Boolean = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class UpdateBewerbRequest(
|
data class UpdateBewerbRequest(
|
||||||
|
// Basis
|
||||||
val klasse: String,
|
val klasse: String,
|
||||||
val hoeheCm: Int? = null,
|
val hoeheCm: Int? = null,
|
||||||
val bezeichnung: String,
|
val bezeichnung: String,
|
||||||
|
|
||||||
|
// Abteilungs-Konfiguration
|
||||||
|
val teilungsTyp: AbteilungsTeilungsTypE? = null,
|
||||||
|
|
||||||
|
// Text & Details
|
||||||
|
val beschreibung: String? = null,
|
||||||
|
val aufgabe: String? = null,
|
||||||
|
val aufgabenNummer: String? = null,
|
||||||
|
val paraGrade: String? = null,
|
||||||
|
|
||||||
|
// Ort & Funktionäre
|
||||||
|
val austragungsplatzId: String? = null,
|
||||||
|
val richterEinsaetze: List<RichterEinsatzDto> = emptyList(),
|
||||||
|
|
||||||
|
// Zeitplan
|
||||||
|
val geplantesDatum: LocalDate? = null,
|
||||||
|
val beginnZeitTyp: BeginnZeitTypE? = null,
|
||||||
|
val beginnZeit: LocalTime? = null,
|
||||||
|
val reitdauerMinuten: Int? = null,
|
||||||
|
val umbauMinuten: Int? = null,
|
||||||
|
val besichtigungMinuten: Int? = null,
|
||||||
|
val stechenGeplant: Boolean = false,
|
||||||
|
|
||||||
|
// Finanzen
|
||||||
|
val startgeldCent: Long? = null,
|
||||||
|
val geldpreisAusbezahlt: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class BewerbResponse(
|
||||||
|
val id: String,
|
||||||
|
val turnierId: String,
|
||||||
|
val klasse: String,
|
||||||
|
val hoeheCm: Int?,
|
||||||
|
val bezeichnung: String,
|
||||||
|
|
||||||
|
// Abteilungs-Konfiguration
|
||||||
|
val teilungsTyp: AbteilungsTeilungsTypE?,
|
||||||
|
|
||||||
|
// Text & Details
|
||||||
|
val beschreibung: String?,
|
||||||
|
val aufgabe: String?,
|
||||||
|
val aufgabenNummer: String?,
|
||||||
|
val paraGrade: String?,
|
||||||
|
|
||||||
|
// Ort & Funktionäre
|
||||||
|
val austragungsplatzId: String?,
|
||||||
|
val richterEinsaetze: List<RichterEinsatzDto>,
|
||||||
|
|
||||||
|
// Zeitplan
|
||||||
|
val geplantesDatum: LocalDate?,
|
||||||
|
val beginnZeitTyp: BeginnZeitTypE?,
|
||||||
|
val beginnZeit: LocalTime?,
|
||||||
|
val reitdauerMinuten: Int?,
|
||||||
|
val umbauMinuten: Int?,
|
||||||
|
val besichtigungMinuten: Int?,
|
||||||
|
val stechenGeplant: Boolean,
|
||||||
|
|
||||||
|
// Finanzen
|
||||||
|
val startgeldCent: Long?,
|
||||||
|
val geldpreisAusbezahlt: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun RichterEinsatzDto.toDomain(): RichterEinsatz =
|
||||||
|
RichterEinsatz(
|
||||||
|
funktionaerId = Uuid.parse(this.funktionaerId),
|
||||||
|
position = this.position
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun domainToDto(b: Bewerb): BewerbResponse = BewerbResponse(
|
||||||
|
id = b.id.toString(),
|
||||||
|
turnierId = b.turnierId.toString(),
|
||||||
|
klasse = b.klasse,
|
||||||
|
hoeheCm = b.hoeheCm,
|
||||||
|
bezeichnung = b.bezeichnung,
|
||||||
|
teilungsTyp = b.teilungsTyp,
|
||||||
|
beschreibung = b.beschreibung,
|
||||||
|
aufgabe = b.aufgabe,
|
||||||
|
aufgabenNummer = b.aufgabenNummer,
|
||||||
|
paraGrade = b.paraGrade,
|
||||||
|
austragungsplatzId = b.austragungsplatzId?.toString(),
|
||||||
|
richterEinsaetze = b.richterEinsaetze.map { RichterEinsatzDto(it.funktionaerId.toString(), it.position) },
|
||||||
|
geplantesDatum = b.geplantesDatum,
|
||||||
|
beginnZeitTyp = b.beginnZeitTyp,
|
||||||
|
beginnZeit = b.beginnZeit,
|
||||||
|
reitdauerMinuten = b.reitdauerMinuten,
|
||||||
|
umbauMinuten = b.umbauMinuten,
|
||||||
|
besichtigungMinuten = b.besichtigungMinuten,
|
||||||
|
stechenGeplant = b.stechenGeplant,
|
||||||
|
startgeldCent = b.startgeldCent,
|
||||||
|
geldpreisAusbezahlt = b.geldpreisAusbezahlt,
|
||||||
)
|
)
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -28,21 +157,26 @@ class BewerbeController(
|
|||||||
suspend fun create(
|
suspend fun create(
|
||||||
@PathVariable turnierId: String,
|
@PathVariable turnierId: String,
|
||||||
@RequestBody body: CreateBewerbRequest
|
@RequestBody body: CreateBewerbRequest
|
||||||
): Bewerb = service.create(Uuid.parse(turnierId), body.klasse, body.hoeheCm, body.bezeichnung)
|
): BewerbResponse = domainToDto(
|
||||||
|
service.create(
|
||||||
|
Uuid.parse(turnierId),
|
||||||
|
body
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@GetMapping("/turniere/{turnierId}/bewerbe")
|
@GetMapping("/turniere/{turnierId}/bewerbe")
|
||||||
suspend fun list(
|
suspend fun list(
|
||||||
@PathVariable turnierId: String,
|
@PathVariable turnierId: String,
|
||||||
@RequestParam(required = false) klasse: String?,
|
@RequestParam(required = false) klasse: String?,
|
||||||
@RequestParam(required = false) q: String?,
|
@RequestParam(required = false) q: String?,
|
||||||
): List<Bewerb> = service.list(Uuid.parse(turnierId), klasse, q)
|
): List<BewerbResponse> = service.list(Uuid.parse(turnierId), klasse, q).map(::domainToDto)
|
||||||
|
|
||||||
@GetMapping("/bewerbe/{id}")
|
@GetMapping("/bewerbe/{id}")
|
||||||
suspend fun get(@PathVariable id: String): Bewerb = service.get(Uuid.parse(id))
|
suspend fun get(@PathVariable id: String): BewerbResponse = domainToDto(service.get(Uuid.parse(id)))
|
||||||
|
|
||||||
@PutMapping("/bewerbe/{id}")
|
@PutMapping("/bewerbe/{id}")
|
||||||
suspend fun update(@PathVariable id: String, @RequestBody body: UpdateBewerbRequest): Bewerb =
|
suspend fun update(@PathVariable id: String, @RequestBody body: UpdateBewerbRequest): BewerbResponse =
|
||||||
service.update(Uuid.parse(id), body.klasse, body.hoeheCm, body.bezeichnung)
|
domainToDto(service.update(Uuid.parse(id), body))
|
||||||
|
|
||||||
@DeleteMapping("/bewerbe/{id}")
|
@DeleteMapping("/bewerbe/{id}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
|
|||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
package at.mocode.turnier.feature.data.remote
|
||||||
|
|
||||||
|
import io.ktor.client.*
|
||||||
|
import io.ktor.client.call.*
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import kotlinx.datetime.LocalDate
|
||||||
|
import kotlinx.datetime.LocalTime
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RichterEinsatzDto(
|
||||||
|
val funktionaerId: String,
|
||||||
|
val position: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CreateBewerbPayload(
|
||||||
|
// Basis
|
||||||
|
val klasse: String,
|
||||||
|
val hoeheCm: Int? = null,
|
||||||
|
val bezeichnung: String,
|
||||||
|
|
||||||
|
// Text & Details
|
||||||
|
val beschreibung: String? = null,
|
||||||
|
val aufgabe: String? = null,
|
||||||
|
val aufgabenNummer: String? = null,
|
||||||
|
val paraGrade: String? = null,
|
||||||
|
|
||||||
|
// Ort & Funktionäre
|
||||||
|
val austragungsplatzId: String? = null,
|
||||||
|
val richterEinsaetze: List<RichterEinsatzDto> = emptyList(),
|
||||||
|
|
||||||
|
// Zeitplan
|
||||||
|
val geplantesDatum: LocalDate? = null,
|
||||||
|
@SerialName("beginnZeitTyp") val beginnZeitTyp: String? = null, // enum name
|
||||||
|
val beginnZeit: LocalTime? = null,
|
||||||
|
val reitdauerMinuten: Int? = null,
|
||||||
|
val umbauMinuten: Int? = null,
|
||||||
|
val besichtigungMinuten: Int? = null,
|
||||||
|
val stechenGeplant: Boolean = false,
|
||||||
|
|
||||||
|
// Finanzen
|
||||||
|
val startgeldCent: Long? = null,
|
||||||
|
val geldpreisAusbezahlt: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BewerbResponse(
|
||||||
|
val id: String,
|
||||||
|
val turnierId: String,
|
||||||
|
val klasse: String,
|
||||||
|
val hoeheCm: Int? = null,
|
||||||
|
val bezeichnung: String,
|
||||||
|
|
||||||
|
// Text & Details
|
||||||
|
val beschreibung: String? = null,
|
||||||
|
val aufgabe: String? = null,
|
||||||
|
val aufgabenNummer: String? = null,
|
||||||
|
val paraGrade: String? = null,
|
||||||
|
|
||||||
|
// Ort & Funktionäre
|
||||||
|
val austragungsplatzId: String? = null,
|
||||||
|
val richterEinsaetze: List<RichterEinsatzDto> = emptyList(),
|
||||||
|
|
||||||
|
// Zeitplan
|
||||||
|
val geplantesDatum: LocalDate? = null,
|
||||||
|
@SerialName("beginnZeitTyp") val beginnZeitTyp: String? = null,
|
||||||
|
val beginnZeit: LocalTime? = null,
|
||||||
|
val reitdauerMinuten: Int? = null,
|
||||||
|
val umbauMinuten: Int? = null,
|
||||||
|
val besichtigungMinuten: Int? = null,
|
||||||
|
val stechenGeplant: Boolean = false,
|
||||||
|
|
||||||
|
// Finanzen
|
||||||
|
val startgeldCent: Long? = null,
|
||||||
|
val geldpreisAusbezahlt: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
class BewerbApi(private val apiClient: HttpClient) {
|
||||||
|
suspend fun createBewerb(turnierId: String, payload: CreateBewerbPayload): BewerbResponse =
|
||||||
|
apiClient.post("/turniere/$turnierId/bewerbe") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(payload)
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user