- 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.
131 lines
4.3 KiB
Markdown
131 lines
4.3 KiB
Markdown
---
|
||
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)
|