fixing web-app
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
||||
package at.mocode.masterdata.service
|
||||
|
||||
import at.mocode.core.utils.config.AppConfig
|
||||
import at.mocode.core.utils.database.DatabaseFactory
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
/**
|
||||
* Main application class for the Masterdata Service.
|
||||
*
|
||||
* This service provides APIs for managing master data such as countries, regions, and other reference data.
|
||||
*/
|
||||
@SpringBootApplication
|
||||
class MasterdataServiceApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
// 1. Lade die Konfiguration explizit, genau einmal beim Start.
|
||||
val appConfig = AppConfig.load()
|
||||
println("Konfiguration für Umgebung '${appConfig.environment}' geladen.")
|
||||
|
||||
// 2. Initialisiere die Datenbank mit der geladenen Konfiguration.
|
||||
// Flyway-Migrationen werden hier automatisch ausgeführt.
|
||||
DatabaseFactory.init(appConfig.database)
|
||||
println("Datenbank initialisiert und migriert.")
|
||||
|
||||
// 3. Starte die Spring Boot / Ktor Anwendung.
|
||||
// Der appConfig-Wert kann hier an die Anwendung übergeben werden,
|
||||
// um ihn später per Dependency Injection zu nutzen.
|
||||
runApplication<MasterdataServiceApplication>(*args)
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
package at.mocode.masterdata.service.config
|
||||
|
||||
import at.mocode.masterdata.application.usecase.*
|
||||
import at.mocode.masterdata.domain.repository.*
|
||||
import at.mocode.masterdata.infrastructure.persistence.*
|
||||
import at.mocode.masterdata.api.rest.*
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.Profile
|
||||
|
||||
/**
|
||||
* Spring Boot configuration for the Masterdata Service.
|
||||
*
|
||||
* This configuration class sets up all the necessary beans for dependency injection
|
||||
* following the clean architecture pattern with proper separation of concerns.
|
||||
*/
|
||||
@Configuration
|
||||
class MasterdataConfiguration {
|
||||
|
||||
// Repository Implementations
|
||||
@Bean
|
||||
fun landRepository(): LandRepository {
|
||||
return LandRepositoryImpl()
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun bundeslandRepository(): BundeslandRepository {
|
||||
return BundeslandRepositoryImpl()
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun altersklasseRepository(): AltersklasseRepository {
|
||||
return AltersklasseRepositoryImpl()
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun platzRepository(): PlatzRepository {
|
||||
return PlatzRepositoryImpl()
|
||||
}
|
||||
|
||||
// Use Cases - Country/Land
|
||||
@Bean
|
||||
fun getCountryUseCase(landRepository: LandRepository): GetCountryUseCase {
|
||||
return GetCountryUseCase(landRepository)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun createCountryUseCase(landRepository: LandRepository): CreateCountryUseCase {
|
||||
return CreateCountryUseCase(landRepository)
|
||||
}
|
||||
|
||||
// Use Cases - Federal State/Bundesland
|
||||
@Bean
|
||||
fun getBundeslandUseCase(bundeslandRepository: BundeslandRepository): GetBundeslandUseCase {
|
||||
return GetBundeslandUseCase(bundeslandRepository)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun createBundeslandUseCase(bundeslandRepository: BundeslandRepository): CreateBundeslandUseCase {
|
||||
return CreateBundeslandUseCase(bundeslandRepository)
|
||||
}
|
||||
|
||||
// Use Cases - Age Class/Altersklasse
|
||||
@Bean
|
||||
fun getAltersklasseUseCase(altersklasseRepository: AltersklasseRepository): GetAltersklasseUseCase {
|
||||
return GetAltersklasseUseCase(altersklasseRepository)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun createAltersklasseUseCase(altersklasseRepository: AltersklasseRepository): CreateAltersklasseUseCase {
|
||||
return CreateAltersklasseUseCase(altersklasseRepository)
|
||||
}
|
||||
|
||||
// Use Cases - Venue/Platz
|
||||
@Bean
|
||||
fun getPlatzUseCase(platzRepository: PlatzRepository): GetPlatzUseCase {
|
||||
return GetPlatzUseCase(platzRepository)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun createPlatzUseCase(platzRepository: PlatzRepository): CreatePlatzUseCase {
|
||||
return CreatePlatzUseCase(platzRepository)
|
||||
}
|
||||
|
||||
// API Controllers
|
||||
@Bean
|
||||
fun countryController(
|
||||
getCountryUseCase: GetCountryUseCase,
|
||||
createCountryUseCase: CreateCountryUseCase
|
||||
): CountryController {
|
||||
return CountryController(getCountryUseCase, createCountryUseCase)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun bundeslandController(
|
||||
getBundeslandUseCase: GetBundeslandUseCase,
|
||||
createBundeslandUseCase: CreateBundeslandUseCase
|
||||
): BundeslandController {
|
||||
return BundeslandController(getBundeslandUseCase, createBundeslandUseCase)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun altersklasseController(
|
||||
getAltersklasseUseCase: GetAltersklasseUseCase,
|
||||
createAltersklasseUseCase: CreateAltersklasseUseCase
|
||||
): AltersklasseController {
|
||||
return AltersklasseController(getAltersklasseUseCase, createAltersklasseUseCase)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun platzController(
|
||||
getPlatzUseCase: GetPlatzUseCase,
|
||||
createPlatzUseCase: CreatePlatzUseCase
|
||||
): PlatzController {
|
||||
return PlatzController(getPlatzUseCase, createPlatzUseCase)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Database configuration for different environments.
|
||||
*/
|
||||
@Configuration
|
||||
class DatabaseConfiguration {
|
||||
|
||||
/**
|
||||
* Development database configuration.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("dev", "development")
|
||||
class DevelopmentDatabaseConfig {
|
||||
// Development-specific database configuration
|
||||
// This would typically include H2 or local PostgreSQL setup
|
||||
}
|
||||
|
||||
/**
|
||||
* Production database configuration.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("prod", "production")
|
||||
class ProductionDatabaseConfig {
|
||||
// Production-specific database configuration
|
||||
// This would include production PostgreSQL setup with connection pooling
|
||||
}
|
||||
|
||||
/**
|
||||
* Test database configuration.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("test")
|
||||
class TestDatabaseConfig {
|
||||
// Test-specific database configuration
|
||||
// This would typically include in-memory H2 database
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package at.mocode.masterdata.service.config
|
||||
|
||||
import at.mocode.core.utils.database.DatabaseConfig
|
||||
import at.mocode.core.utils.database.DatabaseFactory
|
||||
import at.mocode.masterdata.infrastructure.persistence.LandTable
|
||||
import at.mocode.masterdata.infrastructure.persistence.BundeslandTable
|
||||
import at.mocode.masterdata.infrastructure.persistence.AltersklasseTable
|
||||
import at.mocode.masterdata.infrastructure.persistence.PlatzTable
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.Profile
|
||||
import jakarta.annotation.PostConstruct
|
||||
import jakarta.annotation.PreDestroy
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.jetbrains.exposed.sql.SchemaUtils
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
/**
|
||||
* Database configuration for the Masterdata Service.
|
||||
*
|
||||
* This configuration ensures that Database.connect() is called properly
|
||||
* before any Exposed operations are performed.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("!test")
|
||||
class MasterdataDatabaseConfiguration {
|
||||
|
||||
private val log = LoggerFactory.getLogger(MasterdataDatabaseConfiguration::class.java)
|
||||
|
||||
@PostConstruct
|
||||
fun initializeDatabase() {
|
||||
log.info("Initializing database schema for Masterdata Service...")
|
||||
|
||||
try {
|
||||
// Database connection is already initialized by the gateway
|
||||
// Only initialize the schema for this service
|
||||
transaction {
|
||||
SchemaUtils.createMissingTablesAndColumns(
|
||||
LandTable,
|
||||
BundeslandTable,
|
||||
AltersklasseTable,
|
||||
PlatzTable
|
||||
)
|
||||
log.info("Masterdata database schema initialized successfully")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.error("Failed to initialize database schema", e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
fun closeDatabase() {
|
||||
log.info("Closing database connection for Masterdata Service...")
|
||||
try {
|
||||
DatabaseFactory.close()
|
||||
log.info("Database connection closed successfully")
|
||||
} catch (e: Exception) {
|
||||
log.error("Error closing database connection", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test-specific database configuration.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("test")
|
||||
class MasterdataTestDatabaseConfiguration {
|
||||
|
||||
private val log = LoggerFactory.getLogger(MasterdataTestDatabaseConfiguration::class.java)
|
||||
|
||||
@PostConstruct
|
||||
fun initializeTestDatabase() {
|
||||
log.info("Initializing test database connection for Masterdata Service...")
|
||||
|
||||
try {
|
||||
// Use H2 in-memory database for tests
|
||||
val testConfig = DatabaseConfig(
|
||||
jdbcUrl = "jdbc:h2:mem:masterdata_test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE",
|
||||
username = "sa",
|
||||
password = "",
|
||||
driverClassName = "org.h2.Driver",
|
||||
maxPoolSize = 5,
|
||||
minPoolSize = 1,
|
||||
autoMigrate = true
|
||||
)
|
||||
|
||||
DatabaseFactory.init(testConfig)
|
||||
log.info("Test database connection initialized successfully")
|
||||
|
||||
// Initialize database schema for tests
|
||||
transaction {
|
||||
SchemaUtils.createMissingTablesAndColumns(
|
||||
LandTable,
|
||||
BundeslandTable,
|
||||
AltersklasseTable,
|
||||
PlatzTable
|
||||
)
|
||||
log.info("Test masterdata database schema initialized successfully")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.error("Failed to initialize test database connection", e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
fun closeTestDatabase() {
|
||||
log.info("Closing test database connection for Masterdata Service...")
|
||||
try {
|
||||
DatabaseFactory.close()
|
||||
log.info("Test database connection closed successfully")
|
||||
} catch (e: Exception) {
|
||||
log.error("Error closing test database connection", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
-- Migration V001: Create Land (Country) table
|
||||
-- This migration creates the base table for country master data
|
||||
|
||||
CREATE TABLE IF NOT EXISTS land (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
iso_alpha2_code VARCHAR(2) NOT NULL,
|
||||
iso_alpha3_code VARCHAR(3) NOT NULL,
|
||||
iso_numerischer_code VARCHAR(3),
|
||||
name_deutsch VARCHAR(100) NOT NULL,
|
||||
name_englisch VARCHAR(100),
|
||||
wappen_url VARCHAR(500),
|
||||
ist_eu_mitglied BOOLEAN,
|
||||
ist_ewr_mitglied BOOLEAN,
|
||||
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
|
||||
sortier_reihenfolge INTEGER,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Create unique indexes for ISO codes
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_land_iso_alpha2 ON land(iso_alpha2_code);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_land_iso_alpha3 ON land(iso_alpha3_code);
|
||||
|
||||
-- Create indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_land_aktiv ON land(ist_aktiv);
|
||||
CREATE INDEX IF NOT EXISTS idx_land_sortierung ON land(sortier_reihenfolge);
|
||||
CREATE INDEX IF NOT EXISTS idx_land_eu_mitglied ON land(ist_eu_mitglied);
|
||||
CREATE INDEX IF NOT EXISTS idx_land_ewr_mitglied ON land(ist_ewr_mitglied);
|
||||
|
||||
-- Create index for name searches
|
||||
CREATE INDEX IF NOT EXISTS idx_land_name_deutsch ON land(name_deutsch);
|
||||
CREATE INDEX IF NOT EXISTS idx_land_name_englisch ON land(name_englisch);
|
||||
|
||||
-- Add comments for documentation
|
||||
COMMENT ON TABLE land IS 'Master data table for countries/nations with ISO codes and EU/EWR membership information';
|
||||
COMMENT ON COLUMN land.id IS 'Unique internal identifier (UUID)';
|
||||
COMMENT ON COLUMN land.iso_alpha2_code IS '2-letter ISO 3166-1 Alpha-2 code (e.g., AT, DE)';
|
||||
COMMENT ON COLUMN land.iso_alpha3_code IS '3-letter ISO 3166-1 Alpha-3 code (e.g., AUT, DEU)';
|
||||
COMMENT ON COLUMN land.iso_numerischer_code IS '3-digit ISO 3166-1 numeric code (e.g., 040 for Austria)';
|
||||
COMMENT ON COLUMN land.name_deutsch IS 'Official German name of the country';
|
||||
COMMENT ON COLUMN land.name_englisch IS 'Official English name of the country';
|
||||
COMMENT ON COLUMN land.wappen_url IS 'Optional URL path to country coat of arms or flag image';
|
||||
COMMENT ON COLUMN land.ist_eu_mitglied IS 'Indicates if the country is a member of the European Union';
|
||||
COMMENT ON COLUMN land.ist_ewr_mitglied IS 'Indicates if the country is a member of the European Economic Area';
|
||||
COMMENT ON COLUMN land.ist_aktiv IS 'Indicates if this country is currently active/selectable in the system';
|
||||
COMMENT ON COLUMN land.sortier_reihenfolge IS 'Optional number for controlling sort order in selection lists';
|
||||
COMMENT ON COLUMN land.created_at IS 'Timestamp when this record was created';
|
||||
COMMENT ON COLUMN land.updated_at IS 'Timestamp when this record was last updated';
|
||||
|
||||
-- Insert some initial data for common countries
|
||||
INSERT INTO land (iso_alpha2_code, iso_alpha3_code, iso_numerischer_code, name_deutsch, name_englisch, ist_eu_mitglied, ist_ewr_mitglied, sortier_reihenfolge) VALUES
|
||||
('AT', 'AUT', '040', 'Österreich', 'Austria', true, true, 1),
|
||||
('DE', 'DEU', '276', 'Deutschland', 'Germany', true, true, 2),
|
||||
('CH', 'CHE', '756', 'Schweiz', 'Switzerland', false, false, 3),
|
||||
('IT', 'ITA', '380', 'Italien', 'Italy', true, true, 4),
|
||||
('FR', 'FRA', '250', 'Frankreich', 'France', true, true, 5),
|
||||
('CZ', 'CZE', '203', 'Tschechien', 'Czech Republic', true, true, 6),
|
||||
('SK', 'SVK', '703', 'Slowakei', 'Slovakia', true, true, 7),
|
||||
('SI', 'SVN', '705', 'Slowenien', 'Slovenia', true, true, 8),
|
||||
('HU', 'HUN', '348', 'Ungarn', 'Hungary', true, true, 9),
|
||||
('PL', 'POL', '616', 'Polen', 'Poland', true, true, 10)
|
||||
ON CONFLICT (iso_alpha2_code) DO NOTHING;
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
-- Migration V002: Create Bundesland (Federal State) table
|
||||
-- This migration creates the table for federal states/regions with OEPS and ISO codes
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bundesland (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
land_id UUID NOT NULL REFERENCES land(id) ON DELETE CASCADE,
|
||||
oeps_code VARCHAR(10),
|
||||
iso_3166_2_code VARCHAR(10),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
kuerzel VARCHAR(10),
|
||||
wappen_url VARCHAR(500),
|
||||
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
|
||||
sortier_reihenfolge INTEGER,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Create unique constraints
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_bundesland_oeps_land ON bundesland(oeps_code, land_id) WHERE oeps_code IS NOT NULL;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_bundesland_iso3166_2 ON bundesland(iso_3166_2_code) WHERE iso_3166_2_code IS NOT NULL;
|
||||
|
||||
-- Create indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_bundesland_land_id ON bundesland(land_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_bundesland_aktiv ON bundesland(ist_aktiv);
|
||||
CREATE INDEX IF NOT EXISTS idx_bundesland_sortierung ON bundesland(sortier_reihenfolge);
|
||||
CREATE INDEX IF NOT EXISTS idx_bundesland_name ON bundesland(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_bundesland_land_aktiv ON bundesland(land_id, ist_aktiv);
|
||||
|
||||
-- Add comments for documentation
|
||||
COMMENT ON TABLE bundesland IS 'Master data table for federal states/regions with OEPS and ISO 3166-2 codes';
|
||||
COMMENT ON COLUMN bundesland.id IS 'Unique internal identifier (UUID)';
|
||||
COMMENT ON COLUMN bundesland.land_id IS 'Foreign key reference to the country this federal state belongs to';
|
||||
COMMENT ON COLUMN bundesland.oeps_code IS '2-digit OEPS code for Austrian federal states (e.g., 01 for Vienna, 02 for Lower Austria)';
|
||||
COMMENT ON COLUMN bundesland.iso_3166_2_code IS 'Official ISO 3166-2 code for the federal state (e.g., AT-1 for Burgenland, DE-BY for Bavaria)';
|
||||
COMMENT ON COLUMN bundesland.name IS 'Official name of the federal state';
|
||||
COMMENT ON COLUMN bundesland.kuerzel IS 'Common abbreviation for the federal state (e.g., NÖ, W, STMK)';
|
||||
COMMENT ON COLUMN bundesland.wappen_url IS 'Optional URL path to federal state coat of arms image';
|
||||
COMMENT ON COLUMN bundesland.ist_aktiv IS 'Indicates if this federal state is currently active/selectable in the system';
|
||||
COMMENT ON COLUMN bundesland.sortier_reihenfolge IS 'Optional number for controlling sort order in selection lists';
|
||||
COMMENT ON COLUMN bundesland.created_at IS 'Timestamp when this record was created';
|
||||
COMMENT ON COLUMN bundesland.updated_at IS 'Timestamp when this record was last updated';
|
||||
|
||||
-- Insert Austrian federal states (Bundesländer)
|
||||
-- First, get the Austria country ID
|
||||
DO $$
|
||||
DECLARE
|
||||
austria_id UUID;
|
||||
BEGIN
|
||||
SELECT id INTO austria_id FROM land WHERE iso_alpha2_code = 'AT';
|
||||
|
||||
IF austria_id IS NOT NULL THEN
|
||||
INSERT INTO bundesland (land_id, oeps_code, iso_3166_2_code, name, kuerzel, sortier_reihenfolge) VALUES
|
||||
(austria_id, '01', 'AT-1', 'Burgenland', 'BGLD', 1),
|
||||
(austria_id, '02', 'AT-2', 'Kärnten', 'KTN', 2),
|
||||
(austria_id, '03', 'AT-3', 'Niederösterreich', 'NÖ', 3),
|
||||
(austria_id, '04', 'AT-4', 'Oberösterreich', 'OÖ', 4),
|
||||
(austria_id, '05', 'AT-5', 'Salzburg', 'SBG', 5),
|
||||
(austria_id, '06', 'AT-6', 'Steiermark', 'STMK', 6),
|
||||
(austria_id, '07', 'AT-7', 'Tirol', 'T', 7),
|
||||
(austria_id, '08', 'AT-8', 'Vorarlberg', 'VBG', 8),
|
||||
(austria_id, '09', 'AT-9', 'Wien', 'W', 9)
|
||||
ON CONFLICT DO NOTHING;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Insert German federal states (Bundesländer)
|
||||
DO $$
|
||||
DECLARE
|
||||
germany_id UUID;
|
||||
BEGIN
|
||||
SELECT id INTO germany_id FROM land WHERE iso_alpha2_code = 'DE';
|
||||
|
||||
IF germany_id IS NOT NULL THEN
|
||||
INSERT INTO bundesland (land_id, iso_3166_2_code, name, kuerzel, sortier_reihenfolge) VALUES
|
||||
(germany_id, 'DE-BW', 'Baden-Württemberg', 'BW', 1),
|
||||
(germany_id, 'DE-BY', 'Bayern', 'BY', 2),
|
||||
(germany_id, 'DE-BE', 'Berlin', 'BE', 3),
|
||||
(germany_id, 'DE-BB', 'Brandenburg', 'BB', 4),
|
||||
(germany_id, 'DE-HB', 'Bremen', 'HB', 5),
|
||||
(germany_id, 'DE-HH', 'Hamburg', 'HH', 6),
|
||||
(germany_id, 'DE-HE', 'Hessen', 'HE', 7),
|
||||
(germany_id, 'DE-MV', 'Mecklenburg-Vorpommern', 'MV', 8),
|
||||
(germany_id, 'DE-NI', 'Niedersachsen', 'NI', 9),
|
||||
(germany_id, 'DE-NW', 'Nordrhein-Westfalen', 'NW', 10),
|
||||
(germany_id, 'DE-RP', 'Rheinland-Pfalz', 'RP', 11),
|
||||
(germany_id, 'DE-SL', 'Saarland', 'SL', 12),
|
||||
(germany_id, 'DE-SN', 'Sachsen', 'SN', 13),
|
||||
(germany_id, 'DE-ST', 'Sachsen-Anhalt', 'ST', 14),
|
||||
(germany_id, 'DE-SH', 'Schleswig-Holstein', 'SH', 15),
|
||||
(germany_id, 'DE-TH', 'Thüringen', 'TH', 16)
|
||||
ON CONFLICT DO NOTHING;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Insert Swiss cantons
|
||||
DO $$
|
||||
DECLARE
|
||||
switzerland_id UUID;
|
||||
BEGIN
|
||||
SELECT id INTO switzerland_id FROM land WHERE iso_alpha2_code = 'CH';
|
||||
|
||||
IF switzerland_id IS NOT NULL THEN
|
||||
INSERT INTO bundesland (land_id, iso_3166_2_code, name, kuerzel, sortier_reihenfolge) VALUES
|
||||
(switzerland_id, 'CH-AG', 'Aargau', 'AG', 1),
|
||||
(switzerland_id, 'CH-AI', 'Appenzell Innerrhoden', 'AI', 2),
|
||||
(switzerland_id, 'CH-AR', 'Appenzell Ausserrhoden', 'AR', 3),
|
||||
(switzerland_id, 'CH-BE', 'Bern', 'BE', 4),
|
||||
(switzerland_id, 'CH-BL', 'Basel-Landschaft', 'BL', 5),
|
||||
(switzerland_id, 'CH-BS', 'Basel-Stadt', 'BS', 6),
|
||||
(switzerland_id, 'CH-FR', 'Freiburg', 'FR', 7),
|
||||
(switzerland_id, 'CH-GE', 'Genf', 'GE', 8),
|
||||
(switzerland_id, 'CH-GL', 'Glarus', 'GL', 9),
|
||||
(switzerland_id, 'CH-GR', 'Graubünden', 'GR', 10),
|
||||
(switzerland_id, 'CH-JU', 'Jura', 'JU', 11),
|
||||
(switzerland_id, 'CH-LU', 'Luzern', 'LU', 12),
|
||||
(switzerland_id, 'CH-NE', 'Neuenburg', 'NE', 13),
|
||||
(switzerland_id, 'CH-NW', 'Nidwalden', 'NW', 14),
|
||||
(switzerland_id, 'CH-OW', 'Obwalden', 'OW', 15),
|
||||
(switzerland_id, 'CH-SG', 'St. Gallen', 'SG', 16),
|
||||
(switzerland_id, 'CH-SH', 'Schaffhausen', 'SH', 17),
|
||||
(switzerland_id, 'CH-SO', 'Solothurn', 'SO', 18),
|
||||
(switzerland_id, 'CH-SZ', 'Schwyz', 'SZ', 19),
|
||||
(switzerland_id, 'CH-TG', 'Thurgau', 'TG', 20),
|
||||
(switzerland_id, 'CH-TI', 'Tessin', 'TI', 21),
|
||||
(switzerland_id, 'CH-UR', 'Uri', 'UR', 22),
|
||||
(switzerland_id, 'CH-VD', 'Waadt', 'VD', 23),
|
||||
(switzerland_id, 'CH-VS', 'Wallis', 'VS', 24),
|
||||
(switzerland_id, 'CH-ZG', 'Zug', 'ZG', 25),
|
||||
(switzerland_id, 'CH-ZH', 'Zürich', 'ZH', 26)
|
||||
ON CONFLICT DO NOTHING;
|
||||
END IF;
|
||||
END $$;
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
-- Migration V003: Create Altersklasse (Age Class) table
|
||||
-- This migration creates the table for age class definitions with sport and gender filters
|
||||
|
||||
CREATE TABLE IF NOT EXISTS altersklasse (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
altersklasse_code VARCHAR(50) NOT NULL UNIQUE,
|
||||
bezeichnung VARCHAR(200) NOT NULL,
|
||||
min_alter INTEGER,
|
||||
max_alter INTEGER,
|
||||
stichtag_regel_text VARCHAR(500),
|
||||
sparte_filter VARCHAR(50),
|
||||
geschlecht_filter CHAR(1),
|
||||
oeto_regel_referenz_id UUID,
|
||||
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT chk_altersklasse_geschlecht CHECK (geschlecht_filter IN ('M', 'W') OR geschlecht_filter IS NULL),
|
||||
CONSTRAINT chk_altersklasse_alter_range CHECK (min_alter IS NULL OR max_alter IS NULL OR min_alter <= max_alter),
|
||||
CONSTRAINT chk_altersklasse_min_alter CHECK (min_alter IS NULL OR min_alter >= 0),
|
||||
CONSTRAINT chk_altersklasse_max_alter CHECK (max_alter IS NULL OR max_alter >= 0)
|
||||
);
|
||||
|
||||
-- Create indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_altersklasse_aktiv ON altersklasse(ist_aktiv);
|
||||
CREATE INDEX IF NOT EXISTS idx_altersklasse_sparte ON altersklasse(sparte_filter);
|
||||
CREATE INDEX IF NOT EXISTS idx_altersklasse_geschlecht ON altersklasse(geschlecht_filter);
|
||||
CREATE INDEX IF NOT EXISTS idx_altersklasse_alter ON altersklasse(min_alter, max_alter);
|
||||
CREATE INDEX IF NOT EXISTS idx_altersklasse_bezeichnung ON altersklasse(bezeichnung);
|
||||
CREATE INDEX IF NOT EXISTS idx_altersklasse_code ON altersklasse(altersklasse_code);
|
||||
|
||||
-- Add comments for documentation
|
||||
COMMENT ON TABLE altersklasse IS 'Master data table for age class definitions with eligibility rules for participants';
|
||||
COMMENT ON COLUMN altersklasse.id IS 'Unique internal identifier (UUID)';
|
||||
COMMENT ON COLUMN altersklasse.altersklasse_code IS 'Unique code for the age class (e.g., JGD_U16, JUN_U18, YR_U21, AK)';
|
||||
COMMENT ON COLUMN altersklasse.bezeichnung IS 'Official or commonly understood designation of the age class';
|
||||
COMMENT ON COLUMN altersklasse.min_alter IS 'Minimum age (years, inclusive) for this age class. NULL if no lower limit';
|
||||
COMMENT ON COLUMN altersklasse.max_alter IS 'Maximum age (years, inclusive) for this age class. NULL if no upper limit';
|
||||
COMMENT ON COLUMN altersklasse.stichtag_regel_text IS 'Description of the rule for the reference date for age calculation';
|
||||
COMMENT ON COLUMN altersklasse.sparte_filter IS 'Optional specification if this age class definition only applies to a specific sport';
|
||||
COMMENT ON COLUMN altersklasse.geschlecht_filter IS 'Optional filter for gender (M, W) if the age class is gender-specific. NULL means valid for all genders';
|
||||
COMMENT ON COLUMN altersklasse.oeto_regel_referenz_id IS 'Optional link to a specific rule in the OETO rule reference table';
|
||||
COMMENT ON COLUMN altersklasse.ist_aktiv IS 'Indicates if this age class definition can currently be used in the system';
|
||||
COMMENT ON COLUMN altersklasse.created_at IS 'Timestamp when this record was created';
|
||||
COMMENT ON COLUMN altersklasse.updated_at IS 'Timestamp when this record was last updated';
|
||||
|
||||
-- Insert common age class definitions for equestrian sports
|
||||
INSERT INTO altersklasse (altersklasse_code, bezeichnung, min_alter, max_alter, stichtag_regel_text, sparte_filter, geschlecht_filter) VALUES
|
||||
-- General age classes (all sports)
|
||||
('PONY_U10', 'Pony Führzügel U10', NULL, 9, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('PONY_U12', 'Pony U12', NULL, 11, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('PONY_U14', 'Pony U14', NULL, 13, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('PONY_U16', 'Pony U16', NULL, 15, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('JGD_U16', 'Jugend U16', NULL, 15, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('JGD_U18', 'Jugend U18', NULL, 17, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('JUN_U21', 'Junioren U21', NULL, 20, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('YR_U25', 'Junge Reiter U25', NULL, 24, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('AK', 'Allgemeine Klasse', 18, NULL, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('SEN_40', 'Senioren Ü40', 40, NULL, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('SEN_50', 'Senioren Ü50', 50, NULL, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
('SEN_60', 'Senioren Ü60', 60, NULL, '31.12. des laufenden Kalenderjahres', NULL, NULL),
|
||||
|
||||
-- Dressage-specific age classes
|
||||
('DR_PONY_U12', 'Dressur Pony U12', NULL, 11, '31.12. des laufenden Kalenderjahres', 'DRESSUR', NULL),
|
||||
('DR_PONY_U14', 'Dressur Pony U14', NULL, 13, '31.12. des laufenden Kalenderjahres', 'DRESSUR', NULL),
|
||||
('DR_PONY_U16', 'Dressur Pony U16', NULL, 15, '31.12. des laufenden Kalenderjahres', 'DRESSUR', NULL),
|
||||
('DR_JGD_U18', 'Dressur Jugend U18', NULL, 17, '31.12. des laufenden Kalenderjahres', 'DRESSUR', NULL),
|
||||
('DR_JUN_U21', 'Dressur Junioren U21', NULL, 20, '31.12. des laufenden Kalenderjahres', 'DRESSUR', NULL),
|
||||
('DR_YR_U25', 'Dressur Junge Reiter U25', NULL, 24, '31.12. des laufenden Kalenderjahres', 'DRESSUR', NULL),
|
||||
|
||||
-- Jumping-specific age classes
|
||||
('SP_PONY_U12', 'Springen Pony U12', NULL, 11, '31.12. des laufenden Kalenderjahres', 'SPRINGEN', NULL),
|
||||
('SP_PONY_U14', 'Springen Pony U14', NULL, 13, '31.12. des laufenden Kalenderjahres', 'SPRINGEN', NULL),
|
||||
('SP_PONY_U16', 'Springen Pony U16', NULL, 15, '31.12. des laufenden Kalenderjahres', 'SPRINGEN', NULL),
|
||||
('SP_JGD_U18', 'Springen Jugend U18', NULL, 17, '31.12. des laufenden Kalenderjahres', 'SPRINGEN', NULL),
|
||||
('SP_JUN_U21', 'Springen Junioren U21', NULL, 20, '31.12. des laufenden Kalenderjahres', 'SPRINGEN', NULL),
|
||||
('SP_YR_U25', 'Springen Junge Reiter U25', NULL, 24, '31.12. des laufenden Kalenderjahres', 'SPRINGEN', NULL),
|
||||
|
||||
-- Eventing-specific age classes
|
||||
('VK_PONY_U14', 'Vielseitigkeit Pony U14', NULL, 13, '31.12. des laufenden Kalenderjahres', 'VIELSEITIGKEIT', NULL),
|
||||
('VK_PONY_U16', 'Vielseitigkeit Pony U16', NULL, 15, '31.12. des laufenden Kalenderjahres', 'VIELSEITIGKEIT', NULL),
|
||||
('VK_JGD_U18', 'Vielseitigkeit Jugend U18', NULL, 17, '31.12. des laufenden Kalenderjahres', 'VIELSEITIGKEIT', NULL),
|
||||
('VK_JUN_U21', 'Vielseitigkeit Junioren U21', NULL, 20, '31.12. des laufenden Kalenderjahres', 'VIELSEITIGKEIT', NULL),
|
||||
('VK_YR_U25', 'Vielseitigkeit Junge Reiter U25', NULL, 24, '31.12. des laufenden Kalenderjahres', 'VIELSEITIGKEIT', NULL),
|
||||
|
||||
-- Driving-specific age classes
|
||||
('FA_PONY_U16', 'Fahren Pony U16', NULL, 15, '31.12. des laufenden Kalenderjahres', 'FAHREN', NULL),
|
||||
('FA_JGD_U18', 'Fahren Jugend U18', NULL, 17, '31.12. des laufenden Kalenderjahres', 'FAHREN', NULL),
|
||||
('FA_JUN_U21', 'Fahren Junioren U21', NULL, 20, '31.12. des laufenden Kalenderjahres', 'FAHREN', NULL),
|
||||
('FA_YR_U25', 'Fahren Junge Reiter U25', NULL, 24, '31.12. des laufenden Kalenderjahres', 'FAHREN', NULL),
|
||||
|
||||
-- Vaulting-specific age classes
|
||||
('VT_U10', 'Voltigieren U10', NULL, 9, '31.12. des laufenden Kalenderjahres', 'VOLTIGIEREN', NULL),
|
||||
('VT_U12', 'Voltigieren U12', NULL, 11, '31.12. des laufenden Kalenderjahres', 'VOLTIGIEREN', NULL),
|
||||
('VT_U14', 'Voltigieren U14', NULL, 13, '31.12. des laufenden Kalenderjahres', 'VOLTIGIEREN', NULL),
|
||||
('VT_U16', 'Voltigieren U16', NULL, 15, '31.12. des laufenden Kalenderjahres', 'VOLTIGIEREN', NULL),
|
||||
('VT_U18', 'Voltigieren U18', NULL, 17, '31.12. des laufenden Kalenderjahres', 'VOLTIGIEREN', NULL),
|
||||
('VT_JUN_U21', 'Voltigieren Junioren U21', NULL, 20, '31.12. des laufenden Kalenderjahres', 'VOLTIGIEREN', NULL),
|
||||
|
||||
-- Gender-specific examples (if needed)
|
||||
('DR_DAMEN', 'Dressur Damen', 18, NULL, '31.12. des laufenden Kalenderjahres', 'DRESSUR', 'W'),
|
||||
('DR_HERREN', 'Dressur Herren', 18, NULL, '31.12. des laufenden Kalenderjahres', 'DRESSUR', 'M')
|
||||
|
||||
ON CONFLICT (altersklasse_code) DO NOTHING;
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
-- Migration V004: Create Platz (Venue/Arena) table
|
||||
-- This migration creates the table for tournament venues and arenas
|
||||
|
||||
CREATE TABLE IF NOT EXISTS platz (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
turnier_id UUID NOT NULL, -- Foreign key to tournament (not enforced as tournament might be in different module)
|
||||
name VARCHAR(200) NOT NULL,
|
||||
dimension VARCHAR(50),
|
||||
boden VARCHAR(100),
|
||||
typ VARCHAR(50) NOT NULL,
|
||||
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
|
||||
sortier_reihenfolge INTEGER,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT chk_platz_sortier_reihenfolge CHECK (sortier_reihenfolge IS NULL OR sortier_reihenfolge >= 0)
|
||||
);
|
||||
|
||||
-- Create unique constraint for name per tournament
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_platz_name_turnier ON platz(name, turnier_id);
|
||||
|
||||
-- Create indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_turnier ON platz(turnier_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_aktiv ON platz(ist_aktiv);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_typ ON platz(typ);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_turnier_aktiv ON platz(turnier_id, ist_aktiv);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_name ON platz(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_dimension ON platz(dimension);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_boden ON platz(boden);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_sortierung ON platz(sortier_reihenfolge);
|
||||
|
||||
-- Add comments for documentation
|
||||
COMMENT ON TABLE platz IS 'Master data table for tournament venues and arenas with type and dimension specifications';
|
||||
COMMENT ON COLUMN platz.id IS 'Unique internal identifier (UUID)';
|
||||
COMMENT ON COLUMN platz.turnier_id IS 'Foreign key reference to the tournament this venue belongs to';
|
||||
COMMENT ON COLUMN platz.name IS 'Name or designation of the venue (e.g., "Hauptplatz", "Dressurplatz A")';
|
||||
COMMENT ON COLUMN platz.dimension IS 'Dimensions of the venue (e.g., "20x60m", "20x40m")';
|
||||
COMMENT ON COLUMN platz.boden IS 'Type of ground surface (e.g., "Sand", "Gras", "Kunststoff")';
|
||||
COMMENT ON COLUMN platz.typ IS 'Type of venue (see PlatzTypE enum)';
|
||||
COMMENT ON COLUMN platz.ist_aktiv IS 'Indicates if this venue can currently be used';
|
||||
COMMENT ON COLUMN platz.sortier_reihenfolge IS 'Optional number for controlling sort order';
|
||||
COMMENT ON COLUMN platz.created_at IS 'Timestamp when this record was created';
|
||||
COMMENT ON COLUMN platz.updated_at IS 'Timestamp when this record was last updated';
|
||||
|
||||
-- Insert some example venue types and common configurations
|
||||
-- Note: These are examples and would typically be created per tournament
|
||||
-- Using a dummy tournament ID for demonstration purposes
|
||||
|
||||
-- Create a function to generate example venues for a tournament
|
||||
CREATE OR REPLACE FUNCTION create_example_venues(tournament_id UUID) RETURNS VOID AS $$
|
||||
BEGIN
|
||||
INSERT INTO platz (turnier_id, name, dimension, boden, typ, sortier_reihenfolge) VALUES
|
||||
-- Dressage arenas
|
||||
(tournament_id, 'Dressurplatz A', '20x60m', 'Sand', 'DRESSURPLATZ', 10),
|
||||
(tournament_id, 'Dressurplatz B', '20x40m', 'Sand', 'DRESSURPLATZ', 20),
|
||||
(tournament_id, 'Abreiteplatz Dressur', '20x40m', 'Sand', 'ABREITEPLATZ', 30),
|
||||
|
||||
-- Jumping arenas
|
||||
(tournament_id, 'Springplatz Hauptring', '40x80m', 'Sand', 'SPRINGPLATZ', 40),
|
||||
(tournament_id, 'Springplatz Ring 2', '35x70m', 'Sand', 'SPRINGPLATZ', 50),
|
||||
(tournament_id, 'Abreiteplatz Springen', '30x60m', 'Sand', 'ABREITEPLATZ', 60),
|
||||
|
||||
-- Cross-country and eventing
|
||||
(tournament_id, 'Geländestrecke', 'variabel', 'Gras', 'GELAENDESTRECKE', 70),
|
||||
(tournament_id, 'Vielseitigkeitsplatz', '25x65m', 'Sand', 'VIELSEITIGKEITSPLATZ', 80),
|
||||
|
||||
-- Driving arenas
|
||||
(tournament_id, 'Fahrplatz', '40x100m', 'Sand', 'FAHRPLATZ', 90),
|
||||
(tournament_id, 'Hindernisfahren', '40x80m', 'Sand', 'FAHRPLATZ', 100),
|
||||
|
||||
-- Vaulting
|
||||
(tournament_id, 'Voltigierplatz', '20m Durchmesser', 'Sand', 'VOLTIGIERPLATZ', 110),
|
||||
|
||||
-- Training and warm-up areas
|
||||
(tournament_id, 'Führanlage', '20m Durchmesser', 'Sand', 'FUEHRANLAGE', 120),
|
||||
(tournament_id, 'Longierplatz', '20m Durchmesser', 'Sand', 'LONGIERPLATZ', 130),
|
||||
(tournament_id, 'Trainingsplatz 1', '20x40m', 'Sand', 'TRAININGSPLATZ', 140),
|
||||
(tournament_id, 'Trainingsplatz 2', '20x40m', 'Gras', 'TRAININGSPLATZ', 150),
|
||||
|
||||
-- Indoor arenas
|
||||
(tournament_id, 'Reithalle A', '20x60m', 'Sand', 'REITHALLE', 160),
|
||||
(tournament_id, 'Reithalle B', '20x40m', 'Sand', 'REITHALLE', 170),
|
||||
|
||||
-- Outdoor areas
|
||||
(tournament_id, 'Außenplatz 1', '25x50m', 'Gras', 'AUSSENPLATZ', 180),
|
||||
(tournament_id, 'Außenplatz 2', '20x40m', 'Sand', 'AUSSENPLATZ', 190),
|
||||
|
||||
-- Special purpose areas
|
||||
(tournament_id, 'Siegerehrungsplatz', '15x25m', 'Gras', 'SONDERPLATZ', 200),
|
||||
(tournament_id, 'Vorführplatz', '20x30m', 'Sand', 'SONDERPLATZ', 210)
|
||||
|
||||
ON CONFLICT (name, turnier_id) DO NOTHING;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Add some venue type validation comments
|
||||
COMMENT ON FUNCTION create_example_venues(UUID) IS 'Helper function to create example venues for a tournament. Call with tournament UUID.';
|
||||
|
||||
-- Create a view for venue statistics
|
||||
CREATE OR REPLACE VIEW platz_statistics AS
|
||||
SELECT
|
||||
typ,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN ist_aktiv THEN 1 END) as active_count,
|
||||
COUNT(CASE WHEN NOT ist_aktiv THEN 1 END) as inactive_count,
|
||||
COUNT(DISTINCT turnier_id) as tournament_count,
|
||||
COUNT(DISTINCT dimension) as dimension_variants,
|
||||
COUNT(DISTINCT boden) as ground_type_variants
|
||||
FROM platz
|
||||
GROUP BY typ
|
||||
ORDER BY typ;
|
||||
|
||||
COMMENT ON VIEW platz_statistics IS 'Statistical overview of venues by type, showing counts and variants';
|
||||
|
||||
-- Create a view for tournament venue overview
|
||||
CREATE OR REPLACE VIEW tournament_venue_overview AS
|
||||
SELECT
|
||||
turnier_id,
|
||||
COUNT(*) as total_venues,
|
||||
COUNT(CASE WHEN ist_aktiv THEN 1 END) as active_venues,
|
||||
COUNT(DISTINCT typ) as venue_types,
|
||||
COUNT(DISTINCT dimension) as dimension_variants,
|
||||
COUNT(DISTINCT boden) as ground_types,
|
||||
STRING_AGG(DISTINCT typ, ', ' ORDER BY typ) as available_types
|
||||
FROM platz
|
||||
GROUP BY turnier_id
|
||||
ORDER BY turnier_id;
|
||||
|
||||
COMMENT ON VIEW tournament_venue_overview IS 'Overview of venues per tournament with summary statistics';
|
||||
|
||||
-- Example of how to use the function (commented out as it requires actual tournament IDs)
|
||||
-- SELECT create_example_venues('550e8400-e29b-41d4-a716-446655440000'::UUID);
|
||||
|
||||
-- Add some helpful indexes for the views
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_typ_aktiv ON platz(typ, ist_aktiv);
|
||||
CREATE INDEX IF NOT EXISTS idx_platz_turnier_typ ON platz(turnier_id, typ);
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
-- File: V1__Create_Initial_Tables.sql
|
||||
|
||||
-- Tabelle zur Verwaltung der Vereine (Mandanten)
|
||||
CREATE TABLE IF NOT EXISTS dom_verein (
|
||||
verein_id UUID PRIMARY KEY,
|
||||
oeps_vereins_nr VARCHAR(4) UNIQUE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
kuerzel VARCHAR(20),
|
||||
bundesland_code VARCHAR(2),
|
||||
daten_quelle VARCHAR(50) NOT NULL,
|
||||
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Tabelle zur Verwaltung der Personen (Sportler, Funktionäre)
|
||||
CREATE TABLE IF NOT EXISTS dom_person (
|
||||
person_id UUID PRIMARY KEY,
|
||||
oeps_satz_nr VARCHAR(6) UNIQUE,
|
||||
nachname VARCHAR(100) NOT NULL,
|
||||
vorname VARCHAR(100) NOT NULL,
|
||||
geburtsdatum DATE,
|
||||
geschlecht VARCHAR(10),
|
||||
nationalitaet_code VARCHAR(3),
|
||||
stamm_verein_id UUID REFERENCES dom_verein(verein_id),
|
||||
ist_gesperrt BOOLEAN NOT NULL DEFAULT false,
|
||||
daten_quelle VARCHAR(50) NOT NULL,
|
||||
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Weitere Tabellen können hier hinzugefügt werden...
|
||||
@@ -0,0 +1,10 @@
|
||||
<configuration>
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user