Refactor license matrix and tokenizer logic: rename LicenseTable to LizenzTable, replace LicenseMatrixService with LizenzMatrixService, enhance tokenizer with normalized and fallback token handling, improve ZNS import for license extraction, and update related documentation.
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Waiting to run
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Waiting to run
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Waiting to run
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Waiting to run
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Waiting to run
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Waiting to run
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Waiting to run
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Waiting to run
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Waiting to run
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Waiting to run
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 📜 Reiter-Lizenzen & Startberechtigungen (OEPS)
|
||||
|
||||
Diese Dokumentation beschreibt die verschiedenen Lizenzstufen des **OEPS (Österreichischer Pferdesportverband)** und die
|
||||
daraus resultierenden Startberechtigungen für die Sparten **Dressur (CDN)** und **Springen (CSN)** gemäß ÖTO 2026.
|
||||
daraus resultierenden Startberechtigungen für die Sparten **Dressur (CDN)**, **Springen (CSN)**, **Vielseitigkeit (CCN/CCI)** und **Fahren (CAN/CAI)** gemäß ÖTO 2026.
|
||||
|
||||
## 1. Lizenztypen & Klassen
|
||||
|
||||
@@ -11,10 +11,10 @@ Prüfungen antreten darf.
|
||||
| Code | Bezeichnung | Beschreibung | ZNS-Mapping |
|
||||
|:--------|:-----------------|:-------------------------------------------------------|:-------------|
|
||||
| **LZF** | Lizenzfrei | Nur Startkarte oder Reiterpass vorhanden. | `LIZENZFREI` |
|
||||
| **R1** | Reiter-Lizenz 1 | Einstiegslizenz für Springen, Dressur, Vielseitigkeit. | `R1` |
|
||||
| **R1** | Reiter-Lizenz 1 | Einstiegslizenz für Springen. | `R1` |
|
||||
| **R2** | Reiter-Lizenz 2 | Fortgeschrittene (Springen bis LM/130cm). | `R2` |
|
||||
| **R3** | Reiter-Lizenz 3 | Schwere Klasse (Springen bis S/145cm). | `R3` |
|
||||
| **R4** | Reiter-Lizenz 4 | Höchste nationale Stufe (alle Klassen). | `R4` |
|
||||
| **R4** | Reiter-Lizenz 4 | Höchste nationale Stufe Springen (bis 160cm). | `R4` |
|
||||
| **RD1** | Dressur-Lizenz 1 | Speziallizenz nur für Dressur (Kl. A, L). | `RD1` |
|
||||
| **RD2** | Dressur-Lizenz 2 | Speziallizenz nur für Dressur (Kl. LM, M). | `RD2` |
|
||||
| **RD3** | Dressur-Lizenz 3 | Speziallizenz nur für Dressur (Kl. S). | `RD3` |
|
||||
@@ -23,6 +23,8 @@ Prüfungen antreten darf.
|
||||
|
||||
## 2. Startberechtigungen nach Sparten
|
||||
|
||||
> Referenz: ÖTO 2026, A‑Teil § 15 „Reiterlizenzen“. Eine komprimierte Matrix mit Klassen/Höhen und zulässigen Lizenzen findet sich in der Projekt‑Referenz: `docs/03_Domain/02_Reference/OETO_Regelwerk/OETO-2026_A-Teil-Allgemeiner-Teil_16-12-2025.md` (Kapitel „Reiterlizenzen, § 15 ÖTO“).
|
||||
|
||||
### 2.1 Springen (CSN)
|
||||
|
||||
Die Startberechtigung richtet sich nach der Hindernishöhe der jeweiligen Klasse (§ 200 B-Teil).
|
||||
@@ -44,11 +46,81 @@ Die Startberechtigung richtet sich nach dem Aufgabenniveau (§ 100 B-Teil).
|
||||
| Klasse | Niveau | Erforderliche Lizenz | Besonderheiten |
|
||||
|:---------------|:--------------------|:------------------------|:-----------------------------------------|
|
||||
| **lizenzfrei** | - | **LZF** (Reiterpass) | Inkl. First Ridden, Dressurreiterbewerbe |
|
||||
| **A** | Leicht | **R1 / RD1** oder höher | Grundausbildung |
|
||||
| **L** | Mittelleicht | **R1 / RD1** oder höher | - |
|
||||
| **LM** | Leicht-Mittelschwer | **R2 / RD2** oder höher | Kandare wahlweise |
|
||||
| **M** | Mittelschwer | **R2 / RD2** oder höher | Kandarenpflicht |
|
||||
| **S** | Schwer | **R3 / RD3** oder höher | St. Georg bis Grand Prix |
|
||||
| **A** | Leicht | **RD1** oder höher | Grundausbildung |
|
||||
| **L** | Mittelleicht | **RD1** oder höher | - |
|
||||
| **LM** | Leicht-Mittelschwer | **RD2** oder höher | Kandare wahlweise |
|
||||
| **M** | Mittelschwer | **RD2** oder höher | Kandarenpflicht |
|
||||
| **S** | Schwer | **RD3** oder höher | St. Georg bis Grand Prix |
|
||||
|
||||
Hinweis RD4: Das ÖTO kennt in der Tabelle Kombinationsfälle bis `RD4`. Im System ist derzeit kein `RD4`‑Enum modelliert; faktisch wird `RD4` wie `RD3` behandelt (Kappung auf Dressur S). Eine spätere Erweiterung um `RD4` ist vorbereitet, siehe CHANGELOG.
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Vielseitigkeit (CCN/CCI)
|
||||
|
||||
Vielseitigkeit kombiniert Dressur, Gelände und Springen. Für die Startberechtigung gilt das Prinzip der kumulativen Mindestanforderung: Die jeweils geforderte Dressur- und Spring-Lizenz muss erfüllt sein (Details je Klasse und Ausschreibung, § 300 B‑Teil).
|
||||
|
||||
| Klasse (typ.) | Richtwert | Erforderliche Lizenzen (kumulativ) | Besonderheiten |
|
||||
|:--------------|:---------------------|:-----------------------------------|:--------------|
|
||||
| **E/Einsteiger** | national, Einstiegsniveau | **LZF** (Startkarte) ODER `RD1`+`R1` (wenn gefordert) | gem. Ausschreibung |
|
||||
| **A** | Einsteiger/Light | `RD1` UND `R1` | — |
|
||||
| **L** | Mittelleicht | `RD1` UND `R1` | — |
|
||||
| **M** | Mittelschwer | `RD2` UND `R2` | — |
|
||||
| **S** | Schwer | `RD3` UND `R3` | höhere Anforderungen international |
|
||||
|
||||
Hinweis: In der Praxis orientiert sich die Spring-Anforderung an der in der Ausschreibung angegebenen Hindernishöhe der Springprüfung; die Dressur-Anforderung am ausgeschriebenen Dressur-Niveau der Teilprüfung. Wo nationale Sonderregelungen (Ponys, Haflinger/Noriker) bestehen, gelten diese zusätzlich.
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Fahren (CAN/CAI)
|
||||
|
||||
Für Fahren existieren im ÖTO/FEI‑Kontext eigene Fahrlizenzen (z. B. F1–F3). Im aktuellen Systemmodell sind diese noch nicht als `ReiterLizenzKlasseE` hinterlegt. Bis zur Einführung entsprechender Enums/Regeln gilt:
|
||||
|
||||
| Klasse (typ.) | Richtwert | Systemzustand | Teilnahmevoraussetzung (heute) |
|
||||
|:--------------|:-----------------|:----------------------------------------------|:-------------------------------|
|
||||
| **A/L/M/S** | national/intern. | Keine `F*`‑Lizenztypen im Enum vorhanden | **Startkarte** (LZF) plus Zulassung laut Ausschreibung/Verbandsvorgaben |
|
||||
|
||||
Geplante Erweiterung: Ergänzung der Enum‑Werte `F1`..`F3` und einer Fahr‑Matrix analog Dressur/Springen (separates Ticket). Die ZNS‑Integration bleibt davon unberührt, bis ZNS eigene Fahr‑Kodierungen liefert.
|
||||
|
||||
---
|
||||
|
||||
### 2.5 Übersichtstabelle gemäß § 15 (kompakt)
|
||||
|
||||
Zur schnellen Orientierung ist die folgende, auf die System‑Enums abgebildete Kurzfassung der §15‑Tabelle enthalten. „B,C“ bedeutet „Turnierkategorien B, C, C‑NEU zulässig“, „LP“ steht für „Lizenzprüfung erforderlich“.
|
||||
|
||||
| Klasse/Höhe | V 80 | 60–100 | V 90 | A | 105–110 | V 100 | L | 115–120 | V 105 | LM | 125–130 | M | 135 | V110–115 | S | V120 | 140–145 | 150–160 |
|
||||
|:-----------:|:----:|:------:|:----:|:---:|:-------:|:-----:|:---:|:-------:|:-----:|:---:|:-------:|:---:|:---:|:---------:|:---:|:----:|:-------:|:-------:|
|
||||
| Sparte | V | S | V | D | S | V | D | S | V | D | S | D | S | V | D | V | S | S |
|
||||
| R1 | X | X | X | B,C | B,C | X | B,C | B,C | | | | | | | | | | |
|
||||
| R2 | X | X | X | X | X | X | X | X | X | X | X | LP | | | | | | |
|
||||
| R3 | X | X | X | X | X | X | X | X | X | X | X | X | X | X | | X | X | |
|
||||
| RD1 | | | | B,C | | | B,C | | | | | | | | | | | |
|
||||
| RD2 | | | | X | | | X | | | X | | LP | | | | | | |
|
||||
| RD3 | | | | X | | | X | | | X | | X | | | X | | | |
|
||||
| R4 | X | X | X | X | X | X | X | X | X | X | X | X | X | X | | X | X | X |
|
||||
|
||||
Abbildung im System:
|
||||
- Zeilen mit Kombi‑Lizenzen (z. B. `R1D2`, `RDS4`) werden als gleichzeitiger Besitz getrennter Lizenzen interpretiert (zwei Einträge in `Reiter.lizenzen`).
|
||||
- `RD4` ist aktuell nicht als Enum verfügbar; bis zur Erweiterung entspricht das Verhalten `RD3`.
|
||||
|
||||
---
|
||||
|
||||
### 2.6 Kombinationsreihen (§ 15)
|
||||
|
||||
Die folgenden Zeilen aus der ÖTO‑Tabelle (§ 15) bilden Kombinationsfälle ab, die sich aus gleichzeitig erfüllten
|
||||
Voraussetzungen ergeben. Sie sind systemisch als Parallelbesitz mehrerer Lizenzen zu verstehen und dienen der
|
||||
schnellen Orientierung. Spaltenbezeichnungen entsprechen Abschnitt 2.5.
|
||||
|
||||
| Klasse/Höhe | V 80 | 60–100 | V 90 | A | 105–110 | V 100 | L | 115–120 | V 105 | LM | 125–130 | M | 135 | V110–115 | S | V120 | 140–145 | 150–160 |
|
||||
|:-----------:|:----:|:------:|:----:|:---:|:-------:|:-----:|:---:|:-------:|:-----:|:---:|:-------:|:---:|:---:|:---------:|:---:|:----:|:-------:|:-------:|
|
||||
| R1S2 | X | X | X | B,C | X | X | B,C | X | | | X | | | | | | | |
|
||||
| R1S3 | X | X | X | B,C | X | X | B,C | X | | | X | | X | | | | X | |
|
||||
| R1S4 | X | X | X | B,C | X | X | B,C | X | | | X | | X | | | | X | X |
|
||||
| R2S3 | X | X | X | X | X | X | X | X | X | X | X | LP | X | | | | X | |
|
||||
| R2S4 | X | X | X | X | X | X | X | X | X | X | X | LP | X | | | | X | X |
|
||||
| R3S4 | X | X | X | X | X | X | X | X | X | X | X | X | X | X | | X | X | X |
|
||||
|
||||
Legende siehe Abschnitt 2.5 (Bedeutung von „B,C“/„LP“ sowie Spartenkürzel).
|
||||
|
||||
---
|
||||
|
||||
@@ -58,30 +130,58 @@ Die Startberechtigung richtet sich nach dem Aufgabenniveau (§ 100 B-Teil).
|
||||
|
||||
Für Rasse-spezifische Bewerbe gelten oft abweichende (niedrigere) Lizenz-Anforderungen für höhere Klassen.
|
||||
|
||||
Hinweis: Abweichungen sind disziplinspezifisch zu verstehen (Dressur → `RD*`, Springen → `R*`).
|
||||
|
||||
* **Dressur (Haflinger):**
|
||||
* Klasse L/LM: R(D)1 ausreichend.
|
||||
* Klasse M: R(D)3 erforderlich.
|
||||
* Klasse S: R(D)4 erforderlich.
|
||||
* Klasse L/LM: **RD1** ausreichend.
|
||||
* Klasse M: **RD3** erforderlich.
|
||||
* Klasse S: nationale Sonderregelungen, idR **RD3**; höhere Abweichungen gemäß Ausschreibung.
|
||||
* **Springen (Haflinger):**
|
||||
* 95-120cm (bis Klasse M): R1 ausreichend.
|
||||
* 125-135cm (Klasse S): R2 ausreichend.
|
||||
* 95–120cm (bis Klasse M): **R1** ausreichend.
|
||||
* 125–135cm (Klasse S): **R2** ausreichend.
|
||||
|
||||
### 3.2 Pony
|
||||
|
||||
* In Pony-Bewerben (bis Kl. L) ist die **Startkarte Allgemein** (Voraussetzung Reiterpass) ausreichend.
|
||||
* Ab Klasse LM ist eine entsprechende Lizenz (R1/RD1) erforderlich.
|
||||
* Ab Klasse LM ist eine entsprechende Lizenz erforderlich: **RD1** (Dressur) bzw. **R1** (Springen).
|
||||
|
||||
---
|
||||
|
||||
## 4. ZNS-Integration (LIZENZ01.dat)
|
||||
## 4. Validierungslogik & ZNS-Integration
|
||||
|
||||
### 4.1 Validierungslogik (Systemverhalten)
|
||||
|
||||
Die Eligibility wird in zwei strikt getrennten Schritten geprüft:
|
||||
|
||||
1) Spartenlizenz prüfen
|
||||
- Für Springen sind ausschließlich `R1..R4` gültig (keine Dressur-Lizenz ausreichend).
|
||||
- Für Dressur sind ausschließlich `RD1..RD3` gültig (keine Spring-Lizenz ausreichend).
|
||||
- Für Vielseitigkeit müssen die Anforderungen beider Sparten erfüllt sein: Dressur-Teilprüfung (RD*) UND Spring-Teilprüfung (R*), jeweils gemäß ausgeschriebener Klasse.
|
||||
- Für Fahren gibt es aktuell keine `F*`‑Lizenzen im System; bis zur Erweiterung wird Fahren als lizenzfrei (LZF) behandelt und organisatorisch über die Ausschreibung begrenzt.
|
||||
|
||||
2) Maximal erlaubte Turnierklasse ermitteln
|
||||
- Innerhalb der geprüften Sparte bestimmt die höchste bezahlte Lizenz die Obergrenze der Klasse/Höhe.
|
||||
- Zur internen Kappung wird ggf. ein disziplinübergreifendes Mapping verwendet (nur nach bestandener Spartenprüfung):
|
||||
- `R1↔RD1`, `R2↔RD2`, `R3/R4↔RD3`.
|
||||
|
||||
Konsequenz: Ein Reiter mit nur `RD2` darf Dressur bis LM/M reiten, aber im Springen nur lizenzfreie Bewerbe (E0). Umgekehrt
|
||||
ermöglicht eine `R2` Springen bis 130cm, aber keine Dressur-Klassen. In der Vielseitigkeit wären für eine M‑Klasse beide Nachweise (`RD2` UND `R2`) erforderlich.
|
||||
|
||||
### 4.2 ZNS-Integration (LIZENZ01.dat)
|
||||
|
||||
Das System mappt die Felder aus der ZNS-Datei automatisch auf die interne `LizenzKlasseE`.
|
||||
|
||||
* **Feld `Reiterlizenz` (Pos 137):** Enthält die Hauptlizenz (z.B. `R1`).
|
||||
* **Feld `Lizenz-Details` (Pos 201):** Enthält die Liste aller bezahlten Lizenzen (z.B. `RD1,F1`).
|
||||
* *Logik:* Ein Reiter mit `RD2` darf Dressur LM/M reiten, aber Springen nur lizenzfrei (E0), sofern keine `R1` (oder
|
||||
höher) vorhanden ist.
|
||||
* **Feld `Reiterlizenz` (Pos 137):** Enthält die primäre Lizenzangabe (z. B. `R1` oder `RD1`).
|
||||
* **Feld `Lizenz-Details` (Pos 201):** Enthält die Liste aller bezahlten Lizenzen (z. B. `RD1`). Werte für Fahren (`F*`) werden aktuell ignoriert, solange keine System‑Enums existieren.
|
||||
* Das System aggregiert alle Vorkommen und bestimmt je Sparte die höchste vorhandene Lizenz.
|
||||
|
||||
---
|
||||
> 📜 **Rulebook Expert Hinweis:** Die Startberechtigung muss bei jeder Nennung gegen die aktuelle Lizenz des Reiters (
|
||||
> Stichtag Nennschluss) geprüft werden. Eine Höherreihung während eines Turniers ist gemäß § 17 Abs. 6 ausgeschlossen.
|
||||
> 📜 **Rulebook Expert Hinweis:** Die Startberechtigung muss bei jeder Nennung gegen die aktuelle Lizenz des Reiters
|
||||
> (Stichtag Nennschluss) geprüft werden. Eine Höherreihung während eines Turniers ist gemäß § 17 Abs. 6 ausgeschlossen.
|
||||
|
||||
---
|
||||
|
||||
Siehe ergänzend:
|
||||
* `TURNIER_KLASSEN.md` für Klassendefinitionen und Höhen/Niveaus je Sparte.
|
||||
* `GEBUEHRENORDNUNG.md` für Start-/Nenngelder und Mindest-Geldpreise.
|
||||
* `ZNS_SCHNITTSTELLE.md` für Felder und Positionsangaben der LIZENZ01.dat.
|
||||
|
||||
+15
-3
@@ -192,13 +192,25 @@ data class Reiter(
|
||||
|
||||
/**
|
||||
* Checks if the rider holds a license for a specific discipline.
|
||||
* Simple logic for now: Any non-blank license field counts.
|
||||
* Strikte Logik: Eine Dressur-Lizenz (RD1..RD3) gilt nur für DRESSUR,
|
||||
* eine Reit-/Spring-Lizenz (R1..R4) nur für SPRINGEN. FAHREN nutzt die separate Fahr-Lizenz.
|
||||
*/
|
||||
fun hasLizenzForSparte(sparte: at.mocode.core.domain.model.SparteE): Boolean {
|
||||
val lk = lizenzKlasse
|
||||
return when (sparte) {
|
||||
at.mocode.core.domain.model.SparteE.DRESSUR -> !reiterLizenz.isNullOrBlank()
|
||||
at.mocode.core.domain.model.SparteE.SPRINGEN -> !reiterLizenz.isNullOrBlank()
|
||||
at.mocode.core.domain.model.SparteE.DRESSUR ->
|
||||
lk == ReiterLizenzKlasseE.RD1 ||
|
||||
lk == ReiterLizenzKlasseE.RD2 ||
|
||||
lk == ReiterLizenzKlasseE.RD3
|
||||
|
||||
at.mocode.core.domain.model.SparteE.SPRINGEN ->
|
||||
lk == ReiterLizenzKlasseE.R1 ||
|
||||
lk == ReiterLizenzKlasseE.R2 ||
|
||||
lk == ReiterLizenzKlasseE.R3 ||
|
||||
lk == ReiterLizenzKlasseE.R4
|
||||
|
||||
at.mocode.core.domain.model.SparteE.FAHREN -> !fahrLizenz.isNullOrBlank()
|
||||
|
||||
else -> hasLizenz()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class ReitLizenz(
|
||||
data class Reiterlizenz(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val lizenzId: Uuid = Uuid.random(),
|
||||
val code: String,
|
||||
+3
-3
@@ -3,14 +3,14 @@
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.masterdata.domain.model.FahrLizenz
|
||||
import at.mocode.masterdata.domain.model.ReitLizenz
|
||||
import at.mocode.masterdata.domain.model.Reiterlizenz
|
||||
import at.mocode.masterdata.domain.model.Startkarte
|
||||
|
||||
/**
|
||||
* Repository für alle Lizenz-Stammdaten (Reit, Fahr, Startkarten).
|
||||
*/
|
||||
interface MasterdataLicenseRepository {
|
||||
suspend fun findReitLizenzByCode(code: String): ReitLizenz?
|
||||
interface LizenzRepository {
|
||||
suspend fun findReitLizenzByCode(code: String): Reiterlizenz?
|
||||
suspend fun findFahrLizenzByCode(code: String): FahrLizenz?
|
||||
suspend fun findStartkarteByCode(code: String): Startkarte?
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
package at.mocode.masterdata.domain.service
|
||||
|
||||
import at.mocode.core.domain.model.ReiterLizenzKlasseE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.Reiter
|
||||
import at.mocode.masterdata.domain.model.LicenseMatrixEntry
|
||||
import at.mocode.masterdata.domain.model.TurnierklasseDefinition
|
||||
|
||||
/**
|
||||
* Standard-Implementierung des [LicenseMatrixService] gemäß ÖTO.
|
||||
*/
|
||||
class LicenseMatrixServiceImpl : LicenseMatrixService {
|
||||
|
||||
private val classHierarchy = listOf("E", "A", "L", "LM", "M", "S")
|
||||
|
||||
override fun isEligible(
|
||||
reiter: Reiter,
|
||||
turnierklasse: TurnierklasseDefinition,
|
||||
sparte: SparteE,
|
||||
matrix: List<LicenseMatrixEntry>,
|
||||
alleKlassen: List<TurnierklasseDefinition>
|
||||
): Boolean {
|
||||
// 1. Basis-Check: Hat der Reiter überhaupt eine Lizenz für diese Sparte?
|
||||
if (!reiter.hasLizenzForSparte(sparte)) return false
|
||||
|
||||
// 2. Max Turnierklasse aus Matrix ermitteln
|
||||
val maxClassCode = getMaxTurnierklasse(reiter, sparte, matrix) ?: return false
|
||||
|
||||
// 3. Hierarchie-Check (maxClassCode vs. turnierklasse.code)
|
||||
val maxIndex = classHierarchy.indexOf(maxClassCode)
|
||||
val targetIndex = classHierarchy.indexOf(turnierklasse.code)
|
||||
|
||||
if (maxIndex == -1 || targetIndex == -1) return false
|
||||
|
||||
return targetIndex <= maxIndex
|
||||
}
|
||||
|
||||
override fun getMaxTurnierklasse(
|
||||
reiter: Reiter,
|
||||
sparte: SparteE,
|
||||
matrix: List<LicenseMatrixEntry>
|
||||
): String? {
|
||||
// Suche passenden Eintrag in der Matrix für (Sparte, Lizenzklasse)
|
||||
val entry = matrix.find { it.sparte == sparte && it.lizenzKlasse == reiter.lizenzKlasse }
|
||||
?: matrix.find { it.sparte == SparteE.DRESSUR && sparte == SparteE.DRESSUR && it.lizenzKlasse == reiter.lizenzKlasse } // Fallback/Spezial
|
||||
?: if (reiter.lizenzKlasse == ReiterLizenzKlasseE.R1 ||
|
||||
reiter.lizenzKlasse == ReiterLizenzKlasseE.R2 ||
|
||||
reiter.lizenzKlasse == ReiterLizenzKlasseE.R3 ||
|
||||
reiter.lizenzKlasse == ReiterLizenzKlasseE.R4) {
|
||||
// Fallback für Dressur, wenn man eine Springlizenz hat (R1 gilt oft auch als RD1 etc. in manchen Kontexten,
|
||||
// aber hier schauen wir primär ob die Matrix einen generischen Eintrag hat)
|
||||
matrix.find { it.sparte == sparte && it.lizenzKlasse == ReiterLizenzKlasseE.LIZENZFREI }
|
||||
} else null
|
||||
|
||||
return entry?.maxTurnierklasseCode
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import at.mocode.masterdata.domain.model.TurnierklasseDefinition
|
||||
/**
|
||||
* Service zur Prüfung der Teilnahmeberechtigung basierend auf der Lizenz-Matrix.
|
||||
*/
|
||||
interface LicenseMatrixService {
|
||||
interface LizenzMatrixService {
|
||||
|
||||
/**
|
||||
* Prüft, ob ein Reiter mit seiner aktuellen Lizenz in einer bestimmten Turnierklasse startberechtigt ist.
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package at.mocode.masterdata.domain.service
|
||||
|
||||
import at.mocode.core.domain.model.ReiterLizenzKlasseE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.Reiter
|
||||
import at.mocode.masterdata.domain.model.LicenseMatrixEntry
|
||||
import at.mocode.masterdata.domain.model.TurnierklasseDefinition
|
||||
|
||||
/**
|
||||
* Standard-Implementierung des [LizenzMatrixService] gemäß ÖTO.
|
||||
*/
|
||||
class LizenzMatrixServiceImpl : LizenzMatrixService {
|
||||
|
||||
private val classHierarchy = listOf("E", "A", "L", "LM", "M", "S")
|
||||
|
||||
override fun isEligible(
|
||||
reiter: Reiter,
|
||||
turnierklasse: TurnierklasseDefinition,
|
||||
sparte: SparteE,
|
||||
matrix: List<LicenseMatrixEntry>,
|
||||
alleKlassen: List<TurnierklasseDefinition>
|
||||
): Boolean {
|
||||
// 1. Basis-Check: Hat der Reiter überhaupt eine Lizenz für diese Sparte?
|
||||
if (!reiter.hasLizenzForSparte(sparte)) return false
|
||||
|
||||
// 2. Max Turnierklasse aus Matrix ermitteln
|
||||
val maxClassCode = getMaxTurnierklasse(reiter, sparte, matrix) ?: return false
|
||||
|
||||
// 3. Hierarchie-Check (maxClassCode vs. turnierklasse.code)
|
||||
val maxIndex = classHierarchy.indexOf(maxClassCode)
|
||||
val targetIndex = classHierarchy.indexOf(turnierklasse.code)
|
||||
|
||||
if (maxIndex == -1 || targetIndex == -1) return false
|
||||
|
||||
return targetIndex <= maxIndex
|
||||
}
|
||||
|
||||
override fun getMaxTurnierklasse(
|
||||
reiter: Reiter,
|
||||
sparte: SparteE,
|
||||
matrix: List<LicenseMatrixEntry>
|
||||
): String? {
|
||||
// 1) Direkter Treffer in Matrix für (Sparte, Lizenzklasse)
|
||||
val direct = matrix.find { it.sparte == sparte && it.lizenzKlasse == reiter.lizenzKlasse }
|
||||
if (direct != null) return direct.maxTurnierklasseCode
|
||||
|
||||
// 2) Cross-Discipline Mapping (R<->RD) gemäß ÖTO-Äquivalenzen
|
||||
// Hinweis: RD4 ist im aktuellen Enum nicht modelliert. R4 wird für Zwecke der
|
||||
// Dressur-Kappung wie RD3 behandelt (max. S), bis RD4 eingeführt wird.
|
||||
val mappedLizenz = when (sparte) {
|
||||
SparteE.DRESSUR -> when (reiter.lizenzKlasse) {
|
||||
ReiterLizenzKlasseE.R1 -> ReiterLizenzKlasseE.RD1
|
||||
ReiterLizenzKlasseE.R2 -> ReiterLizenzKlasseE.RD2
|
||||
ReiterLizenzKlasseE.R3, ReiterLizenzKlasseE.R4 -> ReiterLizenzKlasseE.RD3 // RD4 derzeit nicht modelliert
|
||||
else -> reiter.lizenzKlasse
|
||||
}
|
||||
SparteE.SPRINGEN -> when (reiter.lizenzKlasse) {
|
||||
ReiterLizenzKlasseE.RD1 -> ReiterLizenzKlasseE.R1
|
||||
ReiterLizenzKlasseE.RD2 -> ReiterLizenzKlasseE.R2
|
||||
ReiterLizenzKlasseE.RD3 -> ReiterLizenzKlasseE.R3
|
||||
else -> reiter.lizenzKlasse
|
||||
}
|
||||
else -> reiter.lizenzKlasse
|
||||
}
|
||||
val cross = matrix.find { it.sparte == sparte && it.lizenzKlasse == mappedLizenz }
|
||||
if (cross != null) return cross.maxTurnierklasseCode
|
||||
|
||||
// 3) Letzter Fallback: LIZENZFREI in gewünschter Sparte
|
||||
return matrix.find { it.sparte == sparte && it.lizenzKlasse == ReiterLizenzKlasseE.LIZENZFREI }
|
||||
?.maxTurnierklasseCode
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -13,9 +13,9 @@ import kotlin.test.assertTrue
|
||||
import kotlin.time.Clock
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
class LicenseMatrixServiceTest {
|
||||
class LiznezMatrixServiceTest {
|
||||
|
||||
private val service = LicenseMatrixServiceImpl()
|
||||
private val service = LizenzMatrixServiceImpl()
|
||||
private val nun = Clock.System.now()
|
||||
|
||||
private val matrix = listOf(
|
||||
+10
-10
@@ -29,7 +29,7 @@ class ExposedRegulationRepository : RegulationRepository {
|
||||
}
|
||||
|
||||
override suspend fun findAllLicenseMatrixEntries(): List<LicenseMatrixEntry> = DatabaseFactory.dbQuery {
|
||||
LicenseTable.selectAll()
|
||||
LizenzTable.selectAll()
|
||||
.map { it.toLicenseMatrixEntry() }
|
||||
}
|
||||
|
||||
@@ -89,15 +89,15 @@ class ExposedRegulationRepository : RegulationRepository {
|
||||
)
|
||||
|
||||
private fun ResultRow.toLicenseMatrixEntry() = LicenseMatrixEntry(
|
||||
licenseId = this[LicenseTable.id],
|
||||
sparte = SparteE.valueOf(this[LicenseTable.sparte]),
|
||||
lizenzKlasse = ReiterLizenzKlasseE.valueOf(this[LicenseTable.lizenzKlasse]),
|
||||
maxTurnierklasseCode = this[LicenseTable.maxTurnierklasseCode],
|
||||
validFrom = this[LicenseTable.validFrom].toKtInstant(),
|
||||
validTo = this[LicenseTable.validTo]?.toOptionalKtInstant(),
|
||||
istAktiv = this[LicenseTable.istAktiv],
|
||||
createdAt = this[LicenseTable.createdAt].toKtInstant(),
|
||||
updatedAt = this[LicenseTable.updatedAt].toKtInstant()
|
||||
licenseId = this[LizenzTable.id],
|
||||
sparte = SparteE.valueOf(this[LizenzTable.sparte]),
|
||||
lizenzKlasse = ReiterLizenzKlasseE.valueOf(this[LizenzTable.lizenzKlasse]),
|
||||
maxTurnierklasseCode = this[LizenzTable.maxTurnierklasseCode],
|
||||
validFrom = this[LizenzTable.validFrom].toKtInstant(),
|
||||
validTo = this[LizenzTable.validTo]?.toOptionalKtInstant(),
|
||||
istAktiv = this[LizenzTable.istAktiv],
|
||||
createdAt = this[LizenzTable.createdAt].toKtInstant(),
|
||||
updatedAt = this[LizenzTable.updatedAt].toKtInstant()
|
||||
)
|
||||
|
||||
private fun ResultRow.toRichtverfahrenDefinition() = RichtverfahrenDefinition(
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import org.jetbrains.exposed.v1.datetime.timestamp
|
||||
* Exposed-Tabellendefinition für die Lizenz-Matrix (Reiter-Lizenz vs. Turnierklasse).
|
||||
* Basierend auf ÖTO 2026.
|
||||
*/
|
||||
object LicenseTable : Table("license_matrix") {
|
||||
object LizenzTable : Table("license_matrix") {
|
||||
val id = uuid("license_id")
|
||||
val sparte = varchar("sparte", 20) // DRESSUR, SPRINGEN, ALLGEMEIN
|
||||
val lizenzKlasse = varchar("lizenz_klasse", 20) // R1, R2, R3, RD1, RD2, RD3, LF
|
||||
+6
-6
@@ -4,21 +4,21 @@ package at.mocode.masterdata.infrastructure.persistence.reiter
|
||||
|
||||
import at.mocode.core.utils.database.DatabaseFactory
|
||||
import at.mocode.masterdata.domain.model.FahrLizenz
|
||||
import at.mocode.masterdata.domain.model.ReitLizenz
|
||||
import at.mocode.masterdata.domain.model.Reiterlizenz
|
||||
import at.mocode.masterdata.domain.model.Startkarte
|
||||
import at.mocode.masterdata.domain.repository.MasterdataLicenseRepository
|
||||
import at.mocode.masterdata.domain.repository.LizenzRepository
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.jdbc.selectAll
|
||||
|
||||
/**
|
||||
* Exposed-basierte Implementierung des MasterdataLicenseRepository.
|
||||
* Exposed-basierte Implementierung des LizenzRepository.
|
||||
*/
|
||||
class MasterdataLicenseExposedRepository : MasterdataLicenseRepository {
|
||||
class MasterdataLicenseExposedRepository : LizenzRepository {
|
||||
|
||||
override suspend fun findReitLizenzByCode(code: String): ReitLizenz? = DatabaseFactory.dbQuery {
|
||||
override suspend fun findReitLizenzByCode(code: String): Reiterlizenz? = DatabaseFactory.dbQuery {
|
||||
ReitLizenzenTable.selectAll().where { ReitLizenzenTable.code eq code }
|
||||
.map {
|
||||
ReitLizenz(
|
||||
Reiterlizenz(
|
||||
lizenzId = it[ReitLizenzenTable.id],
|
||||
code = it[ReitLizenzenTable.code],
|
||||
bezeichnung = it[ReitLizenzenTable.bezeichnung],
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ class RegulationSeedVerificationTest {
|
||||
transaction {
|
||||
SchemaUtils.create(
|
||||
TurnierKlassenTable,
|
||||
LicenseTable,
|
||||
LizenzTable,
|
||||
RichtverfahrenTable,
|
||||
GebuehrTable,
|
||||
RegulationConfigTable,
|
||||
@@ -71,7 +71,7 @@ class RegulationSeedVerificationTest {
|
||||
|
||||
@Test
|
||||
fun `verify domain logic with simulated oeto data`() {
|
||||
val service = at.mocode.masterdata.domain.service.LicenseMatrixServiceImpl()
|
||||
val service = at.mocode.masterdata.domain.service.LizenzMatrixServiceImpl()
|
||||
val now = Clock.System.now()
|
||||
|
||||
val oetoMatrix = listOf(
|
||||
|
||||
+2
-2
@@ -59,7 +59,7 @@ class MasterdataDatabaseConfiguration(
|
||||
TurnierKlassenTable,
|
||||
TurnierSpartenTable,
|
||||
TurnierKategorienTable,
|
||||
LicenseTable,
|
||||
LizenzTable,
|
||||
RichtverfahrenTable,
|
||||
GebuehrTable,
|
||||
RegulationConfigTable
|
||||
@@ -112,7 +112,7 @@ class MasterdataTestDatabaseConfiguration {
|
||||
TurnierKlassenTable,
|
||||
TurnierSpartenTable,
|
||||
TurnierKategorienTable,
|
||||
LicenseTable,
|
||||
LizenzTable,
|
||||
RichtverfahrenTable,
|
||||
GebuehrTable,
|
||||
RegulationConfigTable
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.service.config
|
||||
|
||||
import at.mocode.masterdata.infrastructure.persistence.LizenzTable
|
||||
import jakarta.annotation.PostConstruct
|
||||
import org.jetbrains.exposed.v1.core.*
|
||||
import org.jetbrains.exposed.v1.jdbc.insert
|
||||
import org.jetbrains.exposed.v1.jdbc.selectAll
|
||||
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
|
||||
import org.jetbrains.exposed.v1.jdbc.update
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.DependsOn
|
||||
import org.springframework.context.annotation.Profile
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Seeder für Reiterlizenzen (license_matrix) gemäß ÖTO 2026.
|
||||
*
|
||||
* Ziel: Sicherstellen, dass bei Service-Start alle benötigten Lizenzeinträge
|
||||
* für Dressur und Springen vorhanden sind – auch wenn die DB leer ist oder
|
||||
* frühere Migrationen/Seeds nicht gelaufen sind.
|
||||
*
|
||||
* Idempotent: pro (sparte, lizenz_klasse) exakt ein Datensatz; bei Änderungen
|
||||
* der max_turnierklasse_code wird dieser upgedatet.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("!test")
|
||||
@DependsOn("masterdataDatabaseConfiguration")
|
||||
class ReiterlizenzenSeeder {
|
||||
private val log = LoggerFactory.getLogger(ReiterlizenzenSeeder::class.java)
|
||||
|
||||
@PostConstruct
|
||||
fun seed() {
|
||||
log.info("Starte Seeding der Reiterlizenzen (license_matrix)...")
|
||||
transaction {
|
||||
// Springen: LIZENZFREI→E, R1→L, R2→M, R3→S, R4→S
|
||||
upsert("SPRINGEN", "LIZENZFREI", "E")
|
||||
upsert("SPRINGEN", "R1", "L")
|
||||
upsert("SPRINGEN", "R2", "M")
|
||||
upsert("SPRINGEN", "R3", "S")
|
||||
upsert("SPRINGEN", "R4", "S")
|
||||
|
||||
// Dressur: LIZENZFREI→E, RD1→L, RD2→M, RD3→S
|
||||
upsert("DRESSUR", "LIZENZFREI", "E")
|
||||
upsert("DRESSUR", "RD1", "L")
|
||||
upsert("DRESSUR", "RD2", "M")
|
||||
upsert("DRESSUR", "RD3", "S")
|
||||
}
|
||||
log.info("Seeding der Reiterlizenzen abgeschlossen.")
|
||||
}
|
||||
|
||||
private fun upsert(sparte: String, lizenzKlasse: String, maxTurnierklasseCode: String) {
|
||||
val existing = LizenzTable.selectAll()
|
||||
.where { (LizenzTable.sparte eq sparte) and (LizenzTable.lizenzKlasse eq lizenzKlasse) }
|
||||
.singleOrNull()
|
||||
|
||||
if (existing == null) {
|
||||
LizenzTable.insert {
|
||||
it[id] = Uuid.random()
|
||||
it[LizenzTable.sparte] = sparte
|
||||
it[LizenzTable.lizenzKlasse] = lizenzKlasse
|
||||
it[LizenzTable.maxTurnierklasseCode] = maxTurnierklasseCode
|
||||
it[istAktiv] = true
|
||||
}
|
||||
log.debug("Lizenz-Matrix angelegt: {} / {} -> {}", sparte, lizenzKlasse, maxTurnierklasseCode)
|
||||
} else {
|
||||
val currentMax = existing[LizenzTable.maxTurnierklasseCode]
|
||||
val currentActive = existing[LizenzTable.istAktiv]
|
||||
if (currentMax != maxTurnierklasseCode || !currentActive) {
|
||||
LizenzTable.update({ (LizenzTable.sparte eq sparte) and (LizenzTable.lizenzKlasse eq lizenzKlasse) }) {
|
||||
it[LizenzTable.maxTurnierklasseCode] = maxTurnierklasseCode
|
||||
it[LizenzTable.istAktiv] = true
|
||||
}
|
||||
log.debug("Lizenz-Matrix aktualisiert: {} / {} -> {}", sparte, lizenzKlasse, maxTurnierklasseCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-17
@@ -1,36 +1,79 @@
|
||||
-- V013__Cleanup_and_Standardize_Masterdata.sql
|
||||
-- Datum: 6. April 2026
|
||||
|
||||
-- 1. Bundesland -> bundeslaender
|
||||
ALTER TABLE bundesland RENAME TO bundeslaender;
|
||||
ALTER TABLE bundeslaender RENAME COLUMN id TO bundesland_id;
|
||||
ALTER INDEX IF EXISTS pk_bundesland RENAME TO pk_bundeslaender;
|
||||
ALTER INDEX IF EXISTS idx_bundesland_oeps RENAME TO idx_bundeslaender_oeps;
|
||||
ALTER INDEX IF EXISTS idx_bundesland_iso RENAME TO idx_bundeslaender_iso;
|
||||
ALTER INDEX IF EXISTS ux_bundesland_land_kuerzel RENAME TO ux_bundeslaender_land_kuerzel;
|
||||
ALTER INDEX IF EXISTS bundesland_bundesland_nr_unique RENAME TO bundeslaender_bundesland_nr_unique;
|
||||
-- 1. Bundesland -> bundeslaender (idempotent)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('public.bundesland') IS NOT NULL AND to_regclass('public.bundeslaender') IS NULL THEN
|
||||
ALTER TABLE bundesland RENAME TO bundeslaender;
|
||||
END IF;
|
||||
|
||||
-- 2. qualifikation_master -> funktionaers_qualifikationen
|
||||
ALTER TABLE qualifikation_master RENAME TO funktionaers_qualifikationen;
|
||||
-- Spaltenumbenennung nur, wenn noch "id" existiert
|
||||
IF to_regclass('public.bundeslaender') IS NOT NULL THEN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'public' AND table_name = 'bundeslaender' AND column_name = 'id'
|
||||
) THEN
|
||||
ALTER TABLE bundeslaender RENAME COLUMN id TO bundesland_id;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- Optionale historische Index-Umbenennungen (nur wenn vorhanden)
|
||||
IF EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pk_bundesland') THEN
|
||||
ALTER INDEX pk_bundesland RENAME TO pk_bundeslaender;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_bundesland_oeps') THEN
|
||||
ALTER INDEX idx_bundesland_oeps RENAME TO idx_bundeslaender_oeps;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_bundesland_iso') THEN
|
||||
ALTER INDEX idx_bundesland_iso RENAME TO idx_bundeslaender_iso;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_class WHERE relname = 'ux_bundesland_land_kuerzel') THEN
|
||||
ALTER INDEX ux_bundesland_land_kuerzel RENAME TO ux_bundeslaender_land_kuerzel;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_class WHERE relname = 'bundesland_bundesland_nr_unique') THEN
|
||||
ALTER INDEX bundesland_bundesland_nr_unique RENAME TO bundeslaender_bundesland_nr_unique;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 2. qualifikation_master -> funktionaers_qualifikationen (idempotent)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('public.qualifikation_master') IS NOT NULL AND to_regclass('public.funktionaers_qualifikationen') IS NULL THEN
|
||||
ALTER TABLE qualifikation_master RENAME TO funktionaers_qualifikationen;
|
||||
END IF;
|
||||
END $$;
|
||||
-- Die Join-Tabelle funktionaer_qualifikation bleibt als solche bestehen,
|
||||
-- referenziert aber nun funktionaers_qualifikationen.
|
||||
-- (Der Name der Join-Tabelle ist bereits fast korrekt, wir lassen sie vorerst so,
|
||||
-- da sie die Verknüpfung zw. Funktionär und Qualifikation darstellt.)
|
||||
-- Update: Der User möchte "funktionaers_qualifikationen" als Name für die Qualifikationen.
|
||||
|
||||
-- 3. reiter_lizenz -> reit_lizenzen
|
||||
ALTER TABLE reiter_lizenz RENAME TO reit_lizenzen;
|
||||
-- 3. reiter_lizenz -> reit_lizenzen (idempotent)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('public.reiter_lizenz') IS NOT NULL AND to_regclass('public.reit_lizenzen') IS NULL THEN
|
||||
ALTER TABLE reiter_lizenz RENAME TO reit_lizenzen;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
ALTER INDEX IF EXISTS pk_reiter_lizenz RENAME TO pk_reit_lizenzen;
|
||||
|
||||
-- 4. reiter_sparte entfernen
|
||||
DROP TABLE IF EXISTS reiter_sparte;
|
||||
|
||||
-- 5. turnierklasse -> turnier_klassen
|
||||
ALTER TABLE turnierklasse RENAME TO turnier_klassen;
|
||||
-- 5. turnierklasse -> turnier_klassen (idempotent)
|
||||
-- Hinweis: In der aktuellen Codebasis verwendet Exposed `bewerbs_klassen` als technische Tabelle
|
||||
-- für Turnier-/Bewerbsklassen. Daher nur umbenennen, wenn die Alt-Tabelle tatsächlich existiert.
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('public.turnierklasse') IS NOT NULL AND to_regclass('public.turnier_klassen') IS NULL THEN
|
||||
ALTER TABLE turnierklasse RENAME TO turnier_klassen;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
ALTER INDEX IF EXISTS pk_turnierklasse RENAME TO pk_turnier_klassen;
|
||||
ALTER INDEX IF EXISTS idx_turnierklasse_sparte_code RENAME TO idx_turnier_klassen_sparte_code;
|
||||
|
||||
-- 6. turnier_sparten erstellen
|
||||
CREATE TABLE IF NOT EXISTS turnier_sparten (
|
||||
sparte_id UUID PRIMARY KEY,
|
||||
code VARCHAR(10) UNIQUE NOT NULL, -- z.B. D, S, V, F, R, C
|
||||
@@ -40,6 +83,5 @@ CREATE TABLE IF NOT EXISTS turnier_sparten (
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 7. Constraints aktualisieren (falls nötig)
|
||||
-- Da wir nur Tabellen umbenannt haben, bleiben die Foreign Keys in PostgreSQL erhalten
|
||||
-- und zeigen automatisch auf die neuen Tabellennamen.
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ class ZnsImportServiceApplication {
|
||||
funktionaerRepository: FunktionaerRepository,
|
||||
landRepository: LandRepository,
|
||||
bundeslandRepository: BundeslandRepository,
|
||||
licenseRepository: MasterdataLicenseRepository,
|
||||
licenseRepository: LizenzRepository,
|
||||
altersklassenRepository: AltersklassenRepository
|
||||
): ZnsImportService {
|
||||
return ZnsImportService(
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class RepositoryConfiguration {
|
||||
fun funktionaerRepository(): FunktionaerRepository = FunktionaerExposedRepository()
|
||||
|
||||
@Bean
|
||||
fun licenseRepository(): MasterdataLicenseRepository = MasterdataLicenseExposedRepository()
|
||||
fun licenseRepository(): LizenzRepository = MasterdataLicenseExposedRepository()
|
||||
|
||||
@Bean
|
||||
fun altersklassenRepository(): AltersklassenRepository = AltersklassenExposedRepository()
|
||||
|
||||
Reference in New Issue
Block a user