--- type: Reference status: ACTIVE owner: Backend Developer last_update: 2026-04-03 --- # Datenbankschema V1–V009 (Tenant‑Schema) Quelle: Flyway‑Migrationen im Entries‑Service (`backend/services/entries/entries-service/src/main/resources/db/tenant/`), insbesondere `V2__domain_hierarchy.sql`. Hinweis zur Architektur: Je Veranstaltung (Tenant) existiert ein eigenes Datenbankschema (ADR‑0021). Alle untenstehenden Tabellen werden pro Tenant‑Schema angelegt und sind somit mandantengetrennt. ## Tabellenübersicht - `veranstaltungen` — Eine Veranstaltung (Singleton im Tenant‑Schema) - `turniere` — Turniere einer Veranstaltung (1:N zu `veranstaltungen`) - `bewerbe` — Bewerbe/Prüfungen eines Turniers (1:N zu `turniere`) - `abteilungen` — Abteilungen/Heats eines Bewerbs (1:N zu `bewerbe`) - `teilnehmer_konten` — Aggregierte Salden eines Teilnehmers über alle Turniere der Veranstaltung - `turnier_kassa` — Kassa‑Saldo pro Turnier ## Detaillierte Definitionen (aus V2__domain_hierarchy.sql) ### veranstaltungen Primärschlüssel: `id (UUID)` Spalten: - `id UUID PRIMARY KEY` - `created_at TIMESTAMPTZ NOT NULL` - `updated_at TIMESTAMPTZ NOT NULL` ### turniere Primärschlüssel: `id (UUID)` Fremdschlüssel: `veranstaltung_id → veranstaltungen(id) ON DELETE CASCADE` Spalten: - `id UUID PRIMARY KEY` - `veranstaltung_id UUID NOT NULL` - `oeps_turniernummer VARCHAR(50) NOT NULL` - `created_at TIMESTAMPTZ NOT NULL` - `updated_at TIMESTAMPTZ NOT NULL` Indizes/Constraints: - `UNIQUE (oeps_turniernummer)` → `uq_turniere_oeps_nr` - `INDEX (veranstaltung_id)` → `idx_turniere_veranstaltung_id` ### bewerbe Primärschlüssel: `id (UUID)` Fremdschlüssel: `turnier_id → turniere(id) ON DELETE CASCADE` Spalten: - `id UUID PRIMARY KEY` - `turnier_id UUID NOT NULL` - `klasse VARCHAR(50) NOT NULL` - `hoehe_cm INTEGER NULL` - `bezeichnung TEXT NOT NULL` - `created_at TIMESTAMPTZ NOT NULL` - `updated_at TIMESTAMPTZ NOT NULL` Indizes: - `INDEX (turnier_id)` → `idx_bewerbe_turnier_id` - `INDEX (klasse)` → `idx_bewerbe_klasse` ### abteilungen Primärschlüssel: `id (UUID)` Fremdschlüssel: `bewerb_id → bewerbe(id) ON DELETE CASCADE` Spalten: - `id UUID PRIMARY KEY` - `bewerb_id UUID NOT NULL` - `nr INTEGER NOT NULL` - `bezeichnung TEXT NOT NULL` - `typ VARCHAR(32) NOT NULL` (Werte: `SEPARATE_SIEGEREHRUNG`, `ORGANISATORISCH`) - `created_at TIMESTAMPTZ NOT NULL` - `updated_at TIMESTAMPTZ NOT NULL` Constraints/Indizes: - `CHECK (typ IN ('SEPARATE_SIEGEREHRUNG','ORGANISATORISCH'))` → `chk_abteilungen_typ` - `UNIQUE (bewerb_id, nr)` → `uq_abteilungen_bewerb_nr` - `INDEX (bewerb_id)` → `idx_abteilungen_bewerb_id` - `INDEX (typ)` → `idx_abteilungen_typ` ### teilnehmer_konten Primärschlüssel: `id (UUID)` Fremdschlüssel: `veranstaltung_id → veranstaltungen(id) ON DELETE CASCADE` Spalten: - `id UUID PRIMARY KEY` - `veranstaltung_id UUID NOT NULL` - `teilnehmer_id UUID NOT NULL` - `saldo_cents BIGINT NOT NULL DEFAULT 0` - `currency CHAR(3) NOT NULL DEFAULT 'EUR'` - `created_at TIMESTAMPTZ NOT NULL` - `updated_at TIMESTAMPTZ NOT NULL` Indizes/Constraints: - `UNIQUE (veranstaltung_id, teilnehmer_id)` → `uq_tkonten_veranstaltung_teilnehmer` - `INDEX (veranstaltung_id)` → `idx_tkonten_veranstaltung_id` - `INDEX (teilnehmer_id)` → `idx_tkonten_teilnehmer_id` ### turnier_kassa Primärschlüssel: `id (UUID)` Fremdschlüssel: `turnier_id → turniere(id) ON DELETE CASCADE` Spalten: - `id UUID PRIMARY KEY` - `turnier_id UUID NOT NULL` - `saldo_cents BIGINT NOT NULL DEFAULT 0` - `currency CHAR(3) NOT NULL DEFAULT 'EUR'` - `created_at TIMESTAMPTZ NOT NULL` - `updated_at TIMESTAMPTZ NOT NULL` Indizes/Constraints: - `UNIQUE (turnier_id)` → `uq_turnier_kassa_turnier` - `INDEX (turnier_id)` → `idx_turnier_kassa_turnier_id` ## Versionierung / Flyway - Die oben dokumentierten Tabellen sind in `V2__domain_hierarchy.sql` definiert. - Weitere Migrationen V1–V009 betreffen Bootstrap/Erweiterungen; diese Seite wird fortlaufend ergänzt, sobald neue fachrelevante Strukturen hinzukommen. ## Beziehungen (Kurz) `veranstaltungen (1) ──< (N) turniere (1) ──< (N) bewerbe (1) ──< (N) abteilungen` Separat aggregierend: - `teilnehmer_konten` auf Veranstaltungsebene (pro Teilnehmer genau ein Konto) - `turnier_kassa` auf Turnierebene (pro Turnier genau ein Kassa‑Eintrag)