59 lines
3.2 KiB
Markdown
Executable File
59 lines
3.2 KiB
Markdown
Executable File
# RoggioApp - Analyse: Die Person-Entität (Hard vs. Flexible)
|
|
|
|
## Die Herausforderung
|
|
Was gehört zwingend als harte, durchsuchbare SQL-Spalte in die Tabelle `Person`, und was lagern wir als flexible Eigenschaft (Trait) in das JSONB-Feld oder in Relationen aus?
|
|
|
|
## Sevs Entwurf & Claras Analyse
|
|
|
|
### 1. Originär (Die Person selbst)
|
|
* **Vorname & Nachname:** ✅ Absolut notwendig. Harte SQL-Spalten. (Ggf. um `nickname` als Spalte erweitern).
|
|
* **Geburtsdatum:** ✅ Harte Spalte (für Altersberechnungen, Kurtaxe, Meldescheine extrem wichtig).
|
|
* **Mobile-Nr & Private E-Mail:** ⚠️ *Diskussion:* Sind die eindeutig?
|
|
* *Realität:* Oft buchen Ehepaare oder Familien mit nur *einer* gemeinsamen Mailadresse oder Handynummer.
|
|
* *Lösung:* Wir dürfen `email` und `phone` **nicht** auf `UNIQUE` (Einzigartig) in der Datenbank setzen! Sie bleiben harte SQL-Spalten für die schnelle Suche, aber Doppelungen sind erlaubt.
|
|
|
|
### 2. Relational / Flexibel (Die Eigenschaften)
|
|
* **Anrede (Pronouns / Title):** -> JSONB (`traits`). (Ändert sich gesellschaftlich, JSONB ist hier flexibler als ein harter SQL-Enum).
|
|
* **Identity-Dokument (Perso/Passport):** -> JSONB (`traits`).
|
|
* *Warum:* Die Felder variieren stark je nach Land (Ausgestellt in, Gültig bis, Behörde). Ein JSONB-Objekt `identity_document: { type: "passport", number: "...", valid_until: "..." }` ist hier perfekt.
|
|
* **Geburtsort:** -> JSONB (`traits`).
|
|
* **Adresse (Wohnort):** -> ⚠️ *Eigene Tabelle!*
|
|
* *Warum:* Eine Adresse (Straße, Stadt, Land) kann von 5 Familienmitgliedern oder einer Firma geteilt werden. Wir bauen eine Tabelle `Address` und verknüpfen die Person(en) per ID damit. Das spart immense Redundanz.
|
|
* **Finanz-Infos (IBAN etc.):** -> JSONB (`traits`).
|
|
|
|
### 3. Logisch durch den Graphen gelöst (Architektur-Bonus)
|
|
* **Buchungsverlauf:** Wird *nicht* in der Person gespeichert. Ergibt sich zu 100% aus den `Event`-Knoten, die mit der Person (oder ihrer Gruppe) verknüpft sind.
|
|
* **Loginrights:** Werden nicht gespeichert. Das übernimmt die Nextcloud (SSO). Wir speichern nur die `ssoId`.
|
|
* **Type (Kollektiv / Client / Personal):** Wird *nicht* als hartes Feld gespeichert! Ergibt sich aus den `GroupMembership`-Verknüpfungen (z.B. wenn Person A Mitglied in der Operator-Gruppe ist, ist sie Personal).
|
|
* **Groups & Groupfunction:** Wird 1:1 durch unsere Pivot-Tabelle `GroupMembership` (inkl. `role`) abgebildet.
|
|
|
|
## Claras Vorschlag für die finale Prisma-Tabelle `Person`
|
|
```prisma
|
|
model Person {
|
|
id String @id @default(uuid())
|
|
firstName String @db.VarChar(100)
|
|
lastName String @db.VarChar(100)
|
|
nickname String? @db.VarChar(100)
|
|
birthDate DateTime? @db.Date
|
|
|
|
// Kontaktdaten (NICHT UNIQUE!)
|
|
email String? @db.VarChar(255)
|
|
phone String? @db.VarChar(50)
|
|
|
|
// Verknüpfung zur Authentifizierung
|
|
ssoId String? @unique @db.VarChar(255)
|
|
|
|
// Die Wohnadresse (Relational)
|
|
addressId String?
|
|
address Address? @relation(fields: [addressId], references: [id])
|
|
|
|
// Alles andere (Pass, Finanzen, Anrede, Geburtsort, Allergien)
|
|
traits Json @default("{}")
|
|
|
|
groupMemberships GroupMembership[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
```
|