Init: RoggioApp Architecture, Prisma Schema, API MVP
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
# 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
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user