meldestelle/docs/05_Backend/Schema/Database_Schema_V1-V009.md
StefanMoCoAt dbe7c74a9c Document tenant-aware database schema, multi-tenant strategy, and API references:
- Add database schema documentation: `Database_Schema_V1-V009.md` for tenant-isolated entities (`veranstaltungen`, `turniere`, `bewerbe`, etc.).
- Draft initial Kassa API reference: `Kassa_API.md` (status: DRAFT).
- Finalize Stammdaten API reference: `API_Uebersicht_Stammdaten.md` (status: ACTIVE).
- Summarize tenant isolation and multi-tenant strategy in `Multi_Tenant_Kurz.md`.
- Update `README.md` with links to new references. Mark B-2 roadmap tasks as partially complete.
2026-04-03 22:59:45 +02:00

131 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
type: Reference
status: ACTIVE
owner: Backend Developer
last_update: 2026-04-03
---
# Datenbankschema V1V009 (TenantSchema)
Quelle: FlywayMigrationen im EntriesService (`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 (ADR0021). Alle untenstehenden Tabellen werden pro TenantSchema angelegt und sind somit mandantengetrennt.
## Tabellenübersicht
- `veranstaltungen` — Eine Veranstaltung (Singleton im TenantSchema)
- `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` — KassaSaldo 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 V1V009 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 KassaEintrag)