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.
This commit is contained in:
2026-04-03 22:59:41 +02:00
parent 6e484ee9a1
commit dbe7c74a9c
6 changed files with 269 additions and 5 deletions
@@ -0,0 +1,130 @@
---
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)