chore(ci): Align GH Workflows with Docker SSoT, new paths; minimal SSoT guard; staticAnalysis (#23)
* chore(MP-21): snapshot pre-refactor state (Epic 1)
* chore(MP-22): scaffold new repo structure, relocate Docker Compose, move frontend/backend modules, update Makefile; add docs mapping and env template
* MP-22 Epic 2: Erfolgreich umgesetzt und verifiziert
* MP-23 Epic 3: Gradle/Build Governance zentralisieren
* MP-23 Epic 3: Gradle/Build Governance zentralisieren
* chore(devops)!: Docker-SSoT (.env) konsolidiert, Compose-Mounts ergänzt, Makefile entfernt
- ENV Single Source of Truth
- docker/.env.example neu (inkl. REDIS_PASSWORD, Ports, Build-Overrides)
- config/.env(.example) als DEPRECATED markiert (Verweis auf docker/.env[.example])
- Docker Compose vereinheitlicht (docker/docker-compose.yaml)
- Postgres: zentralen postgresql.conf mounten (../config/postgres/postgresql.conf)
und Start mit -c config_file=/etc/postgresql/postgresql.conf
- Redis: zentralen redis.conf mounten (../config/redis/redis.conf)
und Start via "redis-server … ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"
- Web-Nginx: ../config/nginx/nginx.prod.conf → /etc/nginx/nginx.conf (ro)
- Monitoring: Prometheus/Grafana nutzen ../config/monitoring/* als SSoT
- Frontend/DI/Network (MP-23 Grundlage)
- :frontend:core:network Modul mit Koin `apiClient` (Ktor + JSON/Retry/Timeout/Logging)
- Plattform-Basis-URL-Auflösung (JVM: ENV API_BASE_URL; JS: globalThis.API_BASE_URL / Same-Origin)
- Web index.html setzt API_BASE_URL (Query `?apiBaseUrl=…` > Same-Origin > Fallback)
- Build/Gradle & Module-Refs
- settings.gradle.kts: neue Frontend-/Backend-Pfade bereits inkludiert
- Features/Shell: Abhängigkeiten auf :frontend:shared / :frontend:core:* angepasst
- Ping-API-Refs auf :backend:services:ping:ping-api vereinheitlicht
- Dockerfiles angepasst
- backend/infrastructure/gateway/Dockerfile → Tasks/Pfade auf :backend:gateway
- backend/services/ping/Dockerfile → Tasks/Pfade auf :backend:services:ping:ping-service
- Static Analysis / Guards
- config/detekt/detekt.yml hinzugefügt
- Leichter Arch-Guard (Frontend) gegen manuelle Authorization-Header vorbereitet
- Doku
- docs/ARCHITECTURE.md (Struktur, Mapping, Next Steps) ergänzt
- docs/adr/README.md angelegt
BREAKING CHANGES:
- Makefile komplett entfernt (bitte direkt `docker compose` verwenden)
- ENV-Quelle ist jetzt docker/.env (statt config/.env oder Root)
- Compose-Datei unter docker/docker-compose.yaml (nicht mehr compose.yaml im Repo-Root)
Verifikation (lokal):
- ENV anlegen: `cp docker/.env.example docker/.env` (Werte anpassen)
- Compose prüfen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml config`
- Infrastruktur: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle up -d postgres redis keycloak web-app`
- Services bauen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle build api-gateway ping-service --no-cache --progress=plain`
Refs: MP-22 (Epic 2), MP-23 (Epic 3)
* chore(devops)!: Docker-SSoT (.env) konsolidiert, Compose-Mounts ergänzt, Makefile entfernt
- ENV Single Source of Truth
- docker/.env.example neu (inkl. REDIS_PASSWORD, Ports, Build-Overrides)
- config/.env(.example) als DEPRECATED markiert (Verweis auf docker/.env[.example])
- Docker Compose vereinheitlicht (docker/docker-compose.yaml)
- Postgres: zentralen postgresql.conf mounten (../config/postgres/postgresql.conf)
und Start mit -c config_file=/etc/postgresql/postgresql.conf
- Redis: zentralen redis.conf mounten (../config/redis/redis.conf)
und Start via "redis-server … ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"
- Web-Nginx: ../config/nginx/nginx.prod.conf → /etc/nginx/nginx.conf (ro)
- Monitoring: Prometheus/Grafana nutzen ../config/monitoring/* als SSoT
- Frontend/DI/Network (MP-23 Grundlage)
- :frontend:core:network Modul mit Koin `apiClient` (Ktor + JSON/Retry/Timeout/Logging)
- Plattform-Basis-URL-Auflösung (JVM: ENV API_BASE_URL; JS: globalThis.API_BASE_URL / Same-Origin)
- Web index.html setzt API_BASE_URL (Query `?apiBaseUrl=…` > Same-Origin > Fallback)
- Build/Gradle & Module-Refs
- settings.gradle.kts: neue Frontend-/Backend-Pfade bereits inkludiert
- Features/Shell: Abhängigkeiten auf :frontend:shared / :frontend:core:* angepasst
- Ping-API-Refs auf :backend:services:ping:ping-api vereinheitlicht
- Dockerfiles angepasst
- backend/infrastructure/gateway/Dockerfile → Tasks/Pfade auf :backend:gateway
- backend/services/ping/Dockerfile → Tasks/Pfade auf :backend:services:ping:ping-service
- Static Analysis / Guards
- config/detekt/detekt.yml hinzugefügt
- Leichter Arch-Guard (Frontend) gegen manuelle Authorization-Header vorbereitet
- Doku
- docs/ARCHITECTURE.md (Struktur, Mapping, Next Steps) ergänzt
- docs/adr/README.md angelegt
BREAKING CHANGES:
- Makefile komplett entfernt (bitte direkt `docker compose` verwenden)
- ENV-Quelle ist jetzt docker/.env (statt config/.env oder Root)
- Compose-Datei unter docker/docker-compose.yaml (nicht mehr compose.yaml im Repo-Root)
Verifikation (lokal):
- ENV anlegen: `cp docker/.env.example docker/.env` (Werte anpassen)
- Compose prüfen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml config`
- Infrastruktur: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle up -d postgres redis keycloak web-app`
- Services bauen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle build api-gateway ping-service --no-cache --progress=plain`
Refs: MP-22 (Epic 2), MP-23 (Epic 3)
* chore(devops)!: Docker-SSoT (.env) konsolidiert, Compose-Mounts ergänzt, Makefile entfernt
- ENV Single Source of Truth
- docker/.env.example neu (inkl. REDIS_PASSWORD, Ports, Build-Overrides)
- config/.env(.example) als DEPRECATED markiert (Verweis auf docker/.env[.example])
- Docker Compose vereinheitlicht (docker/docker-compose.yaml)
- Postgres: zentralen postgresql.conf mounten (../config/postgres/postgresql.conf)
und Start mit -c config_file=/etc/postgresql/postgresql.conf
- Redis: zentralen redis.conf mounten (../config/redis/redis.conf)
und Start via "redis-server … ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"
- Web-Nginx: ../config/nginx/nginx.prod.conf → /etc/nginx/nginx.conf (ro)
- Monitoring: Prometheus/Grafana nutzen ../config/monitoring/* als SSoT
- Frontend/DI/Network (MP-23 Grundlage)
- :frontend:core:network Modul mit Koin `apiClient` (Ktor + JSON/Retry/Timeout/Logging)
- Plattform-Basis-URL-Auflösung (JVM: ENV API_BASE_URL; JS: globalThis.API_BASE_URL / Same-Origin)
- Web index.html setzt API_BASE_URL (Query `?apiBaseUrl=…` > Same-Origin > Fallback)
- Build/Gradle & Module-Refs
- settings.gradle.kts: neue Frontend-/Backend-Pfade bereits inkludiert
- Features/Shell: Abhängigkeiten auf :frontend:shared / :frontend:core:* angepasst
- Ping-API-Refs auf :backend:services:ping:ping-api vereinheitlicht
- Dockerfiles angepasst
- backend/infrastructure/gateway/Dockerfile → Tasks/Pfade auf :backend:gateway
- backend/services/ping/Dockerfile → Tasks/Pfade auf :backend:services:ping:ping-service
- Static Analysis / Guards
- config/detekt/detekt.yml hinzugefügt
- Leichter Arch-Guard (Frontend) gegen manuelle Authorization-Header vorbereitet
- Doku
- docs/ARCHITECTURE.md (Struktur, Mapping, Next Steps) ergänzt
- docs/adr/README.md angelegt
BREAKING CHANGES:
- Makefile komplett entfernt (bitte direkt `docker compose` verwenden)
- ENV-Quelle ist jetzt docker/.env (statt config/.env oder Root)
- Compose-Datei unter docker/docker-compose.yaml (nicht mehr compose.yaml im Repo-Root)
Verifikation (lokal):
- ENV anlegen: `cp docker/.env.example docker/.env` (Werte anpassen)
- Compose prüfen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml config`
- Infrastruktur: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle up -d postgres redis keycloak web-app`
- Services bauen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle build api-gateway ping-service --no-cache --progress=plain`
Refs: MP-22 (Epic 2), MP-23 (Epic 3)
* chore(ci): Workflows an Docker-SSoT & neue Struktur angepasst, minimaler SSoT-Guard
- ssot-guard.yml: Option B (minimal) → `docker compose -f docker/docker-compose.yaml config` als Lint
- integration-tests.yml: `./gradlew staticAnalysis` vor Integrationstests
- docs-kdoc-sync.yml: Dokka-Task Fallback (dokkaGfmAll || dokkaGfm), YouTrack-Sync nur wenn Script vorhanden
- deploy-proxmox.yml: Compose-Pfade auf docker/docker-compose.yaml + `--env-file docker/.env`; Build/Test Schritte vereinheitlicht
- ci-main.yml: SSoT-Skripte per `if: hashFiles(...)` guarded, Compose-Lint Fallback; OpenAPI‑Pfad → backend/gateway; ADR‑Pfade → docs/adr/**; `staticAnalysis` in Build integriert
- youtrack-sync.yml: unverändert (funktional)
Refs: MP-22, MP-23
* chore(ci): Workflows an Docker-SSoT & neue Struktur angepasst, minimaler SSoT-Guard
- ssot-guard.yml: Option B (minimal) → `docker compose -f docker/docker-compose.yaml config` als Lint
- integration-tests.yml: `./gradlew staticAnalysis` vor Integrationstests
- docs-kdoc-sync.yml: Dokka-Task Fallback (dokkaGfmAll || dokkaGfm), YouTrack-Sync nur wenn Script vorhanden
- deploy-proxmox.yml: Compose-Pfade auf docker/docker-compose.yaml + `--env-file docker/.env`; Build/Test Schritte vereinheitlicht
- ci-main.yml: SSoT-Skripte per `if: hashFiles(...)` guarded, Compose-Lint Fallback; OpenAPI‑Pfad → backend/gateway; ADR‑Pfade → docs/adr/**; `staticAnalysis` in Build integriert
- youtrack-sync.yml: unverändert (funktional)
Refs: MP-22, MP-23
* fix(ci): create .env from example before validating compose config
* fix(ci): update ssot-guard filename (.yaml) and sync workflow state
* fixing
* fix(webpack): correct sql.js fallback configuration for webpack 5
This commit is contained in:
+59
@@ -0,0 +1,59 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.SparteE // Optional, falls Altersklassen stark spartenspezifisch sind
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Definiert eine spezifische Altersklasse für Teilnehmer (Reiter, Fahrer, Voltigierer)
|
||||
* oder ggf. auch für Pferde, basierend auf den Vorgaben der ÖTO oder anderer Regelwerke.
|
||||
*
|
||||
* Beispiele: "Jugend U16", "Junioren U18", "Junge Reiter U21", "Allgemeine Klasse",
|
||||
* "Pony Jugend U14", "Senioren Ü40".
|
||||
* Diese Definitionen dienen zur Überprüfung von Teilnahmeberechtigungen in Bewerben und Abteilungen.
|
||||
*
|
||||
* @property altersklasseId Eindeutiger interner Identifikator für diese Altersklassendefinition (UUID).
|
||||
* @property altersklasseCode Ein eindeutiges Kürzel oder Code für die Altersklasse
|
||||
* (z.B. "JGD_U16", "JUN_U18", "YR_U21", "AK", "PONY_U14"). Dient als fachlicher Schlüssel.
|
||||
* @property bezeichnung Die offizielle oder allgemein verständliche Bezeichnung der Altersklasse.
|
||||
* @property minAlter Das Mindestalter (Jahre, inklusive) für diese Altersklasse. `null`, wenn es keine Untergrenze gibt.
|
||||
* @property maxAlter Das Höchstalter (Jahre, inklusive) für diese Altersklasse. `null`, wenn es keine Obergrenze gibt.
|
||||
* @property stichtagRegelText Eine Beschreibung der Regel für den Stichtag zur Altersberechnung
|
||||
* (z.B. "31.12. des laufenden Kalenderjahres", "Geburtstag im laufenden Jahr").
|
||||
* @property sparteFilter Optionale Angabe, ob diese Altersklassendefinition nur für eine spezifische Sparte gilt.
|
||||
* @property geschlechtFilter Optionaler Filter für das Geschlecht ('M', 'W'), falls die Altersklasse geschlechtsspezifisch ist.
|
||||
* `null` bedeutet für alle Geschlechter gültig.
|
||||
* @property oetoRegelReferenzId Optionale Verknüpfung zu einer spezifischen Regel in der `OETORegelReferenz`-Tabelle,
|
||||
* die diese Altersklasse definiert.
|
||||
* @property istAktiv Gibt an, ob diese Altersklassendefinition aktuell im System verwendet werden kann.
|
||||
* @property createdAt Zeitstempel der Erstellung dieses Datensatzes.
|
||||
* @property updatedAt Zeitstempel der letzten Aktualisierung dieses Datensatzes.
|
||||
*/
|
||||
@Serializable
|
||||
data class AltersklasseDefinition(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val altersklasseId: Uuid = Uuid.random(), // Interner Primärschlüssel
|
||||
|
||||
var altersklasseCode: String, // Fachlicher PK, z.B. "JGD_U16"
|
||||
var bezeichnung: String,
|
||||
var minAlter: Int? = null,
|
||||
var maxAlter: Int? = null,
|
||||
var stichtagRegelText: String? = "31.12. des laufenden Kalenderjahres", // Typischer Default
|
||||
var sparteFilter: SparteE? = null, // Ist diese Definition spartenspezifisch?
|
||||
var geschlechtFilter: Char? = null, // 'M', 'W', oder null für beide
|
||||
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var oetoRegelReferenzId: Uuid? = null, // FK zu OETORegelReferenz.oetoRegelReferenzId
|
||||
|
||||
var istAktiv: Boolean = true,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
)
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Definiert ein Bundesland oder eine vergleichbare subnationale Verwaltungseinheit.
|
||||
*
|
||||
* Diese Entität ist primär für die österreichischen Bundesländer mit ihren OEPS-spezifischen
|
||||
* Codes gedacht, kann aber auch für Bundesländer/Regionen anderer Nationen erweitert werden.
|
||||
*
|
||||
* @property bundeslandId Eindeutiger interner Identifikator für dieses Bundesland (UUID).
|
||||
* @property landId Fremdschlüssel zur `LandDefinition`, dem dieses Bundesland angehört.
|
||||
* @property oepsCode Der 2-stellige numerische OEPS-Code für österreichische Bundesländer
|
||||
* (z.B. "01" für Wien, "02" für Niederösterreich). Sollte eindeutig sein für Land "Österreich".
|
||||
* @property iso3166_2_Code Optionaler offizieller ISO 3166-2 Code für das Bundesland
|
||||
* (z.B. "AT-1" für Burgenland, "DE-BY" für Bayern).
|
||||
* @property name Der offizielle Name des Bundeslandes.
|
||||
* @property kuerzel Ein gängiges Kürzel für das Bundesland (z.B. "NÖ", "W", "STMK").
|
||||
* @property wappenUrl Optionaler URL-Pfad zu einer Bilddatei des Bundeslandwappens.
|
||||
* @property istAktiv Gibt an, ob dieses Bundesland aktuell im System ausgewählt/verwendet werden kann.
|
||||
* @property sortierReihenfolge Optionale Zahl zur Steuerung der Sortierreihenfolge in Auswahllisten.
|
||||
* @property createdAt Zeitstempel der Erstellung dieses Datensatzes.
|
||||
* @property updatedAt Zeitstempel der letzten Aktualisierung dieses Datensatzes.
|
||||
*/
|
||||
@Serializable
|
||||
data class BundeslandDefinition(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val bundeslandId: Uuid = Uuid.random(),
|
||||
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var landId: Uuid, // FK zu LandDefinition.landId
|
||||
|
||||
var oepsCode: String?, // z.B. "01", "02", ... für Österreich; eindeutig pro landId = Österreich
|
||||
var iso3166_2_Code: String?, // z.B. "AT-1", "DE-BY"; Eindeutig global oder pro Land?
|
||||
var name: String, // z.B. "Niederösterreich", "Bayern"
|
||||
var kuerzel: String? = null, // z.B. "NÖ", "BY"
|
||||
var wappenUrl: String? = null,
|
||||
var istAktiv: Boolean = true,
|
||||
var sortierReihenfolge: Int? = null,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
)
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Definiert ein Land/eine Nation mit seinen offiziellen Codes und Bezeichnungen.
|
||||
*
|
||||
* Diese Entität dient als zentrale Referenz für Länder, die im System für
|
||||
* Nationalitäten von Personen, Vereinen oder für internationale Turniere relevant sind.
|
||||
*
|
||||
* @property landId Eindeutiger interner Identifikator für dieses Land (UUID).
|
||||
* @property isoAlpha2Code Der 2-stellige ISO 3166-1 Alpha-2 Code des Landes (z.B. "AT", "DE"). Sollte eindeutig sein.
|
||||
* @property isoAlpha3Code Der 3-stellige ISO 3166-1 Alpha-3 Code des Landes (z.B. "AUT", "DEU"). Sollte eindeutig sein.
|
||||
* @property isoNumerischerCode Optionaler 3-stelliger numerischer ISO 3166-1 Code des Landes (z.B. "040" für Österreich).
|
||||
* @property nameDeutsch Der offizielle deutsche Name des Landes.
|
||||
* @property nameEnglisch Der offizielle englische Name des Landes.
|
||||
* @property wappenUrl Optionaler URL-Pfad zu einer Bilddatei des Länderwappens oder der Flagge.
|
||||
* @property istEuMitglied Gibt an, ob das Land Mitglied der Europäischen Union ist.
|
||||
* @property istEwrMitglied Gibt an, ob das Land Mitglied des Europäischen Wirtschaftsraums ist.
|
||||
* @property istAktiv Gibt an, ob dieses Land aktuell im System ausgewählt/verwendet werden kann.
|
||||
* @property sortierReihenfolge Optionale Zahl zur Steuerung der Sortierreihenfolge in Auswahllisten.
|
||||
* @property createdAt Zeitstempel der Erstellung dieses Datensatzes.
|
||||
* @property updatedAt Zeitstempel der letzten Aktualisierung dieses Datensatzes.
|
||||
*/
|
||||
@Serializable
|
||||
data class LandDefinition(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val landId: Uuid = Uuid.random(),
|
||||
|
||||
var isoAlpha2Code: String, // z.B. "AT" → Fachlicher PK oder Unique Constraint
|
||||
var isoAlpha3Code: String, // z.B. "AUT" -> Unique Constraint
|
||||
var isoNumerischerCode: String? = null, // z.B. "040"
|
||||
var nameDeutsch: String, // z.B. "Österreich"
|
||||
var nameEnglisch: String? = null, // z.B. "Austria"
|
||||
var wappenUrl: String? = null,
|
||||
var istEuMitglied: Boolean? = null,
|
||||
var istEwrMitglied: Boolean? = null, // Europäischer Wirtschaftsraum
|
||||
var istAktiv: Boolean = true,
|
||||
var sortierReihenfolge: Int? = null,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
)
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.PlatzTypE
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Definiert einen Turnierplatz oder eine Wettkampfstätte.
|
||||
*
|
||||
* Diese Entität repräsentiert die verschiedenen Plätze und Arenen, die bei Turnieren
|
||||
* für verschiedene Disziplinen verwendet werden können.
|
||||
*
|
||||
* @property id Eindeutiger interner Identifikator für diesen Platz (UUID).
|
||||
* @property turnierId Fremdschlüssel zum Turnier, zu dem dieser Platz gehört.
|
||||
* @property name Der Name oder die Bezeichnung des Platzes (z.B. "Hauptplatz", "Dressurplatz A").
|
||||
* @property dimension Die Abmessungen des Platzes (z.B. "20x60m", "20x40m").
|
||||
* @property boden Die Art des Bodenbelags (z.B. "Sand", "Gras", "Kunststoff").
|
||||
* @property typ Der Typ des Platzes (siehe PlatzTypE enum).
|
||||
* @property istAktiv Gibt an, ob dieser Platz aktuell verwendet werden kann.
|
||||
* @property sortierReihenfolge Optionale Zahl zur Steuerung der Sortierreihenfolge.
|
||||
* @property createdAt Zeitstempel der Erstellung dieses Datensatzes.
|
||||
* @property updatedAt Zeitstempel der letzten Aktualisierung dieses Datensatzes.
|
||||
*/
|
||||
@Serializable
|
||||
data class Platz(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val id: Uuid = Uuid.random(),
|
||||
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var turnierId: Uuid,
|
||||
|
||||
var name: String,
|
||||
var dimension: String? = null,
|
||||
var boden: String? = null,
|
||||
var typ: PlatzTypE,
|
||||
var istAktiv: Boolean = true,
|
||||
var sortierReihenfolge: Int? = null,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
)
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.AltersklasseDefinition
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for AltersklasseDefinition (Age Class) domain operations.
|
||||
*
|
||||
* This interface defines the contract for age class data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface AltersklasseRepository {
|
||||
|
||||
/**
|
||||
* Finds an age class by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the age class
|
||||
* @return The age class if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): AltersklasseDefinition?
|
||||
|
||||
/**
|
||||
* Finds an age class by its code.
|
||||
*
|
||||
* @param altersklasseCode The age class code (e.g., "JGD_U16", "JUN_U18")
|
||||
* @return The age class if found, null otherwise
|
||||
*/
|
||||
suspend fun findByCode(altersklasseCode: String): AltersklasseDefinition?
|
||||
|
||||
/**
|
||||
* Finds age classes by name (partial match).
|
||||
*
|
||||
* @param searchTerm The search term to match against age class names
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching age classes
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds all active age classes.
|
||||
*
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @param geschlechtFilter Optional filter by gender ('M', 'W')
|
||||
* @return List of active age classes
|
||||
*/
|
||||
suspend fun findAllActive(sparteFilter: SparteE? = null, geschlechtFilter: Char? = null): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes applicable for a specific age.
|
||||
*
|
||||
* @param age The age to check
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @param geschlechtFilter Optional filter by gender ('M', 'W')
|
||||
* @return List of applicable age classes
|
||||
*/
|
||||
suspend fun findApplicableForAge(age: Int, sparteFilter: SparteE? = null, geschlechtFilter: Char? = null): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by sport type.
|
||||
*
|
||||
* @param sparte The sport type
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes for the sport type
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by gender filter.
|
||||
*
|
||||
* @param geschlecht The gender ('M', 'W')
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes for the gender
|
||||
*/
|
||||
suspend fun findByGeschlecht(geschlecht: Char, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by age range.
|
||||
*
|
||||
* @param minAge Minimum age (inclusive)
|
||||
* @param maxAge Maximum age (inclusive)
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes within the age range
|
||||
*/
|
||||
suspend fun findByAgeRange(minAge: Int?, maxAge: Int?, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by OETO rule reference.
|
||||
*
|
||||
* @param oetoRegelReferenzId The OETO rule reference ID
|
||||
* @return List of age classes linked to the rule
|
||||
*/
|
||||
suspend fun findByOetoRegelReferenz(oetoRegelReferenzId: Uuid): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Saves an age class (create or update).
|
||||
*
|
||||
* @param altersklasse The age class to save
|
||||
* @return The saved age class with updated timestamps
|
||||
*/
|
||||
suspend fun save(altersklasse: AltersklasseDefinition): AltersklasseDefinition
|
||||
|
||||
/**
|
||||
* Deletes an age class by ID.
|
||||
*
|
||||
* @param id The unique identifier of the age class to delete
|
||||
* @return true if the age class was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if an age class with the given code exists.
|
||||
*
|
||||
* @param altersklasseCode The age class code to check
|
||||
* @return true if an age class with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByCode(altersklasseCode: String): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active age classes.
|
||||
*
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @return The total count of active age classes
|
||||
*/
|
||||
suspend fun countActive(sparteFilter: SparteE? = null): Long
|
||||
|
||||
/**
|
||||
* Validates if a person with given age and gender can participate in an age class.
|
||||
*
|
||||
* @param altersklasseId The age class ID
|
||||
* @param age The person's age
|
||||
* @param geschlecht The person's gender ('M', 'W')
|
||||
* @return true if the person can participate, false otherwise
|
||||
*/
|
||||
suspend fun isEligible(altersklasseId: Uuid, age: Int, geschlecht: Char): Boolean
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.masterdata.domain.model.BundeslandDefinition
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for BundeslandDefinition (Federal State) domain operations.
|
||||
*
|
||||
* This interface defines the contract for federal state data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface BundeslandRepository {
|
||||
|
||||
/**
|
||||
* Finds a federal state by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the federal state
|
||||
* @return The federal state if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): BundeslandDefinition?
|
||||
|
||||
/**
|
||||
* Finds a federal state by its OEPS code.
|
||||
*
|
||||
* @param oepsCode The OEPS code (e.g., "01", "02")
|
||||
* @param landId The country ID to search within
|
||||
* @return The federal state if found, null otherwise
|
||||
*/
|
||||
suspend fun findByOepsCode(oepsCode: String, landId: Uuid): BundeslandDefinition?
|
||||
|
||||
/**
|
||||
* Finds a federal state by its ISO 3166-2 code.
|
||||
*
|
||||
* @param iso3166_2_Code The ISO 3166-2 code (e.g., "AT-1", "DE-BY")
|
||||
* @return The federal state if found, null otherwise
|
||||
*/
|
||||
suspend fun findByIso3166_2_Code(iso3166_2_Code: String): BundeslandDefinition?
|
||||
|
||||
/**
|
||||
* Finds all federal states for a specific country.
|
||||
*
|
||||
* @param landId The country ID
|
||||
* @param activeOnly Whether to return only active federal states
|
||||
* @param orderBySortierung Whether to order by sortierReihenfolge field
|
||||
* @return List of federal states for the country
|
||||
*/
|
||||
suspend fun findByCountry(landId: Uuid, activeOnly: Boolean = true, orderBySortierung: Boolean = true): List<BundeslandDefinition>
|
||||
|
||||
/**
|
||||
* Finds federal states by name (partial match).
|
||||
*
|
||||
* @param searchTerm The search term to match against federal state names
|
||||
* @param landId Optional country ID to limit search
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching federal states
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, landId: Uuid? = null, limit: Int = 50): List<BundeslandDefinition>
|
||||
|
||||
/**
|
||||
* Finds all active federal states.
|
||||
*
|
||||
* @param orderBySortierung Whether to order by sortierReihenfolge field
|
||||
* @return List of active federal states
|
||||
*/
|
||||
suspend fun findAllActive(orderBySortierung: Boolean = true): List<BundeslandDefinition>
|
||||
|
||||
/**
|
||||
* Saves a federal state (create or update).
|
||||
*
|
||||
* @param bundesland The federal state to save
|
||||
* @return The saved federal state with updated timestamps
|
||||
*/
|
||||
suspend fun save(bundesland: BundeslandDefinition): BundeslandDefinition
|
||||
|
||||
/**
|
||||
* Deletes a federal state by ID.
|
||||
*
|
||||
* @param id The unique identifier of the federal state to delete
|
||||
* @return true if the federal state was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a federal state with the given OEPS code exists for a country.
|
||||
*
|
||||
* @param oepsCode The OEPS code to check
|
||||
* @param landId The country ID
|
||||
* @return true if a federal state with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByOepsCode(oepsCode: String, landId: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a federal state with the given ISO 3166-2 code exists.
|
||||
*
|
||||
* @param iso3166_2_Code The ISO 3166-2 code to check
|
||||
* @return true if a federal state with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByIso3166_2_Code(iso3166_2_Code: String): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active federal states for a country.
|
||||
*
|
||||
* @param landId The country ID
|
||||
* @return The total count of active federal states
|
||||
*/
|
||||
suspend fun countActiveByCountry(landId: Uuid): Long
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.masterdata.domain.model.LandDefinition
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for LandDefinition (Country) domain operations.
|
||||
*
|
||||
* This interface defines the contract for country data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface LandRepository {
|
||||
|
||||
/**
|
||||
* Finds a country by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the country
|
||||
* @return The country if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): LandDefinition?
|
||||
|
||||
/**
|
||||
* Finds a country by its ISO Alpha-2 code.
|
||||
*
|
||||
* @param isoAlpha2Code The 2-letter ISO code (e.g., "AT", "DE")
|
||||
* @return The country if found, null otherwise
|
||||
*/
|
||||
suspend fun findByIsoAlpha2Code(isoAlpha2Code: String): LandDefinition?
|
||||
|
||||
/**
|
||||
* Finds a country by its ISO Alpha-3 code.
|
||||
*
|
||||
* @param isoAlpha3Code The 3-letter ISO code (e.g., "AUT", "DEU")
|
||||
* @return The country if found, null otherwise
|
||||
*/
|
||||
suspend fun findByIsoAlpha3Code(isoAlpha3Code: String): LandDefinition?
|
||||
|
||||
/**
|
||||
* Finds countries by name (partial match on German or English name).
|
||||
*
|
||||
* @param searchTerm The search term to match against country names
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching countries
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<LandDefinition>
|
||||
|
||||
/**
|
||||
* Finds all active countries.
|
||||
*
|
||||
* @param orderBySortierung Whether to order by sortierReihenfolge field
|
||||
* @return List of active countries
|
||||
*/
|
||||
suspend fun findAllActive(orderBySortierung: Boolean = true): List<LandDefinition>
|
||||
|
||||
/**
|
||||
* Finds all EU member countries.
|
||||
*
|
||||
* @return List of EU member countries
|
||||
*/
|
||||
suspend fun findEuMembers(): List<LandDefinition>
|
||||
|
||||
/**
|
||||
* Finds all EWR (European Economic Area) member countries.
|
||||
*
|
||||
* @return List of EWR member countries
|
||||
*/
|
||||
suspend fun findEwrMembers(): List<LandDefinition>
|
||||
|
||||
/**
|
||||
* Saves a country (create or update).
|
||||
*
|
||||
* @param land The country to save
|
||||
* @return The saved country with updated timestamps
|
||||
*/
|
||||
suspend fun save(land: LandDefinition): LandDefinition
|
||||
|
||||
/**
|
||||
* Deletes a country by ID.
|
||||
*
|
||||
* @param id The unique identifier of the country to delete
|
||||
* @return true if the country was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a country with the given ISO Alpha-2 code exists.
|
||||
*
|
||||
* @param isoAlpha2Code The ISO Alpha-2 code to check
|
||||
* @return true if a country with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByIsoAlpha2Code(isoAlpha2Code: String): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a country with the given ISO Alpha-3 code exists.
|
||||
*
|
||||
* @param isoAlpha3Code The ISO Alpha-3 code to check
|
||||
* @return true if a country with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByIsoAlpha3Code(isoAlpha3Code: String): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active countries.
|
||||
*
|
||||
* @return The total count of active countries
|
||||
*/
|
||||
suspend fun countActive(): Long
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.PlatzTypE
|
||||
import at.mocode.masterdata.domain.model.Platz
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for Platz (Venue/Arena) domain operations.
|
||||
*
|
||||
* This interface defines the contract for venue/arena data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface PlatzRepository {
|
||||
|
||||
/**
|
||||
* Finds a venue by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the venue
|
||||
* @return The venue if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): Platz?
|
||||
|
||||
/**
|
||||
* Finds all venues for a specific tournament.
|
||||
*
|
||||
* @param turnierId The tournament ID
|
||||
* @param activeOnly Whether to return only active venues
|
||||
* @param orderBySortierung Whether to order by sortierReihenfolge field
|
||||
* @return List of venues for the tournament
|
||||
*/
|
||||
suspend fun findByTournament(turnierId: Uuid, activeOnly: Boolean = true, orderBySortierung: Boolean = true): List<Platz>
|
||||
|
||||
/**
|
||||
* Finds venues by name (partial match).
|
||||
*
|
||||
* @param searchTerm The search term to match against venue names
|
||||
* @param turnierId Optional tournament ID to limit search
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching venues
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, turnierId: Uuid? = null, limit: Int = 50): List<Platz>
|
||||
|
||||
/**
|
||||
* Finds venues by type.
|
||||
*
|
||||
* @param typ The venue type
|
||||
* @param turnierId Optional tournament ID to limit search
|
||||
* @param activeOnly Whether to return only active venues
|
||||
* @return List of venues of the specified type
|
||||
*/
|
||||
suspend fun findByType(typ: PlatzTypE, turnierId: Uuid? = null, activeOnly: Boolean = true): List<Platz>
|
||||
|
||||
/**
|
||||
* Finds venues by ground type.
|
||||
*
|
||||
* @param boden The ground type (e.g., "Sand", "Gras", "Kunststoff")
|
||||
* @param turnierId Optional tournament ID to limit search
|
||||
* @param activeOnly Whether to return only active venues
|
||||
* @return List of venues with the specified ground type
|
||||
*/
|
||||
suspend fun findByGroundType(boden: String, turnierId: Uuid? = null, activeOnly: Boolean = true): List<Platz>
|
||||
|
||||
/**
|
||||
* Finds venues by dimensions.
|
||||
*
|
||||
* @param dimension The venue dimensions (e.g., "20x60m", "20x40m")
|
||||
* @param turnierId Optional tournament ID to limit search
|
||||
* @param activeOnly Whether to return only active venues
|
||||
* @return List of venues with the specified dimensions
|
||||
*/
|
||||
suspend fun findByDimensions(dimension: String, turnierId: Uuid? = null, activeOnly: Boolean = true): List<Platz>
|
||||
|
||||
/**
|
||||
* Finds all active venues.
|
||||
*
|
||||
* @param orderBySortierung Whether to order by sortierReihenfolge field
|
||||
* @return List of active venues
|
||||
*/
|
||||
suspend fun findAllActive(orderBySortierung: Boolean = true): List<Platz>
|
||||
|
||||
/**
|
||||
* Finds venues suitable for a specific discipline based on type and dimensions.
|
||||
*
|
||||
* @param requiredType The required venue type
|
||||
* @param requiredDimensions Optional required dimensions
|
||||
* @param turnierId Optional tournament ID to limit search
|
||||
* @return List of suitable venues
|
||||
*/
|
||||
suspend fun findSuitableForDiscipline(
|
||||
requiredType: PlatzTypE,
|
||||
requiredDimensions: String? = null,
|
||||
turnierId: Uuid? = null
|
||||
): List<Platz>
|
||||
|
||||
/**
|
||||
* Saves a venue (create or update).
|
||||
*
|
||||
* @param platz The venue to save
|
||||
* @return The saved venue with updated timestamps
|
||||
*/
|
||||
suspend fun save(platz: Platz): Platz
|
||||
|
||||
/**
|
||||
* Deletes a venue by ID.
|
||||
*
|
||||
* @param id The unique identifier of the venue to delete
|
||||
* @return true if the venue was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a venue with the given name exists for a tournament.
|
||||
*
|
||||
* @param name The venue name to check
|
||||
* @param turnierId The tournament ID
|
||||
* @return true if a venue with this name exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByNameAndTournament(name: String, turnierId: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active venues for a tournament.
|
||||
*
|
||||
* @param turnierId The tournament ID
|
||||
* @return The total count of active venues
|
||||
*/
|
||||
suspend fun countActiveByTournament(turnierId: Uuid): Long
|
||||
|
||||
/**
|
||||
* Counts venues by type for a tournament.
|
||||
*
|
||||
* @param typ The venue type
|
||||
* @param turnierId The tournament ID
|
||||
* @param activeOnly Whether to count only active venues
|
||||
* @return The count of venues of the specified type
|
||||
*/
|
||||
suspend fun countByTypeAndTournament(typ: PlatzTypE, turnierId: Uuid, activeOnly: Boolean = true): Long
|
||||
|
||||
/**
|
||||
* Finds available venues for a specific time slot (if scheduling is implemented).
|
||||
* This method can be extended when venue scheduling functionality is added.
|
||||
*
|
||||
* @param turnierId The tournament ID
|
||||
* @param startTime The start time (placeholder for future scheduling feature)
|
||||
* @param endTime The end time (placeholder for future scheduling feature)
|
||||
* @return List of available venues (currently returns all active venues)
|
||||
*/
|
||||
suspend fun findAvailableForTimeSlot(turnierId: Uuid, startTime: String? = null, endTime: String? = null): List<Platz>
|
||||
}
|
||||
Reference in New Issue
Block a user